@wrongstack/cli 0.298.3 → 0.300.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.
Files changed (51) hide show
  1. package/dist/{acp-S4LZQB66.js → acp-IDNS2YVE.js} +3 -3
  2. package/dist/{auth-G5YKKSRH.js → auth-6T6ZOT2R.js} +5 -5
  3. package/dist/auth-menu/loopback-server.d.ts +41 -55
  4. package/dist/auth-menu/openai-codex-oauth.d.ts +36 -123
  5. package/dist/auto-discover-providers-DRW4OZHG.js +8 -0
  6. package/dist/boot/dispatch-webui.d.ts +3 -0
  7. package/dist/{chunk-PEKUKUCH.js → chunk-3MWUZMOL.js} +19 -12
  8. package/dist/{chunk-TGDHN4LM.js → chunk-4GVH7V3S.js} +4 -24
  9. package/dist/{chunk-4U3DMA2Y.js → chunk-4WJKVQJY.js} +15 -20
  10. package/dist/{chunk-C5GH4YBL.js → chunk-GYDQABMA.js} +271 -182
  11. package/dist/{chunk-4HH3YGG4.js → chunk-MRLYDHQ7.js} +8 -5
  12. package/dist/{chunk-66T43Q4Y.js → chunk-N7ULWBO5.js} +4 -3
  13. package/dist/{chunk-ZNZJ34RF.js → chunk-PEMN4T5O.js} +2 -2
  14. package/dist/chunk-PYTFS4MC.js +238 -0
  15. package/dist/{chunk-L5CE52XW.js → chunk-V76R7DC5.js} +25 -19
  16. package/dist/{cli-main-ZDZMCVLM.js → cli-main-7B3G2YSG.js} +943 -160
  17. package/dist/{execution-BY556FCF.js → execution-SHGM7BVC.js} +76 -8
  18. package/dist/fleet/budget-source.d.ts +18 -0
  19. package/dist/fleet/host-status.d.ts +31 -0
  20. package/dist/fleet/host-types.d.ts +8 -0
  21. package/dist/fleet/host.d.ts +5 -0
  22. package/dist/{hq-WO6CLUSI.js → hq-DVDD4XPV.js} +22 -3
  23. package/dist/hq-server/auth-state.d.ts +29 -1
  24. package/dist/hq-server/auth.d.ts +16 -0
  25. package/dist/hq-server/client-address.d.ts +56 -0
  26. package/dist/hq-server/login-attempt-store.d.ts +30 -10
  27. package/dist/hq-server/routes/auth-handlers.d.ts +66 -26
  28. package/dist/hq-server/routes.d.ts +13 -0
  29. package/dist/hq-server/types.d.ts +10 -0
  30. package/dist/{hq-server-6TSAORAC.js → hq-server-DQHLNHDL.js} +2 -2
  31. package/dist/hq-server.d.ts +19 -0
  32. package/dist/index.js +20 -20
  33. package/dist/{modeldiag-HENYJ4N7.js → modeldiag-YOQZHBQV.js} +2 -2
  34. package/dist/{plugin-usage-VTL7ZTVC.js → plugin-usage-EOG4ET4S.js} +2 -2
  35. package/dist/{plugins-ETY6W3DC.js → plugins-56CMWMPR.js} +3 -3
  36. package/dist/{providers-models-GDELBHZK.js → providers-models-K6RT7ABI.js} +34 -9
  37. package/dist/slash-commands/command-context.d.ts +19 -0
  38. package/dist/slash-commands/intake.d.ts +4 -0
  39. package/dist/slash-commands/memory-triage.d.ts +47 -0
  40. package/dist/webui-server/setup-events.d.ts +17 -0
  41. package/dist/webui-server/terminal-log-view.d.ts +29 -12
  42. package/dist/{webui-server-PCLSXX6L.js → webui-server-G3EKFXLL.js} +109 -38
  43. package/dist/webui-server-options.d.ts +16 -0
  44. package/dist/wiring/brain-and-orchestration.d.ts +3 -0
  45. package/dist/wiring/director-setup.d.ts +4 -0
  46. package/dist/wiring/fallback-gate.d.ts +31 -0
  47. package/dist/wiring/fleet-command-handlers.d.ts +1 -1
  48. package/dist/wiring/plugins.d.ts +2 -8
  49. package/dist/wiring/provider-utility-tools.d.ts +26 -1
  50. package/package.json +23 -22
  51. package/dist/chunk-GO3TJICK.js +0 -489
@@ -1,3 +1,6 @@
1
+ import {
2
+ setupPlugins
3
+ } from "./chunk-4WJKVQJY.js";
1
4
  import {
2
5
  runProjectPicker
3
6
  } from "./chunk-5N34EWJR.js";
@@ -37,13 +40,10 @@ import {
37
40
  matchTaskNode,
38
41
  sddState
39
42
  } from "./chunk-XTIXVJXP.js";
40
- import {
41
- setupPlugins
42
- } from "./chunk-4U3DMA2Y.js";
43
43
  import {
44
44
  PLUGIN_AUDIT_ENTRIES,
45
45
  runPluginManagementCommand
46
- } from "./chunk-PEKUKUCH.js";
46
+ } from "./chunk-3MWUZMOL.js";
47
47
  import {
48
48
  configureSimpleUiRuntimeContext,
49
49
  detectProjectFacts,
@@ -70,7 +70,7 @@ import {
70
70
  loadCachedAcpRegistry,
71
71
  refreshAcpRegistry,
72
72
  setupProvider
73
- } from "./chunk-4HH3YGG4.js";
73
+ } from "./chunk-MRLYDHQ7.js";
74
74
  import {
75
75
  addCustomProvider,
76
76
  addKeyForCatalogProvider,
@@ -80,17 +80,18 @@ import {
80
80
  runClaudeOAuthLogin,
81
81
  runCopilotOAuthLogin,
82
82
  validateFamily
83
- } from "./chunk-L5CE52XW.js";
83
+ } from "./chunk-V76R7DC5.js";
84
84
  import {
85
85
  LOCAL_LLM_PRESETS,
86
86
  parseSpawnFlags
87
- } from "./chunk-ZNZJ34RF.js";
87
+ } from "./chunk-PEMN4T5O.js";
88
88
  import {
89
- buildPickableProviders
90
- } from "./chunk-66T43Q4Y.js";
89
+ buildPickableProviders,
90
+ visibleModelIds
91
+ } from "./chunk-N7ULWBO5.js";
91
92
  import {
92
93
  runCodexOAuthLogin
93
- } from "./chunk-GO3TJICK.js";
94
+ } from "./chunk-PYTFS4MC.js";
94
95
  import {
95
96
  activeLabel,
96
97
  loadConfigProviders,
@@ -2555,7 +2556,8 @@ function wireSessionEvents(deps) {
2555
2556
  attempt: e.attempt,
2556
2557
  delayMs: e.delayMs,
2557
2558
  status: e.status,
2558
- description: e.description
2559
+ description: e.description,
2560
+ ...e.errorBody ? { errorBody: e.errorBody } : {}
2559
2561
  });
2560
2562
  }
2561
2563
  );
@@ -2568,7 +2570,8 @@ function wireSessionEvents(deps) {
2568
2570
  providerId: e.providerId,
2569
2571
  status: e.status,
2570
2572
  description: e.description,
2571
- retryable: e.retryable ?? false
2573
+ retryable: e.retryable ?? false,
2574
+ ...e.errorBody ? { errorBody: e.errorBody } : {}
2572
2575
  });
2573
2576
  }
2574
2577
  );
@@ -3023,7 +3026,7 @@ import {
3023
3026
  } from "@wrongstack/acp";
3024
3027
  import { ToolValidationError } from "@wrongstack/core/types";
3025
3028
  function buildAcpSubagentRunner(subagentId) {
3026
- let cmd = Object.prototype.hasOwnProperty.call(ACP_AGENT_COMMANDS, subagentId) ? ACP_AGENT_COMMANDS[subagentId] : void 0;
3029
+ let cmd = Object.hasOwn(ACP_AGENT_COMMANDS, subagentId) ? ACP_AGENT_COMMANDS[subagentId] : void 0;
3027
3030
  if (!cmd) {
3028
3031
  const desc = findAgentDescriptor(subagentId);
3029
3032
  if (desc) {
@@ -3261,6 +3264,10 @@ function registerDirectorStatsBridge(input) {
3261
3264
  ...u.toolCalls !== void 0 ? { toolCalls: u.toolCalls } : {}
3262
3265
  };
3263
3266
  });
3267
+ const budgetSnap = director.fleetManager?.budgetSnapshot?.();
3268
+ const maxSpawns = budgetSnap?.maxSpawns ?? director.maxSpawns;
3269
+ const usedSpawns = budgetSnap?.usedSpawns ?? director.spawnCount;
3270
+ const remainingSpawns = budgetSnap?.remainingSpawns ?? Math.max(0, (Number.isFinite(maxSpawns) ? maxSpawns : Number.POSITIVE_INFINITY) - usedSpawns);
3264
3271
  events.emit("coordinator.stats", {
3265
3272
  sessionId,
3266
3273
  total: payload.total,
@@ -3271,6 +3278,11 @@ function registerDirectorStatsBridge(input) {
3271
3278
  pending: payload.pending,
3272
3279
  completed: payload.completed,
3273
3280
  ...usage?.total?.cost !== void 0 ? { totalCostUsd: usage.total.cost } : {},
3281
+ maxSpawns,
3282
+ usedSpawns,
3283
+ remainingSpawns,
3284
+ ...budgetSnap?.checkpointMaxSpawns !== void 0 ? { checkpointMaxSpawns: budgetSnap.checkpointMaxSpawns } : {},
3285
+ ...budgetSnap?.ceilingMismatch ? { ceilingMismatch: true } : {},
3274
3286
  subagentStatuses
3275
3287
  });
3276
3288
  });
@@ -4364,7 +4376,47 @@ function buildFleetHostStatus(input) {
4364
4376
  const completedCount = completed.length;
4365
4377
  const liveCount = live.filter((s) => s.status === "running" || s.status === "idle").length;
4366
4378
  const summary = !input.coordinatorStatus && !input.completedResults ? "No subagents have been spawned." : liveCount > 0 ? `${pending.length} pending, ${liveCount} active, ${completedCount} completed.` : `${pending.length} pending, ${completedCount} completed.`;
4367
- return { pending, completed, live, summary };
4379
+ return {
4380
+ pending,
4381
+ completed,
4382
+ live,
4383
+ summary,
4384
+ ...input.budget ? { budget: input.budget } : {}
4385
+ };
4386
+ }
4387
+ function formatFleetBudgetLines(budget, colorize) {
4388
+ const bold = colorize?.bold ?? ((s) => s);
4389
+ const dim = colorize?.dim ?? ((s) => s);
4390
+ const amber = colorize?.amber ?? ((s) => s);
4391
+ const fmtNum = (n) => Number.isFinite(n) ? String(n) : "\u221E";
4392
+ const sourceSuffix = budget.effectiveSource ? ` ${dim(`(source: ${budget.effectiveSource})`)}` : "";
4393
+ const lines = [
4394
+ bold("Budget"),
4395
+ ` maxConcurrent: ${budget.maxConcurrent} \xB7 activeAgents: ${budget.activeAgents}`,
4396
+ ` maxSpawns: ${fmtNum(budget.maxSpawns)} \xB7 usedSpawns: ${budget.usedSpawns} \xB7 remainingSpawns: ${fmtNum(budget.remainingSpawns)}${sourceSuffix}`
4397
+ ];
4398
+ if (budget.maxTokens !== void 0 && Number.isFinite(budget.maxTokens) && budget.maxTokens < Number.POSITIVE_INFINITY) {
4399
+ lines.push(
4400
+ ` tokens: ${budget.usedTokens ?? 0} / ${fmtNum(budget.maxTokens)} remaining ${fmtNum(budget.remainingTokens ?? 0)}`
4401
+ );
4402
+ }
4403
+ if (budget.maxCostUsd !== void 0 && Number.isFinite(budget.maxCostUsd) && budget.maxCostUsd < Number.POSITIVE_INFINITY) {
4404
+ const used = budget.usedCostUsd ?? 0;
4405
+ const rem = budget.remainingCostUsd ?? 0;
4406
+ lines.push(
4407
+ ` costUsd: ${used.toFixed(4)} / ${budget.maxCostUsd.toFixed(4)} remaining ${rem.toFixed(4)}`
4408
+ );
4409
+ }
4410
+ if (budget.ceilingMismatch && budget.checkpointMaxSpawns !== void 0) {
4411
+ lines.push(
4412
+ amber(
4413
+ ` \u26A0 checkpoint maxSpawns was ${budget.checkpointMaxSpawns}; live ceiling is ${fmtNum(budget.maxSpawns)}`
4414
+ )
4415
+ );
4416
+ } else if (budget.checkpointMaxSpawns !== void 0) {
4417
+ lines.push(dim(` checkpointMaxSpawns: ${budget.checkpointMaxSpawns}`));
4418
+ }
4419
+ return lines;
4368
4420
  }
4369
4421
  function aggregateFleetUsage(completed) {
4370
4422
  const bySubagent = /* @__PURE__ */ new Map();
@@ -5072,9 +5124,44 @@ var MultiAgentHost = class {
5072
5124
  coordinatorStatus: this.director ? this.getCoordinator().getStatus() : null,
5073
5125
  fleetStatus: this.fleetManager?.getFleetStatus() ?? null,
5074
5126
  completedResults: this.director ? this.director.completedResults() : null,
5075
- shadowTaskIds: this.shadowTaskIds
5127
+ shadowTaskIds: this.shadowTaskIds,
5128
+ budget: this.budgetView()
5076
5129
  });
5077
5130
  }
5131
+ /**
5132
+ * Read-only concurrency + lifetime spawn budget for `/fleet status` and
5133
+ * resume diagnostics. Safe when no director/fleet is active yet.
5134
+ */
5135
+ budgetView() {
5136
+ const snap = this.fleetManager?.budgetSnapshot?.();
5137
+ const maxSpawns = snap?.maxSpawns ?? this.opts.maxSpawns ?? this.director?.maxSpawns ?? Number.POSITIVE_INFINITY;
5138
+ const usedSpawns = snap?.usedSpawns ?? this.director?.spawnCount ?? 0;
5139
+ const remainingSpawns = snap?.remainingSpawns ?? Math.max(0, (Number.isFinite(maxSpawns) ? maxSpawns : Number.POSITIVE_INFINITY) - usedSpawns);
5140
+ const live = this.director ? this.getCoordinator().getStatus().subagents.filter((s) => s.status === "running" || s.status === "idle").length : 0;
5141
+ const maxConcurrentSource = this.opts.budgetSources?.maxConcurrent ?? "default";
5142
+ const maxSpawnsSource = this.opts.budgetSources?.maxSpawns ?? "default";
5143
+ const effectiveSource = `maxConcurrent=${maxConcurrentSource}, maxSpawns=${maxSpawnsSource}`;
5144
+ return {
5145
+ maxConcurrent: this.getMaxConcurrent(),
5146
+ activeAgents: live,
5147
+ maxSpawns,
5148
+ usedSpawns,
5149
+ remainingSpawns,
5150
+ maxConcurrentSource,
5151
+ maxSpawnsSource,
5152
+ effectiveSource,
5153
+ ...snap ? {
5154
+ maxTokens: snap.maxTokens,
5155
+ usedTokens: snap.usedTokens,
5156
+ remainingTokens: snap.remainingTokens,
5157
+ maxCostUsd: snap.maxCostUsd,
5158
+ usedCostUsd: snap.usedCostUsd,
5159
+ remainingCostUsd: snap.remainingCostUsd,
5160
+ ...snap.checkpointMaxSpawns !== void 0 ? { checkpointMaxSpawns: snap.checkpointMaxSpawns } : {},
5161
+ ...snap.ceilingMismatch ? { ceilingMismatch: true } : {}
5162
+ } : {}
5163
+ };
5164
+ }
5078
5165
  usage() {
5079
5166
  const completed = this.director ? this.director.completedResults().filter((r) => !this.shadowTaskIds.has(r.taskId)) : [];
5080
5167
  return aggregateFleetUsage(completed);
@@ -5174,7 +5261,10 @@ function resolveProviderCfg(config, providerId) {
5174
5261
  function buildProviderForId(args, providerId) {
5175
5262
  const { cfg, factoryType } = resolveProviderCfg(args.config, providerId);
5176
5263
  const useRegistry = !!args.config.features.modelsRegistry && args.providerRegistry.has(factoryType);
5177
- return useRegistry ? args.providerRegistry.create(cfg, factoryType) : makeProviderFromConfig2(providerId, cfg);
5264
+ return useRegistry ? args.providerRegistry.create(cfg, factoryType) : makeProviderFromConfig2(
5265
+ providerId,
5266
+ factoryType === "ai-gateway" ? { ...cfg, type: factoryType } : cfg
5267
+ );
5178
5268
  }
5179
5269
 
5180
5270
  // src/wiring/brain-and-orchestration.ts
@@ -5413,8 +5503,12 @@ function setupBrainAndOrchestration(deps) {
5413
5503
  maxCostUsd: config.fleet.budget.maxCostUsd
5414
5504
  }
5415
5505
  } : {},
5416
- maxSpawns: config.fleet?.budget?.maxSpawns,
5506
+ maxSpawns: deps.maxSpawns ?? config.fleet?.budget?.maxSpawns,
5417
5507
  maxConcurrent,
5508
+ budgetSources: {
5509
+ maxConcurrent: deps.maxConcurrentSource ?? "default",
5510
+ maxSpawns: deps.maxSpawnsSource ?? "default"
5511
+ },
5418
5512
  getLeaderMaxContext: () => effectiveMaxContextRef.current,
5419
5513
  brain,
5420
5514
  agentMonitor,
@@ -5931,13 +6025,78 @@ import * as path10 from "node:path";
5931
6025
  import { expectDefined as expectDefined2 } from "@wrongstack/core/utils";
5932
6026
  import { createAgentMonitorService } from "@wrongstack/core/coordination";
5933
6027
  import { sessionScopedPath as sessionScopedPath2 } from "@wrongstack/core/utils";
6028
+
6029
+ // src/fleet/budget-source.ts
6030
+ import { DEFAULT_MAX_FLEET_SPAWNS as DEFAULT_MAX_FLEET_SPAWNS3 } from "@wrongstack/core/coordination";
6031
+ function positiveInt(raw) {
6032
+ if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) return Math.floor(raw);
6033
+ if (typeof raw === "string" && raw.trim() !== "") {
6034
+ const n = Number.parseInt(raw, 10);
6035
+ if (Number.isFinite(n) && n > 0) return n;
6036
+ }
6037
+ return void 0;
6038
+ }
6039
+ function resolveFleetBudgetSources(input) {
6040
+ const flags = input.flags ?? {};
6041
+ const env = input.env ?? process.env;
6042
+ const config = input.config;
6043
+ const defaultMaxConcurrent = input.defaultMaxConcurrent ?? 4;
6044
+ const defaultMaxSpawns = input.defaultMaxSpawns ?? DEFAULT_MAX_FLEET_SPAWNS3;
6045
+ const maxConcurrentFlag = positiveInt(flags["max-concurrent"]);
6046
+ const maxConcurrentEnv = positiveInt(env["WRONGSTACK_MAX_CONCURRENT"]);
6047
+ const maxConcurrentProfile = positiveInt(config?.maxConcurrent);
6048
+ let maxConcurrent;
6049
+ let maxConcurrentSource;
6050
+ if (maxConcurrentFlag !== void 0) {
6051
+ maxConcurrent = maxConcurrentFlag;
6052
+ maxConcurrentSource = "cli-flag";
6053
+ } else if (maxConcurrentEnv !== void 0) {
6054
+ maxConcurrent = maxConcurrentEnv;
6055
+ maxConcurrentSource = "env";
6056
+ } else if (maxConcurrentProfile !== void 0) {
6057
+ maxConcurrent = maxConcurrentProfile;
6058
+ maxConcurrentSource = "profile";
6059
+ } else {
6060
+ maxConcurrent = defaultMaxConcurrent;
6061
+ maxConcurrentSource = "default";
6062
+ }
6063
+ const maxSpawnsFlag = positiveInt(flags["max-spawns"]);
6064
+ const maxSpawnsEnv = positiveInt(env["WRONGSTACK_MAX_SPAWNS"]);
6065
+ const maxSpawnsProfile = positiveInt(config?.fleet?.budget?.maxSpawns);
6066
+ let maxSpawns;
6067
+ let maxSpawnsSource;
6068
+ if (maxSpawnsFlag !== void 0) {
6069
+ maxSpawns = maxSpawnsFlag;
6070
+ maxSpawnsSource = "cli-flag";
6071
+ } else if (maxSpawnsEnv !== void 0) {
6072
+ maxSpawns = maxSpawnsEnv;
6073
+ maxSpawnsSource = "env";
6074
+ } else if (maxSpawnsProfile !== void 0) {
6075
+ maxSpawns = maxSpawnsProfile;
6076
+ maxSpawnsSource = "profile";
6077
+ } else {
6078
+ maxSpawns = defaultMaxSpawns;
6079
+ maxSpawnsSource = "default";
6080
+ }
6081
+ return {
6082
+ maxConcurrent,
6083
+ maxConcurrentSource,
6084
+ maxSpawns,
6085
+ maxSpawnsSource
6086
+ };
6087
+ }
6088
+
6089
+ // src/wiring/director-setup.ts
5934
6090
  function setupDirectorAndAutonomy(deps) {
5935
6091
  const { flags, config, wpaths, session, events, autonomyModeRef } = deps;
5936
6092
  const directorMode = true;
5937
- const maxConcurrentFromFlag = typeof flags["max-concurrent"] === "string" ? Number.parseInt(flags["max-concurrent"], 10) : void 0;
5938
- const maxConcurrentFromEnv = typeof process.env["WRONGSTACK_MAX_CONCURRENT"] === "string" ? Number.parseInt(process.env["WRONGSTACK_MAX_CONCURRENT"], 10) : void 0;
5939
- const maxConcurrentFromConfig = typeof config.maxConcurrent === "number" && config.maxConcurrent > 0 ? config.maxConcurrent : void 0;
5940
- const maxConcurrent = Number.isFinite(maxConcurrentFromFlag) && maxConcurrentFromFlag > 0 ? maxConcurrentFromFlag : Number.isFinite(maxConcurrentFromEnv) && maxConcurrentFromEnv > 0 ? maxConcurrentFromEnv : Number.isFinite(maxConcurrentFromConfig) && maxConcurrentFromConfig > 0 ? maxConcurrentFromConfig : void 0;
6093
+ const {
6094
+ maxConcurrent: resolvedMaxConcurrent,
6095
+ maxConcurrentSource,
6096
+ maxSpawns,
6097
+ maxSpawnsSource
6098
+ } = resolveFleetBudgetSources({ flags, config });
6099
+ const maxConcurrent = maxConcurrentSource === "default" ? void 0 : resolvedMaxConcurrent;
5941
6100
  const autonomyMode = (() => {
5942
6101
  const v = flags["autonomy"];
5943
6102
  if (v === "auto" || v === "suggest" || v === "eternal" || v === "eternal-parallel") return v;
@@ -5984,6 +6143,9 @@ function setupDirectorAndAutonomy(deps) {
5984
6143
  director: null,
5985
6144
  directorMode,
5986
6145
  maxConcurrent,
6146
+ maxSpawns,
6147
+ maxConcurrentSource,
6148
+ maxSpawnsSource,
5987
6149
  autonomyMode,
5988
6150
  nextPredictEnabled,
5989
6151
  currentSuggestions,
@@ -6103,6 +6265,7 @@ ${color6.dim("\u2500".repeat(40))}` : "";
6103
6265
  onAgents: (subagentId) => formatAgents(input, subagentId),
6104
6266
  onFleet: (action, target) => handleFleetAction(input, action, target),
6105
6267
  onFleetStatus: () => input.getDirector()?.status() ?? null,
6268
+ onFleetBudget: () => input.multiAgentHost.budgetView(),
6106
6269
  onFleetUsage: () => input.getDirector()?.snapshot() ?? null,
6107
6270
  onFleetKill: () => killFleet2(input.getDirector()),
6108
6271
  onFleetTerminate: async (subagentId) => {
@@ -6221,6 +6384,15 @@ async function handleFleetAction(input, action, target) {
6221
6384
  function formatFleetStatus(host) {
6222
6385
  const status = host.status();
6223
6386
  const lines = [color6.bold("Fleet status"), ` ${status.summary}`];
6387
+ const budget = status.budget ?? host.budgetView();
6388
+ lines.push(
6389
+ "",
6390
+ ...formatFleetBudgetLines(budget, {
6391
+ bold: color6.bold,
6392
+ dim: color6.dim,
6393
+ amber: color6.amber
6394
+ })
6395
+ );
6224
6396
  const icons = { running: "\u25CF", idle: "\u25CB", stopped: "\u2298" };
6225
6397
  const active2 = status.live.filter((agent) => agent.status === "running" || agent.status === "idle");
6226
6398
  if (active2.length > 0) {
@@ -6760,6 +6932,7 @@ function setupHqTelemetry(deps) {
6760
6932
  // src/wiring/lifecycle-plugins.ts
6761
6933
  import * as path15 from "node:path";
6762
6934
  import { getSharedProjectMailbox as getSharedProjectMailbox8 } from "@wrongstack/core/coordination";
6935
+ import { CouncilOrchestrator, OneShotOrchestrator as OneShotOrchestrator2 } from "@wrongstack/core/execution";
6763
6936
  import { countShellHooks, HookRegistry, HookRunner, shellHooksEqual } from "@wrongstack/core/hooks";
6764
6937
  import { allServers } from "@wrongstack/core/infrastructure";
6765
6938
  import { TOKENS as TOKENS8 } from "@wrongstack/core/kernel";
@@ -7348,6 +7521,130 @@ function createAgent(params) {
7348
7521
  });
7349
7522
  }
7350
7523
 
7524
+ // src/wiring/provider-utility-tools.ts
7525
+ import { createContextManagerTool as createContextManagerTool2 } from "@wrongstack/core/infrastructure";
7526
+ import { createCouncilTool, createOneShotLLMTool } from "@wrongstack/core/tools";
7527
+ import {
7528
+ createCouncilPersonaRegistry,
7529
+ createCouncilProfileRegistry,
7530
+ OneShotOrchestrator
7531
+ } from "@wrongstack/core/execution";
7532
+ import { ModelRouter } from "@wrongstack/core/models";
7533
+ async function adoptResumedProvider(input) {
7534
+ if (!input.resumedProvider && !input.resumedModel) return;
7535
+ const config = input.getConfig();
7536
+ const provider = input.resumedProvider?.trim() || config.provider;
7537
+ const model = input.resumedModel?.trim() || config.model;
7538
+ if (provider === config.provider && model === config.model) return;
7539
+ const error = await input.switchProviderAndModel(provider, model);
7540
+ if (error) {
7541
+ const current = input.getConfig();
7542
+ input.logger.warn(
7543
+ `Resume: could not switch to the session's model ${provider}/${model} (${error}); continuing with ${current.provider}/${current.model}.`
7544
+ );
7545
+ }
7546
+ }
7547
+ function createLiveModelRouter(getConfig) {
7548
+ return {
7549
+ pickForTask(role, description) {
7550
+ const config = getConfig();
7551
+ const router = new ModelRouter({
7552
+ ...config.modelMatrix ? { matrix: config.modelMatrix } : {},
7553
+ config: {
7554
+ provider: config.provider,
7555
+ model: config.model,
7556
+ ...config.providers ? { providers: config.providers } : {}
7557
+ }
7558
+ });
7559
+ return router.pickForTask(role, description);
7560
+ }
7561
+ };
7562
+ }
7563
+ function buildCouncilRegistries(cfg) {
7564
+ const base = {
7565
+ ...cfg?.defaultProfile ? { defaultProfile: cfg.defaultProfile } : {},
7566
+ ...cfg?.maxConcurrency !== void 0 ? { maxConcurrency: cfg.maxConcurrency } : {}
7567
+ };
7568
+ if (!cfg?.personas?.length && !cfg?.profiles?.length) return base;
7569
+ try {
7570
+ const personas = createCouncilPersonaRegistry(cfg.personas ?? []);
7571
+ const profiles = createCouncilProfileRegistry(
7572
+ cfg.profiles ?? [],
7573
+ personas
7574
+ );
7575
+ return { ...base, personas, profiles };
7576
+ } catch (error) {
7577
+ console.warn(
7578
+ `Council tool: ignoring tools.council personas/profiles \u2014 ${error instanceof Error ? error.message : String(error)}. Falling back to the built-in lenses and panels.`
7579
+ );
7580
+ return base;
7581
+ }
7582
+ }
7583
+ function registerProviderUtilityTools(input) {
7584
+ const config = input.getConfig();
7585
+ const llmTool = createOneShotLLMTool({
7586
+ buildProvider: input.buildProvider,
7587
+ getConfig: input.getConfig,
7588
+ fallbackProfileManager: input.fallbackProfileManager,
7589
+ defaultProvider: config.provider,
7590
+ defaultModel: config.model
7591
+ });
7592
+ registerOrOverride(input.toolRegistry, "llm", llmTool);
7593
+ const councilOrchestrator = new OneShotOrchestrator({
7594
+ buildProvider: input.buildProvider,
7595
+ getConfig: input.getConfig,
7596
+ fallbackProfileManager: input.fallbackProfileManager,
7597
+ statusTracker: input.statusTracker,
7598
+ // Council profiles route each seat by ROLE ('planner', 'critic',
7599
+ // 'analyst', 'security-reviewer'…) rather than pinning models. Without a
7600
+ // router those hints were inert: every seat fell through to the session
7601
+ // provider/model, so a three-seat panel asked one model three times and
7602
+ // reported a distinctness warning on every single call.
7603
+ modelRouter: createLiveModelRouter(input.getConfig)
7604
+ });
7605
+ registerOrOverride(
7606
+ input.toolRegistry,
7607
+ "council",
7608
+ createCouncilTool({
7609
+ caller: councilOrchestrator,
7610
+ fallbackProfileManager: input.fallbackProfileManager,
7611
+ ...buildCouncilRegistries(config.tools?.council)
7612
+ })
7613
+ );
7614
+ try {
7615
+ const summarizer = new OneShotOrchestrator({
7616
+ buildProvider: input.buildProvider,
7617
+ getConfig: input.getConfig,
7618
+ fallbackProfileManager: input.fallbackProfileManager,
7619
+ statusTracker: input.statusTracker
7620
+ });
7621
+ input.toolRegistry.override(
7622
+ "context_manager",
7623
+ createContextManagerTool2({
7624
+ compactor: input.compactor,
7625
+ summarizer: async (messages) => {
7626
+ const result = await summarizer.call({
7627
+ system: "Summarize concisely. Keep decisions and key facts.",
7628
+ messages,
7629
+ model: "deepseek-chat",
7630
+ maxTokens: 1024,
7631
+ timeoutMs: 3e4
7632
+ });
7633
+ return result.text || "(summary unavailable)";
7634
+ }
7635
+ })
7636
+ );
7637
+ } catch {
7638
+ }
7639
+ }
7640
+ function registerOrOverride(registry, name, tool) {
7641
+ try {
7642
+ registry.register(tool);
7643
+ } catch {
7644
+ registry.override(name, tool);
7645
+ }
7646
+ }
7647
+
7351
7648
  // src/wiring/lifecycle-plugins.ts
7352
7649
  async function setupLifecycleAndPlugins(deps) {
7353
7650
  const {
@@ -7516,11 +7813,9 @@ async function setupLifecycleAndPlugins(deps) {
7516
7813
  for (const cfg of Object.values(config.mcpServers ?? {})) {
7517
7814
  const preset = presets[cfg.name];
7518
7815
  const merged = preset ? { ...preset, ...cfg } : cfg;
7519
- try {
7520
- await mcpRegistry.start(merged);
7521
- } catch (err) {
7816
+ void mcpRegistry.start(merged).catch((err) => {
7522
7817
  logger.warn(`MCP server "${cfg.name}" failed to start`, err);
7523
- }
7818
+ });
7524
7819
  }
7525
7820
  }
7526
7821
  registerMcpObservability(healthRegistry, metricsSink, mcpRegistry);
@@ -7532,6 +7827,23 @@ async function setupLifecycleAndPlugins(deps) {
7532
7827
  () => hqPublisherRef.current
7533
7828
  );
7534
7829
  const notifier = new NotifierImpl();
7830
+ const getLiveConfig = () => configStore.get();
7831
+ const fallbackProfileManager = container.resolve(TOKENS8.FallbackProfileManager);
7832
+ const statusTracker = container.resolve(TOKENS8.ProviderModelStatusTracker);
7833
+ const buildUtilityProvider = (providerId) => buildProviderForIdRuntimeFn({ config: getLiveConfig(), providerRegistry }, providerId);
7834
+ const pluginOneShot = new OneShotOrchestrator2({
7835
+ buildProvider: buildUtilityProvider,
7836
+ getConfig: getLiveConfig,
7837
+ fallbackProfileManager,
7838
+ statusTracker,
7839
+ modelRouter: createLiveModelRouter(getLiveConfig),
7840
+ logger
7841
+ });
7842
+ const pluginCouncil = new CouncilOrchestrator({
7843
+ caller: pluginOneShot,
7844
+ fallbackProfileManager,
7845
+ ...buildCouncilRegistries(getLiveConfig().tools?.council)
7846
+ });
7535
7847
  const pluginHost = await setupPlugins({
7536
7848
  config,
7537
7849
  container,
@@ -7572,7 +7884,9 @@ async function setupLifecycleAndPlugins(deps) {
7572
7884
  model: config.model,
7573
7885
  getProvider: () => context.provider,
7574
7886
  getModel: () => context.model,
7575
- createProvider: (name) => buildProviderForIdRuntimeFn({ config: configStore.get(), providerRegistry }, name)
7887
+ createProvider: (name) => buildProviderForIdRuntimeFn({ config: configStore.get(), providerRegistry }, name),
7888
+ oneShot: (input) => pluginOneShot.call(input),
7889
+ council: (question) => pluginCouncil.ask(question)
7576
7890
  }
7577
7891
  });
7578
7892
  return {
@@ -7672,6 +7986,61 @@ import {
7672
7986
  } from "@wrongstack/core/storage";
7673
7987
  import { withCatalogCapabilities as withCatalogCapabilities2 } from "@wrongstack/providers";
7674
7988
  import { getSageService } from "@wrongstack/sage";
7989
+
7990
+ // src/wiring/fallback-gate.ts
7991
+ function createFallbackGate(_events) {
7992
+ const gateFn = (params) => {
7993
+ const { events: bus, sessionId, from, status, candidates, autoSwitchSeconds, requestId } = params;
7994
+ return runGate(bus, { sessionId, from, status, candidates, autoSwitchSeconds, requestId });
7995
+ };
7996
+ return gateFn;
7997
+ }
7998
+ function runGate(events, gateParams) {
7999
+ const { sessionId, from, status, candidates, autoSwitchSeconds, requestId } = gateParams;
8000
+ if (events.listenerCount("provider.fallback_pending") === 0) {
8001
+ return Promise.resolve(null);
8002
+ }
8003
+ return new Promise((resolve8) => {
8004
+ let settled = false;
8005
+ let timer;
8006
+ let deadline;
8007
+ const cleanup = () => {
8008
+ if (timer) clearTimeout(timer);
8009
+ if (deadline) clearTimeout(deadline);
8010
+ events.off("provider.fallback_choice", handler);
8011
+ };
8012
+ const finish = (result) => {
8013
+ if (settled) return;
8014
+ settled = true;
8015
+ cleanup();
8016
+ resolve8(result);
8017
+ };
8018
+ const handler = (payload) => {
8019
+ const p = payload;
8020
+ if (p?.requestId !== requestId) return;
8021
+ if (p.autoSwitch === true) {
8022
+ finish(null);
8023
+ return;
8024
+ }
8025
+ if (typeof p.providerId === "string" && typeof p.model === "string") {
8026
+ finish({ providerId: p.providerId, model: p.model });
8027
+ }
8028
+ };
8029
+ events.on("provider.fallback_choice", handler);
8030
+ deadline = setTimeout(() => finish(null), Math.round(autoSwitchSeconds * 1500));
8031
+ events.emit("provider.fallback_pending", {
8032
+ ...sessionId ? { sessionId } : {},
8033
+ from,
8034
+ status,
8035
+ candidates,
8036
+ autoSwitchSeconds,
8037
+ requestId,
8038
+ timestamp: Date.now()
8039
+ });
8040
+ });
8041
+ }
8042
+
8043
+ // src/wiring/provider-runtime-setup.ts
7675
8044
  function serializeProviderRuntimeSnapshot(snapshot) {
7676
8045
  return JSON.stringify(snapshot);
7677
8046
  }
@@ -7736,6 +8105,12 @@ function setupProviderRuntime(deps) {
7736
8105
  events,
7737
8106
  logger,
7738
8107
  statusTracker,
8108
+ // Fallback gate — shows a modal with countdown + manual pick in every
8109
+ // UI surface (TUI/WebUI/SimpleUI) before switching models. The gate
8110
+ // emits provider.fallback_pending and waits for provider.fallback_choice
8111
+ // or the auto-switch countdown.
8112
+ fallbackGate: createFallbackGate(events),
8113
+ fallbackGateSeconds: 7,
7739
8114
  ...cfg.fallbackStickiness?.primaryProbeInterval !== void 0 ? { primaryCooldownMs: cfg.fallbackStickiness.primaryProbeInterval } : {},
7740
8115
  ...cfg.fallbackStickiness?.stickyFallbackTurns !== void 0 ? { stickyFallbackTurns: cfg.fallbackStickiness.stickyFallbackTurns } : {}
7741
8116
  })
@@ -7977,79 +8352,6 @@ function warnUnlessMissing(logger, operation, error) {
7977
8352
  }
7978
8353
  }
7979
8354
 
7980
- // src/wiring/provider-utility-tools.ts
7981
- import { createContextManagerTool as createContextManagerTool2 } from "@wrongstack/core/infrastructure";
7982
- import { createCouncilTool, createOneShotLLMTool } from "@wrongstack/core/tools";
7983
- import { OneShotOrchestrator } from "@wrongstack/core/execution";
7984
- async function adoptResumedProvider(input) {
7985
- if (!input.resumedProvider && !input.resumedModel) return;
7986
- const config = input.getConfig();
7987
- const provider = input.resumedProvider?.trim() || config.provider;
7988
- const model = input.resumedModel?.trim() || config.model;
7989
- if (provider === config.provider && model === config.model) return;
7990
- const error = await input.switchProviderAndModel(provider, model);
7991
- if (error) {
7992
- const current = input.getConfig();
7993
- input.logger.warn(
7994
- `Resume: could not switch to the session's model ${provider}/${model} (${error}); continuing with ${current.provider}/${current.model}.`
7995
- );
7996
- }
7997
- }
7998
- function registerProviderUtilityTools(input) {
7999
- const config = input.getConfig();
8000
- const llmTool = createOneShotLLMTool({
8001
- buildProvider: input.buildProvider,
8002
- getConfig: input.getConfig,
8003
- fallbackProfileManager: input.fallbackProfileManager,
8004
- defaultProvider: config.provider,
8005
- defaultModel: config.model
8006
- });
8007
- registerOrOverride(input.toolRegistry, "llm", llmTool);
8008
- const councilOrchestrator = new OneShotOrchestrator({
8009
- buildProvider: input.buildProvider,
8010
- getConfig: input.getConfig,
8011
- fallbackProfileManager: input.fallbackProfileManager,
8012
- statusTracker: input.statusTracker
8013
- });
8014
- registerOrOverride(
8015
- input.toolRegistry,
8016
- "council",
8017
- createCouncilTool({ caller: councilOrchestrator, fallbackProfileManager: input.fallbackProfileManager })
8018
- );
8019
- try {
8020
- const summarizer = new OneShotOrchestrator({
8021
- buildProvider: input.buildProvider,
8022
- getConfig: input.getConfig,
8023
- fallbackProfileManager: input.fallbackProfileManager,
8024
- statusTracker: input.statusTracker
8025
- });
8026
- input.toolRegistry.override(
8027
- "context_manager",
8028
- createContextManagerTool2({
8029
- compactor: input.compactor,
8030
- summarizer: async (messages) => {
8031
- const result = await summarizer.call({
8032
- system: "Summarize concisely. Keep decisions and key facts.",
8033
- messages,
8034
- model: "deepseek-chat",
8035
- maxTokens: 1024,
8036
- timeoutMs: 3e4
8037
- });
8038
- return result.text || "(summary unavailable)";
8039
- }
8040
- })
8041
- );
8042
- } catch {
8043
- }
8044
- }
8045
- function registerOrOverride(registry, name, tool) {
8046
- try {
8047
- registry.register(tool);
8048
- } catch {
8049
- registry.override(name, tool);
8050
- }
8051
- }
8052
-
8053
8355
  // src/wiring/runtime-controller-deps.ts
8054
8356
  import { resolveConfiguredRefinerRef, resolveEnhanceFallbackRef } from "@wrongstack/core/execution";
8055
8357
  function createRuntimeControllerDeps(input) {
@@ -9004,8 +9306,9 @@ async function setupSession(params) {
9004
9306
  const tCounts = {};
9005
9307
  for (const t of dirState.tasks) tCounts[t.status] = (tCounts[t.status] ?? 0) + 1;
9006
9308
  const summary = Object.entries(tCounts).map(([k, v]) => `${v} ${k}`).join(", ");
9309
+ const spawnPart = typeof dirState.maxSpawns === "number" && Number.isFinite(dirState.maxSpawns) ? `, spawns ${dirState.spawnCount}/${dirState.maxSpawns} (checkpoint ceiling; live profile may differ)` : `, spawns used ${dirState.spawnCount}`;
9007
9310
  renderer.writeInfo(
9008
- `Prior fleet state: ${dirState.subagents.length} subagent${dirState.subagents.length === 1 ? "" : "s"}, tasks ${summary || "(none)"}.`
9311
+ `Prior fleet state: ${dirState.subagents.length} subagent${dirState.subagents.length === 1 ? "" : "s"}, tasks ${summary || "(none)"}${spawnPart}.`
9009
9312
  );
9010
9313
  }
9011
9314
  } catch {
@@ -10533,11 +10836,18 @@ ${color13.dim("YOLO enabled; tool calls run without approval unless an explicit
10533
10836
  // src/slash-commands/brain.ts
10534
10837
  import { randomUUID as randomUUID5 } from "node:crypto";
10535
10838
  import { readFile as readFile7 } from "node:fs/promises";
10839
+ import { BUILTIN_COUNCIL_PERSONA_IDS, BUILTIN_COUNCIL_PERSONAS } from "@wrongstack/core/execution";
10536
10840
  import { color as color14 } from "@wrongstack/core/utils";
10537
10841
  import { parseModelRef } from "@wrongstack/core/agent";
10538
10842
  var RISK_LEVELS = /* @__PURE__ */ new Set(["off", "low", "medium", "high", "all"]);
10539
10843
  var COUNCIL_RISKS = /* @__PURE__ */ new Set(["medium", "high", "critical"]);
10540
- var PERSONA_SHORTHANDS = /* @__PURE__ */ new Set(["executor", "skeptic", "auditor"]);
10844
+ var COUNCIL_DISTINCTNESS = /* @__PURE__ */ new Set(["none", "model", "provider"]);
10845
+ var COUNCIL_NUMERIC_OPS = {
10846
+ timeout: "perCallTimeoutMs",
10847
+ concurrency: "maxConcurrency",
10848
+ judgetokens: "judgeMaxTokens"
10849
+ };
10850
+ var PERSONA_SHORTHANDS = new Set(BUILTIN_COUNCIL_PERSONA_IDS);
10541
10851
  var HEURISTIC_FIELDS = {
10542
10852
  lowrisk: "lowRiskAutoAnswer",
10543
10853
  blocked: "blockedResolved",
@@ -10613,8 +10923,11 @@ function buildBrainCommand(opts) {
10613
10923
  " /brain human-timeout <ms|off> Interactive escalation wait before terminal policy",
10614
10924
  " /brain council on|off Enable/disable the multi-LLM council",
10615
10925
  " /brain council minrisk <medium|high|critical>",
10616
- " /brain council voters <seat> [<seat> ...] seat = <ref>[:executor|:skeptic|:auditor][:veto][:w=N]",
10926
+ " /brain council voters <seat> [<seat> ...] seat = <ref>[:<persona>][:veto][:w=N]",
10927
+ " /brain council personas List the built-in decision lenses",
10617
10928
  " /brain council judge <ref|auto> | quorum <0..1> | approval <0..1>",
10929
+ " /brain council distinctness <none|model|provider> warn on a non-diverse panel",
10930
+ " /brain council timeout|concurrency|judgetokens <n|default>",
10618
10931
  " /brain ledger [n] Show the last n rows (default 15) of the persistent decision ledger",
10619
10932
  " /brain ledger on|off | autodeny <n>",
10620
10933
  " /brain stats Per-tier decision counts: how often the Brain actually calls a model",
@@ -10835,12 +11148,24 @@ function buildBrainCommand(opts) {
10835
11148
  if (op === "voters") {
10836
11149
  const seats = rest.slice(1).map(parseSeat);
10837
11150
  if (seats.length === 0 || seats.some((s) => s === null)) {
10838
- const msg3 = "Usage: /brain council voters <ref[:executor|:skeptic|:auditor][:veto][:w=N]> [...]";
11151
+ const msg3 = `Usage: /brain council voters <ref[:<persona>][:veto][:w=N]> [...] \u2014 personas: ${BUILTIN_COUNCIL_PERSONA_IDS.join(", ")} (see /brain council personas)`;
10839
11152
  opts.renderer.writeWarning(msg3);
10840
11153
  return { message: msg3 };
10841
11154
  }
10842
11155
  return applyPatch({ council: { voters: seats } }, councilSummary);
10843
11156
  }
11157
+ if (op === "personas") {
11158
+ const lines = [
11159
+ "Council decision lenses (built-in):",
11160
+ ...BUILTIN_COUNCIL_PERSONAS.map(
11161
+ (p) => ` ${color14.cyan(p.id.padEnd(15))} ${p.description}${p.defaultVeto ? color14.dim(" [veto by default]") : ""}`
11162
+ ),
11163
+ color14.dim("Any other string is used verbatim as a custom lens instruction.")
11164
+ ];
11165
+ const msg3 = lines.join("\n");
11166
+ opts.renderer.write(msg3);
11167
+ return { message: msg3 };
11168
+ }
10844
11169
  if (op === "judge") {
10845
11170
  const ref = rest[1];
10846
11171
  if (!ref) {
@@ -10857,7 +11182,33 @@ function buildBrainCommand(opts) {
10857
11182
  (s) => `Brain council ${op} set to ${color14.cyan(String(op === "quorum" ? s.council.quorum ?? 0.5 : s.council.approval ?? 0.5))}`
10858
11183
  );
10859
11184
  }
10860
- const msg2 = `Unknown council subcommand: ${op}. Use on, off, minrisk, voters, judge, quorum, or approval.`;
11185
+ if (op === "distinctness") {
11186
+ const mode = (rest[1] ?? "").toLowerCase();
11187
+ if (!COUNCIL_DISTINCTNESS.has(mode)) {
11188
+ const msg3 = "Usage: /brain council distinctness <none|model|provider>";
11189
+ opts.renderer.writeWarning(msg3);
11190
+ return { message: msg3 };
11191
+ }
11192
+ return applyPatch(
11193
+ { council: { distinctness: mode } },
11194
+ (s) => `Brain council distinctness set to ${color14.cyan(s.council.distinctness)}${mode === "none" ? color14.dim(" \u2014 a non-diverse panel will no longer be reported") : ""}`
11195
+ );
11196
+ }
11197
+ if (COUNCIL_NUMERIC_OPS[op]) {
11198
+ const field = COUNCIL_NUMERIC_OPS[op];
11199
+ const raw = rest[1];
11200
+ if (!raw) {
11201
+ const msg3 = `Usage: /brain council ${op} <positive integer | default>`;
11202
+ opts.renderer.writeWarning(msg3);
11203
+ return { message: msg3 };
11204
+ }
11205
+ const value = raw.toLowerCase() === "default" ? null : Number(raw);
11206
+ return applyPatch({ council: { [field]: value } }, (s) => {
11207
+ const applied = s.council[field];
11208
+ return `Brain council ${op} set to ${color14.cyan(applied === void 0 ? "default" : String(applied))}`;
11209
+ });
11210
+ }
11211
+ const msg2 = `Unknown council subcommand: ${op}. Use on, off, minrisk, voters, personas, judge, quorum, approval, distinctness, timeout, concurrency, or judgetokens.`;
10861
11212
  opts.renderer.writeWarning(msg2);
10862
11213
  return { message: msg2 };
10863
11214
  }
@@ -11996,6 +12347,7 @@ function cacheMechanismLabel(providerId, cacheControl) {
11996
12347
  if (id.includes("google") || id.includes("gemini")) {
11997
12348
  return "implicit (auto) + explicit cachedContents (opt-in)";
11998
12349
  }
12350
+ if (id.includes("gateway")) return "automatic (Gateway-managed, per routed upstream)";
11999
12351
  if (cacheControl === "auto") return "automatic + prompt_cache_key routing";
12000
12352
  return "none / provider-managed";
12001
12353
  }
@@ -12998,6 +13350,58 @@ function diagnoseConfig(cfg, plugins = []) {
12998
13350
  }
12999
13351
  }
13000
13352
  }
13353
+ if ("fleet" in fixed) {
13354
+ if (!isPlainObject(fixed["fleet"])) {
13355
+ findings.push({
13356
+ path: "fleet",
13357
+ problem: `expected object, got ${JSON.stringify(fixed["fleet"])}`,
13358
+ severity: "error",
13359
+ fix: "removed (built-in defaults apply)"
13360
+ });
13361
+ delete fixed["fleet"];
13362
+ } else {
13363
+ const fleet = fixed["fleet"];
13364
+ if ("budget" in fleet) {
13365
+ if (!isPlainObject(fleet["budget"])) {
13366
+ findings.push({
13367
+ path: "fleet.budget",
13368
+ problem: `expected object, got ${JSON.stringify(fleet["budget"])}`,
13369
+ severity: "error",
13370
+ fix: "removed (built-in defaults apply)"
13371
+ });
13372
+ delete fleet["budget"];
13373
+ } else {
13374
+ const budget = fleet["budget"];
13375
+ for (const key of ["maxSpawns", "maxTokens", "maxCostUsd"]) {
13376
+ if (!(key in budget)) continue;
13377
+ const v = budget[key];
13378
+ const n = coerceNumber(v);
13379
+ if (n === void 0) {
13380
+ delete budget[key];
13381
+ findings.push({
13382
+ path: `fleet.budget.${key}`,
13383
+ problem: `expected a non-negative number, got ${JSON.stringify(v)}`,
13384
+ severity: "error",
13385
+ fix: "removed (built-in default applies)"
13386
+ });
13387
+ } else {
13388
+ const clamped = Math.max(0, n);
13389
+ const next = key === "maxCostUsd" ? clamped : Math.floor(clamped);
13390
+ if (next !== v) {
13391
+ budget[key] = next;
13392
+ findings.push({
13393
+ path: `fleet.budget.${key}`,
13394
+ problem: `expected a non-negative ${key === "maxCostUsd" ? "number" : "integer"}, got ${JSON.stringify(v)}`,
13395
+ severity: "error",
13396
+ fix: `set to ${next}`
13397
+ });
13398
+ }
13399
+ }
13400
+ }
13401
+ }
13402
+ }
13403
+ }
13404
+ }
13001
13405
  for (const key of ["provider", "model"]) {
13002
13406
  if (key in fixed && typeof fixed[key] !== "string") {
13003
13407
  findings.push({
@@ -13281,7 +13685,7 @@ function buildDoctorCommand(opts) {
13281
13685
  ].join("\n");
13282
13686
  async function loadPluginSchemas() {
13283
13687
  try {
13284
- const { BUILTIN_PLUGIN_FACTORIES } = await import("./plugins-ETY6W3DC.js");
13688
+ const { BUILTIN_PLUGIN_FACTORIES } = await import("./plugins-56CMWMPR.js");
13285
13689
  const settled = await Promise.allSettled(BUILTIN_PLUGIN_FACTORIES.map((f) => f()));
13286
13690
  const loaded = [];
13287
13691
  for (const s of settled) {
@@ -15198,6 +15602,17 @@ async function handleStatus(opts, cmd) {
15198
15602
  lines.push(` ${id} ${name} ${statusColor} ${ext}${task}`);
15199
15603
  }
15200
15604
  }
15605
+ const budget = opts.onFleetBudget?.();
15606
+ if (budget) {
15607
+ lines.push(
15608
+ "",
15609
+ ...formatFleetBudgetLines(budget, {
15610
+ bold: color26.bold,
15611
+ dim: color26.dim,
15612
+ amber: color26.amber
15613
+ })
15614
+ );
15615
+ }
15201
15616
  const msg2 = lines.join("\n");
15202
15617
  opts.renderer.write(msg2);
15203
15618
  return { message: msg2 };
@@ -16320,6 +16735,78 @@ async function fileExists(filePath) {
16320
16735
  }
16321
16736
  }
16322
16737
 
16738
+ // src/slash-commands/intake.ts
16739
+ import {
16740
+ AllowAllIntakeAuthorizer,
16741
+ RequirementIntakeService,
16742
+ RequirementIntakeStore
16743
+ } from "@wrongstack/requirement-intake";
16744
+ import { ensureProjectIdentity, resolveWstackPaths as resolveWstackPaths2 } from "@wrongstack/core/utils";
16745
+ var INTAKE_ACTOR = { id: "cli-operator", type: "user" };
16746
+ function lastUserPrompt(opts) {
16747
+ const ctx = opts.context;
16748
+ if (!ctx) return "";
16749
+ for (let index = ctx.messages.length - 1; index >= 0; index -= 1) {
16750
+ const message = ctx.messages[index];
16751
+ if (message?.role === "user" && typeof message.content === "string") {
16752
+ const trimmed = message.content.trim();
16753
+ if (trimmed.length > 0) return trimmed;
16754
+ }
16755
+ }
16756
+ return "";
16757
+ }
16758
+ function buildIntakeCommand(opts) {
16759
+ return {
16760
+ name: "intake",
16761
+ category: "Run",
16762
+ description: "Create and submit a requirement intake record from the current prompt (or given text)",
16763
+ argsHint: "[request text]",
16764
+ help: [
16765
+ "/intake [text] Create + submit a requirement intake record.",
16766
+ " No text \u2192 uses the most recent prompt in this session.",
16767
+ "",
16768
+ "The exact text is preserved verbatim as the record's original request;",
16769
+ "the record is stored under the project state dir and is ready for",
16770
+ "downstream modules (SDD interview kickoff, planning)."
16771
+ ].join("\n"),
16772
+ async run(args) {
16773
+ const text = args.trim() || lastUserPrompt(opts);
16774
+ if (!text) {
16775
+ return {
16776
+ message: "Nothing to intake \u2014 give the request as text or submit a prompt first.\nUsage: /intake <request text>"
16777
+ };
16778
+ }
16779
+ const identity = await ensureProjectIdentity(opts.projectRoot);
16780
+ const projectId = identity.identity.projectId;
16781
+ const baseDir = opts.paths?.projectRequirementIntakes ?? resolveWstackPaths2({ projectRoot: opts.projectRoot }).projectRequirementIntakes;
16782
+ const service = new RequirementIntakeService({
16783
+ store: new RequirementIntakeStore({ baseDir }),
16784
+ authorizer: new AllowAllIntakeAuthorizer()
16785
+ });
16786
+ const ctx = { ...INTAKE_ACTOR, projectId };
16787
+ const { record, created, idempotent } = await service.createIntake(
16788
+ { projectId, originalRequest: text, requestedBy: ctx.id },
16789
+ ctx
16790
+ );
16791
+ const { record: submitted } = await service.submitIntake(record.id, ctx);
16792
+ return {
16793
+ message: [
16794
+ idempotent ? "\u26A0 Already recorded \u2014 resubmitted the existing record:" : "\u{1F4E5} Requirement intake recorded:",
16795
+ ` id: ${submitted.id}`,
16796
+ ` title: ${submitted.title}`,
16797
+ ` type: ${submitted.requestType}`,
16798
+ ` status: ${submitted.status} (${created ? "new" : "existing"})`,
16799
+ ` stored: ${baseDir}`,
16800
+ "",
16801
+ "Use /sdd to turn this into a specification. Records live under the",
16802
+ "project state dir (see `stored` above) and are consumed by the",
16803
+ "WebUI requirement-intake API."
16804
+ ].join("\n")
16805
+ };
16806
+ }
16807
+ };
16808
+ }
16809
+
16323
16810
  // src/slash-commands/kanban.ts
16324
16811
  import {
16325
16812
  addCheckToTask,
@@ -18300,7 +18787,7 @@ function errorMessage(err) {
18300
18787
  }
18301
18788
 
18302
18789
  // src/slash-commands/memory.ts
18303
- import { toErrorMessage as toErrorMessage17 } from "@wrongstack/core/utils";
18790
+ import { toErrorMessage as toErrorMessage18 } from "@wrongstack/core/utils";
18304
18791
  import { getSageSurface as getSageSurface2 } from "@wrongstack/sage";
18305
18792
 
18306
18793
  // src/slash-commands/memory-compact.ts
@@ -18564,6 +19051,240 @@ function parseCompactEntries(raw) {
18564
19051
  return entries;
18565
19052
  }
18566
19053
 
19054
+ // src/slash-commands/memory-triage.ts
19055
+ import { toErrorMessage as toErrorMessage17 } from "@wrongstack/core/utils";
19056
+ import { runTriage, formatTriageReport } from "@wrongstack/sage";
19057
+ var DEFAULT_MAX_PHASE3 = 1e3;
19058
+ var DEFAULT_MAX_PHASE4_PAIRS = 50;
19059
+ async function runTriageCommand(opts, args) {
19060
+ const Sage = getSage(opts);
19061
+ if (!Sage) return { message: "No SAGE surface available." };
19062
+ let dryRun = true;
19063
+ let limit;
19064
+ let maxPhase3 = DEFAULT_MAX_PHASE3;
19065
+ let maxPhase4Pairs = DEFAULT_MAX_PHASE4_PAIRS;
19066
+ const flagErrors = [];
19067
+ for (let i = 0; i < args.length; i++) {
19068
+ const token = args[i];
19069
+ if (!token) continue;
19070
+ if (!token.startsWith("--")) continue;
19071
+ const name = token.slice(2).toLowerCase();
19072
+ const next = args[i + 1];
19073
+ switch (name) {
19074
+ case "dry-run":
19075
+ dryRun = true;
19076
+ break;
19077
+ case "apply":
19078
+ dryRun = false;
19079
+ break;
19080
+ case "limit": {
19081
+ if (next === void 0 || next.startsWith("--")) {
19082
+ flagErrors.push("--limit needs a value.");
19083
+ continue;
19084
+ }
19085
+ const parsed = Number.parseInt(next, 10);
19086
+ if (!Number.isFinite(parsed) || parsed < 1) {
19087
+ flagErrors.push(`--limit must be a positive integer (got "${next}").`);
19088
+ continue;
19089
+ }
19090
+ limit = Math.min(500, Math.max(1, parsed));
19091
+ i++;
19092
+ break;
19093
+ }
19094
+ case "max-phase3": {
19095
+ if (next === void 0 || next.startsWith("--")) {
19096
+ flagErrors.push("--max-phase3 needs a value.");
19097
+ continue;
19098
+ }
19099
+ const parsed = Number.parseInt(next, 10);
19100
+ if (!Number.isFinite(parsed) || parsed < 1) {
19101
+ flagErrors.push(`--max-phase3 must be a positive integer (got "${next}").`);
19102
+ continue;
19103
+ }
19104
+ maxPhase3 = parsed;
19105
+ i++;
19106
+ break;
19107
+ }
19108
+ case "max-phase4-pairs": {
19109
+ if (next === void 0 || next.startsWith("--")) {
19110
+ flagErrors.push("--max-phase4-pairs needs a value.");
19111
+ continue;
19112
+ }
19113
+ const parsed = Number.parseInt(next, 10);
19114
+ if (!Number.isFinite(parsed) || parsed < 1) {
19115
+ flagErrors.push(`--max-phase4-pairs must be a positive integer (got "${next}").`);
19116
+ continue;
19117
+ }
19118
+ maxPhase4Pairs = parsed;
19119
+ i++;
19120
+ break;
19121
+ }
19122
+ default:
19123
+ flagErrors.push(`Unknown flag "--${name}".`);
19124
+ }
19125
+ }
19126
+ if (flagErrors.length > 0) {
19127
+ return {
19128
+ message: `Cannot triage:
19129
+ - ${flagErrors.join("\n- ")}
19130
+
19131
+ Usage: /memory triage [--dry-run|--apply] [--limit N] [--max-phase3 N] [--max-phase4-pairs N]`
19132
+ };
19133
+ }
19134
+ const memories = await loadActiveMemories(Sage, limit);
19135
+ if (memories.length === 0) {
19136
+ return { message: "No active memories to triage." };
19137
+ }
19138
+ const provider = opts.llmProvider;
19139
+ const model = opts.llmModel ?? "";
19140
+ const callLlm = provider?.complete ? async (system, userPrompt) => {
19141
+ const signal = AbortSignal.timeout(3e4);
19142
+ const response = await provider.complete(
19143
+ {
19144
+ model,
19145
+ system: [{ type: "text", text: system }],
19146
+ messages: [{ role: "user", content: userPrompt }],
19147
+ maxTokens: 60,
19148
+ temperature: 0.1
19149
+ },
19150
+ { signal }
19151
+ );
19152
+ return response.content.filter((b) => b.type === "text").map((b) => b.text).join("").trim();
19153
+ } : async () => "3";
19154
+ let report;
19155
+ try {
19156
+ report = await runTriage(memories, callLlm, {
19157
+ dryRun,
19158
+ maxPhase3Calls: maxPhase3,
19159
+ maxPhase4Pairs,
19160
+ verbose: false
19161
+ });
19162
+ } catch (err) {
19163
+ return { message: `Triage failed: ${toErrorMessage17(err)}` };
19164
+ }
19165
+ if (!dryRun) {
19166
+ const applyReport = await applyDispatch(Sage, report);
19167
+ return {
19168
+ message: formatTriageReport(report) + "\n\n" + applyReport
19169
+ };
19170
+ }
19171
+ return { message: formatTriageReport(report) };
19172
+ }
19173
+ function getSage(opts) {
19174
+ if (!opts.memoryStore) return null;
19175
+ try {
19176
+ const { getSageSurface: getSageSurface3 } = __require("@wrongstack/sage");
19177
+ return getSageSurface3(opts.memoryStore);
19178
+ } catch {
19179
+ return null;
19180
+ }
19181
+ }
19182
+ async function loadActiveMemories(Sage, limit) {
19183
+ const all = [];
19184
+ let cursor;
19185
+ while (true) {
19186
+ const pageSize = limit ? Math.min(500, limit - all.length) : 500;
19187
+ if (pageSize <= 0) break;
19188
+ const page = await Sage.listSagePage({
19189
+ statuses: ["active", "stale"],
19190
+ limit: pageSize,
19191
+ cursor
19192
+ });
19193
+ all.push(...page.memories);
19194
+ if (limit && all.length >= limit) break;
19195
+ if (!page.nextCursor) break;
19196
+ cursor = page.nextCursor;
19197
+ }
19198
+ return limit ? all.slice(0, limit) : all;
19199
+ }
19200
+ async function applyDispatch(Sage, report) {
19201
+ const lines = ["## Apply Results", ""];
19202
+ let autoOk = 0;
19203
+ let autoFail = 0;
19204
+ for (const action of report.dispatch.autoApply) {
19205
+ const patch = {};
19206
+ for (const update of action.updates) {
19207
+ if (update.field === "status") {
19208
+ patch.status = update.value;
19209
+ } else if (update.field === "confidence") {
19210
+ patch.confidence = update.value;
19211
+ } else if (update.field === "importance") {
19212
+ patch.importance = update.value;
19213
+ }
19214
+ }
19215
+ try {
19216
+ await Sage.updateSage(action.memoryId, patch);
19217
+ autoOk++;
19218
+ } catch (err) {
19219
+ autoFail++;
19220
+ lines.push(` \u2717 Failed to update ${action.memoryId}: ${toErrorMessage17(err)}`);
19221
+ }
19222
+ }
19223
+ lines.push(`**Auto-apply:** ${autoOk} succeeded, ${autoFail} failed`);
19224
+ lines.push("");
19225
+ let mergeOk = 0;
19226
+ let mergeFail = 0;
19227
+ for (const merge of report.merges.merges) {
19228
+ try {
19229
+ await Sage.updateSage(merge.supersededId, { status: "superseded" });
19230
+ await Sage.updateSage(merge.keeperId, { supersedes: [merge.supersededId] });
19231
+ mergeOk++;
19232
+ } catch (err) {
19233
+ mergeFail++;
19234
+ lines.push(` \u2717 Failed to merge ${merge.supersededId} \u2192 ${merge.keeperId}: ${toErrorMessage17(err)}`);
19235
+ }
19236
+ }
19237
+ lines.push(`**Merges:** ${mergeOk} succeeded, ${mergeFail} failed`);
19238
+ lines.push("");
19239
+ const proposalResult = await fileProposals(Sage, report.dispatch.proposals);
19240
+ if (proposalResult.total > 0) {
19241
+ lines.push(
19242
+ `**Proposals:** ${proposalResult.filed} of ${proposalResult.total} filed via memory_candidates (use \`/memory candidates\` to accept/reject).`
19243
+ );
19244
+ }
19245
+ for (const failure of proposalResult.failures) {
19246
+ lines.push(` \u2717 Failed to file proposal for ${failure.memoryId}: ${failure.error}`);
19247
+ }
19248
+ return lines.join("\n");
19249
+ }
19250
+ async function fileProposals(Sage, proposals) {
19251
+ const inputs = [];
19252
+ const failures = [];
19253
+ let filed = 0;
19254
+ for (const proposal of proposals) {
19255
+ const input = {
19256
+ text: proposal.memoryText,
19257
+ targetMemoryId: proposal.memoryId,
19258
+ reviewReason: proposal.reason,
19259
+ suggestedAction: proposal.suggestedAction,
19260
+ kind: "memory_review",
19261
+ scope: "project",
19262
+ importance: 0.5,
19263
+ confidence: 0.9,
19264
+ tags: ["triage"],
19265
+ anchors: [],
19266
+ sources: [{ type: "project_instruction" }]
19267
+ };
19268
+ inputs.push(input);
19269
+ try {
19270
+ await Sage.createCandidate(input);
19271
+ filed++;
19272
+ } catch (err) {
19273
+ failures.push({
19274
+ memoryId: proposal.memoryId,
19275
+ error: toErrorMessage17(err)
19276
+ });
19277
+ }
19278
+ }
19279
+ return {
19280
+ filed,
19281
+ failed: failures.length,
19282
+ total: proposals.length,
19283
+ failures,
19284
+ inputs
19285
+ };
19286
+ }
19287
+
18567
19288
  // src/slash-commands/memory-formatters.ts
18568
19289
  function previewText(text, maxLen) {
18569
19290
  if (text.length <= maxLen) return text;
@@ -18918,7 +19639,7 @@ function buildMemoryCommand(opts) {
18918
19639
  return {
18919
19640
  name: "memory",
18920
19641
  category: "Inspect",
18921
- description: "Inspect or edit persistent memory: /memory [show|search|file|path|for-file|graph|gather|remember|update|delete|forget|hygiene|verify|candidates|audit|import-legacy|clear|compact|compact-log|stats|audience]",
19642
+ description: "Inspect or edit persistent memory: /memory [show|search|file|path|for-file|graph|gather|remember|update|delete|forget|hygiene|verify|candidates|triage|audit|import-legacy|clear|compact|compact-log|stats|audience]",
18922
19643
  async run(args) {
18923
19644
  const store = opts.memoryStore;
18924
19645
  if (!store) return { message: "No memory store configured." };
@@ -18981,7 +19702,7 @@ function buildMemoryCommand(opts) {
18981
19702
  message: `Remembered \`${memory.id}\` [${memory.kind}] ${memory.text}${tags}`
18982
19703
  };
18983
19704
  } catch (err) {
18984
- return { message: `Could not remember: ${toErrorMessage17(err)}` };
19705
+ return { message: `Could not remember: ${toErrorMessage18(err)}` };
18985
19706
  }
18986
19707
  }
18987
19708
  case "update":
@@ -19019,7 +19740,7 @@ function buildMemoryCommand(opts) {
19019
19740
  message: `Updated \`${memory.id}\` [${memory.kind}|${memory.status}] ${memory.text}`
19020
19741
  };
19021
19742
  } catch (err) {
19022
- return { message: `Could not update: ${toErrorMessage17(err)}` };
19743
+ return { message: `Could not update: ${toErrorMessage18(err)}` };
19023
19744
  }
19024
19745
  }
19025
19746
  case "delete":
@@ -19034,7 +19755,7 @@ function buildMemoryCommand(opts) {
19034
19755
  await Sage.deleteSage(id, reason, { force: true });
19035
19756
  return { message: `Deleted \`${id}\`.` };
19036
19757
  } catch (err) {
19037
- return { message: `Could not delete: ${toErrorMessage17(err)}` };
19758
+ return { message: `Could not delete: ${toErrorMessage18(err)}` };
19038
19759
  }
19039
19760
  }
19040
19761
  case "forget":
@@ -19253,7 +19974,7 @@ function buildMemoryCommand(opts) {
19253
19974
  }
19254
19975
  return { message: lines.join("\n") };
19255
19976
  } catch (err) {
19256
- return { message: `gather failed: ${toErrorMessage17(err)}` };
19977
+ return { message: `gather failed: ${toErrorMessage18(err)}` };
19257
19978
  }
19258
19979
  }
19259
19980
  case "verify": {
@@ -19289,6 +20010,10 @@ function buildMemoryCommand(opts) {
19289
20010
  message: formatCandidates(await Sage.listCandidates(action === "all"))
19290
20011
  };
19291
20012
  }
20013
+ case "triage": {
20014
+ if (!Sage) return requiresSage("triage");
20015
+ return runTriageCommand(opts, rest);
20016
+ }
19292
20017
  case "audit": {
19293
20018
  if (!Sage?.readAudit) return requiresSage("audit");
19294
20019
  return { message: formatAudit(await Sage.readAudit(50)) };
@@ -19344,7 +20069,7 @@ function buildMemoryCommand(opts) {
19344
20069
  File size reduced. Audit-logged as \`memory.log_compacted\`.`
19345
20070
  };
19346
20071
  } catch (err) {
19347
- return { message: `Compaction failed: ${toErrorMessage17(err)}` };
20072
+ return { message: `Compaction failed: ${toErrorMessage18(err)}` };
19348
20073
  }
19349
20074
  }
19350
20075
  case "stats": {
@@ -19404,6 +20129,7 @@ File size reduced. Audit-logged as \`memory.log_compacted\`.`
19404
20129
  "hygiene",
19405
20130
  "verify",
19406
20131
  "candidates",
20132
+ "triage",
19407
20133
  "audit",
19408
20134
  "import-legacy",
19409
20135
  "clear",
@@ -19571,7 +20297,7 @@ async function runAudienceMemory(store, rest) {
19571
20297
  message: `Remembered \`${memory.id}\` for ${formatAudienceSelector(memory.audience)}: ${memory.text}`
19572
20298
  };
19573
20299
  } catch (err) {
19574
- return { message: `Could not remember: ${toErrorMessage17(err)}` };
20300
+ return { message: `Could not remember: ${toErrorMessage18(err)}` };
19575
20301
  }
19576
20302
  }
19577
20303
  if (sub === "clear") {
@@ -19583,7 +20309,7 @@ async function runAudienceMemory(store, rest) {
19583
20309
  message: `Cleared audience scope from \`${id}\` \u2014 it is now general project memory.`
19584
20310
  };
19585
20311
  } catch (err) {
19586
- return { message: `Could not clear audience: ${toErrorMessage17(err)}` };
20312
+ return { message: `Could not clear audience: ${toErrorMessage18(err)}` };
19587
20313
  }
19588
20314
  }
19589
20315
  if (sub === "search" || sub === "find") {
@@ -20212,7 +20938,7 @@ function buildModelCapsCommand(opts) {
20212
20938
 
20213
20939
  // src/slash-commands/models.ts
20214
20940
  import * as fs15 from "node:fs/promises";
20215
- import { toErrorMessage as toErrorMessage18 } from "@wrongstack/core/utils";
20941
+ import { toErrorMessage as toErrorMessage19 } from "@wrongstack/core/utils";
20216
20942
  import { atomicWrite as atomicWrite7, color as color37 } from "@wrongstack/core/utils";
20217
20943
  import { ConfigError as ConfigError4, ToolValidationError as ToolValidationError4 } from "@wrongstack/core/types";
20218
20944
  import { decryptConfigSecrets as decryptConfigSecrets3, encryptConfigSecrets as encryptConfigSecrets3, noOpVault as noOpVault4 } from "@wrongstack/core/security";
@@ -20447,7 +21173,7 @@ function buildModelsCommand(opts) {
20447
21173
  };
20448
21174
  } catch (err) {
20449
21175
  return {
20450
- message: `${color37.red("models error")}: ${toErrorMessage18(err)}`
21176
+ message: `${color37.red("models error")}: ${toErrorMessage19(err)}`
20451
21177
  };
20452
21178
  }
20453
21179
  }
@@ -21296,7 +22022,7 @@ function buildPruneCommand(opts) {
21296
22022
  // src/slash-commands/refiner.ts
21297
22023
  import { color as color42 } from "@wrongstack/core/utils";
21298
22024
  import { noOpVault as noOpVault5 } from "@wrongstack/core/security";
21299
- import { toErrorMessage as toErrorMessage19 } from "@wrongstack/core/utils";
22025
+ import { toErrorMessage as toErrorMessage20 } from "@wrongstack/core/utils";
21300
22026
  function buildRefinerCommand(opts) {
21301
22027
  const help = [
21302
22028
  "Usage:",
@@ -21394,7 +22120,7 @@ function buildRefinerCommand(opts) {
21394
22120
  };
21395
22121
  } catch (err) {
21396
22122
  return {
21397
- message: `${color42.red("refiner error")}: ${toErrorMessage19(err)}`
22123
+ message: `${color42.red("refiner error")}: ${toErrorMessage20(err)}`
21398
22124
  };
21399
22125
  }
21400
22126
  }
@@ -21416,7 +22142,7 @@ function buildRefinerCommand(opts) {
21416
22142
  };
21417
22143
  } catch (err) {
21418
22144
  return {
21419
- message: `${color42.red("refiner error")}: ${toErrorMessage19(err)}`
22145
+ message: `${color42.red("refiner error")}: ${toErrorMessage20(err)}`
21420
22146
  };
21421
22147
  }
21422
22148
  }
@@ -22594,7 +23320,7 @@ ${sddHelp()}`
22594
23320
  // src/slash-commands/session.ts
22595
23321
  import { color as color43, isPidAlive } from "@wrongstack/core/utils";
22596
23322
  import { SessionRecovery } from "@wrongstack/core/storage";
22597
- import { toErrorMessage as toErrorMessage20 } from "@wrongstack/core/utils";
23323
+ import { toErrorMessage as toErrorMessage21 } from "@wrongstack/core/utils";
22598
23324
  function statusIcon2(status) {
22599
23325
  switch (status) {
22600
23326
  case "active":
@@ -22712,7 +23438,7 @@ function buildLoadCommand(opts) {
22712
23438
  message: name ? color43.green(`Renamed ${targetId} \u2192 "${name}"`) : color43.green(`Cleared name on ${targetId} (title: "${summary.title}")`)
22713
23439
  };
22714
23440
  } catch (err) {
22715
- return { message: color43.red(`Rename failed: ${toErrorMessage20(err)}`) };
23441
+ return { message: color43.red(`Rename failed: ${toErrorMessage21(err)}`) };
22716
23442
  }
22717
23443
  }
22718
23444
  if (first === "delete") {
@@ -22738,7 +23464,7 @@ function buildLoadCommand(opts) {
22738
23464
  await opts.sessionStore.delete(targetId);
22739
23465
  return { message: color43.green(`Deleted session ${targetId}`) };
22740
23466
  } catch (err) {
22741
- return { message: color43.red(`Delete failed: ${toErrorMessage20(err)}`) };
23467
+ return { message: color43.red(`Delete failed: ${toErrorMessage21(err)}`) };
22742
23468
  }
22743
23469
  }
22744
23470
  const showIncomplete = parts.includes("--incomplete") || parts.includes("-i");
@@ -23076,7 +23802,7 @@ async function killSession(sessionId, confirm) {
23076
23802
  } catch (err) {
23077
23803
  return {
23078
23804
  message: color43.red(
23079
- `Failed to kill session: ${toErrorMessage20(err)}`
23805
+ `Failed to kill session: ${toErrorMessage21(err)}`
23080
23806
  )
23081
23807
  };
23082
23808
  }
@@ -23084,7 +23810,7 @@ async function killSession(sessionId, confirm) {
23084
23810
 
23085
23811
  // src/slash-commands/setmodel.ts
23086
23812
  import * as fs16 from "node:fs/promises";
23087
- import { toErrorMessage as toErrorMessage21 } from "@wrongstack/core/utils";
23813
+ import { toErrorMessage as toErrorMessage22 } from "@wrongstack/core/utils";
23088
23814
  import { AGENT_CATALOG as AGENT_CATALOG2, AGENTS_BY_PHASE as AGENTS_BY_PHASE3 } from "@wrongstack/core/agent-catalog";
23089
23815
  import { atomicWrite as atomicWrite9, color as color44, expectDefined as expectDefined8 } from "@wrongstack/core/utils";
23090
23816
  import { ConfigError as ConfigError5 } from "@wrongstack/core/types";
@@ -23092,6 +23818,26 @@ import { fallbackProfileChain } from "@wrongstack/core/agent";
23092
23818
  import { decryptConfigSecrets as decryptConfigSecrets4, encryptConfigSecrets as encryptConfigSecrets4, noOpVault as noOpVault6 } from "@wrongstack/core/security";
23093
23819
  import { MATRIX_PHASE_KEYS, matrixKeyKind, phaseForRole, resolveModelMatrix, resolveModelTargetFromEntry } from "@wrongstack/core/coordination";
23094
23820
  import { parseModelRef as parseModelRef3 } from "@wrongstack/core/agent";
23821
+ import { catalogProviderIdFor } from "@wrongstack/providers";
23822
+ async function resolveCatalogModelIds(registry, config, providerIds) {
23823
+ const out = /* @__PURE__ */ new Map();
23824
+ if (!registry) return out;
23825
+ await Promise.all(
23826
+ providerIds.map(async (id) => {
23827
+ try {
23828
+ const catalogId = catalogProviderIdFor(id, config.providers?.[id]?.type);
23829
+ const provider = await registry.getProvider(catalogId);
23830
+ if (provider) out.set(id, provider.models.map((m) => m.id));
23831
+ } catch {
23832
+ }
23833
+ })
23834
+ );
23835
+ return out;
23836
+ }
23837
+ function summarizeModelIds(ids, limit = 8) {
23838
+ if (ids.length <= limit) return ids.join(", ");
23839
+ return `${ids.slice(0, limit).join(", ")} ${color44.dim(`\u2026 +${ids.length - limit} more`)}`;
23840
+ }
23095
23841
  function providerHasKey(entry) {
23096
23842
  if (!entry) return false;
23097
23843
  if (typeof entry.apiKey === "string" && entry.apiKey.length > 0) return true;
@@ -23293,9 +24039,10 @@ function buildSetModelCommand(opts) {
23293
24039
  );
23294
24040
  const matrix = config.modelMatrix ?? {};
23295
24041
  if (sub === "list") {
24042
+ const catalogModels = await resolveCatalogModelIds(opts.modelsRegistry, config, keyed);
23296
24043
  const provLines = keyed.map((id) => {
23297
- const models = config.providers?.[id]?.models ?? [];
23298
- const ms = models.length ? models.join(", ") : color44.dim("(any model id accepted)");
24044
+ const models = visibleModelIds(id, config, catalogModels.get(id) ?? []);
24045
+ const ms = models.length ? summarizeModelIds(models) : color44.dim("(any model id accepted)");
23299
24046
  return ` ${color44.cyan(id.padEnd(16))} ${ms}`;
23300
24047
  });
23301
24048
  const roles = Object.keys(AGENT_CATALOG2).sort();
@@ -23371,6 +24118,11 @@ function buildSetModelCommand(opts) {
23371
24118
  if (sub === "doctor") {
23372
24119
  const issues = [];
23373
24120
  const warnings = [];
24121
+ const doctorCatalogModels = await resolveCatalogModelIds(
24122
+ opts.modelsRegistry,
24123
+ config,
24124
+ keyed
24125
+ );
23374
24126
  for (const [key, entry] of Object.entries(matrix)) {
23375
24127
  const kind = matrixKeyKind(key);
23376
24128
  if (kind === "unknown") {
@@ -23393,9 +24145,14 @@ function buildSetModelCommand(opts) {
23393
24145
  const effectiveProvider = entry.provider ?? config.provider;
23394
24146
  const provCfg = config.providers?.[effectiveProvider];
23395
24147
  if (entry.model && provCfg?.models && provCfg.models.length > 0) {
23396
- if (!provCfg.models.includes(entry.model)) {
24148
+ const reachable = visibleModelIds(
24149
+ effectiveProvider,
24150
+ config,
24151
+ doctorCatalogModels.get(effectiveProvider) ?? []
24152
+ );
24153
+ if (!reachable.includes(entry.model)) {
23397
24154
  warnings.push(
23398
- `${color44.amber("\u26A0")} ${color44.amber(key)}: model "${entry.model}" not in ${effectiveProvider}'s model list (${provCfg.models.join(", ")})`
24155
+ `${color44.amber("\u26A0")} ${color44.amber(key)}: model "${entry.model}" not in ${effectiveProvider}'s model list (${summarizeModelIds(reachable)})`
23399
24156
  );
23400
24157
  }
23401
24158
  }
@@ -23617,7 +24374,7 @@ function buildSetModelCommand(opts) {
23617
24374
  };
23618
24375
  } catch (err) {
23619
24376
  return {
23620
- message: `${color44.red("setmodel error")}: ${toErrorMessage21(err)}`
24377
+ message: `${color44.red("setmodel error")}: ${toErrorMessage22(err)}`
23621
24378
  };
23622
24379
  }
23623
24380
  }
@@ -23630,7 +24387,7 @@ import { access as access4 } from "node:fs/promises";
23630
24387
  import * as path25 from "node:path";
23631
24388
  import { color as color45 } from "@wrongstack/core/utils";
23632
24389
  import { parseNextSteps } from "@wrongstack/tools/next-steps";
23633
- import { toErrorMessage as toErrorMessage22 } from "@wrongstack/core/utils";
24390
+ import { toErrorMessage as toErrorMessage23 } from "@wrongstack/core/utils";
23634
24391
  function readGitStatus(projectRoot, includeBranch) {
23635
24392
  const args = ["status", "--short"];
23636
24393
  if (includeBranch) args.push("--branch");
@@ -23754,7 +24511,7 @@ function buildSuggestCommand(opts) {
23754
24511
  suggestCache = { suggestions, at: Date.now() };
23755
24512
  return { message: formatSuggestions(suggestions) };
23756
24513
  } catch (err) {
23757
- const msg = `Suggestion generation failed: ${toErrorMessage22(err)}`;
24514
+ const msg = `Suggestion generation failed: ${toErrorMessage23(err)}`;
23758
24515
  opts.renderer.writeWarning(msg);
23759
24516
  return { message: msg };
23760
24517
  }
@@ -24341,7 +25098,7 @@ import * as path26 from "node:path";
24341
25098
  import {
24342
25099
  color as color47,
24343
25100
  ensureProjectGitignore,
24344
- ensureProjectIdentity,
25101
+ ensureProjectIdentity as ensureProjectIdentity2,
24345
25102
  projectIdentityPath,
24346
25103
  readProjectIdentity,
24347
25104
  rekeyProjectIdentity
@@ -24477,7 +25234,7 @@ ${color47.dim(filePath)}`
24477
25234
  } : { message: `No committed project identity. Run ${color47.cyan("/project init")}.` };
24478
25235
  }
24479
25236
  if (action === "init") {
24480
- const result2 = await ensureProjectIdentity(root);
25237
+ const result2 = await ensureProjectIdentity2(root);
24481
25238
  await ensureProjectGitignore(root);
24482
25239
  return {
24483
25240
  message: result2.created ? `${color47.green("Created")} ${filePath}
@@ -25068,7 +25825,7 @@ function buildSecurityCommand(opts) {
25068
25825
  // src/slash-commands/settings.ts
25069
25826
  import { noOpVault as noOpVault9 } from "@wrongstack/core/security";
25070
25827
  import { resolveFleetChatVerbosity as resolveFleetChatVerbosity2 } from "@wrongstack/core/types";
25071
- import { color as color48, toErrorMessage as toErrorMessage23 } from "@wrongstack/core/utils";
25828
+ import { color as color48, toErrorMessage as toErrorMessage24 } from "@wrongstack/core/utils";
25072
25829
  import { getProcessRegistry } from "@wrongstack/tools";
25073
25830
 
25074
25831
  // src/utils/delay-format.ts
@@ -25983,7 +26740,7 @@ function buildSettingsCommand(opts) {
25983
26740
  };
25984
26741
  } catch (err) {
25985
26742
  return {
25986
- message: `${color48.red("Settings error")}: ${toErrorMessage23(err)}`
26743
+ message: `${color48.red("Settings error")}: ${toErrorMessage24(err)}`
25987
26744
  };
25988
26745
  }
25989
26746
  }
@@ -26273,7 +27030,7 @@ function parseFlags2(args) {
26273
27030
  }
26274
27031
 
26275
27032
  // src/slash-commands/spawn-agents.ts
26276
- import { toErrorMessage as toErrorMessage24 } from "@wrongstack/core/utils";
27033
+ import { toErrorMessage as toErrorMessage25 } from "@wrongstack/core/utils";
26277
27034
  function buildSpawnCommand(opts) {
26278
27035
  return {
26279
27036
  name: "spawn",
@@ -26310,7 +27067,7 @@ function buildSpawnCommand(opts) {
26310
27067
  const summary = Object.keys(parsed).length > 0 ? await opts.onSpawn(description, parsed) : await opts.onSpawn(description);
26311
27068
  return { message: summary };
26312
27069
  } catch (err) {
26313
- return { message: `Spawn failed: ${toErrorMessage24(err)}` };
27070
+ return { message: `Spawn failed: ${toErrorMessage25(err)}` };
26314
27071
  }
26315
27072
  }
26316
27073
  };
@@ -26918,7 +27675,7 @@ ${formatTaskProgress(file.tasks)}`;
26918
27675
  import * as fs18 from "node:fs/promises";
26919
27676
  import * as path28 from "node:path";
26920
27677
  import { color as color51 } from "@wrongstack/core/utils";
26921
- import { toErrorMessage as toErrorMessage25 } from "@wrongstack/core/utils";
27678
+ import { toErrorMessage as toErrorMessage26 } from "@wrongstack/core/utils";
26922
27679
  async function discoverPackageFiles(projectRoot) {
26923
27680
  const files = [];
26924
27681
  const rootPkg = path28.join(projectRoot, "package.json");
@@ -27126,7 +27883,7 @@ function buildTechStackCommand(opts) {
27126
27883
  message: `TechStack remediation finished: ${applied} applied, ${failed} failed, ${skipped} skipped.`
27127
27884
  };
27128
27885
  } catch (err) {
27129
- const msg = `TechStack remediation failed: ${toErrorMessage25(err)}`;
27886
+ const msg = `TechStack remediation failed: ${toErrorMessage26(err)}`;
27130
27887
  opts.renderer.writeWarning(msg);
27131
27888
  return { message: msg };
27132
27889
  } finally {
@@ -27145,7 +27902,7 @@ function buildTechStackCommand(opts) {
27145
27902
  message: `TechStack inventory complete: ${snapshot.workspaces.length} workspaces, ${snapshot.dependencies.length} dependencies (fingerprint: ${snapshot.fingerprint})`
27146
27903
  };
27147
27904
  } catch (err) {
27148
- const msg = `TechStack inventory failed: ${toErrorMessage25(err)}`;
27905
+ const msg = `TechStack inventory failed: ${toErrorMessage26(err)}`;
27149
27906
  opts.renderer.writeWarning(msg);
27150
27907
  return { message: msg };
27151
27908
  }
@@ -27160,7 +27917,7 @@ function buildTechStackCommand(opts) {
27160
27917
  );
27161
27918
  }
27162
27919
  } catch (err) {
27163
- discoveryNote = color51.red(`Could not scan for package files: ${toErrorMessage25(err)}`);
27920
+ discoveryNote = color51.red(`Could not scan for package files: ${toErrorMessage26(err)}`);
27164
27921
  }
27165
27922
  const task = buildTechStackTask({
27166
27923
  projectRoot: opts.projectRoot,
@@ -27200,7 +27957,7 @@ function buildTechStackCommand(opts) {
27200
27957
  });
27201
27958
  return { message: summary };
27202
27959
  } catch (err) {
27203
- const msg = `Tech stack scan failed: ${toErrorMessage25(err)}`;
27960
+ const msg = `Tech stack scan failed: ${toErrorMessage26(err)}`;
27204
27961
  opts.renderer.writeWarning(msg);
27205
27962
  return { message: msg };
27206
27963
  }
@@ -27210,7 +27967,7 @@ function buildTechStackCommand(opts) {
27210
27967
 
27211
27968
  // src/slash-commands/telegram-settings.ts
27212
27969
  import { color as color53 } from "@wrongstack/core/utils";
27213
- import { toErrorMessage as toErrorMessage26 } from "@wrongstack/core/utils";
27970
+ import { toErrorMessage as toErrorMessage27 } from "@wrongstack/core/utils";
27214
27971
 
27215
27972
  // src/slash-commands/telegram-setup.ts
27216
27973
  import { color as color52 } from "@wrongstack/core/utils";
@@ -27708,7 +28465,7 @@ function buildTelegramSettingsCommand(opts) {
27708
28465
  };
27709
28466
  } catch (err) {
27710
28467
  return {
27711
- message: `${color53.red("Settings error")}: ${toErrorMessage26(err)}`
28468
+ message: `${color53.red("Settings error")}: ${toErrorMessage27(err)}`
27712
28469
  };
27713
28470
  }
27714
28471
  }
@@ -27817,7 +28574,7 @@ function buildTodosCommand(opts) {
27817
28574
  // src/slash-commands/tool.ts
27818
28575
  import { color as color54, getToolDescriptionMode as getToolDescriptionMode2, getToolResultRenderMode, normalizeToolDescriptionMode, normalizeToolResultRenderMode, setToolResultRenderMode } from "@wrongstack/core/utils";
27819
28576
  import { noOpVault as noOpVault10 } from "@wrongstack/core/security";
27820
- import { toErrorMessage as toErrorMessage27 } from "@wrongstack/core/utils";
28577
+ import { toErrorMessage as toErrorMessage28 } from "@wrongstack/core/utils";
27821
28578
  function fit(text, width) {
27822
28579
  if (text.length <= width) return text.padEnd(width);
27823
28580
  return `${text.slice(0, Math.max(0, width - 3))}...`;
@@ -28051,7 +28808,7 @@ function buildToolCommand(opts) {
28051
28808
  try {
28052
28809
  return { message: await cmdEnableAll() };
28053
28810
  } catch (err) {
28054
- return { message: `${color54.red("Error")}: ${toErrorMessage27(err)}` };
28811
+ return { message: `${color54.red("Error")}: ${toErrorMessage28(err)}` };
28055
28812
  }
28056
28813
  }
28057
28814
  const name = parts[0] ?? "";
@@ -28065,7 +28822,7 @@ function buildToolCommand(opts) {
28065
28822
  for (const t of targets) results.push(await cmdDisable(t));
28066
28823
  return { message: results.join("\n") };
28067
28824
  } catch (err) {
28068
- return { message: `${color54.red("Error")}: ${toErrorMessage27(err)}` };
28825
+ return { message: `${color54.red("Error")}: ${toErrorMessage28(err)}` };
28069
28826
  }
28070
28827
  }
28071
28828
  if (sub === "enable") {
@@ -28077,7 +28834,7 @@ function buildToolCommand(opts) {
28077
28834
  for (const t of targets) results.push(await cmdEnable(t));
28078
28835
  return { message: results.join("\n") };
28079
28836
  } catch (err) {
28080
- return { message: `${color54.red("Error")}: ${toErrorMessage27(err)}` };
28837
+ return { message: `${color54.red("Error")}: ${toErrorMessage28(err)}` };
28081
28838
  }
28082
28839
  }
28083
28840
  const action = parts[1]?.toLowerCase();
@@ -28090,7 +28847,7 @@ function buildToolCommand(opts) {
28090
28847
  try {
28091
28848
  return { message: action === "disable" ? await cmdDisable(name) : await cmdEnable(name) };
28092
28849
  } catch (err) {
28093
- return { message: `${color54.red("Error")}: ${toErrorMessage27(err)}` };
28850
+ return { message: `${color54.red("Error")}: ${toErrorMessage28(err)}` };
28094
28851
  }
28095
28852
  }
28096
28853
  if (!opts.toolRegistry.get(name) && !opts.toolRegistry.isDisabled(name)) {
@@ -28130,7 +28887,7 @@ function buildToolCommand(opts) {
28130
28887
  };
28131
28888
  } catch (err) {
28132
28889
  return {
28133
- message: `${color54.red("Could not save tool setting")}: ${toErrorMessage27(err)}`
28890
+ message: `${color54.red("Could not save tool setting")}: ${toErrorMessage28(err)}`
28134
28891
  };
28135
28892
  }
28136
28893
  }
@@ -28150,7 +28907,7 @@ function buildToolCommand(opts) {
28150
28907
  };
28151
28908
  } catch (err) {
28152
28909
  return {
28153
- message: `${color54.red("Could not save tool setting")}: ${toErrorMessage27(err)}`
28910
+ message: `${color54.red("Could not save tool setting")}: ${toErrorMessage28(err)}`
28154
28911
  };
28155
28912
  }
28156
28913
  }
@@ -29047,7 +29804,7 @@ function summaryLine(findings, fixable, handoffs, power) {
29047
29804
  import * as fs20 from "node:fs/promises";
29048
29805
  import * as path30 from "node:path";
29049
29806
  import { color as color57 } from "@wrongstack/core/utils";
29050
- import { toErrorMessage as toErrorMessage28 } from "@wrongstack/core/utils";
29807
+ import { toErrorMessage as toErrorMessage29 } from "@wrongstack/core/utils";
29051
29808
  function buildWorkingDirCommand(_opts) {
29052
29809
  return {
29053
29810
  name: "working_dir",
@@ -29104,7 +29861,7 @@ function buildWorkingDirCommand(_opts) {
29104
29861
  ctx.setWorkingDir(resolved);
29105
29862
  } catch (err) {
29106
29863
  return {
29107
- message: color57.red(toErrorMessage28(err))
29864
+ message: color57.red(toErrorMessage29(err))
29108
29865
  };
29109
29866
  }
29110
29867
  const prevRel = path30.relative(ctx.projectRoot, previous) || ".";
@@ -29250,6 +30007,7 @@ function buildBuiltinSlashCommands(opts) {
29250
30007
  buildDesktopCommand(),
29251
30008
  buildWebuiCommand(),
29252
30009
  buildInitCommand(opts),
30010
+ buildIntakeCommand(opts),
29253
30011
  buildClearCommand(opts),
29254
30012
  buildInterruptCommand(opts),
29255
30013
  buildKanbanCommand(opts),
@@ -29673,6 +30431,9 @@ async function runInteractive(cliCtx) {
29673
30431
  let {
29674
30432
  director,
29675
30433
  maxConcurrent,
30434
+ maxSpawns,
30435
+ maxConcurrentSource,
30436
+ maxSpawnsSource,
29676
30437
  autonomyMode,
29677
30438
  nextPredictEnabled,
29678
30439
  currentSuggestions,
@@ -29725,6 +30486,9 @@ async function runInteractive(cliCtx) {
29725
30486
  stateCheckpointPath,
29726
30487
  fleetRootForPromotion,
29727
30488
  maxConcurrent,
30489
+ maxSpawns,
30490
+ maxConcurrentSource,
30491
+ maxSpawnsSource,
29728
30492
  effectiveMaxContextRef,
29729
30493
  mcpRegistry,
29730
30494
  sessResult,
@@ -29765,11 +30529,30 @@ async function runInteractive(cliCtx) {
29765
30529
  for (const tool of director.tools(FLEET_ROSTER5)) {
29766
30530
  toolRegistry.register(tool);
29767
30531
  }
29768
- renderer.writeInfo(`Director mode enabled. Roster: ${Object.keys(FLEET_ROSTER5).join(", ")}`);
29769
- renderer.writeInfo(` fleet root \u2192 ${fleetRoot}`);
29770
- renderer.writeInfo(` manifest \u2192 ${manifestPath}`);
29771
- renderer.writeInfo(` scratchpad \u2192 ${sharedScratchpadPath}`);
29772
- renderer.writeInfo(` subagents \u2192 ${subagentSessionsRoot}`);
30532
+ const browserSurface = flags.webui === true || flags.simpleui === true;
30533
+ if (browserSurface) {
30534
+ renderer.writeInfo(
30535
+ `Director mode enabled (${Object.keys(FLEET_ROSTER5).length} roles) \u2192 ${fleetRoot}`
30536
+ );
30537
+ } else {
30538
+ renderer.writeInfo(`Director mode enabled. Roster: ${Object.keys(FLEET_ROSTER5).join(", ")}`);
30539
+ renderer.writeInfo(` fleet root \u2192 ${fleetRoot}`);
30540
+ renderer.writeInfo(` manifest \u2192 ${manifestPath}`);
30541
+ renderer.writeInfo(` scratchpad \u2192 ${sharedScratchpadPath}`);
30542
+ renderer.writeInfo(` subagents \u2192 ${subagentSessionsRoot}`);
30543
+ }
30544
+ if (priorFleetState) {
30545
+ const budget = multiAgentHost.budgetView();
30546
+ const fmt = (n) => Number.isFinite(n) ? String(n) : "\u221E";
30547
+ renderer.writeInfo(
30548
+ ` fleet budget \u2192 ${budget.usedSpawns}/${fmt(budget.maxSpawns)} spawns used (${fmt(budget.remainingSpawns)} remaining; maxConcurrent ${budget.maxConcurrent})`
30549
+ );
30550
+ if (budget.ceilingMismatch && budget.checkpointMaxSpawns !== void 0) {
30551
+ renderer.writeInfo(
30552
+ ` \u26A0 checkpoint maxSpawns was ${budget.checkpointMaxSpawns}; live ceiling is ${fmt(budget.maxSpawns)}`
30553
+ );
30554
+ }
30555
+ }
29773
30556
  } else {
29774
30557
  renderer.writeInfo(`Running without Director \u2014 fleet orchestration tools disabled.`);
29775
30558
  }
@@ -29993,7 +30776,7 @@ async function runInteractive(cliCtx) {
29993
30776
  onEvent: evOn
29994
30777
  });
29995
30778
  const savedProviderCfg = config.providers?.[config.provider];
29996
- const { execute } = await import("./execution-BY556FCF.js");
30779
+ const { execute } = await import("./execution-SHGM7BVC.js");
29997
30780
  const stopHeapWatchdog = startSharedHeapWatchdog({
29998
30781
  collectStats: () => {
29999
30782
  const hqQueue = hqPublisherRef.current?.getQueueStats();
@@ -30225,4 +31008,4 @@ export {
30225
31008
  CLI_VERSION,
30226
31009
  runInteractive
30227
31010
  };
30228
- //# sourceMappingURL=cli-main-ZDZMCVLM.js.map
31011
+ //# sourceMappingURL=cli-main-7B3G2YSG.js.map