@wrongstack/cli 0.276.3 → 0.277.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/README.md +3 -3
- package/dist/index.js +141 -70
- package/dist/index.js.map +1 -1
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -17,8 +17,7 @@ The `wrongstack` umbrella package transitively installs `@wrongstack/cli` along
|
|
|
17
17
|
```bash
|
|
18
18
|
wstack # interactive REPL — no flags = default
|
|
19
19
|
wstack --tui # Ink-based TUI
|
|
20
|
-
wstack --yolo # auto-approve normal project work
|
|
21
|
-
wstack --yolo --yolo-destructive # also auto-approve destructive-gated calls
|
|
20
|
+
wstack --yolo # auto-approve normal project work; destructive calls still prompt
|
|
22
21
|
wstack "refactor src/auth.ts" # one-shot query (no interactive loop)
|
|
23
22
|
|
|
24
23
|
wstack --provider <id> --model <id> # skip the picker
|
|
@@ -97,7 +96,8 @@ API keys are encrypted at rest with AES-256-GCM and the key file at `~/.wrongsta
|
|
|
97
96
|
|------|--------|
|
|
98
97
|
| `--tui` / `--no-tui` | Force/disable Ink TUI |
|
|
99
98
|
| `--yolo` | Auto-approve normal in-project tool calls |
|
|
100
|
-
| `--
|
|
99
|
+
| `--confirm-destructive` | Deprecated; destructive confirmations are always on in YOLO |
|
|
100
|
+
| `--yolo-destructive` | Deprecated compatibility flag; destructive calls still prompt |
|
|
101
101
|
| `--force-all-yolo` | Deprecated alias for `--yolo-destructive` |
|
|
102
102
|
| `--provider <id>` | Override the configured provider |
|
|
103
103
|
| `--model <id>` | Override the configured model |
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { color, CODEX_MODELS, ToolCapabilities, readBundledInstructionText, writeErr, loadPlugins, renderProgress, SpecStore, TaskGraphStore, analyzeCriticalPath, getTemplate, listTemplates, templateToMarkdown, SpecParser, renderSpecAnalysis, AISpecBuilder, expectDefined, DefaultTaskStore, TaskTracker, renderTaskGraph, withFileLock, ConfigError, resolveHqDataDir, ensureHqFirstRunAuthFile, DEFAULT_HQ_REDACTION_POLICY, watchHqAuthFile, parseHqFrame, HQ_PROTOCOL_VERSION, parseHqEventPayload, scrubAndTruncateHqPreview, FetchError, DefaultSecretScrubber, resolveWstackPaths, watchProviderConfig, projectHash, wstackGlobalRoot, PromptUsageStore, TOKENS, ToolRegistry, GlobalMailbox, resolveSessionLoggingConfig, createSessionEventBridge, HookRegistry, HookRunner, shellHooksEqual, countShellHooks, normalizeTokenSavingTier, SlashCommandRegistry, attachDepWatcherBridge, createFallbackModelExtension, SessionMemoryConsolidator, BrainDecisionQueue, ObservableBrainArbiter, HumanEscalatingBrainArbiter, createTieredBrainArbiter, DefaultBrainArbiter, BrainMonitor, mailboxSessionTag, createDelegateTool, FLEET_ROSTER, createMcpControlTool, startTechStackConsumer, startPackageOutdatedWatcher, SddRunRegistry, recordFileAction, createAutonomyBrain, DefaultPluginAPI, SpecVersioning, buildTranscriptFromEvents, DEFAULT_CONTEXT_WINDOW_MODE_ID, resolveProjectDir, DefaultLogger, DefaultModelsRegistry, isStdinTTY, FsError, atomicWrite, DefaultPathResolver, EventBus, runProviderWithRetry, ReplayLogStore, ReplayProviderRunner, mergeCustomModelDefs, DefaultSystemPromptBuilder, makeAutonomyPromptContributor, sessionScopedPath as sessionScopedPath$1, createContextManagerTool, makeMailboxTool, makeMailSendTool, makeMailInboxTool, applyToolDescriptionModes, applyToolResultRenderModes, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, createHqPublisherFromEnv, DEFAULT_SESSION_PRUNE_DAYS, RecoveryLock, DefaultAttachmentStore, Context, QueueStore, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, loadPlan, createDefaultPipelines, applyModelRuntime, installDesignStudioMiddleware, resolveContextWindowPolicy, resolveAuditLevel, AutoCompactionMiddleware, estimateRequestTokensCalibrated, Agent, FleetManager, makeDirectorSessionFactory, Director, makeFleetEmitTool, AdaptiveConcurrencyController, resolveModelMatrix, resolveModelTargetFromEntry, DEFAULT_SUBAGENT_BASELINE, DefaultTokenCounter, AutoApprovePermissionPolicy, ToolValidationError, WIDE_SUBAGENT_CAPABILITIES, AgentError, PhaseStore, AutoPhasePlanner, PhaseGraphBuilder, WorktreeManager, PhaseOrchestrator, assignNickname, makeLLMClassifier, writeOut, ParallelEternalEngine, EternalAutonomyEngine, allServers as allServers$1, CHIMERA_REVIEW_PROMPT, setQueuedMessagesSnapshot, projectSlug, recentTextTurns, gatedEnhancerReasoning, enhanceUserPrompt, repairToolUseAdjacency, mutateTasks, loadTasks, mutatePlan, setPlanItemStatus, getPlanTemplate, emptyPlan, addPlanItem, savePlan, resolveProviderModelList, bootConfig as bootConfig$1, setOutputLineGuard, setRawMode, DefaultSessionReader, ToolAuditLog, DefaultSessionRewinder, DefaultSessionStore as DefaultSessionStore$1, ProviderRegistry, makeAgentSubagentRunner, NULL_FLEET_BUS, ERROR_CODES, buildChildEnv, formatContextWindowModeList, getContextWindowMode, AGENT_CATALOG, dispatchAgent, normalizeToolDescriptionMode, getToolDescriptionMode, noOpVault, formatTodosList, formatTaskList, formatTaskProgress, formatPlan, SessionRecovery, loadGoal, goalFilePath, summarizeUsage, saveGoal, formatGoal, emptyGoal, buildGoalPreamble, pendingBtwCount, setBtwNote, getDesignKitLoader, getDesignState, clearActiveKit, clearPersistedActiveKit, recordOverrides, setDesignOverrides, loadActiveKit, isDesignStack, applyTokenOverrides, materializeTokens, setActiveKit, readHqRuntimeFileSync, resolveHqConfig, MATRIX_PHASE_KEYS, matrixKeyKind, phaseForRole, fallbackProfileChain, parseModelRef, normalizeModelRef, onResize, InputBuilder, DefaultSecretVault as DefaultSecretVault$1, decryptConfigSecrets as decryptConfigSecrets$1, encryptConfigSecrets as encryptConfigSecrets$1, HQ_AUTH_FILE_VERSION, truncate, estimateMessageTokens, AGENTS_BY_PHASE, validateAgainstSchema, normalizeToolResultRenderMode, getToolResultRenderMode, setToolResultRenderMode, resolveMailboxIdentity, smartDefaultFallbackChain, AutonomousCoordinator, mutateHqAuthFile, mintHqToken, readHqAuthFile, isSecretField as isSecretField$1, renderInstructionTemplate, ParseError, startSessionTelemetryBridge } from '@wrongstack/core';
|
|
2
|
+
import { color, CODEX_MODELS, ToolCapabilities, readBundledInstructionText, writeErr, loadPlugins, renderProgress, SpecStore, TaskGraphStore, analyzeCriticalPath, getTemplate, listTemplates, templateToMarkdown, SpecParser, renderSpecAnalysis, AISpecBuilder, expectDefined, DefaultTaskStore, TaskTracker, renderTaskGraph, withFileLock, ConfigError, resolveHqDataDir, ensureHqFirstRunAuthFile, DEFAULT_HQ_REDACTION_POLICY, watchHqAuthFile, parseHqFrame, HQ_PROTOCOL_VERSION, parseHqEventPayload, scrubAndTruncateHqPreview, FetchError, DefaultSecretScrubber, resolveWstackPaths, watchProviderConfig, projectHash, wstackGlobalRoot, PromptUsageStore, TOKENS, ToolRegistry, GlobalMailbox, resolveSessionLoggingConfig, createSessionEventBridge, HookRegistry, HookRunner, shellHooksEqual, countShellHooks, normalizeTokenSavingTier, SlashCommandRegistry, attachDepWatcherBridge, createFallbackModelExtension, SessionMemoryConsolidator, BrainDecisionQueue, ObservableBrainArbiter, HumanEscalatingBrainArbiter, createTieredBrainArbiter, DefaultBrainArbiter, BrainMonitor, mailboxSessionTag, createDelegateTool, FLEET_ROSTER, createMcpControlTool, startTechStackConsumer, startPackageOutdatedWatcher, SddRunRegistry, recordFileAction, createAutonomyBrain, DefaultPluginAPI, SpecVersioning, buildTranscriptFromEvents, DEFAULT_CONTEXT_WINDOW_MODE_ID, resolveProjectDir, DefaultLogger, DefaultModelsRegistry, isStdinTTY, FsError, atomicWrite, DefaultPathResolver, EventBus, runProviderWithRetry, ReplayLogStore, ReplayProviderRunner, mergeCustomModelDefs, DefaultSystemPromptBuilder, makeAutonomyPromptContributor, sessionScopedPath as sessionScopedPath$1, createContextManagerTool, makeMailboxTool, makeMailSendTool, makeMailInboxTool, applyToolDescriptionModes, applyToolResultRenderModes, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, createHqPublisherFromEnv, DEFAULT_SESSION_PRUNE_DAYS, RecoveryLock, DefaultAttachmentStore, Context, QueueStore, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, loadPlan, createDefaultPipelines, applyModelRuntime, installDesignStudioMiddleware, resolveContextWindowPolicy, resolveAuditLevel, AutoCompactionMiddleware, estimateRequestTokensCalibrated, Agent, FleetManager, makeDirectorSessionFactory, Director, makeFleetEmitTool, AdaptiveConcurrencyController, resolveModelMatrix, resolveModelTargetFromEntry, DEFAULT_SUBAGENT_BASELINE, DefaultTokenCounter, AutoApprovePermissionPolicy, ToolValidationError, WIDE_SUBAGENT_CAPABILITIES, AgentError, PhaseStore, AutoPhasePlanner, PhaseGraphBuilder, WorktreeManager, PhaseOrchestrator, assignNickname, makeLLMClassifier, writeOut, ParallelEternalEngine, EternalAutonomyEngine, allServers as allServers$1, CHIMERA_REVIEW_PROMPT, setQueuedMessagesSnapshot, projectSlug, recentTextTurns, gatedEnhancerReasoning, enhanceUserPrompt, repairToolUseAdjacency, mutateTasks, loadTasks, mutatePlan, setPlanItemStatus, getPlanTemplate, emptyPlan, addPlanItem, savePlan, resolveProviderModelList, bootConfig as bootConfig$1, setOutputLineGuard, setRawMode, DefaultSessionReader, ToolAuditLog, DefaultSessionRewinder, DefaultSessionStore as DefaultSessionStore$1, ProviderRegistry, makeAgentSubagentRunner, NULL_FLEET_BUS, ERROR_CODES, buildChildEnv, formatContextWindowModeList, getContextWindowMode, AGENT_CATALOG, dispatchAgent, normalizeToolDescriptionMode, getToolDescriptionMode, noOpVault, formatTodosList, formatTaskList, formatTaskProgress, formatPlan, SessionRecovery, loadGoal, goalFilePath, summarizeUsage, saveGoal, formatGoal, emptyGoal, buildGoalPreamble, pendingBtwCount, setBtwNote, getDesignKitLoader, getDesignState, clearActiveKit, clearPersistedActiveKit, recordOverrides, setDesignOverrides, loadActiveKit, isDesignStack, applyTokenOverrides, materializeTokens, setActiveKit, readHqRuntimeFileSync, resolveHqConfig, MATRIX_PHASE_KEYS, matrixKeyKind, phaseForRole, fallbackProfileChain, parseModelRef, normalizeModelRef, onResize, hasOpenTodos, InputBuilder, DefaultSecretVault as DefaultSecretVault$1, decryptConfigSecrets as decryptConfigSecrets$1, encryptConfigSecrets as encryptConfigSecrets$1, HQ_AUTH_FILE_VERSION, truncate, estimateMessageTokens, AGENTS_BY_PHASE, validateAgainstSchema, normalizeToolResultRenderMode, getToolResultRenderMode, setToolResultRenderMode, resolveMailboxIdentity, smartDefaultFallbackChain, AutonomousCoordinator, mutateHqAuthFile, mintHqToken, readHqAuthFile, isSecretField as isSecretField$1, renderInstructionTemplate, ParseError, startSessionTelemetryBridge } from '@wrongstack/core';
|
|
3
3
|
import * as fs5 from 'fs/promises';
|
|
4
4
|
import { access, readFile } from 'fs/promises';
|
|
5
5
|
import { DefaultSecretVault, decryptConfigSecrets, encryptConfigSecrets, isSecretField } from '@wrongstack/core/security';
|
|
@@ -16995,6 +16995,32 @@ function buildMailboxDemoCommand(opts) {
|
|
|
16995
16995
|
}
|
|
16996
16996
|
};
|
|
16997
16997
|
}
|
|
16998
|
+
|
|
16999
|
+
// src/utils/win32-cmd.ts
|
|
17000
|
+
var WIN32_CMD_META = /[&|<>"\r\n\0]/;
|
|
17001
|
+
function buildWin32CmdShimInvocation(command2, args = []) {
|
|
17002
|
+
assertSafeWin32CmdArgs([command2, ...args]);
|
|
17003
|
+
const line = ["call", quoteWin32CmdArg(command2), ...args.map(quoteWin32CmdArg)].join(" ");
|
|
17004
|
+
return {
|
|
17005
|
+
command: process.env["COMSPEC"] ?? "cmd.exe",
|
|
17006
|
+
args: ["/d", "/c", line],
|
|
17007
|
+
windowsVerbatimArguments: true
|
|
17008
|
+
};
|
|
17009
|
+
}
|
|
17010
|
+
function assertSafeWin32CmdArgs(args) {
|
|
17011
|
+
for (const arg of args) {
|
|
17012
|
+
if (typeof arg === "string" && WIN32_CMD_META.test(arg)) {
|
|
17013
|
+
throw new Error(
|
|
17014
|
+
'win32 cmd shim spawn: argument contains a shell metacharacter (one of & | < > ", or a newline) that could enable command injection through the .cmd/.bat wrapper - refusing to run. Offending argument: ' + JSON.stringify(arg)
|
|
17015
|
+
);
|
|
17016
|
+
}
|
|
17017
|
+
}
|
|
17018
|
+
}
|
|
17019
|
+
function quoteWin32CmdArg(arg) {
|
|
17020
|
+
return `"${arg}"`;
|
|
17021
|
+
}
|
|
17022
|
+
|
|
17023
|
+
// src/slash-commands/mailbox-serve.ts
|
|
16998
17024
|
function buildMailboxServeCommand(opts) {
|
|
16999
17025
|
return {
|
|
17000
17026
|
name: "mailbox-serve",
|
|
@@ -17040,16 +17066,16 @@ function buildMailboxServeCommand(opts) {
|
|
|
17040
17066
|
const isWin = process.platform === "win32";
|
|
17041
17067
|
let wstackCmd;
|
|
17042
17068
|
let spawnArgs;
|
|
17043
|
-
let
|
|
17069
|
+
let shim = null;
|
|
17044
17070
|
if (cliEntry && /wstack|wrongstack|index\.(js|ts|mjs|cjs)$/.test(cliEntry)) {
|
|
17045
17071
|
wstackCmd = process.execPath;
|
|
17046
17072
|
spawnArgs = [cliEntry, "mailbox", "serve", ...flags];
|
|
17047
17073
|
} else {
|
|
17048
17074
|
wstackCmd = "wstack";
|
|
17049
17075
|
spawnArgs = ["mailbox", "serve", ...flags];
|
|
17050
|
-
|
|
17076
|
+
if (isWin) shim = buildWin32CmdShimInvocation(wstackCmd, spawnArgs);
|
|
17051
17077
|
}
|
|
17052
|
-
const child = spawn(wstackCmd, spawnArgs, {
|
|
17078
|
+
const child = spawn(shim?.command ?? wstackCmd, shim?.args ?? spawnArgs, {
|
|
17053
17079
|
cwd,
|
|
17054
17080
|
// POSIX-only: own process group so the bridge outlives the REPL.
|
|
17055
17081
|
// On win32 `detached` opens a visible console window (project
|
|
@@ -17057,7 +17083,7 @@ function buildMailboxServeCommand(opts) {
|
|
|
17057
17083
|
detached: !isWin,
|
|
17058
17084
|
stdio: ["ignore", "pipe", "pipe"],
|
|
17059
17085
|
windowsHide: true,
|
|
17060
|
-
|
|
17086
|
+
...shim ? { windowsVerbatimArguments: shim.windowsVerbatimArguments } : {},
|
|
17061
17087
|
env: process.env
|
|
17062
17088
|
});
|
|
17063
17089
|
child.unref();
|
|
@@ -23274,12 +23300,12 @@ function buildYoloCommand(opts) {
|
|
|
23274
23300
|
help: [
|
|
23275
23301
|
"Usage:",
|
|
23276
23302
|
" /yolo Show current YOLO status",
|
|
23277
|
-
" /yolo on Enable YOLO mode (auto-approve
|
|
23303
|
+
" /yolo on Enable YOLO mode (auto-approve normal project work)",
|
|
23278
23304
|
" /yolo off Disable YOLO mode (restore permission prompts)",
|
|
23279
|
-
" /yolo destructive
|
|
23305
|
+
" /yolo destructive Show destructive confirmation gate status",
|
|
23280
23306
|
"",
|
|
23281
|
-
"YOLO mode auto-approves
|
|
23282
|
-
"
|
|
23307
|
+
"YOLO mode auto-approves normal project work, including shell/build/test/write flows.",
|
|
23308
|
+
"Clearly destructive operations still require explicit confirmation."
|
|
23283
23309
|
].join("\n"),
|
|
23284
23310
|
async run(args) {
|
|
23285
23311
|
const arg = args.trim().toLowerCase();
|
|
@@ -23305,11 +23331,11 @@ function buildYoloCommand(opts) {
|
|
|
23305
23331
|
} else if (arg === "destructive") {
|
|
23306
23332
|
const currentMode = opts.onYolo();
|
|
23307
23333
|
if (!currentMode) {
|
|
23308
|
-
const msg3 = `${color.amber("YOLO is OFF.")}
|
|
23334
|
+
const msg3 = `${color.amber("YOLO is OFF.")} Destructive operations still require confirmation when YOLO is enabled.`;
|
|
23309
23335
|
opts.renderer.writeWarning(msg3);
|
|
23310
23336
|
return { message: msg3 };
|
|
23311
23337
|
}
|
|
23312
|
-
const msg2 = `${color.amber("Destructive gate:")} ${color.dim("
|
|
23338
|
+
const msg2 = `${color.amber("Destructive gate:")} ${color.dim("ON \u2014 YOLO is enabled, but clearly destructive operations still require confirmation.")}`;
|
|
23313
23339
|
opts.renderer.writeWarning(msg2);
|
|
23314
23340
|
return { message: msg2 };
|
|
23315
23341
|
} else {
|
|
@@ -31653,9 +31679,9 @@ var helpCmd = async (_args, deps) => {
|
|
|
31653
31679
|
" wstack version Print version",
|
|
31654
31680
|
"",
|
|
31655
31681
|
color.bold("Common flags"),
|
|
31656
|
-
" --yolo Auto-approve
|
|
31657
|
-
" --confirm-destructive
|
|
31658
|
-
" --yolo-destructive Deprecated
|
|
31682
|
+
" --yolo Auto-approve normal project work; destructive calls still prompt",
|
|
31683
|
+
" --confirm-destructive Deprecated \u2014 destructive confirmations are always on in YOLO mode",
|
|
31684
|
+
" --yolo-destructive Deprecated compatibility flag; destructive calls still prompt",
|
|
31659
31685
|
" --tui / --no-tui Force or disable TUI mode",
|
|
31660
31686
|
" --mouse Full mouse mode in the TUI (in-app scroll + clickable UI)",
|
|
31661
31687
|
" --webui [--host <h>] [--webui-port <n>] [--ws-port <n>] [--webui-token <t>] [--open]",
|
|
@@ -32443,6 +32469,67 @@ function bindSystemPromptBuilder(deps) {
|
|
|
32443
32469
|
);
|
|
32444
32470
|
}
|
|
32445
32471
|
|
|
32472
|
+
// src/boot/brain-decision-log.ts
|
|
32473
|
+
var MAX_BRAIN_LOG_ENTRIES = 20;
|
|
32474
|
+
function subscribeBrainDecisionLog(events) {
|
|
32475
|
+
const listeners = [];
|
|
32476
|
+
const brainLog = [];
|
|
32477
|
+
const pushBrainLog = (entry) => {
|
|
32478
|
+
brainLog.push(entry);
|
|
32479
|
+
if (brainLog.length > MAX_BRAIN_LOG_ENTRIES) brainLog.shift();
|
|
32480
|
+
};
|
|
32481
|
+
const subscribe = (name, handler) => {
|
|
32482
|
+
events.on(name, handler);
|
|
32483
|
+
listeners.push([name, handler]);
|
|
32484
|
+
};
|
|
32485
|
+
subscribe("brain.decision_answered", (raw) => {
|
|
32486
|
+
const e = raw;
|
|
32487
|
+
pushBrainLog({
|
|
32488
|
+
at: e.at,
|
|
32489
|
+
kind: "answered",
|
|
32490
|
+
question: e.request.question,
|
|
32491
|
+
outcome: e.decision.type === "answer" ? e.decision.optionId ?? e.decision.text ?? "" : ""
|
|
32492
|
+
});
|
|
32493
|
+
});
|
|
32494
|
+
subscribe("brain.decision_ask_human", (raw) => {
|
|
32495
|
+
const e = raw;
|
|
32496
|
+
pushBrainLog({
|
|
32497
|
+
at: e.at,
|
|
32498
|
+
kind: "ask_human",
|
|
32499
|
+
question: e.request.question,
|
|
32500
|
+
outcome: "escalated to human"
|
|
32501
|
+
});
|
|
32502
|
+
});
|
|
32503
|
+
subscribe("brain.decision_denied", (raw) => {
|
|
32504
|
+
const e = raw;
|
|
32505
|
+
pushBrainLog({
|
|
32506
|
+
at: e.at,
|
|
32507
|
+
kind: "denied",
|
|
32508
|
+
question: e.request.question,
|
|
32509
|
+
outcome: e.decision.type === "deny" ? e.decision.reason ?? "" : ""
|
|
32510
|
+
});
|
|
32511
|
+
});
|
|
32512
|
+
subscribe("brain.intervention", (raw) => {
|
|
32513
|
+
const e = raw;
|
|
32514
|
+
pushBrainLog({
|
|
32515
|
+
at: e.at,
|
|
32516
|
+
kind: "intervention",
|
|
32517
|
+
question: e.request.question,
|
|
32518
|
+
outcome: e.intervened ? "steered the agent" : "observed (no action)"
|
|
32519
|
+
});
|
|
32520
|
+
});
|
|
32521
|
+
const dispose = () => {
|
|
32522
|
+
for (const [name, handler] of listeners) {
|
|
32523
|
+
events.off.call(
|
|
32524
|
+
events,
|
|
32525
|
+
name,
|
|
32526
|
+
handler
|
|
32527
|
+
);
|
|
32528
|
+
}
|
|
32529
|
+
};
|
|
32530
|
+
return { brainLog, pushBrainLog, dispose };
|
|
32531
|
+
}
|
|
32532
|
+
|
|
32446
32533
|
// src/boot/short-circuit-flags.ts
|
|
32447
32534
|
async function handleHelpVersionShortCircuit(argv) {
|
|
32448
32535
|
const earlyFlags = parseArgs(argv).flags;
|
|
@@ -34109,7 +34196,10 @@ init_hq_publisher();
|
|
|
34109
34196
|
init_sdd();
|
|
34110
34197
|
init_utils();
|
|
34111
34198
|
var DEFAULT_MAX_CONSECUTIVE_AUTO_PROCEED = 50;
|
|
34112
|
-
function parseSuggestionsFromOutput(finalText) {
|
|
34199
|
+
function parseSuggestionsFromOutput(finalText, todos) {
|
|
34200
|
+
if (hasOpenTodos(todos)) {
|
|
34201
|
+
return null;
|
|
34202
|
+
}
|
|
34113
34203
|
const { texts, autoTexts } = parseNextSteps(finalText, false);
|
|
34114
34204
|
if (autoTexts.length > 0) ;
|
|
34115
34205
|
return texts.length > 0 ? texts : null;
|
|
@@ -34467,7 +34557,10 @@ ${color.dim(taskList2)}
|
|
|
34467
34557
|
}
|
|
34468
34558
|
}
|
|
34469
34559
|
if (opts.onSuggestionsParsed) {
|
|
34470
|
-
const parsed = parseSuggestionsFromOutput(
|
|
34560
|
+
const parsed = parseSuggestionsFromOutput(
|
|
34561
|
+
runResult.finalText,
|
|
34562
|
+
opts.agent.ctx.todos
|
|
34563
|
+
);
|
|
34471
34564
|
opts.onSuggestionsParsed(parsed);
|
|
34472
34565
|
}
|
|
34473
34566
|
}
|
|
@@ -34626,7 +34719,7 @@ ${color.dim(taskList2)}
|
|
|
34626
34719
|
}
|
|
34627
34720
|
}
|
|
34628
34721
|
if (result.status === "done" && result.finalText && opts.onSuggestionsParsed) {
|
|
34629
|
-
const parsed = parseSuggestionsFromOutput(result.finalText);
|
|
34722
|
+
const parsed = parseSuggestionsFromOutput(result.finalText, opts.agent.ctx.todos);
|
|
34630
34723
|
opts.onSuggestionsParsed(parsed);
|
|
34631
34724
|
}
|
|
34632
34725
|
if (opts.tokenCounter && before) {
|
|
@@ -34671,7 +34764,7 @@ ${color.dim(
|
|
|
34671
34764
|
} finally {
|
|
34672
34765
|
activeCtrl = void 0;
|
|
34673
34766
|
}
|
|
34674
|
-
} else if (autonomy === "suggest") {
|
|
34767
|
+
} else if (autonomy === "suggest" && !hasOpenTodos(opts.agent.ctx.todos)) {
|
|
34675
34768
|
const suggestPrompt = 'Based on what you just did, suggest 3 concrete next steps. Format: numbered list, one line each, no explanation. If there is nothing meaningful left, say "No further steps needed."';
|
|
34676
34769
|
const suggestBlocks = [{ type: "text", text: suggestPrompt }];
|
|
34677
34770
|
const suggestCtrl = new AbortController();
|
|
@@ -34695,7 +34788,10 @@ ${suggestResult.finalText}
|
|
|
34695
34788
|
`
|
|
34696
34789
|
);
|
|
34697
34790
|
if (opts.onSuggestionsParsed) {
|
|
34698
|
-
const parsed = parseSuggestionsFromOutput(
|
|
34791
|
+
const parsed = parseSuggestionsFromOutput(
|
|
34792
|
+
suggestResult.finalText,
|
|
34793
|
+
opts.agent.ctx.todos
|
|
34794
|
+
);
|
|
34699
34795
|
opts.onSuggestionsParsed(parsed);
|
|
34700
34796
|
}
|
|
34701
34797
|
}
|
|
@@ -34705,7 +34801,7 @@ ${suggestResult.finalText}
|
|
|
34705
34801
|
}
|
|
34706
34802
|
}
|
|
34707
34803
|
}
|
|
34708
|
-
if (result.status === "done" && opts.getNextPredict?.()) {
|
|
34804
|
+
if (result.status === "done" && opts.getNextPredict?.() && !hasOpenTodos(opts.agent.ctx.todos)) {
|
|
34709
34805
|
const autonomy = opts.getAutonomy?.() ?? "off";
|
|
34710
34806
|
if (autonomy === "off") {
|
|
34711
34807
|
const predictCtrl = new AbortController();
|
|
@@ -34866,7 +34962,7 @@ async function runAutoProceed(opts, suggestion, delayMs, ctrl) {
|
|
|
34866
34962
|
).total
|
|
34867
34963
|
);
|
|
34868
34964
|
if (runResult.status === "done" && runResult.finalText && opts.onSuggestionsParsed) {
|
|
34869
|
-
const parsed = parseSuggestionsFromOutput(runResult.finalText);
|
|
34965
|
+
const parsed = parseSuggestionsFromOutput(runResult.finalText, opts.agent.ctx.todos);
|
|
34870
34966
|
opts.onSuggestionsParsed(parsed);
|
|
34871
34967
|
}
|
|
34872
34968
|
} finally {
|
|
@@ -35327,9 +35423,13 @@ async function execute(deps) {
|
|
|
35327
35423
|
},
|
|
35328
35424
|
// Parse 💡 Next steps from assistant output and store them in the
|
|
35329
35425
|
// shared suggestion store so `/next 1`, `/next 1 2 3` work without
|
|
35330
|
-
// requiring `/suggest` first. Called unconditionally on every done
|
|
35426
|
+
// requiring `/suggest` first. Called unconditionally on every done
|
|
35427
|
+
// turn. The live todo list is passed through so we suppress
|
|
35428
|
+
// <next_steps> while the in-flight todo loop is still in progress
|
|
35429
|
+
// — finishing the open todos comes before offering new prompt
|
|
35430
|
+
// options.
|
|
35331
35431
|
onSuggestionsParsed: (finalText) => {
|
|
35332
|
-
const parsed = parseSuggestionsFromOutput(finalText);
|
|
35432
|
+
const parsed = parseSuggestionsFromOutput(finalText, context.todos);
|
|
35333
35433
|
setSuggestions(parsed ?? []);
|
|
35334
35434
|
},
|
|
35335
35435
|
// Retrieve current suggestions for next-steps auto-submit countdown.
|
|
@@ -36503,11 +36603,13 @@ var MultiAgentHost = class _MultiAgentHost {
|
|
|
36503
36603
|
* and `shell.*` are not in the read-only default), silently crippling
|
|
36504
36604
|
* every code-writing / build role in the catalog.
|
|
36505
36605
|
* 3. No tool restriction (full registry) → the WIDE working set
|
|
36506
|
-
* (`WIDE_SUBAGENT_CAPABILITIES`: read, write, net, shell, install
|
|
36507
|
-
*
|
|
36508
|
-
*
|
|
36509
|
-
* blast-radius-escaping
|
|
36510
|
-
*
|
|
36606
|
+
* (`WIDE_SUBAGENT_CAPABILITIES`: read, write, net, shell, install,
|
|
36607
|
+
* session todo, tool metadata, read-only memory). The user authorized full
|
|
36608
|
+
* developer work when they invoked the leader, so a delegated agent runs
|
|
36609
|
+
* the same toolchain end-to-end. The genuinely blast-radius-escaping
|
|
36610
|
+
* capabilities (fs.write.outside-project, tool.mutate.any, memory writes,
|
|
36611
|
+
* mcp.proxy, subagent.spawn, config.mutate) stay off and need an explicit
|
|
36612
|
+
* (1) grant.
|
|
36511
36613
|
*/
|
|
36512
36614
|
resolveSubagentCapabilities(subCfg) {
|
|
36513
36615
|
if (subCfg.allowedCapabilities) return subCfg.allowedCapabilities;
|
|
@@ -36801,6 +36903,7 @@ var MultiAgentHost = class _MultiAgentHost {
|
|
|
36801
36903
|
if (this.director) {
|
|
36802
36904
|
await this.getCoordinator().stopAll();
|
|
36803
36905
|
}
|
|
36906
|
+
await this.fleetManager?.flushManifest();
|
|
36804
36907
|
}
|
|
36805
36908
|
/**
|
|
36806
36909
|
* Current effective concurrent-subagent ceiling. Reads the live
|
|
@@ -36861,6 +36964,9 @@ var MultiAgentHost = class _MultiAgentHost {
|
|
|
36861
36964
|
if (this.director) {
|
|
36862
36965
|
await this.director.shutdown();
|
|
36863
36966
|
}
|
|
36967
|
+
await this.fleetManager?.flushManifest();
|
|
36968
|
+
this.fleetManager?.dispose();
|
|
36969
|
+
this.fleetManager = void 0;
|
|
36864
36970
|
const monitor = this.opts.agentMonitor;
|
|
36865
36971
|
if (monitor) {
|
|
36866
36972
|
monitor.stop();
|
|
@@ -37310,16 +37416,16 @@ function defaultSpawn(args, cwd) {
|
|
|
37310
37416
|
const isWin = process.platform === "win32";
|
|
37311
37417
|
let cmd;
|
|
37312
37418
|
let spawnArgs;
|
|
37313
|
-
let
|
|
37419
|
+
let shim = null;
|
|
37314
37420
|
if (cliEntry && /wstack|wrongstack|index\.(js|ts|mjs|cjs)$/.test(cliEntry)) {
|
|
37315
37421
|
cmd = process.execPath;
|
|
37316
37422
|
spawnArgs = [cliEntry, ...args];
|
|
37317
37423
|
} else {
|
|
37318
37424
|
cmd = "wstack";
|
|
37319
37425
|
spawnArgs = args;
|
|
37320
|
-
|
|
37426
|
+
if (isWin) shim = buildWin32CmdShimInvocation(cmd, spawnArgs);
|
|
37321
37427
|
}
|
|
37322
|
-
const child = spawn(cmd, spawnArgs, {
|
|
37428
|
+
const child = spawn(shim?.command ?? cmd, shim?.args ?? spawnArgs, {
|
|
37323
37429
|
cwd,
|
|
37324
37430
|
// `detached` gives the bridge its own process group on POSIX so it
|
|
37325
37431
|
// outlives the REPL. On win32 it forces a visible console window
|
|
@@ -37328,7 +37434,7 @@ function defaultSpawn(args, cwd) {
|
|
|
37328
37434
|
detached: !isWin,
|
|
37329
37435
|
stdio: ["ignore", "pipe", "pipe"],
|
|
37330
37436
|
windowsHide: true,
|
|
37331
|
-
|
|
37437
|
+
...shim ? { windowsVerbatimArguments: shim.windowsVerbatimArguments } : {},
|
|
37332
37438
|
env: process.env
|
|
37333
37439
|
});
|
|
37334
37440
|
return {
|
|
@@ -38075,7 +38181,7 @@ async function main(argv) {
|
|
|
38075
38181
|
renderer,
|
|
38076
38182
|
modelsRegistry,
|
|
38077
38183
|
yoloDestructive: flags["yolo-destructive"] === true || flags["force-all-yolo"] === true,
|
|
38078
|
-
confirmDestructive:
|
|
38184
|
+
confirmDestructive: true
|
|
38079
38185
|
});
|
|
38080
38186
|
const replayFlag = flags["replay"];
|
|
38081
38187
|
const recordFlag = flags["record"];
|
|
@@ -38732,43 +38838,8 @@ async function main(argv) {
|
|
|
38732
38838
|
events
|
|
38733
38839
|
);
|
|
38734
38840
|
container.bind(TOKENS.BrainArbiter, () => brain);
|
|
38735
|
-
const brainLog =
|
|
38736
|
-
|
|
38737
|
-
brainLog.push(entry);
|
|
38738
|
-
if (brainLog.length > 20) brainLog.shift();
|
|
38739
|
-
};
|
|
38740
|
-
evOn("brain.decision_answered", (e) => {
|
|
38741
|
-
pushBrainLog({
|
|
38742
|
-
at: e.at,
|
|
38743
|
-
kind: "answered",
|
|
38744
|
-
question: e.request.question,
|
|
38745
|
-
outcome: e.decision.type === "answer" ? e.decision.optionId ?? e.decision.text : ""
|
|
38746
|
-
});
|
|
38747
|
-
});
|
|
38748
|
-
evOn("brain.decision_ask_human", (e) => {
|
|
38749
|
-
pushBrainLog({
|
|
38750
|
-
at: e.at,
|
|
38751
|
-
kind: "ask_human",
|
|
38752
|
-
question: e.request.question,
|
|
38753
|
-
outcome: "escalated to human"
|
|
38754
|
-
});
|
|
38755
|
-
});
|
|
38756
|
-
evOn("brain.decision_denied", (e) => {
|
|
38757
|
-
pushBrainLog({
|
|
38758
|
-
at: e.at,
|
|
38759
|
-
kind: "denied",
|
|
38760
|
-
question: e.request.question,
|
|
38761
|
-
outcome: e.decision.type === "deny" ? e.decision.reason : ""
|
|
38762
|
-
});
|
|
38763
|
-
});
|
|
38764
|
-
evOn("brain.intervention", (e) => {
|
|
38765
|
-
pushBrainLog({
|
|
38766
|
-
at: e.at,
|
|
38767
|
-
kind: "intervention",
|
|
38768
|
-
question: e.request.question,
|
|
38769
|
-
outcome: e.intervened ? "steered the agent" : "observed (no action)"
|
|
38770
|
-
});
|
|
38771
|
-
});
|
|
38841
|
+
const { brainLog, dispose: disposeBrainLog } = subscribeBrainDecisionLog(events);
|
|
38842
|
+
teardownHandlers.push(disposeBrainLog);
|
|
38772
38843
|
let hqPublisher;
|
|
38773
38844
|
let stopHqSessionBridge;
|
|
38774
38845
|
const hqConnection = startCliHqConnection({
|