@wrongstack/cli 0.302.0 → 0.303.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 (120) hide show
  1. package/data/providers.json +41 -155
  2. package/dist/{acp-DATHHPNT.js → acp-AQMGKW6O.js} +6 -5
  3. package/dist/{audit-QRCLEHHW.js → audit-BBR22QH3.js} +2 -2
  4. package/dist/{auth-PJD3JRH2.js → auth-K7CYVVKH.js} +121 -78
  5. package/dist/auth-menu/index.d.ts +5 -5
  6. package/dist/auth-menu/local.d.ts +4 -5
  7. package/dist/auth-menu/openai-codex-oauth.d.ts +1 -1
  8. package/dist/{auto-discover-providers-DRW4OZHG.js → auto-discover-providers-MHFLDSD3.js} +2 -2
  9. package/dist/{bench-7ZDWSNEF.js → bench-XNDUJOSZ.js} +10 -11
  10. package/dist/boot/auto-discover-providers.d.ts +1 -1
  11. package/dist/boot/container-wiring.d.ts +3 -3
  12. package/dist/boot/dispatch-webui.d.ts +1 -1
  13. package/dist/boot/system-prompt.d.ts +1 -2
  14. package/dist/boot/tool-registry.d.ts +1 -1
  15. package/dist/boot/tui-coordinator-setup.d.ts +1 -1
  16. package/dist/boot/tui-project-picker-callback.d.ts +1 -1
  17. package/dist/boot/tui-theme-adapter.d.ts +33 -0
  18. package/dist/boot-config.d.ts +2 -2
  19. package/dist/boot.d.ts +1 -1
  20. package/dist/{chunk-ETOEGL3V.js → chunk-3IC4IEZC.js} +7 -2
  21. package/dist/{chunk-PFVVUH5B.js → chunk-3JPTNADJ.js} +3 -2
  22. package/dist/{chunk-4GVH7V3S.js → chunk-52C7PD2H.js} +1 -1
  23. package/dist/{chunk-I5MEUFDI.js → chunk-53STH6CX.js} +94 -15
  24. package/dist/{chunk-OP47B3IX.js → chunk-7YLN7YUA.js} +7 -2
  25. package/dist/{chunk-263G3FMB.js → chunk-B4JLSXZB.js} +11 -14
  26. package/dist/{chunk-MT6FGXO3.js → chunk-C5NXM2SI.js} +19 -6
  27. package/dist/{chunk-XTIXVJXP.js → chunk-DGXNL7OT.js} +1 -1
  28. package/dist/{chunk-3MOUBRKZ.js → chunk-FJVCVZIV.js} +974 -935
  29. package/dist/{chunk-MRLYDHQ7.js → chunk-JQURRYU4.js} +4 -6
  30. package/dist/{chunk-ZECLGUTF.js → chunk-KV6DNQT6.js} +2 -2
  31. package/dist/{chunk-2KDOFTTM.js → chunk-LUAFQIXT.js} +1067 -900
  32. package/dist/{chunk-F4PEGAJZ.js → chunk-NUIHRGPY.js} +1 -1
  33. package/dist/{chunk-GUHQQG63.js → chunk-RK7E3IXT.js} +2 -4
  34. package/dist/{chunk-PYTFS4MC.js → chunk-SSSJQVUY.js} +27 -16
  35. package/dist/{chunk-PJHET45A.js → chunk-SZ42FYPT.js} +3 -3
  36. package/dist/{chunk-A6Q5KGLV.js → chunk-YKBRFSGL.js} +5 -5
  37. package/dist/cli-context.d.ts +2 -2
  38. package/dist/cli-eternal-flag.d.ts +1 -2
  39. package/dist/{cli-main-EOJ74CI4.js → cli-main-37XO26GK.js} +3269 -2206
  40. package/dist/context-limit.d.ts +11 -5
  41. package/dist/{diag-doctor-OQ3AA63O.js → diag-doctor-ZF5BF2MK.js} +2 -3
  42. package/dist/execute-deps.d.ts +1 -1
  43. package/dist/{execution-CQ772VPS.js → execution-MVOH6PAQ.js} +302 -149
  44. package/dist/{export-DOBGPY23.js → export-CCUXRJOU.js} +3 -11
  45. package/dist/fleet/host-context.d.ts +9 -0
  46. package/dist/fleet/host-learning-tracker.d.ts +2 -2
  47. package/dist/fleet/host-learning.d.ts +12 -1
  48. package/dist/fleet/host-subagent-factory.d.ts +1 -1
  49. package/dist/fleet/host-supervisor.d.ts +1 -1
  50. package/dist/fleet/host.d.ts +23 -1
  51. package/dist/fleet/routing.d.ts +1 -2
  52. package/dist/goal-host.d.ts +2 -2
  53. package/dist/hooks-wiring.d.ts +1 -1
  54. package/dist/{hq-LN5CJHCM.js → hq-CD77GVSS.js} +104 -55
  55. package/dist/hq-command-controller.d.ts +1 -1
  56. package/dist/hq-server/routes/system-handlers.d.ts +1 -2
  57. package/dist/hq-server/routes.d.ts +7 -7
  58. package/dist/{hq-server-S7HZG3PA.js → hq-server-DME6EWIO.js} +2 -2
  59. package/dist/index.d.ts +1 -1
  60. package/dist/index.js +2635 -2642
  61. package/dist/mailbox-bridge-bootstrap.d.ts +2 -2
  62. package/dist/{mcp-OHPJH73U.js → mcp-AX6ZAFJR.js} +8 -7
  63. package/dist/mcp-serve.d.ts +1 -1
  64. package/dist/{modeldiag-3DOK4BWW.js → modeldiag-SIVUOX2Y.js} +18 -13
  65. package/dist/{permissions-FNYLZIL4.js → permissions-2PWBL4YU.js} +5 -3
  66. package/dist/picker.d.ts +1 -1
  67. package/dist/plugin-management.d.ts +1 -1
  68. package/dist/{plugin-usage-YEVLOR33.js → plugin-usage-PTEETL3J.js} +2 -2
  69. package/dist/{plugins-K3BAUP4D.js → plugins-XRGWC3NJ.js} +3 -3
  70. package/dist/pre-launch.d.ts +2 -2
  71. package/dist/{providers-models-WEZ4EGLL.js → providers-models-VV74TRQ2.js} +86 -37
  72. package/dist/repl.d.ts +1 -1
  73. package/dist/{replay-FCBNHW3K.js → replay-WBRMEWQ5.js} +2 -2
  74. package/dist/{rewind-AOD3JIYX.js → rewind-7RE6ONIC.js} +17 -17
  75. package/dist/{sdd-runtime-AIJCJGWC.js → sdd-runtime-GFZ3NJKS.js} +2 -2
  76. package/dist/{sessions-config-XXN7267N.js → sessions-config-YX2ZPAFM.js} +36 -32
  77. package/dist/{simpleui-dist-JIFGUJO7.js → simpleui-dist-33VO3QHF.js} +9 -2
  78. package/dist/slash-commands/agent-improve.d.ts +4 -1
  79. package/dist/slash-commands/agents.d.ts +14 -0
  80. package/dist/slash-commands/command-context.d.ts +2 -3
  81. package/dist/slash-commands/helpers.d.ts +1 -1
  82. package/dist/slash-commands/index.d.ts +1 -1
  83. package/dist/slash-commands/intake.d.ts +10 -0
  84. package/dist/slash-commands/memory-triage.d.ts +1 -1
  85. package/dist/slash-commands/provider-status.d.ts +1 -1
  86. package/dist/slash-commands/theme.d.ts +6 -0
  87. package/dist/subcommands/handlers/hq.d.ts +20 -0
  88. package/dist/subcommands/handlers/per-subcommand-help-data.d.ts +1 -1
  89. package/dist/subcommands/handlers/update.d.ts +2 -0
  90. package/dist/{update-MV6TUACD.js → update-VZSOZGYC.js} +3 -3
  91. package/dist/{update-check-UMYTOH7Z.js → update-check-WARHSVZA.js} +2 -2
  92. package/dist/webui-server/connection-handler.d.ts +1 -1
  93. package/dist/webui-server/context-breakdown.d.ts +1 -1
  94. package/dist/webui-server/cost-helpers.d.ts +1 -1
  95. package/dist/webui-server/lifecycle.d.ts +1 -1
  96. package/dist/webui-server/prefs-seeding.d.ts +1 -1
  97. package/dist/webui-server/setup-events.d.ts +1 -1
  98. package/dist/webui-server/static-serve.d.ts +1 -1
  99. package/dist/{webui-server-NFNRGNNT.js → webui-server-E3OPEKU5.js} +18 -10
  100. package/dist/webui-server-options.d.ts +1 -1
  101. package/dist/wiring/command-host-state.d.ts +2 -2
  102. package/dist/wiring/controllers.d.ts +1 -2
  103. package/dist/wiring/dep-watcher.d.ts +1 -1
  104. package/dist/wiring/director-setup.d.ts +3 -3
  105. package/dist/wiring/eternal-command-handlers.d.ts +2 -2
  106. package/dist/wiring/management-tools.d.ts +2 -2
  107. package/dist/wiring/provider-runtime.d.ts +1 -1
  108. package/dist/wiring/provider-status.d.ts +1 -1
  109. package/dist/wiring/provider-utility-tools.d.ts +3 -3
  110. package/dist/wiring/provider.d.ts +1 -1
  111. package/dist/wiring/replay.d.ts +1 -1
  112. package/dist/wiring/runtime-controller-deps.d.ts +1 -1
  113. package/dist/wiring/runtime-dispatch-state.d.ts +1 -2
  114. package/dist/wiring/runtime-lifecycle-deps.d.ts +2 -2
  115. package/dist/wiring/runtime-picker-deps.d.ts +1 -2
  116. package/dist/wiring/sage.d.ts +1 -1
  117. package/dist/wiring/session-command-handlers.d.ts +1 -2
  118. package/dist/wiring/session.d.ts +6 -1
  119. package/dist/wiring/slash-commands.d.ts +2 -3
  120. package/package.json +23 -23
@@ -24,18 +24,24 @@ import {
24
24
  trySaveImplementationPlan,
25
25
  trySaveSpecFromAIOutput,
26
26
  trySaveTasksFromAIOutput
27
- } from "./chunk-XTIXVJXP.js";
27
+ } from "./chunk-DGXNL7OT.js";
28
28
  import {
29
29
  WEBUI_SESSION_CHILD_CAPABILITIES,
30
30
  writeWebuiSessionChildError,
31
31
  writeWebuiSessionChildReady
32
- } from "./chunk-PFVVUH5B.js";
32
+ } from "./chunk-3JPTNADJ.js";
33
33
  import {
34
34
  theme
35
35
  } from "./chunk-QD544J2B.js";
36
36
  import {
37
37
  fmtTok
38
38
  } from "./chunk-TYO2OVAD.js";
39
+ import {
40
+ resolveActiveApiKey
41
+ } from "./chunk-SZ42FYPT.js";
42
+ import {
43
+ activeProfileConfigPath
44
+ } from "./chunk-YMXXOOFN.js";
39
45
  import {
40
46
  terminalLink,
41
47
  terminalText
@@ -43,16 +49,10 @@ import {
43
49
  import {
44
50
  CLI_VERSION
45
51
  } from "./chunk-XJXDOF63.js";
46
- import {
47
- resolveActiveApiKey
48
- } from "./chunk-PJHET45A.js";
49
- import {
50
- activeProfileConfigPath
51
- } from "./chunk-YMXXOOFN.js";
52
52
  import "./chunk-7OCVIDC7.js";
53
53
 
54
54
  // src/execution.ts
55
- import * as path12 from "node:path";
55
+ import * as path13 from "node:path";
56
56
  import { effectiveFallbackChain as effectiveFallbackChain2, setQueuedMessagesSnapshot as setQueuedMessagesSnapshot2 } from "@wrongstack/core/agent";
57
57
  import { attachTodosCheckpoint as attachTodosCheckpoint2 } from "@wrongstack/core/storage";
58
58
  import { normalizeTokenSavingTier as normalizeTokenSavingTier2 } from "@wrongstack/core/types";
@@ -203,7 +203,7 @@ async function runWebUIDispatch(ctx) {
203
203
  const isSimpleUi = !isSessionChild && flags["simpleui"] === true;
204
204
  agent.disableInteractiveConfirmation();
205
205
  renderer.setSilent(true);
206
- const { runWebUI } = await import("./webui-server-NFNRGNNT.js");
206
+ const { runWebUI } = await import("./webui-server-E3OPEKU5.js");
207
207
  const flagValue = (names) => {
208
208
  for (const name of names) {
209
209
  if (!Object.hasOwn(flags, name)) continue;
@@ -258,7 +258,7 @@ async function runWebUIDispatch(ctx) {
258
258
  webuiPublicWsUrl = webuiSessionChild?.publicWsUrl ?? flagValue(["webui-public-ws-url", "public-ws-url"]) ?? process.env["WEBUI_PUBLIC_WS_URL"];
259
259
  webuiRequireToken = webuiSessionChild?.requireToken ?? flagBoolean(["webui-require-token", "require-token"]) ?? envFlag("WEBUI_REQUIRE_TOKEN");
260
260
  if (isSimpleUi) {
261
- const { ensureSimpleUiDistDir } = await import("./simpleui-dist-JIFGUJO7.js");
261
+ const { ensureSimpleUiDistDir } = await import("./simpleui-dist-33VO3QHF.js");
262
262
  frontendDistDir = await ensureSimpleUiDistDir();
263
263
  }
264
264
  } catch (err) {
@@ -435,7 +435,8 @@ async function runWebUIDispatch(ctx) {
435
435
  function resolveExecutionMode(positional, flags) {
436
436
  const prompt = typeof flags["prompt"] === "string" ? flags["prompt"] : "";
437
437
  if (positional.length > 0 || prompt.length > 0) return "single-shot";
438
- if (flags.tui && flags["no-tui"] !== true && !flags.webui && !flags["webui-session-child"]) return "tui";
438
+ if (flags.tui && flags["no-tui"] !== true && !flags.webui && !flags["webui-session-child"])
439
+ return "tui";
439
440
  if (flags.webui || flags["webui-session-child"]) return "webui";
440
441
  return "repl";
441
442
  }
@@ -579,7 +580,17 @@ function createTuiCoordinatorCallbacks({
579
580
  import * as path2 from "node:path";
580
581
  import { AutonomousCoordinator } from "@wrongstack/core/coordination";
581
582
  function setupAutonomousCoordinator(ctx) {
582
- const { state, events, context, wpaths, mailbox, director, getDirector, coordinatorController, onCoordinatorStopSetter } = ctx;
583
+ const {
584
+ state,
585
+ events,
586
+ context,
587
+ wpaths,
588
+ mailbox,
589
+ director,
590
+ getDirector,
591
+ coordinatorController,
592
+ onCoordinatorStopSetter
593
+ } = ctx;
583
594
  const ensure = () => {
584
595
  if (state.autonomousCoordinator) return state.autonomousCoordinator;
585
596
  const currentDirector = getDirector?.() ?? director;
@@ -601,7 +612,9 @@ function setupAutonomousCoordinator(ctx) {
601
612
  Context: ${JSON.stringify(prompt.context)}
602
613
 
603
614
  Options:
604
- ${prompt.options.map((o, i) => ` ${i + 1}. [${o.id}] ${o.label}${o.consequence ? ` \u2014 ${o.consequence}` : ""}`).join("\n")}
615
+ ${prompt.options.map(
616
+ (o, i) => ` ${i + 1}. [${o.id}] ${o.label}${o.consequence ? ` \u2014 ${o.consequence}` : ""}`
617
+ ).join("\n")}
605
618
 
606
619
  Risk: ${prompt.risk}
607
620
 
@@ -622,7 +635,9 @@ Reply with ONLY the JSON object.`
622
635
  },
623
636
  { signal: context.signal }
624
637
  );
625
- const text = resp.content.filter((b) => b.type === "text").map((b) => b.text).join("\n").trim();
638
+ const text = resp.content.filter(
639
+ (b) => b.type === "text"
640
+ ).map((b) => b.text).join("\n").trim();
626
641
  const cleaned = text.replace(/^```(?:json)?\s*/i, "").replace(/```$/, "").trim();
627
642
  try {
628
643
  const parsed = JSON.parse(cleaned);
@@ -666,14 +681,20 @@ Reply with ONLY the JSON object.`
666
681
  coordinatorController["onCoordinatorTasks"] = async () => {
667
682
  if (!state.autonomousCoordinator) return null;
668
683
  await state.autonomousCoordinator.graph.load();
669
- return state.autonomousCoordinator.auction.getPendingTasks().map((task) => ({ id: task.id, title: task.title, priority: task.priority, tags: task.tags }));
684
+ return state.autonomousCoordinator.auction.getPendingTasks().map((task) => ({
685
+ id: task.id,
686
+ title: task.title,
687
+ priority: task.priority,
688
+ tags: task.tags
689
+ }));
670
690
  };
671
691
  coordinatorController["onCoordinatorClaim"] = async (taskId) => {
672
692
  if (!state.autonomousCoordinator) return "No coordinator is active.";
673
693
  await state.autonomousCoordinator.graph.load();
674
694
  const goal = state.autonomousCoordinator.graph.get(taskId);
675
695
  if (goal?.type !== "goal") return `Task ${taskId.slice(0, 8)} not found.`;
676
- if (goal.status !== "pending") return `Task ${taskId.slice(0, 8)} is ${goal.status}, not claimable.`;
696
+ if (goal.status !== "pending")
697
+ return `Task ${taskId.slice(0, 8)} is ${goal.status}, not claimable.`;
677
698
  const ok = await state.autonomousCoordinator.auction.claim(
678
699
  taskId,
679
700
  `terminal@${context.session.id ?? "unknown"}`,
@@ -687,8 +708,12 @@ Reply with ONLY the JSON object.`
687
708
  await state.autonomousCoordinator.graph.load();
688
709
  const goal = state.autonomousCoordinator.graph.get(taskId);
689
710
  if (goal?.type !== "goal") return `Task ${taskId.slice(0, 8)} not found.`;
690
- if (goal.status !== "in_progress") return `Task ${taskId.slice(0, 8)} is ${goal.status}, cannot complete.`;
691
- await state.autonomousCoordinator.reportTaskCompletion(taskId, result ?? "Terminal worker completed the task");
711
+ if (goal.status !== "in_progress")
712
+ return `Task ${taskId.slice(0, 8)} is ${goal.status}, cannot complete.`;
713
+ await state.autonomousCoordinator.reportTaskCompletion(
714
+ taskId,
715
+ result ?? "Terminal worker completed the task"
716
+ );
692
717
  return null;
693
718
  };
694
719
  coordinatorController["onCoordinatorFail"] = async (taskId, error) => {
@@ -696,7 +721,8 @@ Reply with ONLY the JSON object.`
696
721
  await state.autonomousCoordinator.graph.load();
697
722
  const goal = state.autonomousCoordinator.graph.get(taskId);
698
723
  if (goal?.type !== "goal") return `Task ${taskId.slice(0, 8)} not found.`;
699
- if (goal.status !== "in_progress") return `Task ${taskId.slice(0, 8)} is ${goal.status}, cannot fail.`;
724
+ if (goal.status !== "in_progress")
725
+ return `Task ${taskId.slice(0, 8)} is ${goal.status}, cannot fail.`;
700
726
  await state.autonomousCoordinator.reportTaskFailure(taskId, error);
701
727
  return null;
702
728
  };
@@ -705,8 +731,18 @@ Reply with ONLY the JSON object.`
705
731
  await state.autonomousCoordinator.syncFromGraph();
706
732
  const stats = state.autonomousCoordinator.getStats();
707
733
  return {
708
- goals: { total: stats.goals.total, done: stats.goals.done, pending: stats.goals.pending, failed: stats.goals.failed },
709
- dag: { running: stats.dag.running, ready: stats.dag.ready, done: stats.dag.done, failed: stats.dag.failed },
734
+ goals: {
735
+ total: stats.goals.total,
736
+ done: stats.goals.done,
737
+ pending: stats.goals.pending,
738
+ failed: stats.goals.failed
739
+ },
740
+ dag: {
741
+ running: stats.dag.running,
742
+ ready: stats.dag.ready,
743
+ done: stats.dag.done,
744
+ failed: stats.dag.failed
745
+ },
710
746
  auction: { pending: stats.auction.pending, inProgress: stats.auction.in_progress }
711
747
  };
712
748
  };
@@ -798,9 +834,9 @@ function wireGoal(events) {
798
834
  // src/boot/tui-live-sessions.ts
799
835
  import * as path3 from "node:path";
800
836
  async function getLiveSessions(ctx) {
801
- const { SessionRegistry } = await import("@wrongstack/core/storage");
837
+ const { getSessionRegistry } = await import("@wrongstack/core/storage");
802
838
  const globalRoot = path3.dirname(ctx.state.wpaths.globalConfig);
803
- const registry = new SessionRegistry(globalRoot);
839
+ const registry = getSessionRegistry(globalRoot);
804
840
  const sessions = await registry.list();
805
841
  return sessions.filter((s) => s.status !== "stale").map((s) => ({
806
842
  sessionId: s.sessionId,
@@ -863,9 +899,12 @@ async function onProjectSelect(ctx, slug, kind) {
863
899
  const hasActiveAgents = fleetRunning > 0 || eternalActive || parallelActive;
864
900
  if (hasActiveAgents) {
865
901
  const parts = [
866
- color3.yellow("\u26A0 Switching project in place; active background work is still tied to the previous project:")
902
+ color3.yellow(
903
+ "\u26A0 Switching project in place; active background work is still tied to the previous project:"
904
+ )
867
905
  ];
868
- if (fleetRunning > 0) parts.push(color3.dim(` \u2022 ${fleetRunning} subagent(s) currently running`));
906
+ if (fleetRunning > 0)
907
+ parts.push(color3.dim(` \u2022 ${fleetRunning} subagent(s) currently running`));
869
908
  if (eternalActive) parts.push(color3.dim(" \u2022 Eternal engine is active"));
870
909
  if (parallelActive) parts.push(color3.dim(" \u2022 Parallel engine is active"));
871
910
  parts.push("");
@@ -881,18 +920,16 @@ ${parts.join("\n")}
881
920
  `));
882
921
  } catch (err) {
883
922
  renderer.write(
884
- color3.red(
885
- `Project switch failed: ${err instanceof Error ? err.message : String(err)}
886
- `
887
- )
923
+ color3.red(`Project switch failed: ${err instanceof Error ? err.message : String(err)}
924
+ `)
888
925
  );
889
926
  }
890
927
  }
891
928
 
892
929
  // src/boot/tui-project-spawn.ts
893
930
  import { spawn } from "node:child_process";
894
- import { createRequire } from "node:module";
895
931
  import * as fs from "node:fs/promises";
932
+ import { createRequire } from "node:module";
896
933
  import * as path5 from "node:path";
897
934
  import { color as color4 } from "@wrongstack/core/utils";
898
935
  async function handleProjectSwitchSpawn(opts) {
@@ -968,6 +1005,7 @@ async function switchProjectInPlace(ctx, targetRoot, displayName) {
968
1005
  const stat2 = await fs2.stat(resolved).catch(() => null);
969
1006
  if (!stat2?.isDirectory()) return `Cannot switch: not a directory: ${resolved}`;
970
1007
  const oldWriter = context.session;
1008
+ const oldSessionStore = state.activeSessionStore;
971
1009
  const oldUsage = tokenCounter.total();
972
1010
  const oldProjectRoot = state.projectRoot;
973
1011
  const nextWpaths = resolveWstackPaths({
@@ -992,23 +1030,53 @@ async function switchProjectInPlace(ctx, targetRoot, displayName) {
992
1030
  } catch (err) {
993
1031
  await nextWriter.close().catch(() => void 0);
994
1032
  await nextSessionStore.delete(nextWriter.id).catch(() => void 0);
1033
+ await nextSessionStore.dispose?.();
995
1034
  return `Cannot switch: ${err instanceof Error ? err.message : String(err)}`;
996
1035
  }
997
1036
  if (!state.activateSessionIdentity) {
998
1037
  await nextWriter.close().catch(() => void 0);
999
1038
  await nextSessionStore.delete(nextWriter.id).catch(() => void 0);
1039
+ await nextSessionStore.dispose?.();
1000
1040
  return "Cannot switch: session ownership registry is unavailable.";
1001
1041
  }
1042
+ let targetClaim;
1043
+ let targetActivated = false;
1002
1044
  try {
1003
- await state.activateSessionIdentity(nextWriter.id, {
1045
+ const { getSessionRegistry } = await import("@wrongstack/core/storage");
1046
+ const registry = getSessionRegistry(state.wpaths.globalRoot);
1047
+ targetClaim = await registry.reserveResume({
1048
+ sessionId: nextWriter.id,
1049
+ projectSlug: nextWpaths.projectSlug,
1050
+ projectRoot: resolved
1051
+ });
1052
+ const target = {
1004
1053
  projectSlug: nextWpaths.projectSlug,
1005
1054
  projectRoot: resolved,
1006
1055
  projectName: displayName || path6.basename(resolved),
1007
1056
  workingDir: resolved
1057
+ };
1058
+ await targetClaim.activate({
1059
+ sessionId: nextWriter.id,
1060
+ ...target,
1061
+ clientType: "tui",
1062
+ pid: process.pid,
1063
+ startedAt: (/* @__PURE__ */ new Date()).toISOString()
1008
1064
  });
1065
+ targetActivated = true;
1066
+ await state.activateSessionIdentity(nextWriter.id, target);
1009
1067
  } catch (err) {
1068
+ if (!targetActivated) await targetClaim?.cancel().catch(() => void 0);
1069
+ else if (oldWriter) {
1070
+ await state.activateSessionIdentity(oldWriter.id, {
1071
+ projectSlug: state.wpaths.projectSlug,
1072
+ projectRoot: oldProjectRoot,
1073
+ projectName: path6.basename(oldProjectRoot),
1074
+ workingDir: context.workingDir
1075
+ }).catch(() => void 0);
1076
+ }
1010
1077
  await nextWriter.close().catch(() => void 0);
1011
1078
  await nextSessionStore.delete(nextWriter.id).catch(() => void 0);
1079
+ await nextSessionStore.dispose?.();
1012
1080
  return `Cannot switch: ${err instanceof Error ? err.message : String(err)}`;
1013
1081
  }
1014
1082
  await Promise.resolve(state.detachActiveTodosCheckpoint?.()).catch(() => void 0);
@@ -1093,6 +1161,7 @@ async function switchProjectInPlace(ctx, targetRoot, displayName) {
1093
1161
  })
1094
1162
  );
1095
1163
  }
1164
+ await oldSessionStore?.dispose?.().catch(() => void 0);
1096
1165
  const emitUntyped = events.emit;
1097
1166
  emitUntyped("project.switched", { from: oldProjectRoot, to: resolved, name: displayName });
1098
1167
  return null;
@@ -1100,7 +1169,7 @@ async function switchProjectInPlace(ctx, targetRoot, displayName) {
1100
1169
 
1101
1170
  // src/boot/tui-sdd-callback.ts
1102
1171
  async function getSDDContext() {
1103
- const { getActiveSDDContext: getActiveSDDContext2 } = await import("./sdd-runtime-AIJCJGWC.js");
1172
+ const { getActiveSDDContext: getActiveSDDContext2 } = await import("./sdd-runtime-GFZ3NJKS.js");
1104
1173
  return getActiveSDDContext2();
1105
1174
  }
1106
1175
  async function onSDDOutput(output) {
@@ -1111,11 +1180,10 @@ async function onSDDOutput(output) {
1111
1180
  autoDetectTaskCompletion: autoDetectTaskCompletion2,
1112
1181
  getTaskProgress: getTaskProgress2,
1113
1182
  getActiveSDDPhase: getActiveSDDPhase2
1114
- } = await import("./sdd-runtime-AIJCJGWC.js");
1183
+ } = await import("./sdd-runtime-GFZ3NJKS.js");
1115
1184
  const messages = [];
1116
1185
  const specSaved = await trySaveSpecFromAIOutput2(output);
1117
- if (specSaved)
1118
- messages.push("\u2713 Spec detected and saved! Use /sdd approve to continue.");
1186
+ if (specSaved) messages.push("\u2713 Spec detected and saved! Use /sdd approve to continue.");
1119
1187
  const planSaved = trySaveImplementationPlan2(output);
1120
1188
  if (planSaved) messages.push("\u2713 Implementation plan saved!");
1121
1189
  const tasksSaved = await trySaveTasksFromAIOutput2(output);
@@ -1164,22 +1232,9 @@ async function resumeSession(ctx, sessionId) {
1164
1232
  );
1165
1233
  return null;
1166
1234
  }
1167
- try {
1168
- const { SessionRegistry } = await import("@wrongstack/core/storage");
1169
- const registry = new SessionRegistry(path7.dirname(state.wpaths.globalConfig));
1170
- const live = (await registry.list()).find(
1171
- (s) => s.sessionId === canonicalSessionId && s.status !== "stale" && s.pid !== process.pid
1172
- );
1173
- if (live) {
1174
- throw new Error(
1175
- `Session is open in another running wstack (pid ${live.pid}) \u2014 it cannot be resumed here while live.`
1176
- );
1177
- }
1178
- } catch (err) {
1179
- if (err instanceof Error && err.message.startsWith("Session is open")) throw err;
1180
- }
1181
1235
  const previousSessionId = agent.ctx.session?.id;
1182
1236
  let identityClaimed = false;
1237
+ let resumeClaim;
1183
1238
  let writerSwapped = false;
1184
1239
  let openedWriter;
1185
1240
  let oldWriter;
@@ -1189,12 +1244,34 @@ async function resumeSession(ctx, sessionId) {
1189
1244
  let oldPlanPath;
1190
1245
  let oldTaskPath;
1191
1246
  try {
1192
- if (state.activateSessionIdentity) {
1247
+ if (state.wpaths.projectSlug && state.wpaths.globalRoot) {
1248
+ const { getSessionRegistry } = await import("@wrongstack/core/storage");
1249
+ const registry = getSessionRegistry(state.wpaths.globalRoot);
1250
+ resumeClaim = await registry.reserveResume({
1251
+ sessionId: canonicalSessionId,
1252
+ projectSlug: state.wpaths.projectSlug,
1253
+ projectRoot: state.projectRoot
1254
+ });
1255
+ } else if (state.activateSessionIdentity) {
1193
1256
  await state.activateSessionIdentity(canonicalSessionId);
1194
1257
  identityClaimed = true;
1195
1258
  }
1196
1259
  const resumed = await state.activeSessionStore.resume(canonicalSessionId);
1197
1260
  openedWriter = resumed.writer;
1261
+ if (resumeClaim) {
1262
+ await resumeClaim.activate({
1263
+ sessionId: canonicalSessionId,
1264
+ projectSlug: state.wpaths.projectSlug,
1265
+ projectRoot: state.projectRoot,
1266
+ projectName: path7.basename(state.projectRoot),
1267
+ workingDir: agent.ctx.workingDir,
1268
+ clientType: "tui",
1269
+ pid: process.pid,
1270
+ startedAt: (/* @__PURE__ */ new Date()).toISOString()
1271
+ });
1272
+ identityClaimed = true;
1273
+ await state.activateSessionIdentity?.(canonicalSessionId);
1274
+ }
1198
1275
  const meta = resumed.data.metadata;
1199
1276
  const entries = replaySessionMessages(
1200
1277
  resumed.data.messages,
@@ -1329,6 +1406,7 @@ async function resumeSession(ctx, sessionId) {
1329
1406
  void oldWriterFinalize;
1330
1407
  return result;
1331
1408
  } catch (err) {
1409
+ if (!identityClaimed) await resumeClaim?.cancel().catch(() => void 0);
1332
1410
  if (identityClaimed && previousSessionId) {
1333
1411
  await state.activateSessionIdentity?.(previousSessionId).catch((rollbackErr) => {
1334
1412
  console.error(
@@ -1773,6 +1851,57 @@ function createSettingsAdapter(ctx) {
1773
1851
  return { getSettings, saveSettings };
1774
1852
  }
1775
1853
 
1854
+ // src/boot/tui-theme-adapter.ts
1855
+ import * as fs4 from "node:fs/promises";
1856
+ import * as path9 from "node:path";
1857
+ import { atomicWrite as atomicWrite2 } from "@wrongstack/core/utils";
1858
+ var VALID_PRESETS = /* @__PURE__ */ new Set([
1859
+ "catppuccin",
1860
+ "tokyo-night",
1861
+ "nord",
1862
+ "cyberpunk",
1863
+ "dracula",
1864
+ "gruvbox-dark",
1865
+ "solarized-dark",
1866
+ "one-dark",
1867
+ "monokai",
1868
+ "rose-pine",
1869
+ "kanagawa",
1870
+ "ayu-dark",
1871
+ "everforest",
1872
+ "night-owl",
1873
+ "synthwave"
1874
+ ]);
1875
+ function createThemeAdapter({ configStore, wpaths }) {
1876
+ return {
1877
+ getThemePreset: () => {
1878
+ const live = configStore.get();
1879
+ const candidate = live.themePreset;
1880
+ return candidate && VALID_PRESETS.has(candidate) ? candidate : void 0;
1881
+ },
1882
+ saveThemePreset: async (preset) => {
1883
+ if (!VALID_PRESETS.has(preset)) {
1884
+ throw new Error(`Unknown theme preset: ${preset}`);
1885
+ }
1886
+ configStore.update({ themePreset: preset });
1887
+ const configPath = activeProfileConfigPath(wpaths, configStore.get());
1888
+ let parsed = {};
1889
+ try {
1890
+ const raw = await fs4.readFile(configPath, "utf8");
1891
+ parsed = JSON.parse(raw);
1892
+ } catch (err) {
1893
+ const e = err;
1894
+ if (e.code !== "ENOENT") {
1895
+ throw err;
1896
+ }
1897
+ }
1898
+ parsed.themePreset = preset;
1899
+ await fs4.mkdir(path9.dirname(configPath), { recursive: true });
1900
+ await atomicWrite2(configPath, JSON.stringify(parsed, null, 2), { mode: 384 });
1901
+ }
1902
+ };
1903
+ }
1904
+
1776
1905
  // src/brain-menu/panel-service.ts
1777
1906
  import { BUILTIN_COUNCIL_PERSONAS } from "@wrongstack/core/execution";
1778
1907
  var PERSONA_CATALOG = BUILTIN_COUNCIL_PERSONAS.map((persona) => ({
@@ -2127,19 +2256,16 @@ async function finalizeExecutionCleanup(input) {
2127
2256
  );
2128
2257
  });
2129
2258
  const sessionEndProducers = /* @__PURE__ */ new Set();
2130
- events.emit(
2131
- "session.ended",
2132
- {
2133
- id: activeSession.id,
2134
- sessionId: activeSession.id,
2135
- usage: tokenCounter.total(),
2136
- waitUntil: (work) => {
2137
- const tracked = Promise.resolve(work).finally(() => sessionEndProducers.delete(tracked));
2138
- void tracked.catch(() => void 0);
2139
- sessionEndProducers.add(tracked);
2140
- }
2259
+ events.emit("session.ended", {
2260
+ id: activeSession.id,
2261
+ sessionId: activeSession.id,
2262
+ usage: tokenCounter.total(),
2263
+ waitUntil: (work) => {
2264
+ const tracked = Promise.resolve(work).finally(() => sessionEndProducers.delete(tracked));
2265
+ void tracked.catch(() => void 0);
2266
+ sessionEndProducers.add(tracked);
2141
2267
  }
2142
- );
2268
+ });
2143
2269
  try {
2144
2270
  while (sessionEndProducers.size > 0) {
2145
2271
  await Promise.allSettled([...sessionEndProducers]);
@@ -2196,10 +2322,7 @@ import { randomUUID } from "node:crypto";
2196
2322
  import { WIDE_SUBAGENT_CAPABILITIES } from "@wrongstack/core/security";
2197
2323
 
2198
2324
  // src/kanban-dispatch-route.ts
2199
- import {
2200
- fallbackProfileChain,
2201
- parseModelRef as parseModelRef2
2202
- } from "@wrongstack/core/agent";
2325
+ import { fallbackProfileChain, parseModelRef as parseModelRef2 } from "@wrongstack/core/agent";
2203
2326
  function resolveKanbanDispatchRoute(config, spawnOpts) {
2204
2327
  let provider = spawnOpts?.provider;
2205
2328
  let model = spawnOpts?.model;
@@ -2330,8 +2453,7 @@ function createReplFleetCallbacks({
2330
2453
  }
2331
2454
 
2332
2455
  // src/fleet-statusline.ts
2333
- import { color as color5 } from "@wrongstack/core/utils";
2334
- import { onResize } from "@wrongstack/core/utils";
2456
+ import { color as color5, onResize } from "@wrongstack/core/utils";
2335
2457
  function fmtElapsed(ms) {
2336
2458
  const s = Math.floor(ms / 1e3);
2337
2459
  if (s < 60) return `${s}s`;
@@ -2593,7 +2715,7 @@ function createChimeraWorkRegistry() {
2593
2715
 
2594
2716
  // src/execution-chimera-cascade.ts
2595
2717
  import * as fsp from "node:fs/promises";
2596
- import * as path9 from "node:path";
2718
+ import * as path10 from "node:path";
2597
2719
  import { emitReviewIfChanged } from "@wrongstack/core/plugin";
2598
2720
 
2599
2721
  // src/chimera-review-task.ts
@@ -2956,7 +3078,7 @@ async function maybeReReviewCascade({
2956
3078
  const reReadFiles = [];
2957
3079
  for (const f of bundle.files) {
2958
3080
  try {
2959
- const absPath = path9.join(bundle.cwd, f.path);
3081
+ const absPath = path10.join(bundle.cwd, f.path);
2960
3082
  const content = await fsp.readFile(absPath, "utf8");
2961
3083
  reReadFiles.push({ path: f.path, status: "modified", content });
2962
3084
  } catch {
@@ -3025,7 +3147,7 @@ async function maybeReReviewCascade({
3025
3147
 
3026
3148
  // src/execution-chimera-review.ts
3027
3149
  import { randomUUID as randomUUID3 } from "node:crypto";
3028
- import path10 from "node:path";
3150
+ import path11 from "node:path";
3029
3151
  import { effectiveFallbackChain } from "@wrongstack/core/agent";
3030
3152
  import {
3031
3153
  CHIMERA_REVIEW_PROMPT,
@@ -3038,7 +3160,7 @@ import {
3038
3160
  function normalizeFileKeyForCitation(raw, cwd) {
3039
3161
  const forward = raw.replace(/\\/g, "/").replace(/^\.\//, "");
3040
3162
  const isAbsolute = forward.startsWith("/") || /^[a-zA-Z]:\//.test(forward);
3041
- const pathMod = process.platform === "win32" ? path10.win32 : path10;
3163
+ const pathMod = process.platform === "win32" ? path11.win32 : path11;
3042
3164
  const relative = isAbsolute ? pathMod.relative(cwd, forward).replace(/\\/g, "/").replace(/^\.\//, "") : forward;
3043
3165
  return process.platform === "win32" ? relative.toLowerCase() : relative;
3044
3166
  }
@@ -3236,16 +3358,16 @@ function installChimeraReviewHandler({
3236
3358
  const changedBasenameIndex = /* @__PURE__ */ new Map();
3237
3359
  for (const file of p.files) {
3238
3360
  const normalized = normalizeFileKeyForCitation(file.path, p.cwd);
3239
- const basename6 = path10.basename(file.path).toLowerCase();
3240
- const bucket = changedBasenameIndex.get(basename6);
3361
+ const basename7 = path11.basename(file.path).toLowerCase();
3362
+ const bucket = changedBasenameIndex.get(basename7);
3241
3363
  if (bucket) bucket.push(normalized);
3242
- else changedBasenameIndex.set(basename6, [normalized]);
3364
+ else changedBasenameIndex.set(basename7, [normalized]);
3243
3365
  }
3244
3366
  const droppedCitations = citedFindings.filter((finding) => {
3245
3367
  const citedKey = normalizeFileKeyForCitation(finding.location.file, p.cwd);
3246
3368
  if (citedPaths.has(citedKey)) return false;
3247
- const basename6 = path10.basename(finding.location.file).toLowerCase();
3248
- const bucket = changedBasenameIndex.get(basename6);
3369
+ const basename7 = path11.basename(finding.location.file).toLowerCase();
3370
+ const bucket = changedBasenameIndex.get(basename7);
3249
3371
  return !(bucket && bucket.length === 1);
3250
3372
  });
3251
3373
  const effectiveHasFindings = reviewHasFindings && (parsedReview.findings.length === 0 || parsedReview.findings.length > droppedCitations.length);
@@ -3534,11 +3656,24 @@ async function predictNextTasks(input, opts) {
3534
3656
  }
3535
3657
 
3536
3658
  // src/repl.ts
3537
- import { toErrorMessage } from "@wrongstack/core/utils";
3538
- import { color as color9, estimateRequestTokensCalibrated as estimateRequestTokensCalibrated2, expectDefined, hasOpenTodos as hasOpenTodos2 } from "@wrongstack/core/utils";
3539
3659
  import { detectContinueIntent, InputBuilder, resolveContinuation } from "@wrongstack/core/agent";
3540
3660
  import { goalFilePath, loadGoal, summarizeUsage } from "@wrongstack/core/goal";
3661
+ import {
3662
+ color as color9,
3663
+ estimateRequestTokensCalibrated as estimateRequestTokensCalibrated2,
3664
+ expectDefined,
3665
+ hasOpenTodos as hasOpenTodos2,
3666
+ toErrorMessage
3667
+ } from "@wrongstack/core/utils";
3541
3668
  import { readClipboardImage, routeImagesForModel } from "@wrongstack/runtime";
3669
+ import { createAutoProceedLoopGuard } from "@wrongstack/tools/auto-proceed-loop-guard";
3670
+ import { todoTool } from "@wrongstack/tools/todo";
3671
+
3672
+ // src/repl-auto-proceed.ts
3673
+ import { color as color6, estimateRequestTokensCalibrated } from "@wrongstack/core/utils";
3674
+ import {
3675
+ GROUNDED_NO_PROGRESS_STEER
3676
+ } from "@wrongstack/tools/auto-proceed-loop-guard";
3542
3677
 
3543
3678
  // src/repl-suggestions.ts
3544
3679
  import { hasOpenTodos } from "@wrongstack/core/utils";
@@ -3556,8 +3691,6 @@ function parseSuggestionsFromOutput(finalText, todos) {
3556
3691
  }
3557
3692
 
3558
3693
  // src/repl-auto-proceed.ts
3559
- import { color as color6, estimateRequestTokensCalibrated } from "@wrongstack/core/utils";
3560
- import { GROUNDED_NO_PROGRESS_STEER } from "@wrongstack/tools/auto-proceed-loop-guard";
3561
3694
  async function runAutoProceed(opts, suggestion, delayMs, ctrl, loopGuard, grounded = false) {
3562
3695
  const truncated = suggestion.length > 80 ? `${suggestion.slice(0, 77)}\u2026` : suggestion;
3563
3696
  console.log(
@@ -3708,6 +3841,54 @@ async function runContextCompaction(opts, _signal) {
3708
3841
  }
3709
3842
  }
3710
3843
 
3844
+ // src/repl-client-registration.ts
3845
+ import * as crypto from "node:crypto";
3846
+ import * as path12 from "node:path";
3847
+ import { getSharedProjectMailbox, resolveProjectDir } from "@wrongstack/core/coordination";
3848
+ import { wstackGlobalRoot } from "@wrongstack/core/utils";
3849
+ function registerReplClient(opts) {
3850
+ const replProjectRoot = opts.projectRoot ?? process.cwd();
3851
+ const projectDir = resolveProjectDir(replProjectRoot, wstackGlobalRoot());
3852
+ const clientId = `repl@${crypto.randomUUID().slice(0, 8)}`;
3853
+ const hqConnection = startCliHqConnection({
3854
+ clientKind: "repl",
3855
+ projectRoot: replProjectRoot,
3856
+ projectName: path12.basename(replProjectRoot),
3857
+ appConfig: opts.appConfig,
3858
+ capabilities: ["telemetry.publish", "mailbox.summary"]
3859
+ });
3860
+ const clientMailbox = getSharedProjectMailbox(
3861
+ projectDir,
3862
+ void 0,
3863
+ () => hqConnection.getPublisher()
3864
+ );
3865
+ let closed = false;
3866
+ let clientHeartbeat;
3867
+ clientMailbox.registerClient({
3868
+ clientId,
3869
+ sessionId: opts.getSessionId?.() ?? replProjectRoot,
3870
+ name: `REPL [${path12.basename(replProjectRoot)}]`,
3871
+ source: "repl",
3872
+ pid: process.pid
3873
+ }).then(() => {
3874
+ if (closed) return;
3875
+ clientHeartbeat = setInterval(() => {
3876
+ clientMailbox.clientHeartbeat({ clientId, sessionId: opts.getSessionId?.() ?? replProjectRoot }).catch(() => {
3877
+ });
3878
+ }, 15e3);
3879
+ }).catch(() => {
3880
+ });
3881
+ return {
3882
+ clientId,
3883
+ close() {
3884
+ closed = true;
3885
+ if (clientHeartbeat) clearInterval(clientHeartbeat);
3886
+ clientMailbox.deregisterClient(clientId).catch(() => void 0);
3887
+ hqConnection.stop();
3888
+ }
3889
+ };
3890
+ }
3891
+
3711
3892
  // src/repl-input.ts
3712
3893
  import { color as color7 } from "@wrongstack/core/utils";
3713
3894
  async function readPossiblyMultiline(opts) {
@@ -3765,59 +3946,7 @@ function printBanner(renderer, projectName) {
3765
3946
  `);
3766
3947
  }
3767
3948
 
3768
- // src/repl-client-registration.ts
3769
- import * as crypto from "node:crypto";
3770
- import * as path11 from "node:path";
3771
- import {
3772
- getSharedProjectMailbox,
3773
- resolveProjectDir
3774
- } from "@wrongstack/core/coordination";
3775
- import { wstackGlobalRoot } from "@wrongstack/core/utils";
3776
- function registerReplClient(opts) {
3777
- const replProjectRoot = opts.projectRoot ?? process.cwd();
3778
- const projectDir = resolveProjectDir(replProjectRoot, wstackGlobalRoot());
3779
- const clientId = `repl@${crypto.randomUUID().slice(0, 8)}`;
3780
- const hqConnection = startCliHqConnection({
3781
- clientKind: "repl",
3782
- projectRoot: replProjectRoot,
3783
- projectName: path11.basename(replProjectRoot),
3784
- appConfig: opts.appConfig,
3785
- capabilities: ["telemetry.publish", "mailbox.summary"]
3786
- });
3787
- const clientMailbox = getSharedProjectMailbox(
3788
- projectDir,
3789
- void 0,
3790
- () => hqConnection.getPublisher()
3791
- );
3792
- let closed = false;
3793
- let clientHeartbeat;
3794
- clientMailbox.registerClient({
3795
- clientId,
3796
- sessionId: opts.getSessionId?.() ?? replProjectRoot,
3797
- name: `REPL [${path11.basename(replProjectRoot)}]`,
3798
- source: "repl",
3799
- pid: process.pid
3800
- }).then(() => {
3801
- if (closed) return;
3802
- clientHeartbeat = setInterval(() => {
3803
- clientMailbox.clientHeartbeat({ clientId, sessionId: opts.getSessionId?.() ?? replProjectRoot }).catch(() => {
3804
- });
3805
- }, 15e3);
3806
- }).catch(() => {
3807
- });
3808
- return {
3809
- clientId,
3810
- close() {
3811
- closed = true;
3812
- if (clientHeartbeat) clearInterval(clientHeartbeat);
3813
- clientMailbox.deregisterClient(clientId).catch(() => void 0);
3814
- hqConnection.stop();
3815
- }
3816
- };
3817
- }
3818
-
3819
3949
  // src/repl.ts
3820
- import { createAutoProceedLoopGuard } from "@wrongstack/tools/auto-proceed-loop-guard";
3821
3950
  var DEFAULT_MAX_CONSECUTIVE_AUTO_PROCEED = 50;
3822
3951
  async function runRepl(opts) {
3823
3952
  if (opts.banner !== false) printBanner(opts.renderer, opts.projectName);
@@ -3931,9 +4060,7 @@ async function runRepl(opts) {
3931
4060
  continue;
3932
4061
  }
3933
4062
  } catch (err) {
3934
- opts.renderer.writeError(
3935
- `[eternal] ${toErrorMessage(err)}`
3936
- );
4063
+ opts.renderer.writeError(`[eternal] ${toErrorMessage(err)}`);
3937
4064
  }
3938
4065
  await new Promise((resolve3) => setTimeout(resolve3, 250));
3939
4066
  continue;
@@ -4007,9 +4134,7 @@ async function runRepl(opts) {
4007
4134
  continue;
4008
4135
  }
4009
4136
  } catch (err) {
4010
- opts.renderer.writeError(
4011
- `[parallel] ${toErrorMessage(err)}`
4012
- );
4137
+ opts.renderer.writeError(`[parallel] ${toErrorMessage(err)}`);
4013
4138
  }
4014
4139
  await new Promise((resolve3) => setTimeout(resolve3, 250));
4015
4140
  continue;
@@ -4041,6 +4166,20 @@ ${lines.join("\n")}
4041
4166
  const resolved = resolveContinuation({ todos, suggestions: [] });
4042
4167
  top = resolved.source === "todo" ? resolved.text : "";
4043
4168
  groundedTodo = top !== "";
4169
+ if (resolved.source === "todo" && resolved.todoId) {
4170
+ const selected = todos.find((todo) => todo.id === resolved.todoId);
4171
+ if (selected?.status === "pending") {
4172
+ await todoTool.execute(
4173
+ {
4174
+ todos: todos.map(
4175
+ (todo) => todo.id === resolved.todoId ? { ...todo, status: "in_progress" } : todo.status === "in_progress" ? { ...todo, status: "pending" } : todo
4176
+ )
4177
+ },
4178
+ opts.agent.ctx,
4179
+ { signal: AbortSignal.timeout(3e4) }
4180
+ );
4181
+ }
4182
+ }
4044
4183
  }
4045
4184
  if (!top) {
4046
4185
  } else {
@@ -4207,10 +4346,26 @@ ${color9.dim(taskList2)}
4207
4346
  todos: opts.agent.ctx.todos,
4208
4347
  suggestions: getSuggestions()
4209
4348
  });
4349
+ if (resolved.source === "todo" && resolved.todoId) {
4350
+ const selected = opts.agent.ctx.todos.find((todo) => todo.id === resolved.todoId);
4351
+ if (selected?.status === "pending") {
4352
+ await todoTool.execute(
4353
+ {
4354
+ todos: opts.agent.ctx.todos.map(
4355
+ (todo) => todo.id === resolved.todoId ? { ...todo, status: "in_progress" } : todo.status === "in_progress" ? { ...todo, status: "pending" } : todo
4356
+ )
4357
+ },
4358
+ opts.agent.ctx,
4359
+ { signal: AbortSignal.timeout(3e4) }
4360
+ );
4361
+ }
4362
+ }
4210
4363
  if (resolved.source === "open") {
4211
4364
  opts.renderer.write(
4212
4365
  ` ${color9.amber("\u26A0")} ${color9.bold("'continue' has no anchor")} ${color9.dim("\u2014 no pending todo or suggestion.")}
4213
- ` + color9.dim(" If you proceed, I'll choose the next step from context; that can drift.\n")
4366
+ ` + color9.dim(
4367
+ " If you proceed, I'll choose the next step from context; that can drift.\n"
4368
+ )
4214
4369
  );
4215
4370
  const ans = (await opts.reader.readLine(color9.dim(" Proceed anyway? [Y/n \xB7 e = type your own] "))).trim().toLowerCase();
4216
4371
  if (ans === "n" || ans === "no") {
@@ -4487,9 +4642,7 @@ async function pasteClipboardImage(builder, opts) {
4487
4642
  opts.renderer.write(color9.dim(` \u21B3 ${placeholder} (PNG ${kb}KB)
4488
4643
  `));
4489
4644
  } catch (err) {
4490
- opts.renderer.writeError(
4491
- `Clipboard image error: ${toErrorMessage(err)}`
4492
- );
4645
+ opts.renderer.writeError(`Clipboard image error: ${toErrorMessage(err)}`);
4493
4646
  }
4494
4647
  }
4495
4648
  async function loadGoalSafe(opts) {
@@ -4525,9 +4678,7 @@ async function renderGoalBanner(opts) {
4525
4678
  try {
4526
4679
  await opts.slashRegistry.dispatch("/autonomy eternal", opts.agent.ctx);
4527
4680
  } catch (err) {
4528
- opts.renderer.writeError(
4529
- `Auto-resume failed: ${toErrorMessage(err)}`
4530
- );
4681
+ opts.renderer.writeError(`Auto-resume failed: ${toErrorMessage(err)}`);
4531
4682
  }
4532
4683
  } else {
4533
4684
  opts.renderer.write(
@@ -4897,6 +5048,8 @@ async function execute(deps) {
4897
5048
  fleetStreamController,
4898
5049
  applyLiveSettings
4899
5050
  }),
5051
+ ...createThemeAdapter({ configStore, wpaths }),
5052
+ configStore,
4900
5053
  effectiveMaxContext,
4901
5054
  titleAnimation: config.autonomy?.["terminalTitleAnimation"] ?? true,
4902
5055
  chime: config.autonomy?.["chime"] ?? false,
@@ -5100,7 +5253,7 @@ async function execute(deps) {
5100
5253
  attachments,
5101
5254
  effectiveMaxContext,
5102
5255
  getEffectiveMaxContext,
5103
- projectName: path12.basename(projectRoot) || void 0,
5256
+ projectName: path13.basename(projectRoot) || void 0,
5104
5257
  projectRoot,
5105
5258
  appConfig: config,
5106
5259
  getSessionId: () => agent.ctx.session?.id ?? session.id,
@@ -5159,4 +5312,4 @@ export {
5159
5312
  execute,
5160
5313
  resolveReviewerFallbackModels
5161
5314
  };
5162
- //# sourceMappingURL=execution-CQ772VPS.js.map
5315
+ //# sourceMappingURL=execution-MVOH6PAQ.js.map