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
@@ -9,7 +9,8 @@
9
9
 
10
10
  The release channel follows the SAME switch as the MCP server: the tag in
11
11
  MCPStartCommand ("npx -y sensorium-mcp@<tag>"). @latest -> supervisor-latest
12
- (stable, built from main); @refactor -> supervisor-refactor (built from the
12
+ (stable, built from main); @board -> supervisor-board (built from
13
+ feature/agent-task-board); @refactor -> supervisor-refactor (built from the
13
14
  refactor branch). One edit to install.config.json flips both node + supervisor.
14
15
 
15
16
  All configuration is read from ~/.remote-copilot-mcp/install.config.json.
@@ -41,11 +42,25 @@ $ConfigFile = Join-Path $DataDir "install.config.json"
41
42
  $StartupDir = [Environment]::GetFolderPath("Startup")
42
43
  $StartupLauncher = Join-Path $StartupDir "SensoriumSupervisor.cmd"
43
44
 
45
+ # Isolated MCP runtime: a PRIVATE npm cache + a repo-independent cwd for the MCP,
46
+ # both living under $DataDir (never a dev checkout). This severs the shared-cache /
47
+ # shared-cwd coupling that lets a worker's `npm ci`/build in a dev repo interfere
48
+ # with (and kill) the live MCP — WITHOUT pinning the version, so `npx ...@latest`
49
+ # still auto-updates the MCP on each restart. npx also stages its packages in
50
+ # <cache>/_npx, so a private npm cache isolates npx resolution too.
51
+ $McpRuntimeRoot = Join-Path $DataDir "mcp-runtime"
52
+ $McpRuntimeCache = Join-Path $McpRuntimeRoot "npm-cache"
53
+
44
54
  # ── Config File ──────────────────────────────────────────────────────────────
45
55
  $Defaults = @{
46
56
  SecureVaultProfile = "SENSORIUM"
47
57
  UpdateMode = "production"
48
58
  MCPStartCommand = "npx -y sensorium-mcp@latest"
59
+ # Opt-in runtime isolation. When "true", the MCP keeps its `npx ...@latest`
60
+ # start command (so auto-update still works) but is given its OWN npm cache
61
+ # ($McpRuntimeCache) and a repo-independent cwd ($McpRuntimeRoot), decoupled
62
+ # from any dev checkout's shared npm cache / cwd. "false" = legacy behaviour.
63
+ IsolateMcpRuntime = "false"
49
64
  }
50
65
 
51
66
  function Load-Config {
@@ -78,14 +93,16 @@ $Config = Load-Config
78
93
  $SecureVaultProfile = $Config["SecureVaultProfile"]
79
94
  $UpdateMode = $Config["UpdateMode"]
80
95
  $EffectiveMCPStartCommand = $Config["MCPStartCommand"]
96
+ $IsolateMcpRuntime = $Config["IsolateMcpRuntime"] -eq "true"
81
97
 
82
98
  # Resolve the supervisor release channel from the same tag the node server
83
- # follows: the "@<tag>" in MCPStartCommand. Only @refactor uses the branch
84
- # build; everything else (incl. @latest, a bare version pin, or no tag) stays
99
+ # follows: the "@<tag>" in MCPStartCommand. Only @board (supervisor-board, built
100
+ # from feature/agent-task-board) and @refactor (supervisor-refactor) use branch
101
+ # builds; everything else (incl. @latest, a bare version pin, or no tag) stays
85
102
  # on the stable supervisor-latest release. This keeps the stable rollback path
86
103
  # intact — pointing the config back at @latest restores the main supervisor.
87
104
  $mcpTag = if ($EffectiveMCPStartCommand -match 'sensorium-mcp@([A-Za-z0-9._-]+)') { $Matches[1] } else { "latest" }
88
- $ReleaseTag = if ($mcpTag -eq "refactor") { "supervisor-refactor" } else { "supervisor-latest" }
105
+ $ReleaseTag = if ($mcpTag -eq "board") { "supervisor-board" } elseif ($mcpTag -eq "refactor") { "supervisor-refactor" } else { "supervisor-latest" }
89
106
  Write-Host "Supervisor channel: $ReleaseTag (from MCP tag '$mcpTag')" -ForegroundColor Cyan
90
107
 
91
108
  # Validate config values
@@ -102,8 +119,27 @@ Save-Config $Config
102
119
  function Stop-SupervisorProcess {
103
120
  $procs = Get-Process -Name "sensorium-supervisor" -ErrorAction SilentlyContinue
104
121
  if ($procs) {
122
+ # Keep the original PID set. A name-only lookup after stopping can confuse a
123
+ # newly launched process with the instance we were asked to stop.
124
+ $targetPids = @($procs | Select-Object -ExpandProperty Id)
105
125
  Write-Host "Stopping background sensorium-supervisor process(es)..."
106
- $procs | Stop-Process -Force
126
+ $procs | Stop-Process -Force -ErrorAction Stop
127
+
128
+ # Stop-Process returns once a signal has been sent, not once all image/file
129
+ # handles are released. Do not attempt an in-place replacement until every
130
+ # PID we targeted is gone; a continuing process makes the update unsafe.
131
+ $deadline = (Get-Date).AddSeconds(10)
132
+ do {
133
+ $remainingPids = @($targetPids | Where-Object {
134
+ Get-Process -Id $_ -ErrorAction SilentlyContinue
135
+ })
136
+ if ($remainingPids.Count -eq 0) { break }
137
+ Start-Sleep -Milliseconds 250
138
+ } while ((Get-Date) -lt $deadline)
139
+
140
+ if ($remainingPids.Count -gt 0) {
141
+ throw "Refusing to update: sensorium-supervisor PID(s) $($remainingPids -join ', ') did not stop within 10 seconds."
142
+ }
107
143
  Write-Host "Process(es) stopped." -ForegroundColor Yellow
108
144
  }
109
145
  }
@@ -212,7 +248,45 @@ function Save-BinaryMetadata {
212
248
  InstalledAt = (Get-Date).ToString("o")
213
249
  }
214
250
 
215
- $metadata | ConvertTo-Json | Set-Content -LiteralPath $MetadataPath -Encoding ASCII
251
+ # Do not write metadata in place: a failure halfway through a write would make a
252
+ # good binary look stale on the next run. The temp name is unique so concurrent
253
+ # or previously interrupted installs cannot collide with it.
254
+ $metadataTempPath = "$MetadataPath.tmp.$PID.$([guid]::NewGuid().ToString('N'))"
255
+ try {
256
+ $metadata | ConvertTo-Json | Set-Content -LiteralPath $metadataTempPath -Encoding ASCII
257
+ Move-FileWithRetry -Source $metadataTempPath -Destination $MetadataPath -Operation "update release metadata"
258
+ }
259
+ finally {
260
+ if (Test-Path -LiteralPath $metadataTempPath) {
261
+ Remove-Item -LiteralPath $metadataTempPath -Force -ErrorAction SilentlyContinue
262
+ }
263
+ }
264
+ }
265
+
266
+ function Move-FileWithRetry {
267
+ param(
268
+ [string]$Source,
269
+ [string]$Destination,
270
+ [string]$Operation = "replace file",
271
+ [int]$MaxAttempts = 20,
272
+ [int]$RetryDelayMs = 1500
273
+ )
274
+
275
+ for ($attempt = 1; $attempt -le $MaxAttempts; $attempt++) {
276
+ try {
277
+ Move-Item -LiteralPath $Source -Destination $Destination -Force -ErrorAction Stop
278
+ return
279
+ }
280
+ catch {
281
+ if ($attempt -eq $MaxAttempts) {
282
+ throw "Failed to $Operation at $Destination after $MaxAttempts attempts (~$([math]::Round($MaxAttempts * $RetryDelayMs / 1000))s). Original error: $_"
283
+ }
284
+ if ($attempt % 4 -eq 0) {
285
+ Write-Host " ... waiting to $Operation (attempt $attempt/$MaxAttempts)..." -ForegroundColor Yellow
286
+ }
287
+ Start-Sleep -Milliseconds $RetryDelayMs
288
+ }
289
+ }
216
290
  }
217
291
 
218
292
  function Get-BinaryAsset {
@@ -229,7 +303,13 @@ function Get-BinaryAsset {
229
303
  $headers = Get-GithubAuthHeaders -Accept "application/octet-stream"
230
304
  Write-Host "Downloading $($AssetInfo.AssetName) ..."
231
305
 
232
- $tmpFile = "$Destination.tmp"
306
+ $operationId = "$PID.$([guid]::NewGuid().ToString('N'))"
307
+ $tmpFile = "$Destination.tmp.$operationId"
308
+ $backupPath = "$Destination.bak.$operationId"
309
+ $metadataBackupPath = "$MetadataPath.bak.$operationId"
310
+ $hadBinary = Test-Path -LiteralPath $Destination
311
+ $hadMetadata = Test-Path -LiteralPath $MetadataPath
312
+ $swapped = $false
233
313
  try {
234
314
  Invoke-WebRequest -Uri $downloadUrl -Headers $headers -OutFile $tmpFile -UseBasicParsing -ErrorAction Stop
235
315
  }
@@ -241,15 +321,74 @@ function Get-BinaryAsset {
241
321
  throw "Download failed: $_"
242
322
  }
243
323
 
244
- # Atomic replace
245
- if (Test-Path $Destination) {
246
- $backupPath = "$Destination.bak"
247
- Copy-Item $Destination $backupPath -Force
324
+ try {
325
+ # Preserve both halves of the installed state. If anything after the
326
+ # executable swap fails (notably metadata persistence), restore the pair.
327
+ if ($hadBinary) { Copy-Item -LiteralPath $Destination -Destination $backupPath -Force -ErrorAction Stop }
328
+ if ($hadMetadata) { Copy-Item -LiteralPath $MetadataPath -Destination $metadataBackupPath -Force -ErrorAction Stop }
329
+
330
+ # The old exe can still be locked for a while after Stop-Process — AV/EDR
331
+ # may retain its image-section handle during a post-exit scan.
332
+ Move-FileWithRetry -Source $tmpFile -Destination $Destination -Operation "replace supervisor binary"
333
+ $swapped = $true
334
+
335
+ try {
336
+ Unblock-File -Path $Destination -ErrorAction Stop
337
+ }
338
+ catch {
339
+ Write-Host "[WARN] Could not unblock ${Destination}: $($_.Exception.Message)" -ForegroundColor Yellow
340
+ }
341
+
342
+ Save-BinaryMetadata -MetadataPath $MetadataPath -AssetInfo $AssetInfo
343
+ Write-Host "Binary placed at: $Destination" -ForegroundColor Green
344
+ }
345
+ catch {
346
+ $updateError = $_
347
+ if ($swapped) {
348
+ Write-Host "[WARN] Update failed after binary replacement; restoring the previous binary and metadata..." -ForegroundColor Yellow
349
+ $restoreErrors = @()
350
+ try {
351
+ if ($hadBinary) {
352
+ $restoreFile = "$Destination.restore.$operationId"
353
+ Copy-Item -LiteralPath $backupPath -Destination $restoreFile -Force -ErrorAction Stop
354
+ Move-FileWithRetry -Source $restoreFile -Destination $Destination -Operation "restore previous supervisor binary"
355
+ }
356
+ elseif (Test-Path -LiteralPath $Destination) {
357
+ Remove-Item -LiteralPath $Destination -Force -ErrorAction Stop
358
+ }
359
+ }
360
+ catch { $restoreErrors += "binary: $($_.Exception.Message)" }
361
+
362
+ try {
363
+ if ($hadMetadata) {
364
+ # Stage the backup under a unique name, then use the same
365
+ # retrying replacement path as the binary. Copy-Item directly
366
+ # to $MetadataPath could leave metadata restoration vulnerable
367
+ # to a locked destination and bypass the retry policy.
368
+ $metadataRestoreFile = "$MetadataPath.restore.$operationId"
369
+ Copy-Item -LiteralPath $metadataBackupPath -Destination $metadataRestoreFile -Force -ErrorAction Stop
370
+ Move-FileWithRetry -Source $metadataRestoreFile -Destination $MetadataPath -Operation "restore previous release metadata"
371
+ }
372
+ elseif (Test-Path -LiteralPath $MetadataPath) {
373
+ Remove-Item -LiteralPath $MetadataPath -Force -ErrorAction Stop
374
+ }
375
+ }
376
+ catch { $restoreErrors += "metadata: $($_.Exception.Message)" }
377
+
378
+ if ($restoreErrors.Count -gt 0) {
379
+ throw "Update failed and recovery was incomplete ($($restoreErrors -join '; ')). Original error: $($updateError.Exception.Message)"
380
+ }
381
+ throw "Update failed after replacement; the previous binary and metadata were restored. Original error: $($updateError.Exception.Message)"
382
+ }
383
+ throw
384
+ }
385
+ finally {
386
+ foreach ($path in @($tmpFile, $backupPath, $metadataBackupPath, "$Destination.restore.$operationId", "$MetadataPath.restore.$operationId")) {
387
+ if (Test-Path -LiteralPath $path) {
388
+ Remove-Item -LiteralPath $path -Force -ErrorAction SilentlyContinue
389
+ }
390
+ }
248
391
  }
249
- Move-Item $tmpFile $Destination -Force
250
- Unblock-File -Path $Destination -ErrorAction SilentlyContinue
251
- Save-BinaryMetadata -MetadataPath $MetadataPath -AssetInfo $AssetInfo
252
- Write-Host "Binary placed at: $Destination" -ForegroundColor Green
253
392
  }
254
393
 
255
394
  function Install-StartupLauncher {
@@ -306,10 +445,44 @@ function Test-SecureVaultAvailable {
306
445
  catch { return $false }
307
446
  }
308
447
 
448
+ function Initialize-IsolatedMcpRuntime {
449
+ <#
450
+ Prepares the PRIVATE MCP runtime area: a dedicated npm cache and a
451
+ repo-independent cwd, both under $McpRuntimeRoot. It does NOT install or pin
452
+ any package — the MCP keeps its `npx ...@latest` start command so auto-update
453
+ still works; isolation comes purely from the private cache + cwd handed to the
454
+ supervisor (and thus to npx) via Start-Supervisor. Idempotent; only creates dirs.
455
+ #>
456
+ Write-Host "Isolated MCP runtime enabled — preparing private cache + cwd..." -ForegroundColor Cyan
457
+ Write-Host " Runtime cwd : $McpRuntimeRoot"
458
+ Write-Host " npm cache : $McpRuntimeCache (npx stages under $McpRuntimeCache\_npx)"
459
+
460
+ try {
461
+ New-Item -ItemType Directory -Path $McpRuntimeRoot -Force | Out-Null
462
+ New-Item -ItemType Directory -Path $McpRuntimeCache -Force | Out-Null
463
+ }
464
+ catch {
465
+ Write-Host "[WARN] Could not create isolated runtime dirs: $($_.Exception.Message) — keeping legacy behaviour." -ForegroundColor Yellow
466
+ return $false
467
+ }
468
+ return $true
469
+ }
470
+
309
471
  function Start-Supervisor {
310
472
  $env:SUPERVISOR_UPDATE_MODE = $UpdateMode
311
473
  $env:MCP_START_COMMAND = $EffectiveMCPStartCommand
312
474
 
475
+ # In isolated mode, hand the supervisor a private npm cache and a repo-independent
476
+ # cwd. The supervisor inherits its whole environment and passes it to the MCP, so
477
+ # NPM_CONFIG_CACHE reaches the `npx ...@latest` child automatically (isolating both
478
+ # the npm cache and npx's <cache>\_npx staging); MCP_WORKING_DIR is consumed by the
479
+ # supervisor to set the MCP's spawn cwd. The `@latest` command is unchanged, so
480
+ # auto-update keeps working — only WHERE npx resolves/caches changes.
481
+ if ($IsolateMcpRuntime) {
482
+ $env:NPM_CONFIG_CACHE = $McpRuntimeCache
483
+ $env:MCP_WORKING_DIR = $McpRuntimeRoot
484
+ }
485
+
313
486
  $useSecureVault = (-not [string]::IsNullOrWhiteSpace($SecureVaultProfile)) -and (Test-SecureVaultAvailable)
314
487
 
315
488
  if ($useSecureVault) {
@@ -390,7 +563,7 @@ function Sync-ReleaseBinary {
390
563
  Write-Host "Fetching release via SecureVault (profile: $SecureVaultProfile)..."
391
564
  securevault run pwsh -NoProfile -File "`"$PSCommandPath`"" -SyncReleaseOnly --profile $SecureVaultProfile
392
565
  if ($LASTEXITCODE -ne 0) {
393
- throw "SecureVault-driven release sync failed (exit $LASTEXITCODE). Ensure profile '$SecureVaultProfile' maps a GitHub PAT to env var SENSORIUM_GH_TOKEN."
566
+ throw "SecureVault-driven release sync failed (exit $LASTEXITCODE). See the error above for the actual cause (e.g. a locked binary, network failure, or a missing GitHub PAT for profile '$SecureVaultProfile' -> `$env:SENSORIUM_GH_TOKEN)."
394
567
  }
395
568
  }
396
569
 
@@ -402,35 +575,76 @@ if ($SyncReleaseOnly) {
402
575
  }
403
576
 
404
577
  # ── Main ─────────────────────────────────────────────────────────────────────
405
- $alreadyExists = Test-Path $Binary
578
+ # Serialize only full installer invocations for this Windows user. The
579
+ # SecureVault child above deliberately returns before this point, so it can do
580
+ # the authenticated release sync without waiting on (and deadlocking with) its
581
+ # parent installer process.
582
+ $currentUserSid = [Security.Principal.WindowsIdentity]::GetCurrent().User.Value
583
+ $installMutexName = "Local\SensoriumSupervisor.Install.$($currentUserSid -replace '[^A-Za-z0-9_.-]', '_')"
584
+ $installMutex = [System.Threading.Mutex]::new($false, $installMutexName)
585
+ $mutexHeld = $false
586
+
587
+ try {
588
+ try {
589
+ $mutexHeld = $installMutex.WaitOne([TimeSpan]::FromMinutes(5))
590
+ }
591
+ catch [System.Threading.AbandonedMutexException] {
592
+ # The prior installer died without releasing the mutex; Windows has given
593
+ # us ownership, so continue while making that state visible to the user.
594
+ $mutexHeld = $true
595
+ Write-Host "[WARN] Recovered an abandoned installer mutex; continuing." -ForegroundColor Yellow
596
+ }
406
597
 
407
- Write-Host ""
408
- if ($alreadyExists) {
409
- Write-Host "=== Sensorium Supervisor UPDATE ===" -ForegroundColor Cyan
410
- }
411
- else {
412
- Write-Host "=== Sensorium Supervisor INSTALL ===" -ForegroundColor Cyan
413
- }
414
- Write-Host "SecureVault profile: $(if ([string]::IsNullOrWhiteSpace($SecureVaultProfile)) { '<disabled>' } else { $SecureVaultProfile })"
415
- Write-Host "Watcher mode: $UpdateMode"
416
- Write-Host "MCP start command: $EffectiveMCPStartCommand"
417
- Write-Host "Binary : $Binary"
418
- Write-Host ""
419
-
420
- # Step 1 — stop existing instance
421
- if ($alreadyExists) {
422
- Stop-SupervisorProcess
423
- }
598
+ if (-not $mutexHeld) {
599
+ throw "Another Sensorium install/update is still running for this user. Timed out waiting for it to finish."
600
+ }
424
601
 
425
- # Step 2 — ensure bin dir exists
426
- New-Item -ItemType Directory -Path $BinDir -Force | Out-Null
602
+ $alreadyExists = Test-Path $Binary
427
603
 
428
- # Step 3 — fetch release metadata and download only when needed
429
- Sync-ReleaseBinary
604
+ Write-Host ""
605
+ if ($alreadyExists) {
606
+ Write-Host "=== Sensorium Supervisor UPDATE ===" -ForegroundColor Cyan
607
+ }
608
+ else {
609
+ Write-Host "=== Sensorium Supervisor INSTALL ===" -ForegroundColor Cyan
610
+ }
611
+ Write-Host "SecureVault profile: $(if ([string]::IsNullOrWhiteSpace($SecureVaultProfile)) { '<disabled>' } else { $SecureVaultProfile })"
612
+ Write-Host "Watcher mode: $UpdateMode"
613
+ Write-Host "MCP start command: $EffectiveMCPStartCommand"
614
+ Write-Host "MCP runtime isolation: $(if ($IsolateMcpRuntime) { 'ENABLED' } else { 'disabled (legacy npx)' })"
615
+ Write-Host "Binary : $Binary"
616
+ Write-Host ""
617
+
618
+ # Step 1 — stop existing instance
619
+ if ($alreadyExists) {
620
+ Stop-SupervisorProcess
621
+ }
622
+
623
+ # Step 2 — ensure bin dir exists
624
+ New-Item -ItemType Directory -Path $BinDir -Force | Out-Null
625
+
626
+ # Step 3 — fetch release metadata and download only when needed
627
+ Sync-ReleaseBinary
628
+
629
+ # Step 3b — prepare the isolated MCP runtime area (opt-in): a private npm cache +
630
+ # repo-independent cwd. The `npx ...@latest` command is unchanged (auto-update
631
+ # preserved). On any failure this disables the isolation env in Start-Supervisor,
632
+ # so the install degrades safely to legacy behaviour.
633
+ if ($IsolateMcpRuntime) {
634
+ if (-not (Initialize-IsolatedMcpRuntime)) {
635
+ $IsolateMcpRuntime = $false
636
+ Write-Host "[WARN] Isolation disabled for this run — using the shared npm cache / inherited cwd." -ForegroundColor Yellow
637
+ }
638
+ }
430
639
 
431
- # Step 4 — install launcher and start
432
- Install-StartupLauncher
433
- Start-Supervisor
640
+ # Step 4 — install launcher and start
641
+ Install-StartupLauncher
642
+ Start-Supervisor
434
643
 
435
- # Step 5 — verify
436
- Show-Status
644
+ # Step 5 — verify
645
+ Show-Status
646
+ }
647
+ finally {
648
+ if ($mutexHeld) { $installMutex.ReleaseMutex() }
649
+ if ($installMutex) { $installMutex.Dispose() }
650
+ }
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.
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Data-adapter switch. ❌ FROZEN SEAM — the ONLY seam is data.
3
+ *
4
+ * MODE decides the implementation ONCE, lazily:
5
+ * - preview → mock/api.mock.js is DYNAMICALLY imported (so not a single mock
6
+ * byte is loaded in production).
7
+ * - production → api/client.js (real fetch).
8
+ *
9
+ * Every method returns a Promise and forwards to the resolved adapter, so callers
10
+ * (state/ composables) never know or care which one is live.
11
+ *
12
+ * @typedef {import('./contract.js').BoardApi} BoardApi
13
+ */
14
+
15
+ import { MODE } from "../config.js";
16
+
17
+ let implPromise = null;
18
+
19
+ /** @returns {Promise<BoardApi>} */
20
+ function load() {
21
+ if (!implPromise) {
22
+ implPromise = (
23
+ MODE === "preview"
24
+ ? import("../mock/api.mock.js").then((m) => m.mockApi)
25
+ : import("./client.js").then((m) => m.client)
26
+ ).then(assertAdapterComplete);
27
+ }
28
+ return implPromise;
29
+ }
30
+
31
+ const METHODS = [
32
+ "listCards",
33
+ "getCard",
34
+ "createCard",
35
+ "previewBriefing",
36
+ "updateCard",
37
+ "deleteCard",
38
+ "stopCard",
39
+ "addComment",
40
+ "postDecision",
41
+ "listLaneGroups",
42
+ "getProfiles",
43
+ "saveProfile",
44
+ "threadRunning",
45
+ "threadLogs",
46
+ // Card-builder "How" schema + presets.
47
+ "getPolicySchema",
48
+ "getPresets",
49
+ "createLaneGroup",
50
+ "updateLaneGroup",
51
+ "deleteLaneGroup",
52
+ // Working-directory picker: one filesystem level per call (lazy browse).
53
+ "listDir",
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
+
78
+ /** @type {BoardApi} */
79
+ const api = /** @type {any} */ ({});
80
+ for (const name of METHODS) {
81
+ api[name] = (...args) => load().then((impl) => impl[name](...args));
82
+ }
83
+
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
+ });
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Production data adapter. ❌ FROZEN SEAM.
3
+ *
4
+ * Real `fetch` to the board API. Root-relative `/api/...` paths (never a host or
5
+ * port) so the app works unchanged behind the Dev Tunnel. This is the ONLY module
6
+ * that talks to the network.
7
+ *
8
+ * @typedef {import('./contract.js').BoardApi} BoardApi
9
+ * @typedef {import('./contract.js').BoardCard} BoardCard
10
+ */
11
+
12
+ import { API_BASE } from "../config.js";
13
+
14
+ /**
15
+ * @param {string} method
16
+ * @param {string} path
17
+ * @param {unknown} [body]
18
+ */
19
+ async function req(method, path, body) {
20
+ const headers = {};
21
+ if (body !== undefined) headers["Content-Type"] = "application/json";
22
+
23
+ const res = await fetch(`${API_BASE}${path}`, {
24
+ method,
25
+ headers,
26
+ ...(body !== undefined ? { body: JSON.stringify(body) } : {}),
27
+ });
28
+
29
+ const text = await res.text();
30
+ let data = null;
31
+ if (text) {
32
+ try {
33
+ data = JSON.parse(text);
34
+ } catch {
35
+ data = { error: text };
36
+ }
37
+ }
38
+ if (!res.ok) {
39
+ const msg = (data && data.error) || `${res.status} ${res.statusText}`;
40
+ const err = new Error(msg);
41
+ err.status = res.status;
42
+ throw err;
43
+ }
44
+ return data;
45
+ }
46
+
47
+ /** @type {BoardApi} */
48
+ export const client = {
49
+ listCards({ includeArchived = false } = {}) {
50
+ const p = new URLSearchParams();
51
+ if (includeArchived) p.set("includeArchived", "1");
52
+ const qs = p.toString();
53
+ return req("GET", `/api/board/cards${qs ? `?${qs}` : ""}`);
54
+ },
55
+ getCard(id) {
56
+ return req("GET", `/api/board/cards/${id}`);
57
+ },
58
+ createCard(card) {
59
+ return req("POST", "/api/board/cards", card).then((d) => d.card);
60
+ },
61
+ previewBriefing(draft) {
62
+ return req("POST", "/api/board/cards/preview", draft).then((d) => d.briefing);
63
+ },
64
+ updateCard(id, patch) {
65
+ return req("PATCH", `/api/board/cards/${id}`, patch).then((d) => d.card);
66
+ },
67
+ deleteCard(id) {
68
+ return req("DELETE", `/api/board/cards/${id}`).then(() => undefined);
69
+ },
70
+ stopCard(id) {
71
+ return req("POST", `/api/board/cards/${id}/stop`, {}).then((d) => d.card);
72
+ },
73
+ addComment(id, content) {
74
+ return req("POST", `/api/board/cards/${id}/comments`, { content }).then((d) => d.comment);
75
+ },
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);
90
+ },
91
+ getProfiles() {
92
+ return req("GET", "/api/board/profiles").then((d) => d.profiles);
93
+ },
94
+ saveProfile(input) {
95
+ return req("POST", "/api/board/profiles", input).then((d) => d.profile);
96
+ },
97
+ threadRunning(threadId) {
98
+ return req("GET", `/api/threads/${threadId}/running`).then((d) => !!d.running);
99
+ },
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
+ },
104
+ getPolicySchema() {
105
+ return req("GET", "/api/board/policy").then((d) => d.schema);
106
+ },
107
+ getPresets() {
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 || "")}`);
112
+ },
113
+ };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Bottom navigation — ✅ EDITABLE. Pure: `active` in, `navigate` out.
3
+ * Thumb-reach primary nav (board / new / settings).
4
+ */
5
+
6
+ export default {
7
+ name: "BottomNav",
8
+ props: { active: { type: String, default: "board" } },
9
+ emits: ["navigate"],
10
+ setup(props, { emit }) {
11
+ const items = [
12
+ { name: "board", to: "/board", label: "Board", icon: "▦" },
13
+ { name: "settings", to: "/settings", label: "Settings", icon: "⚙" },
14
+ ];
15
+ return { items, emit };
16
+ },
17
+ template: `
18
+ <nav class="bottom-nav">
19
+ <button
20
+ v-for="it in items"
21
+ :key="it.name"
22
+ type="button"
23
+ class="bottom-nav__item"
24
+ :class="{ 'is-active': active === it.name }"
25
+ @click="emit('navigate', it.to)"
26
+ >
27
+ <span class="bottom-nav__icon" aria-hidden="true">{{ it.icon }}</span>
28
+ <span class="bottom-nav__label">{{ it.label }}</span>
29
+ </button>
30
+ </nav>
31
+ `,
32
+ };