feat: init memory command (#138)
This commit is contained in:
129
src/cli/App.tsx
129
src/cli/App.tsx
@@ -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 */}
|
||||
|
||||
@@ -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...";
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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>{" "}
|
||||
|
||||
Reference in New Issue
Block a user