@wrongstack/core 0.313.0 → 0.313.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/dist/chronicle/index.js +84 -6391
  2. package/dist/chronicle/project-server.js +84 -4868
  3. package/dist/chunk-2BUUIMQB.js +225 -0
  4. package/dist/chunk-2FK4WTFF.js +207 -0
  5. package/dist/chunk-2FQL4PDC.js +292 -0
  6. package/dist/chunk-2KKODIQU.js +2256 -0
  7. package/dist/chunk-2YU4WVBW.js +134 -0
  8. package/dist/chunk-3E244UDA.js +356 -0
  9. package/dist/chunk-3XPVB7BA.js +135 -0
  10. package/dist/chunk-4LJJYBAU.js +388 -0
  11. package/dist/chunk-4VWO3ZXL.js +342 -0
  12. package/dist/chunk-4XV6IR37.js +187 -0
  13. package/dist/chunk-4ZHTKJHM.js +183 -0
  14. package/dist/chunk-52RTVH4M.js +361 -0
  15. package/dist/chunk-57GEWK5X.js +26 -0
  16. package/dist/chunk-5DSMEVA4.js +931 -0
  17. package/dist/chunk-5RP3QTRL.js +1223 -0
  18. package/dist/chunk-5S437PRC.js +50 -0
  19. package/dist/chunk-5XDUGTKN.js +511 -0
  20. package/dist/chunk-62V2AFVG.js +422 -0
  21. package/dist/chunk-65RDIOR2.js +2470 -0
  22. package/dist/chunk-6AKOTGLM.js +597 -0
  23. package/dist/chunk-7ZHZE5EO.js +28 -0
  24. package/dist/chunk-A455ATZB.js +140 -0
  25. package/dist/chunk-AD7ZFZCS.js +46 -0
  26. package/dist/chunk-AI4LLQ2U.js +856 -0
  27. package/dist/chunk-ASX6AW36.js +789 -0
  28. package/dist/chunk-AT4V4XGI.js +3522 -0
  29. package/dist/chunk-AWNQ6ED6.js +311 -0
  30. package/dist/chunk-B4AMLZPB.js +9 -0
  31. package/dist/chunk-BAKVJLEV.js +417 -0
  32. package/dist/chunk-BJHVULHO.js +55 -0
  33. package/dist/chunk-CB2HFKTP.js +9 -0
  34. package/dist/chunk-CE4ZOCOI.js +1640 -0
  35. package/dist/chunk-CQQL4ZOQ.js +151 -0
  36. package/dist/chunk-DEIQMBD2.js +65 -0
  37. package/dist/chunk-E6I5RXVK.js +58 -0
  38. package/dist/chunk-EFEHDQGY.js +1589 -0
  39. package/dist/chunk-EODDVJBM.js +82 -0
  40. package/dist/chunk-EPC3GZD4.js +308 -0
  41. package/dist/chunk-FAYRX2AD.js +13 -0
  42. package/dist/chunk-FFSX2QDQ.js +362 -0
  43. package/dist/chunk-FHAMQS7Q.js +5856 -0
  44. package/dist/chunk-FIV4IJL7.js +2263 -0
  45. package/dist/chunk-FNXVT7HF.js +52 -0
  46. package/dist/chunk-FSWCWSTS.js +395 -0
  47. package/dist/chunk-FW5LDDMJ.js +16464 -0
  48. package/dist/chunk-FXQLIX3K.js +211 -0
  49. package/dist/chunk-G5AAKEEZ.js +228 -0
  50. package/dist/chunk-G5S3S5ZN.js +38 -0
  51. package/dist/chunk-GAZEWQEZ.js +231 -0
  52. package/dist/chunk-GFJOMSHG.js +125 -0
  53. package/dist/chunk-GFXZTHNI.js +158 -0
  54. package/dist/chunk-GM54GJBU.js +960 -0
  55. package/dist/chunk-GPQ3NJPR.js +900 -0
  56. package/dist/chunk-GTCU6DZ3.js +1 -0
  57. package/dist/chunk-H5E77KUJ.js +15 -0
  58. package/dist/chunk-H72H4XDU.js +1023 -0
  59. package/dist/chunk-HA4ZYA6T.js +178 -0
  60. package/dist/chunk-I45KAW2N.js +5020 -0
  61. package/dist/chunk-IQ35HMQL.js +1396 -0
  62. package/dist/chunk-IYFBFX34.js +86 -0
  63. package/dist/chunk-JJPMWPB6.js +109 -0
  64. package/dist/chunk-JTHKOYWU.js +663 -0
  65. package/dist/chunk-JVGPR3TS.js +365 -0
  66. package/dist/chunk-JVKB2TBL.js +48 -0
  67. package/dist/chunk-JX7VBZDK.js +31 -0
  68. package/dist/chunk-K3G6JBUC.js +5232 -0
  69. package/dist/chunk-K4YUNKU7.js +589 -0
  70. package/dist/chunk-KBZGE6LN.js +710 -0
  71. package/dist/chunk-KDQJCT2J.js +45 -0
  72. package/dist/chunk-KI4L2DUL.js +560 -0
  73. package/dist/chunk-KJ2ZTQSL.js +47 -0
  74. package/dist/chunk-KSJ5UTP7.js +154 -0
  75. package/dist/chunk-LHOA5DWA.js +28 -0
  76. package/dist/chunk-LX5QWLBL.js +27 -0
  77. package/dist/chunk-LZDDLNCZ.js +279 -0
  78. package/dist/chunk-M2WF6AXG.js +115 -0
  79. package/dist/chunk-M7BS2K6U.js +1 -0
  80. package/dist/chunk-NDBIPFNY.js +102 -0
  81. package/dist/chunk-NEMIWEXC.js +1199 -0
  82. package/dist/chunk-NFAYHPRH.js +323 -0
  83. package/dist/chunk-O37BQ65S.js +21 -0
  84. package/dist/chunk-O74MJHXU.js +187 -0
  85. package/dist/chunk-OJZEX73F.js +112 -0
  86. package/dist/chunk-PAAWLLZX.js +74 -0
  87. package/dist/chunk-PFXFQQRT.js +339 -0
  88. package/dist/chunk-PFZO3C6H.js +14 -0
  89. package/dist/chunk-PHH7LD45.js +113 -0
  90. package/dist/chunk-QRTG4XTI.js +188 -0
  91. package/dist/chunk-QVOVMXJR.js +1351 -0
  92. package/dist/chunk-RCQYT2I4.js +757 -0
  93. package/dist/chunk-RD6DEE36.js +1178 -0
  94. package/dist/chunk-RJIZEJ42.js +30 -0
  95. package/dist/chunk-RPOA7IAE.js +150 -0
  96. package/dist/chunk-SN2DQRL6.js +1172 -0
  97. package/dist/chunk-SQJVFEBV.js +41 -0
  98. package/dist/chunk-SQP64RCS.js +5391 -0
  99. package/dist/chunk-SVT4RNTR.js +49 -0
  100. package/dist/chunk-SWUFN7XM.js +43 -0
  101. package/dist/chunk-SXMVYC5H.js +174 -0
  102. package/dist/chunk-SZ6AYUIZ.js +23 -0
  103. package/dist/chunk-T3KGZBU5.js +3171 -0
  104. package/dist/chunk-TBRL2RCC.js +9 -0
  105. package/dist/chunk-TRT2HRWZ.js +18 -0
  106. package/dist/chunk-TYW2GI5I.js +1077 -0
  107. package/dist/chunk-UIWONWVG.js +4959 -0
  108. package/dist/chunk-VB3H5WWB.js +151 -0
  109. package/dist/chunk-W4A6QA3D.js +258 -0
  110. package/dist/chunk-WBPVKEEE.js +227 -0
  111. package/dist/chunk-WEBMSQP2.js +123 -0
  112. package/dist/chunk-WOEZV3Q4.js +333 -0
  113. package/dist/chunk-WQQON3SV.js +473 -0
  114. package/dist/chunk-WQTOVMGV.js +119 -0
  115. package/dist/chunk-WZO23AWO.js +2779 -0
  116. package/dist/chunk-XBDP4QPW.js +7 -0
  117. package/dist/chunk-XEBHSJLT.js +103 -0
  118. package/dist/chunk-XQ2ECNK3.js +1 -0
  119. package/dist/chunk-XQ2XGIBF.js +2086 -0
  120. package/dist/chunk-Y2GE5TSI.js +355 -0
  121. package/dist/chunk-YBUJCZ57.js +351 -0
  122. package/dist/chunk-YNCVSFGF.js +149 -0
  123. package/dist/chunk-YUPMXOGP.js +282 -0
  124. package/dist/chunk-YY6APYUM.js +49 -0
  125. package/dist/chunk-Z2IJUO45.js +691 -0
  126. package/dist/chunk-ZEHUCJHY.js +129 -0
  127. package/dist/chunk-ZYU2YOJ6.js +1496 -0
  128. package/dist/chunk-ZZ4V3WIZ.js +163 -0
  129. package/dist/coordination/agents/index.js +145 -6260
  130. package/dist/coordination/index.js +365 -34324
  131. package/dist/coordination/mailbox-project-server.js +48 -3276
  132. package/dist/coordination/provider-status-tracker.d.ts +4 -0
  133. package/dist/core/agent.d.ts +14 -1
  134. package/dist/core/index.js +267 -12480
  135. package/dist/core/model-ref.js +5 -23
  136. package/dist/core/provider-runner.d.ts +36 -1
  137. package/dist/design/index.js +50 -1087
  138. package/dist/execution/index.d.ts +1 -1
  139. package/dist/execution/index.js +1599 -21888
  140. package/dist/execution/prompt-enhancer.js +16 -535
  141. package/dist/execution/retry-policy.d.ts +31 -1
  142. package/dist/extension/index.js +7 -311
  143. package/dist/goal/index.js +33 -3435
  144. package/dist/hooks/index.js +14 -1138
  145. package/dist/hq/index.js +112 -5139
  146. package/dist/hq/protocol.js +21 -668
  147. package/dist/index.js +1410 -92656
  148. package/dist/infrastructure/index.js +64 -4811
  149. package/dist/kernel/events/provider-events.d.ts +15 -0
  150. package/dist/kernel/index.js +14 -992
  151. package/dist/models/index.js +40 -1117
  152. package/dist/notifications/index.js +3 -108
  153. package/dist/observability/index.js +17 -279
  154. package/dist/plugin/index.js +584 -14835
  155. package/dist/prompts/index.js +14 -948
  156. package/dist/registry/index.js +9 -822
  157. package/dist/registry-R23UBE7H.js +14 -0
  158. package/dist/replay/index.js +6 -84
  159. package/dist/review-finding-store-DKAV3AS6.js +21 -0
  160. package/dist/review-report-store-OWY3EC3N.js +19 -0
  161. package/dist/security/index.js +114 -2202
  162. package/dist/session-catalog/index.js +36 -2103
  163. package/dist/session-catalog/project-server.js +42 -1435
  164. package/dist/skills/index.js +35 -1578
  165. package/dist/storage/index.js +182 -15600
  166. package/dist/tasking/index.js +10 -676
  167. package/dist/tools/index.js +52 -9590
  168. package/dist/types/config/autonomy.d.ts +5 -0
  169. package/dist/types/config/ui.d.ts +1 -1
  170. package/dist/types/errors.d.ts +18 -0
  171. package/dist/types/index.js +121 -1342
  172. package/dist/types/provider-runner.d.ts +8 -0
  173. package/dist/types/session-markers.js +8 -144
  174. package/dist/utils/error.js +3 -4
  175. package/dist/utils/expect-defined.js +3 -9
  176. package/dist/utils/heap-watchdog.js +6 -706
  177. package/dist/utils/index.js +269 -5685
  178. package/dist/utils/sage-output-block.js +5 -42
  179. package/dist/wiring/proxy-rewrite.d.ts +18 -0
  180. package/dist/wiring/proxy-rewrite.js +18 -121
  181. package/dist/worktree/index.js +6 -887
  182. package/package.json +4 -4
@@ -0,0 +1,417 @@
1
+ import {
2
+ appendJournal,
3
+ loadGoal,
4
+ recordProgress,
5
+ saveGoal
6
+ } from "./chunk-LZDDLNCZ.js";
7
+ import {
8
+ color
9
+ } from "./chunk-4VWO3ZXL.js";
10
+
11
+ // src/storage/board-store-port.ts
12
+ var notWired = () => {
13
+ throw new Error(
14
+ "Kanban BoardStorePort is not wired \u2014 register the implementation at the CLI composition root (see setBoardStorePort)."
15
+ );
16
+ };
17
+ var port = void 0;
18
+ function setBoardStorePort(impl) {
19
+ port = impl;
20
+ }
21
+ function boardStore() {
22
+ return port ?? notWired();
23
+ }
24
+ function tryBoardStore() {
25
+ return port ?? null;
26
+ }
27
+
28
+ // src/storage/goal-kanban.ts
29
+ var GOAL_BOARD_TAG_PREFIX = "goal:";
30
+ async function createGoalKanbanBoard(projectRoot, goalFile) {
31
+ if (!projectRoot) return null;
32
+ const store = tryBoardStore();
33
+ if (!store) return null;
34
+ const existingId = goalFile.kanbanBoardId;
35
+ if (existingId) {
36
+ const existing = await store.getBoard(projectRoot, existingId).catch(() => null);
37
+ if (existing) return existingId;
38
+ }
39
+ const displayGoal = (goalFile.refinedGoal || goalFile.goal).replace(/\s+/g, " ").trim();
40
+ const titleSuffix = displayGoal.length > 80 ? displayGoal.slice(0, 77) + "\u2026" : displayGoal;
41
+ const board = await store.createBoard(projectRoot, {
42
+ title: `\u{1F3AF} ${titleSuffix}`,
43
+ description: `Kanban board auto-created for goal: ${displayGoal}`,
44
+ tags: [goalTag(goalFile)],
45
+ // Goal boards mirror an engine-driven run; the goal coordinator owns
46
+ // completion semantics, so the kanban completion gate stays out of the way.
47
+ completionGate: { enforcement: "off" }
48
+ });
49
+ const targetColumnId = board.columns[0]?.id ?? "backlog";
50
+ if (goalFile.deliverables && goalFile.deliverables.length > 0) {
51
+ for (let index = 0; index < goalFile.deliverables.length; index++) {
52
+ const d = goalFile.deliverables[index];
53
+ const cleaned = d.replace(/^\[[x✓]\]|✅|\(done\)\s*/i, "").trim();
54
+ if (cleaned) {
55
+ await store.addTask(projectRoot, board.id, {
56
+ title: cleaned,
57
+ columnId: targetColumnId,
58
+ description: `Deliverable for goal: ${displayGoal}`,
59
+ priority: "medium",
60
+ origin: {
61
+ system: "goal",
62
+ taskId: `deliverable:${index}`
63
+ }
64
+ }).catch(() => {
65
+ });
66
+ }
67
+ }
68
+ }
69
+ goalFile.kanbanBoardId = board.id;
70
+ return board.id;
71
+ }
72
+ async function findGoalKanbanBoard(projectRoot, boardId) {
73
+ if (!projectRoot || !boardId) return null;
74
+ try {
75
+ return await boardStore().getBoard(projectRoot, boardId);
76
+ } catch {
77
+ return null;
78
+ }
79
+ }
80
+ async function deleteGoalKanbanBoard(projectRoot, boardId) {
81
+ if (!projectRoot || !boardId) return;
82
+ const store = tryBoardStore();
83
+ if (!store) return;
84
+ await store.removeBoard(projectRoot, boardId).catch(() => {
85
+ });
86
+ }
87
+ async function findGoalBoardByTag(projectRoot, goalFile) {
88
+ if (!projectRoot) return null;
89
+ const store = tryBoardStore();
90
+ if (!store) return null;
91
+ const tag = goalTag(goalFile);
92
+ const boards = await store.listBoards(projectRoot);
93
+ const matched = boards.find((b) => b.tags?.includes(tag));
94
+ if (!matched) return null;
95
+ return store.getBoard(projectRoot, matched.id).catch(() => null);
96
+ }
97
+ function formatGoalKanbanPreview(goalFile, boardId, taskCount) {
98
+ const lines = [];
99
+ const displayGoal = (goalFile.refinedGoal || goalFile.goal).replace(/\s+/g, " ").trim();
100
+ lines.push("");
101
+ lines.push(color.bold(color.cyan("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")));
102
+ lines.push(color.bold(color.cyan(" \u{1F3AF} GOAL KANBAN \u2014 Mission Board")));
103
+ lines.push(color.bold(color.cyan("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")));
104
+ lines.push("");
105
+ lines.push(` ${color.bold("Mission:")} ${color.bold(displayGoal)}`);
106
+ if (boardId) {
107
+ lines.push(` ${color.dim(`Board: ${boardId.slice(0, 12)}\u2026`)}`);
108
+ }
109
+ if (typeof taskCount === "number") {
110
+ lines.push(` ${color.dim(`${taskCount} task(s)`)}`);
111
+ }
112
+ lines.push("");
113
+ const deliverables = goalFile.deliverables ?? [];
114
+ const doneDeliverables = deliverables.filter((d) => /^\[[x✓]\]|✅|\(done\)/i.test(d)).length;
115
+ const totalDeliverables = deliverables.length;
116
+ if (totalDeliverables > 0) {
117
+ const backlog = deliverables.filter((d) => !/^\[[x✓]\]|✅|\(done\)|🔄|in.progress/i.test(d));
118
+ const inProgress = deliverables.filter((d) => /🔄|in.progress/i.test(d));
119
+ const done = deliverables.filter((d) => /^\[[x✓]\]|✅|\(done\)/i.test(d));
120
+ const renderColumn = (title, items, icon, accent) => {
121
+ if (items.length === 0) {
122
+ lines.push(` ${accent(color.bold(`${icon} ${title}`))} ${color.dim("(empty)")}`);
123
+ return;
124
+ }
125
+ lines.push(` ${accent(color.bold(`${icon} ${title} (${items.length})`))}`);
126
+ for (const item of items) {
127
+ const cleaned = item.replace(/^\[[x✓]\]|✅|\(done\)|🔄|in.progress\s*/gi, "").trim();
128
+ lines.push(` \u25CB ${cleaned}`);
129
+ }
130
+ };
131
+ renderColumn("Backlog", backlog, "\u{1F4CB}", (s) => color.dim(s));
132
+ renderColumn("In Progress", inProgress, "\u{1F504}", (s) => color.cyan(s));
133
+ renderColumn("Done", done, "\u2705", (s) => color.green(s));
134
+ lines.push("");
135
+ lines.push(
136
+ ` ${color.dim(`Progress: ${doneDeliverables}/${totalDeliverables} deliverables complete`)}`
137
+ );
138
+ }
139
+ if (typeof goalFile.progress === "number") {
140
+ const pct = Math.min(100, Math.max(0, Math.round(goalFile.progress)));
141
+ const filled = Math.round(pct / 5);
142
+ const empty = 20 - filled;
143
+ const bar = color.green("\u2588".repeat(filled)) + color.dim("\u2591".repeat(empty));
144
+ lines.push(` ${color.dim("Overall:")} ${bar} ${color.bold(`${pct}%`)}`);
145
+ if (goalFile.progressNote) {
146
+ lines.push(` ${color.dim(goalFile.progressNote)}`);
147
+ }
148
+ }
149
+ if (typeof goalFile.progress === "undefined" && totalDeliverables > 0) {
150
+ const pct = Math.round(doneDeliverables / totalDeliverables * 100);
151
+ const filled = Math.round(pct / 5);
152
+ const empty = 20 - filled;
153
+ const bar = (pct > 0 ? color.green("\u2588".repeat(filled)) : "") + color.dim("\u2591".repeat(empty));
154
+ lines.push(` ${color.dim("Overall:")} ${bar} ${color.bold(`${pct}%`)}`);
155
+ }
156
+ lines.push("");
157
+ lines.push(color.bold(color.cyan("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")));
158
+ return lines.join("\n");
159
+ }
160
+ function formatGoalEvent(goalFile, boardId) {
161
+ const lines = [];
162
+ lines.push("");
163
+ lines.push(color.bold(color.green("\u250C\u2500\u2500\u2500 Goal Event \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510")));
164
+ lines.push(color.bold(color.green("\u2502")) + " \u{1F3AF} Mission locked and ready");
165
+ if (boardId) {
166
+ lines.push(
167
+ color.bold(color.green("\u2502")) + ` \u{1F4CB} Kanban board created: ${color.cyan(boardId.slice(0, 12) + "\u2026")}`
168
+ );
169
+ }
170
+ const deliverables = goalFile.deliverables ?? [];
171
+ lines.push(
172
+ color.bold(color.green("\u2502")) + ` \u{1F4E6} ${deliverables.length} deliverable${deliverables.length !== 1 ? "s" : ""} extracted`
173
+ );
174
+ if (typeof goalFile.progress === "number") {
175
+ lines.push(color.bold(color.green("\u2502")) + ` \u{1F4CA} Progress: ${goalFile.progress}%`);
176
+ }
177
+ lines.push(color.bold(color.green("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518")));
178
+ return lines.join("\n");
179
+ }
180
+ function formatGoalAutonomyChoice() {
181
+ const lines = [];
182
+ lines.push("");
183
+ lines.push(color.bold(color.magenta("\u2550\u2550\u2550 Choose Autonomy Mode \u2550\u2550\u2550")));
184
+ lines.push("");
185
+ lines.push(
186
+ ` ${color.bold("1")}. ${color.red("Autonomy Eternal")} ${color.dim("\u2014 Single-agent sense/decide/execute/reflect loop")}`
187
+ );
188
+ lines.push(
189
+ ` ${color.bold("2")}. ${color.magenta("Eternal Parallel")} ${color.dim("\u2014 Multi-agent fan-out (4-8 subagents per tick)")}`
190
+ );
191
+ lines.push("");
192
+ lines.push(` ${color.dim("Enter 1 or 2 (or press Enter to skip):")}`);
193
+ return lines.join("\n");
194
+ }
195
+ function parseAutonomyChoice(input) {
196
+ const trimmed = input.trim().toLowerCase();
197
+ if (trimmed === "1" || trimmed === "eternal" || trimmed === "e") return "eternal";
198
+ if (trimmed === "2" || trimmed === "parallel" || trimmed === "p") return "eternal-parallel";
199
+ if (trimmed === "" || trimmed === "skip" || trimmed === "s" || trimmed === "0") return null;
200
+ return null;
201
+ }
202
+ function goalTag(goalFile) {
203
+ const goal = (goalFile.refinedGoal || goalFile.goal).replace(/\s+/g, "-").slice(0, 24).toLowerCase();
204
+ return `${GOAL_BOARD_TAG_PREFIX}${goal}`;
205
+ }
206
+
207
+ // src/storage/goal-coordination.ts
208
+ var DONE_MARKER = /\[done:\s*([^\]]+)\]/gi;
209
+ var DONE_PREFIX = /^\s*(?:✅|\[[x✓]\]|\(done\))\s*/i;
210
+ function parseCompletedGoalDeliverables(finalText, deliverables) {
211
+ if (!finalText || deliverables.length === 0) return [];
212
+ const seen = /* @__PURE__ */ new Set();
213
+ const completed = [];
214
+ for (const match of finalText.matchAll(DONE_MARKER)) {
215
+ const raw = match[1]?.trim();
216
+ if (!raw) continue;
217
+ const numeric = /^\d+$/.test(raw) ? Number.parseInt(raw, 10) : void 0;
218
+ let index = numeric === void 0 ? -1 : numeric === 0 ? 0 : numeric - 1;
219
+ if (index < 0 || index >= deliverables.length) {
220
+ const prefix = raw.toLowerCase();
221
+ index = deliverables.findIndex(
222
+ (item) => stripGoalDeliverableMarker(item).toLowerCase().startsWith(prefix)
223
+ );
224
+ }
225
+ if (index < 0 || index >= deliverables.length || seen.has(index)) continue;
226
+ const source = deliverables[index] ?? "";
227
+ if (isGoalDeliverableComplete(source)) continue;
228
+ seen.add(index);
229
+ completed.push({ index, text: stripGoalDeliverableMarker(source) });
230
+ }
231
+ return completed;
232
+ }
233
+ function isGoalDeliverableComplete(value) {
234
+ return DONE_PREFIX.test(value);
235
+ }
236
+ function stripGoalDeliverableMarker(value) {
237
+ return value.replace(DONE_PREFIX, "").trim();
238
+ }
239
+ function applyGoalDeliverableCompletions(goal, completed) {
240
+ if (completed.length === 0) return recomputeGoalProgress(goal);
241
+ const completedIndices = new Set(completed.map((item) => item.index));
242
+ let next = {
243
+ ...goal,
244
+ deliverables: (goal.deliverables ?? []).map(
245
+ (item, index) => completedIndices.has(index) && !isGoalDeliverableComplete(item) ? `\u2705 ${item}` : item
246
+ )
247
+ };
248
+ next = appendGoalDeliverableJournals(next, completed);
249
+ return recomputeGoalProgress(next);
250
+ }
251
+ function appendGoalDeliverableJournals(goal, completed) {
252
+ let next = goal;
253
+ for (const item of completed) {
254
+ next = appendJournal(next, {
255
+ source: "deliverable",
256
+ task: `Deliverable completed: ${item.text}`.slice(0, 240),
257
+ status: "success",
258
+ note: `[DONE: ${item.index + 1}]`
259
+ });
260
+ }
261
+ return next;
262
+ }
263
+ function recomputeGoalProgress(goal) {
264
+ const deliverables = goal.deliverables ?? [];
265
+ if (deliverables.length === 0) return goal;
266
+ const done = deliverables.filter(isGoalDeliverableComplete).length;
267
+ const progress = Math.round(done / deliverables.length * 100);
268
+ return recordProgress(goal, progress, `${done}/${deliverables.length} deliverables complete`);
269
+ }
270
+ async function coordinateGoalIteration(options) {
271
+ const current = await loadGoal(options.goalPath, options.events);
272
+ if (!current) return null;
273
+ const completed = parseCompletedGoalDeliverables(options.finalText, current.deliverables ?? []);
274
+ const board = await resolveGoalBoard(options.projectRoot, current);
275
+ let kanbanUpdatedTaskIds = [];
276
+ let goal;
277
+ if (board) {
278
+ kanbanUpdatedTaskIds = await refreshGoalKanban(options.projectRoot, current, completed, board);
279
+ goal = await recomputeGoalProgressFromKanban(options.projectRoot, current);
280
+ const confirmed = completed.filter(
281
+ (item) => !isGoalDeliverableComplete(current.deliverables?.[item.index] ?? "") && isGoalDeliverableComplete(goal.deliverables?.[item.index] ?? "")
282
+ );
283
+ goal = appendGoalDeliverableJournals(goal, confirmed);
284
+ } else {
285
+ goal = applyGoalDeliverableCompletions(current, completed);
286
+ }
287
+ let reached = false;
288
+ const allComplete = (goal.deliverables?.length ?? 0) > 0 && goal.deliverables?.every(isGoalDeliverableComplete) === true;
289
+ if (allComplete && options.brain) {
290
+ const decision = await options.brain.decide({
291
+ id: `goal-reached-${goal.iterations}`,
292
+ sessionId: options.sessionId,
293
+ source: "system",
294
+ question: "Have all goal deliverables been reached and verified?",
295
+ context: [
296
+ `Goal: ${goal.refinedGoal ?? goal.goal}`,
297
+ `Progress: ${goal.progress ?? 0}%`,
298
+ "Completed deliverables:",
299
+ ...(goal.deliverables ?? []).map(
300
+ (item, index) => `${index + 1}. ${stripGoalDeliverableMarker(item)}`
301
+ )
302
+ ].join("\n"),
303
+ risk: "high",
304
+ fallback: "continue",
305
+ options: [
306
+ {
307
+ id: "goal_reached",
308
+ label: "Goal reached",
309
+ consequence: "Persist the completed goal and stop the eternal loop."
310
+ },
311
+ {
312
+ id: "keep_working",
313
+ label: "Keep working",
314
+ consequence: "Leave the goal active for another iteration."
315
+ }
316
+ ]
317
+ });
318
+ reached = decision.type === "answer" && decision.optionId === "goal_reached";
319
+ }
320
+ if (reached) {
321
+ const reachedAt = (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString();
322
+ goal = appendJournal(
323
+ {
324
+ ...goal,
325
+ goalState: "completed",
326
+ engineState: "stopped",
327
+ progress: 100,
328
+ progressNote: "goal reached",
329
+ reachedAt,
330
+ reachedNote: "goal reached"
331
+ },
332
+ {
333
+ source: "deliverable",
334
+ task: "GOAL REACHED",
335
+ status: "success",
336
+ note: "goal reached"
337
+ }
338
+ );
339
+ }
340
+ await saveGoal(options.goalPath, goal, options.events);
341
+ return { goal, completed, kanbanUpdatedTaskIds, reached };
342
+ }
343
+ async function resolveGoalBoard(projectRoot, goal) {
344
+ const boardId = goal.kanbanBoardId;
345
+ if (boardId) {
346
+ const board = await findGoalKanbanBoard(projectRoot, boardId);
347
+ if (board) return board;
348
+ }
349
+ return findGoalBoardByTag(projectRoot, goal);
350
+ }
351
+ async function refreshGoalKanban(projectRoot, goal, completed, resolvedBoard) {
352
+ if (completed.length === 0) return [];
353
+ const board = resolvedBoard ?? await resolveGoalBoard(projectRoot, goal);
354
+ if (!board) return [];
355
+ const doneColumn = board.columns.find((column) => column.title.toLowerCase() === "done");
356
+ if (!doneColumn) return [];
357
+ const originKeys = new Set(completed.map((item) => `deliverable:${item.index}`));
358
+ const completedTitles = new Set(completed.map((item) => normalizeTitle(item.text)));
359
+ const updated = [];
360
+ for (const task of board.tasks) {
361
+ const originMatch = task.origin?.system === "goal" && task.origin?.taskId ? originKeys.has(task.origin.taskId) : false;
362
+ const titleMatch = !task.origin?.taskId && completedTitles.has(normalizeTitle(task.title));
363
+ if (!originMatch && !titleMatch) continue;
364
+ const result = await boardStore().updateTask(
365
+ projectRoot,
366
+ board.id,
367
+ task.id,
368
+ { columnId: doneColumn.id, status: "completed" },
369
+ {
370
+ actor: "goal-coordinator",
371
+ note: originMatch ? `deliverable-completed: Matched by origin ${task.origin.taskId}.` : "deliverable-completed: Updated from [DONE:] marker (title fallback)."
372
+ }
373
+ );
374
+ if (result) updated.push(task.id);
375
+ }
376
+ return updated;
377
+ }
378
+ async function recomputeGoalProgressFromKanban(projectRoot, goal) {
379
+ const board = await resolveGoalBoard(projectRoot, goal);
380
+ if (!board || !goal.deliverables?.length) return recomputeGoalProgress(goal);
381
+ const tasksByOrigin = new Map(
382
+ board.tasks.filter((task) => task.origin?.system === "goal" && task.origin.taskId).map((task) => [task.origin.taskId, task])
383
+ );
384
+ const completedLegacyTitles = new Set(
385
+ board.tasks.filter((task) => !task.origin?.taskId && task.status === "completed").map((task) => normalizeTitle(task.title))
386
+ );
387
+ const deliverables = goal.deliverables.map((item, index) => {
388
+ const text = stripGoalDeliverableMarker(item);
389
+ const originTask = tasksByOrigin.get(`deliverable:${index}`);
390
+ const complete = originTask ? originTask.status === "completed" : completedLegacyTitles.has(normalizeTitle(text)) || isGoalDeliverableComplete(item);
391
+ return complete ? `\u2705 ${text}` : text;
392
+ });
393
+ return recomputeGoalProgress({ ...goal, deliverables });
394
+ }
395
+ function normalizeTitle(value) {
396
+ return stripGoalDeliverableMarker(value).replace(/\s+/g, " ").trim().toLowerCase();
397
+ }
398
+
399
+ export {
400
+ setBoardStorePort,
401
+ boardStore,
402
+ createGoalKanbanBoard,
403
+ findGoalKanbanBoard,
404
+ deleteGoalKanbanBoard,
405
+ findGoalBoardByTag,
406
+ formatGoalKanbanPreview,
407
+ formatGoalEvent,
408
+ formatGoalAutonomyChoice,
409
+ parseAutonomyChoice,
410
+ parseCompletedGoalDeliverables,
411
+ isGoalDeliverableComplete,
412
+ stripGoalDeliverableMarker,
413
+ applyGoalDeliverableCompletions,
414
+ recomputeGoalProgress,
415
+ coordinateGoalIteration
416
+ };
417
+ //# sourceMappingURL=chunk-BAKVJLEV.js.map
@@ -0,0 +1,55 @@
1
+ import {
2
+ hashRequest
3
+ } from "./chunk-SWUFN7XM.js";
4
+
5
+ // src/replay/replay-provider-runner.ts
6
+ var ReplayProviderRunner = class {
7
+ constructor(inner, opts) {
8
+ this.inner = inner;
9
+ this.opts = opts;
10
+ }
11
+ inner;
12
+ opts;
13
+ /** Resolve the target session for this call. See {@link ReplayProviderRunnerOptions.sessionId}. */
14
+ resolveSessionId() {
15
+ const { sessionId } = this.opts;
16
+ return typeof sessionId === "function" ? sessionId() : sessionId;
17
+ }
18
+ async run(runOpts) {
19
+ const hash = hashRequest(runOpts.request);
20
+ const sessionId = this.resolveSessionId();
21
+ const cached = await this.opts.log.lookup(sessionId, hash);
22
+ if (this.opts.mode === "replay") {
23
+ if (!cached) {
24
+ this.opts.logger?.warn?.(
25
+ `replay: no recorded response for hash ${hash} (model ${runOpts.request.model})`
26
+ );
27
+ throw new Error(
28
+ `ReplayProviderRunner: no recorded response for hash ${hash} in session ${sessionId}. Either the request changed since recording, or this session has no replay log.`
29
+ );
30
+ }
31
+ this.opts.logger?.debug?.(
32
+ `replay: served cached response for hash ${hash} (recorded ${cached.ts})`
33
+ );
34
+ return cached.response;
35
+ }
36
+ if (this.opts.mode === "auto" && cached) {
37
+ this.opts.logger?.debug?.(
38
+ `replay: auto-hit hash ${hash}, served cached response`
39
+ );
40
+ return cached.response;
41
+ }
42
+ const response = await this.inner.run(runOpts);
43
+ await this.opts.log.record({
44
+ sessionId,
45
+ request: runOpts.request,
46
+ response
47
+ });
48
+ return response;
49
+ }
50
+ };
51
+
52
+ export {
53
+ ReplayProviderRunner
54
+ };
55
+ //# sourceMappingURL=chunk-BJHVULHO.js.map
@@ -0,0 +1,9 @@
1
+ // src/types/system-prompt.ts
2
+ function flattenSystemPromptRegions(regions) {
3
+ return [...regions.core, ...regions.session, ...regions.volatile];
4
+ }
5
+
6
+ export {
7
+ flattenSystemPromptRegions
8
+ };
9
+ //# sourceMappingURL=chunk-CB2HFKTP.js.map