feat: init memory command (#138)

This commit is contained in:
Charles Packer
2025-11-30 18:31:01 -08:00
committed by GitHub
parent 6089ce1cdd
commit f50e608718
7 changed files with 454 additions and 16 deletions

View File

@@ -1531,6 +1531,124 @@ export default function App({
return { submitted: true };
}
// Special handling for /init command - initialize agent memory
if (msg.trim() === "/init") {
const cmdId = uid("cmd");
buffersRef.current.byId.set(cmdId, {
kind: "command",
id: cmdId,
input: msg,
output: "Gathering project context...",
phase: "running",
});
buffersRef.current.order.push(cmdId);
refreshDerived();
setCommandRunning(true);
try {
// Import the initialization prompt
const { INITIALIZE_PROMPT } = await import(
"../agent/promptAssets.js"
);
// Gather git context if available
let gitContext = "";
try {
const { execSync } = await import("node:child_process");
const cwd = process.cwd();
// Check if we're in a git repo
try {
execSync("git rev-parse --git-dir", {
cwd,
stdio: "pipe",
});
// Gather git info
const branch = execSync("git branch --show-current", {
cwd,
encoding: "utf-8",
}).trim();
const mainBranch = execSync(
"git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo 'main'",
{ cwd, encoding: "utf-8", shell: "/bin/bash" },
).trim();
const status = execSync("git status --short", {
cwd,
encoding: "utf-8",
}).trim();
const recentCommits = execSync(
"git log --oneline -10 2>/dev/null || echo 'No commits yet'",
{ cwd, encoding: "utf-8" },
).trim();
gitContext = `
## Current Project Context
**Working directory**: ${cwd}
### Git Status
- **Current branch**: ${branch}
- **Main branch**: ${mainBranch}
- **Status**:
${status || "(clean working tree)"}
### Recent Commits
${recentCommits}
`;
} catch {
// Not a git repo, just include working directory
gitContext = `
## Current Project Context
**Working directory**: ${cwd}
**Git**: Not a git repository
`;
}
} catch {
// execSync import failed, skip git context
}
// Mark command as finished before sending message
buffersRef.current.byId.set(cmdId, {
kind: "command",
id: cmdId,
input: msg,
output:
"Assimilating project context and defragmenting memories...",
phase: "finished",
success: true,
});
refreshDerived();
// Send initialization prompt with git context as a system reminder
const initMessage = `<system-reminder>\n${INITIALIZE_PROMPT}\n${gitContext}\n</system-reminder>`;
// Process conversation with the init prompt
await processConversation([
{
type: "message",
role: "user",
content: initMessage,
},
]);
} catch (error) {
buffersRef.current.byId.set(cmdId, {
kind: "command",
id: cmdId,
input: msg,
output: `Failed: ${error instanceof Error ? error.message : String(error)}`,
phase: "finished",
success: false,
});
refreshDerived();
} finally {
setCommandRunning(false);
}
return { submitted: true };
}
// Immediately add command to transcript with "running" phase
const cmdId = uid("cmd");
buffersRef.current.byId.set(cmdId, {
@@ -2798,13 +2916,10 @@ Plan file path: ${planFilePath}`;
{/* Question Dialog - for AskUserQuestion tool */}
{questionApprovalPending && (
<>
<Box height={1} />
<QuestionDialog
questions={questionApprovalPending.questions}
onSubmit={handleQuestionSubmit}
/>
</>
<QuestionDialog
questions={questionApprovalPending.questions}
onSubmit={handleQuestionSubmit}
/>
)}
{/* Enter Plan Mode Dialog - for EnterPlanMode tool */}

View File

@@ -106,6 +106,13 @@ export const commands: Record<string, Command> = {
return "Showing background processes...";
},
},
"/init": {
desc: "Initialize agent memory for this project",
handler: () => {
// Handled specially in App.tsx to send initialization prompt
return "Initializing memory...";
},
},
};
/**

View File

@@ -135,7 +135,7 @@ export const QuestionDialog = memo(({ questions, onSubmit }: Props) => {
if (!currentQuestion) return null;
return (
<Box flexDirection="column" paddingY={1}>
<Box flexDirection="column">
<Box marginBottom={1}>
<Text color={colors.approval.header}>
<Text bold>[{currentQuestion.header}]</Text>{" "}