@freesyntax/notch-cli 0.5.11 → 0.5.13
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 +53 -58
- 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
|
}
|
|
@@ -4301,7 +4301,7 @@ import os4 from "os";
|
|
|
4301
4301
|
import { execSync as execSync3 } from "child_process";
|
|
4302
4302
|
import chalk8 from "chalk";
|
|
4303
4303
|
var CACHE_FILE = path18.join(os4.homedir(), ".notch", "update-check.json");
|
|
4304
|
-
var CHECK_INTERVAL =
|
|
4304
|
+
var CHECK_INTERVAL = 0;
|
|
4305
4305
|
var PACKAGE_NAME = "@freesyntax/notch-cli";
|
|
4306
4306
|
var REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`;
|
|
4307
4307
|
async function checkForUpdates(currentVersion) {
|
|
@@ -6897,7 +6897,8 @@ Analyze the above input.`;
|
|
|
6897
6897
|
promptTokens: response.usage.promptTokens,
|
|
6898
6898
|
completionTokens: response.usage.completionTokens,
|
|
6899
6899
|
totalTokens: response.usage.totalTokens,
|
|
6900
|
-
|
|
6900
|
+
toolCalls: response.toolCallCount,
|
|
6901
|
+
iterations: response.iterations
|
|
6901
6902
|
});
|
|
6902
6903
|
costTracker.record(activeModelId, response.usage.promptTokens, response.usage.completionTokens);
|
|
6903
6904
|
console.log(usage.formatLast() + " " + costTracker.formatLastCost());
|
|
@@ -6942,7 +6943,7 @@ Analyze the above input.`;
|
|
|
6942
6943
|
if (messages.length > 0) {
|
|
6943
6944
|
try {
|
|
6944
6945
|
const name = getSessionName();
|
|
6945
|
-
const id = await saveSession(config.projectRoot,
|
|
6946
|
+
const id = await saveSession(messages, config.projectRoot, activeModelId);
|
|
6946
6947
|
console.log(chalk27.gray(` Session saved: ${id}${name ? ` (${name})` : ""}`));
|
|
6947
6948
|
} catch {
|
|
6948
6949
|
}
|
|
@@ -7068,7 +7069,7 @@ Analyze the above input.`;
|
|
|
7068
7069
|
} else {
|
|
7069
7070
|
for (const df of diffs) {
|
|
7070
7071
|
console.log(chalk27.cyan(` ${df.path}:`));
|
|
7071
|
-
console.log(unifiedDiff(df.before, df.after, df.path));
|
|
7072
|
+
console.log(unifiedDiff(df.before ?? "", df.after ?? "", df.path));
|
|
7072
7073
|
console.log("");
|
|
7073
7074
|
}
|
|
7074
7075
|
}
|
|
@@ -7076,12 +7077,11 @@ Analyze the above input.`;
|
|
|
7076
7077
|
return;
|
|
7077
7078
|
}
|
|
7078
7079
|
if (input.startsWith("/export")) {
|
|
7079
|
-
const exportPath = input.replace("/export", "").trim() ||
|
|
7080
|
+
const exportPath = input.replace("/export", "").trim() || "notch-export.md";
|
|
7080
7081
|
try {
|
|
7081
|
-
const ePath = await exportSession(messages, {
|
|
7082
|
+
const ePath = await exportSession(messages, exportPath, {
|
|
7082
7083
|
model: activeModelId,
|
|
7083
|
-
|
|
7084
|
-
outputPath: exportPath
|
|
7084
|
+
project: config.projectRoot
|
|
7085
7085
|
});
|
|
7086
7086
|
console.log(chalk27.green(` Exported to ${ePath}
|
|
7087
7087
|
`));
|
|
@@ -7094,7 +7094,7 @@ Analyze the above input.`;
|
|
|
7094
7094
|
}
|
|
7095
7095
|
if (input === "/save") {
|
|
7096
7096
|
try {
|
|
7097
|
-
const id = await saveSession(config.projectRoot,
|
|
7097
|
+
const id = await saveSession(messages, config.projectRoot, activeModelId);
|
|
7098
7098
|
sessionId = id;
|
|
7099
7099
|
console.log(chalk27.green(` Session saved: ${id}
|
|
7100
7100
|
`));
|
|
@@ -7107,13 +7107,13 @@ Analyze the above input.`;
|
|
|
7107
7107
|
}
|
|
7108
7108
|
if (input === "/sessions") {
|
|
7109
7109
|
try {
|
|
7110
|
-
const sessions = await listSessions(
|
|
7110
|
+
const sessions = await listSessions();
|
|
7111
7111
|
if (sessions.length === 0) {
|
|
7112
7112
|
console.log(chalk27.gray(" No saved sessions.\n"));
|
|
7113
7113
|
} else {
|
|
7114
7114
|
console.log(chalk27.gray("\n Saved sessions:\n"));
|
|
7115
7115
|
for (const s of sessions.slice(0, 10)) {
|
|
7116
|
-
console.log(chalk27.gray(` ${s.id} ${s.turns} turns ${s.
|
|
7116
|
+
console.log(chalk27.gray(` ${s.id} ${s.turns} turns ${s.updated} ${s.model}`));
|
|
7117
7117
|
}
|
|
7118
7118
|
console.log("");
|
|
7119
7119
|
}
|
|
@@ -7191,7 +7191,7 @@ Analyze the above input.`;
|
|
|
7191
7191
|
const task = input.replace("/plan ", "").trim();
|
|
7192
7192
|
const planSpinner = ora4("Generating plan...").start();
|
|
7193
7193
|
try {
|
|
7194
|
-
activePlan = await generatePlan(task, model,
|
|
7194
|
+
activePlan = await generatePlan(task, model, { cwd: config.projectRoot, repoMap: repoMapStr || void 0, history: messages });
|
|
7195
7195
|
planSpinner.succeed("Plan generated");
|
|
7196
7196
|
console.log(formatPlan(activePlan));
|
|
7197
7197
|
console.log(chalk27.gray(" Use /plan approve to execute, /plan edit to modify, or /plan cancel to discard.\n"));
|
|
@@ -7210,6 +7210,7 @@ Analyze the above input.`;
|
|
|
7210
7210
|
console.log(chalk27.green(" Executing plan...\n"));
|
|
7211
7211
|
while (!isPlanComplete(activePlan)) {
|
|
7212
7212
|
const stepPrompt = currentStepPrompt(activePlan);
|
|
7213
|
+
if (!stepPrompt) break;
|
|
7213
7214
|
messages.push({ role: "user", content: stepPrompt });
|
|
7214
7215
|
const planStepSpinner = ora4(`Step ${activePlan.currentStep + 1}/${activePlan.steps.length}...`).start();
|
|
7215
7216
|
try {
|
|
@@ -7234,7 +7235,7 @@ Analyze the above input.`;
|
|
|
7234
7235
|
console.log("\n");
|
|
7235
7236
|
messages.length = 0;
|
|
7236
7237
|
messages.push(...response.messages);
|
|
7237
|
-
|
|
7238
|
+
advancePlan(activePlan);
|
|
7238
7239
|
} catch (err) {
|
|
7239
7240
|
planStepSpinner.fail(`Step failed: ${err.message}`);
|
|
7240
7241
|
break;
|
|
@@ -7267,36 +7268,36 @@ Analyze the above input.`;
|
|
|
7267
7268
|
}
|
|
7268
7269
|
if (input.startsWith("/agent ")) {
|
|
7269
7270
|
const task = input.replace("/agent ", "").trim();
|
|
7270
|
-
const agentId = nextSubagentId();
|
|
7271
|
+
const agentId = nextSubagentId("general");
|
|
7271
7272
|
console.log(chalk27.cyan(` Spawning subagent #${agentId}: ${task}
|
|
7272
7273
|
`));
|
|
7273
7274
|
spawnSubagent({
|
|
7274
7275
|
id: agentId,
|
|
7275
|
-
|
|
7276
|
+
type: "general",
|
|
7277
|
+
prompt: task,
|
|
7276
7278
|
model,
|
|
7277
|
-
systemPrompt,
|
|
7278
7279
|
toolContext: toolCtx,
|
|
7279
|
-
|
|
7280
|
-
|
|
7281
|
-
|
|
7280
|
+
onStatus: (id, status) => {
|
|
7281
|
+
console.log(chalk27.gray(` [${id}] ${status}`));
|
|
7282
|
+
}
|
|
7283
|
+
}).then((result) => {
|
|
7284
|
+
console.log(chalk27.green(`
|
|
7282
7285
|
Subagent #${agentId} finished:`));
|
|
7283
|
-
|
|
7286
|
+
console.log(chalk27.gray(` ${result.text.slice(0, 200)}
|
|
7284
7287
|
`));
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
|
|
7288
|
-
|
|
7289
|
-
Subagent #${agentId} failed: ${err}
|
|
7288
|
+
rl.prompt();
|
|
7289
|
+
}).catch((err) => {
|
|
7290
|
+
console.log(chalk27.red(`
|
|
7291
|
+
Subagent #${agentId} failed: ${err.message}
|
|
7290
7292
|
`));
|
|
7291
|
-
|
|
7292
|
-
}
|
|
7293
|
+
rl.prompt();
|
|
7293
7294
|
});
|
|
7294
7295
|
rl.prompt();
|
|
7295
7296
|
return;
|
|
7296
7297
|
}
|
|
7297
7298
|
if (input === "/memory") {
|
|
7298
7299
|
try {
|
|
7299
|
-
const memories = await loadMemories(
|
|
7300
|
+
const memories = await loadMemories();
|
|
7300
7301
|
if (memories.length === 0) {
|
|
7301
7302
|
console.log(chalk27.gray(" No saved memories.\n"));
|
|
7302
7303
|
} else {
|
|
@@ -7318,7 +7319,7 @@ Analyze the above input.`;
|
|
|
7318
7319
|
if (input.startsWith("/memory search ")) {
|
|
7319
7320
|
const query = input.replace("/memory search ", "").trim();
|
|
7320
7321
|
try {
|
|
7321
|
-
const results = await searchMemories(
|
|
7322
|
+
const results = await searchMemories(query);
|
|
7322
7323
|
if (results.length === 0) {
|
|
7323
7324
|
console.log(chalk27.gray(` No memories matching "${query}"
|
|
7324
7325
|
`));
|
|
@@ -7337,9 +7338,9 @@ Analyze the above input.`;
|
|
|
7337
7338
|
}
|
|
7338
7339
|
if (input === "/memory clear") {
|
|
7339
7340
|
try {
|
|
7340
|
-
const memories = await loadMemories(
|
|
7341
|
+
const memories = await loadMemories();
|
|
7341
7342
|
for (const m of memories) {
|
|
7342
|
-
await deleteMemory(
|
|
7343
|
+
await deleteMemory(m.filename);
|
|
7343
7344
|
}
|
|
7344
7345
|
console.log(chalk27.yellow(` Cleared ${memories.length} memories.
|
|
7345
7346
|
`));
|
|
@@ -7360,8 +7361,8 @@ Analyze the above input.`;
|
|
|
7360
7361
|
const goal = input.replace("/ralph plan ", "").trim();
|
|
7361
7362
|
const planSpinner = ora4("Ralph is planning...").start();
|
|
7362
7363
|
try {
|
|
7363
|
-
ralphPlan = await generateRalphPlan(goal, model,
|
|
7364
|
-
await savePlan(config.projectRoot
|
|
7364
|
+
ralphPlan = await generateRalphPlan(goal, model, config.projectRoot);
|
|
7365
|
+
await savePlan(ralphPlan, config.projectRoot);
|
|
7365
7366
|
planSpinner.succeed(`Ralph planned ${ralphPlan.tasks.length} tasks`);
|
|
7366
7367
|
console.log(formatRalphStatus(ralphPlan));
|
|
7367
7368
|
} catch (err) {
|
|
@@ -7378,18 +7379,13 @@ Analyze the above input.`;
|
|
|
7378
7379
|
}
|
|
7379
7380
|
console.log(chalk27.green(" Ralph is running...\n"));
|
|
7380
7381
|
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}
|
|
7382
|
+
ralphPlan = await runRalphLoop(ralphPlan, model, toolCtx, config.projectRoot, {
|
|
7383
|
+
onTaskStart: (task) => console.log(chalk27.cyan(` \u25B6 Task: ${task.title}`)),
|
|
7384
|
+
onTaskEnd: (task) => console.log(chalk27.green(` \u2713 Done: ${task.title}
|
|
7388
7385
|
`)),
|
|
7389
|
-
|
|
7390
|
-
`))
|
|
7386
|
+
onText: (chunk) => process.stdout.write(chunk)
|
|
7391
7387
|
});
|
|
7392
|
-
await savePlan(config.projectRoot
|
|
7388
|
+
await savePlan(ralphPlan, config.projectRoot);
|
|
7393
7389
|
console.log(formatRalphStatus(ralphPlan));
|
|
7394
7390
|
} catch (err) {
|
|
7395
7391
|
console.log(chalk27.red(` Ralph error: ${err.message}
|
|
@@ -7565,7 +7561,8 @@ Analyze the above input.`;
|
|
|
7565
7561
|
promptTokens: response.usage.promptTokens,
|
|
7566
7562
|
completionTokens: response.usage.completionTokens,
|
|
7567
7563
|
totalTokens: response.usage.totalTokens,
|
|
7568
|
-
|
|
7564
|
+
toolCalls: response.toolCallCount,
|
|
7565
|
+
iterations: response.iterations
|
|
7569
7566
|
});
|
|
7570
7567
|
costTracker.record(activeModelId, response.usage.promptTokens, response.usage.completionTokens);
|
|
7571
7568
|
console.log(usage.formatLast() + " " + costTracker.formatLastCost());
|
|
@@ -7583,8 +7580,10 @@ Analyze the above input.`;
|
|
|
7583
7580
|
const memMatch = lastText.match(/\[(?:MEMORY|memory):\s*([^\]]+)\]/);
|
|
7584
7581
|
if (memMatch) {
|
|
7585
7582
|
try {
|
|
7586
|
-
await saveMemory(
|
|
7587
|
-
|
|
7583
|
+
await saveMemory({
|
|
7584
|
+
name: "auto-saved",
|
|
7585
|
+
description: memMatch[1].slice(0, 80),
|
|
7586
|
+
type: "project",
|
|
7588
7587
|
content: memMatch[1]
|
|
7589
7588
|
});
|
|
7590
7589
|
console.log(chalk27.gray(" (Saved to memory)\n"));
|
|
@@ -7631,8 +7630,8 @@ async function handleRalphSubcommand(args, cliOpts) {
|
|
|
7631
7630
|
process.exit(1);
|
|
7632
7631
|
}
|
|
7633
7632
|
const spinner = ora4("Ralph is planning...").start();
|
|
7634
|
-
const plan = await generateRalphPlan(goal, model,
|
|
7635
|
-
await savePlan(config.projectRoot
|
|
7633
|
+
const plan = await generateRalphPlan(goal, model, config.projectRoot);
|
|
7634
|
+
await savePlan(plan, config.projectRoot);
|
|
7636
7635
|
spinner.succeed(`Planned ${plan.tasks.length} tasks`);
|
|
7637
7636
|
console.log(formatRalphStatus(plan));
|
|
7638
7637
|
} else if (subcommand === "run") {
|
|
@@ -7641,16 +7640,12 @@ async function handleRalphSubcommand(args, cliOpts) {
|
|
|
7641
7640
|
console.error(chalk27.red(" No plan found. Run: notch ralph plan <goal>"));
|
|
7642
7641
|
process.exit(1);
|
|
7643
7642
|
}
|
|
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}`))
|
|
7643
|
+
plan = await runRalphLoop(plan, model, toolCtx, config.projectRoot, {
|
|
7644
|
+
onTaskStart: (t) => console.log(chalk27.cyan(` \u25B6 ${t.title}`)),
|
|
7645
|
+
onTaskEnd: (t) => console.log(chalk27.green(` \u2713 ${t.title}`)),
|
|
7646
|
+
onText: (chunk) => process.stdout.write(chunk)
|
|
7652
7647
|
});
|
|
7653
|
-
await savePlan(config.projectRoot
|
|
7648
|
+
await savePlan(plan, config.projectRoot);
|
|
7654
7649
|
console.log(formatRalphStatus(plan));
|
|
7655
7650
|
} else if (subcommand === "status") {
|
|
7656
7651
|
const plan = await loadPlan(config.projectRoot);
|