elanous 0.2.9 → 0.2.11

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 (694) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/Y4zKzL62sakG5momz3SoQ/_buildManifest.js +1 -0
  4. package/apps/pwa/out/_next/static/chunks/1159-0c5ef8bc21cb6afb.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/1394-556de6d71bbdb0fb.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1452.93700483b9d4fc61.js +9 -0
  7. package/apps/pwa/out/_next/static/chunks/{6062-73e68343a9814f6a.js → 1829-b453a1b22d3999bb.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/2176-c379e3ebce874151.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/2310-7a59f043f6db207e.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/2426.8c6ee0c668d53def.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/2548-6e316138d347cefe.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/3170-7ec60a56fa0e4728.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/3278-ae6ef084769f6195.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/3454-988a53dac60a1763.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/3638-aa80b4641ea439db.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/3735-fe3402553ac1c9c6.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/3869-a39d1d9921e10d43.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/390.c373e31b3b9d0c41.js +5 -0
  19. package/apps/pwa/out/_next/static/chunks/3992-2e522a8ac5f2afde.js +25 -0
  20. package/apps/pwa/out/_next/static/chunks/4215-c9d91dd644ec1719.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/4508-5d0161d1e724d735.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/4685-c3c1c625b71accd1.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/4733-623a79345b171e1c.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/4883.3bd969ea1d3aaaff.js +2 -0
  25. package/apps/pwa/out/_next/static/chunks/507-5acd98bd6dab2d8a.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/5445-745eb795c5963d79.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/5532.6899a12958a89b72.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/5845-e6c003ce8d5fd36a.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/5978-b27004c677119115.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/{8046cadf-211ca3c0e00f2b72.js → 5cd7e3a9-404fd6b8d0ecd44c.js} +1 -1
  31. package/apps/pwa/out/_next/static/chunks/6048-4c5c33579bc4ef78.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/6303-422dbf0f67c72aac.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/6751-bb3595948b2e311b.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/7274-19b7279f18b47ab3.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/{4323.c5dfb6f503304775.js → 7334.a6679d9168f37aa8.js} +1 -1
  36. package/apps/pwa/out/_next/static/chunks/7551-a0e0707b79164ddd.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/7777-79f845045aa1ed86.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/79f8be9e-957d68913b590b08.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/8025-cc24ee5d8f2fb6f8.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/8039-df92e08fede5de8f.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/8206-c6684dcde12be721.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/8421-1c4acfb1395a0edf.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/8605-ea5bee9dfae512c7.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/8725.bf46bb1395dd0fa2.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/8734-252d511cd276c0dc.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/8834-ca1cb09c1cb1a6bf.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{2415.ed6428ff334c7ce2.js → 9269.d2a4795bc6812717.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/9538-2816b90923606459.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/9656-c1540088f5859c80.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/9906-482c6619b3fdda20.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d16993889b125c42.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/app/approvals/page-1dcdc58fc2de2454.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-6a061bd97f0b9398.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/app/board/page-cb95a7432c9ee744.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-f972fc1c00a62e88.js → page-b12b6d2f8d2d1aea.js} +1 -1
  56. package/apps/pwa/out/_next/static/chunks/app/bots/page-b9efe868bfd36255.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/app/chat/page-7c97dcdfe2e37a60.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/app/consult/page-8fd36984f549270a.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/app/control/page-5721537ca8a3598c.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/app/design-check/page-b654240a572e4c48.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/app/editor/page-b9750abc897508c3.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/app/exec/page-4cd1de371f8ad048.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/app/field/page-d99f89657828421c.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/app/healthz/route-d16993889b125c42.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/app/inside/page-50cb2a0eb15e6c83.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/app/intake/page-c8b1ccda6ba7ae98.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/app/layout-d6b1d156fb95e74b.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/app/live/page-2a9932ddb62d76bd.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/app/market/page-9688f5b4f1ff950f.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-6b15dd6456c5df09.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/app/morning/{page-adfbd2ba9598e59a.js → page-35414e0a007b4082.js} +1 -1
  72. package/apps/pwa/out/_next/static/chunks/app/not-found-e7a529e0507ac86c.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/app/observatory/page-e001823c35c9dd67.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-371423d1a573d64b.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-4b764b125339ac17.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cdf8e4b01067bcf1.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3a24072b35470157.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/app/page-94c82eb0ae5abb32.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/app/reflection/page-0be8d4b2ced75ba0.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d37cb0d52f9b6bd5.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/app/sessions/page-686da0df9bf23e5c.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-4dc614f3ce043e63.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/app/settings/page-53f80edc6b8dc07c.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-d02c782fc792e2af.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/app/setup/layout-d16993889b125c42.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/app/setup/page-239c17b911b84e72.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/app/share/page-dc6a79fb003f746c.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/app/showroom/page-0fffb84cafdc9da6.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/app/tasks/page-1218753c82d585f6.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/app/term/page-4b5935e67531efb5.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/app/today/page-3285bc87caf1eaa5.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/app/trace/page-ad553b0e06505ecd.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/app/vault/page-fca096e3e860306f.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ebfa78f0d9885c3.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/app/workflows/page-3dc5f21f7e39622d.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/app/workspace/page-c6da2b468454532d.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-93bc70e36f595414.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/{2ea96958-e8c7e112de50b067.js → f48170cc-d05d28bf87a43bf4.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/framework-172630e6aa5e2d7f.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/main-app-f0fe2d7477845181.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/main-fc98ac70b44eccb0.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/pages/_app-5bd7f10271f72413.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/pages/_error-97d0d85ea05fef9b.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/webpack-9e4d02d567b98240.js +1 -0
  105. package/apps/pwa/out/_next/static/css/543f56bcb1f79fca.css +1 -0
  106. package/apps/pwa/out/approvals/index.html +1 -1
  107. package/apps/pwa/out/approvals/index.txt +23 -23
  108. package/apps/pwa/out/autopilot/index.html +1 -1
  109. package/apps/pwa/out/autopilot/index.txt +23 -23
  110. package/apps/pwa/out/board/index.html +1 -1
  111. package/apps/pwa/out/board/index.txt +23 -23
  112. package/apps/pwa/out/botlab/index.html +1 -1
  113. package/apps/pwa/out/botlab/index.txt +22 -22
  114. package/apps/pwa/out/bots/index.html +1 -1
  115. package/apps/pwa/out/bots/index.txt +22 -22
  116. package/apps/pwa/out/chat/index.html +1 -1
  117. package/apps/pwa/out/chat/index.txt +22 -22
  118. package/apps/pwa/out/consult/index.html +1 -1
  119. package/apps/pwa/out/consult/index.txt +23 -23
  120. package/apps/pwa/out/control/index.html +1 -1
  121. package/apps/pwa/out/control/index.txt +23 -23
  122. package/apps/pwa/out/design-check/index.html +1 -1
  123. package/apps/pwa/out/design-check/index.txt +23 -23
  124. package/apps/pwa/out/editor/index.html +1 -1
  125. package/apps/pwa/out/editor/index.txt +23 -23
  126. package/apps/pwa/out/exec/index.html +1 -1
  127. package/apps/pwa/out/exec/index.txt +23 -23
  128. package/apps/pwa/out/field/index.html +1 -1
  129. package/apps/pwa/out/field/index.txt +23 -23
  130. package/apps/pwa/out/healthz +1 -1
  131. package/apps/pwa/out/index.html +1 -1
  132. package/apps/pwa/out/index.txt +22 -22
  133. package/apps/pwa/out/inside/index.html +1 -0
  134. package/apps/pwa/out/inside/index.txt +31 -0
  135. package/apps/pwa/out/intake/index.html +1 -1
  136. package/apps/pwa/out/intake/index.txt +23 -23
  137. package/apps/pwa/out/live/index.html +1 -1
  138. package/apps/pwa/out/live/index.txt +23 -23
  139. package/apps/pwa/out/market/index.html +1 -1
  140. package/apps/pwa/out/market/index.txt +22 -22
  141. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  142. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  143. package/apps/pwa/out/morning/index.html +1 -1
  144. package/apps/pwa/out/morning/index.txt +23 -23
  145. package/apps/pwa/out/observatory/index.html +1 -1
  146. package/apps/pwa/out/observatory/index.txt +23 -23
  147. package/apps/pwa/out/ops/checklist/index.html +1 -1
  148. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  149. package/apps/pwa/out/ops/release/index.html +1 -1
  150. package/apps/pwa/out/ops/release/index.txt +22 -22
  151. package/apps/pwa/out/ops/seats/index.html +1 -0
  152. package/apps/pwa/out/ops/seats/index.txt +30 -0
  153. package/apps/pwa/out/outputs/index.html +1 -0
  154. package/apps/pwa/out/outputs/index.txt +30 -0
  155. package/apps/pwa/out/reflection/index.html +1 -1
  156. package/apps/pwa/out/reflection/index.txt +23 -23
  157. package/apps/pwa/out/scheduler/index.html +1 -1
  158. package/apps/pwa/out/scheduler/index.txt +23 -23
  159. package/apps/pwa/out/sessions/index.html +1 -1
  160. package/apps/pwa/out/sessions/index.txt +22 -22
  161. package/apps/pwa/out/settings/devices/index.html +1 -1
  162. package/apps/pwa/out/settings/devices/index.txt +23 -23
  163. package/apps/pwa/out/settings/index.html +1 -1
  164. package/apps/pwa/out/settings/index.txt +23 -23
  165. package/apps/pwa/out/setup/done/index.html +1 -1
  166. package/apps/pwa/out/setup/done/index.txt +23 -23
  167. package/apps/pwa/out/setup/index.html +1 -1
  168. package/apps/pwa/out/setup/index.txt +23 -23
  169. package/apps/pwa/out/share/index.html +1 -1
  170. package/apps/pwa/out/share/index.txt +23 -23
  171. package/apps/pwa/out/showroom/index.html +1 -1
  172. package/apps/pwa/out/showroom/index.txt +22 -22
  173. package/apps/pwa/out/tasks/index.html +1 -1
  174. package/apps/pwa/out/tasks/index.txt +23 -23
  175. package/apps/pwa/out/term/index.html +1 -1
  176. package/apps/pwa/out/term/index.txt +23 -24
  177. package/apps/pwa/out/today/index.html +1 -0
  178. package/apps/pwa/out/today/index.txt +33 -0
  179. package/apps/pwa/out/trace/index.html +1 -1
  180. package/apps/pwa/out/trace/index.txt +23 -23
  181. package/apps/pwa/out/vault/index.html +1 -1
  182. package/apps/pwa/out/vault/index.txt +23 -23
  183. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  184. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  185. package/apps/pwa/out/workflows/index.html +1 -1
  186. package/apps/pwa/out/workflows/index.txt +23 -23
  187. package/apps/pwa/out/workspace/index.html +1 -1
  188. package/apps/pwa/out/workspace/index.txt +23 -24
  189. package/apps/pwa/out/worktrees/index.html +1 -1
  190. package/apps/pwa/out/worktrees/index.txt +23 -23
  191. package/graphs/drafts/draft-cleanup.yaml +19 -0
  192. package/graphs/drafts/recipes.yaml +23 -0
  193. package/graphs/field/field-feed.yaml +2 -0
  194. package/graphs/implement-loop.yaml +1 -1
  195. package/graphs/intake/intake-daily.yaml +2 -1
  196. package/graphs/ops/recipes.yaml +3 -0
  197. package/graphs/ops/secret-exposure.yaml +24 -0
  198. package/graphs/release/recipes.yaml +3 -0
  199. package/graphs/release/release-loop.yaml +4 -1
  200. package/graphs/video/explainer-line.yaml +2 -2
  201. package/package.json +2 -1
  202. package/plugins/card-followup/graphs/run-step.ts +48 -13
  203. package/plugins/doc-draft/graphs/doc-draft.yaml +3 -3
  204. package/plugins/doc-draft/graphs/run-step.ts +13 -6
  205. package/plugins/elanous-hwp/README.md +25 -0
  206. package/plugins/elanous-hwp/cli.ts +22 -0
  207. package/plugins/elanous-hwp/converter.ts +237 -0
  208. package/plugins/elanous-hwp/fixtures/fixed-controls.hwpx +0 -0
  209. package/plugins/elanous-hwp/fixtures/fixed-table-controls.hwpx +0 -0
  210. package/plugins/elanous-hwp/fixtures/fixed.hwpx +0 -0
  211. package/plugins/elanous-hwp/plugin.json +16 -0
  212. package/plugins/elanous-hwp/plugin.ts +40 -0
  213. package/scripts/ci-public-export-leak-gate.ts +75 -14
  214. package/scripts/ci-public-leak-gate.ts +44 -9
  215. package/scripts/ci-pwa-build-gate.ts +160 -0
  216. package/scripts/context-hooks/claude-stop.sh +4 -0
  217. package/scripts/context-hooks/emit.ts +24 -0
  218. package/scripts/context-hooks/post-tool-use.sh +4 -0
  219. package/scripts/coord-channel-watch.sh +54 -8
  220. package/scripts/coord-digest.ts +199 -0
  221. package/scripts/coord-post.sh +60 -3
  222. package/scripts/coord-requests-bridge.ts +143 -0
  223. package/scripts/field-feed/lib.ts +4 -0
  224. package/scripts/fleet/node-setup.sh +20 -3
  225. package/scripts/homebrew-formula-bump.ts +69 -0
  226. package/scripts/install.ps1 +68 -9
  227. package/scripts/install.sh +39 -12
  228. package/scripts/lib/pwa-scenarios/scenarios.ts +20 -0
  229. package/scripts/lib/tui-regress-checks.ts +146 -0
  230. package/scripts/marketing/measure-site-numbers.ts +169 -0
  231. package/scripts/measure-gate-shards.ts +309 -0
  232. package/scripts/memory-lifecycle-cycle.ts +2 -2
  233. package/scripts/mission-request-judge.ts +31 -1
  234. package/scripts/morning-report.ts +2 -2
  235. package/scripts/opportunity-scan.ts +1 -1
  236. package/scripts/ops-now-probe.ts +327 -0
  237. package/scripts/publish-internal-dist.ts +11 -1
  238. package/scripts/release-loop/auto-approve-node.ts +21 -4
  239. package/scripts/release-loop/cut-branch.ts +84 -0
  240. package/scripts/release-loop/cutoff.ts +19 -8
  241. package/scripts/release-loop/gate-node.ts +14 -13
  242. package/scripts/release-loop/mac-smoke-node.ts +229 -0
  243. package/scripts/release-loop/node-verdict.ts +3 -3
  244. package/scripts/release-loop/ops-upgrade-node.ts +72 -16
  245. package/scripts/release-loop/release-readiness.ts +9 -0
  246. package/scripts/release-loop/tui-node-checks.ts +42 -0
  247. package/scripts/release-loop/tui-sim-node.ts +32 -8
  248. package/scripts/release-loop/unattended-release.ts +5 -3
  249. package/scripts/release-loop/version-node.ts +112 -13
  250. package/scripts/repo-watch-cycle.ts +1 -1
  251. package/scripts/retro-cycle.ts +2 -2
  252. package/scripts/schedule-health-report.ts +1 -1
  253. package/scripts/signal-digest-cycle.ts +2 -7
  254. package/scripts/signal-digest-photo.ts +11 -0
  255. package/scripts/storyboard/storyboard.ts +5 -161
  256. package/scripts/tech1-public-measure.ts +94 -0
  257. package/scripts/test-diet/lib.ts +30 -1
  258. package/scripts/test-diet/node.ts +83 -8
  259. package/scripts/test-timeout-audit.ts +114 -0
  260. package/scripts/tree-sync-alert.ts +1 -1
  261. package/scripts/tui-regress.ts +71 -0
  262. package/scripts/ux/demo-rehearsal.ts +243 -0
  263. package/scripts/ux/lib/rehearsal-verdict.ts +73 -0
  264. package/scripts/waitlist-daily-digest.ts +1 -1
  265. package/skills/diagram-master/SKILL.md +366 -0
  266. package/skills/diagram-master/references/engines/excalidraw/color-palette.md +67 -0
  267. package/skills/diagram-master/references/engines/excalidraw/element-templates.md +182 -0
  268. package/skills/diagram-master/references/engines/excalidraw/json-schema.md +71 -0
  269. package/skills/diagram-master/references/engines/excalidraw/render_excalidraw.py +189 -0
  270. package/skills/diagram-master/references/engines/excalidraw/render_template.html +57 -0
  271. package/skills/diagram-master/references/engines/matplotlib/matplotlib-patterns.md +235 -0
  272. package/skills/diagram-master/references/engines/matplotlib/render_matplotlib.py +184 -0
  273. package/skills/diagram-master/references/engines/mermaid/domain-templates.md +435 -0
  274. package/skills/diagram-master/references/engines/mermaid/render_mermaid.py +116 -0
  275. package/skills/diagram-master/references/engines/mermaid/syntax-reference.md +2247 -0
  276. package/skills/diagram-master/references/engines/nanobannana/render_nanobannana2.py +168 -0
  277. package/skills/diagram-master/references/engines/svg/color-palette.md +188 -0
  278. package/skills/diagram-master/references/engines/svg/html-base-template.html +332 -0
  279. package/skills/diagram-master/references/engines/svg/interactivity-patterns.md +435 -0
  280. package/skills/diagram-master/references/engines/svg/render_interactive_svg.py +212 -0
  281. package/skills/diagram-master/references/engines/svg/svg-element-templates.md +349 -0
  282. package/skills/diagram-master/references/examples/README.md +69 -0
  283. package/skills/diagram-master/references/examples/ref_grid_architecture.png +0 -0
  284. package/skills/diagram-master/references/examples/ref_layered_flow.png +0 -0
  285. package/skills/diagram-master/references/pyproject.toml +16 -0
  286. package/skills/diagram-master/references/quality-checklist.md +33 -0
  287. package/skills/diagram-master/references/routing-guide.md +164 -0
  288. package/skills/diagram-master/references/uv.lock +1356 -0
  289. package/skills/explainer-video/SKILL.md +4 -0
  290. package/skills/explainer-video/engine/reel.mjs +18 -13
  291. package/skills/explainer-video/engine/reel.sh +24 -5
  292. package/skills/explainer-video/engine/stitch.mjs +145 -0
  293. package/skills/google-workspace/SKILL.md +33 -0
  294. package/skills/google-workspace/scripts/gws-safe.sh +177 -0
  295. package/skills/grill-me/SKILL.md +1 -1
  296. package/skills/lecture-note-digitizer/SKILL.md +926 -0
  297. package/skills/lecture-note-digitizer/references/convert_to_pdf.py +30 -0
  298. package/skills/lecture-note-digitizer/references/extract_slide_diagram.py +73 -0
  299. package/skills/lecture-note-digitizer/references/html-template.md +167 -0
  300. package/skills/lecture-note-digitizer/references/katex-style-guide.md +165 -0
  301. package/skills/omni-crawl/SKILL.md +21 -11
  302. package/skills/omni-crawl/scripts/main.ts +6 -6
  303. package/skills/omni-crawl/src/router.ts +3 -3
  304. package/skills/omni-digest/SKILL.md +17 -9
  305. package/skills/omni-digest/digest.md +2 -2
  306. package/skills/omni-digest/src/fetch.ts +30 -3
  307. package/skills/pitch-deck/SKILL.md +36 -0
  308. package/skills/pitch-deck/template.html +80 -0
  309. package/skills/youtube-master/SKILL.md +163 -0
  310. package/skills/youtube-master/package-lock.json +558 -0
  311. package/skills/youtube-master/package.json +13 -0
  312. package/skills/youtube-master/references/study-note-template.md +124 -0
  313. package/skills/youtube-master/scripts/main.ts +435 -0
  314. package/skills/youtube-master/scripts/transcribe-local.ts +24 -0
  315. package/skills/youtube-master/src/audio.ts +63 -0
  316. package/skills/youtube-master/src/domain-staging.ts +50 -0
  317. package/skills/youtube-master/src/env.ts +36 -0
  318. package/skills/youtube-master/src/obsidian.ts +155 -0
  319. package/skills/youtube-master/src/router.ts +110 -0
  320. package/skills/youtube-master/src/stt.ts +199 -0
  321. package/skills/youtube-master/src/study-note.ts +175 -0
  322. package/skills/youtube-master/src/summarize.ts +358 -0
  323. package/skills/youtube-master/src/transcript.ts +76 -0
  324. package/skills/youtube-master/src/types.ts +91 -0
  325. package/skills/youtube-master/src/util.ts +93 -0
  326. package/skills/youtube-master/src/youtube.ts +70 -0
  327. package/skills/youtube-master/tsconfig.json +13 -0
  328. package/src/acp/codex-approval-adapter.ts +9 -3
  329. package/src/acp/core-turn-bridge.ts +117 -18
  330. package/src/acp/fact-question.ts +11 -0
  331. package/src/acp/server.ts +53 -9
  332. package/src/acp/tool-approval.ts +126 -0
  333. package/src/acp/turn-runner.ts +36 -0
  334. package/src/agent/monad-agent-turn.ts +8 -0
  335. package/src/agent-mission/driver.ts +80 -10
  336. package/src/agent-mission/pty-decision.ts +71 -0
  337. package/src/agent-mission/review-loop.ts +30 -0
  338. package/src/ask-user-question/pending-questions.ts +25 -10
  339. package/src/ask-user-question/types.ts +9 -0
  340. package/src/auth/setup-link-tokens.ts +16 -5
  341. package/src/autopilot/build/integrity-gate.ts +12 -0
  342. package/src/autopilot/build/llm-conflict-merge.ts +16 -3
  343. package/src/autopilot/tool-registry.ts +2 -0
  344. package/src/boot/daemon-prompt-turn.ts +8 -0
  345. package/src/boot/daemon-runtime.ts +9 -3
  346. package/src/boot/daemon-tools/index.ts +8 -0
  347. package/src/boot/daemon-tools/types.ts +2 -0
  348. package/src/boot/daemon-tools/web-search.ts +4 -0
  349. package/src/card-followup/core.ts +109 -0
  350. package/src/chat/ctrl-c-in-input.ts +14 -0
  351. package/src/chat/index.ts +53 -0
  352. package/src/chat/pickers/state.ts +6 -2
  353. package/src/cli/agent-cli.ts +7 -0
  354. package/src/cli/decisions-cli.ts +25 -3
  355. package/src/cli/doctor-bundle-upload.ts +68 -0
  356. package/src/cli/doctor-cli.ts +38 -4
  357. package/src/cli/drive-input-jail.ts +101 -0
  358. package/src/cli/hooks-cli.ts +17 -3
  359. package/src/cli/make-cli.ts +43 -0
  360. package/src/cli/ops-cli.ts +20 -0
  361. package/src/cli/persona-cli.ts +90 -4
  362. package/src/cli/plugin-cli.ts +31 -22
  363. package/src/cli/pod-cli.ts +61 -2
  364. package/src/cli/pr-cli.ts +82 -17
  365. package/src/cli/pty-drive-cli.ts +41 -7
  366. package/src/cli/pty-drive-verdict.ts +40 -0
  367. package/src/cli/pwa-stop.ts +163 -13
  368. package/src/cli/pwa-test.ts +3 -0
  369. package/src/cli/release-cli.ts +80 -24
  370. package/src/cli/self-update.ts +14 -0
  371. package/src/cli/setup-cli.ts +43 -1
  372. package/src/cli/skills-cli.ts +17 -1
  373. package/src/cli/storyboard-cli.ts +37 -0
  374. package/src/cli/test-state-dir-flag.ts +11 -4
  375. package/src/connectors/linear.ts +146 -0
  376. package/src/context-bus/claude-hooks-install.ts +10 -0
  377. package/src/context-bus/context-now-surfaces.ts +48 -0
  378. package/src/context-bus/context-now.ts +104 -0
  379. package/src/context-bus/coord-events.ts +115 -0
  380. package/src/context-bus/external-events.ts +52 -0
  381. package/src/context-bus/long-term-memory.ts +108 -0
  382. package/src/dashboard/dashboard-boot-fixture.ts +23 -0
  383. package/src/dashboard/index.ts +63 -21
  384. package/src/dashboard/slash-runtime/dashboard-handlers.ts +14 -1
  385. package/src/dashboard/slash-runtime/help-from-registry.ts +43 -28
  386. package/src/decisions/decision-cards.ts +58 -3
  387. package/src/decisions/decision-ledger.ts +85 -6
  388. package/src/decisions/decision-linear-projection.ts +157 -0
  389. package/src/decisions/web-push-decision-cards.ts +50 -0
  390. package/src/directive/interpretation-card.ts +36 -0
  391. package/src/discord/sprint21-runtime.ts +5 -1
  392. package/src/discord-self-message.ts +32 -0
  393. package/src/discord-slash-wire.ts +5 -1
  394. package/src/discord.ts +19 -2
  395. package/src/domains/coo-admin-tool.ts +62 -0
  396. package/src/domains/core-tools.ts +13 -4
  397. package/src/domains/elanous-card.ts +29 -0
  398. package/src/domains/ops-facts-tool.ts +76 -0
  399. package/src/domains/outbound-alert.ts +46 -13
  400. package/src/domains/release-tool.ts +168 -0
  401. package/src/domains/telegram-kind-route.ts +65 -9
  402. package/src/exec-requests/default-outputs.ts +25 -0
  403. package/src/exec-requests/planner.ts +106 -28
  404. package/src/exec-requests/runner.ts +123 -12
  405. package/src/exec-requests/store.ts +11 -2
  406. package/src/execution-loop/launch-gate.ts +100 -0
  407. package/src/field/field-media.ts +10 -7
  408. package/src/field/field-reel.ts +19 -5
  409. package/src/field-note/index.ts +201 -0
  410. package/src/field-note/transcribe.ts +248 -0
  411. package/src/git-fs/worktree.ts +45 -6
  412. package/src/graph-kinds/registry.ts +3 -3
  413. package/src/graph-runner/graph-approval-card.ts +113 -0
  414. package/src/graph-runner/graph-cli.ts +189 -4
  415. package/src/graph-runner/graph-grow-llm.ts +37 -0
  416. package/src/graph-runner/graph-grow.ts +47 -0
  417. package/src/graph-runner/graph-notify.ts +25 -3
  418. package/src/graph-runner/runner.ts +453 -35
  419. package/src/grok/agent-search.ts +8 -2
  420. package/src/guardian/secret-exposure-scan.ts +101 -0
  421. package/src/harness/browser-verify.ts +25 -2
  422. package/src/harness/harness-cli-command.ts +478 -42
  423. package/src/harness/harness-incidents-writer.fixture.ts +24 -0
  424. package/src/harness/harness-incidents.ts +129 -0
  425. package/src/harness/harness-pod-dispatch.ts +43 -23
  426. package/src/harness/harness-seams.ts +38 -4
  427. package/src/harness/harness-stop.ts +75 -6
  428. package/src/harness/launch-registry.ts +91 -0
  429. package/src/harness/process-garbage.ts +5 -3
  430. package/src/hitl/clarification-policy.ts +3 -1
  431. package/src/hooks/dispatch.ts +82 -0
  432. package/src/hooks/expose.ts +254 -0
  433. package/src/hooks/github-shadow.ts +108 -0
  434. package/src/hooks/providers.ts +71 -5
  435. package/src/hooks/queue.ts +1 -1
  436. package/src/hooks/receiver.ts +21 -20
  437. package/src/index.ts +206 -49
  438. package/src/intake-plane/author-goals.ts +37 -4
  439. package/src/intake-plane/categorize.ts +18 -46
  440. package/src/intake-plane/check.ts +3 -0
  441. package/src/intake-plane/discord-seat-work.ts +57 -2
  442. package/src/intake-plane/front-route-classifier.ts +33 -39
  443. package/src/intake-plane/persona-answer.ts +30 -0
  444. package/src/intake-plane/runtime-callables.ts +8 -1
  445. package/src/intake-plane/seat-doc-route.ts +170 -6
  446. package/src/intake-plane/telegram-seat-work.ts +80 -4
  447. package/src/intake-plane/telegram-work.ts +1 -0
  448. package/src/intake-plane/wish-folder.ts +67 -0
  449. package/src/intent-gate/gate.ts +30 -10
  450. package/src/live/detail-switch.ts +5 -0
  451. package/src/llm/difficulty.ts +57 -0
  452. package/src/llm/judge-layer.ts +101 -0
  453. package/src/llm/mission-router.ts +33 -19
  454. package/src/loops/contract/examples/cmo-seat.loop.yaml +51 -0
  455. package/src/loops/contract/examples/orchestrator.loop.yaml +57 -0
  456. package/src/loops/contract/examples/steward.loop.yaml +50 -0
  457. package/src/loops/contract/loop-agent.schema.json +138 -0
  458. package/src/loops/contract/validate.ts +64 -0
  459. package/src/loops/registry.ts +20 -6
  460. package/src/market/signed-index.ts +4 -0
  461. package/src/maturity/bot-command-maturity.ts +45 -0
  462. package/src/maturity/cli-maturity.ts +34 -0
  463. package/src/maturity/feature-maturity.ts +120 -1
  464. package/src/maturity/tui-slash-maturity.ts +31 -0
  465. package/src/memory.ts +32 -4
  466. package/src/model-tier/index.ts +2 -2
  467. package/src/model-tier/tier-resolver.ts +20 -20
  468. package/src/model-tier/types.ts +6 -6
  469. package/src/mss/logging/log-store.ts +15 -0
  470. package/src/nexus/api/config-model-tier.ts +5 -4
  471. package/src/nexus/api/exec-requests.ts +33 -3
  472. package/src/nexus/api/fabric-plans.ts +53 -0
  473. package/src/nexus/api/harness-api.ts +5 -1
  474. package/src/nexus/api/health.ts +2 -0
  475. package/src/nexus/api/http-server.ts +89 -1
  476. package/src/nexus/api/inside-events.ts +226 -0
  477. package/src/nexus/api/meta-api.ts +32 -8
  478. package/src/nexus/api/missions.ts +6 -1
  479. package/src/nexus/api/ops-api.ts +10 -1
  480. package/src/nexus/api/ops-seats-sources.ts +37 -7
  481. package/src/nexus/api/ops-seats.ts +49 -6
  482. package/src/nexus/api/outputs-route.ts +44 -0
  483. package/src/nexus/api/seat-requests.ts +132 -10
  484. package/src/nexus/api/sessions-store.ts +42 -0
  485. package/src/nexus/api/setup-codex-login.ts +160 -0
  486. package/src/nexus/api/sub-seat-charters.ts +34 -0
  487. package/src/nexus/api/tabs-mutations.ts +3 -1
  488. package/src/nexus/api/trace.ts +18 -6
  489. package/src/nexus/api/usage-api.ts +102 -0
  490. package/src/nexus/api/workflow-run-event-bridge.ts +1 -0
  491. package/src/nexus/api/workflows.ts +80 -6
  492. package/src/nexus/index.ts +47 -4
  493. package/src/nexus/kinds/webterm.ts +2 -1
  494. package/src/nexus/webterm/pty.ts +6 -2
  495. package/src/onboarding/cli-auth-status.ts +80 -0
  496. package/src/onboarding/first-run.ts +89 -0
  497. package/src/onboarding/lan-address.ts +45 -0
  498. package/src/onboarding/voice-ai.ts +3 -3
  499. package/src/onboarding/web-first.ts +119 -24
  500. package/src/onboarding.ts +4 -0
  501. package/src/ops-now/ops-now-refresh.ts +100 -0
  502. package/src/org/seat-budget.ts +48 -0
  503. package/src/org/stall-escalation.ts +63 -0
  504. package/src/outputs/ledger.ts +120 -0
  505. package/src/persona/persona-todo.ts +79 -0
  506. package/src/persona/presets.ts +116 -2
  507. package/src/persona/team-set.ts +155 -0
  508. package/src/plugins/install/plugin-install.ts +14 -0
  509. package/src/plugins/maker/market-bundle.ts +109 -0
  510. package/src/plugins/maker/plugin-maker.ts +254 -11
  511. package/src/plugins/maker/wizard-generate.ts +103 -0
  512. package/src/pod-lease/admission.ts +150 -0
  513. package/src/pod-lease/dependency-state.ts +85 -0
  514. package/src/pod-lease/host-lease.ts +127 -0
  515. package/src/project/project-store.ts +115 -0
  516. package/src/project/project-suggestion.ts +16 -0
  517. package/src/project/session-context.ts +24 -0
  518. package/src/release-loop/checklist.ts +79 -5
  519. package/src/release-loop/feature-store.ts +159 -24
  520. package/src/release-loop/next-md-merge.ts +58 -0
  521. package/src/release-loop/release-note.ts +59 -4
  522. package/src/release-loop/release-schedule.ts +53 -0
  523. package/src/repl/index.ts +7 -0
  524. package/src/seat-dispatch/ceo-commands.ts +41 -8
  525. package/src/seat-dispatch/ceo-intent.ts +38 -0
  526. package/src/seat-dispatch/seat-ask.ts +130 -0
  527. package/src/seat-dispatch/seat-questions.ts +100 -0
  528. package/src/seat-loop/seat-loop.ts +750 -0
  529. package/src/seat-loop/seat-report.ts +99 -0
  530. package/src/self-dev/decompose.ts +66 -11
  531. package/src/self-dev/dev-cli.ts +4 -1
  532. package/src/self-dev/dev-pipeline.ts +37 -1
  533. package/src/self-dev/draft-sweep.ts +38 -33
  534. package/src/self-dev/draft-triage-rules.ts +8 -5
  535. package/src/self-dev/fabric-plan-core.ts +297 -0
  536. package/src/self-dev/orchestrate.ts +36 -4
  537. package/src/self-dev/release-path-guard.ts +62 -0
  538. package/src/self-dev/run-store.ts +10 -1
  539. package/src/self-dev/shard-aggregate.ts +230 -0
  540. package/src/self-dev/shard-placement.ts +60 -0
  541. package/src/self-dev/shard-plan.ts +48 -0
  542. package/src/self-dev/shard-pod-run.ts +77 -0
  543. package/src/self-dev/shard-run.ts +105 -0
  544. package/src/self-implement/execution-clarification.ts +115 -0
  545. package/src/self-implement/gate-baseline.ts +1 -1
  546. package/src/self-implement/gate-cli.ts +46 -4
  547. package/src/self-implement/gate-scope.ts +37 -7
  548. package/src/self-implement/graph-variant.ts +171 -0
  549. package/src/self-implement/harness-policy-gates.ts +1 -1
  550. package/src/self-implement/headless-elanous-driver.ts +22 -3
  551. package/src/self-implement/host-regate.ts +22 -1
  552. package/src/self-implement/importer-test-index.ts +2 -1
  553. package/src/self-implement/l8-merge-queue.ts +130 -0
  554. package/src/self-implement/orchestrator.ts +279 -12
  555. package/src/self-implement/pipeline-shape.ts +1 -1
  556. package/src/self-implement/route-consumer-test-index.ts +122 -0
  557. package/src/self-implement/run-status-mapping.ts +5 -3
  558. package/src/self-implement/seams.ts +72 -11
  559. package/src/self-implement/test-seams.ts +1 -0
  560. package/src/self-implement/uncommitted-work.ts +59 -0
  561. package/src/session/chat.ts +2 -0
  562. package/src/session/index.ts +45 -13
  563. package/src/shell-env-bootstrap.ts +17 -0
  564. package/src/skills/gift-install.ts +215 -0
  565. package/src/skills/tools/web-search.ts +4 -1
  566. package/src/steward/directive.ts +51 -2
  567. package/src/steward/launch.ts +266 -0
  568. package/src/steward/outcome-notify.ts +115 -0
  569. package/src/steward/steward-cards.ts +25 -11
  570. package/src/steward/triage-plan.ts +32 -4
  571. package/src/steward/triage.ts +129 -13
  572. package/src/steward/working-backwards.ts +64 -0
  573. package/src/storyboard/storyboard.ts +141 -0
  574. package/src/task-cards/card-cli.ts +25 -1
  575. package/src/task-cards/card-store.ts +2 -2
  576. package/src/task-orchestrator/mission.ts +5 -0
  577. package/src/task-orchestrator/store.ts +12 -3
  578. package/src/task-orchestrator/surfaces/pod-command-job.ts +29 -7
  579. package/src/task-orchestrator/surfaces/pod-lease.ts +397 -0
  580. package/src/task-orchestrator/surfaces/pod-pool.ts +127 -26
  581. package/src/task-orchestrator/surfaces/self-implement-pod.ts +214 -40
  582. package/src/task-orchestrator/surfaces/self-implement.ts +15 -2
  583. package/src/task-orchestrator/types.ts +2 -0
  584. package/src/telegram-card-followup.ts +153 -0
  585. package/src/telegram-commands.ts +10 -1
  586. package/src/telegram-project-command.ts +71 -0
  587. package/src/telegram-report.ts +29 -19
  588. package/src/telegram-run.ts +7 -0
  589. package/src/telegram.ts +58 -11
  590. package/src/tool-runtime/self-cognition-runtimes.ts +13 -3
  591. package/src/tool-runtime/types.ts +4 -0
  592. package/src/tui-client/dashboard-session.ts +2 -0
  593. package/src/user-config.ts +216 -27
  594. package/src/version/packed-revision.json +1 -1
  595. package/src/web-push/notify-exec-request.ts +32 -0
  596. package/src/web-search/grok.ts +7 -1
  597. package/src/web-search/index.ts +28 -1
  598. package/src/web-search/provider.ts +4 -0
  599. package/src/web-search/x-intent.ts +5 -0
  600. package/src/workflow-runtime/executor.ts +277 -47
  601. package/src/workflow-runtime/index.ts +1 -0
  602. package/src/workflow-runtime/nodes/subworkflow.ts +60 -0
  603. package/src/workflow-runtime/plugin-kind-node.ts +1 -1
  604. package/src/workflow-runtime/schema.ts +79 -4
  605. package/src/workflow-runtime/types.ts +35 -4
  606. package/apps/pwa/out/_next/static/bFI5EEwg7T6aG88ibX4Zq/_buildManifest.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/1201-09613bce624467c0.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/1377-1efeffbbac0963ff.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/1470.98a6ab61ccb4131c.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/2375-cb6debea56cce4fb.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/2929-617f1e66a55be184.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/2977-e38442e86289f1d3.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/2982-2a2df543be3d2e5a.js +0 -25
  617. package/apps/pwa/out/_next/static/chunks/3403.4bc97b4066945a94.js +0 -5
  618. package/apps/pwa/out/_next/static/chunks/3441-a1dd4acfeda14488.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/5080-1613752891fcadb4.js +0 -10
  622. package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/5791-bb82743fa6299562.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/6090-85a3f05f954e5697.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/6284-69db415193d5f8bd.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/6320-baac91d68843a9a6.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/6416-505ba707cacafbba.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/7032-f4ef698518fba61c.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/7647.2fcd30d894d5ee30.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/8067-d976b441a104ab74.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/8142-744998d65d7bb17e.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/8519-5632377cce994f86.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/8619-4365e03a2862830f.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/8630-cdfc61e82c653ffc.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/8894-e263b332208e3957.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/9454-139040d37c79dbc9.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/9651-3cd291a6fa1370d2.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/9740-8f5ff96c522b5f55.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/ae787e4c-f2998de7f1ba72a4.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fb7c2d458f32fcad.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-35e2713597dd24d1.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/app/board/page-918b656f064577ba.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/bots/page-5f30e00693527ebd.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/chat/page-7fbae173b3c103a7.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/consult/page-3b4edcce364062ea.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/control/page-c5794f484c251f44.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/design-check/page-1130d8eefcd87e76.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/editor/page-973996d584f008c1.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/exec/page-016e2bda04eecb1f.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/field/page-b4d6d9a3b56f2940.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/intake/page-ec49a466121233ba.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/layout-f72db356744ceade.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/live/page-a6fd9b50d1b85378.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/market/page-8b0402a46a749a3d.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-037f83e2a1edc8e2.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/not-found-46fedff57d4bec67.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/observatory/page-0cf318e9dcee2bbf.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-899b327cb8b6845c.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6c1e6ba743a29dfe.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/page-1a8e4807292f6b17.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/reflection/page-28deba6bcb834916.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-de68e2205794037d.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/sessions/page-c71c33a573230672.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-0df30e0c7e50148a.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/settings/page-4fc56790fe0d2682.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-59df2aebb38a7c1e.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/setup/page-4647be5dbcbd0795.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/share/page-e025892bda74b743.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/showroom/page-a0955de73b89f078.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/tasks/page-369846d2921af584.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/term/page-72cbc1c8cdd0f65d.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/trace/page-77b28bfb0996d5ea.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/vault/page-3220c4934f49c6c2.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-90670589b87abea8.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/workflows/page-7df9243ed021a4cc.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/workspace/page-4498c3853f4f688d.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-35bedde6d885f08f.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/main-app-6870f30ea99f8346.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/webpack-e5bea36f183b25e6.js +0 -1
  692. package/apps/pwa/out/_next/static/css/f92f63a5df0ba229.css +0 -1
  693. package/src/dashboard/turn-typeahead-echo.ts +0 -23
  694. /package/apps/pwa/out/_next/static/{bFI5EEwg7T6aG88ibX4Zq → Y4zKzL62sakG5momz3SoQ}/_ssgManifest.js +0 -0
@@ -0,0 +1,48 @@
1
+ import { contextNow, type ContextFact, type ContextNowAnswer, type ContextNowDeps } from './context-now.js';
2
+
3
+ export function readSlashContextNow(args: string[], deps?: ContextNowDeps): ContextNowAnswer {
4
+ return contextNow({ topic: args.join(' ').trim() }, deps);
5
+ }
6
+
7
+ function factText(fact: ContextFact): string {
8
+ switch (fact.kind) {
9
+ case 'version': return fact.version;
10
+ case 'cell': return `${fact.id} ${fact.title} (${fact.status})`;
11
+ case 'decision': return `${fact.id} ${fact.title} (${fact.status})`;
12
+ case 'seat': return `${fact.seat} ${fact.id ?? ''} ${fact.title ?? ''} (${fact.status})`.trim();
13
+ }
14
+ }
15
+
16
+ export function renderTelegramNow(answer: ContextNowAnswer): string {
17
+ const rows = [
18
+ ['판', answer.facts.filter(f => f.kind === 'version')],
19
+ ['칸', answer.facts.filter(f => f.kind === 'cell')],
20
+ ['결정', answer.facts.filter(f => f.kind === 'decision')],
21
+ ['자리', answer.facts.filter(f => f.kind === 'seat')],
22
+ ] as const;
23
+ const lines = rows.map(([label, facts]) => `${label}: ${facts.length ? facts.map(f => `${factText(f)} — ${f.source}`).join(' · ') : '없음'}`);
24
+ lines.push(`최근: ${answer.events.length ? answer.events.map(e => `${e.summary} — ${e.source}`).join(' · ') : '없음'}${answer.guide.length ? ` · 안내 ${answer.guide.join(' · ')}` : ''}`);
25
+ return lines.map(line => line.replace(/\s+/g, ' ').trim()).join('\n');
26
+ }
27
+
28
+ export function renderTuiNow(answer: ContextNowAnswer): string[] {
29
+ const rows = [
30
+ ...answer.facts.map(f => [f.kind, factText(f), f.source]),
31
+ ...answer.events.map(e => [e.kind, e.summary, e.source]),
32
+ ...answer.guide.map(guide => ['안내', guide, '']),
33
+ ];
34
+ return [
35
+ `지금${answer.topic ? ` · ${answer.topic}` : ''} (${answer.at})`,
36
+ '| 종류 | 사실 | 출처 |',
37
+ '| --- | --- | --- |',
38
+ ...rows.map(row => `| ${row.map(cell => cell.replaceAll('|', '\\|').replaceAll(/\r?\n/g, ' ')).join(' | ')} |`),
39
+ ];
40
+ }
41
+
42
+ export function telegramNowSlash(args: string[], deps?: ContextNowDeps): string {
43
+ return renderTelegramNow(readSlashContextNow(args, deps));
44
+ }
45
+
46
+ export function tuiNowSlash(args: string[], deps?: ContextNowDeps): string[] {
47
+ return renderTuiNow(readSlashContextNow(args, deps));
48
+ }
@@ -0,0 +1,104 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { debug, redactSecretText } from '../debug/log.js';
3
+ import { DecisionLedger, type DecisionEntry } from '../decisions/decision-ledger.js';
4
+ import { listChecklist, devVersion, type Checklist } from '../release-loop/checklist.js';
5
+ import { effectiveInstanceRoot } from '../instance/resolve.js';
6
+ import { seatDay, seatLedgerPath, type SeatEntry } from '../seat-loop/seat-loop.js';
7
+ import { listCoordEvents, type CoordEvent } from './coord-events.js';
8
+
9
+ export type ContextFact =
10
+ | { kind: 'version'; version: string; source: string }
11
+ | { kind: 'cell'; version: string; id: string; title: string; status: string; owner: string | null; source: string }
12
+ | { kind: 'decision'; id: string; title: string; status: string; dueAt: string | null; source: string }
13
+ | { kind: 'seat'; seat: string; at: string; status: string; id: string | null; title: string | null; source: string };
14
+ export type ContextEvent = { at: string; kind: string; summary: string; source: string };
15
+ export type ContextNowAnswer = { at: string; topic: string | null; facts: ContextFact[]; events: ContextEvent[]; guide: string[] };
16
+
17
+ export interface ContextNowDeps {
18
+ now?: () => Date;
19
+ version?: () => string;
20
+ checklist?: (version: string) => Checklist;
21
+ decisions?: () => DecisionEntry[];
22
+ seatEntries?: (now: Date) => Array<{ entry: SeatEntry; source: string }>;
23
+ events?: (since: string) => CoordEvent[];
24
+ }
25
+
26
+ function todaySeatEntries(now: Date): Array<{ entry: SeatEntry; source: string }> {
27
+ const root = effectiveInstanceRoot();
28
+ const day = seatDay(now);
29
+ return ['OP', 'TC', 'MK', 'UX'].flatMap(seat => {
30
+ const path = seatLedgerPath(seat, root, now);
31
+ if (!existsSync(path)) return [];
32
+ return readFileSync(path, 'utf8').split('\n').flatMap((line, index) => line.trim() ? [{
33
+ entry: JSON.parse(line) as SeatEntry,
34
+ source: `elanous://seat-loop/${seat}/${day}#${index + 1}`,
35
+ }] : []);
36
+ });
37
+ }
38
+
39
+ /** Read a bounded, source-labelled view of current ledgers, never a transcript or decision body. */
40
+ export function contextNow(options: { topic?: string; limit?: number } = {}, deps: ContextNowDeps = {}): ContextNowAnswer {
41
+ const now = (deps.now ?? (() => new Date()))();
42
+ const at = `${now.toISOString().slice(0, 16)}:00.000Z`;
43
+ const topic = options.topic?.trim() || null;
44
+ const limit = typeof options.limit === 'number' && Number.isFinite(options.limit)
45
+ ? Math.max(1, Math.min(100, Math.floor(options.limit))) : 20;
46
+ const version = (deps.version ?? devVersion)().replace(/-.*$/, '');
47
+ const next = version.replace(/^(\d+)\.(\d+)\.(\d+)$/, (_, major: string, minor: string, patch: string) => `${major}.${minor}.${Number(patch) + 1}`);
48
+ const facts: ContextFact[] = [];
49
+ for (const v of [...new Set([version, next])]) {
50
+ const checklist = (deps.checklist ?? listChecklist)(v);
51
+ if (v === version) facts.push({ kind: 'version', version: v, source: `elanous://release/${v}/checklist` });
52
+ for (const item of checklist.items) {
53
+ if (item.status === 'done') continue;
54
+ facts.push({ kind: 'cell', version: v, id: item.id, title: redactSecretText(item.title.split(/\r?\n/, 1)[0] ?? '').slice(0, 120),
55
+ status: item.status, owner: item.owner ?? null, source: `elanous://release/${v}/checklist#${encodeURIComponent(item.id)}` });
56
+ }
57
+ }
58
+ for (const item of (deps.decisions ?? (() => new DecisionLedger().list({ status: 'open' })))()) {
59
+ if (item.status !== 'open') continue;
60
+ facts.push({ kind: 'decision', id: item.id, title: redactSecretText(item.title.split(/\r?\n/, 1)[0] ?? '').slice(0, 120),
61
+ status: item.status, dueAt: item.dueAt ?? null, source: `elanous://decisions/${encodeURIComponent(item.id)}` });
62
+ }
63
+ for (const { entry, source } of (deps.seatEntries ?? todaySeatEntries)(now)) {
64
+ facts.push({ kind: 'seat', seat: entry.seat, at: entry.at, status: entry.status,
65
+ id: entry.item?.id ?? null, title: entry.item?.source === 'checklist'
66
+ ? redactSecretText(entry.item.title.split(/\r?\n/, 1)[0] ?? '').slice(0, 120) : null, source });
67
+ }
68
+ const rawEvents = (deps.events ?? (since => listCoordEvents({ since })))(new Date(now.getTime() - 7 * 86_400_000).toISOString());
69
+ const chronologicalEvents = rawEvents.slice().sort((a, b) => a.at.localeCompare(b.at) || a.id.localeCompare(b.id));
70
+ const matches = (text: string) => !topic || text.toLocaleLowerCase().includes(topic.toLocaleLowerCase());
71
+ const selectedFacts = facts.filter(f => !topic || (f.kind === 'cell' && matches(`${f.id} ${f.title}`))
72
+ || (f.kind === 'seat' && matches(`${f.id ?? ''} ${f.title ?? ''}`)));
73
+ const groups = (['version', 'cell', 'decision', 'seat'] as const).map(kind => selectedFacts.filter(f => f.kind === kind));
74
+ groups[3]!.sort((a, b) => (a.kind === 'seat' && b.kind === 'seat' ? b.at.localeCompare(a.at) : 0));
75
+ const nonEmpty = groups.filter(group => group.length > 0);
76
+ const perKind = Math.floor(limit / nonEmpty.length);
77
+ const chosen = groups.map(group => group.splice(0, perKind));
78
+ let remaining = limit - chosen.reduce((total, group) => total + group.length, 0);
79
+ for (const index of [2, 3, 0, 1]) {
80
+ if (remaining <= 0) break;
81
+ if (chosen[index]!.length === 0 && groups[index]!.length > 0) {
82
+ chosen[index]!.push(...groups[index]!.splice(0, 1));
83
+ remaining--;
84
+ }
85
+ }
86
+ for (const index of [1, 2, 3, 0]) {
87
+ if (remaining <= 0) break;
88
+ const extra = groups[index]!.splice(0, remaining);
89
+ chosen[index]!.push(...extra);
90
+ remaining -= extra.length;
91
+ }
92
+ const boundedFacts = chosen.flat();
93
+ const summaries = chronologicalEvents.map(event => ({
94
+ at: event.at, kind: event.kind, summary: redactSecretText(event.summary.split(/\r?\n/, 1)[0] ?? '').slice(0, 120),
95
+ source: event.refs.source ?? event.refs.url ?? `elanous://context/event/${encodeURIComponent(event.id)}`,
96
+ }));
97
+ const selectedEvents = summaries.filter(event => matches(event.summary)).reverse().slice(0, limit);
98
+ const guide = summaries.filter(event => event.kind === 'guide-changed' || event.summary.startsWith('📌안내'))
99
+ .filter(event => matches(event.summary)).reverse().slice(0, limit)
100
+ .map(event => `📌 ${event.summary} — ${event.source}`);
101
+ const answer = { at, topic, facts: boundedFacts, events: selectedEvents, guide };
102
+ debug.log('context.now', 'answer', { topic, facts: answer.facts, events: answer.events });
103
+ return answer;
104
+ }
@@ -0,0 +1,115 @@
1
+ import type { Database } from 'bun:sqlite';
2
+ import { readFileSync, existsSync } from 'node:fs';
3
+ import { resolve } from 'node:path';
4
+ import { debug, redactSecretText } from '../debug/log.js';
5
+ import { openSurfaceEventsDb, recordEvent, surfaceEventsDbPath } from '../domains/surface-events.js';
6
+
7
+ export interface CoordEventInput {
8
+ seat: string;
9
+ recipients: string[];
10
+ all: boolean;
11
+ kind: string | null;
12
+ slot: string | null;
13
+ deadline: string | null;
14
+ url: string | null;
15
+ headline: string;
16
+ at?: string;
17
+ }
18
+
19
+ export interface CoordEvent {
20
+ id: string;
21
+ at: string;
22
+ text: string;
23
+ summary: string;
24
+ kind: string;
25
+ refs: Pick<CoordEventInput, 'seat' | 'recipients' | 'all' | 'kind' | 'slot' | 'deadline' | 'url'> & { origin?: string; source?: string };
26
+ }
27
+
28
+ function seatIds(): Set<string> {
29
+ return new Set((JSON.parse(readFileSync(resolve(import.meta.dir, '../../scripts/coord-tracks.json'), 'utf8')) as
30
+ { tracks: Array<{ id: string }> }).tracks.map((track) => track.id));
31
+ }
32
+ const kinds = new Set(['요청', '결정', '사고', '보고', '정정']);
33
+
34
+ /** Mirror the sender's ordered envelope fields; only the first line enters this parser. */
35
+ export function parseCoordHeader(seat: string, header: string): Omit<CoordEventInput, 'url' | 'at'> {
36
+ const first = header.split(/\r?\n/, 1)[0] ?? '';
37
+ if (!first.startsWith(`**[${seat}]**`)) throw new Error('조율 글 신원 접두 불일치');
38
+ const headline = first.slice(`**[${seat}]**`.length)
39
+ .replace(/^\s*(?:📌안내\s*)?\d{4}-\d\d-\d\d\s+\d\d:\d\d\s+KST\s*/, '').trim();
40
+ const headerBody = first.slice(`**[${seat}]**`.length);
41
+ const arrow = headerBody.indexOf('→');
42
+ const envelope = arrow >= 0 && !headerBody.slice(0, arrow).includes(' · ') ? headerBody.slice(arrow + 1).trim() : '';
43
+ const fields = envelope ? envelope.split(' · ') : [];
44
+ const ids = seatIds();
45
+ const recipients: string[] = [];
46
+ let all = false;
47
+ let i = 0;
48
+ for (; i < fields.length; i++) {
49
+ const field = fields[i]!.trim().split(' — ')[0]!;
50
+ const tokens = field.replaceAll(',', ' ').split(/\s+/).filter(Boolean);
51
+ if (!tokens.length || !tokens.every((t) => t === '전원' || ids.has(t))) break;
52
+ for (const token of tokens) {
53
+ if (token === '전원') all = true;
54
+ else recipients.push(token);
55
+ }
56
+ if (fields[i]!.includes(' — ')) { i++; break; }
57
+ }
58
+ const candidate = fields[i]?.trim() ?? '';
59
+ const kind = kinds.has(candidate) ? candidate : null;
60
+ const slot = fields[i + 1]?.trim() || null;
61
+ const deadline = fields.slice(i + 1).map((f) => f.trim()).find((f) => /^기한\s+\S/.test(f)) ?? null;
62
+ return { seat, recipients, all, kind, slot, deadline, headline };
63
+ }
64
+
65
+ /** Atomic lookup+insert makes retries safe, including URL-less posts in the same minute. */
66
+ export function recordCoordEvent(input: CoordEventInput, deps: { db?: Database } = {}): string {
67
+ const hasUrl = !!input.url;
68
+ let db: Database | undefined;
69
+ try {
70
+ db = deps.db ?? openSurfaceEventsDb();
71
+ const at = input.at ?? new Date().toISOString();
72
+ const first = input.headline.split(/\r?\n/, 1)[0] ?? '';
73
+ const withoutPrefix = first.replace(/^\*\*\[[A-Z]+\]\*\*\s*/, '')
74
+ .replace(/^(?:📌안내\s*)?\d{4}-\d\d-\d\d\s+\d\d:\d\d\s+KST\s*/, '');
75
+ const headline = redactSecretText(withoutPrefix).trim().slice(0, 120);
76
+ const safe = (value: string) => redactSecretText(value.split(/\r?\n/, 1)[0] ?? '');
77
+ const refs = { seat: safe(input.seat), recipients: input.recipients.map(safe), all: input.all,
78
+ kind: input.kind === null ? null : safe(input.kind), slot: input.slot === null ? null : safe(input.slot),
79
+ deadline: input.deadline === null ? null : safe(input.deadline), url: input.url ? safe(input.url) : null };
80
+ const result = db.transaction(() => {
81
+ const prior = (refs.url
82
+ ? db!.prepare(`SELECT id FROM events WHERE surface='coord:channel' AND json_extract(refs,'$.url')=? LIMIT 1`).get(refs.url)
83
+ : db!.prepare(`SELECT id FROM events WHERE surface='coord:channel' AND json_extract(refs,'$.url') IS NULL
84
+ AND json_extract(refs,'$.seat')=? AND summary=? AND substr(ts,1,16)=? LIMIT 1`)
85
+ .get(refs.seat, headline, at.slice(0, 16))) as { id: string } | null;
86
+ if (prior) return { id: prior.id, dedup: true };
87
+ return { id: recordEvent(db!, { surface: 'coord:channel', direction: 'outbound', kind: refs.kind ?? 'unknown',
88
+ domain: 'elanous', category: 'coordination', text: headline, summary: headline,
89
+ refs: JSON.stringify(refs), ts: at }), dedup: false };
90
+ }).immediate();
91
+ try { debug.log('context.coord', result.dedup ? 'dedup' : 'recorded', { seat: refs.seat, kind: refs.kind, hasUrl }); }
92
+ catch { /* observation cannot turn a successful write into a failed send */ }
93
+ return result.id;
94
+ } catch (error) {
95
+ try { debug.log('context.coord', 'failed', { seat: redactSecretText(input.seat), kind: input.kind && redactSecretText(input.kind), hasUrl }); }
96
+ catch { /* preserve the original write error */ }
97
+ throw error;
98
+ } finally { if (!deps.db) db?.close(); }
99
+ }
100
+
101
+ /** Read-only chronological list; a missing store is an empty ledger, not a newly created one. */
102
+ export function listCoordEvents(opts: { since: string; seat?: string }, deps: { db?: Database } = {}): CoordEvent[] {
103
+ if (!deps.db && !existsSync(surfaceEventsDbPath())) return [];
104
+ const db = deps.db ?? openSurfaceEventsDb();
105
+ try {
106
+ const rows = db.prepare(`SELECT id, ts, text, summary, kind, refs FROM events
107
+ WHERE surface IN ('coord:channel', 'context:external') AND direction='outbound' AND ts>=?
108
+ ${opts.seat ? "AND json_extract(refs,'$.seat')=?" : ''} ORDER BY ts ASC, rowid ASC`)
109
+ .all(...(opts.seat ? [opts.since, opts.seat] : [opts.since])) as Array<{
110
+ id: string; ts: string; text: string; summary: string; kind: string; refs: string;
111
+ }>;
112
+ return rows.map((r) => ({ id: r.id, at: r.ts, text: r.text, summary: r.summary, kind: r.kind,
113
+ refs: JSON.parse(r.refs) as CoordEvent['refs'] }));
114
+ } finally { if (!deps.db) db.close(); }
115
+ }
@@ -0,0 +1,52 @@
1
+ import type { Database } from 'bun:sqlite';
2
+ import { debug, redactSecretText } from '../debug/log.js';
3
+ import { openSurfaceEventsDb, recordEvent } from '../domains/surface-events.js';
4
+
5
+ export type ExternalEventOrigin = 'claude-code' | 'codex-agent-mission' | 'harness-child';
6
+ export type ContextHookKind = 'claimed' | 'done' | 'asked' | 'guide-changed';
7
+ export type ExternalEventKind = ContextHookKind | 'started' | 'finished';
8
+ export const CONTEXT_SUMMARY_MAX = 120;
9
+ export const CONTEXT_SOURCE_MAX = 512;
10
+
11
+ export interface ExternalEventInput {
12
+ origin: ExternalEventOrigin;
13
+ kind: ExternalEventKind;
14
+ summary: string;
15
+ source: string;
16
+ at?: string;
17
+ }
18
+
19
+ /** Only a single, bounded, redacted summary and a locator enter the journal; no prompt or transcript. */
20
+ export function recordExternalEvent(input: ExternalEventInput, deps: { db?: Database } = {}): string {
21
+ if (!['claude-code', 'codex-agent-mission', 'harness-child'].includes(input.origin)) throw new Error('invalid context origin');
22
+ if (input.origin === 'claude-code'
23
+ ? !['claimed', 'done', 'asked', 'guide-changed'].includes(input.kind)
24
+ : !['started', 'finished'].includes(input.kind)) throw new Error('invalid context kind');
25
+ const summary = redactSecretText(input.summary.split(/\r?\n/, 1)[0] ?? '').trim().slice(0, CONTEXT_SUMMARY_MAX);
26
+ const source = redactSecretText(input.source.split(/\r?\n/, 1)[0] ?? '').trim();
27
+ if (!summary) throw new Error('context summary must be one nonempty line');
28
+
29
+ if (!/^(?:https?:\/\/|elanous:\/\/)[^\s]+$/.test(source) || source.length > CONTEXT_SOURCE_MAX) {
30
+ throw new Error('context source must be a link (http(s) or elanous://), at most 512 characters');
31
+ }
32
+ const db = deps.db ?? openSurfaceEventsDb();
33
+ try {
34
+ return recordEvent(db, {
35
+ surface: 'context:external', direction: 'outbound', domain: 'elanous', category: 'coordination',
36
+ kind: input.kind, text: summary, summary,
37
+ refs: JSON.stringify({ seat: input.origin, recipients: [], all: false, kind: input.kind,
38
+ slot: null, deadline: null, url: source, origin: input.origin, source }),
39
+ ...(input.at ? { ts: input.at } : {}),
40
+ });
41
+ } finally { if (!deps.db) db.close(); }
42
+ }
43
+
44
+ /** Instrumentation never changes an agent's result. Failures remain visible without logging untrusted payloads. */
45
+ export function observeExternalEvent(input: ExternalEventInput, record: typeof recordExternalEvent = recordExternalEvent): void {
46
+ try { record(input); }
47
+ catch (error) {
48
+ try { debug.log('context.external', 'record-failed', {
49
+ origin: input.origin, kind: input.kind, reason: error instanceof Error ? error.message : String(error),
50
+ }, { level: 'warn' }); } catch { /* A broken logger cannot change an agent's result. */ }
51
+ }
52
+ }
@@ -0,0 +1,108 @@
1
+ import { redactSecretText } from '../debug/log.js';
2
+ import { DecisionLedger, type DecisionEntry } from '../decisions/decision-ledger.js';
3
+ import { listCoordEvents, type CoordEvent } from './coord-events.js';
4
+
5
+ export interface MemoryItem {
6
+ project: string;
7
+ seat: string;
8
+ topic: string;
9
+ summary: string;
10
+ source: string;
11
+ updatedAt: string;
12
+ status: 'active' | 'retired';
13
+ /** A normalized, comparable assertion supplied by the summarizer; absent means no conflict judgment. */
14
+ claim?: { key: string; value: string };
15
+ conflict?: { owner: 'OP'; sources: [string, string] };
16
+ }
17
+
18
+ export type MemorySource =
19
+ | { kind: 'event'; at: string; seat: string; text: string; source: string }
20
+ | { kind: 'decision'; at: string; seat: string; text: string; source: string };
21
+
22
+ export interface MemorySummary {
23
+ project: string;
24
+ topic: string;
25
+ summary: string;
26
+ /** Only supply this when the two strings identify the same fact and mutually exclusive values. */
27
+ claim?: { key: string; value: string };
28
+ }
29
+
30
+ export interface MemoryDeps {
31
+ summarize: (source: MemorySource) => Promise<MemorySummary>;
32
+ events?: (since: string) => CoordEvent[];
33
+ decisions?: () => DecisionEntry[];
34
+ }
35
+
36
+ const DAY_MS = 86_400_000;
37
+ const oneLine = (text: string) => redactSecretText(text.split(/\r?\n/, 1)[0] ?? '').trim();
38
+
39
+ /** Condense one UTC day; callers persist the returned snapshot, not raw transcripts. Read-only ledger access. */
40
+ export async function condenseContextDay(
41
+ day: string, previous: readonly MemoryItem[], deps: MemoryDeps, now: Date = new Date(),
42
+ ): Promise<MemoryItem[]> {
43
+ if (!/^\d{4}-\d\d-\d\d$/.test(day) || new Date(`${day}T00:00:00.000Z`).toISOString().slice(0, 10) !== day) {
44
+ throw new Error('day must be a valid UTC YYYY-MM-DD');
45
+ }
46
+ const since = `${day}T00:00:00.000Z`;
47
+ const start = Date.parse(since);
48
+ const until = start + DAY_MS;
49
+ // The store compares timestamp text, so fetch the previous local day too before UTC filtering.
50
+ const events = (deps.events ?? (from => listCoordEvents({ since: from })))(new Date(start - DAY_MS).toISOString());
51
+ const decisions = (deps.decisions ?? (() => new DecisionLedger().list({ status: 'all' })))();
52
+ const sources: MemorySource[] = [
53
+ ...events.map(event => ({ kind: 'event' as const, at: event.at, seat: event.refs.seat,
54
+ text: event.summary, source: event.refs.source ?? event.refs.url ?? `elanous://context/event/${encodeURIComponent(event.id)}` })),
55
+ ...decisions.map(decision => ({ kind: 'decision' as const,
56
+ at: decision.decidedAt ?? decision.raisedAt ?? decision.importedAt ?? '',
57
+ seat: decision.raisedBy.track ?? 'OP',
58
+ text: decision.status === 'decided' ? `${decision.title}: ${decision.options.find(o => o.key === decision.choice)?.label ?? decision.note ?? decision.scqa.a ?? '결정됨'}` : `${decision.title}: ${decision.status}`,
59
+ source: `elanous://decisions/${encodeURIComponent(decision.id)}` })),
60
+ ].filter(source => {
61
+ const at = Date.parse(source.at);
62
+ return Number.isFinite(at) && at >= start && at < until;
63
+ }).sort((a, b) => Date.parse(a.at) - Date.parse(b.at) || a.source.localeCompare(b.source));
64
+
65
+ const items = new Map<string, MemoryItem>();
66
+ const keyFor = (item: Pick<MemoryItem, 'project' | 'seat' | 'topic'>) => JSON.stringify([item.project, item.seat, item.topic]);
67
+ for (const item of previous) items.set(keyFor(item), { ...item });
68
+ for (const source of sources) {
69
+ const summary = await deps.summarize(source);
70
+ const project = oneLine(summary.project);
71
+ const seat = oneLine(source.seat);
72
+ const topic = oneLine(summary.topic);
73
+ const text = oneLine(summary.summary);
74
+ const link = oneLine(source.source);
75
+ if (!project || !seat || !topic || !text || !/^(?:https?:\/\/|elanous:\/\/)[^\s]+$/.test(link)) {
76
+ throw new Error('memory summary needs a project, seat, topic, one-line summary and source link');
77
+ }
78
+ const claim = summary.claim && { key: oneLine(summary.claim.key), value: oneLine(summary.claim.value) };
79
+ if (claim && (!claim.key || !claim.value)) throw new Error('memory claim needs key and value');
80
+ const key = keyFor({ project, seat, topic });
81
+ const old = items.get(key);
82
+ // Equal timestamps are resolved by the source link, so shuffled input does not change the winner.
83
+ if (old && (Date.parse(old.updatedAt) > Date.parse(source.at)
84
+ || (Date.parse(old.updatedAt) === Date.parse(source.at) && old.source >= link))) continue;
85
+ items.set(key, { project, seat, topic, summary: text, source: link, updatedAt: source.at,
86
+ status: 'active', ...(claim ? { claim } : {}) });
87
+ }
88
+ const cutoff = now.getTime() - 30 * DAY_MS;
89
+ // Compare only the winning, non-retired assertions; a superseded claim cannot keep a decision candidate alive.
90
+ const finalItems: MemoryItem[] = [...items.values()].map(({ conflict: _conflict, ...item }) => ({ ...item,
91
+ status: Date.parse(item.updatedAt) < cutoff ? 'retired' as const : 'active' as const,
92
+ }));
93
+ finalItems.sort((a, b) => Date.parse(a.updatedAt) - Date.parse(b.updatedAt) || a.source.localeCompare(b.source)
94
+ || a.seat.localeCompare(b.seat));
95
+ for (let index = 0; index < finalItems.length; index++) {
96
+ const item = finalItems[index]!;
97
+ if (item.status !== 'active' || !item.claim) continue;
98
+ const { key, value } = item.claim;
99
+ const conflicting = finalItems.slice(0, index).find(other => other.status === 'active'
100
+ && other.project === item.project
101
+ && other.claim?.key === key && other.claim.value !== value);
102
+ if (conflicting) {
103
+ finalItems[index] = { ...item, conflict: { owner: 'OP', sources: [conflicting.source, item.source] } };
104
+ }
105
+ }
106
+ return finalItems.sort((a, b) => a.project.localeCompare(b.project) || a.seat.localeCompare(b.seat)
107
+ || a.topic.localeCompare(b.topic));
108
+ }
@@ -0,0 +1,23 @@
1
+ import { showDashboard } from './index.js';
2
+
3
+ const expected = process.env.DASHBOARD_BOOT_SUGGESTION;
4
+ if (!expected) throw new Error('DASHBOARD_BOOT_SUGGESTION is required');
5
+
6
+ const originalWrite = process.stdout.write.bind(process.stdout);
7
+ let screen = '';
8
+ process.stdout.write = ((chunk: string | Uint8Array, ...args: unknown[]) => {
9
+ screen += typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString('utf8');
10
+ if (screen.includes(expected)) {
11
+ originalWrite(`FIRST_SCREEN_SUGGESTION=${expected}\n`);
12
+ process.exit(0);
13
+ }
14
+ return true;
15
+ }) as typeof process.stdout.write;
16
+
17
+ setTimeout(() => {
18
+ originalWrite(`FIRST_SCREEN_TIMEOUT=${screen.slice(-2000)}\n`);
19
+ process.exit(1);
20
+ }, 20_000).unref();
21
+
22
+ await showDashboard();
23
+ throw new Error('dashboard exited before suggestion appeared');
@@ -17,6 +17,8 @@ import type { CommandRunner } from '../ad-pipeline/higgsfield-backend.js';
17
17
  import type { ShootRunOptions } from '../ad-pipeline/shoot-run.js';
18
18
  import type { QcThresholds } from '../ad-pipeline/qc.js';
19
19
  import { elanousStateRoot } from '../autopilot/state-paths.js';
20
+ import { suggestProjectForFolder } from '../project/project-store.js';
21
+ import { createProjectSuggester } from '../project/project-suggestion.js';
20
22
 
21
23
  const dashboardDefaultShootRunOptions: Required<Pick<ShootRunOptions, 'pollIntervalMs' | 'maxPollsPerJob' | 'submitStaggerMs'>> = {
22
24
  pollIntervalMs: 3_000,
@@ -425,7 +427,6 @@ import {
425
427
  renderTurnTypeaheadEcho,
426
428
  } from '../chat/turn-typeahead.js';
427
429
  import { dispatchStreamingTurnTypeaheadSubmission } from './input/streaming-turn-typeahead.js';
428
- import { wireDashboardTurnTypeaheadEcho } from './turn-typeahead-echo.js';
429
430
  import { composeVertical, type LayoutZone } from '../layout/composer.js';
430
431
  import type { CoreTurnDispatchTool } from '../core-turn/index.js';
431
432
  // streamGrok kept as back-compat shim in chat.ts — not imported here
@@ -2656,6 +2657,41 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
2656
2657
  }
2657
2658
  chatScrollOffset = -1;
2658
2659
  };
2660
+ const liveTypeaheadEchoes: { at: number; lines: string[] }[] = [];
2661
+ const restoreLiveTypeaheadEchoes = (): void => {
2662
+ let after = 0;
2663
+ for (const echo of liveTypeaheadEchoes) {
2664
+ let found = -1;
2665
+ for (let i = after; i <= chatLines.length - echo.lines.length; i++) {
2666
+ if (echo.lines.every((line, offset) => chatLines[i + offset] === line)) {
2667
+ found = i;
2668
+ break;
2669
+ }
2670
+ }
2671
+ if (found < 0) {
2672
+ found = Math.max(after, Math.min(echo.at, chatLines.length));
2673
+ chatLines.splice(found, 0, ...echo.lines);
2674
+ }
2675
+ echo.at = found;
2676
+ after = found + echo.lines.length;
2677
+ }
2678
+ };
2679
+ const echoSubmittedUserText = (text: string, opts?: { live?: boolean }): void => {
2680
+ const echoStart = chatLines.length;
2681
+ chatLines.push('');
2682
+ if (opts?.live) chatLines.push(C.muted(' ↳ 이어서'));
2683
+ const echoWrapCols = Math.max(20, termSize().cols - 6);
2684
+ const echoRows = wrapAnsiByWidth(`❯ ${text}`, echoWrapCols);
2685
+ if (echoRows.length === 0) {
2686
+ chatLines.push(C.accent('❯ '));
2687
+ } else {
2688
+ echoRows.forEach((row, i) => {
2689
+ chatLines.push(C.accent(i === 0 ? row : ` ${row}`));
2690
+ });
2691
+ }
2692
+ if (opts?.live) liveTypeaheadEchoes.push({ at: echoStart, lines: chatLines.slice(echoStart) });
2693
+ chatScrollOffset = -1;
2694
+ };
2659
2695
  const pushDebugLine = (line: string): void => {
2660
2696
  debugLines.push(line);
2661
2697
  const dropCount = trimLogBuffer(debugLines, DEBUG_LOG_BUFFER_SOFT_LIMIT);
@@ -6907,7 +6943,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6907
6943
  turnTypeaheadRef.state = r.state;
6908
6944
  if (r.submissionDisposition) {
6909
6945
  debug.log('dashboard.turn-typeahead', 'submission-classified', {
6910
- text: r.immediateSubmission ?? turnTypeaheadRef.state.queuedSubmissions.at(-1),
6946
+ length: (r.immediateSubmission ?? turnTypeaheadRef.state.queuedSubmissions.at(-1))?.length ?? 0,
6911
6947
  disposition: r.submissionDisposition,
6912
6948
  });
6913
6949
  // ⭐⭐⭐ `B3`(2026-08-19 · 대표 지시 ②) — FIFO 로 «턴 종료 후» 나가던 것을,
@@ -6934,6 +6970,11 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6934
6970
  // 배수된 만큼을 앞에서부터 떨어낸다(FIFO · 순서 보존).
6935
6971
  const remaining = turnTypeaheadRef.state.queuedSubmissions.slice(drained.length);
6936
6972
  turnTypeaheadRef.state = { ...turnTypeaheadRef.state, queuedSubmissions: remaining };
6973
+ for (const text of drained) {
6974
+ echoSubmittedUserText(text, { live: true });
6975
+ debug.log('dashboard.turn-typeahead', 'echoed', { path: 'live', length: text.length });
6976
+ }
6977
+ if (drained.length > 0) draw();
6937
6978
  debug.log('dashboard.turn-typeahead', 'drained-into-live-turn', {
6938
6979
  drained: drained.length, remaining: remaining.length,
6939
6980
  });
@@ -15751,6 +15792,16 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
15751
15792
  chatLines.push(C.muted(` ${resume.turns} turns restored. Next turn continues this conversation.`));
15752
15793
  }
15753
15794
  }
15795
+ // 제안은 세션 작업 폴더 기준 — 시작 폴더 한 번이 아니라 폴더가 바뀔 때마다 다시 계산한다(IA1 리뷰 must-fix).
15796
+ const nextProjectSuggestion = createProjectSuggester(suggestProjectForFolder);
15797
+ const pushProjectSuggestion = (folder: string): void => {
15798
+ const project = nextProjectSuggestion(folder);
15799
+ if (project) chatLines.push(C.muted(` Project suggestion: ${project.name} (${project.id})`));
15800
+ };
15801
+ if (dashboardAcpBootResult.mode !== 'resumed' && !chat.history.some((message) => message.role !== 'system')) {
15802
+ pushProjectSuggestion(getSessionCwd());
15803
+ }
15804
+ subscribeSessionCwd((state) => { pushProjectSuggestion(state.cwd); });
15754
15805
  chatScrollOffset = -1;
15755
15806
  void renderDashboardFirstScreenBand({
15756
15807
  history: chat.history,
@@ -16820,8 +16871,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
16820
16871
  lastTurnFinalStatus = undefined;
16821
16872
  turnTypeaheadRef.state = drained.state;
16822
16873
  nextInitial = drained.nextInitial;
16823
- const turnTypeaheadEcho = wireDashboardTurnTypeaheadEcho(drained);
16824
- if (turnTypeaheadEcho) chatLines.push(C.muted(turnTypeaheadEcho));
16874
+ const queuedTurnEndText = drained.injectEnter ? drained.nextInitial : undefined;
16825
16875
  if (interrupted && queuedBeforeDrain > 0) {
16826
16876
  debug.log('dashboard.turn-typeahead', 'restored-after-interrupt', { count: queuedBeforeDrain });
16827
16877
  }
@@ -18655,25 +18705,11 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
18655
18705
  // pattern. Without this draw(), the echo sits in the chatLines
18656
18706
  // array but doesn't paint until after the skill router's
18657
18707
  // classifier LLM call returns (~1-2s of visual silence).
18658
- chatLines.push('');
18659
- // Wrap the echoed user message to the log width so long input
18660
- // soft-wraps onto continuation rows instead of being truncated
18661
- // with a `\u2026+N` marker by the log-pane renderer (which keeps a
18662
- // strict 1-line-per-row invariant and only truncates lines that
18663
- // weren't pre-wrapped). termCols-6 leaves room for the log
18664
- // pane's 2-col left margin plus the 2-col hanging indent on
18665
- // continuation rows; the \u276f marker stays on the first row only.
18666
- const echoWrapCols = Math.max(20, termSize().cols - 6);
18667
- const echoRows = wrapAnsiByWidth(`\u276f ${tok.text}`, echoWrapCols);
18668
- if (echoRows.length === 0) {
18669
- chatLines.push(C.accent('\u276f '));
18670
- } else {
18671
- echoRows.forEach((row, i) => {
18672
- chatLines.push(C.accent(i === 0 ? row : ` ${row}`));
18673
- });
18708
+ echoSubmittedUserText(tok.text);
18709
+ if (queuedTurnEndText !== undefined && input.text === queuedTurnEndText) {
18710
+ debug.log('dashboard.turn-typeahead', 'echoed', { path: 'turn-end', length: queuedTurnEndText.length });
18674
18711
  }
18675
18712
  renderAttachmentSummary(tok.added);
18676
- chatScrollOffset = -1;
18677
18713
  draw();
18678
18714
 
18679
18715
  // Start the animated thinking indicator BEFORE the router so
@@ -19031,6 +19067,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
19031
19067
  createTurnStreamRuntime: (initialAssistantStart) => {
19032
19068
  latestTurnUsage = undefined;
19033
19069
  createDashboardTurnStreamRuntimeEscBoundary(escAbortToolState);
19070
+ liveTypeaheadEchoes.length = 0;
19034
19071
  const toolRendering = {
19035
19072
  ...getUserConfig().chat.rendering.tool,
19036
19073
  expandHint: false,
@@ -19070,6 +19107,11 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
19070
19107
  });
19071
19108
  return {
19072
19109
  ...turnStreamRuntime,
19110
+ onText: (chunk, accumulated) => {
19111
+ turnStreamRuntime.onText(chunk, accumulated);
19112
+ restoreLiveTypeaheadEchoes();
19113
+ draw();
19114
+ },
19073
19115
  onToolCall: (call) => {
19074
19116
  const toolCall = call as DashboardTurnStreamCall;
19075
19117
  trackEscAbortToolCall(escAbortToolState, toolCall);
@@ -272,6 +272,8 @@
272
272
  // `../index.ts`) instead of importing the type — keeps this module free
273
273
  // of circular dependency on dashboard/index.ts.
274
274
 
275
+ import { tuiNowSlash } from '../../context-bus/context-now-surfaces.js';
276
+ import type { ContextNowDeps } from '../../context-bus/context-now.js';
275
277
  import { runRebindCommand } from '../../input-core/index.js';
276
278
  // B4 (TUI half) — /design reuses the CLI's own resolution so the three
277
279
  // surfaces (CLI, PWA panel, this) cannot answer differently.
@@ -1358,9 +1360,13 @@ function emitReplyToChat(ctx: Pick<DashboardSlashContext, 'pushChatLine'>, line:
1358
1360
  ctx.pushChatLine(line);
1359
1361
  }
1360
1362
 
1361
- export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSlashContext, DashboardSlashReturn> {
1363
+ export function buildDashboardSlashRegistry(nowDeps?: ContextNowDeps): SlashCommandRegistry<DashboardSlashContext, DashboardSlashReturn> {
1362
1364
  const registry = new SlashCommandRegistry<DashboardSlashContext, DashboardSlashReturn>();
1363
1365
 
1366
+ registry.register(['now'], (args, ctx) => {
1367
+ for (const line of tuiNowSlash(args, nowDeps)) ctx.pushChatLine(line);
1368
+ });
1369
+
1364
1370
  // ── B-1.a pilot ────────────────────────────────────────────────────
1365
1371
  registry.register(['quit', 'q', 'exit'], (_args, ctx) => {
1366
1372
  (ctx.exitTui ?? ctx.closeTui)();
@@ -3995,6 +4001,13 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
3995
4001
  }
3996
4002
 
3997
4003
  if (seSub === 'new' || seSub === 'clear') {
4004
+ if (seSub === 'new') {
4005
+ try {
4006
+ const { suggestProjectForFolder } = await import('../../project/project-store.js');
4007
+ const project = suggestProjectForFolder(process.cwd());
4008
+ if (project) ctx.chatLines.push(ctx.muted(` Project suggestion: ${project.name} (${project.id})`));
4009
+ } catch { /* suggestions must not interrupt a new conversation */ }
4010
+ }
3998
4011
  // Clear the in-memory history and detach if attached. Doesn't
3999
4012
  // delete any session files — those stay on disk for
4000
4013
  // /session list to enumerate.