@wrongstack/core 0.313.0 → 0.316.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 (343) hide show
  1. package/dist/chronicle/index.js +84 -6391
  2. package/dist/chronicle/legacy-journal-import.d.ts +0 -6
  3. package/dist/chronicle/metrics-ingest.d.ts +14 -0
  4. package/dist/chronicle/metrics-schema.d.ts +10 -1
  5. package/dist/chronicle/metrics-store.d.ts +20 -2
  6. package/dist/chronicle/project-server.js +98 -4874
  7. package/dist/chronicle/sink.d.ts +13 -0
  8. package/dist/chronicle/sqlite-journal.d.ts +20 -2
  9. package/dist/chunk-25LSLC3G.js +334 -0
  10. package/dist/chunk-27QIURLN.js +1073 -0
  11. package/dist/chunk-2FK4WTFF.js +207 -0
  12. package/dist/chunk-2YU4WVBW.js +134 -0
  13. package/dist/chunk-3AGWVSS7.js +4608 -0
  14. package/dist/chunk-3BDV7RL3.js +211 -0
  15. package/dist/chunk-3ECENVHL.js +325 -0
  16. package/dist/chunk-3XPVB7BA.js +135 -0
  17. package/dist/chunk-45WI72ZB.js +16884 -0
  18. package/dist/chunk-4BMVPOHO.js +3748 -0
  19. package/dist/chunk-4I7HGVVA.js +363 -0
  20. package/dist/chunk-4LCZVJVF.js +317 -0
  21. package/dist/chunk-4SJNS7OB.js +217 -0
  22. package/dist/chunk-4VWO3ZXL.js +342 -0
  23. package/dist/chunk-57GEWK5X.js +26 -0
  24. package/dist/chunk-5BMIE7QG.js +46 -0
  25. package/dist/chunk-5S437PRC.js +50 -0
  26. package/dist/chunk-5XDUGTKN.js +511 -0
  27. package/dist/chunk-5YPSXQXM.js +1443 -0
  28. package/dist/chunk-6FHWXLPT.js +10 -0
  29. package/dist/chunk-6H5GEOET.js +2406 -0
  30. package/dist/chunk-6NWEVFEL.js +151 -0
  31. package/dist/chunk-AYW5YINX.js +58 -0
  32. package/dist/chunk-B4AMLZPB.js +9 -0
  33. package/dist/chunk-B7F4WVP4.js +65 -0
  34. package/dist/chunk-BJHVULHO.js +55 -0
  35. package/dist/chunk-BPBKKBUK.js +2085 -0
  36. package/dist/chunk-BYD345OX.js +589 -0
  37. package/dist/chunk-C27KDLOX.js +279 -0
  38. package/dist/chunk-CU546ESW.js +597 -0
  39. package/dist/chunk-DLHHXUAM.js +172 -0
  40. package/dist/chunk-DOTHQSJ2.js +429 -0
  41. package/dist/chunk-DYLPMV4Q.js +711 -0
  42. package/dist/chunk-EODDVJBM.js +82 -0
  43. package/dist/chunk-F3JWNST7.js +361 -0
  44. package/dist/chunk-FC2ZGRF3.js +140 -0
  45. package/dist/chunk-FCBTO76Z.js +5786 -0
  46. package/dist/chunk-FHZVFYSL.js +396 -0
  47. package/dist/chunk-FNXVT7HF.js +52 -0
  48. package/dist/chunk-FWNLEZYG.js +259 -0
  49. package/dist/chunk-FXQLIX3K.js +211 -0
  50. package/dist/chunk-G5S3S5ZN.js +38 -0
  51. package/dist/chunk-GDQ7CZRQ.js +116 -0
  52. package/dist/chunk-GJJGJB2R.js +1374 -0
  53. package/dist/chunk-GTCU6DZ3.js +1 -0
  54. package/dist/chunk-HA4ZYA6T.js +178 -0
  55. package/dist/chunk-HI3JGZR2.js +188 -0
  56. package/dist/chunk-HMLIGAU7.js +395 -0
  57. package/dist/chunk-HXKZ7OBQ.js +303 -0
  58. package/dist/chunk-I7DALG7J.js +292 -0
  59. package/dist/chunk-IRUTEHCE.js +960 -0
  60. package/dist/chunk-IYFBFX34.js +86 -0
  61. package/dist/chunk-J2WRWR37.js +1104 -0
  62. package/dist/chunk-JFPJ6LLQ.js +129 -0
  63. package/dist/chunk-JMULFFLN.js +9 -0
  64. package/dist/chunk-JO4MGB6Z.js +1264 -0
  65. package/dist/chunk-JVKB2TBL.js +48 -0
  66. package/dist/chunk-JX7VBZDK.js +31 -0
  67. package/dist/chunk-K6BXGITA.js +931 -0
  68. package/dist/chunk-KDQJCT2J.js +45 -0
  69. package/dist/chunk-KJ2ZTQSL.js +47 -0
  70. package/dist/chunk-KZMSZV32.js +187 -0
  71. package/dist/chunk-LA7CLDRW.js +129 -0
  72. package/dist/chunk-LHOA5DWA.js +28 -0
  73. package/dist/chunk-LSMMOS2Z.js +119 -0
  74. package/dist/chunk-LX5QWLBL.js +27 -0
  75. package/dist/chunk-LXWCMQNJ.js +789 -0
  76. package/dist/chunk-M27LIEKV.js +2829 -0
  77. package/dist/chunk-MJPHJRAL.js +663 -0
  78. package/dist/chunk-MTL4O5YR.js +228 -0
  79. package/dist/chunk-NDBIPFNY.js +102 -0
  80. package/dist/chunk-NEMIWEXC.js +1199 -0
  81. package/dist/chunk-NHJ75HXY.js +1 -0
  82. package/dist/chunk-NIOAGFPB.js +1510 -0
  83. package/dist/chunk-NS52ISWS.js +355 -0
  84. package/dist/chunk-NSOFPKGT.js +5352 -0
  85. package/dist/chunk-NVIZG63R.js +757 -0
  86. package/dist/chunk-O37BQ65S.js +21 -0
  87. package/dist/chunk-OOYZPOXM.js +308 -0
  88. package/dist/chunk-OSGLYW5J.js +28 -0
  89. package/dist/chunk-PFCMSSUF.js +1640 -0
  90. package/dist/chunk-PFZO3C6H.js +14 -0
  91. package/dist/chunk-PGRVXIMY.js +158 -0
  92. package/dist/chunk-PHH7LD45.js +113 -0
  93. package/dist/chunk-PISBFBJN.js +109 -0
  94. package/dist/chunk-POOOIWE5.js +9 -0
  95. package/dist/chunk-PQNS3U7Z.js +1240 -0
  96. package/dist/chunk-QSTSJOCK.js +402 -0
  97. package/dist/chunk-RFQMOKWK.js +282 -0
  98. package/dist/chunk-RJIZEJ42.js +30 -0
  99. package/dist/chunk-RTOTNK3P.js +484 -0
  100. package/dist/chunk-RXKSDUAU.js +1172 -0
  101. package/dist/chunk-S45JPKQN.js +3317 -0
  102. package/dist/chunk-SAFHACFA.js +152 -0
  103. package/dist/chunk-SQJVFEBV.js +41 -0
  104. package/dist/chunk-SVT4RNTR.js +49 -0
  105. package/dist/chunk-SWUFN7XM.js +43 -0
  106. package/dist/chunk-SXMVYC5H.js +174 -0
  107. package/dist/chunk-SZ6AYUIZ.js +23 -0
  108. package/dist/chunk-TBRL2RCC.js +9 -0
  109. package/dist/chunk-TCCHINEF.js +655 -0
  110. package/dist/chunk-THEGTRAG.js +316 -0
  111. package/dist/chunk-TR4LQE7L.js +2256 -0
  112. package/dist/chunk-TRT2HRWZ.js +18 -0
  113. package/dist/chunk-TWJMGXCI.js +900 -0
  114. package/dist/chunk-U45AXT5D.js +1023 -0
  115. package/dist/chunk-U4FWBSO3.js +509 -0
  116. package/dist/chunk-UBGDX6FI.js +147 -0
  117. package/dist/chunk-UJILKYES.js +75 -0
  118. package/dist/chunk-ULMAQV3T.js +234 -0
  119. package/dist/chunk-VVBP6KGT.js +9 -0
  120. package/dist/chunk-W5VITDM2.js +168 -0
  121. package/dist/chunk-WAHQVNWT.js +194 -0
  122. package/dist/chunk-WBPVKEEE.js +227 -0
  123. package/dist/chunk-WGGYRBXH.js +5434 -0
  124. package/dist/chunk-WLYKU45P.js +5770 -0
  125. package/dist/chunk-WP7BVANJ.js +53 -0
  126. package/dist/chunk-WQQON3SV.js +473 -0
  127. package/dist/chunk-WQTOVMGV.js +119 -0
  128. package/dist/chunk-XBDP4QPW.js +7 -0
  129. package/dist/chunk-XEBHSJLT.js +103 -0
  130. package/dist/chunk-XF4VUMKW.js +231 -0
  131. package/dist/chunk-XQ2ECNK3.js +1 -0
  132. package/dist/chunk-Y5YXDM7D.js +74 -0
  133. package/dist/chunk-YOPAUVU4.js +2588 -0
  134. package/dist/chunk-YPT4A46F.js +362 -0
  135. package/dist/chunk-YWXT3JNM.js +425 -0
  136. package/dist/chunk-YY6APYUM.js +49 -0
  137. package/dist/chunk-Z2IJUO45.js +691 -0
  138. package/dist/chunk-ZHZ2Y2DH.js +1643 -0
  139. package/dist/chunk-ZT7JNIGX.js +152 -0
  140. package/dist/coordination/agent-monitor.d.ts +9 -1
  141. package/dist/coordination/agent-subagent-runner.d.ts +1 -1
  142. package/dist/coordination/agents/agent-prompts.d.ts +8 -0
  143. package/dist/coordination/agents/index.d.ts +33 -1
  144. package/dist/coordination/agents/index.js +184 -6269
  145. package/dist/coordination/agents/phase3-wave1-platform.d.ts +1 -3
  146. package/dist/coordination/agents/phase3-wave2-meta.d.ts +1 -3
  147. package/dist/coordination/agents/phase8-wave3-products.d.ts +1 -3
  148. package/dist/coordination/agents/phase9-wave4-platform-meta.d.ts +1 -3
  149. package/dist/coordination/agents/project-agent-identity.d.ts +11 -11
  150. package/dist/coordination/agents/types.d.ts +13 -2
  151. package/dist/coordination/brain-monitor.d.ts +30 -7
  152. package/dist/coordination/collab-debug.d.ts +1 -1
  153. package/dist/coordination/collab-pause.d.ts +1 -1
  154. package/dist/coordination/delegate-tool.d.ts +7 -5
  155. package/dist/coordination/director-kanban-queue-helpers.d.ts +1 -0
  156. package/dist/coordination/director-options.d.ts +7 -0
  157. package/dist/coordination/director-spawn-model.d.ts +17 -0
  158. package/dist/coordination/director-tools.d.ts +2 -2
  159. package/dist/coordination/director.d.ts +12 -0
  160. package/dist/coordination/dispatcher.d.ts +8 -0
  161. package/dist/coordination/fleet-bus.d.ts +35 -4
  162. package/dist/coordination/fleet-supervisor.d.ts +10 -2
  163. package/dist/coordination/fleet.d.ts +16 -7
  164. package/dist/coordination/index.d.ts +4 -0
  165. package/dist/coordination/index.js +402 -34324
  166. package/dist/coordination/kanban-dispatch-port.d.ts +2 -2
  167. package/dist/coordination/mailbox-http-router.d.ts +4 -3
  168. package/dist/coordination/mailbox-http-validation.d.ts +1 -1
  169. package/dist/coordination/mailbox-project-server.js +48 -3276
  170. package/dist/coordination/mailbox-types.d.ts +24 -6
  171. package/dist/coordination/model-tier-leader.d.ts +122 -0
  172. package/dist/coordination/model-tier.d.ts +122 -0
  173. package/dist/coordination/multi-agent-coordinator.d.ts +24 -0
  174. package/dist/coordination/origin-session.d.ts +16 -0
  175. package/dist/coordination/provider-status-tracker.d.ts +41 -5
  176. package/dist/coordination/session-note-hub.d.ts +44 -0
  177. package/dist/coordination/session-note-tool.d.ts +10 -0
  178. package/dist/core/agent.d.ts +15 -2
  179. package/dist/core/context.d.ts +22 -3
  180. package/dist/core/index.d.ts +2 -0
  181. package/dist/core/index.js +239 -12360
  182. package/dist/core/model-ref.js +5 -23
  183. package/dist/core/provider-runner.d.ts +36 -1
  184. package/dist/core/request-conversation-binding.d.ts +37 -0
  185. package/dist/core/session-notes.d.ts +25 -0
  186. package/dist/core/system-prompt-builder.d.ts +11 -2
  187. package/dist/core/system-prompt-variants.d.ts +78 -0
  188. package/dist/design/index.js +50 -1087
  189. package/dist/execution/auto-compaction-middleware.d.ts +11 -0
  190. package/dist/execution/autonomy-brain.d.ts +2 -1
  191. package/dist/execution/autonomy-prompt-contributor.d.ts +7 -2
  192. package/dist/execution/compaction-core.d.ts +4 -4
  193. package/dist/execution/eternal-autonomy.d.ts +1 -1
  194. package/dist/execution/index.d.ts +1 -1
  195. package/dist/execution/index.js +1615 -21895
  196. package/dist/execution/model-runtime.d.ts +0 -7
  197. package/dist/execution/parallel-eternal-engine.d.ts +7 -7
  198. package/dist/execution/prompt-enhancer.js +16 -535
  199. package/dist/execution/retry-policy.d.ts +31 -1
  200. package/dist/extension/index.js +7 -311
  201. package/dist/goal/index.js +33 -3435
  202. package/dist/hooks/index.js +14 -1138
  203. package/dist/hq/index.js +114 -5139
  204. package/dist/hq/persistence/event-log.d.ts +0 -1
  205. package/dist/hq/persistence.d.ts +4 -4
  206. package/dist/hq/protocol.js +21 -668
  207. package/dist/hq/publisher.d.ts +2 -0
  208. package/dist/index.d.ts +14 -11
  209. package/dist/index.js +1502 -92655
  210. package/dist/infrastructure/index.d.ts +4 -4
  211. package/dist/infrastructure/index.js +504 -5230
  212. package/dist/infrastructure/token-counter.d.ts +9 -0
  213. package/dist/kernel/events/agent-events.d.ts +77 -3
  214. package/dist/kernel/events/brain-events.d.ts +12 -0
  215. package/dist/kernel/events/provider-events.d.ts +22 -1
  216. package/dist/kernel/events/session-events.d.ts +14 -0
  217. package/dist/kernel/events/tool-events.d.ts +13 -0
  218. package/dist/kernel/index.js +14 -992
  219. package/dist/mailbox-attach.d.ts +1 -1
  220. package/dist/models/index.js +41 -1117
  221. package/dist/notifications/index.js +3 -108
  222. package/dist/observability/event-bridge.d.ts +25 -5
  223. package/dist/observability/index.d.ts +9 -8
  224. package/dist/observability/index.js +477 -631
  225. package/dist/observability/tool-usage-source.d.ts +65 -0
  226. package/dist/plugin/index.d.ts +5 -0
  227. package/dist/plugin/index.js +600 -14835
  228. package/dist/plugins/auto-review-plugin.d.ts +3 -2
  229. package/dist/plugins/review-finding-commands.d.ts +0 -8
  230. package/dist/plugins/review-finding-store.js +22 -0
  231. package/dist/plugins/review-finding-types.js +19 -0
  232. package/dist/plugins/review-report-integration.js +21 -0
  233. package/dist/plugins/review-report-store.js +20 -0
  234. package/dist/plugins/review-report-types.js +13 -0
  235. package/dist/prompts/index.js +14 -948
  236. package/dist/registry/index.js +9 -822
  237. package/dist/registry/tool-registry.d.ts +59 -9
  238. package/dist/registry-7N4O3E7W.js +14 -0
  239. package/dist/replay/index.js +6 -84
  240. package/dist/security/capabilities.d.ts +6 -0
  241. package/dist/security/file-permissions.d.ts +1 -1
  242. package/dist/security/index.js +161 -2235
  243. package/dist/security/permission-policy.d.ts +12 -1
  244. package/dist/security/secret-scrubber.d.ts +15 -0
  245. package/dist/session-catalog/index.d.ts +1 -0
  246. package/dist/session-catalog/index.js +41 -2103
  247. package/dist/session-catalog/project-server.js +59 -1435
  248. package/dist/session-catalog/protocol.d.ts +32 -1
  249. package/dist/session-catalog/registry.d.ts +17 -1
  250. package/dist/session-catalog/session-agents.d.ts +56 -0
  251. package/dist/session-catalog/store-rebuild.d.ts +14 -0
  252. package/dist/session-catalog/store-schema.d.ts +26 -0
  253. package/dist/session-catalog/store.d.ts +27 -1
  254. package/dist/session-note-attach.d.ts +9 -0
  255. package/dist/skills/index.js +35 -1578
  256. package/dist/statusline/index.d.ts +43 -0
  257. package/dist/statusline/index.js +102 -0
  258. package/dist/storage/board-store-port.d.ts +2 -2
  259. package/dist/storage/config-loader/in-project-policy.d.ts +29 -0
  260. package/dist/storage/config-loader.d.ts +3 -2
  261. package/dist/storage/file-session-writer.d.ts +4 -2
  262. package/dist/storage/goal-coordination.d.ts +6 -1
  263. package/dist/storage/goal-kanban.d.ts +4 -1
  264. package/dist/storage/index.d.ts +12 -4
  265. package/dist/storage/index.js +198 -15601
  266. package/dist/storage/input-history-store.d.ts +2 -4
  267. package/dist/storage/memory-curator.d.ts +133 -0
  268. package/dist/storage/session-agent-attribution.d.ts +39 -0
  269. package/dist/storage/session-doctor.d.ts +109 -0
  270. package/dist/storage/session-event-bridge.d.ts +5 -7
  271. package/dist/storage/session-outcome.d.ts +42 -0
  272. package/dist/storage/session-recovery.d.ts +55 -0
  273. package/dist/storage/session-store/load-session-data.d.ts +11 -0
  274. package/dist/storage/session-store/prune-helpers.d.ts +1 -1
  275. package/dist/storage/session-store/resume-session.d.ts +0 -2
  276. package/dist/storage/session-store/types.d.ts +8 -0
  277. package/dist/storage/session-store.d.ts +3 -3
  278. package/dist/storage/session-summary-tracker.d.ts +8 -1
  279. package/dist/storage/session-write-buffer.d.ts +18 -0
  280. package/dist/storage/session-writer-truncate.d.ts +2 -0
  281. package/dist/tasking/index.js +10 -676
  282. package/dist/tools/fallback-manage-tools.d.ts +6 -4
  283. package/dist/tools/index.js +52 -9590
  284. package/dist/tools/model-tier-set-tool.d.ts +66 -0
  285. package/dist/types/agent-bridge.d.ts +2 -1
  286. package/dist/types/config/autonomy.d.ts +5 -0
  287. package/dist/types/config/mcp-features.d.ts +7 -0
  288. package/dist/types/config/model-tiers.d.ts +148 -0
  289. package/dist/types/config/root.d.ts +9 -0
  290. package/dist/types/config/tools.d.ts +73 -0
  291. package/dist/types/config/ui.d.ts +1 -1
  292. package/dist/types/config.d.ts +1 -0
  293. package/dist/types/context.d.ts +2 -0
  294. package/dist/types/default-config.d.ts +6 -0
  295. package/dist/types/errors.d.ts +20 -1
  296. package/dist/types/index.d.ts +11 -9
  297. package/dist/types/index.js +131 -1342
  298. package/dist/types/multi-agent.d.ts +43 -0
  299. package/dist/types/plugin.d.ts +1 -1
  300. package/dist/types/provider-runner.d.ts +8 -0
  301. package/dist/types/provider.d.ts +15 -0
  302. package/dist/types/runtime-capability-manifest.d.ts +1 -1
  303. package/dist/types/secret-scrubber.d.ts +15 -0
  304. package/dist/types/session-markers.d.ts +37 -10
  305. package/dist/types/session-markers.js +8 -144
  306. package/dist/types/session-timeline.d.ts +197 -0
  307. package/dist/types/session-timeline.js +12 -0
  308. package/dist/types/session.d.ts +172 -11
  309. package/dist/types/system-prompt.d.ts +27 -0
  310. package/dist/utils/config-backup.d.ts +9 -1
  311. package/dist/utils/error.js +3 -4
  312. package/dist/utils/expect-defined.js +3 -9
  313. package/dist/utils/heap-watchdog.js +6 -706
  314. package/dist/utils/index.js +271 -5685
  315. package/dist/utils/message-invariants.d.ts +4 -1
  316. package/dist/utils/regex-guard.d.ts +1 -1
  317. package/dist/utils/sage-output-block.js +5 -42
  318. package/dist/utils/socket-path.d.ts +1 -1
  319. package/dist/utils/token-estimate.d.ts +6 -2
  320. package/dist/utils/wstack-paths.d.ts +2 -0
  321. package/dist/wiring/proxy-rewrite.d.ts +46 -0
  322. package/dist/wiring/proxy-rewrite.js +24 -121
  323. package/dist/worktree/index.js +6 -887
  324. package/instructions/agents/explore-companion.md +45 -18
  325. package/instructions/agents/memory-curator.md +34 -22
  326. package/instructions/coordination/director-preamble.md +12 -7
  327. package/instructions/coordination/subagent-baseline.md +26 -5
  328. package/instructions/leader-after-task.md +4 -1
  329. package/instructions/llm/chimera-review.md +30 -9
  330. package/instructions/llm/memory-curator.md +31 -0
  331. package/instructions/sections/tool/delegation-compact.md +2 -0
  332. package/instructions/sections/tool/delegation-full.md +5 -1
  333. package/instructions/sections/tool/mailbox-compact.md +5 -1
  334. package/instructions/sections/tool/mailbox-full.md +3 -0
  335. package/instructions/sections/tool/session-note-compact.md +3 -0
  336. package/instructions/sections/tool/session-note-full.md +15 -0
  337. package/instructions/system-lite.md +9 -4
  338. package/instructions/system-pro.md +66 -143
  339. package/instructions/system.md +73 -175
  340. package/package.json +32 -4
  341. package/dist/coordination/agents.d.ts +0 -8
  342. package/dist/coordination/transport.d.ts +0 -2
  343. package/dist/storage/session-writer/session-writer-summary-tracker.d.ts +0 -28
@@ -0,0 +1,589 @@
1
+ import {
2
+ ERROR_CODES,
3
+ SddError
4
+ } from "./chunk-25LSLC3G.js";
5
+ import {
6
+ toErrorMessage
7
+ } from "./chunk-TBRL2RCC.js";
8
+
9
+ // src/tasking/task-store.ts
10
+ var DefaultTaskStore = class {
11
+ graphs = /* @__PURE__ */ new Map();
12
+ async saveGraph(graph) {
13
+ this.graphs.set(graph.id, this.cloneGraph(graph));
14
+ }
15
+ async loadGraph(id) {
16
+ const graph = this.graphs.get(id);
17
+ return graph ? this.cloneGraph(graph) : null;
18
+ }
19
+ async listGraphs() {
20
+ return Array.from(this.graphs.values()).map((graph) => ({
21
+ id: graph.id,
22
+ title: graph.title,
23
+ updatedAt: graph.updatedAt
24
+ }));
25
+ }
26
+ async deleteGraph(id) {
27
+ this.graphs.delete(id);
28
+ }
29
+ cloneGraph(graph) {
30
+ return {
31
+ ...graph,
32
+ nodes: new Map(graph.nodes),
33
+ edges: [...graph.edges],
34
+ rootNodes: [...graph.rootNodes]
35
+ };
36
+ }
37
+ };
38
+
39
+ // src/types/task-graph.ts
40
+ function computeTaskProgress(graph) {
41
+ let completed = 0;
42
+ let pending = 0;
43
+ let inProgress = 0;
44
+ let blocked = 0;
45
+ let failed = 0;
46
+ let review = 0;
47
+ let estimatedHours = 0;
48
+ let actualHours = 0;
49
+ for (const n of graph.nodes.values()) {
50
+ switch (n.status) {
51
+ case "completed":
52
+ completed++;
53
+ break;
54
+ case "pending":
55
+ pending++;
56
+ break;
57
+ case "in_progress":
58
+ inProgress++;
59
+ break;
60
+ case "blocked":
61
+ blocked++;
62
+ break;
63
+ case "failed":
64
+ failed++;
65
+ break;
66
+ case "review":
67
+ review++;
68
+ break;
69
+ }
70
+ estimatedHours += n.estimateHours ?? 0;
71
+ actualHours += n.actualHours ?? 0;
72
+ }
73
+ const total = graph.nodes.size;
74
+ return {
75
+ total,
76
+ pending,
77
+ inProgress,
78
+ blocked,
79
+ failed,
80
+ review,
81
+ completed,
82
+ percentComplete: total > 0 ? Math.round(completed / total * 100) : 0,
83
+ estimatedHours,
84
+ actualHours
85
+ };
86
+ }
87
+ function topologicalSort(graph) {
88
+ const visited = /* @__PURE__ */ new Set();
89
+ const inStack = /* @__PURE__ */ new Set();
90
+ const result = [];
91
+ function visit(id) {
92
+ if (inStack.has(id)) return;
93
+ if (visited.has(id)) return;
94
+ if (!graph.nodes.has(id)) return;
95
+ visited.add(id);
96
+ inStack.add(id);
97
+ for (const edge of graph.edges) {
98
+ if (edge.from === id) visit(edge.to);
99
+ }
100
+ inStack.delete(id);
101
+ result.push(id);
102
+ }
103
+ for (const rootId of graph.rootNodes) {
104
+ visit(rootId);
105
+ }
106
+ return result;
107
+ }
108
+ function serializeTaskGraph(graph) {
109
+ return {
110
+ ...graph,
111
+ nodes: Array.from(graph.nodes.values())
112
+ };
113
+ }
114
+ function deserializeTaskGraph(input) {
115
+ const nodes = /* @__PURE__ */ new Map();
116
+ if (Array.isArray(input.nodes)) {
117
+ for (const entry of input.nodes) {
118
+ if (Array.isArray(entry)) nodes.set(entry[0], { ...entry[1], id: entry[1].id || entry[0] });
119
+ else nodes.set(entry.id, entry);
120
+ }
121
+ } else {
122
+ for (const [id, node] of Object.entries(input.nodes)) {
123
+ nodes.set(id, { ...node, id: node.id || id });
124
+ }
125
+ }
126
+ return { ...input, nodes };
127
+ }
128
+
129
+ // src/tasking/task-tracker.ts
130
+ var TaskTracker = class _TaskTracker {
131
+ constructor(opts) {
132
+ this.opts = opts;
133
+ }
134
+ opts;
135
+ graph = null;
136
+ transitions = [];
137
+ listeners = [];
138
+ /**
139
+ * Re-entrancy guard for status cascades: true while an auto-block /
140
+ * auto-unblock cascade is running. Listener-driven mutations during a
141
+ * cascade still record their own primary transition — only their
142
+ * cascading is skipped (prevents unbounded recursion).
143
+ */
144
+ cascading = false;
145
+ static MAX_TRANSITIONS = 1e4;
146
+ /**
147
+ * Subscribe to live task mutations (add / update / status change). Returns an
148
+ * unsubscribe fn. This is the hook the board projector uses to stream a live
149
+ * snapshot — the tracker was previously fire-and-forget with no observability.
150
+ */
151
+ subscribe(listener) {
152
+ this.listeners.push(listener);
153
+ return () => {
154
+ const i = this.listeners.indexOf(listener);
155
+ if (i >= 0) this.listeners.splice(i, 1);
156
+ };
157
+ }
158
+ notifyChange(change) {
159
+ for (const l of this.listeners) {
160
+ try {
161
+ l(change);
162
+ } catch {
163
+ }
164
+ }
165
+ }
166
+ /**
167
+ * Attach an existing graph (used by PhaseOrchestrator to associate a tracker
168
+ * with a phase's pre-built task graph without re-creating it).
169
+ */
170
+ setGraph(graph) {
171
+ this.graph = graph;
172
+ }
173
+ async createGraph(specId, title) {
174
+ this.graph = {
175
+ id: crypto.randomUUID(),
176
+ specId,
177
+ title,
178
+ nodes: /* @__PURE__ */ new Map(),
179
+ edges: [],
180
+ rootNodes: [],
181
+ createdAt: Date.now(),
182
+ updatedAt: Date.now()
183
+ };
184
+ await this.opts.store.saveGraph(this.graph);
185
+ return this.graph;
186
+ }
187
+ async loadGraph(id) {
188
+ this.graph = await this.opts.store.loadGraph(id);
189
+ return this.graph;
190
+ }
191
+ addNode(node) {
192
+ if (!this.graph)
193
+ throw new SddError({
194
+ message: "No graph loaded",
195
+ code: ERROR_CODES.SDD_INVALID_STATE
196
+ });
197
+ const now = Date.now();
198
+ const newNode = {
199
+ ...node,
200
+ id: crypto.randomUUID(),
201
+ status: node.status ?? "pending",
202
+ createdAt: now,
203
+ updatedAt: now
204
+ };
205
+ this.graph.nodes.set(newNode.id, newNode);
206
+ if (!node.parentId) {
207
+ this.graph.rootNodes.push(newNode.id);
208
+ }
209
+ this.graph.updatedAt = now;
210
+ this.persist();
211
+ this.notifyChange({ type: "node_added", nodeId: newNode.id, node: newNode });
212
+ return newNode;
213
+ }
214
+ addEdge(from, to, type = "depends_on") {
215
+ if (!this.graph)
216
+ throw new SddError({
217
+ message: "No graph loaded",
218
+ code: ERROR_CODES.SDD_INVALID_STATE
219
+ });
220
+ if (!this.graph.nodes.has(from) || !this.graph.nodes.has(to)) {
221
+ throw new SddError({
222
+ message: `Cannot add ${type} edge ${from} -> ${to}: endpoint task is not in the graph`,
223
+ code: ERROR_CODES.SDD_NOT_READY,
224
+ context: { from, to, type }
225
+ });
226
+ }
227
+ if (from === to) {
228
+ throw new SddError({
229
+ message: `Cannot add ${type} edge: self-loop on task ${from}`,
230
+ code: ERROR_CODES.SDD_INVALID_STATE,
231
+ context: { nodeId: from, type }
232
+ });
233
+ }
234
+ if (this.graph.edges.some((e) => e.from === from && e.to === to && e.type === type)) return;
235
+ if (type === "depends_on" && this.dependsOnTransitively(from, to, /* @__PURE__ */ new Set())) {
236
+ throw new SddError({
237
+ message: `Cannot add depends_on edge ${from} -> ${to}: it would create a dependency cycle`,
238
+ code: ERROR_CODES.SDD_INVALID_STATE,
239
+ context: { from, to }
240
+ });
241
+ }
242
+ this.graph.edges.push({
243
+ id: crypto.randomUUID(),
244
+ from,
245
+ to,
246
+ type
247
+ });
248
+ this.graph.updatedAt = Date.now();
249
+ this.persist();
250
+ }
251
+ /**
252
+ * Declare that `taskId` depends on `depId` (a `depends_on` edge `depId → taskId`),
253
+ * guarding against self-loops, duplicates, missing nodes, and cycles. Returns
254
+ * true if the dependency now holds (added or already present), false if it was
255
+ * rejected (would create a cycle / unknown node). This is the safe entry point
256
+ * for wiring agent-declared `dependsOn` references into the graph.
257
+ */
258
+ addDependency(depId, taskId) {
259
+ if (!this.graph) return false;
260
+ if (depId === taskId) return false;
261
+ if (!this.graph.nodes.has(depId) || !this.graph.nodes.has(taskId)) return false;
262
+ if (this.getBlockers(taskId).includes(depId)) return true;
263
+ if (this.dependsOnTransitively(depId, taskId, /* @__PURE__ */ new Set())) return false;
264
+ this.addEdge(depId, taskId, "depends_on");
265
+ return true;
266
+ }
267
+ /** True when `taskId` transitively depends on `targetId` (follows depends_on blockers). */
268
+ dependsOnTransitively(taskId, targetId, seen) {
269
+ if (taskId === targetId) return true;
270
+ if (seen.has(taskId)) return false;
271
+ seen.add(taskId);
272
+ for (const blocker of this.getBlockers(taskId)) {
273
+ if (this.dependsOnTransitively(blocker, targetId, seen)) return true;
274
+ }
275
+ return false;
276
+ }
277
+ /**
278
+ * Merge `patch` into a node's `metadata` (used for per-task model/provider/
279
+ * fallback assignment and the cancel marker). Persists + notifies as a node
280
+ * update. No-op if the node is missing.
281
+ */
282
+ patchMetadata(id, patch) {
283
+ if (!this.graph) return;
284
+ const node = this.graph.nodes.get(id);
285
+ if (!node) return;
286
+ node.metadata = { ...node.metadata, ...patch };
287
+ node.updatedAt = Date.now();
288
+ this.graph.updatedAt = node.updatedAt;
289
+ this.persist();
290
+ this.notifyChange({ type: "node_updated", nodeId: id, node });
291
+ }
292
+ /**
293
+ * Remove a node and every edge touching it. Intended for deleting a task that
294
+ * has not started yet — callers must gate on status (do not remove a running
295
+ * task). Dependents simply lose this blocker (re-evaluated by `canStart`).
296
+ * Returns true if a node was removed.
297
+ */
298
+ removeNode(id) {
299
+ if (!this.graph) return false;
300
+ const node = this.graph.nodes.get(id);
301
+ if (!node) return false;
302
+ if (node.specRequirementId && this.graph.requiredRequirementIds?.includes(node.specRequirementId) && !Array.from(this.graph.nodes.values()).some(
303
+ (candidate) => candidate.id !== id && candidate.specRequirementId === node.specRequirementId
304
+ )) {
305
+ return false;
306
+ }
307
+ this.graph.nodes.delete(id);
308
+ this.graph.edges = this.graph.edges.filter((e) => e.from !== id && e.to !== id);
309
+ this.graph.rootNodes = this.graph.rootNodes.filter((r) => r !== id);
310
+ for (const n of this.graph.nodes.values()) {
311
+ if (n.children?.includes(id)) n.children = n.children.filter((c) => c !== id);
312
+ }
313
+ this.graph.updatedAt = Date.now();
314
+ this.persist();
315
+ this.notifyChange({ type: "node_removed", nodeId: id, node });
316
+ return true;
317
+ }
318
+ updateNodeStatus(id, status, reason) {
319
+ if (!this.graph)
320
+ throw new SddError({
321
+ message: "No graph loaded",
322
+ code: ERROR_CODES.SDD_INVALID_STATE
323
+ });
324
+ const node = this.graph.nodes.get(id);
325
+ if (!node)
326
+ throw new SddError({
327
+ message: `Node ${id} not found`,
328
+ code: ERROR_CODES.SDD_NOT_READY,
329
+ context: { nodeId: id }
330
+ });
331
+ const from = node.status;
332
+ const now = Date.now();
333
+ node.status = status;
334
+ node.updatedAt = now;
335
+ if (status === "completed") {
336
+ node.completedAt = now;
337
+ node.startedAt = node.startedAt ?? now;
338
+ }
339
+ if (status === "in_progress") {
340
+ node.startedAt = now;
341
+ }
342
+ this.transitions.push({ nodeId: id, from, to: status, timestamp: now, reason });
343
+ if (this.transitions.length > _TaskTracker.MAX_TRANSITIONS) {
344
+ this.transitions.splice(0, this.transitions.length - _TaskTracker.MAX_TRANSITIONS);
345
+ }
346
+ if (status === "completed") {
347
+ this.unblockDependents(id);
348
+ }
349
+ if (status === "in_progress") {
350
+ this.checkAndBlockIfNeeded(id);
351
+ }
352
+ this.graph.updatedAt = now;
353
+ this.persist();
354
+ this.notifyChange({
355
+ type: "status_changed",
356
+ nodeId: id,
357
+ node,
358
+ transition: { nodeId: id, from, to: status, timestamp: now, reason }
359
+ });
360
+ }
361
+ updateNode(id, patch) {
362
+ if (!this.graph)
363
+ throw new SddError({
364
+ message: "No graph loaded",
365
+ code: ERROR_CODES.SDD_INVALID_STATE
366
+ });
367
+ const node = this.graph.nodes.get(id);
368
+ if (!node)
369
+ throw new SddError({
370
+ message: `Node ${id} not found`,
371
+ code: ERROR_CODES.SDD_NOT_READY,
372
+ context: { nodeId: id }
373
+ });
374
+ if (patch.title !== void 0) node.title = patch.title;
375
+ if (patch.description !== void 0) node.description = patch.description;
376
+ if (patch.priority !== void 0) node.priority = patch.priority;
377
+ if (patch.estimateHours !== void 0) node.estimateHours = patch.estimateHours;
378
+ if (patch.tags !== void 0) node.tags = patch.tags;
379
+ if (patch.assignee !== void 0) node.assignee = patch.assignee;
380
+ node.updatedAt = Date.now();
381
+ this.graph.updatedAt = node.updatedAt;
382
+ this.persist();
383
+ this.notifyChange({ type: "node_updated", nodeId: id, node });
384
+ }
385
+ getNode(id) {
386
+ return this.graph?.nodes.get(id);
387
+ }
388
+ getAllNodes(filter, sort) {
389
+ if (!this.graph) return [];
390
+ let nodes = Array.from(this.graph.nodes.values());
391
+ if (filter) {
392
+ nodes = nodes.filter((n) => {
393
+ if (filter.status?.length && !filter.status.includes(n.status)) return false;
394
+ if (filter.priority?.length && !filter.priority.includes(n.priority)) return false;
395
+ if (filter.type?.length && !filter.type.includes(n.type)) return false;
396
+ if (filter.assignee?.length && n.assignee && !filter.assignee.includes(n.assignee))
397
+ return false;
398
+ if (filter.tags?.length && n.tags && !n.tags.some((t) => filter.tags?.includes(t)))
399
+ return false;
400
+ if (filter.specRequirementId && n.specRequirementId !== filter.specRequirementId)
401
+ return false;
402
+ return true;
403
+ });
404
+ }
405
+ if (sort) {
406
+ nodes.sort((a, b) => {
407
+ const cmp = compareByField(a, b, sort.field);
408
+ return sort.direction === "asc" ? cmp : -cmp;
409
+ });
410
+ }
411
+ return nodes;
412
+ }
413
+ getChildren(parentId) {
414
+ if (!this.graph) return [];
415
+ return Array.from(this.graph.nodes.values()).filter((n) => n.parentId === parentId);
416
+ }
417
+ getDependents(taskId) {
418
+ if (!this.graph) return [];
419
+ return this.graph.edges.filter((e) => e.from === taskId && e.type === "depends_on").map((e) => e.to);
420
+ }
421
+ getBlockers(taskId) {
422
+ if (!this.graph) return [];
423
+ return this.graph.edges.filter((e) => e.to === taskId && e.type === "depends_on").map((e) => e.from);
424
+ }
425
+ canStart(taskId) {
426
+ const blockers = this.getBlockers(taskId);
427
+ return blockers.every((id) => {
428
+ const node = this.graph?.nodes.get(id);
429
+ return node?.status === "completed" || node?.status === "failed";
430
+ });
431
+ }
432
+ getProgress() {
433
+ if (!this.graph) {
434
+ return {
435
+ total: 0,
436
+ pending: 0,
437
+ inProgress: 0,
438
+ blocked: 0,
439
+ failed: 0,
440
+ review: 0,
441
+ completed: 0,
442
+ percentComplete: 0,
443
+ estimatedHours: 0,
444
+ actualHours: 0
445
+ };
446
+ }
447
+ return computeTaskProgress(this.graph);
448
+ }
449
+ /**
450
+ * Recorded transitions in insertion order (oldest first — the array is
451
+ * trimmed from the front). With `taskId`, only that task's transitions are
452
+ * returned, still oldest-first; a consumer wanting newest-first reverses
453
+ * the result. Per-task filtering is possible because every TaskTransition
454
+ * carries `nodeId` (BIZ-005).
455
+ */
456
+ getTransitions(taskId) {
457
+ return taskId === void 0 ? [...this.transitions] : this.transitions.filter((t) => t.nodeId === taskId);
458
+ }
459
+ /**
460
+ * Record a cascade-driven status change (BIZ-003): mutate the node, push a
461
+ * TaskTransition, persist, and notify subscribers — the same effects an
462
+ * explicit updateNodeStatus produces — so the board projector's live
463
+ * snapshot and the transition log observe auto-block/auto-unblock.
464
+ */
465
+ recordCascadeStatusChange(nodeId, node, to, reason) {
466
+ const from = node.status;
467
+ if (from === to) return;
468
+ const now = Date.now();
469
+ node.status = to;
470
+ node.updatedAt = now;
471
+ if (this.graph) this.graph.updatedAt = now;
472
+ this.transitions.push({ nodeId, from, to, timestamp: now, reason });
473
+ if (this.transitions.length > _TaskTracker.MAX_TRANSITIONS) {
474
+ this.transitions.splice(0, this.transitions.length - _TaskTracker.MAX_TRANSITIONS);
475
+ }
476
+ this.persist();
477
+ this.notifyChange({
478
+ type: "status_changed",
479
+ nodeId,
480
+ node,
481
+ transition: { nodeId, from, to, timestamp: now, reason }
482
+ });
483
+ }
484
+ unblockDependents(completedId) {
485
+ if (!this.graph || this.cascading) return;
486
+ this.cascading = true;
487
+ try {
488
+ const dependents = this.getDependents(completedId);
489
+ for (const depId of dependents) {
490
+ const dep = this.graph.nodes.get(depId);
491
+ if (dep?.status !== "blocked") continue;
492
+ const remainingBlockers = this.getBlockers(depId);
493
+ const allUnblocked = remainingBlockers.every((id) => {
494
+ const blocker = this.graph?.nodes.get(id);
495
+ return blocker?.status === "completed" || blocker?.status === "failed";
496
+ });
497
+ if (allUnblocked) {
498
+ this.recordCascadeStatusChange(
499
+ depId,
500
+ dep,
501
+ "pending",
502
+ `auto-unblocked: blocker ${completedId} reached a terminal state`
503
+ );
504
+ }
505
+ }
506
+ } finally {
507
+ this.cascading = false;
508
+ }
509
+ }
510
+ checkAndBlockIfNeeded(taskId) {
511
+ if (!this.graph || this.cascading) return;
512
+ this.cascading = true;
513
+ try {
514
+ const blockers = this.getBlockers(taskId);
515
+ const incomplete = blockers.filter((id) => {
516
+ const blocker = this.graph?.nodes.get(id);
517
+ return blocker?.status !== "completed" && blocker?.status !== "failed";
518
+ });
519
+ if (incomplete.length > 0) {
520
+ const node = this.graph.nodes.get(taskId);
521
+ if (node) {
522
+ this.recordCascadeStatusChange(
523
+ taskId,
524
+ node,
525
+ "blocked",
526
+ `auto-blocked: incomplete blocker(s) ${incomplete.join(", ")}`
527
+ );
528
+ }
529
+ }
530
+ } finally {
531
+ this.cascading = false;
532
+ }
533
+ }
534
+ /**
535
+ * Fire-and-forget persistence with attached error handler.
536
+ * Synchronous mutators (addNode/addEdge/updateNodeStatus) use this to
537
+ * avoid forcing an async cascade through every caller; if the store
538
+ * is missing or throwing, the error is surfaced via onPersistError.
539
+ */
540
+ persist() {
541
+ if (!this.graph) return;
542
+ this.opts.store.saveGraph(this.graph).catch((err) => {
543
+ this.opts.onPersistError ? this.opts.onPersistError(err) : console.warn(
544
+ JSON.stringify({
545
+ level: "warn",
546
+ event: "task_tracker.save_graph_failed",
547
+ message: toErrorMessage(err),
548
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
549
+ })
550
+ );
551
+ });
552
+ }
553
+ };
554
+ var PRIORITY_RANK = {
555
+ critical: 0,
556
+ high: 1,
557
+ medium: 2,
558
+ low: 3
559
+ };
560
+ var STATUS_RANK = {
561
+ in_progress: 0,
562
+ pending: 1,
563
+ review: 2,
564
+ blocked: 3,
565
+ failed: 4,
566
+ completed: 5
567
+ };
568
+ function compareByField(a, b, field) {
569
+ switch (field) {
570
+ case "priority":
571
+ return PRIORITY_RANK[a.priority] - PRIORITY_RANK[b.priority];
572
+ case "status":
573
+ return STATUS_RANK[a.status] - STATUS_RANK[b.status];
574
+ case "createdAt":
575
+ return a.createdAt - b.createdAt;
576
+ case "updatedAt":
577
+ return a.updatedAt - b.updatedAt;
578
+ }
579
+ }
580
+
581
+ export {
582
+ DefaultTaskStore,
583
+ computeTaskProgress,
584
+ topologicalSort,
585
+ serializeTaskGraph,
586
+ deserializeTaskGraph,
587
+ TaskTracker
588
+ };
589
+ //# sourceMappingURL=chunk-BYD345OX.js.map