sensorium-mcp 3.1.2 → 3.1.3-board.10

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 (625) hide show
  1. package/Install-Sensorium.ps1 +257 -43
  2. package/README.md +2 -0
  3. package/dist/board/api/api.js +84 -0
  4. package/dist/board/api/api.test.ts +23 -0
  5. package/dist/board/api/client.js +113 -0
  6. package/dist/board/components/BottomNav.js +32 -0
  7. package/dist/board/components/Card.js +78 -0
  8. package/dist/board/components/Combobox.js +79 -0
  9. package/dist/board/components/CommentComposer.js +29 -0
  10. package/dist/board/components/CommentList.js +42 -0
  11. package/dist/board/components/DirTreePicker.js +128 -0
  12. package/dist/board/components/Dropdown.js +67 -0
  13. package/dist/board/components/Lane.js +47 -0
  14. package/dist/board/components/PriorityChip.js +20 -0
  15. package/dist/board/components/ProfileSummary.js +89 -0
  16. package/dist/board/components/StateBanner.js +24 -0
  17. package/dist/board/components/StatusChip.js +26 -0
  18. package/dist/board/components/rateLimit.js +32 -0
  19. package/dist/board/components/rateLimit.test.ts +16 -0
  20. package/dist/board/components/time.js +14 -0
  21. package/dist/board/config.js +56 -0
  22. package/dist/board/index.html +18 -0
  23. package/dist/board/main.js +37 -0
  24. package/dist/board/mock/api.mock.js +491 -0
  25. package/dist/board/mock/api.mock.test.ts +460 -0
  26. package/dist/board/mock/fixtures.js +512 -0
  27. package/dist/board/schema/policy.js +261 -0
  28. package/dist/board/state/recur.js +24 -0
  29. package/dist/board/state/recur.test.ts +24 -0
  30. package/dist/board/state/useBoard.js +161 -0
  31. package/dist/board/state/useBuilder.js +357 -0
  32. package/dist/board/state/useBuilder.test.ts +468 -0
  33. package/dist/board/state/useCard.js +193 -0
  34. package/dist/board/state/useCard.test.ts +435 -0
  35. package/dist/board/state/useDirBrowser.js +23 -0
  36. package/dist/board/styles/board.css +2885 -0
  37. package/dist/board/styles/tokens.css +72 -0
  38. package/dist/board/vendor/vue.esm-browser.js +9 -0
  39. package/dist/board/views/App.js +61 -0
  40. package/dist/board/views/BoardView.js +153 -0
  41. package/dist/board/views/BuilderView.js +582 -0
  42. package/dist/board/views/CardView.js +382 -0
  43. package/dist/board/views/SettingsView.js +152 -0
  44. package/dist/config/agent-settings.d.ts +11 -0
  45. package/dist/config/agent-settings.d.ts.map +1 -1
  46. package/dist/config/agent-settings.js +79 -0
  47. package/dist/config/agent-settings.js.map +1 -1
  48. package/dist/config/detail-grant.d.ts +7 -16
  49. package/dist/config/detail-grant.d.ts.map +1 -1
  50. package/dist/config/detail-grant.js +12 -35
  51. package/dist/config/detail-grant.js.map +1 -1
  52. package/dist/config/index.d.ts +2 -0
  53. package/dist/config/index.d.ts.map +1 -1
  54. package/dist/config/index.js +17 -0
  55. package/dist/config/index.js.map +1 -1
  56. package/dist/config/mcp-settings.d.ts +7 -1
  57. package/dist/config/mcp-settings.d.ts.map +1 -1
  58. package/dist/config/mcp-settings.js +9 -0
  59. package/dist/config/mcp-settings.js.map +1 -1
  60. package/dist/config/misc-settings.d.ts +22 -1
  61. package/dist/config/misc-settings.d.ts.map +1 -1
  62. package/dist/config/misc-settings.js +93 -3
  63. package/dist/config/misc-settings.js.map +1 -1
  64. package/dist/config/operator-grant.d.ts +9 -0
  65. package/dist/config/operator-grant.d.ts.map +1 -0
  66. package/dist/config/operator-grant.js +24 -0
  67. package/dist/config/operator-grant.js.map +1 -0
  68. package/dist/config/voice-grant.d.ts +10 -0
  69. package/dist/config/voice-grant.d.ts.map +1 -0
  70. package/dist/config/voice-grant.js +18 -0
  71. package/dist/config/voice-grant.js.map +1 -0
  72. package/dist/dashboard/board-static.d.ts +22 -0
  73. package/dist/dashboard/board-static.d.ts.map +1 -0
  74. package/dist/dashboard/board-static.js +130 -0
  75. package/dist/dashboard/board-static.js.map +1 -0
  76. package/dist/dashboard/presets.d.ts +1 -1
  77. package/dist/dashboard/presets.d.ts.map +1 -1
  78. package/dist/dashboard/presets.js +1 -1
  79. package/dist/dashboard/presets.js.map +1 -1
  80. package/dist/dashboard/routes/agent-templates.d.ts.map +1 -1
  81. package/dist/dashboard/routes/agent-templates.js +6 -9
  82. package/dist/dashboard/routes/agent-templates.js.map +1 -1
  83. package/dist/dashboard/routes/board-body.d.ts +8 -0
  84. package/dist/dashboard/routes/board-body.d.ts.map +1 -0
  85. package/dist/dashboard/routes/board-body.js +20 -0
  86. package/dist/dashboard/routes/board-body.js.map +1 -0
  87. package/dist/dashboard/routes/board-dir-listing.d.ts +70 -0
  88. package/dist/dashboard/routes/board-dir-listing.d.ts.map +1 -0
  89. package/dist/dashboard/routes/board-dir-listing.js +192 -0
  90. package/dist/dashboard/routes/board-dir-listing.js.map +1 -0
  91. package/dist/dashboard/routes/board-lane-groups.d.ts +6 -0
  92. package/dist/dashboard/routes/board-lane-groups.d.ts.map +1 -0
  93. package/dist/dashboard/routes/board-lane-groups.js +52 -0
  94. package/dist/dashboard/routes/board-lane-groups.js.map +1 -0
  95. package/dist/dashboard/routes/board-policy.d.ts +224 -0
  96. package/dist/dashboard/routes/board-policy.d.ts.map +1 -0
  97. package/dist/dashboard/routes/board-policy.js +214 -0
  98. package/dist/dashboard/routes/board-policy.js.map +1 -0
  99. package/dist/dashboard/routes/board-profile-parse.d.ts +32 -0
  100. package/dist/dashboard/routes/board-profile-parse.d.ts.map +1 -0
  101. package/dist/dashboard/routes/board-profile-parse.js +338 -0
  102. package/dist/dashboard/routes/board-profile-parse.js.map +1 -0
  103. package/dist/dashboard/routes/board.d.ts +90 -0
  104. package/dist/dashboard/routes/board.d.ts.map +1 -0
  105. package/dist/dashboard/routes/board.js +721 -0
  106. package/dist/dashboard/routes/board.js.map +1 -0
  107. package/dist/dashboard/routes/codex.d.ts +14 -0
  108. package/dist/dashboard/routes/codex.d.ts.map +1 -0
  109. package/dist/dashboard/routes/codex.js +92 -0
  110. package/dist/dashboard/routes/codex.js.map +1 -0
  111. package/dist/dashboard/routes/prompts.d.ts +2 -2
  112. package/dist/dashboard/routes/prompts.d.ts.map +1 -1
  113. package/dist/dashboard/routes/prompts.js +2 -2
  114. package/dist/dashboard/routes/prompts.js.map +1 -1
  115. package/dist/dashboard/routes/settings.d.ts +2 -0
  116. package/dist/dashboard/routes/settings.d.ts.map +1 -1
  117. package/dist/dashboard/routes/settings.js +24 -1
  118. package/dist/dashboard/routes/settings.js.map +1 -1
  119. package/dist/dashboard/routes/skills.d.ts +7 -1
  120. package/dist/dashboard/routes/skills.d.ts.map +1 -1
  121. package/dist/dashboard/routes/skills.js +6 -6
  122. package/dist/dashboard/routes/skills.js.map +1 -1
  123. package/dist/dashboard/routes/snapshots.d.ts +2 -1
  124. package/dist/dashboard/routes/snapshots.d.ts.map +1 -1
  125. package/dist/dashboard/routes/snapshots.js +24 -18
  126. package/dist/dashboard/routes/snapshots.js.map +1 -1
  127. package/dist/dashboard/routes/templates.js +5 -5
  128. package/dist/dashboard/routes/templates.js.map +1 -1
  129. package/dist/dashboard/routes/threads-create.d.ts +17 -0
  130. package/dist/dashboard/routes/threads-create.d.ts.map +1 -1
  131. package/dist/dashboard/routes/threads-create.js +32 -10
  132. package/dist/dashboard/routes/threads-create.js.map +1 -1
  133. package/dist/dashboard/routes/threads-helpers.d.ts +11 -2
  134. package/dist/dashboard/routes/threads-helpers.d.ts.map +1 -1
  135. package/dist/dashboard/routes/threads-helpers.js +20 -3
  136. package/dist/dashboard/routes/threads-helpers.js.map +1 -1
  137. package/dist/dashboard/routes/threads-read.d.ts +16 -4
  138. package/dist/dashboard/routes/threads-read.d.ts.map +1 -1
  139. package/dist/dashboard/routes/threads-read.js +61 -55
  140. package/dist/dashboard/routes/threads-read.js.map +1 -1
  141. package/dist/dashboard/routes/threads.d.ts +2 -2
  142. package/dist/dashboard/routes/threads.d.ts.map +1 -1
  143. package/dist/dashboard/routes/threads.js +143 -29
  144. package/dist/dashboard/routes/threads.js.map +1 -1
  145. package/dist/dashboard/routes/types.d.ts +6 -0
  146. package/dist/dashboard/routes/types.d.ts.map +1 -1
  147. package/dist/dashboard/routes/types.js.map +1 -1
  148. package/dist/dashboard/routes.d.ts +2 -2
  149. package/dist/dashboard/routes.d.ts.map +1 -1
  150. package/dist/dashboard/routes.js +85 -7
  151. package/dist/dashboard/routes.js.map +1 -1
  152. package/dist/dashboard/spa.html +15 -12
  153. package/dist/data/board/board-schema.d.ts +29 -0
  154. package/dist/data/board/board-schema.d.ts.map +1 -0
  155. package/dist/data/board/board-schema.js +202 -0
  156. package/dist/data/board/board-schema.js.map +1 -0
  157. package/dist/data/board/board-types.d.ts +175 -0
  158. package/dist/data/board/board-types.d.ts.map +1 -0
  159. package/dist/data/board/board-types.js +9 -0
  160. package/dist/data/board/board-types.js.map +1 -0
  161. package/dist/data/board/card.repository.d.ts +137 -0
  162. package/dist/data/board/card.repository.d.ts.map +1 -0
  163. package/dist/data/board/card.repository.js +470 -0
  164. package/dist/data/board/card.repository.js.map +1 -0
  165. package/dist/data/board/comment.repository.d.ts +14 -0
  166. package/dist/data/board/comment.repository.d.ts.map +1 -0
  167. package/dist/data/board/comment.repository.js +42 -0
  168. package/dist/data/board/comment.repository.js.map +1 -0
  169. package/dist/data/board/lane-group.repository.d.ts +19 -0
  170. package/dist/data/board/lane-group.repository.d.ts.map +1 -0
  171. package/dist/data/board/lane-group.repository.js +66 -0
  172. package/dist/data/board/lane-group.repository.js.map +1 -0
  173. package/dist/data/board/profile-defaults.d.ts +17 -0
  174. package/dist/data/board/profile-defaults.d.ts.map +1 -0
  175. package/dist/data/board/profile-defaults.js +107 -0
  176. package/dist/data/board/profile-defaults.js.map +1 -0
  177. package/dist/data/interfaces.d.ts +1 -0
  178. package/dist/data/interfaces.d.ts.map +1 -1
  179. package/dist/data/memory/bootstrap.d.ts +1 -8
  180. package/dist/data/memory/bootstrap.d.ts.map +1 -1
  181. package/dist/data/memory/bootstrap.js +27 -37
  182. package/dist/data/memory/bootstrap.js.map +1 -1
  183. package/dist/data/memory/consolidation.d.ts +9 -31
  184. package/dist/data/memory/consolidation.d.ts.map +1 -1
  185. package/dist/data/memory/consolidation.js +22 -32
  186. package/dist/data/memory/consolidation.js.map +1 -1
  187. package/dist/data/memory/db-maintenance.d.ts +54 -0
  188. package/dist/data/memory/db-maintenance.d.ts.map +1 -0
  189. package/dist/data/memory/db-maintenance.js +81 -0
  190. package/dist/data/memory/db-maintenance.js.map +1 -0
  191. package/dist/data/memory/episodes.d.ts +2 -1
  192. package/dist/data/memory/episodes.d.ts.map +1 -1
  193. package/dist/data/memory/episodes.js +5 -1
  194. package/dist/data/memory/episodes.js.map +1 -1
  195. package/dist/data/memory/index.d.ts +0 -4
  196. package/dist/data/memory/index.d.ts.map +1 -1
  197. package/dist/data/memory/index.js +0 -4
  198. package/dist/data/memory/index.js.map +1 -1
  199. package/dist/data/memory/key-knowledge.d.ts +51 -0
  200. package/dist/data/memory/key-knowledge.d.ts.map +1 -0
  201. package/dist/data/memory/key-knowledge.js +128 -0
  202. package/dist/data/memory/key-knowledge.js.map +1 -0
  203. package/dist/data/memory/migration-runner.d.ts +1 -1
  204. package/dist/data/memory/migration-runner.d.ts.map +1 -1
  205. package/dist/data/memory/migration-runner.js +407 -1
  206. package/dist/data/memory/migration-runner.js.map +1 -1
  207. package/dist/data/memory/narrative-lint.d.ts +2 -2
  208. package/dist/data/memory/narrative-lint.d.ts.map +1 -1
  209. package/dist/data/memory/narrative-lint.js +23 -13
  210. package/dist/data/memory/narrative-lint.js.map +1 -1
  211. package/dist/data/memory/narrative-resolutions.d.ts +9 -2
  212. package/dist/data/memory/narrative-resolutions.d.ts.map +1 -1
  213. package/dist/data/memory/narrative-resolutions.js +9 -8
  214. package/dist/data/memory/narrative-resolutions.js.map +1 -1
  215. package/dist/data/memory/narrative-sources.d.ts +1 -1
  216. package/dist/data/memory/narrative-sources.d.ts.map +1 -1
  217. package/dist/data/memory/narrative-sources.js +8 -3
  218. package/dist/data/memory/narrative-sources.js.map +1 -1
  219. package/dist/data/memory/narrative-store.d.ts +24 -0
  220. package/dist/data/memory/narrative-store.d.ts.map +1 -1
  221. package/dist/data/memory/narrative-store.js +73 -35
  222. package/dist/data/memory/narrative-store.js.map +1 -1
  223. package/dist/data/memory/narrative.d.ts.map +1 -1
  224. package/dist/data/memory/narrative.js +47 -29
  225. package/dist/data/memory/narrative.js.map +1 -1
  226. package/dist/data/memory/note-archival.d.ts +1 -1
  227. package/dist/data/memory/note-archival.d.ts.map +1 -1
  228. package/dist/data/memory/note-archival.js +7 -3
  229. package/dist/data/memory/note-archival.js.map +1 -1
  230. package/dist/data/memory/note-embeddings.d.ts +7 -0
  231. package/dist/data/memory/note-embeddings.d.ts.map +1 -1
  232. package/dist/data/memory/note-embeddings.js +6 -2
  233. package/dist/data/memory/note-embeddings.js.map +1 -1
  234. package/dist/data/memory/passive-notice.repository.d.ts +70 -0
  235. package/dist/data/memory/passive-notice.repository.d.ts.map +1 -0
  236. package/dist/data/memory/passive-notice.repository.js +85 -0
  237. package/dist/data/memory/passive-notice.repository.js.map +1 -0
  238. package/dist/data/memory/schema-ddl.d.ts +120 -1
  239. package/dist/data/memory/schema-ddl.d.ts.map +1 -1
  240. package/dist/data/memory/schema-ddl.js +171 -4
  241. package/dist/data/memory/schema-ddl.js.map +1 -1
  242. package/dist/data/memory/schema-guard.d.ts.map +1 -1
  243. package/dist/data/memory/schema-guard.js +5 -41
  244. package/dist/data/memory/schema-guard.js.map +1 -1
  245. package/dist/data/memory/schema.d.ts.map +1 -1
  246. package/dist/data/memory/schema.js +10 -34
  247. package/dist/data/memory/schema.js.map +1 -1
  248. package/dist/data/memory/semantic-notes.d.ts +13 -8
  249. package/dist/data/memory/semantic-notes.d.ts.map +1 -1
  250. package/dist/data/memory/semantic-notes.js +12 -17
  251. package/dist/data/memory/semantic-notes.js.map +1 -1
  252. package/dist/data/memory/thread-registry.d.ts +330 -15
  253. package/dist/data/memory/thread-registry.d.ts.map +1 -1
  254. package/dist/data/memory/thread-registry.js +523 -67
  255. package/dist/data/memory/thread-registry.js.map +1 -1
  256. package/dist/data/memory/utils.d.ts +6 -0
  257. package/dist/data/memory/utils.d.ts.map +1 -1
  258. package/dist/data/memory/utils.js +13 -0
  259. package/dist/data/memory/utils.js.map +1 -1
  260. package/dist/data/memory/worker-lifecycle.repository.d.ts +308 -0
  261. package/dist/data/memory/worker-lifecycle.repository.d.ts.map +1 -0
  262. package/dist/data/memory/worker-lifecycle.repository.js +428 -0
  263. package/dist/data/memory/worker-lifecycle.repository.js.map +1 -0
  264. package/dist/data/optional.d.ts +16 -0
  265. package/dist/data/optional.d.ts.map +1 -0
  266. package/dist/data/optional.js +47 -0
  267. package/dist/data/optional.js.map +1 -0
  268. package/dist/index.js +156 -24
  269. package/dist/index.js.map +1 -1
  270. package/dist/integrations/openai/speech.d.ts.map +1 -1
  271. package/dist/integrations/openai/speech.js +52 -19
  272. package/dist/integrations/openai/speech.js.map +1 -1
  273. package/dist/integrations/openai/video.d.ts +1 -1
  274. package/dist/integrations/openai/video.d.ts.map +1 -1
  275. package/dist/integrations/openai/video.js +13 -8
  276. package/dist/integrations/openai/video.js.map +1 -1
  277. package/dist/integrations/telegram/types.d.ts +11 -0
  278. package/dist/integrations/telegram/types.d.ts.map +1 -1
  279. package/dist/lib/http-retry.d.ts +91 -0
  280. package/dist/lib/http-retry.d.ts.map +1 -0
  281. package/dist/lib/http-retry.js +177 -0
  282. package/dist/lib/http-retry.js.map +1 -0
  283. package/dist/lib/mcp-http-port.d.ts +12 -0
  284. package/dist/lib/mcp-http-port.d.ts.map +1 -0
  285. package/dist/lib/mcp-http-port.js +19 -0
  286. package/dist/lib/mcp-http-port.js.map +1 -0
  287. package/dist/lib/paths.d.ts +29 -4
  288. package/dist/lib/paths.d.ts.map +1 -1
  289. package/dist/lib/paths.js +31 -4
  290. package/dist/lib/paths.js.map +1 -1
  291. package/dist/lib/types.d.ts +2 -0
  292. package/dist/lib/types.d.ts.map +1 -1
  293. package/dist/lib/usage-metering/pricing.js +1 -1
  294. package/dist/lib/usage-metering/pricing.js.map +1 -1
  295. package/dist/lib/usage-metering/sink.d.ts +4 -0
  296. package/dist/lib/usage-metering/sink.d.ts.map +1 -1
  297. package/dist/lib/usage-metering/sink.js +6 -4
  298. package/dist/lib/usage-metering/sink.js.map +1 -1
  299. package/dist/lib/utils.d.ts +31 -0
  300. package/dist/lib/utils.d.ts.map +1 -1
  301. package/dist/lib/utils.js +49 -0
  302. package/dist/lib/utils.js.map +1 -1
  303. package/dist/llm/prompts/narrative.d.ts.map +1 -1
  304. package/dist/llm/prompts/narrative.js +27 -86
  305. package/dist/llm/prompts/narrative.js.map +1 -1
  306. package/dist/log-parsing/log-events.d.ts +38 -0
  307. package/dist/log-parsing/log-events.d.ts.map +1 -0
  308. package/dist/log-parsing/log-events.js +2 -0
  309. package/dist/log-parsing/log-events.js.map +1 -0
  310. package/dist/log-parsing/parser-registry.d.ts +4 -0
  311. package/dist/log-parsing/parser-registry.d.ts.map +1 -0
  312. package/dist/log-parsing/parser-registry.js +18 -0
  313. package/dist/log-parsing/parser-registry.js.map +1 -0
  314. package/dist/log-parsing/parsers/claude.d.ts +6 -0
  315. package/dist/log-parsing/parsers/claude.d.ts.map +1 -0
  316. package/dist/log-parsing/parsers/claude.js +100 -0
  317. package/dist/log-parsing/parsers/claude.js.map +1 -0
  318. package/dist/log-parsing/parsers/codex.d.ts +6 -0
  319. package/dist/log-parsing/parsers/codex.d.ts.map +1 -0
  320. package/dist/log-parsing/parsers/codex.js +116 -0
  321. package/dist/log-parsing/parsers/codex.js.map +1 -0
  322. package/dist/log-parsing/parsers/copilot.d.ts +6 -0
  323. package/dist/log-parsing/parsers/copilot.d.ts.map +1 -0
  324. package/dist/log-parsing/parsers/copilot.js +65 -0
  325. package/dist/log-parsing/parsers/copilot.js.map +1 -0
  326. package/dist/log-parsing/parsers/json-lines.d.ts +9 -0
  327. package/dist/log-parsing/parsers/json-lines.d.ts.map +1 -0
  328. package/dist/log-parsing/parsers/json-lines.js +25 -0
  329. package/dist/log-parsing/parsers/json-lines.js.map +1 -0
  330. package/dist/log-parsing/render.d.ts +33 -0
  331. package/dist/log-parsing/render.d.ts.map +1 -0
  332. package/dist/log-parsing/render.js +113 -0
  333. package/dist/log-parsing/render.js.map +1 -0
  334. package/dist/log-parsing/text.d.ts +8 -0
  335. package/dist/log-parsing/text.d.ts.map +1 -0
  336. package/dist/log-parsing/text.js +20 -0
  337. package/dist/log-parsing/text.js.map +1 -0
  338. package/dist/server/http-server.d.ts +8 -1
  339. package/dist/server/http-server.d.ts.map +1 -1
  340. package/dist/server/http-server.js +41 -19
  341. package/dist/server/http-server.js.map +1 -1
  342. package/dist/server/port-holder.d.ts +94 -0
  343. package/dist/server/port-holder.d.ts.map +1 -0
  344. package/dist/server/port-holder.js +122 -0
  345. package/dist/server/port-holder.js.map +1 -0
  346. package/dist/services/agent-spawn.service.d.ts +50 -5
  347. package/dist/services/agent-spawn.service.d.ts.map +1 -1
  348. package/dist/services/agent-spawn.service.js +59 -66
  349. package/dist/services/agent-spawn.service.js.map +1 -1
  350. package/dist/services/background-runner.d.ts +0 -1
  351. package/dist/services/background-runner.d.ts.map +1 -1
  352. package/dist/services/background-runner.js +0 -58
  353. package/dist/services/background-runner.js.map +1 -1
  354. package/dist/services/board/board-signals.d.ts +45 -0
  355. package/dist/services/board/board-signals.d.ts.map +1 -0
  356. package/dist/services/board/board-signals.js +170 -0
  357. package/dist/services/board/board-signals.js.map +1 -0
  358. package/dist/services/board/card-briefing.d.ts +24 -0
  359. package/dist/services/board/card-briefing.d.ts.map +1 -0
  360. package/dist/services/board/card-briefing.js +132 -0
  361. package/dist/services/board/card-briefing.js.map +1 -0
  362. package/dist/services/board/card-diagnostics.d.ts +25 -0
  363. package/dist/services/board/card-diagnostics.d.ts.map +1 -0
  364. package/dist/services/board/card-diagnostics.js +50 -0
  365. package/dist/services/board/card-diagnostics.js.map +1 -0
  366. package/dist/services/board/live-root-thread.d.ts +8 -0
  367. package/dist/services/board/live-root-thread.d.ts.map +1 -0
  368. package/dist/services/board/live-root-thread.js +2 -0
  369. package/dist/services/board/live-root-thread.js.map +1 -0
  370. package/dist/services/board/orchestrator.service.d.ts +119 -0
  371. package/dist/services/board/orchestrator.service.d.ts.map +1 -0
  372. package/dist/services/board/orchestrator.service.js +387 -0
  373. package/dist/services/board/orchestrator.service.js.map +1 -0
  374. package/dist/services/board/release-worker.d.ts +43 -0
  375. package/dist/services/board/release-worker.d.ts.map +1 -0
  376. package/dist/services/board/release-worker.js +96 -0
  377. package/dist/services/board/release-worker.js.map +1 -0
  378. package/dist/services/board/report-capture.d.ts +94 -0
  379. package/dist/services/board/report-capture.d.ts.map +1 -0
  380. package/dist/services/board/report-capture.js +398 -0
  381. package/dist/services/board/report-capture.js.map +1 -0
  382. package/dist/services/board/worker-spawn.d.ts +89 -0
  383. package/dist/services/board/worker-spawn.d.ts.map +1 -0
  384. package/dist/services/board/worker-spawn.js +177 -0
  385. package/dist/services/board/worker-spawn.js.map +1 -0
  386. package/dist/services/board/worktree.d.ts +45 -0
  387. package/dist/services/board/worktree.d.ts.map +1 -0
  388. package/dist/services/board/worktree.js +183 -0
  389. package/dist/services/board/worktree.js.map +1 -0
  390. package/dist/services/broker-client.d.ts +84 -2
  391. package/dist/services/broker-client.d.ts.map +1 -1
  392. package/dist/services/broker-client.js +72 -6
  393. package/dist/services/broker-client.js.map +1 -1
  394. package/dist/services/claude-spawn.service.d.ts +5 -0
  395. package/dist/services/claude-spawn.service.d.ts.map +1 -1
  396. package/dist/services/claude-spawn.service.js +37 -21
  397. package/dist/services/claude-spawn.service.js.map +1 -1
  398. package/dist/services/codex-spawn.service.d.ts +8 -3
  399. package/dist/services/codex-spawn.service.d.ts.map +1 -1
  400. package/dist/services/codex-spawn.service.js +84 -67
  401. package/dist/services/codex-spawn.service.js.map +1 -1
  402. package/dist/services/consolidation.service.d.ts.map +1 -1
  403. package/dist/services/consolidation.service.js +5 -49
  404. package/dist/services/consolidation.service.js.map +1 -1
  405. package/dist/services/copilot-spawn.service.d.ts +1 -1
  406. package/dist/services/copilot-spawn.service.d.ts.map +1 -1
  407. package/dist/services/copilot-spawn.service.js +10 -5
  408. package/dist/services/copilot-spawn.service.js.map +1 -1
  409. package/dist/services/daily-session.d.ts +24 -11
  410. package/dist/services/daily-session.d.ts.map +1 -1
  411. package/dist/services/daily-session.js +113 -33
  412. package/dist/services/daily-session.js.map +1 -1
  413. package/dist/services/death-alert.service.d.ts +55 -0
  414. package/dist/services/death-alert.service.d.ts.map +1 -0
  415. package/dist/services/death-alert.service.js +64 -0
  416. package/dist/services/death-alert.service.js.map +1 -0
  417. package/dist/services/dispatcher/broker.d.ts +66 -0
  418. package/dist/services/dispatcher/broker.d.ts.map +1 -1
  419. package/dist/services/dispatcher/broker.js +60 -52
  420. package/dist/services/dispatcher/broker.js.map +1 -1
  421. package/dist/services/dispatcher/poller.d.ts.map +1 -1
  422. package/dist/services/dispatcher/poller.js +31 -24
  423. package/dist/services/dispatcher/poller.js.map +1 -1
  424. package/dist/services/http-retry.d.ts +1 -90
  425. package/dist/services/http-retry.d.ts.map +1 -1
  426. package/dist/services/http-retry.js +1 -176
  427. package/dist/services/http-retry.js.map +1 -1
  428. package/dist/services/intent.d.ts +15 -1
  429. package/dist/services/intent.d.ts.map +1 -1
  430. package/dist/services/intent.js +39 -27
  431. package/dist/services/intent.js.map +1 -1
  432. package/dist/services/keeper.service.d.ts +76 -3
  433. package/dist/services/keeper.service.d.ts.map +1 -1
  434. package/dist/services/keeper.service.js +112 -35
  435. package/dist/services/keeper.service.js.map +1 -1
  436. package/dist/services/mcp-config.service.d.ts.map +1 -1
  437. package/dist/services/mcp-config.service.js +14 -1
  438. package/dist/services/mcp-config.service.js.map +1 -1
  439. package/dist/services/memory-briefing.service.d.ts +1 -1
  440. package/dist/services/memory-briefing.service.d.ts.map +1 -1
  441. package/dist/services/memory-briefing.service.js +28 -73
  442. package/dist/services/memory-briefing.service.js.map +1 -1
  443. package/dist/services/passive-notice.service.d.ts +56 -0
  444. package/dist/services/passive-notice.service.d.ts.map +1 -0
  445. package/dist/services/passive-notice.service.js +92 -0
  446. package/dist/services/passive-notice.service.js.map +1 -0
  447. package/dist/services/predefined-prompts.d.ts +11 -0
  448. package/dist/services/predefined-prompts.d.ts.map +1 -0
  449. package/dist/services/predefined-prompts.js +25 -0
  450. package/dist/services/predefined-prompts.js.map +1 -0
  451. package/dist/services/process.service.d.ts +111 -27
  452. package/dist/services/process.service.d.ts.map +1 -1
  453. package/dist/services/process.service.js +245 -173
  454. package/dist/services/process.service.js.map +1 -1
  455. package/dist/services/spawn-common.d.ts +281 -5
  456. package/dist/services/spawn-common.d.ts.map +1 -1
  457. package/dist/services/spawn-common.js +884 -188
  458. package/dist/services/spawn-common.js.map +1 -1
  459. package/dist/services/spawn-exit-watcher.d.ts +45 -35
  460. package/dist/services/spawn-exit-watcher.d.ts.map +1 -1
  461. package/dist/services/spawn-exit-watcher.js +120 -100
  462. package/dist/services/spawn-exit-watcher.js.map +1 -1
  463. package/dist/services/telegram.d.ts +31 -8
  464. package/dist/services/telegram.d.ts.map +1 -1
  465. package/dist/services/telegram.js +58 -26
  466. package/dist/services/telegram.js.map +1 -1
  467. package/dist/services/thread-health.service.d.ts +8 -0
  468. package/dist/services/thread-health.service.d.ts.map +1 -1
  469. package/dist/services/thread-health.service.js +14 -10
  470. package/dist/services/thread-health.service.js.map +1 -1
  471. package/dist/services/thread-lifecycle.service.d.ts +17 -1
  472. package/dist/services/thread-lifecycle.service.d.ts.map +1 -1
  473. package/dist/services/thread-lifecycle.service.js +47 -6
  474. package/dist/services/thread-lifecycle.service.js.map +1 -1
  475. package/dist/services/thread-log-reader.d.ts +81 -0
  476. package/dist/services/thread-log-reader.d.ts.map +1 -0
  477. package/dist/services/thread-log-reader.js +141 -0
  478. package/dist/services/thread-log-reader.js.map +1 -0
  479. package/dist/services/thread-purge.service.d.ts +200 -0
  480. package/dist/services/thread-purge.service.d.ts.map +1 -0
  481. package/dist/services/thread-purge.service.js +644 -0
  482. package/dist/services/thread-purge.service.js.map +1 -0
  483. package/dist/services/topic.service.d.ts +44 -2
  484. package/dist/services/topic.service.d.ts.map +1 -1
  485. package/dist/services/topic.service.js +74 -13
  486. package/dist/services/topic.service.js.map +1 -1
  487. package/dist/services/usage/usage-inbox-notifier.d.ts +50 -0
  488. package/dist/services/usage/usage-inbox-notifier.d.ts.map +1 -0
  489. package/dist/services/usage/usage-inbox-notifier.js +118 -0
  490. package/dist/services/usage/usage-inbox-notifier.js.map +1 -0
  491. package/dist/services/usage/usage-poller.service.d.ts +41 -0
  492. package/dist/services/usage/usage-poller.service.d.ts.map +1 -0
  493. package/dist/services/usage/usage-poller.service.js +67 -0
  494. package/dist/services/usage/usage-poller.service.js.map +1 -0
  495. package/dist/services/usage/usage-snapshot-provider.d.ts +40 -0
  496. package/dist/services/usage/usage-snapshot-provider.d.ts.map +1 -0
  497. package/dist/services/usage/usage-snapshot-provider.js +89 -0
  498. package/dist/services/usage/usage-snapshot-provider.js.map +1 -0
  499. package/dist/services/usage/usage-types.d.ts +28 -0
  500. package/dist/services/usage/usage-types.d.ts.map +1 -0
  501. package/dist/services/usage/usage-types.js +14 -0
  502. package/dist/services/usage/usage-types.js.map +1 -0
  503. package/dist/services/worker-birth.d.ts +154 -0
  504. package/dist/services/worker-birth.d.ts.map +1 -0
  505. package/dist/services/worker-birth.js +274 -0
  506. package/dist/services/worker-birth.js.map +1 -0
  507. package/dist/services/worker-cleanup.service.d.ts +242 -19
  508. package/dist/services/worker-cleanup.service.d.ts.map +1 -1
  509. package/dist/services/worker-cleanup.service.js +893 -355
  510. package/dist/services/worker-cleanup.service.js.map +1 -1
  511. package/dist/services/worker-lifecycle-executor.d.ts +42 -0
  512. package/dist/services/worker-lifecycle-executor.d.ts.map +1 -0
  513. package/dist/services/worker-lifecycle-executor.js +63 -0
  514. package/dist/services/worker-lifecycle-executor.js.map +1 -0
  515. package/dist/services/worker-single-use.d.ts +92 -0
  516. package/dist/services/worker-single-use.d.ts.map +1 -0
  517. package/dist/services/worker-single-use.js +155 -0
  518. package/dist/services/worker-single-use.js.map +1 -0
  519. package/dist/sessions/mcp-registry.d.ts +33 -2
  520. package/dist/sessions/mcp-registry.d.ts.map +1 -1
  521. package/dist/sessions/mcp-registry.js +153 -30
  522. package/dist/sessions/mcp-registry.js.map +1 -1
  523. package/dist/test-bootstrap.d.ts +19 -12
  524. package/dist/test-bootstrap.d.ts.map +1 -1
  525. package/dist/test-bootstrap.js +69 -21
  526. package/dist/test-bootstrap.js.map +1 -1
  527. package/dist/test-tripwire.test-support.d.ts +75 -0
  528. package/dist/test-tripwire.test-support.d.ts.map +1 -0
  529. package/dist/test-tripwire.test-support.js +353 -0
  530. package/dist/test-tripwire.test-support.js.map +1 -0
  531. package/dist/tools/defs/memory-defs.d.ts.map +1 -1
  532. package/dist/tools/defs/memory-defs.js +12 -4
  533. package/dist/tools/defs/memory-defs.js.map +1 -1
  534. package/dist/tools/defs/session-defs.d.ts.map +1 -1
  535. package/dist/tools/defs/session-defs.js +26 -10
  536. package/dist/tools/defs/session-defs.js.map +1 -1
  537. package/dist/tools/defs/utility-defs.js +1 -1
  538. package/dist/tools/defs/utility-defs.js.map +1 -1
  539. package/dist/tools/delegate-tool.d.ts +81 -1
  540. package/dist/tools/delegate-tool.d.ts.map +1 -1
  541. package/dist/tools/delegate-tool.js +840 -219
  542. package/dist/tools/delegate-tool.js.map +1 -1
  543. package/dist/tools/memory-tools.d.ts.map +1 -1
  544. package/dist/tools/memory-tools.js +66 -9
  545. package/dist/tools/memory-tools.js.map +1 -1
  546. package/dist/tools/response-builders.d.ts.map +1 -1
  547. package/dist/tools/response-builders.js +12 -8
  548. package/dist/tools/response-builders.js.map +1 -1
  549. package/dist/tools/session-tools.d.ts.map +1 -1
  550. package/dist/tools/session-tools.js +3 -32
  551. package/dist/tools/session-tools.js.map +1 -1
  552. package/dist/tools/skill-tools.js +1 -1
  553. package/dist/tools/skill-tools.js.map +1 -1
  554. package/dist/tools/start-session-tool.d.ts.map +1 -1
  555. package/dist/tools/start-session-tool.js +66 -20
  556. package/dist/tools/start-session-tool.js.map +1 -1
  557. package/dist/tools/utility-tools.d.ts.map +1 -1
  558. package/dist/tools/utility-tools.js +38 -3
  559. package/dist/tools/utility-tools.js.map +1 -1
  560. package/dist/tools/wait/auto-forward.d.ts.map +1 -1
  561. package/dist/tools/wait/auto-forward.js +8 -3
  562. package/dist/tools/wait/auto-forward.js.map +1 -1
  563. package/dist/tools/wait/consolidation-strategy.d.ts +42 -0
  564. package/dist/tools/wait/consolidation-strategy.d.ts.map +1 -0
  565. package/dist/tools/wait/consolidation-strategy.js +50 -0
  566. package/dist/tools/wait/consolidation-strategy.js.map +1 -0
  567. package/dist/tools/wait/drive-handler.d.ts +5 -7
  568. package/dist/tools/wait/drive-handler.d.ts.map +1 -1
  569. package/dist/tools/wait/drive-handler.js +45 -59
  570. package/dist/tools/wait/drive-handler.js.map +1 -1
  571. package/dist/tools/wait/media-processor.d.ts.map +1 -1
  572. package/dist/tools/wait/media-processor.js +8 -4
  573. package/dist/tools/wait/media-processor.js.map +1 -1
  574. package/dist/tools/wait/message-delivery.d.ts +9 -6
  575. package/dist/tools/wait/message-delivery.d.ts.map +1 -1
  576. package/dist/tools/wait/message-delivery.js +77 -58
  577. package/dist/tools/wait/message-delivery.js.map +1 -1
  578. package/dist/tools/wait/message-processing.d.ts.map +1 -1
  579. package/dist/tools/wait/message-processing.js +2 -1
  580. package/dist/tools/wait/message-processing.js.map +1 -1
  581. package/dist/tools/wait/poll-loop.d.ts.map +1 -1
  582. package/dist/tools/wait/poll-loop.js +339 -239
  583. package/dist/tools/wait/poll-loop.js.map +1 -1
  584. package/package.json +4 -3
  585. package/templates/azure-devops-securevault.default.md +20 -6
  586. package/templates/board-quality-checklist.default.md +121 -0
  587. package/templates/buildless-vue-preview.default.md +47 -0
  588. package/templates/expert-code-review.default.md +12 -0
  589. package/templates/handoff.default.md +41 -18
  590. package/templates/increment-pr-pipeline.default.md +79 -0
  591. package/templates/swarm.default.md +1 -0
  592. package/templates/worker-autonomous.default.md +1 -0
  593. package/templates/worker-delegate.default.md +1 -0
  594. package/dist/dashboard/log-parser.d.ts +0 -65
  595. package/dist/dashboard/log-parser.d.ts.map +0 -1
  596. package/dist/dashboard/log-parser.js +0 -219
  597. package/dist/dashboard/log-parser.js.map +0 -1
  598. package/dist/data/memory/reflection-dedup.d.ts +0 -17
  599. package/dist/data/memory/reflection-dedup.d.ts.map +0 -1
  600. package/dist/data/memory/reflection-dedup.js +0 -55
  601. package/dist/data/memory/reflection-dedup.js.map +0 -1
  602. package/dist/data/memory/reflection-gates.d.ts +0 -40
  603. package/dist/data/memory/reflection-gates.d.ts.map +0 -1
  604. package/dist/data/memory/reflection-gates.js +0 -220
  605. package/dist/data/memory/reflection-gates.js.map +0 -1
  606. package/dist/data/memory/reflection-sources.d.ts +0 -13
  607. package/dist/data/memory/reflection-sources.d.ts.map +0 -1
  608. package/dist/data/memory/reflection-sources.js +0 -115
  609. package/dist/data/memory/reflection-sources.js.map +0 -1
  610. package/dist/data/memory/reflection.d.ts +0 -43
  611. package/dist/data/memory/reflection.d.ts.map +0 -1
  612. package/dist/data/memory/reflection.js +0 -329
  613. package/dist/data/memory/reflection.js.map +0 -1
  614. package/dist/llm/prompts/reflection.d.ts +0 -6
  615. package/dist/llm/prompts/reflection.d.ts.map +0 -1
  616. package/dist/llm/prompts/reflection.js +0 -77
  617. package/dist/llm/prompts/reflection.js.map +0 -1
  618. package/dist/services/memory-pruning.service.d.ts +0 -12
  619. package/dist/services/memory-pruning.service.d.ts.map +0 -1
  620. package/dist/services/memory-pruning.service.js +0 -179
  621. package/dist/services/memory-pruning.service.js.map +0 -1
  622. package/templates/daily-review.default.md +0 -26
  623. package/templates/fire-and-forget.default.md +0 -76
  624. package/templates/offload.default.md +0 -33
  625. package/templates/sensorium-repair.default.md +0 -114
@@ -0,0 +1,32 @@
1
+ /**
2
+ * rate_limited helpers — ✅ EDITABLE. Shared by Card tile, Lane badge and the
3
+ * card detail notice. Pure functions: card in, display strings out.
4
+ */
5
+
6
+ export const PROVIDER_LABELS = {
7
+ claude: "Claude",
8
+ copilot: "Copilot",
9
+ codex: "Codex",
10
+ fable: "Fable",
11
+ };
12
+
13
+ /** Proactive usage limit marker for a queued card; reactive cards remain untouched. */
14
+ export function proactiveLimitKind(card, limitedProviders) {
15
+ const provider = card.profile?.agentType;
16
+ return card.status === "backlog" && limitedProviders.includes(provider)
17
+ ? "usage_quota_exceeded"
18
+ : "";
19
+ }
20
+
21
+ /** Live countdown text derived from retryAt (null = unknown reset window). */
22
+ export function retryLabel(card, now = Date.now()) {
23
+ if (!card.retryAt) return "retrying when limit resets";
24
+ const mins = Math.ceil((new Date(card.retryAt).getTime() - now) / 60000);
25
+ if (mins <= 0) return "retrying\u2026";
26
+ if (mins >= 60) return `retry in ~${Math.floor(mins / 60)}h ${mins % 60}m`;
27
+ return `retry in ~${mins}m`;
28
+ }
29
+
30
+ export function providerLabel(agentType) {
31
+ return PROVIDER_LABELS[agentType] || "";
32
+ }
@@ -0,0 +1,16 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import { proactiveLimitKind } from "./rateLimit.js";
4
+
5
+ test("backlog card gets the proactive usage-quota chip only for a limited provider", () => {
6
+ const card = { status: "backlog", profile: { agentType: "codex" } };
7
+
8
+ assert.equal(proactiveLimitKind(card, ["codex"]), "usage_quota_exceeded");
9
+ assert.equal(proactiveLimitKind(card, ["claude"]), "");
10
+ });
11
+
12
+ test("proactive usage-quota chip does not replace reactive rate-limited rendering", () => {
13
+ const card = { status: "rate_limited", profile: { agentType: "codex" } };
14
+
15
+ assert.equal(proactiveLimitKind(card, ["codex"]), "");
16
+ });
@@ -0,0 +1,14 @@
1
+ /** Minutes since an ISO timestamp (0 when absent/unparseable). */
2
+ export function minsSince(iso) {
3
+ if (!iso) return 0;
4
+ const t = new Date(iso).getTime();
5
+ if (Number.isNaN(t)) return 0;
6
+ return Math.max(0, Math.round((Date.now() - t) / 60000));
7
+ }
8
+
9
+ export function humanMins(mins) {
10
+ if (mins < 60) return mins + "m";
11
+ const h = Math.floor(mins / 60);
12
+ if (h < 24) return h + "h " + (mins % 60) + "m";
13
+ return Math.floor(h / 24) + "d " + (h % 24) + "h";
14
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Board-front runtime config. ❌ FROZEN SEAM — do NOT edit during UI iteration.
3
+ *
4
+ * MODE selects the data adapter downstream (see api/api.js):
5
+ * 'production' → real fetch to the board API through the Dev Tunnel.
6
+ * 'preview' → mock adapter over fixtures (Claude Design sandbox), so EVERY
7
+ * screen renders with zero real network calls.
8
+ */
9
+
10
+ /**
11
+ * Canonical card statuses — mirror of src/data/board/board-types.ts `CardStatus`
12
+ * plus the P2 `decision_needed` value the kanban reserves a column for now so the
13
+ * skeleton lane exists before the backend migration lands.
14
+ */
15
+ export const CARD_STATUSES = ["backlog", "in_progress", "decision_needed", "blocked", "done"];
16
+
17
+ /** Board poll cadence while the browser tab is visible (ms). */
18
+ export const POLL_INTERVAL_MS = 5000;
19
+
20
+ /**
21
+ * All API calls are same-origin, ROOT-RELATIVE (`/api/...`) — safe behind any
22
+ * reverse proxy / Cloudflare Tunnel. No host or port is ever hardcoded.
23
+ */
24
+ export const API_BASE = "";
25
+
26
+ function readOverride() {
27
+ try {
28
+ const q = new URLSearchParams(location.search);
29
+ const qMode = q.get("mode") ?? (q.has("preview") ? "preview" : null);
30
+ if (qMode === "preview" || qMode === "production") return qMode;
31
+ const stored = localStorage.getItem("BOARD_MODE");
32
+ if (stored === "preview" || stored === "production") return stored;
33
+ } catch {
34
+ /* sandbox without URL/localStorage — fall through to auto-detect */
35
+ }
36
+ return null;
37
+ }
38
+
39
+ /**
40
+ * Auto-detect the run mode.
41
+ * 1. explicit `?mode=` / `?preview` / localStorage override wins (the design
42
+ * tool can force either without editing this file).
43
+ * 2. non-http(s) origin (file: / blob: / data:) → sandbox → preview.
44
+ * 3. http(s) served under `/board` by our server → production.
45
+ * 4. anything else (an artifact host serving at `/`) → preview.
46
+ */
47
+ export function detectMode() {
48
+ const override = readOverride();
49
+ if (override) return override;
50
+ const proto = typeof location !== "undefined" ? location.protocol : "file:";
51
+ if (proto !== "http:" && proto !== "https:") return "preview";
52
+ const path = (typeof location !== "undefined" && location.pathname) || "/";
53
+ return path.startsWith("/board") ? "production" : "preview";
54
+ }
55
+
56
+ export const MODE = detectMode();
@@ -0,0 +1,18 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
6
+ <meta name="color-scheme" content="dark" />
7
+ <meta name="theme-color" content="#15141d" />
8
+ <title>Dispatch — Agent Task Board</title>
9
+ <!-- ✅ styles/ is editable by Claude Design. -->
10
+ <link rel="stylesheet" href="./styles/tokens.css" />
11
+ <link rel="stylesheet" href="./styles/board.css" />
12
+ </head>
13
+ <body>
14
+ <div id="app"></div>
15
+ <!-- ❌ main.js is the frozen entry/router. -->
16
+ <script type="module" src="./main.js"></script>
17
+ </body>
18
+ </html>
@@ -0,0 +1,37 @@
1
+ /**
2
+ * App entry + hash router. ❌ FROZEN SEAM (entry/router wiring only).
3
+ *
4
+ * Provides a minimal reactive router to the app under the inject key 'router'.
5
+ * Views consume it via `inject('router')` and never import this file:
6
+ * router.current = { name, params, path } // name ∈ board|card|new|settings
7
+ * router.navigate('/card/12') // sets location.hash
8
+ *
9
+ * A hash router (not history routing) is deliberate: the same file set runs from
10
+ * file:// in the design sandbox AND under /board in production with no server-side
11
+ * route table for client paths.
12
+ */
13
+
14
+ import { createApp, reactive } from "./vendor/vue.esm-browser.js";
15
+ import App from "./views/App.js";
16
+
17
+ function parseHash() {
18
+ const raw = (location.hash || "#/board").replace(/^#/, "");
19
+ const path = raw.split("?")[0];
20
+ const parts = path.split("/").filter(Boolean);
21
+ if (parts[0] === "card" && parts[1]) return { name: "card", params: { id: Number(parts[1]) }, path };
22
+ if (parts[0] === "new") return { name: "new", params: {}, path };
23
+ if (parts[0] === "settings") return { name: "settings", params: {}, path };
24
+ return { name: "board", params: {}, path: "/board" };
25
+ }
26
+
27
+ const router = reactive({ current: parseHash() });
28
+ router.navigate = (to) => {
29
+ location.hash = to.startsWith("#") ? to : `#${to}`;
30
+ };
31
+ window.addEventListener("hashchange", () => {
32
+ router.current = parseHash();
33
+ });
34
+
35
+ const app = createApp(App);
36
+ app.provide("router", router);
37
+ app.mount("#app");
@@ -0,0 +1,491 @@
1
+ /**
2
+ * Preview data adapter. ❌ FROZEN SEAM. Dynamically imported ONLY when
3
+ * MODE==='preview' (api/api.js) — no mock byte ships to production.
4
+ *
5
+ * An in-memory store over fixtures that implements the full BoardApi surface,
6
+ * including mutations, so create / move / stop / comment / archive / delete all
7
+ * work standalone in the design sandbox with ZERO real network calls.
8
+ *
9
+ * Extra design affordances (query string, preview only):
10
+ * ?mock=empty → the board renders its empty state.
11
+ * ?mock=error → list calls reject so the error state is visible.
12
+ *
13
+ * @typedef {import('../api/contract.js').BoardApi} BoardApi
14
+ */
15
+
16
+ import { fixtures, dirTree } from "./fixtures.js";
17
+ import { POLICY_SCHEMA, PRESETS } from "../schema/policy.js";
18
+
19
+ const clone = (x) => JSON.parse(JSON.stringify(x));
20
+ const OPERATOR_STATUS_TARGETS = ["backlog", "done"];
21
+ const PROFILE_FIELDS = new Set([
22
+ "repository", "createBranch", "skills", "operatorReview", "openPr", "prDraft",
23
+ "verifyDone", "prProvider", "expertReview", "reviewAgentType", "workerSplit",
24
+ "agentType", "model", "memory", "worktree", "autonomy", "phases", "size",
25
+ "runTests", "build", "push", "ciCheck", "inline", "ttlMinutes",
26
+ ]);
27
+ const PROFILE_ENUMS = {
28
+ prProvider: ["Auto", "GitHub", "Azure DevOps"],
29
+ reviewAgentType: ["claude", "copilot", "codex", "fable"],
30
+ workerSplit: ["single", "multi"], agentType: ["claude", "copilot", "codex", "fable"],
31
+ autonomy: ["Autonomous", "Checkpoints", "Collaborative"], size: ["operational", "code"],
32
+ ciCheck: ["none", "github", "azure"],
33
+ };
34
+
35
+ function httpError(status, message) {
36
+ const error = new Error(message);
37
+ error.status = status;
38
+ return error;
39
+ }
40
+
41
+ function validateProfile(profile) {
42
+ if (profile === null || typeof profile !== "object" || Array.isArray(profile)) return "profile must be a JSON object";
43
+ for (const key of Object.keys(profile)) if (!PROFILE_FIELDS.has(key)) return `unknown profile field '${key}'`;
44
+ for (const field of ["repository", "model"])
45
+ if (field in profile && typeof profile[field] !== "string") return `'${field}' must be a string`;
46
+ for (const field of ["createBranch", "operatorReview", "openPr", "prDraft", "verifyDone", "expertReview", "worktree", "runTests", "build", "push", "inline"])
47
+ if (field in profile && typeof profile[field] !== "boolean") return `'${field}' must be a boolean`;
48
+ if ("skills" in profile && (!Array.isArray(profile.skills) || !profile.skills.every((x) => typeof x === "string"))) return "'skills' must be an array of strings";
49
+ if ("memory" in profile) {
50
+ const memory = profile.memory;
51
+ if (memory === null || typeof memory !== "object" || Array.isArray(memory)) return "'memory' must be a JSON object";
52
+ if (Object.keys(memory).some((key) => !["mode", "threadId"].includes(key))) return "unknown memory field";
53
+ if (!["Ephemeral", "Existing thread"].includes(memory.mode)) return `Unknown memory mode '${String(memory.mode)}' — allowed: Ephemeral, Existing thread`;
54
+ if ("threadId" in memory && memory.threadId !== null && typeof memory.threadId !== "number") return "'memory.threadId' must be a number or null";
55
+ if (memory.mode === "Existing thread" && typeof memory.threadId !== "number") return "'memory.threadId' is required for Existing thread";
56
+ }
57
+ if ("phases" in profile) {
58
+ if (!Array.isArray(profile.phases)) return "'phases' must be an array";
59
+ for (const phase of profile.phases) {
60
+ if (phase === null || typeof phase !== "object" || Array.isArray(phase)) return "each phase must be a JSON object";
61
+ if (Object.keys(phase).some((key) => !["name", "review", "provider", "model"].includes(key))) return "unknown phase field";
62
+ if (["name", "review", "provider", "model"].some((key) => !(key in phase))) return "phase field is required";
63
+ if (typeof phase.name !== "string" || !phase.name.trim()) return "phase 'name' must be non-empty";
64
+ if (typeof phase.review !== "boolean") return "phase 'review' must be a boolean";
65
+ if (typeof phase.model !== "string") return "phase 'model' must be a string";
66
+ if (!["Inherit", "Claude", "Copilot", "Codex"].includes(phase.provider)) return `Unknown phase provider '${String(phase.provider)}' — allowed: Inherit, Claude, Copilot, Codex`;
67
+ }
68
+ }
69
+ if ("ttlMinutes" in profile && (typeof profile.ttlMinutes !== "number" || !Number.isFinite(profile.ttlMinutes))) return "'ttlMinutes' must be a number";
70
+ for (const [field, values] of Object.entries(PROFILE_ENUMS))
71
+ if (field in profile && (typeof profile[field] !== "string" || !values.includes(profile[field]))) return `Unknown ${field} '${String(profile[field])}' — allowed: ${values.join(", ")}`;
72
+ return null;
73
+ }
74
+
75
+ function parseRecurDelay(value) {
76
+ if (value === null || value === undefined || value === "") return null;
77
+ const parsed = typeof value === "number" ? value : Number(value);
78
+ if (!Number.isInteger(parsed)) return undefined;
79
+ return parsed >= 1 ? parsed : null;
80
+ }
81
+
82
+ /** Depth-first lookup of a node by absolute path in the preview dir tree. */
83
+ function locateDir(nodes, path) {
84
+ for (const n of nodes || []) {
85
+ if (n.path === path) return n;
86
+ const hit = locateDir(n.children, path);
87
+ if (hit) return hit;
88
+ }
89
+ return null;
90
+ }
91
+
92
+ /** Best-effort parent of an absolute path (null at a drive/volume root). */
93
+ function parentDir(path) {
94
+ const trimmed = path.replace(/[\\/]+$/, "");
95
+ const cut = Math.max(trimmed.lastIndexOf("\\"), trimmed.lastIndexOf("/"));
96
+ if (cut <= 1) return null;
97
+ const parent = trimmed.slice(0, cut);
98
+ return /^[A-Za-z]:$/.test(parent) ? `${parent}\\` : parent;
99
+ }
100
+
101
+ /**
102
+ * Preview-only stand-in for the server's renderProfileDirectives: an HONEST but
103
+ * intentionally partial subset, enough that the compiled-policy panel visibly
104
+ * changes as the draft's profile changes offline. Not the full server renderer.
105
+ */
106
+ function previewDirectives(profile) {
107
+ const d = [];
108
+ if (profile.repository) d.push(`Work in repository: ${profile.repository}.`);
109
+ d.push(
110
+ profile.createBranch
111
+ ? "Create a work branch before changing anything."
112
+ : "Do NOT create a new branch unless the current branch is unusable.",
113
+ );
114
+ if (profile.skills && profile.skills.length)
115
+ d.push(`Load these skills via get_skill first: ${profile.skills.join(", ")}.`);
116
+ if (profile.autonomy) d.push(`Autonomy: ${profile.autonomy}.`);
117
+ if (profile.phases && profile.phases.length)
118
+ d.push(
119
+ `Execute in ${profile.phases.length} ordered phase(s): ${profile.phases.map((p) => p.name).join(" → ")}.`,
120
+ );
121
+ d.push(
122
+ profile.runTests
123
+ ? "Run the relevant tests and make them pass."
124
+ : "Do not run test suites unless a change demands it.",
125
+ );
126
+ d.push(profile.push ? "Push your commits." : "Do NOT push.");
127
+ if (profile.openPr) {
128
+ const target =
129
+ profile.prProvider && profile.prProvider !== "Auto" ? profile.prProvider : "the repo remote";
130
+ d.push(
131
+ `Open a ${profile.prDraft === false ? "ready" : "draft"} pull request targeting ${target}.`,
132
+ );
133
+ } else {
134
+ d.push("Do NOT open a pull request.");
135
+ }
136
+ if (profile.verifyDone)
137
+ d.push("Independently verify the acceptance criteria before reporting DONE.");
138
+ return d;
139
+ }
140
+
141
+ const scenario = (() => {
142
+ try {
143
+ return new URLSearchParams(location.search).get("mock") || "default";
144
+ } catch {
145
+ return "default";
146
+ }
147
+ })();
148
+
149
+ const delay = (v) => new Promise((r) => setTimeout(() => r(v), 120));
150
+ const nowIso = () => new Date().toISOString();
151
+
152
+ function guardScenario() {
153
+ if (scenario === "error") throw httpError(500, "Simulated preview error (?mock=error)");
154
+ }
155
+
156
+ /** @returns {BoardApi} */
157
+ export function createMockApi() {
158
+ const db = {
159
+ laneGroups: clone(fixtures.laneGroups),
160
+ cards: scenario === "empty" ? [] : clone(fixtures.cards),
161
+ comments: clone(fixtures.comments),
162
+ profiles: clone(fixtures.profiles),
163
+ seq: 1000,
164
+ };
165
+ const find = (id) => db.cards.find((c) => c.cardId === id);
166
+ const findLaneGroup = (id) => db.laneGroups.find((group) => group.groupId === id);
167
+ const findProfile = (idOrName) =>
168
+ db.profiles.find((profile) => profile.id === idOrName || profile.name === idOrName);
169
+ const resolveProfile = (input) => {
170
+ const profileError = input.profile === undefined ? null : validateProfile(input.profile);
171
+ if (profileError) throw httpError(400, profileError);
172
+ const requestedId = input.profileId || "default";
173
+ const namedProfile = findProfile(requestedId);
174
+ if (!namedProfile) throw httpError(400, `Unknown profile '${requestedId}'`);
175
+ return { id: namedProfile.id, profile: { ...namedProfile.profile, ...input.profile } };
176
+ };
177
+
178
+ return {
179
+ async listCards({ includeArchived = false } = {}) {
180
+ await delay();
181
+ guardScenario();
182
+ let cards = db.cards.filter((c) => (includeArchived ? true : !c.archivedAt));
183
+ return clone({ cards, limitedProviders: [] });
184
+ },
185
+
186
+ async getCard(id) {
187
+ await delay();
188
+ const card = find(id);
189
+ if (!card) throw httpError(404, `Card ${id} not found`);
190
+ return clone({ card, comments: db.comments[id] || [] });
191
+ },
192
+
193
+ async createCard(input) {
194
+ await delay();
195
+ if (!input.title || !input.title.trim()) throw httpError(400, "'title' is required");
196
+ if (input.laneGroupId != null && !findLaneGroup(input.laneGroupId)) {
197
+ const status = Number.isInteger(input.laneGroupId) ? 404 : 400;
198
+ throw httpError(status, `Lane group ${input.laneGroupId} not found`);
199
+ }
200
+ const recurDelayMin = parseRecurDelay(input.recurDelayMin);
201
+ if (recurDelayMin === undefined)
202
+ throw httpError(400, "'recurDelayMin' must be an integer ≥ 1 (or empty to disable)");
203
+ const resolvedProfile = resolveProfile(input);
204
+ const id = ++db.seq;
205
+ const card = {
206
+ cardId: id,
207
+ correlationId: input.correlationId || crypto.randomUUID(),
208
+ title: input.title.trim(),
209
+ description: input.description || "",
210
+ acceptance: input.acceptance || "",
211
+ profileId: resolvedProfile.id,
212
+ laneGroupId: input.laneGroupId ?? null,
213
+ priority: input.priority || 0,
214
+ status: "backlog",
215
+ profile: resolvedProfile.profile,
216
+ escalate: input.escalate === true,
217
+ recurDelayMin,
218
+ recurGroupId: null,
219
+ nextSpawnAt: null,
220
+ workerThreadId: null,
221
+ operatorReleasing: false,
222
+ blockedReason: null,
223
+ ask: null,
224
+ rateLimitProvider: null,
225
+ retryAt: null,
226
+ archivedAt: null,
227
+ createdAt: nowIso(),
228
+ updatedAt: nowIso(),
229
+ startedAt: null,
230
+ finishedAt: null,
231
+ };
232
+ db.cards.push(card);
233
+ return clone(card);
234
+ },
235
+
236
+ async previewBriefing(draft) {
237
+ await delay();
238
+ const { profile } = resolveProfile(draft);
239
+ const lines = [];
240
+ lines.push(`# Task Board card (preview): ${(draft.title || "").trim() || "(untitled)"}`);
241
+ lines.push(`Priority: ${draft.priority ?? 0}`);
242
+ lines.push("");
243
+ lines.push("## Description");
244
+ lines.push((draft.description || "").trim() || "(none — the title is the task)");
245
+ if ((draft.acceptance || "").trim()) {
246
+ lines.push("");
247
+ lines.push("## Acceptance criteria");
248
+ lines.push(draft.acceptance.trim());
249
+ }
250
+ lines.push("");
251
+ lines.push("## Standing orders (execution profile)");
252
+ for (const directive of previewDirectives(profile)) lines.push(`- ${directive}`);
253
+ return lines.join("\n");
254
+ },
255
+
256
+ async updateCard(id, patch) {
257
+ await delay();
258
+ const card = find(id);
259
+ if (!card) throw httpError(404, `Card ${id} not found`);
260
+ if (patch.laneGroupId != null && !findLaneGroup(patch.laneGroupId)) {
261
+ const status = Number.isInteger(patch.laneGroupId) ? 404 : 400;
262
+ throw httpError(status, `Lane group ${patch.laneGroupId} not found`);
263
+ }
264
+ if (patch.status && patch.status !== card.status && !OPERATOR_STATUS_TARGETS.includes(patch.status))
265
+ throw httpError(400, "Operator moves may only target backlog/done — in_progress and blocked are set by the board itself");
266
+ const recurDelayMin = "recurDelayMin" in patch ? parseRecurDelay(patch.recurDelayMin) : undefined;
267
+ if (recurDelayMin === undefined && "recurDelayMin" in patch)
268
+ throw httpError(400, "'recurDelayMin' must be an integer ≥ 1 (or empty to disable)");
269
+ const existingRecurDelayMin = card.recurDelayMin;
270
+ const wasNonRecurring = existingRecurDelayMin === null && card.recurGroupId === null;
271
+ const resolvedProfile = typeof patch.profileId === "string" ? resolveProfile(patch) : null;
272
+ const profileError = patch.profile === undefined ? null : validateProfile(patch.profile);
273
+ if (profileError) throw httpError(400, profileError);
274
+ if ("archivedAt" in patch) card.archivedAt = patch.archivedAt === null ? null : nowIso();
275
+ for (const k of [
276
+ "title",
277
+ "description",
278
+ "acceptance",
279
+ "laneGroupId",
280
+ "priority",
281
+ "escalate",
282
+ "status",
283
+ ]) {
284
+ if (k in patch && patch[k] !== undefined) card[k] = patch[k];
285
+ }
286
+ if (resolvedProfile) {
287
+ card.profileId = resolvedProfile.id;
288
+ card.profile = resolvedProfile.profile;
289
+ }
290
+ if (patch.profile !== undefined) card.profile = patch.profile;
291
+ if (recurDelayMin !== undefined) card.recurDelayMin = recurDelayMin;
292
+ if (recurDelayMin !== undefined && recurDelayMin === null) card.nextSpawnAt = null;
293
+ if (
294
+ recurDelayMin != null &&
295
+ wasNonRecurring
296
+ ) {
297
+ card.recurGroupId = card.cardId;
298
+ }
299
+ if (patch.status === "backlog") {
300
+ card.workerThreadId = null;
301
+ card.blockedReason = null;
302
+ } else if (patch.status === "done") {
303
+ card.finishedAt = nowIso();
304
+ card.workerThreadId = null;
305
+ card.blockedReason = null;
306
+ card.nextSpawnAt =
307
+ recurDelayMin === null || existingRecurDelayMin == null
308
+ ? null
309
+ : new Date(
310
+ new Date(card.finishedAt).getTime() + existingRecurDelayMin * 60_000,
311
+ ).toISOString();
312
+ }
313
+ card.updatedAt = nowIso();
314
+ return clone(card);
315
+ },
316
+
317
+ async deleteCard(id) {
318
+ await delay();
319
+ const i = db.cards.findIndex((c) => c.cardId === id);
320
+ if (i < 0) throw httpError(404, `Card ${id} not found`);
321
+ db.cards.splice(i, 1);
322
+ delete db.comments[id];
323
+ },
324
+
325
+ async stopCard(id) {
326
+ await delay();
327
+ const card = find(id);
328
+ if (!card) throw httpError(404, `Card ${id} not found`);
329
+ if (card.status !== "in_progress")
330
+ throw httpError(409, `Card ${id} is not running (status: ${card.status})`);
331
+ card.status = "blocked";
332
+ card.blockedReason = "Stopped by operator";
333
+ card.workerThreadId = null;
334
+ card.updatedAt = nowIso();
335
+ return clone(card);
336
+ },
337
+
338
+ async addComment(id, content) {
339
+ await delay();
340
+ const card = find(id);
341
+ const text = typeof content === "string" ? content.trim() : "";
342
+ if (!text) throw httpError(400, "'content' is required");
343
+ if (!card) throw httpError(404, `Card ${id} not found`);
344
+ const comment = {
345
+ id: ++db.seq,
346
+ cardId: id,
347
+ author: "operator",
348
+ content: text,
349
+ createdAt: nowIso(),
350
+ };
351
+ (db.comments[id] ||= []).push(comment);
352
+ return clone(comment);
353
+ },
354
+
355
+ async postDecision(id, answer) {
356
+ await delay();
357
+ const card = find(id);
358
+ if (!card) throw httpError(404, `Card ${id} not found`);
359
+ if (card.status !== "decision_needed")
360
+ throw httpError(409, `Card ${id} is not awaiting a decision`);
361
+ const content = String(answer).trim();
362
+ if (!content) throw httpError(400, "'answer' is required");
363
+ const comment = {
364
+ id: ++db.seq,
365
+ cardId: id,
366
+ author: "operator",
367
+ content: `Decision: ${content}`,
368
+ createdAt: nowIso(),
369
+ };
370
+ (db.comments[id] ||= []).push(comment);
371
+ // Mirrors the backend: the answer is recorded onto the retained ask and the
372
+ // card resumes to backlog (buildBacklogResumePatch) so the worker picks it up.
373
+ if (card.ask) card.ask = { ...card.ask, answer: content, answeredAt: nowIso() };
374
+ card.status = "backlog";
375
+ card.workerThreadId = null;
376
+ card.blockedReason = null;
377
+ card.nextSpawnAt = null;
378
+ card.updatedAt = nowIso();
379
+ return clone(card);
380
+ },
381
+
382
+ async listLaneGroups() {
383
+ await delay();
384
+ return clone(db.laneGroups);
385
+ },
386
+
387
+ async getProfiles() {
388
+ await delay();
389
+ return clone(db.profiles);
390
+ },
391
+
392
+ // Upsert a named profile by id into the same store getProfiles reads, so a
393
+ // saved profile is available offline and a re-save (same id) updates in place.
394
+ async saveProfile(input) {
395
+ await delay();
396
+ const id = String(input.id || "").trim();
397
+ const name = String(input.name || "").trim();
398
+ if (!id || !name) throw httpError(400, "non-empty 'id' and 'name' are required");
399
+ if (db.profiles.some((profile) => profile.id !== id && profile.name === name)) {
400
+ throw httpError(400, "A profile with this name already exists");
401
+ }
402
+ const saved = { id, name, profile: clone(input.profile || {}), builtin: false };
403
+ const index = db.profiles.findIndex((profile) => profile.id === id);
404
+ if (index === -1) db.profiles.push(saved);
405
+ else db.profiles[index] = saved;
406
+ return clone(saved);
407
+ },
408
+
409
+ async threadRunning(threadId) {
410
+ await delay();
411
+ // A worker referenced by an in_progress fixture card is "running".
412
+ return db.cards.some((c) => c.status === "in_progress" && c.workerThreadId === threadId);
413
+ },
414
+
415
+ async threadLogs(threadId, { view = "assistant", offset = 0, limit = 4000 } = {}) {
416
+ await delay();
417
+ const text = fixtures.threadLogs[view === "full" ? "full" : "assistant"];
418
+ const start = Math.max(0, Number(offset) || 0);
419
+ const size = Math.max(1, Number(limit) || 4000);
420
+ const end = Math.max(0, text.length - start);
421
+ const chunk = text.slice(Math.max(0, end - size), end);
422
+ const nextOffset = start + chunk.length;
423
+ return clone({
424
+ threadId,
425
+ text: chunk,
426
+ offset: start,
427
+ nextOffset,
428
+ hasMore: nextOffset < text.length,
429
+ totalLength: text.length,
430
+ });
431
+ },
432
+
433
+ // Card-builder "How" step schema + presets. Sourced from the EDITABLE
434
+ // design-layer file schema/policy.js so a designer can tune the controls and
435
+ // see them live in preview; production uses the matching board-policy endpoint.
436
+ async getPolicySchema() {
437
+ await delay();
438
+ return clone(POLICY_SCHEMA);
439
+ },
440
+
441
+ async getPresets() {
442
+ await delay();
443
+ return clone(PRESETS);
444
+ },
445
+
446
+ async createLaneGroup(name) {
447
+ await delay();
448
+ if (!name || !name.trim()) throw httpError(400, "'name' is required");
449
+ const laneGroup = { groupId: ++db.seq, name: name.trim(), position: 0, createdAt: nowIso() };
450
+ db.laneGroups.push(laneGroup);
451
+ return clone(laneGroup);
452
+ },
453
+
454
+ async updateLaneGroup(id, patch) {
455
+ await delay();
456
+ const name = typeof patch.name === "string" ? patch.name.trim() : "";
457
+ if (!name) throw httpError(400, "non-empty 'name' is required");
458
+ const laneGroup = db.laneGroups.find((group) => group.groupId === id);
459
+ if (!laneGroup) throw httpError(404, `Lane group ${id} not found`);
460
+ laneGroup.name = name;
461
+ return clone(laneGroup);
462
+ },
463
+
464
+ async deleteLaneGroup(id) {
465
+ await delay();
466
+ if (!findLaneGroup(id)) throw httpError(404, `Lane group ${id} not found`);
467
+ const used = db.cards.filter((card) => card.laneGroupId === id).length;
468
+ if (used) throw httpError(409, `Lane group has ${used} card(s) — move or delete them first`);
469
+ const i = db.laneGroups.findIndex((group) => group.groupId === id);
470
+ db.laneGroups.splice(i, 1);
471
+ },
472
+
473
+ // One filesystem level from the preview dir tree — mirrors the real
474
+ // GET /api/board/dir-listing (roots when path is empty).
475
+ async listDir(path) {
476
+ await delay();
477
+ guardScenario();
478
+ if (!path) {
479
+ const entries = dirTree.map(({ name, path }) => ({ name, path }));
480
+ return { path: "", parent: null, entries };
481
+ }
482
+ const node = locateDir(dirTree, path);
483
+ if (!node) throw httpError(400, "path must be an absolute directory");
484
+ const entries = (node.children || []).map(({ name, path }) => ({ name, path }));
485
+ return { path, parent: parentDir(path), entries };
486
+ },
487
+ };
488
+ }
489
+
490
+ /** @type {BoardApi} */
491
+ export const mockApi = createMockApi();