@wrongstack/cli 0.6.6 → 0.7.0
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 +216 -32
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import * as path23 from 'path';
|
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import * as fsp2 from 'fs/promises';
|
|
5
5
|
import { readdir, readFile } from 'fs/promises';
|
|
6
|
-
import { color, DefaultPathResolver, TOKENS, DefaultSystemPromptBuilder, makeAutonomyPromptContributor, ToolRegistry, createContextManagerTool, EventBus, SlashCommandRegistry, createDelegateTool, FLEET_ROSTER, createMcpControlTool, EternalAutonomyEngine, DefaultLogger, DefaultModelsRegistry, ProviderRegistry, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, RecoveryLock, DefaultAttachmentStore, QueueStore, Context, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, loadPlan, createDefaultPipelines, AutoCompactionMiddleware, estimateRequestTokens, Agent, loadPlugins, FleetManager, makeDirectorSessionFactory, Director, makeAgentSubagentRunner, NULL_FLEET_BUS, resolveWstackPaths, DefaultSecretVault, migratePlaintextSecrets, DefaultConfigLoader, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, atomicWrite, DefaultPluginAPI, AutoApprovePermissionPolicy, formatContextWindowModeList, repairToolUseAdjacency, getContextWindowMode, resolveContextWindowPolicy, formatTodosList, emptyPlan, clearPlan, savePlan, formatPlanTemplates, getPlanTemplate, addPlanItem, formatPlan, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, SpecStore, TaskGraphStore, analyzeCriticalPath, getTemplate, listTemplates, templateToMarkdown, SpecParser, renderSpecAnalysis, AISpecBuilder, DefaultTaskStore, TaskTracker, renderProgress, renderTaskGraph, loadGoal, goalFilePath, summarizeUsage, saveGoal, emptyGoal, buildGoalPreamble, formatGoal, InputBuilder, projectHash, defaultOrchestrator, decryptConfigSecrets, encryptConfigSecrets as encryptConfigSecrets$1, SpecVersioning, ParallelEternalEngine, allServers as allServers$1 } from '@wrongstack/core';
|
|
6
|
+
import { color, DefaultPathResolver, TOKENS, DefaultSystemPromptBuilder, makeAutonomyPromptContributor, ToolRegistry, createContextManagerTool, EventBus, SlashCommandRegistry, createDelegateTool, FLEET_ROSTER, createMcpControlTool, EternalAutonomyEngine, DefaultLogger, DefaultModelsRegistry, ProviderRegistry, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, RecoveryLock, DefaultAttachmentStore, QueueStore, Context, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, loadPlan, createDefaultPipelines, AutoCompactionMiddleware, estimateRequestTokens, Agent, loadPlugins, FleetManager, makeDirectorSessionFactory, Director, makeAgentSubagentRunner, NULL_FLEET_BUS, resolveWstackPaths, DefaultSecretVault, migratePlaintextSecrets, DefaultConfigLoader, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, atomicWrite, DefaultPluginAPI, AutoApprovePermissionPolicy, formatContextWindowModeList, repairToolUseAdjacency, getContextWindowMode, resolveContextWindowPolicy, formatTodosList, emptyPlan, clearPlan, savePlan, formatPlanTemplates, getPlanTemplate, addPlanItem, formatPlan, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, SpecStore, TaskGraphStore, analyzeCriticalPath, getTemplate, listTemplates, templateToMarkdown, SpecParser, renderSpecAnalysis, AISpecBuilder, DefaultTaskStore, TaskTracker, renderProgress, renderTaskGraph, loadGoal, goalFilePath, summarizeUsage, saveGoal, emptyGoal, buildGoalPreamble, formatGoal, InputBuilder, FsError, ERROR_CODES, projectHash, WrongStackError, defaultOrchestrator, decryptConfigSecrets, encryptConfigSecrets as encryptConfigSecrets$1, SpecVersioning, ParallelEternalEngine, allServers as allServers$1 } from '@wrongstack/core';
|
|
7
7
|
import { createRequire } from 'module';
|
|
8
8
|
import * as os6 from 'os';
|
|
9
9
|
import os6__default from 'os';
|
|
@@ -372,7 +372,7 @@ function getActiveBuilder() {
|
|
|
372
372
|
return sddState.getBuilder();
|
|
373
373
|
}
|
|
374
374
|
function buildSddCommand(opts) {
|
|
375
|
-
getSessionState(opts.context);
|
|
375
|
+
const sessionState = getSessionState(opts.context);
|
|
376
376
|
return {
|
|
377
377
|
name: "sdd",
|
|
378
378
|
description: "AI-driven SDD: /sdd [new|approve|execute|cancel|status|list|show|templates]",
|
|
@@ -395,7 +395,7 @@ function buildSddCommand(opts) {
|
|
|
395
395
|
case "create": {
|
|
396
396
|
const forceFlag = rest.includes("--force") || rest.includes("-f");
|
|
397
397
|
const title = rest.filter((a) => !a.startsWith("-")).join(" ").trim() || "Untitled Feature";
|
|
398
|
-
if (!
|
|
398
|
+
if (!sessionState.getBuilder() && !forceFlag) {
|
|
399
399
|
const sessionPath = path23.join(projectRoot, ".wrongstack", "sdd-session.json");
|
|
400
400
|
try {
|
|
401
401
|
await fsp2.access(sessionPath);
|
|
@@ -1030,6 +1030,14 @@ Start executing the tasks one by one.`
|
|
|
1030
1030
|
deletedFromDisk = true;
|
|
1031
1031
|
} catch {
|
|
1032
1032
|
}
|
|
1033
|
+
try {
|
|
1034
|
+
await fsp2.rm(path23.join(projectRoot, ".wrongstack", "specs"), { recursive: true, force: true });
|
|
1035
|
+
} catch {
|
|
1036
|
+
}
|
|
1037
|
+
try {
|
|
1038
|
+
await fsp2.rm(path23.join(projectRoot, ".wrongstack", "task-graphs"), { recursive: true, force: true });
|
|
1039
|
+
} catch {
|
|
1040
|
+
}
|
|
1033
1041
|
const cancelBuilder = sddState.getBuilder();
|
|
1034
1042
|
if (cancelBuilder) {
|
|
1035
1043
|
const title = cancelBuilder.getSession().title;
|
|
@@ -2745,7 +2753,16 @@ function entryId(ts) {
|
|
|
2745
2753
|
return ts.replace(/[:.]/g, "-").slice(0, 19);
|
|
2746
2754
|
}
|
|
2747
2755
|
async function ensureHistoryDir(homeFn = defaultHomeDir) {
|
|
2748
|
-
|
|
2756
|
+
try {
|
|
2757
|
+
await fsp2.mkdir(historyDir(homeFn), { recursive: true });
|
|
2758
|
+
} catch (err) {
|
|
2759
|
+
throw new FsError({
|
|
2760
|
+
message: err instanceof Error ? err.message : String(err),
|
|
2761
|
+
code: ERROR_CODES.FS_MKDIR_FAILED,
|
|
2762
|
+
path: historyDir(homeFn),
|
|
2763
|
+
cause: err
|
|
2764
|
+
});
|
|
2765
|
+
}
|
|
2749
2766
|
}
|
|
2750
2767
|
async function readIndex(homeFn = defaultHomeDir) {
|
|
2751
2768
|
try {
|
|
@@ -2757,7 +2774,16 @@ async function readIndex(homeFn = defaultHomeDir) {
|
|
|
2757
2774
|
}
|
|
2758
2775
|
async function writeIndex(idx, homeFn = defaultHomeDir) {
|
|
2759
2776
|
await ensureHistoryDir(homeFn);
|
|
2760
|
-
|
|
2777
|
+
try {
|
|
2778
|
+
await atomicWrite(historyIndexPath(homeFn), JSON.stringify(idx, null, 2));
|
|
2779
|
+
} catch (err) {
|
|
2780
|
+
throw new FsError({
|
|
2781
|
+
message: err instanceof Error ? err.message : String(err),
|
|
2782
|
+
code: ERROR_CODES.FS_ATOMIC_WRITE_FAILED,
|
|
2783
|
+
path: historyIndexPath(homeFn),
|
|
2784
|
+
cause: err
|
|
2785
|
+
});
|
|
2786
|
+
}
|
|
2761
2787
|
}
|
|
2762
2788
|
async function backupCurrent(homeFn = defaultHomeDir) {
|
|
2763
2789
|
const cfg = configPath(homeFn);
|
|
@@ -2802,11 +2828,20 @@ async function appendHistory(oldCfg, newCfg, description, homeFn = defaultHomeDi
|
|
|
2802
2828
|
snapshotMasked: maskConfigSecrets(newCfg),
|
|
2803
2829
|
diffSummary: diffSummary(oldCfg, newCfg)
|
|
2804
2830
|
};
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2831
|
+
try {
|
|
2832
|
+
await fsp2.writeFile(
|
|
2833
|
+
path23.join(historyDir(homeFn), `${id}.json`),
|
|
2834
|
+
JSON.stringify(entry, null, 2),
|
|
2835
|
+
"utf8"
|
|
2836
|
+
);
|
|
2837
|
+
} catch (err) {
|
|
2838
|
+
throw new FsError({
|
|
2839
|
+
message: err instanceof Error ? err.message : String(err),
|
|
2840
|
+
code: ERROR_CODES.FS_WRITE_FAILED,
|
|
2841
|
+
path: path23.join(historyDir(homeFn), `${id}.json`),
|
|
2842
|
+
cause: err
|
|
2843
|
+
});
|
|
2844
|
+
}
|
|
2810
2845
|
const idx = await readIndex(homeFn);
|
|
2811
2846
|
idx.entries.unshift({ id, timestamp, description });
|
|
2812
2847
|
await writeIndex(idx, homeFn);
|
|
@@ -3468,17 +3503,37 @@ function buildClearCommand(opts) {
|
|
|
3468
3503
|
};
|
|
3469
3504
|
}
|
|
3470
3505
|
async function runGit(args, cwd) {
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3506
|
+
try {
|
|
3507
|
+
return await new Promise((resolve4, reject) => {
|
|
3508
|
+
const child = spawn("git", args, {
|
|
3509
|
+
cwd,
|
|
3510
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
3511
|
+
});
|
|
3512
|
+
let stdout = "";
|
|
3513
|
+
let stderr = "";
|
|
3514
|
+
child.stdout?.on("data", (d) => stdout += d);
|
|
3515
|
+
child.stderr?.on("data", (d) => stderr += d);
|
|
3516
|
+
child.on("error", (err) => {
|
|
3517
|
+
reject(new WrongStackError({
|
|
3518
|
+
message: `Failed to run git: ${err.message}`,
|
|
3519
|
+
code: ERROR_CODES.TOOL_EXECUTION_FAILED,
|
|
3520
|
+
subsystem: "tool",
|
|
3521
|
+
context: { command: "git", args, cwd },
|
|
3522
|
+
cause: err
|
|
3523
|
+
}));
|
|
3524
|
+
});
|
|
3525
|
+
child.on("close", (code) => resolve4({ stdout, stderr, code: code ?? 0 }));
|
|
3475
3526
|
});
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3527
|
+
} catch (err) {
|
|
3528
|
+
if (err instanceof WrongStackError) throw err;
|
|
3529
|
+
throw new WrongStackError({
|
|
3530
|
+
message: err instanceof Error ? err.message : String(err),
|
|
3531
|
+
code: ERROR_CODES.TOOL_EXECUTION_FAILED,
|
|
3532
|
+
subsystem: "tool",
|
|
3533
|
+
context: { command: "git", args, cwd },
|
|
3534
|
+
cause: err
|
|
3535
|
+
});
|
|
3536
|
+
}
|
|
3482
3537
|
}
|
|
3483
3538
|
function detectCommitType(stats) {
|
|
3484
3539
|
const lines = stats.split("\n");
|
|
@@ -5497,8 +5552,17 @@ async function loadStatuslineConfig() {
|
|
|
5497
5552
|
}
|
|
5498
5553
|
async function saveStatuslineConfig(cfg) {
|
|
5499
5554
|
const p = resolveConfigPath();
|
|
5500
|
-
|
|
5501
|
-
|
|
5555
|
+
try {
|
|
5556
|
+
await fsp2.mkdir(path23.dirname(p), { recursive: true });
|
|
5557
|
+
await atomicWrite(p, JSON.stringify(cfg, null, 2));
|
|
5558
|
+
} catch (err) {
|
|
5559
|
+
throw new FsError({
|
|
5560
|
+
message: err instanceof Error ? err.message : String(err),
|
|
5561
|
+
code: err instanceof Error && err.message.includes("mkdir") ? ERROR_CODES.FS_MKDIR_FAILED : ERROR_CODES.FS_ATOMIC_WRITE_FAILED,
|
|
5562
|
+
path: p,
|
|
5563
|
+
cause: err
|
|
5564
|
+
});
|
|
5565
|
+
}
|
|
5502
5566
|
}
|
|
5503
5567
|
function buildStatuslineCommand(deps) {
|
|
5504
5568
|
return {
|
|
@@ -6700,6 +6764,7 @@ async function runProjectCheck(opts) {
|
|
|
6700
6764
|
const { spawn: spawn3 } = await import('child_process');
|
|
6701
6765
|
await new Promise((resolve4, reject) => {
|
|
6702
6766
|
const child = spawn3("git", ["init"], { cwd: projectRoot });
|
|
6767
|
+
child.on("error", reject);
|
|
6703
6768
|
child.on("close", (code) => code === 0 ? resolve4() : reject(new Error(`git init failed with ${code}`)));
|
|
6704
6769
|
});
|
|
6705
6770
|
renderer.write(` ${color.green("\u2713")} Git repository initialized
|
|
@@ -6915,6 +6980,85 @@ var TerminalRenderer = class {
|
|
|
6915
6980
|
this.out.write("\x1B[2J\x1B[H");
|
|
6916
6981
|
this.lineStart = true;
|
|
6917
6982
|
}
|
|
6983
|
+
/**
|
|
6984
|
+
* Write a flashy agent completion banner for delegate tool results.
|
|
6985
|
+
* Renders a box like:
|
|
6986
|
+
* ┌─────────────────────────────────────┐
|
|
6987
|
+
* │ ✓ [role] done in 4m 32s │
|
|
6988
|
+
* │ 127 iterations · 341 tools │
|
|
6989
|
+
* │ Found 14 bugs across 6 files... │
|
|
6990
|
+
* └─────────────────────────────────────┘
|
|
6991
|
+
*/
|
|
6992
|
+
writeAgentSummary(summary, ok) {
|
|
6993
|
+
if (this.silent) return;
|
|
6994
|
+
if (!this.lineStart) this.out.write("\n");
|
|
6995
|
+
const lines = summary.split("\n");
|
|
6996
|
+
const icon = ok ? theme2.success("\u2713") : theme2.error("\u2718");
|
|
6997
|
+
const firstLine = `${icon} ${lines[0] ?? summary}`;
|
|
6998
|
+
const body = lines.slice(1);
|
|
6999
|
+
const maxWidth = Math.min(process.stdout.columns ?? 80, 120);
|
|
7000
|
+
const contentWidth = Math.max(
|
|
7001
|
+
firstLine.length,
|
|
7002
|
+
body.reduce((a, l) => Math.max(a, l.length), 0)
|
|
7003
|
+
);
|
|
7004
|
+
const boxWidth = Math.min(Math.max(contentWidth + 4, 44), maxWidth);
|
|
7005
|
+
const thick = "\u2501".repeat(boxWidth - 2);
|
|
7006
|
+
const thin = "\u2500".repeat(boxWidth - 2);
|
|
7007
|
+
this.out.write(`
|
|
7008
|
+
${theme2.primary("\u250C")}${thick}${theme2.primary("\u2510")}
|
|
7009
|
+
`);
|
|
7010
|
+
const centre = (s) => {
|
|
7011
|
+
const inner = ` ${s} `;
|
|
7012
|
+
const padLen = Math.max(0, boxWidth - 2 - s.length);
|
|
7013
|
+
const left = Math.floor(padLen / 2);
|
|
7014
|
+
const right = padLen - left;
|
|
7015
|
+
return `${" ".repeat(left)}${inner}${" ".repeat(right)}`;
|
|
7016
|
+
};
|
|
7017
|
+
this.out.write(` ${theme2.primary("\u2502")}${centre(firstLine)}${theme2.primary("\u2502")}
|
|
7018
|
+
`);
|
|
7019
|
+
for (const l of body) {
|
|
7020
|
+
this.out.write(
|
|
7021
|
+
` ${theme2.primary("\u2502")} ${l}${" ".repeat(Math.max(0, boxWidth - 3 - l.length))}${theme2.primary("\u2502")}
|
|
7022
|
+
`
|
|
7023
|
+
);
|
|
7024
|
+
}
|
|
7025
|
+
this.out.write(` ${theme2.primary("\u2514")}${thin}${theme2.primary("\u2518")}
|
|
7026
|
+
`);
|
|
7027
|
+
this.lineStart = true;
|
|
7028
|
+
}
|
|
7029
|
+
/**
|
|
7030
|
+
* Render subagent completion banners from a RunResult.
|
|
7031
|
+
* Uses `delegateSummaries` when available (populated by delegate tool),
|
|
7032
|
+
* otherwise falls back to scanning message history.
|
|
7033
|
+
*/
|
|
7034
|
+
writeDelegateSummaries(result) {
|
|
7035
|
+
if (this.silent) return;
|
|
7036
|
+
if (result.delegateSummaries) {
|
|
7037
|
+
for (const { summary, ok } of result.delegateSummaries) {
|
|
7038
|
+
this.writeAgentSummary(summary, ok);
|
|
7039
|
+
}
|
|
7040
|
+
return;
|
|
7041
|
+
}
|
|
7042
|
+
if (!result.messages) return;
|
|
7043
|
+
for (const msg of result.messages) {
|
|
7044
|
+
const m = msg;
|
|
7045
|
+
if (!Array.isArray(m.content)) continue;
|
|
7046
|
+
for (const block of m.content) {
|
|
7047
|
+
const b = block;
|
|
7048
|
+
if (b.type !== "tool_result" || b.name !== "delegate") continue;
|
|
7049
|
+
let obj;
|
|
7050
|
+
try {
|
|
7051
|
+
obj = typeof b.content === "string" ? JSON.parse(b.content) : b.content;
|
|
7052
|
+
} catch {
|
|
7053
|
+
continue;
|
|
7054
|
+
}
|
|
7055
|
+
const o = obj;
|
|
7056
|
+
if (o.summary) {
|
|
7057
|
+
this.writeAgentSummary(o.summary, o.ok ?? true);
|
|
7058
|
+
}
|
|
7059
|
+
}
|
|
7060
|
+
}
|
|
7061
|
+
}
|
|
6918
7062
|
};
|
|
6919
7063
|
function renderMarkdown(s) {
|
|
6920
7064
|
let out = s;
|
|
@@ -7699,7 +7843,7 @@ var updateCmd = async (args, deps) => {
|
|
|
7699
7843
|
deps.renderer.write(`Updating wrongstack from v${info.current} to v${info.latest}...
|
|
7700
7844
|
`);
|
|
7701
7845
|
try {
|
|
7702
|
-
const result = await new Promise((resolve4) => {
|
|
7846
|
+
const result = await new Promise((resolve4, reject) => {
|
|
7703
7847
|
const child = spawn("npm", ["install", "-g", "wrongstack@latest"], {
|
|
7704
7848
|
cwd,
|
|
7705
7849
|
stdio: "pipe"
|
|
@@ -7708,6 +7852,7 @@ var updateCmd = async (args, deps) => {
|
|
|
7708
7852
|
child.stderr?.on("data", (d) => {
|
|
7709
7853
|
stderr += d;
|
|
7710
7854
|
});
|
|
7855
|
+
child.on("error", reject);
|
|
7711
7856
|
child.on("close", (code) => resolve4({ code: code ?? 0 }));
|
|
7712
7857
|
});
|
|
7713
7858
|
if (result.code === 0) {
|
|
@@ -9225,11 +9370,13 @@ async function runRepl(opts) {
|
|
|
9225
9370
|
await renderGoalBanner(opts);
|
|
9226
9371
|
let activeCtrl;
|
|
9227
9372
|
let interrupts = 0;
|
|
9373
|
+
let exiting = false;
|
|
9228
9374
|
const onSigint = () => {
|
|
9229
9375
|
interrupts++;
|
|
9230
9376
|
if (interrupts >= 2) {
|
|
9231
9377
|
opts.renderer.writeWarning("Exiting.");
|
|
9232
|
-
|
|
9378
|
+
exiting = true;
|
|
9379
|
+
return;
|
|
9233
9380
|
}
|
|
9234
9381
|
if (opts.getAutonomy?.() === "eternal" || opts.getAutonomy?.() === "eternal-parallel") {
|
|
9235
9382
|
opts.getEternalEngine?.()?.stop();
|
|
@@ -9250,6 +9397,7 @@ async function runRepl(opts) {
|
|
|
9250
9397
|
const builder = new InputBuilder({ store: opts.attachments });
|
|
9251
9398
|
try {
|
|
9252
9399
|
for (; ; ) {
|
|
9400
|
+
if (exiting) break;
|
|
9253
9401
|
if (opts.getAutonomy?.() === "eternal") {
|
|
9254
9402
|
const engine = opts.getEternalEngine?.();
|
|
9255
9403
|
if (!engine) {
|
|
@@ -9292,9 +9440,15 @@ async function runRepl(opts) {
|
|
|
9292
9440
|
} else {
|
|
9293
9441
|
const beforeGoal = await loadGoalSafe(opts);
|
|
9294
9442
|
const beforeIter = beforeGoal?.iterations ?? 0;
|
|
9443
|
+
const coord = engine.getCoordinator();
|
|
9444
|
+
if (coord) {
|
|
9445
|
+
const stats = coord.getStats();
|
|
9446
|
+
opts.renderer.write(
|
|
9447
|
+
color.dim(` \u250C\u2500 Fleet: ${stats.running} running, ${stats.idle} idle, ${stats.pending} pending, ${stats.completed} done`) + "\n"
|
|
9448
|
+
);
|
|
9449
|
+
}
|
|
9295
9450
|
opts.renderer.write(
|
|
9296
|
-
color.magenta(`
|
|
9297
|
-
\u21B3 [parallel #${beforeIter + 1}] launching fan-out\u2026
|
|
9451
|
+
color.magenta(` \u21B3 [parallel #${beforeIter + 1}] launching fan-out\u2026
|
|
9298
9452
|
`)
|
|
9299
9453
|
);
|
|
9300
9454
|
interrupts = 0;
|
|
@@ -9302,6 +9456,13 @@ async function runRepl(opts) {
|
|
|
9302
9456
|
const ok = await engine.runOneIteration();
|
|
9303
9457
|
const afterGoal = await loadGoalSafe(opts);
|
|
9304
9458
|
const last = afterGoal?.journal[afterGoal.journal.length - 1];
|
|
9459
|
+
if (coord) {
|
|
9460
|
+
const stats = coord.getStats();
|
|
9461
|
+
opts.renderer.write(
|
|
9462
|
+
color.dim(` \u2514\u2500 Fleet: ${stats.running} running, ${stats.idle} idle, ${stats.completed} done
|
|
9463
|
+
`)
|
|
9464
|
+
);
|
|
9465
|
+
}
|
|
9305
9466
|
if (last) {
|
|
9306
9467
|
const mark = last.status === "success" ? color.green("\u2713") : last.status === "failure" ? color.red("\u2717") : color.amber("\u2298");
|
|
9307
9468
|
const tail = last.note ? color.dim(` \u2014 ${last.note.slice(0, 80)}`) : "";
|
|
@@ -9653,9 +9814,17 @@ async function renderGoalBanner(opts) {
|
|
|
9653
9814
|
const goal = await loadGoalSafe(opts);
|
|
9654
9815
|
if (!goal) return;
|
|
9655
9816
|
const summary = goal.goal.length > 80 ? `${goal.goal.slice(0, 77)}\u2026` : goal.goal;
|
|
9817
|
+
const stateColor = goal.goalState === "active" ? color.green : goal.goalState === "paused" ? color.amber : goal.goalState === "completed" ? color.green : goal.goalState === "abandoned" ? color.dim : color.dim;
|
|
9656
9818
|
opts.renderer.write(
|
|
9657
|
-
color.dim("Goal: ") +
|
|
9819
|
+
color.dim("Goal: ") + stateColor(summary) + color.dim(` [${goal.goalState}] (iter ${goal.iterations})`) + "\n"
|
|
9658
9820
|
);
|
|
9821
|
+
if (goal.journal.length > 0) {
|
|
9822
|
+
const lastEntry = goal.journal[goal.journal.length - 1];
|
|
9823
|
+
const statusIcon2 = lastEntry.status === "success" ? "\u2713" : lastEntry.status === "failure" ? "\u2717" : lastEntry.status === "aborted" ? "\u2298" : lastEntry.status === "skipped" ? "\u229D" : "\xB7";
|
|
9824
|
+
opts.renderer.write(
|
|
9825
|
+
color.dim(` Last: ${statusIcon2} ${lastEntry.task} (${lastEntry.status})`) + "\n"
|
|
9826
|
+
);
|
|
9827
|
+
}
|
|
9659
9828
|
if (goal.engineState === "running") {
|
|
9660
9829
|
opts.renderer.write(
|
|
9661
9830
|
color.amber(" \u21BA Eternal engine was running when last session ended.") + "\n"
|
|
@@ -9680,6 +9849,18 @@ async function renderGoalBanner(opts) {
|
|
|
9680
9849
|
color.dim(" Use `/autonomy eternal` to resume.") + "\n"
|
|
9681
9850
|
);
|
|
9682
9851
|
}
|
|
9852
|
+
} else if (goal.goalState === "paused") {
|
|
9853
|
+
opts.renderer.write(
|
|
9854
|
+
color.amber(" \u23F8 Goal is paused. Use `/goal resume` to continue.") + "\n"
|
|
9855
|
+
);
|
|
9856
|
+
} else if (goal.goalState === "completed") {
|
|
9857
|
+
opts.renderer.write(
|
|
9858
|
+
color.green(" \u2713 Goal completed! Use `/goal clear` to set a new goal.") + "\n"
|
|
9859
|
+
);
|
|
9860
|
+
} else if (goal.goalState === "abandoned") {
|
|
9861
|
+
opts.renderer.write(
|
|
9862
|
+
color.dim(" Use `/goal clear` to set a new goal.") + "\n"
|
|
9863
|
+
);
|
|
9683
9864
|
}
|
|
9684
9865
|
opts.renderer.write("\n");
|
|
9685
9866
|
}
|
|
@@ -9855,6 +10036,8 @@ async function execute(deps) {
|
|
|
9855
10036
|
renderer.writeWarning(`Hit max iterations (${result.iterations}).`);
|
|
9856
10037
|
}
|
|
9857
10038
|
if (result.finalText) renderer.write("\n" + result.finalText + "\n");
|
|
10039
|
+
const r = result;
|
|
10040
|
+
renderer.writeDelegateSummaries(r);
|
|
9858
10041
|
renderer.write(
|
|
9859
10042
|
"\n" + color.dim(
|
|
9860
10043
|
`[in: ${fmtTok(usage.input)} out: ${fmtTok(usage.output)} iters: ${usage.iterations} cost: ${usage.cost.toFixed(4)} ${(usage.elapsedMs / 1e3).toFixed(1)}s]`
|
|
@@ -9919,6 +10102,7 @@ async function execute(deps) {
|
|
|
9919
10102
|
setStatuslineHiddenItems,
|
|
9920
10103
|
initialGoal: goalFlag,
|
|
9921
10104
|
initialAsk: askFlag,
|
|
10105
|
+
projectRoot,
|
|
9922
10106
|
getSDDContext: () => {
|
|
9923
10107
|
const { getActiveSDDContext: getActiveSDDContext2 } = (init_sdd(), __toCommonJS(sdd_exports));
|
|
9924
10108
|
return getActiveSDDContext2();
|
|
@@ -10258,8 +10442,7 @@ var MultiAgentHost = class {
|
|
|
10258
10442
|
}
|
|
10259
10443
|
subagentToolRegistry(allow) {
|
|
10260
10444
|
if (!allow || allow.length === 0) return this.deps.toolRegistry;
|
|
10261
|
-
const
|
|
10262
|
-
const sub = new cloneCtor();
|
|
10445
|
+
const sub = this.deps.toolRegistry.clone();
|
|
10263
10446
|
for (const t of this.filterTools(allow)) sub.register(t);
|
|
10264
10447
|
return sub;
|
|
10265
10448
|
}
|
|
@@ -12004,10 +12187,11 @@ Restart WrongStack to load or unload plugin code in this session.`;
|
|
|
12004
12187
|
onBeforeExit: async () => {
|
|
12005
12188
|
const { spawn: spawn3 } = await import('child_process');
|
|
12006
12189
|
const cwd2 = projectRoot;
|
|
12007
|
-
const statusResult = await new Promise((resolve4) => {
|
|
12190
|
+
const statusResult = await new Promise((resolve4, reject) => {
|
|
12008
12191
|
const child = spawn3("git", ["status", "--porcelain"], { cwd: cwd2, stdio: ["ignore", "pipe", "pipe"] });
|
|
12009
12192
|
let stdout = "";
|
|
12010
12193
|
child.stdout?.on("data", (d) => stdout += d);
|
|
12194
|
+
child.on("error", reject);
|
|
12011
12195
|
child.on("close", (code) => resolve4({ stdout, code: code ?? 0 }));
|
|
12012
12196
|
});
|
|
12013
12197
|
if (statusResult.stdout.trim().length > 0) {
|
|
@@ -12171,12 +12355,12 @@ if (isMain) {
|
|
|
12171
12355
|
main(process.argv.slice(2)).then(
|
|
12172
12356
|
(c) => {
|
|
12173
12357
|
process.exitCode = c;
|
|
12174
|
-
setTimeout(() => process.exit(c),
|
|
12358
|
+
setTimeout(() => process.exit(c), 500).unref();
|
|
12175
12359
|
},
|
|
12176
12360
|
(err) => {
|
|
12177
12361
|
process.stderr.write((err instanceof Error ? err.stack : String(err)) + "\n");
|
|
12178
12362
|
process.exitCode = 1;
|
|
12179
|
-
setTimeout(() => process.exit(1),
|
|
12363
|
+
setTimeout(() => process.exit(1), 500).unref();
|
|
12180
12364
|
}
|
|
12181
12365
|
);
|
|
12182
12366
|
}
|