@wrongstack/cli 0.306.4 → 0.307.1
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/{auth-L3WGSGDX.js → auth-TVOOHL4Q.js} +45 -106
- package/dist/boot/short-circuit-flags.d.ts +2 -2
- package/dist/chimera-cascade-evidence.d.ts +1 -1
- package/dist/chimera-reviewer-policy.d.ts +1 -1
- package/dist/chunk-2VMJ3E5Z.js +71 -0
- package/dist/{chunk-RHLQT3EV.js → chunk-CB35UVXO.js} +1636 -1528
- package/dist/{chunk-YKBRFSGL.js → chunk-DOJLAULS.js} +28 -28
- package/dist/{chunk-KXN5HZDL.js → chunk-PKHGLWUJ.js} +24 -6
- package/dist/{chunk-HITHEXE3.js → chunk-TOG7OMKJ.js} +2 -2
- package/dist/{chunk-ARWGQUB3.js → chunk-XSG33WHN.js} +15 -5
- package/dist/{cli-main-4TZCCZR6.js → cli-main-DD3I7KOO.js} +29198 -28411
- package/dist/cli-main.d.ts +0 -20
- package/dist/{execution-547PM3NI.js → execution-4ASWJ7EY.js} +309 -273
- package/dist/fleet/host-learning-scheduler.d.ts +27 -0
- package/dist/fleet/host-shadow-manager.d.ts +64 -0
- package/dist/fleet/host.d.ts +5 -140
- package/dist/{hq-ZK6PGN3W.js → hq-PA6RH2UW.js} +2 -2
- package/dist/hq-server/mailbox-gateway-manager.d.ts +32 -0
- package/dist/hq-server/routes/auth/bootstrap-routes.d.ts +5 -0
- package/dist/hq-server/routes/auth/common.d.ts +11 -0
- package/dist/hq-server/routes/auth/password-routes.d.ts +9 -0
- package/dist/hq-server/routes/auth/session-audit-routes.d.ts +6 -0
- package/dist/hq-server/routes/auth/totp-routes.d.ts +9 -0
- package/dist/hq-server/routes/auth-handlers.d.ts +5 -132
- package/dist/hq-server/routes/command-handlers.d.ts +7 -0
- package/dist/hq-server/routes/data-handlers.d.ts +8 -0
- package/dist/hq-server/routes/mailbox-handlers.d.ts +22 -0
- package/dist/hq-server/routes.d.ts +3 -3
- package/dist/hq-server/server-lifecycle.d.ts +37 -0
- package/dist/hq-server/snapshot.d.ts +6 -5
- package/dist/hq-server/types.d.ts +4 -0
- package/dist/hq-server/upgrade-handler.d.ts +34 -0
- package/dist/hq-server/ws-client-events.d.ts +25 -0
- package/dist/hq-server/ws-leader.d.ts +47 -0
- package/dist/hq-server/ws-resume.d.ts +27 -0
- package/dist/hq-server/ws.d.ts +4 -71
- package/dist/{hq-server-IVZLVCFV.js → hq-server-PBRU275L.js} +2 -2
- package/dist/hq-server.d.ts +0 -38
- package/dist/index.js +1267 -122
- package/dist/{mcp-W7HHN7IA.js → mcp-CMLFHRG2.js} +14 -7
- package/dist/mcp-serve.d.ts +12 -1
- package/dist/{modeldiag-6VS5KDP5.js → modeldiag-ICMPHT5L.js} +868 -831
- package/dist/{providers-models-HQN3AT3K.js → providers-models-4FAKM2WO.js} +4 -4
- package/dist/repl-eternal-loop.d.ts +8 -0
- package/dist/repl-goal-banner.d.ts +21 -0
- package/dist/slash-commands/brain-council.d.ts +36 -0
- package/dist/slash-commands/brain-status.d.ts +12 -0
- package/dist/slash-commands/kanban-board-handlers.d.ts +13 -0
- package/dist/slash-commands/kanban-lifecycle-diagnostics.d.ts +16 -0
- package/dist/slash-commands/kanban-task-subcommands.d.ts +8 -0
- package/dist/slash-commands/memory-audience.d.ts +14 -0
- package/dist/slash-commands/memory-gather.d.ts +9 -0
- package/dist/slash-commands/memory-stats.d.ts +5 -0
- package/dist/slash-commands/settings-mutations.d.ts +6 -0
- package/dist/slash-commands/settings-view.d.ts +5 -0
- package/dist/subcommands/handlers/modeldiag-bench.d.ts +10 -0
- package/dist/subcommands/handlers/modeldiag-eval.d.ts +27 -0
- package/dist/subcommands/handlers/modeldiag-test.d.ts +8 -0
- package/dist/{version-help-ASKQYXDJ.js → version-help-TFD6VPF3.js} +2 -2
- package/dist/vibe-protocol-wiring.d.ts +2 -0
- package/dist/webui-server/credential-watcher.d.ts +15 -0
- package/dist/webui-server/domain-handlers.d.ts +21 -0
- package/dist/webui-server/route-contexts.d.ts +41 -0
- package/dist/{webui-server-FTG7JAZU.js → webui-server-IPHGJGXE.js} +515 -437
- package/dist/wiring/cli-execute-builder.d.ts +88 -0
- package/dist/wiring/cli-heap-watchdog.d.ts +33 -0
- package/dist/wiring/cli-prompt-and-tools-setup.d.ts +25 -0
- package/dist/wiring/cli-slash-commands-setup.d.ts +79 -0
- package/dist/wiring/heap-watchdog-setup.d.ts +53 -0
- package/dist/wiring/metrics.d.ts +1 -0
- package/dist/wiring/prompt-journal-recorder.d.ts +45 -0
- package/dist/wiring/replay-governance-setup.d.ts +31 -0
- package/package.json +27 -27
|
@@ -29,27 +29,27 @@ import {
|
|
|
29
29
|
import {
|
|
30
30
|
theme
|
|
31
31
|
} from "./chunk-QD544J2B.js";
|
|
32
|
-
import {
|
|
33
|
-
fmtTok
|
|
34
|
-
} from "./chunk-TYO2OVAD.js";
|
|
35
32
|
import {
|
|
36
33
|
WEBUI_SESSION_CHILD_CAPABILITIES,
|
|
37
34
|
writeWebuiSessionChildError,
|
|
38
35
|
writeWebuiSessionChildReady
|
|
39
36
|
} from "./chunk-3JPTNADJ.js";
|
|
40
37
|
import {
|
|
41
|
-
|
|
42
|
-
} from "./chunk-
|
|
38
|
+
fmtTok
|
|
39
|
+
} from "./chunk-TYO2OVAD.js";
|
|
43
40
|
import {
|
|
44
41
|
terminalLink,
|
|
45
42
|
terminalText
|
|
46
43
|
} from "./chunk-KE7E7DPX.js";
|
|
47
44
|
import {
|
|
48
|
-
|
|
49
|
-
} from "./chunk-
|
|
45
|
+
CLI_VERSION
|
|
46
|
+
} from "./chunk-XJXDOF63.js";
|
|
50
47
|
import {
|
|
51
48
|
activeProfileConfigPath
|
|
52
49
|
} from "./chunk-YMXXOOFN.js";
|
|
50
|
+
import {
|
|
51
|
+
resolveActiveApiKey
|
|
52
|
+
} from "./chunk-SZ42FYPT.js";
|
|
53
53
|
import "./chunk-7OCVIDC7.js";
|
|
54
54
|
|
|
55
55
|
// src/execution.ts
|
|
@@ -205,7 +205,7 @@ async function runWebUIDispatch(ctx) {
|
|
|
205
205
|
const isSimpleUi = !isSessionChild && flags["simpleui"] === true;
|
|
206
206
|
agent.disableInteractiveConfirmation();
|
|
207
207
|
renderer.setSilent(true);
|
|
208
|
-
const { runWebUI } = await import("./webui-server-
|
|
208
|
+
const { runWebUI } = await import("./webui-server-IPHGJGXE.js");
|
|
209
209
|
const flagValue = (names) => {
|
|
210
210
|
for (const name of names) {
|
|
211
211
|
if (!Object.hasOwn(flags, name)) continue;
|
|
@@ -1318,7 +1318,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1318
1318
|
throw err;
|
|
1319
1319
|
}
|
|
1320
1320
|
writerSwapped = true;
|
|
1321
|
-
state.sessionRef
|
|
1321
|
+
if (state.sessionRef) state.sessionRef.current = resumed.writer;
|
|
1322
1322
|
await agent.ctx.flushConversationJournal().catch((err) => {
|
|
1323
1323
|
console.error(
|
|
1324
1324
|
JSON.stringify({
|
|
@@ -1358,30 +1358,31 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1358
1358
|
const targetProviderId = typeof meta.provider === "string" && meta.provider.length > 0 ? meta.provider : currentProviderId;
|
|
1359
1359
|
const targetModel = typeof meta.model === "string" && meta.model.length > 0 ? meta.model : agent.ctx.model;
|
|
1360
1360
|
if (switchProviderAndModel && targetProviderId && (targetProviderId !== currentProviderId || targetModel !== agent.ctx.model)) {
|
|
1361
|
-
|
|
1362
|
-
(
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
)
|
|
1373
|
-
|
|
1374
|
-
|
|
1361
|
+
try {
|
|
1362
|
+
await Promise.resolve(switchProviderAndModel(targetProviderId, targetModel));
|
|
1363
|
+
} catch (err) {
|
|
1364
|
+
console.error(
|
|
1365
|
+
JSON.stringify({
|
|
1366
|
+
level: "error",
|
|
1367
|
+
event: "execution.resume_model_restore_failed",
|
|
1368
|
+
provider: targetProviderId,
|
|
1369
|
+
model: targetModel,
|
|
1370
|
+
message: err instanceof Error ? err.message : String(err),
|
|
1371
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1372
|
+
})
|
|
1373
|
+
);
|
|
1374
|
+
}
|
|
1375
1375
|
} else if (targetModel !== agent.ctx.model) {
|
|
1376
1376
|
agent.ctx.model = targetModel;
|
|
1377
1377
|
}
|
|
1378
|
-
let
|
|
1378
|
+
let finalizeOldWriter;
|
|
1379
1379
|
if (oldWriter && oldWriter !== resumed.writer) {
|
|
1380
|
+
const staleWriter = oldWriter;
|
|
1380
1381
|
const endedUsage = tokenCounter.total();
|
|
1381
|
-
|
|
1382
|
+
finalizeOldWriter = async () => {
|
|
1382
1383
|
let appendOk = false;
|
|
1383
1384
|
try {
|
|
1384
|
-
await
|
|
1385
|
+
await staleWriter.append({
|
|
1385
1386
|
type: "session_end",
|
|
1386
1387
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1387
1388
|
usage: endedUsage
|
|
@@ -1399,7 +1400,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1399
1400
|
}
|
|
1400
1401
|
if (appendOk) {
|
|
1401
1402
|
try {
|
|
1402
|
-
await
|
|
1403
|
+
await staleWriter.close();
|
|
1403
1404
|
} catch (err) {
|
|
1404
1405
|
console.error(
|
|
1405
1406
|
JSON.stringify({
|
|
@@ -1411,7 +1412,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1411
1412
|
);
|
|
1412
1413
|
}
|
|
1413
1414
|
}
|
|
1414
|
-
}
|
|
1415
|
+
};
|
|
1415
1416
|
}
|
|
1416
1417
|
tokenCounter.reset();
|
|
1417
1418
|
tokenCounter.account(resumed.data.usage, targetModel, targetProviderId);
|
|
@@ -1424,7 +1425,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1424
1425
|
sessionId: resumed.writer.id,
|
|
1425
1426
|
contextSnapshot: { tokens, maxContext }
|
|
1426
1427
|
};
|
|
1427
|
-
void
|
|
1428
|
+
if (finalizeOldWriter) void finalizeOldWriter();
|
|
1428
1429
|
return result;
|
|
1429
1430
|
} catch (err) {
|
|
1430
1431
|
if (!identityClaimed) await resumeClaim?.cancel().catch(() => void 0);
|
|
@@ -2181,8 +2182,12 @@ var CHIMERA_REVIEW_READ_ONLY_TOOLS = Object.freeze([
|
|
|
2181
2182
|
"grep",
|
|
2182
2183
|
"glob",
|
|
2183
2184
|
"tree",
|
|
2185
|
+
"codebase-stats",
|
|
2184
2186
|
"codebase-search",
|
|
2185
|
-
"codebase-
|
|
2187
|
+
"codebase-skeleton",
|
|
2188
|
+
"codebase-repo-map",
|
|
2189
|
+
"codebase-incoming-calls",
|
|
2190
|
+
"codebase-outgoing-calls"
|
|
2186
2191
|
]);
|
|
2187
2192
|
function applyChimeraReviewerReadOnlyPolicy(config) {
|
|
2188
2193
|
return {
|
|
@@ -2750,18 +2755,26 @@ import { emitReviewIfChanged } from "@wrongstack/core/plugin";
|
|
|
2750
2755
|
|
|
2751
2756
|
// src/chimera-cascade-evidence.ts
|
|
2752
2757
|
import { spawn as spawn2 } from "node:child_process";
|
|
2753
|
-
var JSON_BLOCK_RE = /```json
|
|
2758
|
+
var JSON_BLOCK_RE = /```(?:json)?\s*([\s\S]*?)```/gi;
|
|
2759
|
+
function tryParseJson(raw) {
|
|
2760
|
+
try {
|
|
2761
|
+
return JSON.parse(raw);
|
|
2762
|
+
} catch {
|
|
2763
|
+
try {
|
|
2764
|
+
const cleaned = raw.replace(/,\s*([}\]])/g, "$1");
|
|
2765
|
+
return JSON.parse(cleaned);
|
|
2766
|
+
} catch {
|
|
2767
|
+
return null;
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2754
2771
|
function extractCascadeEvidence(text) {
|
|
2755
2772
|
if (!text) return null;
|
|
2756
2773
|
for (const match of text.matchAll(JSON_BLOCK_RE)) {
|
|
2757
2774
|
const body = match[1]?.trim();
|
|
2758
2775
|
if (!body) continue;
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
parsed = JSON.parse(body);
|
|
2762
|
-
} catch {
|
|
2763
|
-
continue;
|
|
2764
|
-
}
|
|
2776
|
+
const parsed = tryParseJson(body);
|
|
2777
|
+
if (!parsed) continue;
|
|
2765
2778
|
const evidence = parseEvidenceObject(parsed);
|
|
2766
2779
|
if (evidence) return evidence;
|
|
2767
2780
|
}
|
|
@@ -2822,7 +2835,7 @@ function isSafeCascadeCommand(command) {
|
|
|
2822
2835
|
const tokens = command.trim().split(/\s+/);
|
|
2823
2836
|
if (tokens.length === 0) return false;
|
|
2824
2837
|
if (!SAFE_EXECUTABLES.has(tokens[0])) return false;
|
|
2825
|
-
return tokens.every((token) => /^[A-Za-z0-9@/._
|
|
2838
|
+
return tokens.every((token) => /^[A-Za-z0-9@/._:=~+*?[\]-]+$/.test(token));
|
|
2826
2839
|
}
|
|
2827
2840
|
var runCascadeVerificationCommand = (command, cwd, timeoutMs) => {
|
|
2828
2841
|
if (!isSafeCascadeCommand(command)) {
|
|
@@ -3656,6 +3669,10 @@ function installChimeraReviewHandler({
|
|
|
3656
3669
|
const inScopeCited = citedFindings.filter((finding) => {
|
|
3657
3670
|
const citedKey = normalizeFileKeyForCitation(finding.location.file, p.cwd);
|
|
3658
3671
|
if (citedPaths.has(citedKey)) return true;
|
|
3672
|
+
const suffixMatches = [...citedPaths].filter(
|
|
3673
|
+
(cp) => cp.endsWith(`/${citedKey}`) || cp === citedKey
|
|
3674
|
+
);
|
|
3675
|
+
if (suffixMatches.length === 1) return true;
|
|
3659
3676
|
const basename7 = path11.basename(finding.location.file).toLowerCase();
|
|
3660
3677
|
const bucket = changedBasenameIndex.get(basename7);
|
|
3661
3678
|
return !!(bucket && bucket.length === 1);
|
|
@@ -3672,7 +3689,7 @@ function installChimeraReviewHandler({
|
|
|
3672
3689
|
const failedVerificationCount = inScopeCited.filter(
|
|
3673
3690
|
(finding) => finding.verification?.status === "failed"
|
|
3674
3691
|
).length;
|
|
3675
|
-
const effectiveHasFindings = reviewHasFindings && actionableFindings.length > 0;
|
|
3692
|
+
const effectiveHasFindings = reviewHasFindings && (actionableFindings.length > 0 || unverifiedInScope.length > 0);
|
|
3676
3693
|
const verifiedCount = actionableFindings.length;
|
|
3677
3694
|
const unverifiedCount = unverifiedInScope.length;
|
|
3678
3695
|
const hallucinationNote = droppedCitations.length > 0 ? `
|
|
@@ -3958,13 +3975,11 @@ async function predictNextTasks(input, opts) {
|
|
|
3958
3975
|
|
|
3959
3976
|
// src/repl.ts
|
|
3960
3977
|
import { detectContinueIntent, InputBuilder, resolveContinuation } from "@wrongstack/core/agent";
|
|
3961
|
-
import { goalFilePath, loadGoal, summarizeUsage } from "@wrongstack/core/goal";
|
|
3962
3978
|
import {
|
|
3963
|
-
color as
|
|
3979
|
+
color as color11,
|
|
3964
3980
|
estimateRequestTokensCalibrated as estimateRequestTokensCalibrated2,
|
|
3965
|
-
expectDefined,
|
|
3966
3981
|
hasOpenTodos as hasOpenTodos2,
|
|
3967
|
-
toErrorMessage
|
|
3982
|
+
toErrorMessage as toErrorMessage3
|
|
3968
3983
|
} from "@wrongstack/core/utils";
|
|
3969
3984
|
import { readClipboardImage, routeImagesForModel } from "@wrongstack/runtime";
|
|
3970
3985
|
import { createAutoProceedLoopGuard } from "@wrongstack/tools/auto-proceed-loop-guard";
|
|
@@ -4190,11 +4205,210 @@ function registerReplClient(opts) {
|
|
|
4190
4205
|
};
|
|
4191
4206
|
}
|
|
4192
4207
|
|
|
4208
|
+
// src/repl-eternal-loop.ts
|
|
4209
|
+
import { goalFilePath as goalFilePath2, summarizeUsage } from "@wrongstack/core/goal";
|
|
4210
|
+
import { color as color8, toErrorMessage as toErrorMessage2 } from "@wrongstack/core/utils";
|
|
4211
|
+
|
|
4212
|
+
// src/repl-goal-banner.ts
|
|
4213
|
+
import { goalFilePath, loadGoal } from "@wrongstack/core/goal";
|
|
4214
|
+
import { color as color7, expectDefined, toErrorMessage } from "@wrongstack/core/utils";
|
|
4215
|
+
async function loadGoalSafe(opts) {
|
|
4216
|
+
if (!opts.projectRoot) return null;
|
|
4217
|
+
try {
|
|
4218
|
+
return await loadGoal(goalFilePath(opts.projectRoot));
|
|
4219
|
+
} catch {
|
|
4220
|
+
return null;
|
|
4221
|
+
}
|
|
4222
|
+
}
|
|
4223
|
+
async function renderGoalBanner(opts) {
|
|
4224
|
+
const goal = await loadGoalSafe(opts);
|
|
4225
|
+
if (!goal) return;
|
|
4226
|
+
const summary = goal.goal.length > 80 ? `${goal.goal.slice(0, 77)}\u2026` : goal.goal;
|
|
4227
|
+
const stateColor = goal.goalState === "active" ? color7.green : goal.goalState === "paused" ? color7.amber : goal.goalState === "completed" ? color7.green : color7.dim;
|
|
4228
|
+
opts.renderer.write(
|
|
4229
|
+
color7.dim("Goal: ") + stateColor(summary) + color7.dim(` [${goal.goalState}] (iter ${goal.iterations})`) + "\n"
|
|
4230
|
+
);
|
|
4231
|
+
if (goal.journal.length > 0) {
|
|
4232
|
+
const lastEntry = expectDefined(goal.journal[goal.journal.length - 1]);
|
|
4233
|
+
const statusIcon = lastEntry.status === "success" ? "\u2713" : lastEntry.status === "failure" ? "\u2717" : lastEntry.status === "aborted" ? "\u2298" : lastEntry.status === "skipped" ? "\u229D" : "\xB7";
|
|
4234
|
+
opts.renderer.write(
|
|
4235
|
+
color7.dim(` Last: ${statusIcon} ${lastEntry.task} (${lastEntry.status})`) + "\n"
|
|
4236
|
+
);
|
|
4237
|
+
}
|
|
4238
|
+
if (goal.engineState === "running") {
|
|
4239
|
+
opts.renderer.write(
|
|
4240
|
+
color7.amber(" \u21BA Eternal engine was running when last session ended.") + "\n"
|
|
4241
|
+
);
|
|
4242
|
+
try {
|
|
4243
|
+
const answer = (await opts.reader.readLine(color7.dim(" Resume eternal mode? [y/N] "))).trim().toLowerCase();
|
|
4244
|
+
if (answer === "y" || answer === "yes") {
|
|
4245
|
+
try {
|
|
4246
|
+
await opts.slashRegistry.dispatch("/autonomy eternal", opts.agent.ctx);
|
|
4247
|
+
} catch (err) {
|
|
4248
|
+
opts.renderer.writeError(`Auto-resume failed: ${toErrorMessage(err)}`);
|
|
4249
|
+
}
|
|
4250
|
+
} else {
|
|
4251
|
+
opts.renderer.write(
|
|
4252
|
+
color7.dim(" Not resuming. Use `/autonomy eternal` later to continue.") + "\n"
|
|
4253
|
+
);
|
|
4254
|
+
}
|
|
4255
|
+
} catch {
|
|
4256
|
+
opts.renderer.write(color7.dim(" Use `/autonomy eternal` to resume.") + "\n");
|
|
4257
|
+
}
|
|
4258
|
+
} else if (goal.goalState === "paused") {
|
|
4259
|
+
opts.renderer.write(color7.amber(" \u23F8 Goal is paused. Use `/goal resume` to continue.") + "\n");
|
|
4260
|
+
} else if (goal.goalState === "completed") {
|
|
4261
|
+
opts.renderer.write(
|
|
4262
|
+
color7.green(" \u2713 Goal completed! Use `/goal clear` to set a new goal.") + "\n"
|
|
4263
|
+
);
|
|
4264
|
+
} else if (goal.goalState === "abandoned") {
|
|
4265
|
+
opts.renderer.write(color7.dim(" Use `/goal clear` to set a new goal.") + "\n");
|
|
4266
|
+
}
|
|
4267
|
+
opts.renderer.write("\n");
|
|
4268
|
+
}
|
|
4269
|
+
|
|
4270
|
+
// src/repl-eternal-loop.ts
|
|
4271
|
+
async function runReplEternalLoop(opts, onInterruptsReset) {
|
|
4272
|
+
const autonomy = opts.getAutonomy?.();
|
|
4273
|
+
if (autonomy === "eternal") {
|
|
4274
|
+
const engine = opts.getEternalEngine?.();
|
|
4275
|
+
if (!engine) {
|
|
4276
|
+
opts.renderer.writeWarning("Eternal mode set but no engine wired \u2014 falling back to off.");
|
|
4277
|
+
return false;
|
|
4278
|
+
}
|
|
4279
|
+
const beforeGoal = await loadGoalSafe(opts);
|
|
4280
|
+
const beforeIter = beforeGoal?.iterations ?? 0;
|
|
4281
|
+
opts.renderer.write(color8.dim(`
|
|
4282
|
+
\u21B3 [eternal #${beforeIter + 1}] running iteration\u2026
|
|
4283
|
+
`));
|
|
4284
|
+
onInterruptsReset();
|
|
4285
|
+
try {
|
|
4286
|
+
const ok = await engine.runOneIteration();
|
|
4287
|
+
const afterGoal = await loadGoalSafe(opts);
|
|
4288
|
+
const last = afterGoal?.journal[afterGoal.journal.length - 1];
|
|
4289
|
+
if (!ok && !last) {
|
|
4290
|
+
opts.renderer.write(color8.dim(" \u21B3 [eternal] iteration produced no progress.\n"));
|
|
4291
|
+
} else if (last) {
|
|
4292
|
+
const mark = last.status === "success" ? color8.green("\u2713") : last.status === "failure" ? color8.red("\u2717") : color8.amber("\u2298");
|
|
4293
|
+
const tail = last.note ? color8.dim(` \u2014 ${last.note.slice(0, 80)}`) : "";
|
|
4294
|
+
opts.renderer.write(
|
|
4295
|
+
` ${mark} ${color8.dim(`#${last.iteration}`)} ${color8.dim(`[${last.source}]`)} ${last.task}${tail}
|
|
4296
|
+
`
|
|
4297
|
+
);
|
|
4298
|
+
}
|
|
4299
|
+
if (engine.currentState === "stopped") {
|
|
4300
|
+
const goal = await loadGoalSafe(opts);
|
|
4301
|
+
if (goal?.goalState === "completed") {
|
|
4302
|
+
const u = goal.journal.length > 0 ? summarizeUsage(goal) : null;
|
|
4303
|
+
const costLine = u && u.iterationsWithUsage > 0 ? color8.dim(
|
|
4304
|
+
` \u2014 ${u.totalCostUsd.toFixed(4)} \xB7 ${u.totalInputTokens} in / ${u.totalOutputTokens} out \xB7 ${goal.iterations} iterations`
|
|
4305
|
+
) : goal.iterations > 0 ? color8.dim(` \u2014 ${goal.iterations} iterations`) : "";
|
|
4306
|
+
opts.renderer.write(
|
|
4307
|
+
color8.green(`
|
|
4308
|
+
\u{1F3AF} Goal completed!${costLine}
|
|
4309
|
+
|
|
4310
|
+
`) + color8.dim(" Goal cleared. Use /goal set <mission> to create a new goal.\n")
|
|
4311
|
+
);
|
|
4312
|
+
if (opts.projectRoot) {
|
|
4313
|
+
try {
|
|
4314
|
+
const { unlink } = await import("node:fs/promises");
|
|
4315
|
+
await unlink(goalFilePath2(opts.projectRoot));
|
|
4316
|
+
} catch {
|
|
4317
|
+
}
|
|
4318
|
+
}
|
|
4319
|
+
}
|
|
4320
|
+
opts.onAutonomy?.("auto");
|
|
4321
|
+
return true;
|
|
4322
|
+
}
|
|
4323
|
+
} catch (err) {
|
|
4324
|
+
opts.renderer.writeError(`[eternal] ${toErrorMessage2(err)}`);
|
|
4325
|
+
}
|
|
4326
|
+
await new Promise((resolve3) => setTimeout(resolve3, 250));
|
|
4327
|
+
return true;
|
|
4328
|
+
}
|
|
4329
|
+
if (autonomy === "eternal-parallel") {
|
|
4330
|
+
const engine = opts.getParallelEngine?.();
|
|
4331
|
+
if (!engine) {
|
|
4332
|
+
opts.renderer.writeWarning(
|
|
4333
|
+
"Parallel mode set but no engine wired \u2014 falling back to off."
|
|
4334
|
+
);
|
|
4335
|
+
return false;
|
|
4336
|
+
}
|
|
4337
|
+
const beforeGoal = await loadGoalSafe(opts);
|
|
4338
|
+
const beforeIter = beforeGoal?.iterations ?? 0;
|
|
4339
|
+
const coord = engine.getCoordinator();
|
|
4340
|
+
if (coord) {
|
|
4341
|
+
const stats = coord.getStats();
|
|
4342
|
+
opts.renderer.write(
|
|
4343
|
+
color8.dim(
|
|
4344
|
+
` \u250C\u2500 Fleet: ${stats.running} running, ${stats.idle} idle, ${stats.pending} pending, ${stats.completed} done`
|
|
4345
|
+
) + "\n"
|
|
4346
|
+
);
|
|
4347
|
+
}
|
|
4348
|
+
opts.renderer.write(
|
|
4349
|
+
color8.magenta(` \u21B3 [parallel #${beforeIter + 1}] launching fan-out\u2026
|
|
4350
|
+
`)
|
|
4351
|
+
);
|
|
4352
|
+
onInterruptsReset();
|
|
4353
|
+
try {
|
|
4354
|
+
await engine.runOneIteration();
|
|
4355
|
+
const afterGoal = await loadGoalSafe(opts);
|
|
4356
|
+
const last = afterGoal?.journal[afterGoal.journal.length - 1];
|
|
4357
|
+
if (coord) {
|
|
4358
|
+
const stats = coord.getStats();
|
|
4359
|
+
opts.renderer.write(
|
|
4360
|
+
color8.dim(
|
|
4361
|
+
` \u2514\u2500 Fleet: ${stats.running} running, ${stats.idle} idle, ${stats.completed} done
|
|
4362
|
+
`
|
|
4363
|
+
)
|
|
4364
|
+
);
|
|
4365
|
+
}
|
|
4366
|
+
if (last) {
|
|
4367
|
+
const mark = last.status === "success" ? color8.green("\u2713") : last.status === "failure" ? color8.red("\u2717") : color8.amber("\u2298");
|
|
4368
|
+
const tail = last.note ? color8.dim(` \u2014 ${last.note.slice(0, 80)}`) : "";
|
|
4369
|
+
opts.renderer.write(
|
|
4370
|
+
` ${mark} ${color8.dim(`#${last.iteration}`)} ${color8.dim(`[${last.source}]`)} ${last.task}${tail}
|
|
4371
|
+
`
|
|
4372
|
+
);
|
|
4373
|
+
}
|
|
4374
|
+
if (engine.currentState === "stopped") {
|
|
4375
|
+
const goal = await loadGoalSafe(opts);
|
|
4376
|
+
if (goal?.goalState === "completed") {
|
|
4377
|
+
const u = goal.journal.length > 0 ? summarizeUsage(goal) : null;
|
|
4378
|
+
const costLine = u && u.iterationsWithUsage > 0 ? color8.dim(
|
|
4379
|
+
` \u2014 ${u.totalCostUsd.toFixed(4)} \xB7 ${u.totalInputTokens} in / ${u.totalOutputTokens} out \xB7 ${goal.iterations} iterations`
|
|
4380
|
+
) : goal.iterations > 0 ? color8.dim(` \u2014 ${goal.iterations} iterations`) : "";
|
|
4381
|
+
opts.renderer.write(
|
|
4382
|
+
color8.green(`
|
|
4383
|
+
\u{1F3AF} Goal completed!${costLine}
|
|
4384
|
+
|
|
4385
|
+
`) + color8.dim(" Goal cleared. Use /goal set <mission> to create a new goal.\n")
|
|
4386
|
+
);
|
|
4387
|
+
if (opts.projectRoot) {
|
|
4388
|
+
try {
|
|
4389
|
+
const { unlink } = await import("node:fs/promises");
|
|
4390
|
+
await unlink(goalFilePath2(opts.projectRoot));
|
|
4391
|
+
} catch {
|
|
4392
|
+
}
|
|
4393
|
+
}
|
|
4394
|
+
}
|
|
4395
|
+
opts.onAutonomy?.("auto");
|
|
4396
|
+
return true;
|
|
4397
|
+
}
|
|
4398
|
+
} catch (err) {
|
|
4399
|
+
opts.renderer.writeError(`[parallel] ${toErrorMessage2(err)}`);
|
|
4400
|
+
}
|
|
4401
|
+
await new Promise((resolve3) => setTimeout(resolve3, 250));
|
|
4402
|
+
return true;
|
|
4403
|
+
}
|
|
4404
|
+
return false;
|
|
4405
|
+
}
|
|
4406
|
+
|
|
4193
4407
|
// src/repl-input.ts
|
|
4194
|
-
import { color as
|
|
4408
|
+
import { color as color9 } from "@wrongstack/core/utils";
|
|
4195
4409
|
async function readPossiblyMultiline(opts) {
|
|
4196
4410
|
const firstPrompt = theme.primary("\u203A ");
|
|
4197
|
-
const contPrompt =
|
|
4411
|
+
const contPrompt = color9.dim("\xB7 ");
|
|
4198
4412
|
const first = await opts.reader.readLine(firstPrompt);
|
|
4199
4413
|
if (first.trim() === '"""') {
|
|
4200
4414
|
const parts = [];
|
|
@@ -4219,7 +4433,7 @@ async function readPossiblyMultiline(opts) {
|
|
|
4219
4433
|
}
|
|
4220
4434
|
|
|
4221
4435
|
// src/repl-rendering.ts
|
|
4222
|
-
import { color as
|
|
4436
|
+
import { color as color10 } from "@wrongstack/core/utils";
|
|
4223
4437
|
var FILLED = "\u2588";
|
|
4224
4438
|
var EMPTY = "\u2591";
|
|
4225
4439
|
function renderContextChip(used, max) {
|
|
@@ -4236,13 +4450,13 @@ function renderProgress(ratio, width) {
|
|
|
4236
4450
|
}
|
|
4237
4451
|
function printBanner(renderer, projectName) {
|
|
4238
4452
|
const lines = [
|
|
4239
|
-
theme.primary(theme.bold("WrongStack")) +
|
|
4240
|
-
|
|
4453
|
+
theme.primary(theme.bold("WrongStack")) + color10.dim(` v${CLI_VERSION}`),
|
|
4454
|
+
color10.dim("Built on the wrong stack. Shipped anyway.")
|
|
4241
4455
|
];
|
|
4242
4456
|
if (projectName && projectName.length > 0) {
|
|
4243
|
-
lines.push(
|
|
4457
|
+
lines.push(color10.dim("Project: ") + theme.bold(projectName));
|
|
4244
4458
|
}
|
|
4245
|
-
lines.push(
|
|
4459
|
+
lines.push(color10.dim("Type /help for commands, /exit or q to quit."), "");
|
|
4246
4460
|
renderer.write(`${lines.join("\n")}
|
|
4247
4461
|
`);
|
|
4248
4462
|
}
|
|
@@ -4311,144 +4525,21 @@ async function runRepl(opts) {
|
|
|
4311
4525
|
try {
|
|
4312
4526
|
for (; ; ) {
|
|
4313
4527
|
if (exiting) break;
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
opts.renderer.writeWarning("Eternal mode set but no engine wired \u2014 falling back to off.");
|
|
4318
|
-
} else {
|
|
4319
|
-
const beforeGoal = await loadGoalSafe(opts);
|
|
4320
|
-
const beforeIter = beforeGoal?.iterations ?? 0;
|
|
4321
|
-
opts.renderer.write(color9.dim(`
|
|
4322
|
-
\u21B3 [eternal #${beforeIter + 1}] running iteration\u2026
|
|
4323
|
-
`));
|
|
4528
|
+
const autonomy = opts.getAutonomy?.();
|
|
4529
|
+
if (autonomy === "eternal" || autonomy === "eternal-parallel") {
|
|
4530
|
+
const handled = await runReplEternalLoop(opts, () => {
|
|
4324
4531
|
interrupts = 0;
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
const afterGoal = await loadGoalSafe(opts);
|
|
4328
|
-
const last = afterGoal?.journal[afterGoal.journal.length - 1];
|
|
4329
|
-
if (!ok && !last) {
|
|
4330
|
-
opts.renderer.write(color9.dim(" \u21B3 [eternal] iteration produced no progress.\n"));
|
|
4331
|
-
} else if (last) {
|
|
4332
|
-
const mark = last.status === "success" ? color9.green("\u2713") : last.status === "failure" ? color9.red("\u2717") : color9.amber("\u2298");
|
|
4333
|
-
const tail = last.note ? color9.dim(` \u2014 ${last.note.slice(0, 80)}`) : "";
|
|
4334
|
-
opts.renderer.write(
|
|
4335
|
-
` ${mark} ${color9.dim(`#${last.iteration}`)} ${color9.dim(`[${last.source}]`)} ${last.task}${tail}
|
|
4336
|
-
`
|
|
4337
|
-
);
|
|
4338
|
-
}
|
|
4339
|
-
if (engine.currentState === "stopped") {
|
|
4340
|
-
const goal = await loadGoalSafe(opts);
|
|
4341
|
-
if (goal?.goalState === "completed") {
|
|
4342
|
-
const u = goal.journal.length > 0 ? summarizeUsage(goal) : null;
|
|
4343
|
-
const costLine = u && u.iterationsWithUsage > 0 ? color9.dim(
|
|
4344
|
-
` \u2014 ${u.totalCostUsd.toFixed(4)} \xB7 ${u.totalInputTokens} in / ${u.totalOutputTokens} out \xB7 ${goal.iterations} iterations`
|
|
4345
|
-
) : goal.iterations > 0 ? color9.dim(` \u2014 ${goal.iterations} iterations`) : "";
|
|
4346
|
-
opts.renderer.write(
|
|
4347
|
-
color9.green(`
|
|
4348
|
-
\u{1F3AF} Goal completed!${costLine}
|
|
4349
|
-
|
|
4350
|
-
`) + color9.dim(" Goal cleared. Use /goal set <mission> to create a new goal.\n")
|
|
4351
|
-
);
|
|
4352
|
-
if (opts.projectRoot) {
|
|
4353
|
-
try {
|
|
4354
|
-
const { unlink } = await import("node:fs/promises");
|
|
4355
|
-
await unlink(goalFilePath(opts.projectRoot));
|
|
4356
|
-
} catch {
|
|
4357
|
-
}
|
|
4358
|
-
}
|
|
4359
|
-
}
|
|
4360
|
-
opts.onAutonomy?.("auto");
|
|
4361
|
-
continue;
|
|
4362
|
-
}
|
|
4363
|
-
} catch (err) {
|
|
4364
|
-
opts.renderer.writeError(`[eternal] ${toErrorMessage(err)}`);
|
|
4365
|
-
}
|
|
4366
|
-
await new Promise((resolve3) => setTimeout(resolve3, 250));
|
|
4367
|
-
continue;
|
|
4368
|
-
}
|
|
4369
|
-
} else if (opts.getAutonomy?.() === "eternal-parallel") {
|
|
4370
|
-
const engine = opts.getParallelEngine?.();
|
|
4371
|
-
if (!engine) {
|
|
4372
|
-
opts.renderer.writeWarning(
|
|
4373
|
-
"Parallel mode set but no engine wired \u2014 falling back to off."
|
|
4374
|
-
);
|
|
4375
|
-
} else {
|
|
4376
|
-
const beforeGoal = await loadGoalSafe(opts);
|
|
4377
|
-
const beforeIter = beforeGoal?.iterations ?? 0;
|
|
4378
|
-
const coord = engine.getCoordinator();
|
|
4379
|
-
if (coord) {
|
|
4380
|
-
const stats = coord.getStats();
|
|
4381
|
-
opts.renderer.write(
|
|
4382
|
-
color9.dim(
|
|
4383
|
-
` \u250C\u2500 Fleet: ${stats.running} running, ${stats.idle} idle, ${stats.pending} pending, ${stats.completed} done`
|
|
4384
|
-
) + "\n"
|
|
4385
|
-
);
|
|
4386
|
-
}
|
|
4387
|
-
opts.renderer.write(
|
|
4388
|
-
color9.magenta(` \u21B3 [parallel #${beforeIter + 1}] launching fan-out\u2026
|
|
4389
|
-
`)
|
|
4390
|
-
);
|
|
4391
|
-
interrupts = 0;
|
|
4392
|
-
try {
|
|
4393
|
-
await engine.runOneIteration();
|
|
4394
|
-
const afterGoal = await loadGoalSafe(opts);
|
|
4395
|
-
const last = afterGoal?.journal[afterGoal.journal.length - 1];
|
|
4396
|
-
if (coord) {
|
|
4397
|
-
const stats = coord.getStats();
|
|
4398
|
-
opts.renderer.write(
|
|
4399
|
-
color9.dim(
|
|
4400
|
-
` \u2514\u2500 Fleet: ${stats.running} running, ${stats.idle} idle, ${stats.completed} done
|
|
4401
|
-
`
|
|
4402
|
-
)
|
|
4403
|
-
);
|
|
4404
|
-
}
|
|
4405
|
-
if (last) {
|
|
4406
|
-
const mark = last.status === "success" ? color9.green("\u2713") : last.status === "failure" ? color9.red("\u2717") : color9.amber("\u2298");
|
|
4407
|
-
const tail = last.note ? color9.dim(` \u2014 ${last.note.slice(0, 80)}`) : "";
|
|
4408
|
-
opts.renderer.write(
|
|
4409
|
-
` ${mark} ${color9.dim(`#${last.iteration}`)} ${color9.dim(`[${last.source}]`)} ${last.task}${tail}
|
|
4410
|
-
`
|
|
4411
|
-
);
|
|
4412
|
-
}
|
|
4413
|
-
if (engine.currentState === "stopped") {
|
|
4414
|
-
const goal = await loadGoalSafe(opts);
|
|
4415
|
-
if (goal?.goalState === "completed") {
|
|
4416
|
-
const u = goal.journal.length > 0 ? summarizeUsage(goal) : null;
|
|
4417
|
-
const costLine = u && u.iterationsWithUsage > 0 ? color9.dim(
|
|
4418
|
-
` \u2014 ${u.totalCostUsd.toFixed(4)} \xB7 ${u.totalInputTokens} in / ${u.totalOutputTokens} out \xB7 ${goal.iterations} iterations`
|
|
4419
|
-
) : goal.iterations > 0 ? color9.dim(` \u2014 ${goal.iterations} iterations`) : "";
|
|
4420
|
-
opts.renderer.write(
|
|
4421
|
-
color9.green(`
|
|
4422
|
-
\u{1F3AF} Goal completed!${costLine}
|
|
4423
|
-
|
|
4424
|
-
`) + color9.dim(" Goal cleared. Use /goal set <mission> to create a new goal.\n")
|
|
4425
|
-
);
|
|
4426
|
-
if (opts.projectRoot) {
|
|
4427
|
-
try {
|
|
4428
|
-
const { unlink } = await import("node:fs/promises");
|
|
4429
|
-
await unlink(goalFilePath(opts.projectRoot));
|
|
4430
|
-
} catch {
|
|
4431
|
-
}
|
|
4432
|
-
}
|
|
4433
|
-
}
|
|
4434
|
-
opts.onAutonomy?.("auto");
|
|
4435
|
-
continue;
|
|
4436
|
-
}
|
|
4437
|
-
} catch (err) {
|
|
4438
|
-
opts.renderer.writeError(`[parallel] ${toErrorMessage(err)}`);
|
|
4439
|
-
}
|
|
4440
|
-
await new Promise((resolve3) => setTimeout(resolve3, 250));
|
|
4441
|
-
continue;
|
|
4442
|
-
}
|
|
4532
|
+
});
|
|
4533
|
+
if (handled) continue;
|
|
4443
4534
|
}
|
|
4444
4535
|
{
|
|
4445
4536
|
const mode = opts.getAutonomy?.() ?? "off";
|
|
4446
4537
|
const suggestions = opts.getSuggestions?.() ?? [];
|
|
4447
4538
|
if (mode === "suggest" && suggestions.length > 0) {
|
|
4448
|
-
const lines = suggestions.map((s, i) => ` ${
|
|
4539
|
+
const lines = suggestions.map((s, i) => ` ${color11.bold(`${i + 1}.`)} ${color11.dim(s)}`);
|
|
4449
4540
|
opts.renderer.write(
|
|
4450
4541
|
`
|
|
4451
|
-
${
|
|
4542
|
+
${color11.cyan(" \u{1F4A1} Suggested next steps")} ${color11.dim("(use /next 1, /next 2, or /next 1 2 3)")}
|
|
4452
4543
|
${lines.join("\n")}
|
|
4453
4544
|
|
|
4454
4545
|
`
|
|
@@ -4482,8 +4573,7 @@ ${lines.join("\n")}
|
|
|
4482
4573
|
}
|
|
4483
4574
|
}
|
|
4484
4575
|
}
|
|
4485
|
-
if (
|
|
4486
|
-
} else {
|
|
4576
|
+
if (top) {
|
|
4487
4577
|
const maxAuto = opts.autoProceedMaxIterations ?? DEFAULT_MAX_CONSECUTIVE_AUTO_PROCEED;
|
|
4488
4578
|
if (maxAuto > 0 && autoIterCount >= maxAuto) {
|
|
4489
4579
|
if (!autoCapWarned) {
|
|
@@ -4536,7 +4626,7 @@ ${lines.join("\n")}
|
|
|
4536
4626
|
autoCapWarned = false;
|
|
4537
4627
|
autoProceedLoopGuard.reset();
|
|
4538
4628
|
if (trimmed === "q") {
|
|
4539
|
-
opts.renderer.write(
|
|
4629
|
+
opts.renderer.write(color11.dim(" Goodbye!\n"));
|
|
4540
4630
|
break;
|
|
4541
4631
|
}
|
|
4542
4632
|
if (trimmed === "wd" || trimmed.startsWith("cd ")) {
|
|
@@ -4546,7 +4636,7 @@ ${lines.join("\n")}
|
|
|
4546
4636
|
if (res?.message) opts.renderer.write(`${res.message}
|
|
4547
4637
|
`);
|
|
4548
4638
|
} catch (err) {
|
|
4549
|
-
opts.renderer.writeError(
|
|
4639
|
+
opts.renderer.writeError(toErrorMessage3(err));
|
|
4550
4640
|
}
|
|
4551
4641
|
continue;
|
|
4552
4642
|
}
|
|
@@ -4578,14 +4668,14 @@ ${lines.join("\n")}
|
|
|
4578
4668
|
if (specSaved) {
|
|
4579
4669
|
opts.renderer.write(
|
|
4580
4670
|
`
|
|
4581
|
-
${
|
|
4671
|
+
${color11.cyan(" \u2713 Spec detected and saved! Use /sdd approve to continue.")}
|
|
4582
4672
|
`
|
|
4583
4673
|
);
|
|
4584
4674
|
}
|
|
4585
4675
|
const planSaved = trySaveImplementationPlan(runResult.finalText);
|
|
4586
4676
|
if (planSaved) {
|
|
4587
4677
|
opts.renderer.write(`
|
|
4588
|
-
${
|
|
4678
|
+
${color11.cyan(" \u2713 Implementation plan saved!")}
|
|
4589
4679
|
`);
|
|
4590
4680
|
}
|
|
4591
4681
|
const tasksSaved = await trySaveTasksFromAIOutput(runResult.finalText);
|
|
@@ -4594,7 +4684,7 @@ ${color9.cyan(" \u2713 Implementation plan saved!")}
|
|
|
4594
4684
|
const count = progress?.total ?? 0;
|
|
4595
4685
|
opts.renderer.write(
|
|
4596
4686
|
`
|
|
4597
|
-
${
|
|
4687
|
+
${color11.cyan(` \u2713 ${count} tasks detected and saved! Use /sdd approve to execute.`)}
|
|
4598
4688
|
`
|
|
4599
4689
|
);
|
|
4600
4690
|
}
|
|
@@ -4606,13 +4696,13 @@ ${color9.cyan(` \u2713 ${count} tasks detected and saved! Use /sdd approve to e
|
|
|
4606
4696
|
if (progress) {
|
|
4607
4697
|
opts.renderer.write(
|
|
4608
4698
|
`
|
|
4609
|
-
${
|
|
4699
|
+
${color11.cyan(` \u2713 ${autoCompleted} task(s) auto-completed! Progress: ${progress.completed}/${progress.total} (${progress.percentComplete}%)`)}
|
|
4610
4700
|
`
|
|
4611
4701
|
);
|
|
4612
4702
|
const taskList2 = renderTaskListWithProgress();
|
|
4613
4703
|
if (taskList2) {
|
|
4614
4704
|
opts.renderer.write(`
|
|
4615
|
-
${
|
|
4705
|
+
${color11.dim(taskList2)}
|
|
4616
4706
|
`);
|
|
4617
4707
|
}
|
|
4618
4708
|
}
|
|
@@ -4620,7 +4710,7 @@ ${color9.dim(taskList2)}
|
|
|
4620
4710
|
const taskList2 = renderTaskListWithProgress();
|
|
4621
4711
|
if (taskList2) {
|
|
4622
4712
|
opts.renderer.write(`
|
|
4623
|
-
${
|
|
4713
|
+
${color11.dim(taskList2)}
|
|
4624
4714
|
`);
|
|
4625
4715
|
}
|
|
4626
4716
|
}
|
|
@@ -4638,7 +4728,7 @@ ${color9.dim(taskList2)}
|
|
|
4638
4728
|
}
|
|
4639
4729
|
}
|
|
4640
4730
|
} catch (err) {
|
|
4641
|
-
opts.renderer.writeError(
|
|
4731
|
+
opts.renderer.writeError(toErrorMessage3(err));
|
|
4642
4732
|
}
|
|
4643
4733
|
continue;
|
|
4644
4734
|
}
|
|
@@ -4663,22 +4753,22 @@ ${color9.dim(taskList2)}
|
|
|
4663
4753
|
}
|
|
4664
4754
|
if (resolved.source === "open") {
|
|
4665
4755
|
opts.renderer.write(
|
|
4666
|
-
` ${
|
|
4667
|
-
` +
|
|
4756
|
+
` ${color11.amber("\u26A0")} ${color11.bold("'continue' has no anchor")} ${color11.dim("\u2014 no pending todo or suggestion.")}
|
|
4757
|
+
` + color11.dim(
|
|
4668
4758
|
" If you proceed, I'll choose the next step from context; that can drift.\n"
|
|
4669
4759
|
)
|
|
4670
4760
|
);
|
|
4671
|
-
const ans = (await opts.reader.readLine(
|
|
4761
|
+
const ans = (await opts.reader.readLine(color11.dim(" Proceed anyway? [Y/n \xB7 e = type your own] "))).trim().toLowerCase();
|
|
4672
4762
|
if (ans === "n" || ans === "no") {
|
|
4673
|
-
opts.renderer.write(
|
|
4763
|
+
opts.renderer.write(color11.dim(" Cancelled \u2014 nothing sent.\n"));
|
|
4674
4764
|
continue;
|
|
4675
4765
|
}
|
|
4676
4766
|
if (ans === "e" || ans === "edit") {
|
|
4677
|
-
opts.renderer.write(
|
|
4767
|
+
opts.renderer.write(color11.dim(" Okay \u2014 type what to continue with.\n"));
|
|
4678
4768
|
continue;
|
|
4679
4769
|
}
|
|
4680
4770
|
} else {
|
|
4681
|
-
opts.renderer.write(
|
|
4771
|
+
opts.renderer.write(color11.dim(` ${resolved.label}
|
|
4682
4772
|
`));
|
|
4683
4773
|
}
|
|
4684
4774
|
builder.appendText(resolved.text);
|
|
@@ -4686,7 +4776,7 @@ ${color9.dim(taskList2)}
|
|
|
4686
4776
|
const ph = await builder.appendPaste(raw);
|
|
4687
4777
|
if (ph) {
|
|
4688
4778
|
const lineCount = raw.split("\n").length;
|
|
4689
|
-
opts.renderer.write(
|
|
4779
|
+
opts.renderer.write(color11.dim(` \u21B3 ${ph} (${lineCount} lines)
|
|
4690
4780
|
`));
|
|
4691
4781
|
}
|
|
4692
4782
|
}
|
|
@@ -4739,7 +4829,7 @@ ${taskList}`;
|
|
|
4739
4829
|
}) : { blocks: effectiveBlocks, route: "none", convertedImages: 0 };
|
|
4740
4830
|
if (routed.route === "adapter") {
|
|
4741
4831
|
opts.renderer.write(
|
|
4742
|
-
|
|
4832
|
+
color11.dim(
|
|
4743
4833
|
` \u21B3 image analyzed via ${routed.adapterName ?? "vision adapter"} (${routed.convertedImages} image${routed.convertedImages === 1 ? "" : "s"})
|
|
4744
4834
|
`
|
|
4745
4835
|
)
|
|
@@ -4773,14 +4863,14 @@ ${taskList}`;
|
|
|
4773
4863
|
if (specSaved) {
|
|
4774
4864
|
opts.renderer.write(
|
|
4775
4865
|
`
|
|
4776
|
-
${
|
|
4866
|
+
${color11.cyan(" \u2713 Spec detected and saved! Use /sdd approve to continue.")}
|
|
4777
4867
|
`
|
|
4778
4868
|
);
|
|
4779
4869
|
}
|
|
4780
4870
|
const planSaved = trySaveImplementationPlan(result.finalText);
|
|
4781
4871
|
if (planSaved) {
|
|
4782
4872
|
opts.renderer.write(`
|
|
4783
|
-
${
|
|
4873
|
+
${color11.cyan(" \u2713 Implementation plan saved!")}
|
|
4784
4874
|
`);
|
|
4785
4875
|
}
|
|
4786
4876
|
const tasksSaved = await trySaveTasksFromAIOutput(result.finalText);
|
|
@@ -4789,7 +4879,7 @@ ${color9.cyan(" \u2713 Implementation plan saved!")}
|
|
|
4789
4879
|
const count = progress?.total ?? 0;
|
|
4790
4880
|
opts.renderer.write(
|
|
4791
4881
|
`
|
|
4792
|
-
${
|
|
4882
|
+
${color11.cyan(` \u2713 ${count} tasks detected and saved! Use /sdd approve to execute.`)}
|
|
4793
4883
|
`
|
|
4794
4884
|
);
|
|
4795
4885
|
}
|
|
@@ -4801,13 +4891,13 @@ ${color9.cyan(` \u2713 ${count} tasks detected and saved! Use /sdd approve to e
|
|
|
4801
4891
|
if (progress) {
|
|
4802
4892
|
opts.renderer.write(
|
|
4803
4893
|
`
|
|
4804
|
-
${
|
|
4894
|
+
${color11.cyan(` \u2713 ${autoCompleted} task(s) auto-completed! Progress: ${progress.completed}/${progress.total} (${progress.percentComplete}%)`)}
|
|
4805
4895
|
`
|
|
4806
4896
|
);
|
|
4807
4897
|
if (progress.percentComplete === 100) {
|
|
4808
4898
|
opts.renderer.write(
|
|
4809
4899
|
`
|
|
4810
|
-
${
|
|
4900
|
+
${color11.green(" \u{1F389} All tasks completed! Use /sdd cancel to end the session.")}
|
|
4811
4901
|
`
|
|
4812
4902
|
);
|
|
4813
4903
|
}
|
|
@@ -4816,14 +4906,14 @@ ${color9.green(" \u{1F389} All tasks completed! Use /sdd cancel to end the sess
|
|
|
4816
4906
|
const taskList2 = renderTaskListWithProgress();
|
|
4817
4907
|
if (taskList2) {
|
|
4818
4908
|
opts.renderer.write(`
|
|
4819
|
-
${
|
|
4909
|
+
${color11.dim(taskList2)}
|
|
4820
4910
|
`);
|
|
4821
4911
|
}
|
|
4822
4912
|
} else {
|
|
4823
4913
|
const taskList2 = renderTaskListWithProgress();
|
|
4824
4914
|
if (taskList2) {
|
|
4825
4915
|
opts.renderer.write(`
|
|
4826
|
-
${
|
|
4916
|
+
${color11.dim(taskList2)}
|
|
4827
4917
|
`);
|
|
4828
4918
|
}
|
|
4829
4919
|
}
|
|
@@ -4840,15 +4930,15 @@ ${color9.dim(taskList2)}
|
|
|
4840
4930
|
const ctxChip = effectiveMaxContext && effectiveMaxContext > 0 ? ` ctx: ${renderContextChip(after.input, effectiveMaxContext)}` : "";
|
|
4841
4931
|
opts.renderer.write(
|
|
4842
4932
|
`
|
|
4843
|
-
${
|
|
4933
|
+
${color11.dim(
|
|
4844
4934
|
`[in: ${fmtTok(after.input - before.input)} out: ${fmtTok(after.output - before.output)} iters: ${result.iterations} cost: ${(costAfter - costBefore).toFixed(4)} ${((Date.now() - startedAt) / 1e3).toFixed(1)}s]${ctxChip}`
|
|
4845
4935
|
)}
|
|
4846
4936
|
`
|
|
4847
4937
|
);
|
|
4848
4938
|
}
|
|
4849
4939
|
if (result.status === "done" && opts.getAutonomy) {
|
|
4850
|
-
const
|
|
4851
|
-
if (
|
|
4940
|
+
const autonomy2 = opts.getAutonomy();
|
|
4941
|
+
if (autonomy2 === "suggest" && !hasOpenTodos2(opts.agent.ctx.todos)) {
|
|
4852
4942
|
const suggestPrompt = 'Based on what you just did, suggest 3 exact prompt messages that can be submitted back to you through the TUI or WebUI. Each prompt must ask the agent to perform work; never assign a manual chore to the user. If you include suggestions, wrap them in a balanced <nextsteps>...</nextsteps> block, with one numbered prompt per line and no explanation. If there is nothing meaningful left, say "No further steps needed."';
|
|
4853
4943
|
const suggestBlocks = [{ type: "text", text: suggestPrompt }];
|
|
4854
4944
|
const suggestCtrl = new AbortController();
|
|
@@ -4867,7 +4957,7 @@ ${color9.dim(
|
|
|
4867
4957
|
if (suggestResult.status === "done" && suggestResult.finalText) {
|
|
4868
4958
|
opts.renderer.write(
|
|
4869
4959
|
`
|
|
4870
|
-
${
|
|
4960
|
+
${color11.cyan(" Suggested next steps:")}
|
|
4871
4961
|
${suggestResult.finalText}
|
|
4872
4962
|
`
|
|
4873
4963
|
);
|
|
@@ -4886,8 +4976,8 @@ ${suggestResult.finalText}
|
|
|
4886
4976
|
}
|
|
4887
4977
|
}
|
|
4888
4978
|
if (result.status === "done" && opts.getNextPredict?.() && !hasOpenTodos2(opts.agent.ctx.todos)) {
|
|
4889
|
-
const
|
|
4890
|
-
if (
|
|
4979
|
+
const autonomy2 = opts.getAutonomy?.() ?? "off";
|
|
4980
|
+
if (autonomy2 === "off") {
|
|
4891
4981
|
const predictCtrl = new AbortController();
|
|
4892
4982
|
activeCtrl = predictCtrl;
|
|
4893
4983
|
try {
|
|
@@ -4906,8 +4996,8 @@ ${suggestResult.finalText}
|
|
|
4906
4996
|
if (predictions.length > 0) {
|
|
4907
4997
|
const lines = predictions.map((p, i) => ` ${i + 1}. ${p}`).join("\n");
|
|
4908
4998
|
opts.renderer.write(`
|
|
4909
|
-
${
|
|
4910
|
-
${
|
|
4999
|
+
${color11.dim(" \u21B3 likely next:")}
|
|
5000
|
+
${color11.dim(lines)}
|
|
4911
5001
|
`);
|
|
4912
5002
|
}
|
|
4913
5003
|
} catch {
|
|
@@ -4917,7 +5007,7 @@ ${color9.dim(lines)}
|
|
|
4917
5007
|
}
|
|
4918
5008
|
}
|
|
4919
5009
|
} catch (err) {
|
|
4920
|
-
opts.renderer.writeError(
|
|
5010
|
+
opts.renderer.writeError(toErrorMessage3(err));
|
|
4921
5011
|
} finally {
|
|
4922
5012
|
activeCtrl = void 0;
|
|
4923
5013
|
}
|
|
@@ -4935,71 +5025,17 @@ async function pasteClipboardImage(builder, opts) {
|
|
|
4935
5025
|
try {
|
|
4936
5026
|
const img = await readClipboardImage();
|
|
4937
5027
|
if (!img) {
|
|
4938
|
-
opts.renderer.write(
|
|
5028
|
+
opts.renderer.write(color11.dim(" no image on clipboard\n"));
|
|
4939
5029
|
return;
|
|
4940
5030
|
}
|
|
4941
5031
|
const placeholder = await builder.appendImage(img.base64, img.mediaType);
|
|
4942
5032
|
const kb = (img.bytes / 1024).toFixed(0);
|
|
4943
|
-
opts.renderer.write(
|
|
5033
|
+
opts.renderer.write(color11.dim(` \u21B3 ${placeholder} (PNG ${kb}KB)
|
|
4944
5034
|
`));
|
|
4945
5035
|
} catch (err) {
|
|
4946
|
-
opts.renderer.writeError(`Clipboard image error: ${
|
|
5036
|
+
opts.renderer.writeError(`Clipboard image error: ${toErrorMessage3(err)}`);
|
|
4947
5037
|
}
|
|
4948
5038
|
}
|
|
4949
|
-
async function loadGoalSafe(opts) {
|
|
4950
|
-
if (!opts.projectRoot) return null;
|
|
4951
|
-
try {
|
|
4952
|
-
return await loadGoal(goalFilePath(opts.projectRoot));
|
|
4953
|
-
} catch {
|
|
4954
|
-
return null;
|
|
4955
|
-
}
|
|
4956
|
-
}
|
|
4957
|
-
async function renderGoalBanner(opts) {
|
|
4958
|
-
const goal = await loadGoalSafe(opts);
|
|
4959
|
-
if (!goal) return;
|
|
4960
|
-
const summary = goal.goal.length > 80 ? `${goal.goal.slice(0, 77)}\u2026` : goal.goal;
|
|
4961
|
-
const stateColor = goal.goalState === "active" ? color9.green : goal.goalState === "paused" ? color9.amber : goal.goalState === "completed" ? color9.green : goal.goalState === "abandoned" ? color9.dim : color9.dim;
|
|
4962
|
-
opts.renderer.write(
|
|
4963
|
-
color9.dim("Goal: ") + stateColor(summary) + color9.dim(` [${goal.goalState}] (iter ${goal.iterations})`) + "\n"
|
|
4964
|
-
);
|
|
4965
|
-
if (goal.journal.length > 0) {
|
|
4966
|
-
const lastEntry = expectDefined(goal.journal[goal.journal.length - 1]);
|
|
4967
|
-
const statusIcon = lastEntry.status === "success" ? "\u2713" : lastEntry.status === "failure" ? "\u2717" : lastEntry.status === "aborted" ? "\u2298" : lastEntry.status === "skipped" ? "\u229D" : "\xB7";
|
|
4968
|
-
opts.renderer.write(
|
|
4969
|
-
color9.dim(` Last: ${statusIcon} ${lastEntry.task} (${lastEntry.status})`) + "\n"
|
|
4970
|
-
);
|
|
4971
|
-
}
|
|
4972
|
-
if (goal.engineState === "running") {
|
|
4973
|
-
opts.renderer.write(
|
|
4974
|
-
color9.amber(" \u21BA Eternal engine was running when last session ended.") + "\n"
|
|
4975
|
-
);
|
|
4976
|
-
try {
|
|
4977
|
-
const answer = (await opts.reader.readLine(color9.dim(" Resume eternal mode? [y/N] "))).trim().toLowerCase();
|
|
4978
|
-
if (answer === "y" || answer === "yes") {
|
|
4979
|
-
try {
|
|
4980
|
-
await opts.slashRegistry.dispatch("/autonomy eternal", opts.agent.ctx);
|
|
4981
|
-
} catch (err) {
|
|
4982
|
-
opts.renderer.writeError(`Auto-resume failed: ${toErrorMessage(err)}`);
|
|
4983
|
-
}
|
|
4984
|
-
} else {
|
|
4985
|
-
opts.renderer.write(
|
|
4986
|
-
color9.dim(" Not resuming. Use `/autonomy eternal` later to continue.") + "\n"
|
|
4987
|
-
);
|
|
4988
|
-
}
|
|
4989
|
-
} catch {
|
|
4990
|
-
opts.renderer.write(color9.dim(" Use `/autonomy eternal` to resume.") + "\n");
|
|
4991
|
-
}
|
|
4992
|
-
} else if (goal.goalState === "paused") {
|
|
4993
|
-
opts.renderer.write(color9.amber(" \u23F8 Goal is paused. Use `/goal resume` to continue.") + "\n");
|
|
4994
|
-
} else if (goal.goalState === "completed") {
|
|
4995
|
-
opts.renderer.write(
|
|
4996
|
-
color9.green(" \u2713 Goal completed! Use `/goal clear` to set a new goal.") + "\n"
|
|
4997
|
-
);
|
|
4998
|
-
} else if (goal.goalState === "abandoned") {
|
|
4999
|
-
opts.renderer.write(color9.dim(" Use `/goal clear` to set a new goal.") + "\n");
|
|
5000
|
-
}
|
|
5001
|
-
opts.renderer.write("\n");
|
|
5002
|
-
}
|
|
5003
5039
|
|
|
5004
5040
|
// src/execution-tui-next-step-callbacks.ts
|
|
5005
5041
|
function createTuiNextStepCallbacks(input) {
|
|
@@ -5998,4 +6034,4 @@ export {
|
|
|
5998
6034
|
execute,
|
|
5999
6035
|
resolveReviewerFallbackModels
|
|
6000
6036
|
};
|
|
6001
|
-
//# sourceMappingURL=execution-
|
|
6037
|
+
//# sourceMappingURL=execution-4ASWJ7EY.js.map
|