@wrongstack/cli 1.0.3 → 1.0.6

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 (83) hide show
  1. package/dist/{acp-JK4ZQO3R.js → acp-GOQURNC2.js} +128 -43
  2. package/dist/acp-agent-list.d.ts +14 -0
  3. package/dist/acp-hq-telemetry.d.ts +9 -2
  4. package/dist/acp-mcp-servers.d.ts +49 -0
  5. package/dist/acp-server-agent.d.ts +18 -6
  6. package/dist/{auth-XD3GN5RJ.js → auth-WBXXIQUO.js} +3 -3
  7. package/dist/boot/short-circuit-desktop.d.ts +1 -0
  8. package/dist/boot/short-circuit-hq.d.ts +2 -0
  9. package/dist/boot/tool-registry.d.ts +18 -1
  10. package/dist/{chunk-JHPXJRRI.js → chunk-4XCBEUBX.js} +13 -3
  11. package/dist/{chunk-ONOT5OJ2.js → chunk-5A5GCSJC.js} +1 -1
  12. package/dist/chunk-5EA6OTLJ.js +239 -0
  13. package/dist/{chunk-O4A3HHKD.js → chunk-672UXYL3.js} +2 -2
  14. package/dist/{chunk-FPIWTJ2G.js → chunk-6WRKAACA.js} +4 -4
  15. package/dist/chunk-AUQDGU5D.js +32 -0
  16. package/dist/{chunk-VOTTENR5.js → chunk-CDY4D5QK.js} +2 -2
  17. package/dist/{chunk-E6RFXHWD.js → chunk-EK2P53GL.js} +3 -2
  18. package/dist/{chunk-MXEJEYT7.js → chunk-JX6KL7OF.js} +15 -5
  19. package/dist/{chunk-GMY45LO6.js → chunk-KEPABQYT.js} +101 -2
  20. package/dist/{chunk-IMWXXF4J.js → chunk-KNMIBKLV.js} +79 -1
  21. package/dist/{chunk-4NHD5OXJ.js → chunk-NR7BD73C.js} +5 -5
  22. package/dist/{chunk-C2E24IXZ.js → chunk-PQZPHGGD.js} +272 -299
  23. package/dist/chunk-Q7E3BPDU.js +62 -0
  24. package/dist/{chunk-IUEKNHPT.js → chunk-QDQPF4PB.js} +11 -11
  25. package/dist/{chunk-VFCJOWJB.js → chunk-VPS2SJW4.js} +4 -5
  26. package/dist/{chunk-U6KCWRMC.js → chunk-XJ7K67PP.js} +5 -1
  27. package/dist/{cli-context-Q6QP534K.js → cli-context-BYKJDAFF.js} +129 -25
  28. package/dist/{cli-main-JQXCDZEA.js → cli-main-5WZBH3WA.js} +1345 -800
  29. package/dist/{diag-doctor-7LYUYU35.js → diag-doctor-PCER6KHH.js} +2 -2
  30. package/dist/{execution-KH7WJNAX.js → execution-Z6A26EG6.js} +132 -40
  31. package/dist/execution-specialist-trigger.d.ts +28 -0
  32. package/dist/fleet/acp-live-progress.d.ts +19 -0
  33. package/dist/fleet/host-acp-runner-cache.d.ts +3 -1
  34. package/dist/fleet/host-acp.d.ts +14 -2
  35. package/dist/fleet/host.d.ts +1 -0
  36. package/dist/{hq-IG3YRGCO.js → hq-V4PHEETW.js} +127 -8
  37. package/dist/hq-command-controller.d.ts +31 -2
  38. package/dist/hq-server/auth-state.d.ts +6 -0
  39. package/dist/hq-server/auth.d.ts +10 -1
  40. package/dist/hq-server/client-address.d.ts +2 -0
  41. package/dist/hq-server/ip-allowlist.d.ts +16 -0
  42. package/dist/hq-server/preflight.d.ts +1 -0
  43. package/dist/hq-server/routes/auth/common.d.ts +34 -0
  44. package/dist/hq-server/routes/auth/password-routes.d.ts +4 -2
  45. package/dist/hq-server/routes.d.ts +5 -4
  46. package/dist/hq-server/secret-input.d.ts +7 -0
  47. package/dist/hq-server/types.d.ts +21 -2
  48. package/dist/hq-server/upgrade-handler.d.ts +2 -0
  49. package/dist/hq-server/utils.d.ts +6 -0
  50. package/dist/{hq-server-OILU3NPI.js → hq-server-MZ7DV6X7.js} +4 -3
  51. package/dist/hq-server.d.ts +4 -0
  52. package/dist/hq-service-L5INQFM4.js +507 -0
  53. package/dist/hq-service.d.ts +22 -0
  54. package/dist/index.js +9 -6
  55. package/dist/ip-allowlist-NHXO6AKJ.js +9 -0
  56. package/dist/live-settings-input.d.ts +2 -0
  57. package/dist/{mcp-HOMLC4WE.js → mcp-FX7TKPTV.js} +10 -8
  58. package/dist/mcp-serve.d.ts +31 -0
  59. package/dist/{per-subcommand-help-BWBHYVJO.js → per-subcommand-help-DHTYU524.js} +2 -2
  60. package/dist/{plugins-U7KGQAUG.js → plugins-WJLW6ULV.js} +2 -2
  61. package/dist/projects-LMNAGGEU.js +36 -0
  62. package/dist/{proxy-wiring-MGRSKZZB.js → proxy-wiring-K2DORFFL.js} +3 -3
  63. package/dist/short-circuit-flags-KBTYSJTW.js +10 -0
  64. package/dist/slash-commands/acp.d.ts +3 -0
  65. package/dist/slash-commands/command-context.d.ts +22 -0
  66. package/dist/slash-commands/ensemble.d.ts +1 -1
  67. package/dist/slash-commands/profile.d.ts +7 -0
  68. package/dist/subcommands/handlers/hq.d.ts +1 -0
  69. package/dist/subcommands/handlers/projects.d.ts +14 -0
  70. package/dist/{subcommands-CUTGBDKP.js → subcommands-DEYSYHIM.js} +2 -2
  71. package/dist/{version-help-MYKF724O.js → version-help-WXI42PZ3.js} +2 -2
  72. package/dist/{webui-server-QWBUT7BO.js → webui-server-OBV5JYJV.js} +9 -3
  73. package/dist/wiring/cli-slash-commands-setup.d.ts +7 -0
  74. package/dist/wiring/codebase-embeddings.d.ts +2 -2
  75. package/dist/wiring/command-host-state.d.ts +7 -0
  76. package/dist/wiring/pipeline.d.ts +2 -0
  77. package/dist/wiring/provider-runtime-setup.d.ts +1 -1
  78. package/dist/wiring/session-command-handlers.d.ts +2 -1
  79. package/dist/wiring/slash-commands.d.ts +1 -0
  80. package/package.json +28 -28
  81. package/dist/chunk-Q5GTM25S.js +0 -17
  82. package/dist/projects-L6C6XLDY.js +0 -37
  83. package/dist/short-circuit-flags-ZNZX44MC.js +0 -10
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  startProxyProbe
3
- } from "./chunk-JHPXJRRI.js";
3
+ } from "./chunk-4XCBEUBX.js";
4
4
  import {
5
5
  formatGateCounterReport,
6
6
  loadWrongTraceGateCounters
@@ -382,4 +382,4 @@ export {
382
382
  doctorCmd,
383
383
  proxyCmd
384
384
  };
385
- //# sourceMappingURL=diag-doctor-7LYUYU35.js.map
385
+ //# sourceMappingURL=diag-doctor-PCER6KHH.js.map
@@ -11,17 +11,6 @@ import {
11
11
  resolveActualTarget,
12
12
  resolvePersistPath
13
13
  } from "./chunk-JACOMTIH.js";
14
- import {
15
- theme
16
- } from "./chunk-QD544J2B.js";
17
- import {
18
- WEBUI_SESSION_CHILD_CAPABILITIES,
19
- writeWebuiSessionChildError,
20
- writeWebuiSessionChildReady
21
- } from "./chunk-GPPRNAKW.js";
22
- import {
23
- fmtTok
24
- } from "./chunk-EWKESL4L.js";
25
14
  import "./chunk-WHOIR577.js";
26
15
  import {
27
16
  advanceToNextTask,
@@ -36,6 +25,17 @@ import {
36
25
  trySaveSpecFromAIOutput,
37
26
  trySaveTasksFromAIOutput
38
27
  } from "./chunk-JHUJUIOH.js";
28
+ import {
29
+ theme
30
+ } from "./chunk-QD544J2B.js";
31
+ import {
32
+ fmtTok
33
+ } from "./chunk-EWKESL4L.js";
34
+ import {
35
+ WEBUI_SESSION_CHILD_CAPABILITIES,
36
+ writeWebuiSessionChildError,
37
+ writeWebuiSessionChildReady
38
+ } from "./chunk-GPPRNAKW.js";
39
39
  import {
40
40
  terminalLink,
41
41
  terminalText
@@ -212,7 +212,7 @@ async function runWebUIDispatch(ctx) {
212
212
  const isSimpleUi = !isSessionChild && flags["simpleui"] === true;
213
213
  agent.disableInteractiveConfirmation();
214
214
  renderer.setSilent(true);
215
- const { runWebUI } = await import("./webui-server-QWBUT7BO.js");
215
+ const { runWebUI } = await import("./webui-server-OBV5JYJV.js");
216
216
  const flagValue = (names) => {
217
217
  for (const name of names) {
218
218
  if (!Object.hasOwn(flags, name)) continue;
@@ -416,7 +416,7 @@ async function runWebUIDispatch(ctx) {
416
416
  applyLiveSettings?.({ yolo: enabled });
417
417
  },
418
418
  onWrongProxyPrefsChange: (payload) => {
419
- void import("./proxy-wiring-MGRSKZZB.js").then(
419
+ void import("./proxy-wiring-K2DORFFL.js").then(
420
420
  ({ applyWrongProxyPrefs }) => applyWrongProxyPrefs(payload)
421
421
  );
422
422
  }
@@ -1258,7 +1258,7 @@ import * as path7 from "node:path";
1258
1258
  import { restoreSessionSubagentPolicy } from "@wrongstack/core/coordination";
1259
1259
  import { attachTodosCheckpoint, loadTodosCheckpoint } from "@wrongstack/core/storage";
1260
1260
  import { projectLastRequestTokens } from "@wrongstack/core/types/session-timeline";
1261
- import { sessionScopedPath as sessionScopedPath2 } from "@wrongstack/core/utils";
1261
+ import { sessionScopedPath as sessionScopedPath2, toErrorMessage } from "@wrongstack/core/utils";
1262
1262
  var RESERVATION_WINDOW_MS = 6e4;
1263
1263
  var RESERVATION_RENEW_MS = 2e4;
1264
1264
  function messageText(content) {
@@ -1288,7 +1288,7 @@ async function resumeSession(ctx, sessionId) {
1288
1288
  };
1289
1289
  const warnings = [];
1290
1290
  const warn = (label, err) => {
1291
- warnings.push(`${label}: ${err instanceof Error ? err.message : String(err)}`);
1291
+ warnings.push(`${label}: ${toErrorMessage(err)}`);
1292
1292
  };
1293
1293
  let stage = "start";
1294
1294
  const setStage = (next) => {
@@ -1309,7 +1309,7 @@ async function resumeSession(ctx, sessionId) {
1309
1309
  throw new TypeError("@wrongstack/tui does not export replaySessionMessages");
1310
1310
  }
1311
1311
  } catch (err) {
1312
- return fail(stage, err instanceof Error ? err.message : String(err));
1312
+ return fail(stage, toErrorMessage(err));
1313
1313
  }
1314
1314
  setStage("resolve_id");
1315
1315
  let canonicalSessionId = sessionId;
@@ -1323,11 +1323,11 @@ async function resumeSession(ctx, sessionId) {
1323
1323
  level: "error",
1324
1324
  event: "execution.resume_id_resolve_failed",
1325
1325
  sessionId,
1326
- message: err instanceof Error ? err.message : String(err),
1326
+ message: toErrorMessage(err),
1327
1327
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1328
1328
  })
1329
1329
  );
1330
- return fail(stage, err instanceof Error ? err.message : String(err));
1330
+ return fail(stage, toErrorMessage(err));
1331
1331
  }
1332
1332
  const previousSessionId = agent.ctx.session?.id;
1333
1333
  let hydrated;
@@ -1369,7 +1369,7 @@ async function resumeSession(ctx, sessionId) {
1369
1369
  level: "warn",
1370
1370
  event: "execution.resume_reservation_renew_failed",
1371
1371
  sessionId: canonicalSessionId,
1372
- message: err instanceof Error ? err.message : String(err),
1372
+ message: toErrorMessage(err),
1373
1373
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1374
1374
  })
1375
1375
  );
@@ -1441,7 +1441,7 @@ async function resumeSession(ctx, sessionId) {
1441
1441
  JSON.stringify({
1442
1442
  level: "error",
1443
1443
  event: "execution.resume_journal_flush_failed",
1444
- message: err instanceof Error ? err.message : String(err),
1444
+ message: toErrorMessage(err),
1445
1445
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1446
1446
  })
1447
1447
  );
@@ -1498,7 +1498,7 @@ async function resumeSession(ctx, sessionId) {
1498
1498
  event: "execution.resume_model_restore_failed",
1499
1499
  provider: targetProviderId,
1500
1500
  model: targetModel,
1501
- message: err instanceof Error ? err.message : String(err),
1501
+ message: toErrorMessage(err),
1502
1502
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1503
1503
  })
1504
1504
  );
@@ -1526,7 +1526,7 @@ async function resumeSession(ctx, sessionId) {
1526
1526
  JSON.stringify({
1527
1527
  level: "error",
1528
1528
  event: "execution.session_end_append_failed",
1529
- message: err instanceof Error ? err.message : String(err),
1529
+ message: toErrorMessage(err),
1530
1530
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1531
1531
  })
1532
1532
  );
@@ -1539,7 +1539,7 @@ async function resumeSession(ctx, sessionId) {
1539
1539
  JSON.stringify({
1540
1540
  level: "error",
1541
1541
  event: "execution.session_close_failed",
1542
- message: err instanceof Error ? err.message : String(err),
1542
+ message: toErrorMessage(err),
1543
1543
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1544
1544
  })
1545
1545
  );
@@ -1580,7 +1580,7 @@ async function resumeSession(ctx, sessionId) {
1580
1580
  level: "error",
1581
1581
  event: "execution.resume_identity_rollback_failed",
1582
1582
  sessionId: previousSessionId,
1583
- message: rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr),
1583
+ message: toErrorMessage(rollbackErr),
1584
1584
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1585
1585
  })
1586
1586
  );
@@ -1602,7 +1602,7 @@ async function resumeSession(ctx, sessionId) {
1602
1602
  JSON.stringify({
1603
1603
  level: "error",
1604
1604
  event: "execution.resume_post_swap_rollback_failed",
1605
- message: rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr),
1605
+ message: toErrorMessage(rollbackErr),
1606
1606
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1607
1607
  })
1608
1608
  );
@@ -1613,7 +1613,7 @@ async function resumeSession(ctx, sessionId) {
1613
1613
  JSON.stringify({
1614
1614
  level: "error",
1615
1615
  event: "execution.resume_opened_writer_close_failed",
1616
- message: closeErr instanceof Error ? closeErr.message : String(closeErr),
1616
+ message: toErrorMessage(closeErr),
1617
1617
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1618
1618
  })
1619
1619
  );
@@ -1631,7 +1631,7 @@ async function resumeSession(ctx, sessionId) {
1631
1631
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1632
1632
  })
1633
1633
  );
1634
- const message = err instanceof Error ? err.message : String(err);
1634
+ const message = toErrorMessage(err);
1635
1635
  if (err instanceof Error && err.name === "SessionOwnershipConflictError") {
1636
1636
  return fail(stage, message);
1637
1637
  }
@@ -1670,7 +1670,7 @@ async function resumeSession(ctx, sessionId) {
1670
1670
  level: "error",
1671
1671
  event: "execution.resume_readonly_render_failed",
1672
1672
  sessionId: canonicalSessionId,
1673
- message: renderErr instanceof Error ? renderErr.message : String(renderErr),
1673
+ message: toErrorMessage(renderErr),
1674
1674
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1675
1675
  })
1676
1676
  );
@@ -1937,6 +1937,7 @@ function createSettingsAdapter(ctx) {
1937
1937
  breakerEnabled: cfg.circuitBreaker?.enabled === true,
1938
1938
  breakerAutoKillResetMs: cfg.circuitBreaker?.autoKillResetMs ?? 6e4,
1939
1939
  showModelReasoning: autonomy?.showModelReasoning ?? false,
1940
+ toolResultViewMode: autonomy?.toolResultViewMode === "minimal" || autonomy?.toolResultViewMode === "full" ? autonomy.toolResultViewMode : "normal",
1940
1941
  showAgentSwarmPanel: coerceAgentSwarmMode(autonomy?.showAgentSwarmPanel),
1941
1942
  showSidebar: autonomy?.showSidebar ?? true,
1942
1943
  // Migrate the legacy `autonomy.showAgentSwarmPanel: 'sidebar'` into
@@ -1963,7 +1964,7 @@ function createSettingsAdapter(ctx) {
1963
1964
  }
1964
1965
  async function saveSettings(s) {
1965
1966
  try {
1966
- if (s.mode !== void 0 || s.delayMs !== void 0 || s.titleAnimation !== void 0 || s.yolo !== void 0 || s.fleetChatVerbosity !== void 0 || s.chime !== void 0 || s.confirmExit !== void 0 || s.mouseMode !== void 0 || s.featureMcp !== void 0 || s.featurePlugins !== void 0 || s.featureMemory !== void 0 || s.featureSkills !== void 0 || s.featureModelsRegistry !== void 0 || s.featureTokenSaving !== void 0 || s.allowOutsideProjectRoot !== void 0 || s.contextAutoCompact !== void 0 || s.contextStrategy !== void 0 || s.contextMode !== void 0 || s.maxConcurrent !== void 0 || s.logLevel !== void 0 || s.auditLevel !== void 0 || s.indexOnStart !== void 0 || s.maxIterations !== void 0 || s.multiDiffSummaryThreshold !== void 0 || s.nextStepsTool !== void 0 || s.restrictFsToRoot !== void 0 || s.nextPrediction !== void 0 || s.debugStream !== void 0 || s.shellBangWarningDontShowAgain !== void 0 || s.configScope !== void 0 || s.enhanceDelayMs !== void 0 || s.enhanceEnabled !== void 0 || s.preRefineSeconds !== void 0 || s.enhanceLanguage !== void 0 || s.midRunSendPicker !== void 0 || s.statuslineMode !== void 0 || s.thinkingWord !== void 0 || s.animationStyle !== void 0 || s.autonomyNextPrompt !== void 0 || s.autoProceedMaxIterations !== void 0 || s.reasoningMode !== void 0 || s.reasoningEffort !== void 0 || s.reasoningPreserve !== void 0 || s.cacheTtl !== void 0 || s.breakerEnabled !== void 0 || s.breakerAutoKillResetMs !== void 0 || s.showModelReasoning !== void 0 || s.showAgentSwarmPanel !== void 0 || s.showSidebar !== void 0 || s.panelPositions !== void 0 || s.showSageMemoryInject !== void 0 || s.sageMemoryInjectThreshold !== void 0 || s.readSymbols !== void 0 || // WrongProxy / WrongTrace: gate the persisted-section write on
1967
+ if (s.mode !== void 0 || s.delayMs !== void 0 || s.titleAnimation !== void 0 || s.yolo !== void 0 || s.fleetChatVerbosity !== void 0 || s.chime !== void 0 || s.confirmExit !== void 0 || s.mouseMode !== void 0 || s.featureMcp !== void 0 || s.featurePlugins !== void 0 || s.featureMemory !== void 0 || s.featureSkills !== void 0 || s.featureModelsRegistry !== void 0 || s.featureTokenSaving !== void 0 || s.allowOutsideProjectRoot !== void 0 || s.contextAutoCompact !== void 0 || s.contextStrategy !== void 0 || s.contextMode !== void 0 || s.maxConcurrent !== void 0 || s.logLevel !== void 0 || s.auditLevel !== void 0 || s.indexOnStart !== void 0 || s.maxIterations !== void 0 || s.multiDiffSummaryThreshold !== void 0 || s.nextStepsTool !== void 0 || s.restrictFsToRoot !== void 0 || s.nextPrediction !== void 0 || s.debugStream !== void 0 || s.shellBangWarningDontShowAgain !== void 0 || s.configScope !== void 0 || s.enhanceDelayMs !== void 0 || s.enhanceEnabled !== void 0 || s.preRefineSeconds !== void 0 || s.enhanceLanguage !== void 0 || s.midRunSendPicker !== void 0 || s.statuslineMode !== void 0 || s.thinkingWord !== void 0 || s.animationStyle !== void 0 || s.autonomyNextPrompt !== void 0 || s.autoProceedMaxIterations !== void 0 || s.reasoningMode !== void 0 || s.reasoningEffort !== void 0 || s.reasoningPreserve !== void 0 || s.cacheTtl !== void 0 || s.breakerEnabled !== void 0 || s.breakerAutoKillResetMs !== void 0 || s.showModelReasoning !== void 0 || s.toolResultViewMode !== void 0 || s.showAgentSwarmPanel !== void 0 || s.showSidebar !== void 0 || s.panelPositions !== void 0 || s.showSageMemoryInject !== void 0 || s.sageMemoryInjectThreshold !== void 0 || s.readSymbols !== void 0 || // WrongProxy / WrongTrace: gate the persisted-section write on
1967
1968
  // either key being present in the live patch. Without this, a
1968
1969
  // picker toggle round-trip would silently no-op the persistence
1969
1970
  // layer (the runtime probe would never read the change).
@@ -2018,6 +2019,7 @@ function createSettingsAdapter(ctx) {
2018
2019
  autonomy.thinkingWord = normalizeTuiThinkingWord(s.thinkingWord);
2019
2020
  if (s.animationStyle !== void 0) autonomy.animationStyle = s.animationStyle;
2020
2021
  if (s.showModelReasoning !== void 0) autonomy.showModelReasoning = s.showModelReasoning;
2022
+ if (s.toolResultViewMode !== void 0) autonomy.toolResultViewMode = s.toolResultViewMode;
2021
2023
  if (s.showAgentSwarmPanel !== void 0)
2022
2024
  autonomy.showAgentSwarmPanel = s.showAgentSwarmPanel;
2023
2025
  if (s.showSidebar !== void 0) autonomy.showSidebar = s.showSidebar;
@@ -4369,6 +4371,87 @@ async function persistChimeraReview(payload, projectDir) {
4369
4371
  }
4370
4372
  }
4371
4373
 
4374
+ // src/execution-specialist-trigger.ts
4375
+ import { randomUUID as randomUUID4 } from "node:crypto";
4376
+ var SPECIALIST_MAX_ITERATIONS = 30;
4377
+ var SPECIALIST_MAX_TOOL_CALLS = 120;
4378
+ var SPECIALIST_TIMEOUT_MS = 6 * 60 * 1e3;
4379
+ function installSpecialistTriggerHandler({
4380
+ events,
4381
+ director,
4382
+ session,
4383
+ teardownHandlers,
4384
+ trackWork
4385
+ }) {
4386
+ const off = events.onPattern(
4387
+ "fleet.specialist_needed",
4388
+ (_event, payload) => {
4389
+ const request = payload;
4390
+ const dir = director;
4391
+ if (!dir) return;
4392
+ if (!request?.role || !request.task) return;
4393
+ const work = (async () => {
4394
+ try {
4395
+ const subagentId = await dir.spawn({
4396
+ name: `trigger-${request.role}`,
4397
+ role: request.role,
4398
+ tier: request.tier,
4399
+ maxIterations: SPECIALIST_MAX_ITERATIONS,
4400
+ maxToolCalls: SPECIALIST_MAX_TOOL_CALLS,
4401
+ timeoutMs: SPECIALIST_TIMEOUT_MS,
4402
+ // Triggered specialists are background infrastructure, like
4403
+ // reviewers: they must not eat the leader's lifetime spawn budget,
4404
+ // which the user reserved for work they asked for.
4405
+ spawnBudgetExempt: true
4406
+ });
4407
+ const taskId = await dir.assign({
4408
+ id: randomUUID4(),
4409
+ description: request.task,
4410
+ subagentId,
4411
+ timeoutMs: SPECIALIST_TIMEOUT_MS
4412
+ });
4413
+ const [result] = await dir.awaitTasks([taskId]);
4414
+ if (result?.status === "success") {
4415
+ const text = typeof result.result === "string" ? result.result : JSON.stringify(result.result);
4416
+ await session.append({
4417
+ type: "llm_response",
4418
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
4419
+ content: [
4420
+ {
4421
+ type: "text",
4422
+ text: `\u{1F514} ${request.role} (triggered by ${request.paths.length} changed file(s)) \u2014 ${text}`
4423
+ }
4424
+ ],
4425
+ stopReason: "end_turn",
4426
+ usage: { input: 0, output: 0 }
4427
+ });
4428
+ return;
4429
+ }
4430
+ await session.append({
4431
+ type: "error",
4432
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
4433
+ message: `\u{1F514} ${request.role} trigger ${result?.status ?? "unknown"}: ${result?.error?.message ?? "no result"}`,
4434
+ phase: "agent"
4435
+ });
4436
+ } catch (err) {
4437
+ try {
4438
+ await session.append({
4439
+ type: "error",
4440
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
4441
+ message: `\u{1F514} ${request.role} trigger failed to run: ${err instanceof Error ? err.message : String(err)}`,
4442
+ phase: "agent"
4443
+ });
4444
+ } catch {
4445
+ }
4446
+ }
4447
+ })();
4448
+ trackWork?.(work);
4449
+ },
4450
+ "specialist-trigger"
4451
+ );
4452
+ if (off) teardownHandlers.push(off);
4453
+ }
4454
+
4372
4455
  // src/execution-storage-observability.ts
4373
4456
  function installStorageObservability(events, rootTraceId) {
4374
4457
  const isStorageNamespace = (event) => event === "storage.read" || event === "storage.write" || event === "storage.error" || event.startsWith("storage.");
@@ -4509,7 +4592,7 @@ import {
4509
4592
  color as color11,
4510
4593
  estimateRequestTokensCalibrated as estimateRequestTokensCalibrated2,
4511
4594
  hasOpenTodos as hasOpenTodos2,
4512
- toErrorMessage as toErrorMessage3
4595
+ toErrorMessage as toErrorMessage4
4513
4596
  } from "@wrongstack/core/utils";
4514
4597
  import { readClipboardImage, routeImagesForModel } from "@wrongstack/runtime";
4515
4598
  import { createAutoProceedLoopGuard } from "@wrongstack/tools/auto-proceed-loop-guard";
@@ -4737,11 +4820,11 @@ function registerReplClient(opts) {
4737
4820
 
4738
4821
  // src/repl-eternal-loop.ts
4739
4822
  import { goalFilePath as goalFilePath2, summarizeUsage } from "@wrongstack/core/goal";
4740
- import { color as color8, toErrorMessage as toErrorMessage2 } from "@wrongstack/core/utils";
4823
+ import { color as color8, toErrorMessage as toErrorMessage3 } from "@wrongstack/core/utils";
4741
4824
 
4742
4825
  // src/repl-goal-banner.ts
4743
4826
  import { goalFilePath, loadGoal } from "@wrongstack/core/goal";
4744
- import { color as color7, expectDefined, toErrorMessage } from "@wrongstack/core/utils";
4827
+ import { color as color7, expectDefined, toErrorMessage as toErrorMessage2 } from "@wrongstack/core/utils";
4745
4828
  async function loadGoalSafe(opts) {
4746
4829
  if (!opts.projectRoot) return null;
4747
4830
  try {
@@ -4775,7 +4858,7 @@ async function renderGoalBanner(opts) {
4775
4858
  try {
4776
4859
  await opts.slashRegistry.dispatch("/autonomy eternal", opts.agent.ctx);
4777
4860
  } catch (err) {
4778
- opts.renderer.writeError(`Auto-resume failed: ${toErrorMessage(err)}`);
4861
+ opts.renderer.writeError(`Auto-resume failed: ${toErrorMessage2(err)}`);
4779
4862
  }
4780
4863
  } else {
4781
4864
  opts.renderer.write(
@@ -4851,7 +4934,7 @@ async function runReplEternalLoop(opts, onInterruptsReset) {
4851
4934
  return true;
4852
4935
  }
4853
4936
  } catch (err) {
4854
- opts.renderer.writeError(`[eternal] ${toErrorMessage2(err)}`);
4937
+ opts.renderer.writeError(`[eternal] ${toErrorMessage3(err)}`);
4855
4938
  }
4856
4939
  await new Promise((resolve4) => setTimeout(resolve4, 250));
4857
4940
  return true;
@@ -4922,7 +5005,7 @@ async function runReplEternalLoop(opts, onInterruptsReset) {
4922
5005
  return true;
4923
5006
  }
4924
5007
  } catch (err) {
4925
- opts.renderer.writeError(`[parallel] ${toErrorMessage2(err)}`);
5008
+ opts.renderer.writeError(`[parallel] ${toErrorMessage3(err)}`);
4926
5009
  }
4927
5010
  await new Promise((resolve4) => setTimeout(resolve4, 250));
4928
5011
  return true;
@@ -5162,7 +5245,7 @@ ${lines.join("\n")}
5162
5245
  if (res?.message) opts.renderer.write(`${res.message}
5163
5246
  `);
5164
5247
  } catch (err) {
5165
- opts.renderer.writeError(toErrorMessage3(err));
5248
+ opts.renderer.writeError(toErrorMessage4(err));
5166
5249
  }
5167
5250
  continue;
5168
5251
  }
@@ -5254,7 +5337,7 @@ ${color11.dim(taskList2)}
5254
5337
  }
5255
5338
  }
5256
5339
  } catch (err) {
5257
- opts.renderer.writeError(toErrorMessage3(err));
5340
+ opts.renderer.writeError(toErrorMessage4(err));
5258
5341
  }
5259
5342
  continue;
5260
5343
  }
@@ -5533,7 +5616,7 @@ ${color11.dim(lines)}
5533
5616
  }
5534
5617
  }
5535
5618
  } catch (err) {
5536
- opts.renderer.writeError(toErrorMessage3(err));
5619
+ opts.renderer.writeError(toErrorMessage4(err));
5537
5620
  } finally {
5538
5621
  activeCtrl = void 0;
5539
5622
  }
@@ -5559,7 +5642,7 @@ async function pasteClipboardImage(builder, opts) {
5559
5642
  opts.renderer.write(color11.dim(` \u21B3 ${placeholder} (PNG ${kb}KB)
5560
5643
  `));
5561
5644
  } catch (err) {
5562
- opts.renderer.writeError(`Clipboard image error: ${toErrorMessage3(err)}`);
5645
+ opts.renderer.writeError(`Clipboard image error: ${toErrorMessage4(err)}`);
5563
5646
  }
5564
5647
  }
5565
5648
 
@@ -6217,6 +6300,15 @@ async function execute(deps) {
6217
6300
  chimeraWork.track(work);
6218
6301
  }
6219
6302
  });
6303
+ installSpecialistTriggerHandler({
6304
+ events,
6305
+ director,
6306
+ session,
6307
+ teardownHandlers: chimeraTeardowns,
6308
+ trackWork: (work) => {
6309
+ chimeraWork.track(work);
6310
+ }
6311
+ });
6220
6312
  installChimeraCascadeHandler({
6221
6313
  events,
6222
6314
  director,
@@ -6748,4 +6840,4 @@ export {
6748
6840
  execute,
6749
6841
  resolveReviewerFallbackModels
6750
6842
  };
6751
- //# sourceMappingURL=execution-KH7WJNAX.js.map
6843
+ //# sourceMappingURL=execution-Z6A26EG6.js.map
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Spawns the roster specialist a file-pattern trigger asked for.
3
+ *
4
+ * The detection half lives in core (`specialist-trigger-plugin.ts`) and knows
5
+ * nothing about the fleet; this is the other side of that boundary, mirroring
6
+ * how `chimera.review_needed` is handled. A host with no Director simply never
7
+ * spawns, and the plugin keeps working as a pure detector.
8
+ *
9
+ * What it deliberately does not do: retry ladders, model pinning, cascades, or
10
+ * report persistence. A specialist woken by a glob is a background opinion,
11
+ * not a gate — if the model is down, the right outcome is one line in the
12
+ * transcript saying so, not a chain of failovers spending more money on an
13
+ * opinion nobody asked for.
14
+ */
15
+ import type { Director } from '@wrongstack/core/coordination';
16
+ import type { EventBus } from '@wrongstack/core/kernel';
17
+ import type { SessionWriter } from '@wrongstack/core/types';
18
+ export interface InstallSpecialistTriggerHandlerOptions {
19
+ events: EventBus;
20
+ director: Director | null | undefined;
21
+ session: SessionWriter;
22
+ /** Session-scoped disposers, drained at session end. */
23
+ teardownHandlers: Array<() => void>;
24
+ /** Registers background work so the session waits for it before closing. */
25
+ trackWork?: ((work: Promise<void>) => void) | undefined;
26
+ }
27
+ export declare function installSpecialistTriggerHandler({ events, director, session, teardownHandlers, trackWork, }: InstallSpecialistTriggerHandlerOptions): void;
28
+ //# sourceMappingURL=execution-specialist-trigger.d.ts.map
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Bridge ACP session/update progress onto the same buses in-process
3
+ * subagents use, so TUI fleet chat, WebUI Agents panel, and HQ timeline
4
+ * can watch Claude Code / Gemini / Kimi the same way they watch a native worker.
5
+ */
6
+ import type { ACPProgressEvent } from '@wrongstack/acp';
7
+ import type { FleetBus } from '@wrongstack/core/coordination';
8
+ import type { EventBus } from '@wrongstack/core/kernel';
9
+ export interface PublishAcpLiveProgressOpts {
10
+ event: ACPProgressEvent;
11
+ subagentId: string;
12
+ agentName: string;
13
+ sessionId?: string | undefined;
14
+ taskId?: string | undefined;
15
+ fleet?: Pick<FleetBus, 'emit'> | undefined;
16
+ hostEvents?: Pick<EventBus, 'emit'> | undefined;
17
+ }
18
+ export declare function publishAcpLiveProgress(opts: PublishAcpLiveProgressOpts): void;
19
+ //# sourceMappingURL=acp-live-progress.d.ts.map
@@ -1,9 +1,11 @@
1
1
  import type { SubagentRunner } from '@wrongstack/core/types';
2
+ import { type BuildAcpSubagentRunnerOptions } from './host-acp.js';
2
3
  export declare class HostAcpRunnerCache {
3
4
  private readonly maxEntries;
5
+ private readonly resolveOpts?;
4
6
  private readonly runners;
5
7
  private readonly accessOrder;
6
- constructor(maxEntries?: number);
8
+ constructor(maxEntries?: number, resolveOpts?: (() => BuildAcpSubagentRunnerOptions | undefined) | undefined);
7
9
  get(subagentId: string): Promise<SubagentRunner>;
8
10
  }
9
11
  //# sourceMappingURL=host-acp-runner-cache.d.ts.map
@@ -1,3 +1,15 @@
1
- import type { SubagentRunner } from '@wrongstack/core/types';
2
- export declare function buildAcpSubagentRunner(subagentId: string): Promise<SubagentRunner>;
1
+ import { type ACPProgressEvent, type AcpAgentCommandOverrides, type AcpLiveCatalog } from '@wrongstack/acp';
2
+ import type { SubagentRunContext, SubagentRunner, TaskSpec } from '@wrongstack/core/types';
3
+ export type AcpLivePublisher = (ctx: SubagentRunContext, task: TaskSpec, event: ACPProgressEvent) => void;
4
+ export interface BuildAcpSubagentRunnerOptions {
5
+ overrides?: AcpAgentCommandOverrides | undefined;
6
+ live?: AcpLiveCatalog | undefined;
7
+ publishLive?: AcpLivePublisher | undefined;
8
+ }
9
+ /**
10
+ * Same command resolution as `wstack acp spawn` / `/acp` — user override,
11
+ * bundled catalog, synced registry, then the legacy map. Director / `--bg`
12
+ * must not use a different argv than the CLI spawn path.
13
+ */
14
+ export declare function buildAcpSubagentRunner(subagentId: string, options?: BuildAcpSubagentRunnerOptions): Promise<SubagentRunner>;
3
15
  //# sourceMappingURL=host-acp.d.ts.map
@@ -120,6 +120,7 @@ export declare class MultiAgentHost {
120
120
  */
121
121
  buildSubagentRunner(config: Config): Promise<SubagentRunner>;
122
122
  buildACPRunner(subagentId: string): Promise<SubagentRunner>;
123
+ private acpCommandOpts;
123
124
  spawnACP(subagentId: string, task: string, config: Config): Promise<string>;
124
125
  private filterTools;
125
126
  private mailboxProjectDir;