sensorium-mcp 3.1.3-board.6 → 3.1.3-board.7

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 (417) hide show
  1. package/README.md +2 -0
  2. package/dist/board/api/api.js +37 -14
  3. package/dist/board/api/api.test.ts +23 -0
  4. package/dist/board/api/client.js +33 -16
  5. package/dist/board/components/Card.js +34 -9
  6. package/dist/board/components/Combobox.js +3 -2
  7. package/dist/board/components/CommentList.js +4 -1
  8. package/dist/board/components/DirTreePicker.js +128 -0
  9. package/dist/board/components/Dropdown.js +2 -1
  10. package/dist/board/components/Lane.js +4 -2
  11. package/dist/board/components/PriorityChip.js +5 -2
  12. package/dist/board/components/ProfileSummary.js +72 -22
  13. package/dist/board/components/StatusChip.js +6 -2
  14. package/dist/board/components/rateLimit.js +16 -3
  15. package/dist/board/components/rateLimit.test.ts +16 -0
  16. package/dist/board/components/time.js +14 -0
  17. package/dist/board/config.js +3 -3
  18. package/dist/board/mock/api.mock.js +456 -158
  19. package/dist/board/mock/api.mock.test.ts +460 -0
  20. package/dist/board/mock/fixtures.js +367 -53
  21. package/dist/board/schema/policy.js +30 -26
  22. package/dist/board/state/recur.js +24 -0
  23. package/dist/board/state/recur.test.ts +24 -0
  24. package/dist/board/state/useBoard.js +39 -27
  25. package/dist/board/state/useBuilder.js +284 -25
  26. package/dist/board/state/useBuilder.test.ts +468 -0
  27. package/dist/board/state/useCard.js +157 -31
  28. package/dist/board/state/useCard.test.ts +435 -0
  29. package/dist/board/state/useDirBrowser.js +23 -0
  30. package/dist/board/styles/board.css +701 -33
  31. package/dist/board/styles/tokens.css +2 -1
  32. package/dist/board/views/App.js +17 -21
  33. package/dist/board/views/BoardView.js +73 -10
  34. package/dist/board/views/BuilderView.js +132 -158
  35. package/dist/board/views/CardView.js +226 -108
  36. package/dist/board/views/SettingsView.js +84 -77
  37. package/dist/config/index.d.ts.map +1 -1
  38. package/dist/config/index.js +4 -0
  39. package/dist/config/index.js.map +1 -1
  40. package/dist/dashboard/board-static.d.ts +2 -3
  41. package/dist/dashboard/board-static.d.ts.map +1 -1
  42. package/dist/dashboard/board-static.js +2 -3
  43. package/dist/dashboard/board-static.js.map +1 -1
  44. package/dist/dashboard/routes/agent-templates.d.ts.map +1 -1
  45. package/dist/dashboard/routes/agent-templates.js +6 -9
  46. package/dist/dashboard/routes/agent-templates.js.map +1 -1
  47. package/dist/dashboard/routes/board-body.d.ts +8 -0
  48. package/dist/dashboard/routes/board-body.d.ts.map +1 -0
  49. package/dist/dashboard/routes/board-body.js +20 -0
  50. package/dist/dashboard/routes/board-body.js.map +1 -0
  51. package/dist/dashboard/routes/board-dir-listing.d.ts +70 -0
  52. package/dist/dashboard/routes/board-dir-listing.d.ts.map +1 -0
  53. package/dist/dashboard/routes/board-dir-listing.js +192 -0
  54. package/dist/dashboard/routes/board-dir-listing.js.map +1 -0
  55. package/dist/dashboard/routes/board-lane-groups.d.ts +6 -0
  56. package/dist/dashboard/routes/board-lane-groups.d.ts.map +1 -0
  57. package/dist/dashboard/routes/board-lane-groups.js +52 -0
  58. package/dist/dashboard/routes/board-lane-groups.js.map +1 -0
  59. package/dist/dashboard/routes/board-policy.d.ts +224 -0
  60. package/dist/dashboard/routes/board-policy.d.ts.map +1 -0
  61. package/dist/dashboard/routes/board-policy.js +214 -0
  62. package/dist/dashboard/routes/board-policy.js.map +1 -0
  63. package/dist/dashboard/routes/board-profile-parse.d.ts +32 -0
  64. package/dist/dashboard/routes/board-profile-parse.d.ts.map +1 -0
  65. package/dist/dashboard/routes/board-profile-parse.js +338 -0
  66. package/dist/dashboard/routes/board-profile-parse.js.map +1 -0
  67. package/dist/dashboard/routes/board.d.ts +34 -19
  68. package/dist/dashboard/routes/board.d.ts.map +1 -1
  69. package/dist/dashboard/routes/board.js +414 -487
  70. package/dist/dashboard/routes/board.js.map +1 -1
  71. package/dist/dashboard/routes/skills.d.ts +7 -1
  72. package/dist/dashboard/routes/skills.d.ts.map +1 -1
  73. package/dist/dashboard/routes/skills.js +6 -6
  74. package/dist/dashboard/routes/skills.js.map +1 -1
  75. package/dist/dashboard/routes/snapshots.d.ts +2 -1
  76. package/dist/dashboard/routes/snapshots.d.ts.map +1 -1
  77. package/dist/dashboard/routes/snapshots.js +24 -18
  78. package/dist/dashboard/routes/snapshots.js.map +1 -1
  79. package/dist/dashboard/routes/templates.js +5 -5
  80. package/dist/dashboard/routes/templates.js.map +1 -1
  81. package/dist/dashboard/routes/threads-create.d.ts +17 -0
  82. package/dist/dashboard/routes/threads-create.d.ts.map +1 -1
  83. package/dist/dashboard/routes/threads-create.js +32 -10
  84. package/dist/dashboard/routes/threads-create.js.map +1 -1
  85. package/dist/dashboard/routes/threads-helpers.d.ts +11 -2
  86. package/dist/dashboard/routes/threads-helpers.d.ts.map +1 -1
  87. package/dist/dashboard/routes/threads-helpers.js +20 -3
  88. package/dist/dashboard/routes/threads-helpers.js.map +1 -1
  89. package/dist/dashboard/routes/threads-read.d.ts +14 -9
  90. package/dist/dashboard/routes/threads-read.d.ts.map +1 -1
  91. package/dist/dashboard/routes/threads-read.js +51 -70
  92. package/dist/dashboard/routes/threads-read.js.map +1 -1
  93. package/dist/dashboard/routes/threads.d.ts +1 -1
  94. package/dist/dashboard/routes/threads.d.ts.map +1 -1
  95. package/dist/dashboard/routes/threads.js +124 -69
  96. package/dist/dashboard/routes/threads.js.map +1 -1
  97. package/dist/dashboard/routes.d.ts +2 -2
  98. package/dist/dashboard/routes.d.ts.map +1 -1
  99. package/dist/dashboard/routes.js +47 -14
  100. package/dist/dashboard/routes.js.map +1 -1
  101. package/dist/dashboard/spa.html +11 -12
  102. package/dist/data/board/board-schema.d.ts +8 -1
  103. package/dist/data/board/board-schema.d.ts.map +1 -1
  104. package/dist/data/board/board-schema.js +148 -49
  105. package/dist/data/board/board-schema.js.map +1 -1
  106. package/dist/data/board/board-types.d.ts +73 -15
  107. package/dist/data/board/board-types.d.ts.map +1 -1
  108. package/dist/data/board/card.repository.d.ts +36 -7
  109. package/dist/data/board/card.repository.d.ts.map +1 -1
  110. package/dist/data/board/card.repository.js +189 -50
  111. package/dist/data/board/card.repository.js.map +1 -1
  112. package/dist/data/board/comment.repository.d.ts +2 -0
  113. package/dist/data/board/comment.repository.d.ts.map +1 -1
  114. package/dist/data/board/comment.repository.js +11 -0
  115. package/dist/data/board/comment.repository.js.map +1 -1
  116. package/dist/data/board/lane-group.repository.d.ts +19 -0
  117. package/dist/data/board/lane-group.repository.d.ts.map +1 -0
  118. package/dist/data/board/lane-group.repository.js +66 -0
  119. package/dist/data/board/lane-group.repository.js.map +1 -0
  120. package/dist/data/board/profile-defaults.d.ts +16 -18
  121. package/dist/data/board/profile-defaults.d.ts.map +1 -1
  122. package/dist/data/board/profile-defaults.js +94 -105
  123. package/dist/data/board/profile-defaults.js.map +1 -1
  124. package/dist/data/interfaces.d.ts +2 -1
  125. package/dist/data/interfaces.d.ts.map +1 -1
  126. package/dist/data/memory/consolidation.d.ts +1 -42
  127. package/dist/data/memory/consolidation.d.ts.map +1 -1
  128. package/dist/data/memory/consolidation.js +2 -62
  129. package/dist/data/memory/consolidation.js.map +1 -1
  130. package/dist/data/memory/db-maintenance.d.ts +54 -0
  131. package/dist/data/memory/db-maintenance.d.ts.map +1 -0
  132. package/dist/data/memory/db-maintenance.js +81 -0
  133. package/dist/data/memory/db-maintenance.js.map +1 -0
  134. package/dist/data/memory/episodes.d.ts +2 -1
  135. package/dist/data/memory/episodes.d.ts.map +1 -1
  136. package/dist/data/memory/episodes.js +5 -1
  137. package/dist/data/memory/episodes.js.map +1 -1
  138. package/dist/data/memory/migration-runner.d.ts +1 -1
  139. package/dist/data/memory/migration-runner.d.ts.map +1 -1
  140. package/dist/data/memory/migration-runner.js +367 -1
  141. package/dist/data/memory/migration-runner.js.map +1 -1
  142. package/dist/data/memory/passive-notice.repository.d.ts +61 -0
  143. package/dist/data/memory/passive-notice.repository.d.ts.map +1 -0
  144. package/dist/data/memory/passive-notice.repository.js +70 -0
  145. package/dist/data/memory/passive-notice.repository.js.map +1 -0
  146. package/dist/data/memory/schema-ddl.d.ts +120 -1
  147. package/dist/data/memory/schema-ddl.d.ts.map +1 -1
  148. package/dist/data/memory/schema-ddl.js +167 -3
  149. package/dist/data/memory/schema-ddl.js.map +1 -1
  150. package/dist/data/memory/schema-guard.d.ts.map +1 -1
  151. package/dist/data/memory/schema-guard.js +5 -41
  152. package/dist/data/memory/schema-guard.js.map +1 -1
  153. package/dist/data/memory/schema.d.ts.map +1 -1
  154. package/dist/data/memory/schema.js +6 -34
  155. package/dist/data/memory/schema.js.map +1 -1
  156. package/dist/data/memory/thread-registry.d.ts +261 -79
  157. package/dist/data/memory/thread-registry.d.ts.map +1 -1
  158. package/dist/data/memory/thread-registry.js +418 -126
  159. package/dist/data/memory/thread-registry.js.map +1 -1
  160. package/dist/data/memory/worker-lifecycle.repository.d.ts +309 -0
  161. package/dist/data/memory/worker-lifecycle.repository.d.ts.map +1 -0
  162. package/dist/data/memory/worker-lifecycle.repository.js +429 -0
  163. package/dist/data/memory/worker-lifecycle.repository.js.map +1 -0
  164. package/dist/data/optional.d.ts +16 -0
  165. package/dist/data/optional.d.ts.map +1 -0
  166. package/dist/data/optional.js +47 -0
  167. package/dist/data/optional.js.map +1 -0
  168. package/dist/index.js +56 -22
  169. package/dist/index.js.map +1 -1
  170. package/dist/integrations/openai/video.d.ts +1 -1
  171. package/dist/integrations/openai/video.d.ts.map +1 -1
  172. package/dist/integrations/openai/video.js +13 -8
  173. package/dist/integrations/openai/video.js.map +1 -1
  174. package/dist/lib/paths.d.ts +12 -4
  175. package/dist/lib/paths.d.ts.map +1 -1
  176. package/dist/lib/paths.js +12 -4
  177. package/dist/lib/paths.js.map +1 -1
  178. package/dist/lib/types.d.ts +2 -0
  179. package/dist/lib/types.d.ts.map +1 -1
  180. package/dist/lib/usage-metering/sink.d.ts +4 -0
  181. package/dist/lib/usage-metering/sink.d.ts.map +1 -1
  182. package/dist/lib/usage-metering/sink.js +6 -4
  183. package/dist/lib/usage-metering/sink.js.map +1 -1
  184. package/dist/lib/utils.d.ts +21 -0
  185. package/dist/lib/utils.d.ts.map +1 -1
  186. package/dist/lib/utils.js +27 -0
  187. package/dist/lib/utils.js.map +1 -1
  188. package/dist/log-parsing/log-events.d.ts +38 -0
  189. package/dist/log-parsing/log-events.d.ts.map +1 -0
  190. package/dist/log-parsing/log-events.js +2 -0
  191. package/dist/log-parsing/log-events.js.map +1 -0
  192. package/dist/log-parsing/parser-registry.d.ts +4 -0
  193. package/dist/log-parsing/parser-registry.d.ts.map +1 -0
  194. package/dist/log-parsing/parser-registry.js +18 -0
  195. package/dist/log-parsing/parser-registry.js.map +1 -0
  196. package/dist/log-parsing/parsers/claude.d.ts +6 -0
  197. package/dist/log-parsing/parsers/claude.d.ts.map +1 -0
  198. package/dist/log-parsing/parsers/claude.js +100 -0
  199. package/dist/log-parsing/parsers/claude.js.map +1 -0
  200. package/dist/log-parsing/parsers/codex.d.ts +6 -0
  201. package/dist/log-parsing/parsers/codex.d.ts.map +1 -0
  202. package/dist/log-parsing/parsers/codex.js +116 -0
  203. package/dist/log-parsing/parsers/codex.js.map +1 -0
  204. package/dist/log-parsing/parsers/copilot.d.ts +6 -0
  205. package/dist/log-parsing/parsers/copilot.d.ts.map +1 -0
  206. package/dist/log-parsing/parsers/copilot.js +65 -0
  207. package/dist/log-parsing/parsers/copilot.js.map +1 -0
  208. package/dist/log-parsing/parsers/json-lines.d.ts +9 -0
  209. package/dist/log-parsing/parsers/json-lines.d.ts.map +1 -0
  210. package/dist/log-parsing/parsers/json-lines.js +25 -0
  211. package/dist/log-parsing/parsers/json-lines.js.map +1 -0
  212. package/dist/log-parsing/render.d.ts +33 -0
  213. package/dist/log-parsing/render.d.ts.map +1 -0
  214. package/dist/log-parsing/render.js +113 -0
  215. package/dist/log-parsing/render.js.map +1 -0
  216. package/dist/log-parsing/text.d.ts +8 -0
  217. package/dist/log-parsing/text.d.ts.map +1 -0
  218. package/dist/log-parsing/text.js +20 -0
  219. package/dist/log-parsing/text.js.map +1 -0
  220. package/dist/server/http-server.d.ts.map +1 -1
  221. package/dist/server/http-server.js +15 -8
  222. package/dist/server/http-server.js.map +1 -1
  223. package/dist/services/agent-spawn.service.d.ts +50 -5
  224. package/dist/services/agent-spawn.service.d.ts.map +1 -1
  225. package/dist/services/agent-spawn.service.js +55 -37
  226. package/dist/services/agent-spawn.service.js.map +1 -1
  227. package/dist/services/background-runner.d.ts.map +1 -1
  228. package/dist/services/background-runner.js +38 -25
  229. package/dist/services/background-runner.js.map +1 -1
  230. package/dist/services/board/board-signals.d.ts +28 -10
  231. package/dist/services/board/board-signals.d.ts.map +1 -1
  232. package/dist/services/board/board-signals.js +104 -22
  233. package/dist/services/board/board-signals.js.map +1 -1
  234. package/dist/services/board/card-briefing.d.ts +5 -4
  235. package/dist/services/board/card-briefing.d.ts.map +1 -1
  236. package/dist/services/board/card-briefing.js +48 -11
  237. package/dist/services/board/card-briefing.js.map +1 -1
  238. package/dist/services/board/card-diagnostics.d.ts +25 -0
  239. package/dist/services/board/card-diagnostics.d.ts.map +1 -0
  240. package/dist/services/board/card-diagnostics.js +50 -0
  241. package/dist/services/board/card-diagnostics.js.map +1 -0
  242. package/dist/services/board/live-root-thread.d.ts +8 -0
  243. package/dist/services/board/live-root-thread.d.ts.map +1 -0
  244. package/dist/services/board/live-root-thread.js +2 -0
  245. package/dist/services/board/live-root-thread.js.map +1 -0
  246. package/dist/services/board/orchestrator.service.d.ts +62 -6
  247. package/dist/services/board/orchestrator.service.d.ts.map +1 -1
  248. package/dist/services/board/orchestrator.service.js +231 -61
  249. package/dist/services/board/orchestrator.service.js.map +1 -1
  250. package/dist/services/board/release-worker.d.ts +12 -1
  251. package/dist/services/board/release-worker.d.ts.map +1 -1
  252. package/dist/services/board/release-worker.js +64 -17
  253. package/dist/services/board/release-worker.js.map +1 -1
  254. package/dist/services/board/report-capture.d.ts +26 -9
  255. package/dist/services/board/report-capture.d.ts.map +1 -1
  256. package/dist/services/board/report-capture.js +253 -52
  257. package/dist/services/board/report-capture.js.map +1 -1
  258. package/dist/services/board/worker-spawn.d.ts +67 -8
  259. package/dist/services/board/worker-spawn.d.ts.map +1 -1
  260. package/dist/services/board/worker-spawn.js +160 -73
  261. package/dist/services/board/worker-spawn.js.map +1 -1
  262. package/dist/services/board/worktree.d.ts +45 -0
  263. package/dist/services/board/worktree.d.ts.map +1 -0
  264. package/dist/services/board/worktree.js +183 -0
  265. package/dist/services/board/worktree.js.map +1 -0
  266. package/dist/services/broker-client.d.ts +45 -3
  267. package/dist/services/broker-client.d.ts.map +1 -1
  268. package/dist/services/broker-client.js +15 -3
  269. package/dist/services/broker-client.js.map +1 -1
  270. package/dist/services/claude-spawn.service.d.ts +5 -0
  271. package/dist/services/claude-spawn.service.d.ts.map +1 -1
  272. package/dist/services/claude-spawn.service.js +28 -18
  273. package/dist/services/claude-spawn.service.js.map +1 -1
  274. package/dist/services/codex-spawn.service.d.ts +1 -1
  275. package/dist/services/codex-spawn.service.d.ts.map +1 -1
  276. package/dist/services/codex-spawn.service.js +7 -2
  277. package/dist/services/codex-spawn.service.js.map +1 -1
  278. package/dist/services/consolidation.service.d.ts.map +1 -1
  279. package/dist/services/consolidation.service.js +0 -11
  280. package/dist/services/consolidation.service.js.map +1 -1
  281. package/dist/services/copilot-spawn.service.d.ts +1 -1
  282. package/dist/services/copilot-spawn.service.d.ts.map +1 -1
  283. package/dist/services/copilot-spawn.service.js +3 -3
  284. package/dist/services/copilot-spawn.service.js.map +1 -1
  285. package/dist/services/daily-session.d.ts +2 -0
  286. package/dist/services/daily-session.d.ts.map +1 -1
  287. package/dist/services/daily-session.js +16 -1
  288. package/dist/services/daily-session.js.map +1 -1
  289. package/dist/services/death-alert.service.d.ts +55 -0
  290. package/dist/services/death-alert.service.d.ts.map +1 -0
  291. package/dist/services/death-alert.service.js +64 -0
  292. package/dist/services/death-alert.service.js.map +1 -0
  293. package/dist/services/dispatcher/broker.d.ts +57 -0
  294. package/dist/services/dispatcher/broker.d.ts.map +1 -1
  295. package/dist/services/dispatcher/broker.js +60 -52
  296. package/dist/services/dispatcher/broker.js.map +1 -1
  297. package/dist/services/intent.d.ts +15 -1
  298. package/dist/services/intent.d.ts.map +1 -1
  299. package/dist/services/intent.js +39 -27
  300. package/dist/services/intent.js.map +1 -1
  301. package/dist/services/keeper.service.d.ts +76 -3
  302. package/dist/services/keeper.service.d.ts.map +1 -1
  303. package/dist/services/keeper.service.js +113 -36
  304. package/dist/services/keeper.service.js.map +1 -1
  305. package/dist/services/passive-notice.service.d.ts +29 -19
  306. package/dist/services/passive-notice.service.d.ts.map +1 -1
  307. package/dist/services/passive-notice.service.js +42 -232
  308. package/dist/services/passive-notice.service.js.map +1 -1
  309. package/dist/services/process.service.d.ts +97 -30
  310. package/dist/services/process.service.d.ts.map +1 -1
  311. package/dist/services/process.service.js +284 -81
  312. package/dist/services/process.service.js.map +1 -1
  313. package/dist/services/spawn-common.d.ts +289 -9
  314. package/dist/services/spawn-common.d.ts.map +1 -1
  315. package/dist/services/spawn-common.js +844 -151
  316. package/dist/services/spawn-common.js.map +1 -1
  317. package/dist/services/spawn-exit-watcher.d.ts.map +1 -1
  318. package/dist/services/spawn-exit-watcher.js +75 -2
  319. package/dist/services/spawn-exit-watcher.js.map +1 -1
  320. package/dist/services/telegram.d.ts +24 -3
  321. package/dist/services/telegram.d.ts.map +1 -1
  322. package/dist/services/telegram.js +40 -13
  323. package/dist/services/telegram.js.map +1 -1
  324. package/dist/services/thread-health.service.d.ts +8 -0
  325. package/dist/services/thread-health.service.d.ts.map +1 -1
  326. package/dist/services/thread-health.service.js +10 -1
  327. package/dist/services/thread-health.service.js.map +1 -1
  328. package/dist/services/thread-lifecycle.service.d.ts +8 -1
  329. package/dist/services/thread-lifecycle.service.d.ts.map +1 -1
  330. package/dist/services/thread-lifecycle.service.js +33 -18
  331. package/dist/services/thread-lifecycle.service.js.map +1 -1
  332. package/dist/services/thread-log-reader.d.ts +81 -0
  333. package/dist/services/thread-log-reader.d.ts.map +1 -0
  334. package/dist/services/thread-log-reader.js +141 -0
  335. package/dist/services/thread-log-reader.js.map +1 -0
  336. package/dist/services/thread-purge.service.d.ts +79 -41
  337. package/dist/services/thread-purge.service.d.ts.map +1 -1
  338. package/dist/services/thread-purge.service.js +318 -183
  339. package/dist/services/thread-purge.service.js.map +1 -1
  340. package/dist/services/topic.service.d.ts +44 -2
  341. package/dist/services/topic.service.d.ts.map +1 -1
  342. package/dist/services/topic.service.js +74 -13
  343. package/dist/services/topic.service.js.map +1 -1
  344. package/dist/services/usage/usage-poller.service.d.ts.map +1 -1
  345. package/dist/services/usage/usage-poller.service.js +5 -4
  346. package/dist/services/usage/usage-poller.service.js.map +1 -1
  347. package/dist/services/usage/usage-snapshot-provider.d.ts +11 -0
  348. package/dist/services/usage/usage-snapshot-provider.d.ts.map +1 -1
  349. package/dist/services/usage/usage-snapshot-provider.js +30 -0
  350. package/dist/services/usage/usage-snapshot-provider.js.map +1 -1
  351. package/dist/services/usage/usage-types.d.ts +6 -1
  352. package/dist/services/usage/usage-types.d.ts.map +1 -1
  353. package/dist/services/worker-birth.d.ts +154 -0
  354. package/dist/services/worker-birth.d.ts.map +1 -0
  355. package/dist/services/worker-birth.js +275 -0
  356. package/dist/services/worker-birth.js.map +1 -0
  357. package/dist/services/worker-cleanup.service.d.ts +250 -21
  358. package/dist/services/worker-cleanup.service.d.ts.map +1 -1
  359. package/dist/services/worker-cleanup.service.js +786 -364
  360. package/dist/services/worker-cleanup.service.js.map +1 -1
  361. package/dist/services/worker-lifecycle-executor.d.ts +41 -0
  362. package/dist/services/worker-lifecycle-executor.d.ts.map +1 -0
  363. package/dist/services/worker-lifecycle-executor.js +62 -0
  364. package/dist/services/worker-lifecycle-executor.js.map +1 -0
  365. package/dist/services/worker-single-use.d.ts +92 -0
  366. package/dist/services/worker-single-use.d.ts.map +1 -0
  367. package/dist/services/worker-single-use.js +155 -0
  368. package/dist/services/worker-single-use.js.map +1 -0
  369. package/dist/sessions/mcp-registry.d.ts +26 -0
  370. package/dist/sessions/mcp-registry.d.ts.map +1 -1
  371. package/dist/sessions/mcp-registry.js +101 -0
  372. package/dist/sessions/mcp-registry.js.map +1 -1
  373. package/dist/tools/defs/session-defs.d.ts.map +1 -1
  374. package/dist/tools/defs/session-defs.js +24 -8
  375. package/dist/tools/defs/session-defs.js.map +1 -1
  376. package/dist/tools/delegate-tool.d.ts +70 -0
  377. package/dist/tools/delegate-tool.d.ts.map +1 -1
  378. package/dist/tools/delegate-tool.js +787 -219
  379. package/dist/tools/delegate-tool.js.map +1 -1
  380. package/dist/tools/skill-tools.js +1 -1
  381. package/dist/tools/skill-tools.js.map +1 -1
  382. package/dist/tools/start-session-tool.d.ts.map +1 -1
  383. package/dist/tools/start-session-tool.js +53 -19
  384. package/dist/tools/start-session-tool.js.map +1 -1
  385. package/dist/tools/wait/auto-forward.d.ts.map +1 -1
  386. package/dist/tools/wait/auto-forward.js +9 -4
  387. package/dist/tools/wait/auto-forward.js.map +1 -1
  388. package/dist/tools/wait/media-processor.d.ts.map +1 -1
  389. package/dist/tools/wait/media-processor.js +8 -4
  390. package/dist/tools/wait/media-processor.js.map +1 -1
  391. package/dist/tools/wait/message-delivery.js +1 -1
  392. package/dist/tools/wait/message-delivery.js.map +1 -1
  393. package/dist/tools/wait/poll-loop.d.ts.map +1 -1
  394. package/dist/tools/wait/poll-loop.js +330 -237
  395. package/dist/tools/wait/poll-loop.js.map +1 -1
  396. package/package.json +2 -1
  397. package/templates/azure-devops-securevault.default.md +20 -6
  398. package/templates/board-quality-checklist.default.md +114 -0
  399. package/templates/expert-code-review.default.md +12 -0
  400. package/templates/handoff.default.md +41 -18
  401. package/templates/swarm.default.md +1 -0
  402. package/templates/worker-autonomous.default.md +1 -0
  403. package/templates/worker-delegate.default.md +1 -0
  404. package/dist/board/components/TokenEntry.js +0 -42
  405. package/dist/board/state/auth.js +0 -55
  406. package/dist/dashboard/log-parser.d.ts +0 -65
  407. package/dist/dashboard/log-parser.d.ts.map +0 -1
  408. package/dist/dashboard/log-parser.js +0 -219
  409. package/dist/dashboard/log-parser.js.map +0 -1
  410. package/dist/data/board/lane.repository.d.ts +0 -18
  411. package/dist/data/board/lane.repository.d.ts.map +0 -1
  412. package/dist/data/board/lane.repository.js +0 -44
  413. package/dist/data/board/lane.repository.js.map +0 -1
  414. package/dist/services/memory-pruning.service.d.ts +0 -12
  415. package/dist/services/memory-pruning.service.d.ts.map +0 -1
  416. package/dist/services/memory-pruning.service.js +0 -197
  417. package/dist/services/memory-pruning.service.js.map +0 -1
package/README.md CHANGED
@@ -5,6 +5,8 @@
5
5
 
6
6
  MCP server with multi-layer memory, voice analysis, multi-thread orchestration, and Telegram bridge for AI assistants.
7
7
 
8
+ Internal TypeScript conventions: [coding guidelines](docs/coding-guidelines.md).
9
+
8
10
  ## Why?
9
11
 
10
12
  AI assistants forget everything between sessions. Every restart is a blank slate — no memory of your preferences, past decisions, or ongoing projects. Voice messages arrive as opaque audio blobs. And there's no way to talk to your agent when it's running headless in CI or on a remote machine.
@@ -19,10 +19,11 @@ let implPromise = null;
19
19
  /** @returns {Promise<BoardApi>} */
20
20
  function load() {
21
21
  if (!implPromise) {
22
- implPromise =
22
+ implPromise = (
23
23
  MODE === "preview"
24
24
  ? import("../mock/api.mock.js").then((m) => m.mockApi)
25
- : import("./client.js").then((m) => m.client);
25
+ : import("./client.js").then((m) => m.client)
26
+ ).then(assertAdapterComplete);
26
27
  }
27
28
  return implPromise;
28
29
  }
@@ -31,31 +32,53 @@ const METHODS = [
31
32
  "listCards",
32
33
  "getCard",
33
34
  "createCard",
35
+ "previewBriefing",
34
36
  "updateCard",
35
37
  "deleteCard",
36
38
  "stopCard",
37
39
  "addComment",
38
- "listLanes",
40
+ "postDecision",
41
+ "listLaneGroups",
39
42
  "getProfiles",
43
+ "saveProfile",
40
44
  "threadRunning",
41
- // Card-builder "How" schema + presets. Preview is served by mock/api.mock.js
42
- // (from the editable schema/policy.js). TODO(P1): api/client.js must implement
43
- // getPolicySchema()/getPresets() against the real board API before production
44
- // uses the schema-driven builder; until then production calls reject and
45
- // useBuilder() degrades to a schema-less builder (no crash).
45
+ "threadLogs",
46
+ // Card-builder "How" schema + presets.
46
47
  "getPolicySchema",
47
48
  "getPresets",
48
- // Lane management (Settings). Preview served by the mock; TODO(P1): implement
49
- // in api/client.js before production exposes lane CRUD.
50
- "createLane",
51
- "updateLane",
52
- "deleteLane",
49
+ "createLaneGroup",
50
+ "updateLaneGroup",
51
+ "deleteLaneGroup",
52
+ // Working-directory picker: one filesystem level per call (lazy browse).
53
+ "listDir",
53
54
  ];
54
55
 
56
+ /**
57
+ * Fail LOUD if the resolved adapter is missing any METHODS entry. A method listed
58
+ * in the contract/registry but never implemented in the active adapter used to
59
+ * surface as a late "undefined is not a function" at call time — exactly how
60
+ * lane-group CRUD and previewBriefing broke in production
61
+ * while preview worked. Asserting completeness once, at load, turns that silent
62
+ * drift into an immediate, named error.
63
+ *
64
+ * @param {Partial<BoardApi>} impl
65
+ * @returns {BoardApi}
66
+ */
67
+ function assertAdapterComplete(impl) {
68
+ const missing = METHODS.filter((name) => typeof impl?.[name] !== "function");
69
+ if (missing.length) {
70
+ throw new Error(
71
+ `Board API adapter is missing method(s): ${missing.join(", ")}. ` +
72
+ `Every METHODS entry must be implemented by the active adapter (api/client.js or mock/api.mock.js).`,
73
+ );
74
+ }
75
+ return /** @type {BoardApi} */ (impl);
76
+ }
77
+
55
78
  /** @type {BoardApi} */
56
79
  const api = /** @type {any} */ ({});
57
80
  for (const name of METHODS) {
58
81
  api[name] = (...args) => load().then((impl) => impl[name](...args));
59
82
  }
60
83
 
61
- export { api };
84
+ export { api, assertAdapterComplete };
@@ -0,0 +1,23 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import { assertAdapterComplete } from "./api.js";
4
+ import { client } from "./client.js";
5
+ import type { BoardApi } from "./contract.js";
6
+
7
+ test("the adapter completeness guard passes for the production client", () => {
8
+ // Arrange
9
+ const impl = client;
10
+
11
+ // Act & Assert — every contract/registry method is now implemented in client.js.
12
+ assert.doesNotThrow(() => assertAdapterComplete(impl));
13
+ });
14
+
15
+ test("the adapter completeness guard throws naming a method missing from the adapter", () => {
16
+ // Arrange — a client with one contract method dropped (the exact drift that
17
+ // shipped lane CRUD as a late `undefined is not a function`).
18
+ const incomplete: Partial<BoardApi> = { ...client };
19
+ delete incomplete.createLaneGroup;
20
+
21
+ // Act & Assert
22
+ assert.throws(() => assertAdapterComplete(incomplete), /createLaneGroup/);
23
+ });
@@ -2,15 +2,14 @@
2
2
  * Production data adapter. ❌ FROZEN SEAM.
3
3
  *
4
4
  * Real `fetch` to the board API. Root-relative `/api/...` paths (never a host or
5
- * port) so the app works unchanged behind the Cloudflare Tunnel. Bearer token is
6
- * injected from state/auth.js. This is the ONLY module that talks to the network.
5
+ * port) so the app works unchanged behind the Dev Tunnel. This is the ONLY module
6
+ * that talks to the network.
7
7
  *
8
8
  * @typedef {import('./contract.js').BoardApi} BoardApi
9
9
  * @typedef {import('./contract.js').BoardCard} BoardCard
10
10
  */
11
11
 
12
12
  import { API_BASE } from "../config.js";
13
- import { getToken } from "../state/auth.js";
14
13
 
15
14
  /**
16
15
  * @param {string} method
@@ -19,8 +18,6 @@ import { getToken } from "../state/auth.js";
19
18
  */
20
19
  async function req(method, path, body) {
21
20
  const headers = {};
22
- const token = getToken();
23
- if (token) headers.Authorization = `Bearer ${token}`;
24
21
  if (body !== undefined) headers["Content-Type"] = "application/json";
25
22
 
26
23
  const res = await fetch(`${API_BASE}${path}`, {
@@ -49,12 +46,11 @@ async function req(method, path, body) {
49
46
 
50
47
  /** @type {BoardApi} */
51
48
  export const client = {
52
- listCards({ includeArchived = false, lane } = {}) {
49
+ listCards({ includeArchived = false } = {}) {
53
50
  const p = new URLSearchParams();
54
51
  if (includeArchived) p.set("includeArchived", "1");
55
- if (lane != null) p.set("lane", String(lane));
56
52
  const qs = p.toString();
57
- return req("GET", `/api/board/cards${qs ? `?${qs}` : ""}`).then((d) => d.cards);
53
+ return req("GET", `/api/board/cards${qs ? `?${qs}` : ""}`);
58
54
  },
59
55
  getCard(id) {
60
56
  return req("GET", `/api/board/cards/${id}`);
@@ -62,6 +58,9 @@ export const client = {
62
58
  createCard(card) {
63
59
  return req("POST", "/api/board/cards", card).then((d) => d.card);
64
60
  },
61
+ previewBriefing(draft) {
62
+ return req("POST", "/api/board/cards/preview", draft).then((d) => d.briefing);
63
+ },
65
64
  updateCard(id, patch) {
66
65
  return req("PATCH", `/api/board/cards/${id}`, patch).then((d) => d.card);
67
66
  },
@@ -74,23 +73,41 @@ export const client = {
74
73
  addComment(id, content) {
75
74
  return req("POST", `/api/board/cards/${id}/comments`, { content }).then((d) => d.comment);
76
75
  },
77
- listLanes() {
78
- return req("GET", "/api/board/lanes").then((d) => d.lanes);
76
+ postDecision(id, answer) {
77
+ return req("POST", `/api/board/cards/${id}/decision`, { answer }).then((d) => d.card);
78
+ },
79
+ listLaneGroups() {
80
+ return req("GET", "/api/board/lane-groups").then((d) => d.laneGroups);
81
+ },
82
+ createLaneGroup(name) {
83
+ return req("POST", "/api/board/lane-groups", { name }).then((d) => d.laneGroup);
84
+ },
85
+ updateLaneGroup(id, patch) {
86
+ return req("PATCH", `/api/board/lane-groups/${id}`, patch).then((d) => d.laneGroup);
87
+ },
88
+ deleteLaneGroup(id) {
89
+ return req("DELETE", `/api/board/lane-groups/${id}`).then(() => undefined);
79
90
  },
80
91
  getProfiles() {
81
92
  return req("GET", "/api/board/profiles").then((d) => d.profiles);
82
93
  },
94
+ saveProfile(input) {
95
+ return req("POST", "/api/board/profiles", input).then((d) => d.profile);
96
+ },
83
97
  threadRunning(threadId) {
84
98
  return req("GET", `/api/threads/${threadId}/running`).then((d) => !!d.running);
85
99
  },
86
- // TODO(P1): serve the card-builder "How" schema/presets from the real board
87
- // API (e.g. GET /api/board/policy). Until then these reject explicitly so the
88
- // production failure is legible; useBuilder() swallows the rejection and falls
89
- // back to a schema-less builder (no crash).
100
+ threadLogs(threadId, { view = "assistant", offset = 0, limit = 4000 } = {}) {
101
+ const params = new URLSearchParams({ view, offset: String(offset), limit: String(limit) });
102
+ return req("GET", `/api/threads/${threadId}/logs?${params}`);
103
+ },
90
104
  getPolicySchema() {
91
- return Promise.reject(new Error("getPolicySchema not implemented — P1"));
105
+ return req("GET", "/api/board/policy").then((d) => d.schema);
92
106
  },
93
107
  getPresets() {
94
- return Promise.reject(new Error("getPresets not implemented — P1"));
108
+ return req("GET", "/api/board/policy").then((d) => d.presets);
109
+ },
110
+ listDir(path) {
111
+ return req("GET", `/api/board/dir-listing?path=${encodeURIComponent(path || "")}`);
95
112
  },
96
113
  };
@@ -1,52 +1,77 @@
1
1
  /**
2
2
  * Card tile — ✅ EDITABLE. Pure: `card` + `laneName` in, `open` out.
3
3
  * Dispatch design: floating dark card — title, then chip row with priority,
4
- * type, live worker pulse / blocked / archived.
4
+ * live worker pulse / blocked / archived. A decision_needed card gets a distinct
5
+ * badge plus a waiting-age cue so a stalled decision is obvious at a glance.
5
6
  */
6
7
 
7
8
  import StatusChip from "./StatusChip.js";
8
9
  import PriorityChip from "./PriorityChip.js";
9
- import { providerLabel, retryLabel } from "./rateLimit.js";
10
+ import { proactiveLimitKind, providerLabel, retryLabel } from "./rateLimit.js";
11
+ import { humanMins, minsSince } from "./time.js";
10
12
 
11
13
  export default {
12
14
  name: "Card",
13
15
  components: { StatusChip, PriorityChip },
14
16
  props: {
15
17
  card: { type: Object, required: true },
16
- laneName: { type: Function, default: (id) => `Thread ${id}` },
18
+ laneName: { type: Function, default: () => "Ungrouped" },
19
+ limitedProviders: { type: Array, default: () => [] },
17
20
  },
18
21
  emits: ["open"],
19
22
  setup(props, { emit }) {
20
23
  function elapsed() {
21
24
  if (!props.card.startedAt) return "";
22
- const mins = Math.max(0, Math.round((Date.now() - new Date(props.card.startedAt)) / 60000));
23
- return mins >= 60 ? Math.floor(mins / 60) + "h " + (mins % 60) + "m" : mins + "m";
25
+ return humanMins(minsSince(props.card.startedAt));
24
26
  }
25
27
  function rlText() {
26
- const p = providerLabel(props.card);
28
+ const p = providerLabel(props.card.rateLimitProvider);
27
29
  return (p ? p + " · " : "") + retryLabel(props.card);
28
30
  }
29
- return { emit, elapsed, rlText };
31
+ function proactiveProvider() {
32
+ return providerLabel(props.card.profile?.agentType);
33
+ }
34
+ function proactiveKind() {
35
+ return proactiveLimitKind(props.card, props.limitedProviders);
36
+ }
37
+ /** How long this card has been waiting on the operator. */
38
+ function waiting() {
39
+ const c = props.card;
40
+ if (c.status !== "decision_needed") return null;
41
+ const mins = minsSince(c.updatedAt || c.finishedAt || c.startedAt || c.createdAt);
42
+ return { text: humanMins(mins), stale: mins >= 480 };
43
+ }
44
+ return { emit, elapsed, proactiveKind, proactiveProvider, rlText, waiting };
30
45
  },
31
46
  template: `
32
47
  <article class="card" role="listitem" tabindex="0"
48
+ :class="{ 'card--decision': card.status === 'decision_needed' }"
33
49
  @click="emit('open', card)"
34
50
  @keydown.enter="emit('open', card)">
51
+ <div v-if="waiting()" class="card__decision" :class="{ 'is-stale': waiting().stale }">
52
+ <span class="card__decision-label">
53
+ <span class="dot dot--pulse"></span>NEEDS YOU
54
+ </span>
55
+ <span class="card__decision-age">waiting {{ waiting().text }}</span>
56
+ </div>
35
57
  <h3 class="card__title">{{ card.title }}</h3>
36
58
  <p v-if="card.description" class="card__desc">{{ card.description }}</p>
37
59
  <div v-if="card.status === 'rate_limited'" class="card__rl">
38
60
  <svg viewBox="0 0 12 12" width="11" height="11" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" aria-hidden="true"><circle cx="6" cy="6" r="4.6"></circle><path d="M6 3.6V6l1.8 1.2"></path></svg>
39
61
  <span>rate limited · {{ rlText() }}</span>
40
62
  </div>
63
+ <div v-if="proactiveKind()" class="card__rl">
64
+ <StatusChip status="rate_limited" :kind="proactiveKind()" />
65
+ <span v-if="proactiveProvider()">{{ proactiveProvider() }}</span>
66
+ </div>
41
67
  <div class="card__foot">
42
68
  <PriorityChip :priority="card.priority" />
43
- <span class="chip chip--muted">{{ card.type }}</span>
44
69
  <span v-if="card.status === 'in_progress'" class="chip chip--live">
45
70
  <span class="dot dot--pulse"></span>working<template v-if="card.startedAt"> · {{ elapsed() }}</template>
46
71
  </span>
47
72
  <span v-else-if="card.blockedReason" class="chip chip--warn">blocked</span>
48
73
  <span v-if="card.archivedAt" class="chip chip--muted">archived</span>
49
- <span class="card__lane">{{ laneName(card.laneThreadId) }}</span>
74
+ <span class="card__lane">{{ laneName(card.laneGroupId) }}</span>
50
75
  </div>
51
76
  </article>
52
77
  `,
@@ -13,6 +13,7 @@ export default {
13
13
  modelValue: { type: String, default: "" },
14
14
  groups: { type: Array, default: () => [] },
15
15
  placeholder: { type: String, default: "" },
16
+ disabled: { type: Boolean, default: false },
16
17
  },
17
18
  emits: ["update:modelValue"],
18
19
  setup(props, { emit }) {
@@ -55,9 +56,9 @@ export default {
55
56
  <div class="dropdown combobox" ref="rootEl">
56
57
  <div class="combobox__wrap">
57
58
  <input class="input combobox__input" :value="modelValue" :placeholder="placeholder"
58
- role="combobox" :aria-expanded="open" aria-autocomplete="list"
59
+ role="combobox" :aria-expanded="open" aria-autocomplete="list" :disabled="disabled"
59
60
  @input="onInput" @focus="open = true" />
60
- <button type="button" class="combobox__toggle" :class="{ 'is-open': open }"
61
+ <button type="button" class="combobox__toggle" :class="{ 'is-open': open }" :disabled="disabled"
61
62
  aria-label="Show suggestions" tabindex="-1" @click="open = !open">▾</button>
62
63
  </div>
63
64
  <ul v-if="open && filtered.length" class="dropdown__menu" role="listbox">
@@ -33,7 +33,10 @@ export default {
33
33
  <p class="comment__body">{{ c.content }}</p>
34
34
  </div>
35
35
  </li>
36
- <li v-if="!comments.length" class="comment comment--empty">No comments yet.</li>
36
+ <li v-if="!comments.length" class="comment comment--empty">
37
+ <span class="comment__empty-title">No activity yet</span>
38
+ <span class="comment__empty-note">Worker updates, decisions and your notes all land here.</span>
39
+ </li>
37
40
  </ul>
38
41
  `,
39
42
  };
@@ -0,0 +1,128 @@
1
+ /**
2
+ * DirTreePicker — ✅ EDITABLE. Modal browser for picking an absolute directory
3
+ * on the HOST machine (the browser's own dialog only yields a folder name).
4
+ *
5
+ * Pure presentational: it never fetches. One filesystem level is loaded at a
6
+ * time through the async `load(path)` prop (path "" → volume roots), which the
7
+ * parent wires to the data seam (state/useDirBrowser.js → api.listDir). The
8
+ * chosen absolute path leaves via `select`.
9
+ */
10
+
11
+ import { computed, ref, watch, onMounted, onUnmounted } from "../vendor/vue.esm-browser.js";
12
+
13
+ export default {
14
+ name: "DirTreePicker",
15
+ props: {
16
+ open: { type: Boolean, default: false },
17
+ /** async (path: string) => { path, parent, entries: [{ name, path }] } */
18
+ load: { type: Function, required: true },
19
+ value: { type: String, default: "" },
20
+ recent: { type: Array, default: () => [] },
21
+ },
22
+ emits: ["close", "select"],
23
+ setup(props, { emit }) {
24
+ // Breadcrumb chain of entered folders ([] = roots view).
25
+ const stack = ref([]);
26
+ const items = ref([]); // entries of the current level
27
+ const loading = ref(false);
28
+ const error = ref("");
29
+
30
+ const current = computed(() => stack.value[stack.value.length - 1] || null);
31
+
32
+ // Sequence guard: rapid breadcrumb/row clicks fire overlapping loads; only
33
+ // the newest may write, so a slow earlier response can't overwrite the level.
34
+ let loadSeq = 0;
35
+ async function loadLevel(path) {
36
+ const seq = ++loadSeq;
37
+ loading.value = true;
38
+ error.value = "";
39
+ try {
40
+ const listing = await props.load(path || "");
41
+ if (seq !== loadSeq) return;
42
+ items.value = (listing && listing.entries) || [];
43
+ } catch (e) {
44
+ if (seq !== loadSeq) return;
45
+ error.value = (e && e.message) || String(e);
46
+ items.value = [];
47
+ } finally {
48
+ if (seq === loadSeq) loading.value = false;
49
+ }
50
+ }
51
+
52
+ watch(
53
+ () => props.open,
54
+ (open) => {
55
+ if (!open) return;
56
+ stack.value = []; // always reopen at the roots
57
+ loadLevel("");
58
+ },
59
+ );
60
+
61
+ function enter(node) {
62
+ stack.value = [...stack.value, node];
63
+ loadLevel(node.path);
64
+ }
65
+ function jumpTo(i) {
66
+ // i = -1 → roots view; i = index in stack → that folder.
67
+ stack.value = stack.value.slice(0, i + 1);
68
+ loadLevel(i < 0 ? "" : stack.value[i].path);
69
+ }
70
+ function confirm() {
71
+ if (current.value) emit("select", current.value.path);
72
+ }
73
+ function onKey(e) {
74
+ if (e.key === "Escape" && props.open) emit("close");
75
+ }
76
+ onMounted(() => document.addEventListener("keydown", onKey));
77
+ onUnmounted(() => document.removeEventListener("keydown", onKey));
78
+
79
+ return { stack, current, items, loading, error, enter, jumpTo, confirm };
80
+ },
81
+ template: `
82
+ <div v-if="open" class="dtp-overlay" @click.self="$emit('close')">
83
+ <div class="dtp" role="dialog" aria-modal="true" aria-label="Choose working directory">
84
+ <header class="dtp__head">
85
+ <h3 class="dtp__title">Choose working directory</h3>
86
+ <button type="button" class="btn btn--ghost dtp__close" aria-label="Close" @click="$emit('close')">✕</button>
87
+ </header>
88
+
89
+ <nav class="dtp__crumbs" aria-label="Current location">
90
+ <button type="button" class="dtp__crumb dtp__crumb--root" :class="{ 'is-here': !current }" @click="jumpTo(-1)">HOST</button>
91
+ <template v-for="(n, i) in stack" :key="n.path">
92
+ <span class="dtp__crumbsep" aria-hidden="true">›</span>
93
+ <button type="button" class="dtp__crumb" :class="{ 'is-here': i === stack.length - 1 }" @click="jumpTo(i)">{{ n.name }}</button>
94
+ </template>
95
+ </nav>
96
+
97
+ <ul class="dtp__list" role="listbox">
98
+ <li v-if="loading" class="dtp__empty">Loading…</li>
99
+ <li v-else-if="error" class="dtp__empty dtp__empty--error">{{ error }}</li>
100
+ <template v-else>
101
+ <li v-for="n in items" :key="n.path">
102
+ <button type="button" class="dtp__row" @click="enter(n)">
103
+ <svg class="dtp__rowicon" viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M1.8 4.5c0-.7.6-1.3 1.3-1.3h3l1.4 1.5h5.4c.7 0 1.3.6 1.3 1.3v6c0 .7-.6 1.3-1.3 1.3H3.1c-.7 0-1.3-.6-1.3-1.3v-7.5z"/></svg>
104
+ <span class="dtp__rowname">{{ n.name }}</span>
105
+ <span class="dtp__rowchev" aria-hidden="true">›</span>
106
+ </button>
107
+ </li>
108
+ <li v-if="!items.length" class="dtp__empty">No subfolders</li>
109
+ </template>
110
+ </ul>
111
+
112
+ <div v-if="recent.length" class="dtp__recent">
113
+ <span class="dtp__recentlabel mono-label">RECENT</span>
114
+ <button v-for="p in recent" :key="p" type="button" class="dtp__recentchip"
115
+ :class="{ 'is-on': value === p }" @click="$emit('select', p)">{{ p }}</button>
116
+ </div>
117
+
118
+ <footer class="dtp__foot">
119
+ <span class="dtp__path" :class="{ 'is-empty': !current }">{{ current ? current.path : 'Navigate to a folder' }}</span>
120
+ <div class="dtp__actions">
121
+ <button type="button" class="btn btn--ghost" @click="$emit('close')">Cancel</button>
122
+ <button type="button" class="btn btn--primary" :disabled="!current" @click="confirm">Use this folder</button>
123
+ </div>
124
+ </footer>
125
+ </div>
126
+ </div>
127
+ `,
128
+ };
@@ -12,6 +12,7 @@ export default {
12
12
  modelValue: { default: null },
13
13
  options: { type: Array, default: () => [] },
14
14
  placeholder: { type: String, default: "Select…" },
15
+ disabled: { type: Boolean, default: false },
15
16
  },
16
17
  emits: ["update:modelValue"],
17
18
  setup(props, { emit }) {
@@ -43,7 +44,7 @@ export default {
43
44
  },
44
45
  template: `
45
46
  <div class="dropdown" ref="rootEl">
46
- <button type="button" class="dropdown__btn" :class="{ 'is-open': open }"
47
+ <button type="button" class="dropdown__btn" :class="{ 'is-open': open }" :disabled="disabled"
47
48
  aria-haspopup="listbox" :aria-expanded="open" @click="open = !open">
48
49
  <span class="dropdown__value" :class="{ 'is-placeholder': !current }">
49
50
  {{ current ? current.label : placeholder }}
@@ -13,7 +13,8 @@ export default {
13
13
  title: { type: String, required: true },
14
14
  status: { type: String, required: true },
15
15
  cards: { type: Array, default: () => [] },
16
- laneName: { type: Function, default: (id) => `Thread ${id}` },
16
+ laneName: { type: Function, default: () => "Ungrouped" },
17
+ limitedProviders: { type: Array, default: () => [] },
17
18
  },
18
19
  emits: ["open"],
19
20
  setup(props, { emit }) {
@@ -36,9 +37,10 @@ export default {
36
37
  :key="c.cardId"
37
38
  :card="c"
38
39
  :lane-name="laneName"
40
+ :limited-providers="limitedProviders"
39
41
  @open="emit('open', $event)"
40
42
  />
41
- <p v-if="!cards.length" class="lane__empty">Nothing here</p>
43
+ <div v-if="!cards.length" class="lane__empty" aria-hidden="true"></div>
42
44
  </div>
43
45
  </section>
44
46
  `,
@@ -1,10 +1,13 @@
1
1
  /**
2
2
  * Priority chip — ✅ EDITABLE. Pure: `priority` (int) in.
3
3
  * Higher int = higher urgency (matches dispatch ORDER BY priority DESC).
4
- * Dispatch design: tinted pill — Low / Medium / High / Urgent.
4
+ * Labels are P0–P3 with **P0 = most urgent**, so the label is the INVERSE of the
5
+ * stored integer: int 3 → P0, int 0 → P3. Label + colour only — the integer and
6
+ * every sort/filter path stay untouched.
5
7
  */
6
8
 
7
- const LABELS = ["Low", "Medium", "High", "Urgent"];
9
+ /** Indexed by the stored integer. */
10
+ const LABELS = ["P3", "P2", "P1", "P0"];
8
11
 
9
12
  export default {
10
13
  name: "PriorityChip",
@@ -1,39 +1,89 @@
1
1
  /**
2
- * Execution-profile summary — ✅ EDITABLE. Pure: `profile` in.
3
- * Renders the set flags as readable chips; nothing set → a muted note.
2
+ * Execution-plan summary — ✅ EDITABLE. Pure: `profile` in.
3
+ *
4
+ * Reads the real seam shape (api/contract.d.ts ExecutionProfile plus the fields
5
+ * state/useBuilder.js writes: model, autonomy, prDraft, prProvider). Renders the
6
+ * plan as labelled rows — only rows with data appear, so the panel never invents
7
+ * a plan the card does not have. Phases are NOT part of ExecutionProfile and are
8
+ * not persisted anywhere yet, so they are deliberately absent.
4
9
  */
5
10
 
6
11
  import { computed } from "../vendor/vue.esm-browser.js";
7
12
 
8
- const FLAG_LABELS = {
9
- createBranch: "branch",
10
- runTests: "tests",
11
- build: "build",
12
- openPr: "PR",
13
- push: "push",
14
- expertReview: "expert review",
15
- operatorReview: "operator review",
16
- };
13
+ const CI_LABELS = { github: "GitHub Actions", azure: "Azure Pipelines", none: "none" };
14
+
15
+ /** "on"/"off" flag pills for a group of booleans. */
16
+ function flags(profile, spec) {
17
+ const out = [];
18
+ for (const [key, label] of spec) {
19
+ if (profile[key] === undefined) continue;
20
+ out.push({ label, on: !!profile[key] });
21
+ }
22
+ return out;
23
+ }
17
24
 
18
25
  export default {
19
26
  name: "ProfileSummary",
20
27
  props: { profile: { type: Object, default: () => ({}) } },
21
28
  setup(props) {
22
- const items = computed(() => {
23
- const p = props.profile || {};
29
+ const p = computed(() => props.profile || {});
30
+
31
+ const agent = computed(() => {
24
32
  const out = [];
25
- if (p.agentType) out.push(p.agentType);
26
- for (const [k, label] of Object.entries(FLAG_LABELS)) if (p[k]) out.push(label);
27
- if (p.ciCheck && p.ciCheck !== "none") out.push("ci:" + p.ciCheck);
28
- if (Array.isArray(p.skills) && p.skills.length) out.push(p.skills.length + " skill(s)");
29
- return out;
33
+ if (p.value.agentType) out.push(p.value.agentType);
34
+ if (p.value.model) out.push(p.value.model);
35
+ return out.join(" · ");
30
36
  });
31
- return { items };
37
+
38
+ const rows = computed(() => {
39
+ const v = p.value;
40
+ const list = [];
41
+ if (agent.value) list.push({ key: "agent", label: "AGENT", text: agent.value, strong: true });
42
+ if (v.autonomy) list.push({ key: "autonomy", label: "AUTONOMY", text: v.autonomy });
43
+ if (v.repository) list.push({ key: "repo", label: "REPOSITORY", text: v.repository, mono: true });
44
+
45
+ const code = flags(v, [["worktree", "worktree"], ["createBranch", "branch"], ["push", "push"]]);
46
+ if (code.length) list.push({ key: "code", label: "CODE", flags: code });
47
+
48
+ const verify = flags(v, [["runTests", "tests"], ["build", "build"]]);
49
+ if (v.ciCheck && v.ciCheck !== "none") verify.push({ label: CI_LABELS[v.ciCheck] || v.ciCheck, on: true });
50
+ if (verify.length) list.push({ key: "verify", label: "VERIFY", flags: verify });
51
+
52
+ const review = flags(v, [["expertReview", "expert review"], ["operatorReview", "operator review"]]);
53
+ if (v.reviewAgentType) review.push({ label: "by " + v.reviewAgentType, on: true });
54
+ if (review.length) list.push({ key: "review", label: "REVIEW", flags: review });
55
+
56
+ if (v.openPr !== undefined) {
57
+ const pr = [{ label: v.openPr ? "open PR" : "no PR", on: !!v.openPr }];
58
+ if (v.openPr) {
59
+ if (v.prDraft !== undefined) pr.push({ label: v.prDraft ? "draft" : "ready for review", on: true });
60
+ if (v.prProvider) pr.push({ label: v.prProvider, on: true });
61
+ }
62
+ list.push({ key: "pr", label: "PULL REQUEST", flags: pr });
63
+ }
64
+
65
+ if (Array.isArray(v.skills) && v.skills.length) {
66
+ list.push({ key: "skills", label: "SKILLS", flags: v.skills.map((s) => ({ label: s, on: true })) });
67
+ }
68
+ return list;
69
+ });
70
+
71
+ return { rows };
32
72
  },
33
73
  template: `
34
- <div class="profile">
35
- <span v-for="(it, i) in items" :key="i" class="chip chip--live">{{ it }}</span>
36
- <span v-if="!items.length" class="profile__empty">Default profile (no flags set).</span>
74
+ <div class="plan">
75
+ <dl v-if="rows.length" class="plan__rows">
76
+ <div v-for="r in rows" :key="r.key" class="plan__row">
77
+ <dt class="plan__label">{{ r.label }}</dt>
78
+ <dd class="plan__value">
79
+ <span v-if="r.text" class="plan__text" :class="{ 'plan__text--strong': r.strong, 'plan__text--mono': r.mono }">{{ r.text }}</span>
80
+ <span v-if="r.flags" class="plan__flags">
81
+ <span v-for="(f, i) in r.flags" :key="i" class="plan__flag" :class="f.on ? 'is-on' : 'is-off'">{{ f.label }}</span>
82
+ </span>
83
+ </dd>
84
+ </div>
85
+ </dl>
86
+ <p v-else class="plan__empty">No execution plan on this card — the worker runs the lane default.</p>
37
87
  </div>
38
88
  `,
39
89
  };