@freesyntax/notch-cli 0.5.12 → 0.5.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +55 -61
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2576,7 +2576,7 @@ async function buildSystemPrompt(projectRoot, modelId) {
|
|
|
2576
2576
|
} catch {
|
|
2577
2577
|
}
|
|
2578
2578
|
try {
|
|
2579
|
-
const memoryStr = await formatMemoriesForPrompt(
|
|
2579
|
+
const memoryStr = await formatMemoriesForPrompt();
|
|
2580
2580
|
if (memoryStr) {
|
|
2581
2581
|
parts.push("", "## Saved Context (Memory)", memoryStr);
|
|
2582
2582
|
}
|
|
@@ -6390,8 +6390,8 @@ function clearMenu(state) {
|
|
|
6390
6390
|
if (state.renderedLines === 0) return "";
|
|
6391
6391
|
const lines = state.renderedLines;
|
|
6392
6392
|
state.renderedLines = 0;
|
|
6393
|
-
let ansi = "";
|
|
6394
|
-
for (let i = 0; i < lines; i++) {
|
|
6393
|
+
let ansi = "\x1B[2K";
|
|
6394
|
+
for (let i = 0; i < lines + 1; i++) {
|
|
6395
6395
|
ansi += "\x1B[1A\x1B[2K";
|
|
6396
6396
|
}
|
|
6397
6397
|
return ansi;
|
|
@@ -6456,16 +6456,15 @@ function attachSlashMenu(rl) {
|
|
|
6456
6456
|
const shouldShow = updateMenu(state, line);
|
|
6457
6457
|
if (wasVisible && !shouldShow) {
|
|
6458
6458
|
process.stdout.write(clearMenu(state));
|
|
6459
|
+
rewritePromptLine(rl);
|
|
6459
6460
|
} else if (shouldShow) {
|
|
6460
6461
|
if (wasVisible) {
|
|
6461
6462
|
process.stdout.write(clearMenu(state));
|
|
6462
6463
|
}
|
|
6463
6464
|
const menuStr = renderMenu(state);
|
|
6464
6465
|
if (menuStr) {
|
|
6465
|
-
process.stdout.write("\x1B[s");
|
|
6466
6466
|
process.stdout.write(menuStr + "\n");
|
|
6467
6467
|
rewritePromptLine(rl);
|
|
6468
|
-
process.stdout.write("\x1B[u");
|
|
6469
6468
|
}
|
|
6470
6469
|
}
|
|
6471
6470
|
}
|
|
@@ -6897,7 +6896,8 @@ Analyze the above input.`;
|
|
|
6897
6896
|
promptTokens: response.usage.promptTokens,
|
|
6898
6897
|
completionTokens: response.usage.completionTokens,
|
|
6899
6898
|
totalTokens: response.usage.totalTokens,
|
|
6900
|
-
|
|
6899
|
+
toolCalls: response.toolCallCount,
|
|
6900
|
+
iterations: response.iterations
|
|
6901
6901
|
});
|
|
6902
6902
|
costTracker.record(activeModelId, response.usage.promptTokens, response.usage.completionTokens);
|
|
6903
6903
|
console.log(usage.formatLast() + " " + costTracker.formatLastCost());
|
|
@@ -6942,7 +6942,7 @@ Analyze the above input.`;
|
|
|
6942
6942
|
if (messages.length > 0) {
|
|
6943
6943
|
try {
|
|
6944
6944
|
const name = getSessionName();
|
|
6945
|
-
const id = await saveSession(config.projectRoot,
|
|
6945
|
+
const id = await saveSession(messages, config.projectRoot, activeModelId);
|
|
6946
6946
|
console.log(chalk27.gray(` Session saved: ${id}${name ? ` (${name})` : ""}`));
|
|
6947
6947
|
} catch {
|
|
6948
6948
|
}
|
|
@@ -7068,7 +7068,7 @@ Analyze the above input.`;
|
|
|
7068
7068
|
} else {
|
|
7069
7069
|
for (const df of diffs) {
|
|
7070
7070
|
console.log(chalk27.cyan(` ${df.path}:`));
|
|
7071
|
-
console.log(unifiedDiff(df.before, df.after, df.path));
|
|
7071
|
+
console.log(unifiedDiff(df.before ?? "", df.after ?? "", df.path));
|
|
7072
7072
|
console.log("");
|
|
7073
7073
|
}
|
|
7074
7074
|
}
|
|
@@ -7076,12 +7076,11 @@ Analyze the above input.`;
|
|
|
7076
7076
|
return;
|
|
7077
7077
|
}
|
|
7078
7078
|
if (input.startsWith("/export")) {
|
|
7079
|
-
const exportPath = input.replace("/export", "").trim() ||
|
|
7079
|
+
const exportPath = input.replace("/export", "").trim() || "notch-export.md";
|
|
7080
7080
|
try {
|
|
7081
|
-
const ePath = await exportSession(messages, {
|
|
7081
|
+
const ePath = await exportSession(messages, exportPath, {
|
|
7082
7082
|
model: activeModelId,
|
|
7083
|
-
|
|
7084
|
-
outputPath: exportPath
|
|
7083
|
+
project: config.projectRoot
|
|
7085
7084
|
});
|
|
7086
7085
|
console.log(chalk27.green(` Exported to ${ePath}
|
|
7087
7086
|
`));
|
|
@@ -7094,7 +7093,7 @@ Analyze the above input.`;
|
|
|
7094
7093
|
}
|
|
7095
7094
|
if (input === "/save") {
|
|
7096
7095
|
try {
|
|
7097
|
-
const id = await saveSession(config.projectRoot,
|
|
7096
|
+
const id = await saveSession(messages, config.projectRoot, activeModelId);
|
|
7098
7097
|
sessionId = id;
|
|
7099
7098
|
console.log(chalk27.green(` Session saved: ${id}
|
|
7100
7099
|
`));
|
|
@@ -7107,13 +7106,13 @@ Analyze the above input.`;
|
|
|
7107
7106
|
}
|
|
7108
7107
|
if (input === "/sessions") {
|
|
7109
7108
|
try {
|
|
7110
|
-
const sessions = await listSessions(
|
|
7109
|
+
const sessions = await listSessions();
|
|
7111
7110
|
if (sessions.length === 0) {
|
|
7112
7111
|
console.log(chalk27.gray(" No saved sessions.\n"));
|
|
7113
7112
|
} else {
|
|
7114
7113
|
console.log(chalk27.gray("\n Saved sessions:\n"));
|
|
7115
7114
|
for (const s of sessions.slice(0, 10)) {
|
|
7116
|
-
console.log(chalk27.gray(` ${s.id} ${s.turns} turns ${s.
|
|
7115
|
+
console.log(chalk27.gray(` ${s.id} ${s.turns} turns ${s.updated} ${s.model}`));
|
|
7117
7116
|
}
|
|
7118
7117
|
console.log("");
|
|
7119
7118
|
}
|
|
@@ -7191,7 +7190,7 @@ Analyze the above input.`;
|
|
|
7191
7190
|
const task = input.replace("/plan ", "").trim();
|
|
7192
7191
|
const planSpinner = ora4("Generating plan...").start();
|
|
7193
7192
|
try {
|
|
7194
|
-
activePlan = await generatePlan(task, model,
|
|
7193
|
+
activePlan = await generatePlan(task, model, { cwd: config.projectRoot, repoMap: repoMapStr || void 0, history: messages });
|
|
7195
7194
|
planSpinner.succeed("Plan generated");
|
|
7196
7195
|
console.log(formatPlan(activePlan));
|
|
7197
7196
|
console.log(chalk27.gray(" Use /plan approve to execute, /plan edit to modify, or /plan cancel to discard.\n"));
|
|
@@ -7210,6 +7209,7 @@ Analyze the above input.`;
|
|
|
7210
7209
|
console.log(chalk27.green(" Executing plan...\n"));
|
|
7211
7210
|
while (!isPlanComplete(activePlan)) {
|
|
7212
7211
|
const stepPrompt = currentStepPrompt(activePlan);
|
|
7212
|
+
if (!stepPrompt) break;
|
|
7213
7213
|
messages.push({ role: "user", content: stepPrompt });
|
|
7214
7214
|
const planStepSpinner = ora4(`Step ${activePlan.currentStep + 1}/${activePlan.steps.length}...`).start();
|
|
7215
7215
|
try {
|
|
@@ -7234,7 +7234,7 @@ Analyze the above input.`;
|
|
|
7234
7234
|
console.log("\n");
|
|
7235
7235
|
messages.length = 0;
|
|
7236
7236
|
messages.push(...response.messages);
|
|
7237
|
-
|
|
7237
|
+
advancePlan(activePlan);
|
|
7238
7238
|
} catch (err) {
|
|
7239
7239
|
planStepSpinner.fail(`Step failed: ${err.message}`);
|
|
7240
7240
|
break;
|
|
@@ -7267,36 +7267,36 @@ Analyze the above input.`;
|
|
|
7267
7267
|
}
|
|
7268
7268
|
if (input.startsWith("/agent ")) {
|
|
7269
7269
|
const task = input.replace("/agent ", "").trim();
|
|
7270
|
-
const agentId = nextSubagentId();
|
|
7270
|
+
const agentId = nextSubagentId("general");
|
|
7271
7271
|
console.log(chalk27.cyan(` Spawning subagent #${agentId}: ${task}
|
|
7272
7272
|
`));
|
|
7273
7273
|
spawnSubagent({
|
|
7274
7274
|
id: agentId,
|
|
7275
|
-
|
|
7275
|
+
type: "general",
|
|
7276
|
+
prompt: task,
|
|
7276
7277
|
model,
|
|
7277
|
-
systemPrompt,
|
|
7278
7278
|
toolContext: toolCtx,
|
|
7279
|
-
|
|
7280
|
-
|
|
7281
|
-
|
|
7279
|
+
onStatus: (id, status) => {
|
|
7280
|
+
console.log(chalk27.gray(` [${id}] ${status}`));
|
|
7281
|
+
}
|
|
7282
|
+
}).then((result) => {
|
|
7283
|
+
console.log(chalk27.green(`
|
|
7282
7284
|
Subagent #${agentId} finished:`));
|
|
7283
|
-
|
|
7285
|
+
console.log(chalk27.gray(` ${result.text.slice(0, 200)}
|
|
7284
7286
|
`));
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
|
|
7288
|
-
|
|
7289
|
-
Subagent #${agentId} failed: ${err}
|
|
7287
|
+
rl.prompt();
|
|
7288
|
+
}).catch((err) => {
|
|
7289
|
+
console.log(chalk27.red(`
|
|
7290
|
+
Subagent #${agentId} failed: ${err.message}
|
|
7290
7291
|
`));
|
|
7291
|
-
|
|
7292
|
-
}
|
|
7292
|
+
rl.prompt();
|
|
7293
7293
|
});
|
|
7294
7294
|
rl.prompt();
|
|
7295
7295
|
return;
|
|
7296
7296
|
}
|
|
7297
7297
|
if (input === "/memory") {
|
|
7298
7298
|
try {
|
|
7299
|
-
const memories = await loadMemories(
|
|
7299
|
+
const memories = await loadMemories();
|
|
7300
7300
|
if (memories.length === 0) {
|
|
7301
7301
|
console.log(chalk27.gray(" No saved memories.\n"));
|
|
7302
7302
|
} else {
|
|
@@ -7318,7 +7318,7 @@ Analyze the above input.`;
|
|
|
7318
7318
|
if (input.startsWith("/memory search ")) {
|
|
7319
7319
|
const query = input.replace("/memory search ", "").trim();
|
|
7320
7320
|
try {
|
|
7321
|
-
const results = await searchMemories(
|
|
7321
|
+
const results = await searchMemories(query);
|
|
7322
7322
|
if (results.length === 0) {
|
|
7323
7323
|
console.log(chalk27.gray(` No memories matching "${query}"
|
|
7324
7324
|
`));
|
|
@@ -7337,9 +7337,9 @@ Analyze the above input.`;
|
|
|
7337
7337
|
}
|
|
7338
7338
|
if (input === "/memory clear") {
|
|
7339
7339
|
try {
|
|
7340
|
-
const memories = await loadMemories(
|
|
7340
|
+
const memories = await loadMemories();
|
|
7341
7341
|
for (const m of memories) {
|
|
7342
|
-
await deleteMemory(
|
|
7342
|
+
await deleteMemory(m.filename);
|
|
7343
7343
|
}
|
|
7344
7344
|
console.log(chalk27.yellow(` Cleared ${memories.length} memories.
|
|
7345
7345
|
`));
|
|
@@ -7360,8 +7360,8 @@ Analyze the above input.`;
|
|
|
7360
7360
|
const goal = input.replace("/ralph plan ", "").trim();
|
|
7361
7361
|
const planSpinner = ora4("Ralph is planning...").start();
|
|
7362
7362
|
try {
|
|
7363
|
-
ralphPlan = await generateRalphPlan(goal, model,
|
|
7364
|
-
await savePlan(config.projectRoot
|
|
7363
|
+
ralphPlan = await generateRalphPlan(goal, model, config.projectRoot);
|
|
7364
|
+
await savePlan(ralphPlan, config.projectRoot);
|
|
7365
7365
|
planSpinner.succeed(`Ralph planned ${ralphPlan.tasks.length} tasks`);
|
|
7366
7366
|
console.log(formatRalphStatus(ralphPlan));
|
|
7367
7367
|
} catch (err) {
|
|
@@ -7378,18 +7378,13 @@ Analyze the above input.`;
|
|
|
7378
7378
|
}
|
|
7379
7379
|
console.log(chalk27.green(" Ralph is running...\n"));
|
|
7380
7380
|
try {
|
|
7381
|
-
ralphPlan = await runRalphLoop(ralphPlan, {
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
toolContext: toolCtx,
|
|
7385
|
-
contextWindow: MODEL_CATALOG[activeModelId].contextWindow,
|
|
7386
|
-
onTaskStart: (task) => console.log(chalk27.cyan(` \u25B6 Task: ${task.description}`)),
|
|
7387
|
-
onTaskComplete: (task) => console.log(chalk27.green(` \u2713 Done: ${task.description}
|
|
7381
|
+
ralphPlan = await runRalphLoop(ralphPlan, model, toolCtx, config.projectRoot, {
|
|
7382
|
+
onTaskStart: (task) => console.log(chalk27.cyan(` \u25B6 Task: ${task.title}`)),
|
|
7383
|
+
onTaskEnd: (task) => console.log(chalk27.green(` \u2713 Done: ${task.title}
|
|
7388
7384
|
`)),
|
|
7389
|
-
|
|
7390
|
-
`))
|
|
7385
|
+
onText: (chunk) => process.stdout.write(chunk)
|
|
7391
7386
|
});
|
|
7392
|
-
await savePlan(config.projectRoot
|
|
7387
|
+
await savePlan(ralphPlan, config.projectRoot);
|
|
7393
7388
|
console.log(formatRalphStatus(ralphPlan));
|
|
7394
7389
|
} catch (err) {
|
|
7395
7390
|
console.log(chalk27.red(` Ralph error: ${err.message}
|
|
@@ -7565,7 +7560,8 @@ Analyze the above input.`;
|
|
|
7565
7560
|
promptTokens: response.usage.promptTokens,
|
|
7566
7561
|
completionTokens: response.usage.completionTokens,
|
|
7567
7562
|
totalTokens: response.usage.totalTokens,
|
|
7568
|
-
|
|
7563
|
+
toolCalls: response.toolCallCount,
|
|
7564
|
+
iterations: response.iterations
|
|
7569
7565
|
});
|
|
7570
7566
|
costTracker.record(activeModelId, response.usage.promptTokens, response.usage.completionTokens);
|
|
7571
7567
|
console.log(usage.formatLast() + " " + costTracker.formatLastCost());
|
|
@@ -7583,8 +7579,10 @@ Analyze the above input.`;
|
|
|
7583
7579
|
const memMatch = lastText.match(/\[(?:MEMORY|memory):\s*([^\]]+)\]/);
|
|
7584
7580
|
if (memMatch) {
|
|
7585
7581
|
try {
|
|
7586
|
-
await saveMemory(
|
|
7587
|
-
|
|
7582
|
+
await saveMemory({
|
|
7583
|
+
name: "auto-saved",
|
|
7584
|
+
description: memMatch[1].slice(0, 80),
|
|
7585
|
+
type: "project",
|
|
7588
7586
|
content: memMatch[1]
|
|
7589
7587
|
});
|
|
7590
7588
|
console.log(chalk27.gray(" (Saved to memory)\n"));
|
|
@@ -7631,8 +7629,8 @@ async function handleRalphSubcommand(args, cliOpts) {
|
|
|
7631
7629
|
process.exit(1);
|
|
7632
7630
|
}
|
|
7633
7631
|
const spinner = ora4("Ralph is planning...").start();
|
|
7634
|
-
const plan = await generateRalphPlan(goal, model,
|
|
7635
|
-
await savePlan(config.projectRoot
|
|
7632
|
+
const plan = await generateRalphPlan(goal, model, config.projectRoot);
|
|
7633
|
+
await savePlan(plan, config.projectRoot);
|
|
7636
7634
|
spinner.succeed(`Planned ${plan.tasks.length} tasks`);
|
|
7637
7635
|
console.log(formatRalphStatus(plan));
|
|
7638
7636
|
} else if (subcommand === "run") {
|
|
@@ -7641,16 +7639,12 @@ async function handleRalphSubcommand(args, cliOpts) {
|
|
|
7641
7639
|
console.error(chalk27.red(" No plan found. Run: notch ralph plan <goal>"));
|
|
7642
7640
|
process.exit(1);
|
|
7643
7641
|
}
|
|
7644
|
-
plan = await runRalphLoop(plan, {
|
|
7645
|
-
|
|
7646
|
-
|
|
7647
|
-
|
|
7648
|
-
contextWindow: MODEL_CATALOG[config.models.chat.model].contextWindow,
|
|
7649
|
-
onTaskStart: (t) => console.log(chalk27.cyan(` \u25B6 ${t.description}`)),
|
|
7650
|
-
onTaskComplete: (t) => console.log(chalk27.green(` \u2713 ${t.description}`)),
|
|
7651
|
-
onTaskFail: (t, e) => console.log(chalk27.red(` \u2717 ${t.description}: ${e}`))
|
|
7642
|
+
plan = await runRalphLoop(plan, model, toolCtx, config.projectRoot, {
|
|
7643
|
+
onTaskStart: (t) => console.log(chalk27.cyan(` \u25B6 ${t.title}`)),
|
|
7644
|
+
onTaskEnd: (t) => console.log(chalk27.green(` \u2713 ${t.title}`)),
|
|
7645
|
+
onText: (chunk) => process.stdout.write(chunk)
|
|
7652
7646
|
});
|
|
7653
|
-
await savePlan(config.projectRoot
|
|
7647
|
+
await savePlan(plan, config.projectRoot);
|
|
7654
7648
|
console.log(formatRalphStatus(plan));
|
|
7655
7649
|
} else if (subcommand === "status") {
|
|
7656
7650
|
const plan = await loadPlan(config.projectRoot);
|