elanous 0.2.10 → 0.2.12

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 (615) 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/-6XrAoD3eU7NyMHAE4xPS/_buildManifest.js +1 -0
  4. package/apps/pwa/out/_next/static/chunks/1147-466ec15afacc1a65.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/1159-0c5ef8bc21cb6afb.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1394-ee3795b112907122.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1452.93700483b9d4fc61.js +9 -0
  8. package/apps/pwa/out/_next/static/chunks/{6062-73e68343a9814f6a.js → 1829-b453a1b22d3999bb.js} +1 -1
  9. package/apps/pwa/out/_next/static/chunks/2176-c379e3ebce874151.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/2426.8c6ee0c668d53def.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/3170-7ec60a56fa0e4728.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/3278-ae6ef084769f6195.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/3454-988a53dac60a1763.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/3638-aa80b4641ea439db.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/3735-fe3402553ac1c9c6.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/3869-3cd46526879f454c.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/390.c373e31b3b9d0c41.js +5 -0
  18. package/apps/pwa/out/_next/static/chunks/3992-2e522a8ac5f2afde.js +25 -0
  19. package/apps/pwa/out/_next/static/chunks/4215-c9d91dd644ec1719.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/4508-5d0161d1e724d735.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/4685-c3c1c625b71accd1.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/4733-623a79345b171e1c.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/4883.3bd969ea1d3aaaff.js +2 -0
  24. package/apps/pwa/out/_next/static/chunks/5532.6899a12958a89b72.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/{8067-87ce253ec2f23697.js → 5845-e6c003ce8d5fd36a.js} +1 -1
  26. package/apps/pwa/out/_next/static/chunks/5978-b27004c677119115.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/{8046cadf-211ca3c0e00f2b72.js → 5cd7e3a9-404fd6b8d0ecd44c.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/6048-4c5c33579bc4ef78.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/6303-422dbf0f67c72aac.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/6751-bb3595948b2e311b.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/7274-19b7279f18b47ab3.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/7277-0b2fc7c16ba2d64b.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/{4323.c5dfb6f503304775.js → 7334.a6679d9168f37aa8.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/7551-a0e0707b79164ddd.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/7758-0b018a9e4fc56200.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/7777-79f845045aa1ed86.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/79f8be9e-957d68913b590b08.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/8025-cc24ee5d8f2fb6f8.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/8039-df92e08fede5de8f.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/8206-c6684dcde12be721.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/8421-1c4acfb1395a0edf.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/8605-0259994816604c49.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/8725.bf46bb1395dd0fa2.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/8734-252d511cd276c0dc.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/8834-ca1cb09c1cb1a6bf.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/{2415.ed6428ff334c7ce2.js → 9269.d2a4795bc6812717.js} +1 -1
  47. package/apps/pwa/out/_next/static/chunks/9538-2816b90923606459.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/9656-c1540088f5859c80.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/9906-482c6619b3fdda20.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/9920-5cfdc5e8fd209825.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-cb169620945d1952.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cefe8169e36cf62a.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/app/board/page-d2e35228bc497119.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-54b32bd27726588d.js → page-5c05b0da4bc1392c.js} +1 -1
  56. package/apps/pwa/out/_next/static/chunks/app/bots/page-e0ccdb576812b523.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/app/chat/page-813c4a52c9d05ca8.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/app/consult/page-4731f2c215358937.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/app/control/page-a022b257950f39e6.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/app/design-check/page-a2ffc717e04b8b0a.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/app/editor/page-b59ee4e70fc18fcf.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/app/exec/page-a67e11ba962337b5.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/app/field/page-c172dabd796eb7a3.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-1efd0cb9e0ed9d13.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/app/intake/page-d5dc7ff69a37b4cf.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/app/layout-e71c84189e8c683e.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/app/live/page-1d6a533ce5a6efcb.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/app/market/page-dfca9b7d2de0b135.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-793fa536b3a6ef37.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/app/morning/page-6dd3bfbbde2a5c2c.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/app/not-found-490653e8d4cc8852.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/app/observatory/page-77447356baad75d2.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-29e961191f6057df.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-c822f55b884d9104.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fa4ccfc432424e52.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/app/outputs/page-6d604227e1664b71.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/app/page-9c7e8f744a765daf.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/app/reflection/page-4048543b4b7ad5e0.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-4c3a3126abed551a.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/app/sessions/page-64b0aecb1ca75e75.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-4292d0149020e8a7.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/app/settings/page-db14d0be7f1c460c.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-e5d8072cd7cfef73.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-9547b5cec7cf76bf.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/app/share/page-e6dcb83265530636.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/app/showroom/page-45248f08d6aecae5.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/app/tasks/page-2cddeb9e2aeedc55.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/app/term/page-e297866051595d81.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/app/today/page-baba2e047872fb0f.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/app/trace/page-e895da4ec9cac345.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/app/vault/page-4344faf20216233b.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-698bb29f11864b89.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/app/workflows/page-bd6a6dc1ddc273f2.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/app/workspace/page-2e9e2fb01c9da1c9.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-d62ceb13411ebba4.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/128fb7fb670b2fbf.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 -1
  152. package/apps/pwa/out/ops/seats/index.txt +22 -22
  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 -1
  178. package/apps/pwa/out/today/index.txt +23 -23
  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/context/nightly-condense.yaml +21 -0
  192. package/graphs/context/recipes.yaml +12 -0
  193. package/graphs/demo/inside-seed.yaml +20 -0
  194. package/graphs/demo/recipes.yaml +12 -0
  195. package/graphs/drafts/draft-cleanup.yaml +19 -0
  196. package/graphs/drafts/recipes.yaml +23 -0
  197. package/graphs/intake/intake-daily.yaml +2 -1
  198. package/graphs/ops/recipes.yaml +3 -0
  199. package/graphs/ops/secret-exposure.yaml +24 -0
  200. package/graphs/release/recipes.yaml +3 -0
  201. package/graphs/release/release-loop.yaml +4 -1
  202. package/graphs/video/explainer-line.yaml +2 -2
  203. package/package.json +2 -1
  204. package/plugins/card-followup/examples/sample-card.png +0 -0
  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/context-hooks/claude-stop.sh +4 -0
  216. package/scripts/context-hooks/emit.ts +24 -0
  217. package/scripts/context-hooks/post-tool-use.sh +4 -0
  218. package/scripts/coord-channel-watch.sh +12 -0
  219. package/scripts/coord-requests-bridge.ts +143 -0
  220. package/scripts/field-feed/lib.ts +4 -0
  221. package/scripts/fleet/node-setup.sh +20 -3
  222. package/scripts/homebrew-formula-bump.ts +69 -0
  223. package/scripts/lib/telegram-inject-args.ts +31 -0
  224. package/scripts/marketing/measure-site-numbers.ts +169 -0
  225. package/scripts/measure-gate-shards.ts +309 -0
  226. package/scripts/measure-pod-memory-by-goal.ts +130 -0
  227. package/scripts/mission-request-judge.ts +31 -1
  228. package/scripts/morning-report.ts +2 -2
  229. package/scripts/opportunity-scan.ts +1 -1
  230. package/scripts/release-loop/auto-approve-node.ts +21 -4
  231. package/scripts/release-loop/checklist-gate-node.ts +2 -1
  232. package/scripts/release-loop/cut-branch.ts +84 -0
  233. package/scripts/release-loop/gate-node.ts +22 -15
  234. package/scripts/release-loop/mac-smoke-node.ts +229 -0
  235. package/scripts/release-loop/node-verdict.ts +3 -3
  236. package/scripts/release-loop/ops-upgrade-node.ts +47 -6
  237. package/scripts/release-loop/publish-node.ts +4 -1
  238. package/scripts/release-loop/tui-node-checks.ts +42 -0
  239. package/scripts/release-loop/tui-sim-node.ts +32 -8
  240. package/scripts/release-loop/unattended-release.ts +5 -3
  241. package/scripts/release-loop/version-node.ts +74 -13
  242. package/scripts/signal-digest-cycle.ts +2 -7
  243. package/scripts/signal-digest-photo.ts +11 -0
  244. package/scripts/tech1-public-measure.ts +94 -0
  245. package/scripts/telegram-inject.ts +14 -6
  246. package/scripts/test-diet/node.ts +1 -1
  247. package/scripts/test-diet/remeasure-list.ts +112 -0
  248. package/scripts/tui-regress.ts +2 -2
  249. package/scripts/ux/demo-rehearsal.ts +247 -0
  250. package/scripts/ux/demo-seed.ts +108 -0
  251. package/scripts/ux/lib/rehearsal-verdict.ts +80 -0
  252. package/skills/diagram-master/SKILL.md +366 -0
  253. package/skills/diagram-master/references/engines/excalidraw/color-palette.md +67 -0
  254. package/skills/diagram-master/references/engines/excalidraw/element-templates.md +182 -0
  255. package/skills/diagram-master/references/engines/excalidraw/json-schema.md +71 -0
  256. package/skills/diagram-master/references/engines/excalidraw/render_excalidraw.py +189 -0
  257. package/skills/diagram-master/references/engines/excalidraw/render_template.html +57 -0
  258. package/skills/diagram-master/references/engines/matplotlib/matplotlib-patterns.md +235 -0
  259. package/skills/diagram-master/references/engines/matplotlib/render_matplotlib.py +184 -0
  260. package/skills/diagram-master/references/engines/mermaid/domain-templates.md +435 -0
  261. package/skills/diagram-master/references/engines/mermaid/render_mermaid.py +116 -0
  262. package/skills/diagram-master/references/engines/mermaid/syntax-reference.md +2247 -0
  263. package/skills/diagram-master/references/engines/nanobannana/render_nanobannana2.py +168 -0
  264. package/skills/diagram-master/references/engines/svg/color-palette.md +188 -0
  265. package/skills/diagram-master/references/engines/svg/html-base-template.html +332 -0
  266. package/skills/diagram-master/references/engines/svg/interactivity-patterns.md +435 -0
  267. package/skills/diagram-master/references/engines/svg/render_interactive_svg.py +212 -0
  268. package/skills/diagram-master/references/engines/svg/svg-element-templates.md +349 -0
  269. package/skills/diagram-master/references/examples/README.md +69 -0
  270. package/skills/diagram-master/references/examples/ref_grid_architecture.png +0 -0
  271. package/skills/diagram-master/references/examples/ref_layered_flow.png +0 -0
  272. package/skills/diagram-master/references/pyproject.toml +16 -0
  273. package/skills/diagram-master/references/quality-checklist.md +33 -0
  274. package/skills/diagram-master/references/routing-guide.md +164 -0
  275. package/skills/diagram-master/references/uv.lock +1356 -0
  276. package/skills/google-workspace/SKILL.md +33 -0
  277. package/skills/google-workspace/scripts/gws-safe.sh +177 -0
  278. package/skills/grill-me/SKILL.md +1 -1
  279. package/skills/lecture-note-digitizer/SKILL.md +926 -0
  280. package/skills/lecture-note-digitizer/references/convert_to_pdf.py +30 -0
  281. package/skills/lecture-note-digitizer/references/extract_slide_diagram.py +73 -0
  282. package/skills/lecture-note-digitizer/references/html-template.md +167 -0
  283. package/skills/lecture-note-digitizer/references/katex-style-guide.md +165 -0
  284. package/skills/omni-crawl/SKILL.md +21 -11
  285. package/skills/omni-crawl/scripts/main.ts +6 -6
  286. package/skills/omni-crawl/src/router.ts +3 -3
  287. package/skills/omni-digest/SKILL.md +17 -9
  288. package/skills/omni-digest/digest.md +2 -2
  289. package/skills/omni-digest/src/fetch.ts +30 -3
  290. package/skills/pitch-deck/SKILL.md +2 -2
  291. package/skills/pitch-deck/template.html +2 -2
  292. package/skills/youtube-master/SKILL.md +163 -0
  293. package/skills/youtube-master/package-lock.json +558 -0
  294. package/skills/youtube-master/package.json +13 -0
  295. package/skills/youtube-master/references/study-note-template.md +124 -0
  296. package/skills/youtube-master/scripts/main.ts +435 -0
  297. package/skills/youtube-master/scripts/transcribe-local.ts +24 -0
  298. package/skills/youtube-master/src/audio.ts +63 -0
  299. package/skills/youtube-master/src/domain-staging.ts +50 -0
  300. package/skills/youtube-master/src/env.ts +36 -0
  301. package/skills/youtube-master/src/obsidian.ts +155 -0
  302. package/skills/youtube-master/src/router.ts +110 -0
  303. package/skills/youtube-master/src/stt.ts +199 -0
  304. package/skills/youtube-master/src/study-note.ts +175 -0
  305. package/skills/youtube-master/src/summarize.ts +358 -0
  306. package/skills/youtube-master/src/transcript.ts +76 -0
  307. package/skills/youtube-master/src/types.ts +91 -0
  308. package/skills/youtube-master/src/util.ts +93 -0
  309. package/skills/youtube-master/src/youtube.ts +70 -0
  310. package/skills/youtube-master/tsconfig.json +13 -0
  311. package/src/acp/server.ts +5 -2
  312. package/src/agent-mission/driver.ts +215 -23
  313. package/src/agent-mission/pty-decision.ts +71 -0
  314. package/src/agent-mission/review-loop.ts +30 -0
  315. package/src/autopilot/build/llm-conflict-merge.ts +16 -3
  316. package/src/autopilot/pty-control-loop.ts +4 -1
  317. package/src/autopilot/tool-registry.ts +2 -0
  318. package/src/boot/daemon-prompt-turn.ts +5 -0
  319. package/src/boot/daemon-runtime.ts +9 -3
  320. package/src/boot/daemon-tools/web-search.ts +3 -0
  321. package/src/card-followup/core.ts +109 -0
  322. package/src/chat/index.ts +2 -0
  323. package/src/cli/drive-input-jail.ts +101 -0
  324. package/src/cli/hooks-cli.ts +17 -3
  325. package/src/cli/make-cli.ts +43 -0
  326. package/src/cli/persona-cli.ts +98 -9
  327. package/src/cli/plugin-cli.ts +31 -22
  328. package/src/cli/pod-cli.ts +36 -9
  329. package/src/cli/pod-memory-advice.ts +35 -0
  330. package/src/cli/pr-cli.ts +51 -15
  331. package/src/cli/pty-drive-cli.ts +41 -7
  332. package/src/cli/pty-drive-verdict.ts +40 -0
  333. package/src/cli/release-cli.ts +63 -10
  334. package/src/cli/setup-cli.ts +43 -1
  335. package/src/cli/skills-cli.ts +17 -1
  336. package/src/context-bus/claude-hooks-install.ts +10 -0
  337. package/src/context-bus/context-now-surfaces.ts +65 -0
  338. package/src/context-bus/context-now.ts +104 -0
  339. package/src/context-bus/coord-events.ts +2 -2
  340. package/src/context-bus/external-events.ts +52 -0
  341. package/src/context-bus/long-term-memory.ts +108 -0
  342. package/src/context-bus/nightly-condense.ts +153 -0
  343. package/src/context-bus/session-events.ts +35 -0
  344. package/src/dashboard/dashboard-status-lines.ts +2 -0
  345. package/src/dashboard/index.ts +17 -4
  346. package/src/dashboard/slash-runtime/dashboard-handlers.ts +31 -1
  347. package/src/decisions/decision-cards.ts +10 -3
  348. package/src/decisions/decision-ledger.ts +13 -5
  349. package/src/discord/sprint21-runtime.ts +5 -1
  350. package/src/discord-self-message.ts +32 -0
  351. package/src/discord-slash-wire.ts +5 -1
  352. package/src/discord.ts +17 -1
  353. package/src/domains/core-tools.ts +3 -2
  354. package/src/domains/outbound-alert.ts +105 -32
  355. package/src/domains/outbound-log-probe.ts +8 -0
  356. package/src/domains/telegram-kind-route.ts +51 -13
  357. package/src/exec-requests/default-outputs.ts +25 -0
  358. package/src/exec-requests/planner.ts +10 -2
  359. package/src/exec-requests/runner.ts +20 -6
  360. package/src/exec-requests/store.ts +3 -0
  361. package/src/execution-loop/launch-gate.ts +109 -0
  362. package/src/field/field-reel.ts +5 -1
  363. package/src/field-note/index.ts +201 -0
  364. package/src/field-note/telegram.ts +142 -0
  365. package/src/field-note/transcribe.ts +248 -0
  366. package/src/graph-kinds/registry.ts +3 -3
  367. package/src/graph-runner/graph-cli.ts +61 -1
  368. package/src/graph-runner/graph-grow-llm.ts +47 -0
  369. package/src/graph-runner/graph-grow.ts +50 -0
  370. package/src/graph-runner/runner.ts +329 -33
  371. package/src/grok/agent-search.ts +8 -2
  372. package/src/guardian/secret-exposure-scan.ts +101 -0
  373. package/src/harness/harness-cli-command.ts +375 -13
  374. package/src/harness/harness-pod-dispatch.ts +43 -23
  375. package/src/harness/harness-seams.ts +38 -4
  376. package/src/harness/harness-stop.ts +23 -4
  377. package/src/harness/launch-registry.ts +91 -0
  378. package/src/harness/process-garbage.ts +5 -3
  379. package/src/hooks/consult-intake.ts +153 -0
  380. package/src/hooks/dispatch.ts +82 -0
  381. package/src/hooks/expose.ts +254 -0
  382. package/src/hooks/github-shadow.ts +108 -0
  383. package/src/hooks/providers.ts +71 -5
  384. package/src/hooks/queue.ts +1 -1
  385. package/src/hooks/receiver.ts +94 -16
  386. package/src/index.ts +76 -14
  387. package/src/intake-plane/categorize.ts +18 -46
  388. package/src/intake-plane/discord-seat-work.ts +38 -2
  389. package/src/intake-plane/front-route-classifier.ts +33 -39
  390. package/src/intake-plane/persona-answer.ts +30 -0
  391. package/src/intake-plane/runtime-callables.ts +8 -1
  392. package/src/intake-plane/telegram-seat-work.ts +36 -2
  393. package/src/intake-plane/wish-card.ts +33 -0
  394. package/src/intake-plane/wish-folder.ts +67 -0
  395. package/src/intent-gate/gate.ts +30 -10
  396. package/src/live/detail-switch.ts +5 -0
  397. package/src/llm/difficulty.ts +57 -0
  398. package/src/llm/judge-layer.ts +101 -0
  399. package/src/llm/mission-router.ts +33 -19
  400. package/src/loops/contract/examples/cmo-seat.loop.yaml +51 -0
  401. package/src/loops/contract/examples/orchestrator.loop.yaml +57 -0
  402. package/src/loops/contract/examples/steward.loop.yaml +50 -0
  403. package/src/loops/contract/loop-agent.schema.json +138 -0
  404. package/src/loops/contract/validate.ts +64 -0
  405. package/src/loops/registry.ts +20 -6
  406. package/src/market/signed-index.ts +4 -0
  407. package/src/maturity/bot-command-maturity.ts +45 -0
  408. package/src/maturity/feature-maturity.ts +27 -4
  409. package/src/model-tier/index.ts +2 -2
  410. package/src/model-tier/tier-resolver.ts +20 -20
  411. package/src/model-tier/types.ts +6 -6
  412. package/src/mss/logging/log-store.ts +15 -0
  413. package/src/nexus/api/config-model-tier.ts +5 -4
  414. package/src/nexus/api/fabric-plans.ts +53 -0
  415. package/src/nexus/api/harness-api.ts +5 -1
  416. package/src/nexus/api/health.ts +2 -0
  417. package/src/nexus/api/http-server.ts +67 -8
  418. package/src/nexus/api/inside-events.ts +226 -0
  419. package/src/nexus/api/meta-api.ts +21 -8
  420. package/src/nexus/api/missions.ts +6 -1
  421. package/src/nexus/api/ops-seats.ts +33 -0
  422. package/src/nexus/api/outbound-report.ts +40 -7
  423. package/src/nexus/api/outputs-route.ts +44 -0
  424. package/src/nexus/api/personas.ts +95 -53
  425. package/src/nexus/api/seat-requests.ts +44 -2
  426. package/src/nexus/api/sessions-store.ts +17 -38
  427. package/src/nexus/api/sub-seat-charters.ts +34 -0
  428. package/src/nexus/api/tabs-mutations.ts +3 -1
  429. package/src/nexus/api/task-cards-api.ts +19 -0
  430. package/src/nexus/api/trace.ts +18 -6
  431. package/src/nexus/api/workflow-history.ts +88 -0
  432. package/src/nexus/api/workflow-run-event-bridge.ts +1 -0
  433. package/src/nexus/api/workflows.ts +132 -6
  434. package/src/nexus/index.ts +2 -0
  435. package/src/nexus/kinds/webterm.ts +2 -1
  436. package/src/nexus/outbound/delivery-ledger.ts +17 -8
  437. package/src/nexus/outbound/router.ts +8 -3
  438. package/src/nexus/webterm/pty.ts +6 -2
  439. package/src/onboarding/cli-auth-status.ts +80 -0
  440. package/src/onboarding/voice-ai.ts +3 -3
  441. package/src/org/seat-budget.ts +48 -0
  442. package/src/org/stall-escalation.ts +63 -0
  443. package/src/outputs/ledger.ts +120 -0
  444. package/src/persona/persona-todo.ts +79 -0
  445. package/src/persona/presets.ts +123 -2
  446. package/src/persona/team-set.ts +155 -0
  447. package/src/plugins/install/plugin-install.ts +14 -0
  448. package/src/plugins/maker/market-bundle.ts +110 -0
  449. package/src/plugins/maker/plugin-maker.ts +254 -11
  450. package/src/plugins/maker/wizard-generate.ts +103 -0
  451. package/src/pod-lease/admission.ts +150 -0
  452. package/src/pod-lease/dependency-state.ts +85 -0
  453. package/src/pod-lease/host-lease.ts +127 -0
  454. package/src/project/project-suggestion.ts +16 -0
  455. package/src/project/session-context.ts +24 -0
  456. package/src/release-loop/checklist.ts +17 -5
  457. package/src/release-loop/feature-store.ts +29 -13
  458. package/src/release-loop/landed-but-yellow.ts +48 -0
  459. package/src/release-loop/next-md-merge.ts +58 -0
  460. package/src/release-loop/release-note.ts +59 -4
  461. package/src/seat-dispatch/seat-ask.ts +130 -0
  462. package/src/seat-dispatch/seat-questions.ts +100 -0
  463. package/src/seat-loop/seat-loop.ts +709 -29
  464. package/src/seat-loop/seat-report.ts +37 -2
  465. package/src/self-dev/dev-cli.ts +4 -1
  466. package/src/self-dev/dev-pipeline.ts +37 -1
  467. package/src/self-dev/draft-sweep.ts +79 -40
  468. package/src/self-dev/draft-triage-rules.ts +62 -7
  469. package/src/self-dev/fabric-plan-core.ts +297 -0
  470. package/src/self-dev/orchestrate.ts +36 -4
  471. package/src/self-dev/release-path-guard.ts +62 -0
  472. package/src/self-dev/shard-aggregate.ts +230 -0
  473. package/src/self-dev/shard-placement.ts +60 -0
  474. package/src/self-dev/shard-plan.ts +48 -0
  475. package/src/self-dev/shard-pod-run.ts +77 -0
  476. package/src/self-dev/shard-run.ts +105 -0
  477. package/src/self-implement/budget-gate.ts +29 -12
  478. package/src/self-implement/gate-baseline.ts +1 -1
  479. package/src/self-implement/gate-candidate-ranking.ts +60 -0
  480. package/src/self-implement/gate-cli.ts +40 -1
  481. package/src/self-implement/gate-scope.ts +44 -13
  482. package/src/self-implement/graph-variant.ts +171 -0
  483. package/src/self-implement/harness-policy-gates.ts +1 -1
  484. package/src/self-implement/headless-elanous-driver.ts +27 -3
  485. package/src/self-implement/host-regate.ts +22 -1
  486. package/src/self-implement/importer-test-index.ts +2 -1
  487. package/src/self-implement/l8-merge-queue.ts +130 -0
  488. package/src/self-implement/orchestrator.ts +257 -9
  489. package/src/self-implement/route-consumer-test-index.ts +122 -0
  490. package/src/self-implement/seams.ts +72 -11
  491. package/src/self-implement/test-seams.ts +2 -0
  492. package/src/self-implement/uncommitted-work.ts +59 -0
  493. package/src/session/index.ts +36 -13
  494. package/src/skills/gift-install.ts +215 -0
  495. package/src/skills/tools/web-search.ts +4 -1
  496. package/src/steward/launch.ts +42 -26
  497. package/src/steward/steward-cards.ts +17 -9
  498. package/src/steward/triage.ts +46 -14
  499. package/src/task-cards/card-cli.ts +25 -1
  500. package/src/task-orchestrator/mission.ts +5 -0
  501. package/src/task-orchestrator/store.ts +12 -3
  502. package/src/task-orchestrator/surfaces/pod-command-job.ts +43 -17
  503. package/src/task-orchestrator/surfaces/pod-lease.ts +156 -19
  504. package/src/task-orchestrator/surfaces/pod-pool.ts +127 -26
  505. package/src/task-orchestrator/surfaces/self-implement-pod.ts +222 -40
  506. package/src/task-orchestrator/surfaces/self-implement.ts +15 -2
  507. package/src/task-orchestrator/types.ts +2 -0
  508. package/src/telegram-card-followup.ts +16 -96
  509. package/src/telegram-commands.ts +31 -1
  510. package/src/telegram-project-command.ts +145 -0
  511. package/src/telegram-report.ts +21 -17
  512. package/src/telegram.ts +61 -8
  513. package/src/tool-runtime/self-cognition-runtimes.ts +13 -3
  514. package/src/user-config.ts +110 -24
  515. package/src/version/packed-revision.json +1 -1
  516. package/src/web-search/grok.ts +7 -1
  517. package/src/web-search/index.ts +28 -1
  518. package/src/web-search/provider.ts +4 -0
  519. package/src/web-search/x-intent.ts +5 -0
  520. package/src/workflow-runtime/executor.ts +277 -47
  521. package/src/workflow-runtime/index.ts +1 -0
  522. package/src/workflow-runtime/nodes/subworkflow.ts +60 -0
  523. package/src/workflow-runtime/plugin-kind-node.ts +1 -1
  524. package/src/workflow-runtime/schema.ts +79 -4
  525. package/src/workflow-runtime/types.ts +35 -4
  526. package/apps/pwa/out/_next/static/2DsiDfDCks44g1cPUMhiW/_buildManifest.js +0 -1
  527. package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/1377-1efeffbbac0963ff.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/1470.98a6ab61ccb4131c.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/2375-cb6debea56cce4fb.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/24-e6d28380efab7faf.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/2977-e38442e86289f1d3.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/2982-2a2df543be3d2e5a.js +0 -25
  536. package/apps/pwa/out/_next/static/chunks/3403.4bc97b4066945a94.js +0 -5
  537. package/apps/pwa/out/_next/static/chunks/3615-740dd270764ffa24.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/3734-1015fe991eb9b7e7.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/5012-a7fe6f3c8b6fe45a.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/5783-ef40ebfc91d55230.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/5791-bb82743fa6299562.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/62-ff227c3edb8b248b.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/6320-baac91d68843a9a6.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/7633-1b3709b0854c9412.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/7647.2fcd30d894d5ee30.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/7951-8b03dbb10b24cd06.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/8142-744998d65d7bb17e.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/8195-6fde3d7a39859206.js +0 -10
  556. package/apps/pwa/out/_next/static/chunks/8619-4365e03a2862830f.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/8894-b5fb36bab837cd29.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/9454-84d0d5d77446bd92.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/9651-3cd291a6fa1370d2.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/988-5f92e7ab7ccea3dd.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/9989-5582582f06429840.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/ae787e4c-f2998de7f1ba72a4.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d2253d7e58ef1890.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5441d4a9ab35e518.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/app/board/page-d9b12d680922d980.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/app/bots/page-e268d6d145827a22.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/app/chat/page-f8116559c7424da7.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/app/consult/page-1085399fd0f32112.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/app/control/page-1df686a14f65895a.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/app/design-check/page-54e1f966ab60a4dc.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/app/editor/page-7ed95f296f5ee8e9.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/app/exec/page-11edac668d77e5c3.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/field/page-59e2b9a22cd5a6d5.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/intake/page-2976df21ad74ab48.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/layout-34d211a67f16d510.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/app/live/page-8ff652d5d950639b.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/app/market/page-b31610deda76337b.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-6cb0e1bbefe5fb3d.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/app/morning/page-a286a152cf584576.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/app/not-found-d9237581e7003bcb.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/app/observatory/page-83274e761643fdd2.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ceee6cfb1d4e6d68.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-9c9f8bb3e4a64091.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-c17217603ea3426a.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/app/page-efb6177cbf1e8a51.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/app/reflection/page-d307523703bc4df3.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-462f4e4bab45ce7d.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/app/sessions/page-8990e96f33af3837.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-e168fa1030af0548.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/app/settings/page-1233e05a4068bc9c.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-13a1840b1fac337a.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/app/setup/page-64a29fc80b11ab55.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/app/share/page-68e787339a16b3dc.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/app/showroom/page-4fddc90b23feb215.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/app/tasks/page-886ba8260dc79c79.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/app/term/page-0f26507a1722e40b.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/app/today/page-109d4ccd42259c9d.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/app/trace/page-f5c2a4e510726774.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/app/vault/page-b2e0039416f42522.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-26102fd7350f171e.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/app/workflows/page-708948bc8a802794.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/app/workspace/page-5e5611620f78fb0b.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-139ba5c367bbf60a.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/main-app-202b4e81f33895ea.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/webpack-e5bea36f183b25e6.js +0 -1
  614. package/apps/pwa/out/_next/static/css/43feca5fd387dcbd.css +0 -1
  615. /package/apps/pwa/out/_next/static/{2DsiDfDCks44g1cPUMhiW → -6XrAoD3eU7NyMHAE4xPS}/_ssgManifest.js +0 -0
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * Steps: temp worktree at <sha> → `scripts/tui-sim.ts start --test` (that commit's code, the
8
8
  * repo's `.elanous-test` config so no first-run wizard) → first screen → `/help` → Esc → dump PNG
9
- * → stop, clean, remove worktree. Never touches the production daemon or ~/.elanous.
9
+ * → stop, clean → run seven PTY regression checks → remove worktree. Never touches the production daemon or ~/.elanous.
10
10
  * macOS only (the TUI PTY checks run on the mbp). One retry of the whole session → «flaky».
11
11
  *
12
12
  * Exit: 0 = pass or flaky · 1 = fail · 2 = could not run (not macOS, worktree).
@@ -15,7 +15,7 @@ import { spawn, spawnSync } from 'node:child_process';
15
15
  import { copyFileSync, existsSync, mkdtempSync, openSync, symlinkSync } from 'node:fs';
16
16
  import { tmpdir } from 'node:os';
17
17
  import { basename, join, resolve } from 'node:path';
18
- import { tuiChecks, tuiVerdict, type TuiCheck } from './tui-node-checks';
18
+ import { parseTuiRegress, regressWarning, tuiChecks, tuiVerdict, type TuiCheck, type TuiRegress } from './tui-node-checks';
19
19
 
20
20
  const log = (msg: string) => process.stderr.write(`[tui-node] ${msg}\n`);
21
21
  const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
@@ -64,6 +64,27 @@ async function session(worktree: string, stateDir: string, id: string, work: str
64
64
  }
65
65
  }
66
66
 
67
+ export function measureTuiRegress(worktree: string, runner: typeof spawnSync = spawnSync): TuiRegress {
68
+ try {
69
+ const measured = runner('bun', ['scripts/tui-regress.ts', '--json'], {
70
+ cwd: worktree, encoding: 'utf8', timeout: 180_000, maxBuffer: 16 * 1024 * 1024,
71
+ });
72
+ if (measured.error) return { unmeasured: measured.error.message };
73
+ if (measured.status !== 0 && measured.status !== 1) {
74
+ return { unmeasured: `실행 종료 코드 ${measured.status ?? measured.signal ?? '없음'}: ${(measured.stderr ?? '').trim().slice(0, 200)}` };
75
+ }
76
+ return parseTuiRegress(measured.stdout ?? '');
77
+ } catch (error) {
78
+ return { unmeasured: String(error) };
79
+ }
80
+ }
81
+
82
+ export function tuiNodeOutput(commit: string, attempts: Array<{ checks: TuiCheck[]; png?: string }>, regress: TuiRegress, failure?: string) {
83
+ const last = attempts.at(-1);
84
+ const verdict = !last ? 'error' : tuiVerdict(last.checks) === 'fail' ? 'fail' : attempts.length > 1 ? 'flaky' : 'pass';
85
+ return { verdict, commit, attempts: attempts.length, checks: last?.checks ?? [], png: last?.png, regress, ...(failure ? { error: failure } : {}) };
86
+ }
87
+
67
88
  async function main(): Promise<number> {
68
89
  const argv = process.argv.slice(2);
69
90
  const commit = argv[argv.indexOf('--commit') + 1] ?? '';
@@ -77,9 +98,12 @@ async function main(): Promise<number> {
77
98
  const worktree = join(work, 'tree');
78
99
  let attempts: Array<{ checks: TuiCheck[]; png?: string }> = [];
79
100
  let failure: string | undefined;
101
+ let regress: TuiRegress = { unmeasured: 'worktree를 만들지 못했다' };
102
+ let worktreeReady = false;
80
103
  try {
81
104
  const add = spawnSync('git', ['worktree', 'add', '--detach', worktree, commit], { cwd: repo, encoding: 'utf8' });
82
105
  if (add.status !== 0) throw new Error(`worktree add failed: ${(add.stderr ?? '').trim()}`);
106
+ worktreeReady = true;
83
107
  symlinkSync(join(repo, 'node_modules'), join(worktree, 'node_modules'));
84
108
  if (!existsSync(join(stateDir, 'config.json'))) log(`⚠ ${stateDir}/config.json missing — the TUI may open the first-run wizard`);
85
109
  const id = `rl-${commit.slice(0, 8)}-${Date.now().toString(36)}`;
@@ -94,20 +118,20 @@ async function main(): Promise<number> {
94
118
  log(`could not run: ${failure}`);
95
119
  attempts = [];
96
120
  } finally {
121
+ if (worktreeReady) regress = measureTuiRegress(worktree);
97
122
  spawnSync('git', ['worktree', 'remove', '--force', worktree], { cwd: repo });
98
123
  }
99
124
 
100
- const last = attempts.at(-1);
101
- const verdict = !last ? 'error' : tuiVerdict(last.checks) === 'fail' ? 'fail' : attempts.length > 1 ? 'flaky' : 'pass';
102
- const out = { verdict, commit, attempts: attempts.length, checks: last?.checks ?? [], png: last?.png, ...(failure ? { error: failure } : {}) };
125
+ const out = tuiNodeOutput(commit, attempts, regress, failure);
103
126
  if (json) console.log(JSON.stringify(out));
104
127
  else {
105
- console.log(`tui-node: ${verdict} · ${commit.slice(0, 10)} · attempts ${attempts.length}`);
128
+ console.log(`tui-node: ${out.verdict} · ${commit.slice(0, 10)} · attempts ${attempts.length}`);
106
129
  for (const c of out.checks) console.log(` ${c.pass ? '✓' : '✗'} ${c.id} — ${c.detail}`);
107
130
  if (out.png) console.log(` screen: ${out.png}`);
131
+ console.log(` ${regressWarning(regress).line}`);
108
132
  if (failure) console.log(` error: ${failure}`);
109
133
  }
110
- return verdict === 'error' ? 2 : verdict === 'fail' ? 1 : 0;
134
+ return out.verdict === 'error' ? 2 : out.verdict === 'fail' ? 1 : 0;
111
135
  }
112
136
 
113
- process.exit(await main());
137
+ if (import.meta.main) process.exit(await main());
@@ -24,6 +24,7 @@ export interface ReleaseLoopConfig {
24
24
  export interface ReleaseRunInput extends ReleaseLoopConfig {
25
25
  version: string;
26
26
  previousVersion: string;
27
+ cutCommit?: string;
27
28
  gatePodPool: string;
28
29
  }
29
30
 
@@ -67,7 +68,7 @@ export function releaseLoopConfig(configPath = getElanousConfigDirOverride() ? j
67
68
  return raw.release?.loop ?? {};
68
69
  }
69
70
 
70
- export function buildReleaseRunInput(version: string, deps: UnattendedReleaseDeps = {}): ReleaseRunInput {
71
+ export function buildReleaseRunInput(version: string, deps: UnattendedReleaseDeps = {}, cutCommit?: string): ReleaseRunInput {
71
72
  const config = deps.config ?? releaseLoopConfig(deps.configPath);
72
73
  const pool = config.gatePodPool;
73
74
  if (typeof pool !== 'string' || !pool.trim()) throw new Error('release.loop.gatePodPool is required before graph execution');
@@ -75,16 +76,17 @@ export function buildReleaseRunInput(version: string, deps: UnattendedReleaseDep
75
76
  return {
76
77
  ...config,
77
78
  version, previousVersion,
79
+ ...(cutCommit !== undefined ? { cutCommit } : {}),
78
80
  gatePodPool: pool.trim(),
79
81
  };
80
82
  }
81
83
 
82
84
  /** Fail closed at the entry boundary, before any graph node can change a release. */
83
85
  export async function runUnattendedRelease(
84
- opts: { version: string; dryRun?: boolean },
86
+ opts: { version: string; dryRun?: boolean; cutCommit?: string },
85
87
  deps: UnattendedReleaseDeps = {},
86
88
  ): Promise<{ input: ReleaseRunInput; dryRun: boolean; state?: GraphRunState }> {
87
- const input = buildReleaseRunInput(opts.version, deps);
89
+ const input = buildReleaseRunInput(opts.version, deps, opts.cutCommit);
88
90
  if (opts.dryRun) return { input, dryRun: true };
89
91
  const gate = (deps.checklist ?? checklistGate)(opts.version);
90
92
  if (!gate.ok) throw new Error(`release checklist blocked: ${[...gate.red, ...gate.undecided, ...gate.blocked].join(', ')}`);
@@ -7,7 +7,7 @@ import { emitNodeResult } from './node-verdict.js';
7
7
  import { debug } from '../../src/debug/log.js';
8
8
 
9
9
  type Kind = 'release' | 'dev-bump';
10
- type Output = { outcome: 'ok' | 'error'; kind: Kind | null; version: string | null; commit: string | null; pr: number | null; worktree?: string; error?: string };
10
+ type Output = { outcome: 'ok' | 'error'; kind: Kind | null; version: string | null; commit: string | null; pr: number | null; files?: string[]; worktree?: string; error?: string };
11
11
 
12
12
  export function nextDevVersion(version: string): string {
13
13
  const match = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.exec(version);
@@ -49,9 +49,9 @@ function fetchMain(repo: string): void {
49
49
  }
50
50
  }
51
51
 
52
- function versionAt(repo: string): string {
53
- const pkg = JSON.parse(git(repo, 'show', 'origin/main:package.json')) as { version?: unknown };
54
- if (typeof pkg.version !== 'string') throw new Error('origin/main package.json has no version');
52
+ function versionAt(repo: string, ref = 'origin/main'): string {
53
+ const pkg = JSON.parse(git(repo, 'show', `${ref}:package.json`)) as { version?: unknown };
54
+ if (typeof pkg.version !== 'string') throw new Error(`${ref} package.json has no version`);
55
55
  return pkg.version;
56
56
  }
57
57
 
@@ -64,13 +64,49 @@ function shippedNextMdLines(repo: string, cut: string | undefined): { lines: Set
64
64
  return { lines: new Set(shown.stdout.split('\n').map((line) => line.trim()).filter((line) => line.startsWith('- '))) };
65
65
  }
66
66
 
67
- function landing(repo: string, kind: Kind, releaseVersion: string, cut?: string): Output {
67
+ function landing(repo: string, kind: Kind, releaseVersion: string, cut?: string, cutCommit?: string): Output {
68
68
  const target = kind === 'release' ? releaseVersion : nextDevVersion(releaseVersion);
69
69
  const source = kind === 'release' ? `${releaseVersion}-dev.N` : releaseVersion;
70
70
  fetchMain(repo);
71
+ if (kind === 'release' && cutCommit !== undefined) {
72
+ if (!/^[0-9a-f]{7,40}$/i.test(cutCommit)) throw new Error(`invalid cut commit SHA: ${cutCommit}`);
73
+ const local = spawnSync('git', ['rev-parse', '--verify', `${cutCommit}^{commit}`], { cwd: repo, encoding: 'utf8' });
74
+ let chosen = local.status === 0 ? local.stdout.trim() : '';
75
+ const onMain = chosen ? spawnSync('git', ['merge-base', '--is-ancestor', chosen, 'origin/main'], { cwd: repo }) : null;
76
+ if (onMain && onMain.status !== 0 && onMain.status !== 1) throw new Error(`git merge-base failed: ${onMain.error || onMain.stderr || 'unknown'}`);
77
+ if (onMain?.status !== 0) {
78
+ const remote = git(repo, 'ls-remote', '--heads', 'origin', `refs/heads/release/${releaseVersion}`);
79
+ const branchTip = remote.split(/\s+/)[0];
80
+ if (!chosen && branchTip?.toLowerCase().startsWith(cutCommit.toLowerCase())) {
81
+ git(repo, 'fetch', 'origin', `refs/heads/release/${releaseVersion}`);
82
+ chosen = git(repo, 'rev-parse', '--verify', `${cutCommit}^{commit}`);
83
+ }
84
+ if (!chosen) chosen = git(repo, 'rev-parse', '--verify', `${cutCommit}^{commit}`);
85
+ if (branchTip !== chosen) {
86
+ throw new Error(`cut commit ${chosen} is neither an ancestor of origin/main nor the tip of release/${releaseVersion}`);
87
+ }
88
+ }
89
+ const current = versionAt(repo, chosen);
90
+ if (current !== target) throw new Error(`cut commit ${chosen} package.json version ${current} is not ${target}`);
91
+ debug.log('release-loop.cut', 'chosen', { version: releaseVersion, source: 'cut-commit', commit: chosen });
92
+ return { outcome: 'ok', kind, version: target, commit: chosen, pr: null };
93
+ }
71
94
  const current = versionAt(repo);
72
95
  const before = git(repo, 'rev-parse', 'origin/main');
73
- if (current === target) return { outcome: 'ok', kind, version: target, commit: before, pr: null };
96
+ if (current === target) {
97
+ if (kind === 'release') debug.log('release-loop.cut', 'chosen', { version: releaseVersion, source: 'main', commit: before });
98
+ return { outcome: 'ok', kind, version: target, commit: before, pr: null };
99
+ }
100
+ // An older chosen cut may finish after main has already advanced to the next stable release.
101
+ // Keep that newer main untouched; a -dev.N mismatch is not evidence of a later release.
102
+ if (kind === 'dev-bump' && /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.test(current)) {
103
+ const mainParts = current.split('.').map(BigInt);
104
+ const nextParts = target.slice(0, -'-dev.0'.length).split('.').map(BigInt);
105
+ const firstDifference = mainParts.findIndex((part, index) => part !== nextParts[index]);
106
+ if (firstDifference === -1 || mainParts[firstDifference]! > nextParts[firstDifference]!) {
107
+ return { outcome: 'ok', kind, version: current, commit: before, pr: null };
108
+ }
109
+ }
74
110
  if (kind === 'release' ? !new RegExp(`^${releaseVersion.replaceAll('.', '\\.')}\\-dev\\.(0|[1-9][0-9]*)$`).test(current) : current !== source) {
75
111
  throw new Error(`origin/main version ${current} is not ${source} (target ${target})`);
76
112
  }
@@ -84,6 +120,23 @@ function landing(repo: string, kind: Kind, releaseVersion: string, cut?: string)
84
120
  const old = `"version": "${current}"`;
85
121
  if (!text.includes(old)) throw new Error(`package.json version field not found: ${current}`);
86
122
  writeFileSync(path, text.replace(old, `"version": "${target}"`));
123
+ const files = ['package.json'];
124
+ const serverPath = join(worktree, 'server.json');
125
+ if (existsSync(serverPath)) {
126
+ const server = JSON.parse(readFileSync(serverPath, 'utf8')) as { version: string; packages: Array<{ version: string }> };
127
+ server.version = target;
128
+ server.packages[0]!.version = target;
129
+ writeFileSync(serverPath, `${JSON.stringify(server, null, 2)}\n`);
130
+ files.push('server.json');
131
+ }
132
+ const agentPath = join(worktree, 'integrations', 'acp-registry', 'elanous', 'agent.json');
133
+ if (existsSync(agentPath)) {
134
+ const agent = JSON.parse(readFileSync(agentPath, 'utf8')) as { version: string; distribution: { npx: { package: string } } };
135
+ agent.version = target;
136
+ agent.distribution.npx.package = `elanous@${target}`;
137
+ writeFileSync(agentPath, `${JSON.stringify(agent, null, 2)}\n`);
138
+ files.push('agent.json');
139
+ }
87
140
  const lockPath = join(worktree, 'bun.lock');
88
141
  const lock = readFileSync(lockPath, 'utf8');
89
142
  const root = /"workspaces"\s*:\s*\{\s*""\s*:\s*\{([\s\S]*?)(?=\s*"(?:dependencies|devDependencies|optionalDependencies)"\s*:)/.exec(lock);
@@ -142,7 +195,8 @@ function landing(repo: string, kind: Kind, releaseVersion: string, cut?: string)
142
195
  fetchMain(repo);
143
196
  const commit = git(repo, 'rev-parse', 'origin/main');
144
197
  if (versionAt(repo) !== target || commit === before) throw new Error(`origin/main did not advance to ${target} after merge`);
145
- const output: Output = { outcome: 'ok', kind, version: target, commit, pr: pr ? Number(pr[1]) : null };
198
+ const output: Output = { outcome: 'ok', kind, version: target, commit, pr: pr ? Number(pr[1]) : null, files };
199
+ if (kind === 'release') debug.log('release-loop.cut', 'chosen', { version: releaseVersion, source: 'main', commit });
146
200
  git(repo, 'worktree', 'remove', '--force', worktree);
147
201
  rmSync(temp, { recursive: true, force: true });
148
202
  return output;
@@ -156,27 +210,34 @@ function main(args: string[] = process.argv.slice(2), repo = process.cwd()): Out
156
210
  let kind: Kind | null = null;
157
211
  let version: string | null = null;
158
212
  let cut: string | undefined;
213
+ let cutCommit: string | undefined;
159
214
  try {
160
- if (args[0] !== 'release' && args[0] !== 'dev-bump') throw new Error('usage: version-node.ts <release|dev-bump> [--version <v>] [--cut <sha>] --json');
215
+ if (args[0] !== 'release' && args[0] !== 'dev-bump') throw new Error('usage: version-node.ts <release|dev-bump> [--version <v>] [--cut <sha>] [--cut-commit <sha>] --json');
161
216
  kind = args[0];
162
217
  for (let i = 1; i < args.length; i++) {
163
218
  if (args[i] === '--json') continue;
164
219
  if (args[i] === '--version' && args[i + 1]) { version = args[++i]!; continue; }
165
220
  if (args[i] === '--cut' && args[i + 1]) { cut = args[++i]!; continue; }
221
+ if (args[i] === '--cut-commit' && args[i + 1]) { cutCommit = args[++i]!; continue; }
166
222
  throw new Error(`unknown or incomplete argument: ${args[i]}`);
167
223
  }
168
224
  if (process.env.ELANOUS_GRAPH_CONTEXT) {
169
225
  const location = process.env.ELANOUS_GRAPH_CONTEXT;
170
226
  const context = JSON.parse(location.trimStart().startsWith('{') ? location : readFileSync(location, 'utf8')) as {
171
- input?: { version?: unknown }; outputs?: Record<string, { commit?: unknown } | undefined> };
227
+ input?: { version?: unknown; cutCommit?: unknown }; outputs?: Record<string, { commit?: unknown } | undefined> };
172
228
  if (!version && typeof context.input?.version === 'string') version = context.input.version;
229
+ if (kind === 'release' && cutCommit === undefined && context.input?.cutCommit !== undefined) {
230
+ if (typeof context.input.cutCommit !== 'string') throw new Error('cutCommit must be a commit SHA');
231
+ cutCommit = context.input.cutCommit;
232
+ }
173
233
  // The cut = the commit version-release landed (what cutoff and the gate measured).
174
- const cutCommit = context.outputs?.['version-release']?.commit;
175
- if (!cut && typeof cutCommit === 'string' && cutCommit) cut = cutCommit;
234
+ const releasedCommit = context.outputs?.['version-release']?.commit;
235
+ if (!cut && typeof releasedCommit === 'string' && releasedCommit) cut = releasedCommit;
176
236
  }
177
237
  if (!version) throw new Error('version required (--version or ELANOUS_GRAPH_CONTEXT.input.version)');
178
238
  nextDevVersion(version);
179
- return landing(resolve(repo), kind, version, cut);
239
+ if (kind === 'dev-bump' && cutCommit !== undefined) throw new Error('--cut-commit is only valid for release');
240
+ return landing(resolve(repo), kind, version, cut, cutCommit);
180
241
  } catch (error) {
181
242
  const message = error instanceof Error ? error.message : String(error);
182
243
  const worktree = /\[worktree: ([^\]]+)\]$/.exec(message)?.[1];
@@ -189,7 +250,7 @@ function main(args: string[] = process.argv.slice(2), repo = process.cwd()): Out
189
250
 
190
251
  if (import.meta.main) {
191
252
  const output = main();
192
- debug.log(`release-loop.version-${output.kind ?? 'unknown'}`, 'result', { version: output.version, outcome: output.outcome });
253
+ debug.log(`release-loop.version-${output.kind ?? 'unknown'}`, 'result', { version: output.version, outcome: output.outcome, files: output.files ?? [] });
193
254
  emitNodeResult({ ...output, verdict: output.outcome === 'ok' ? 'pass' : 'fail', summary: output.outcome === 'ok' ? `${output.kind} ${output.version} · ${output.commit}` : `${output.kind ?? 'version'}: ${output.error ?? 'failed'}` });
194
255
  if (output.outcome === 'error') process.exitCode = 1;
195
256
  }
@@ -13,8 +13,7 @@ import { appendFileSync } from 'node:fs';
13
13
  import { SignalPool } from '../src/domains/signal-pool.js';
14
14
  import { runDigest, runCommunityBuzzDigest } from '../src/domains/signal-router.js';
15
15
  import { sendOutbound } from '../src/domains/outbound-alert.js';
16
- import { sendReportPhotoBuffer } from '../src/telegram-report.js';
17
- import { getUserConfig } from '../src/user-config.js';
16
+ import { createDigestPhotoSender } from './signal-digest-photo.js';
18
17
  import { ensureCronNodePath } from '../src/domains/cron-path.js';
19
18
  import { unknownCronFlag } from '../src/domains/cron-flag-contract.js';
20
19
 
@@ -35,14 +34,10 @@ function log(msg: string): void {
35
34
  try { appendFileSync(LOG, line + '\n'); } catch { /* fail-soft */ }
36
35
  }
37
36
 
38
- async function sendDigestPhoto(png: Buffer, opts?: { caption?: string }): Promise<boolean> {
39
- return sendReportPhotoBuffer(getUserConfig(), png, opts);
40
- }
41
-
42
37
  async function main(): Promise<void> {
43
38
  const pool = new SignalPool();
44
39
  try {
45
- const d = await runDigest(pool, LIVE ? { send: sendOutbound, sendPhoto: sendDigestPhoto } : {});
40
+ const d = await runDigest(pool, LIVE ? { send: sendOutbound, sendPhoto: createDigestPhotoSender() } : {});
46
41
  log(`[${d.mode}] 다이제스트 대기 ${d.count} · 발송 ${d.sent}`);
47
42
  if (!LIVE && d.count > 0) {
48
43
  log(` ▶ [digest shadow]\n${d.preview}`);
@@ -0,0 +1,11 @@
1
+ import type { UserConfig } from '../src/user-config.js';
2
+ import { getUserConfig } from '../src/user-config.js';
3
+ import { sendReportPhotoBuffer } from '../src/telegram-report.js';
4
+
5
+ /** The callback passed to runDigest for trading signal images. */
6
+ export function createDigestPhotoSender(
7
+ config: () => UserConfig = getUserConfig,
8
+ sendPhoto: typeof sendReportPhotoBuffer = sendReportPhotoBuffer,
9
+ ): (png: Buffer, opts?: { caption?: string }) => Promise<boolean> {
10
+ return (png, opts) => sendPhoto(config(), png, { ...opts, kind: 'digest' });
11
+ }
@@ -0,0 +1,94 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { loadGraphTemplatesFrom, defaultGraphsDir } from '../src/self-implement/graph-templates.js';
3
+
4
+ // Public metrics for release/public/tech/tech1.json. Log metrics read the installed `elanous`
5
+ // (operational universe) over --since/--until; `--all` adds every registered instance incl. test.
6
+ const key = process.argv[2];
7
+ const flag = (name: string): string | undefined => {
8
+ const at = process.argv.indexOf(name);
9
+ return at < 0 ? undefined : process.argv[at + 1];
10
+ };
11
+ const PAGE = 100000;
12
+
13
+ type Row = { id?: number; category: string; event: string; data?: unknown };
14
+
15
+ function logRows(args: string[]): { rows: Row[]; limitReached: boolean } {
16
+ const proc = Bun.spawnSync(['elanous', 'logs', ...args, '--json', '--json-data'], { stdout: 'pipe', stderr: 'pipe', maxBuffer: 2 ** 31 } as Parameters<typeof Bun.spawnSync>[1]);
17
+ if (proc.exitCode !== 0) throw new Error(`elanous logs failed: ${new TextDecoder().decode(proc.stderr).slice(0, 300)}`);
18
+ const rows: Row[] = [];
19
+ let limitReached = false;
20
+ for (const line of new TextDecoder().decode(proc.stdout).split('\n')) {
21
+ if (!line) continue;
22
+ const row = JSON.parse(line) as Row & { _meta?: { type?: string; limitReached?: boolean } };
23
+ if (row._meta) { if (row._meta.type === 'log-query-limit' && row._meta.limitReached) limitReached = true; continue; }
24
+ rows.push(row);
25
+ }
26
+ return { rows, limitReached };
27
+ }
28
+
29
+ function window(): string[] {
30
+ const since = flag('--since');
31
+ const until = flag('--until');
32
+ if (!since || !until) throw new Error('--since <ISO> --until <ISO> required');
33
+ return ['--since', since, '--until', until];
34
+ }
35
+
36
+ /** One page across all instances; refuses a truncated page instead of reporting a short count. */
37
+ function unionCount(categories: string, events?: string): Map<string, number> {
38
+ const args = [...window(), '--all', '--include-test', '--limit', String(PAGE), '--category', categories, ...(events ? ['--event', events] : [])];
39
+ const { rows, limitReached } = logRows(args);
40
+ if (limitReached) throw new Error(`truncated at ${PAGE} rows — narrow --event`);
41
+ const counts = new Map<string, number>();
42
+ for (const row of rows) counts.set(`${row.category} ${row.event}`, (counts.get(`${row.category} ${row.event}`) ?? 0) + 1);
43
+ return counts;
44
+ }
45
+
46
+ const at = (counts: Map<string, number>, k: string): number => counts.get(k) ?? 0;
47
+
48
+ if (key === 'graph.templates') {
49
+ const result = loadGraphTemplatesFrom(defaultGraphsDir());
50
+ console.log(Object.keys(result.templates).length);
51
+ } else if (key === 'loop-agents.loops') {
52
+ const proc = Bun.spawnSync(['bun', 'bin/elanous.mjs', '--test', 'loop', 'list', '--json'], { stdout: 'pipe', stderr: 'pipe' });
53
+ if (proc.exitCode !== 0) throw new Error('loop catalog unavailable');
54
+ console.log(JSON.parse(new TextDecoder().decode(proc.stdout)).length);
55
+ } else if (key === 'harness.author-tags') {
56
+ const tags = [...readFileSync('src/self-implement/goal-author.ts', 'utf8').matchAll(/tag: '([a-z-]+)'/g)].map(match => match[1]);
57
+ console.log(new Set(tags).size);
58
+ } else if (key === 'observability.events') {
59
+ // Operational instance only; pages with --before so the 100k page cap does not cut the count.
60
+ let before: number | undefined;
61
+ let total = 0;
62
+ for (;;) {
63
+ const { rows } = logRows([...window(), '--limit', String(PAGE), ...(before === undefined ? [] : ['--before', String(before)])]);
64
+ total += rows.length;
65
+ if (rows.length < PAGE) break;
66
+ before = Math.min(...rows.map((row) => row.id ?? Number.POSITIVE_INFINITY));
67
+ }
68
+ console.log(total);
69
+ } else if (key === 'stages.author') {
70
+ const c = unionCount('harness.author', 'goal-id-assigned');
71
+ console.log(JSON.stringify({ auto: at(c, 'harness.author goal-id-assigned') }));
72
+ } else if (key === 'stages.clarify') {
73
+ const c = unionCount('hitl.execution,harness.author.clarify', 'auto-recommended,assumed,asked,self-answered,unresolved');
74
+ console.log(JSON.stringify({
75
+ auto: at(c, 'hitl.execution auto-recommended') + at(c, 'hitl.execution assumed') + at(c, 'harness.author.clarify self-answered'),
76
+ human: at(c, 'hitl.execution asked'),
77
+ unknown: at(c, 'harness.author.clarify unresolved'),
78
+ }));
79
+ } else if (key === 'stages.ledger') {
80
+ const { rows, limitReached } = logRows([...window(), '--all', '--include-test', '--limit', String(PAGE), '--category', 'self-implement.pod', '--event', 'ledger-live-appended']);
81
+ if (limitReached) throw new Error(`truncated at ${PAGE} rows`);
82
+ const runs = new Set(rows.map((row) => (row.data as { runId?: string } | undefined)?.runId).filter(Boolean));
83
+ console.log(JSON.stringify({ auto: runs.size, appends: rows.length }));
84
+ } else if (key === 'stages.heal') {
85
+ const c = unionCount('self-dev.rework,self-dev.hitl', 'repeat-count,escalation');
86
+ console.log(JSON.stringify({ auto: at(c, 'self-dev.rework repeat-count'), human: at(c, 'self-dev.hitl escalation') }));
87
+ } else if (key === 'pty.missions') {
88
+ // External coding agents driven through an inner PTY (agent-mission) — distinct missions with any row in the window.
89
+ const { rows, limitReached } = logRows([...window(), '--all', '--include-test', '--limit', String(PAGE), '--category', 'agent-mission']);
90
+ if (limitReached) throw new Error(`truncated at ${PAGE} rows`);
91
+ console.log(new Set(rows.map((row) => (row.data as { missionId?: string } | undefined)?.missionId).filter(Boolean)).size);
92
+ } else {
93
+ throw new Error(`Unknown public metric: ${key ?? '(missing)'}`);
94
+ }
@@ -16,6 +16,7 @@
16
16
  import { TelegramClient, Api } from 'telegram';
17
17
  import { StringSession } from 'telegram/sessions';
18
18
  import { createInterface } from 'node:readline/promises';
19
+ import { parseInjectArgs } from './lib/telegram-inject-args.js';
19
20
 
20
21
  const args = process.argv.slice(2);
21
22
  const has = (f: string): boolean => args.includes(f);
@@ -201,15 +202,22 @@ if (has('--buttons') || has('--click') || has('--react')) {
201
202
 
202
203
  // 무인 주입: SESSION STRING 으로 로그인 → 봇에게 메시지.
203
204
  const sessionStr = process.env.TELEGRAM_USER_SESSION ?? val('--session');
204
- const to = val('--to') ?? process.env.TELEGRAM_TEST_BOT ?? configBot;
205
- const text = val('--text');
206
205
  if (!sessionStr) { console.error('❌ TELEGRAM_USER_SESSION 필요 — 먼저 `--login` 으로 발급.'); process.exit(2); }
207
- if (!to || !text) { console.error('사용: telegram-inject.ts --to @monad_test_bot --text "<objective>"'); process.exit(2); }
208
-
206
+ let inject: ReturnType<typeof parseInjectArgs>;
207
+ try {
208
+ inject = parseInjectArgs(args, { TELEGRAM_TEST_BOT: process.env.TELEGRAM_TEST_BOT ?? configBot });
209
+ } catch (error) {
210
+ console.error((error as Error).message);
211
+ process.exit(2);
212
+ }
213
+ const { to, text, photos, caption } = inject;
209
214
  const client = new TelegramClient(new StringSession(sessionStr), apiId, apiHash, { connectionRetries: 5 });
210
215
  await client.connect();
211
- const msg = await client.sendMessage(to, { message: text });
212
- console.log(`✅ 주입 완료 → ${to} (msgId=${(msg as { id?: number }).id ?? '?'}). 이 계정의 텔레그램 앱에도 대화가 보입니다.`);
216
+ const msg = photos.length > 0
217
+ ? await client.sendFile(to, { file: photos.length === 1 ? photos[0]! : photos, caption })
218
+ : await client.sendMessage(to, { message: text! });
219
+ const sent = Array.isArray(msg) ? msg[0] : msg;
220
+ console.log(`✅ 주입 완료 → ${to} (msgId=${(sent as { id?: number } | undefined)?.id ?? '?'}). 이 계정의 텔레그램 앱에도 대화가 보입니다.`);
213
221
  console.log(' → 데몬 처리 후 watchdog 검증: log/watchdog-stall.log (stall 없으면 A subprocess 격리 정상).');
214
222
  await client.disconnect();
215
223
  process.exit(0);
@@ -54,7 +54,7 @@ function measure(ctx: Context, audit = false): number {
54
54
  'while IFS= read -r f; do',
55
55
  ' [ -n "$f" ] || continue',
56
56
  ' s=$(date +%s)',
57
- ' if [ -n "$TO" ]; then /usr/bin/time -l "$TO" -k 10 300 bun run scripts/test-deterministic.ts "./$f" > "$T/out" 2> "$T/err"; else /usr/bin/time -l bun run scripts/test-deterministic.ts "./$f" > "$T/out" 2> "$T/err"; fi',
57
+ ` if [ -n "$TO" ]; then /usr/bin/time -l "$TO" -k 10 300 ${audit ? 'env ELANOUS_NIGHTLY_AUDIT=1 ' : ''}bun run scripts/test-deterministic.ts "./$f" > "$T/out" 2> "$T/err"; else /usr/bin/time -l ${audit ? 'env ELANOUS_NIGHTLY_AUDIT=1 ' : ''}bun run scripts/test-deterministic.ts "./$f" > "$T/out" 2> "$T/err"; fi`,
58
58
  ' rc=$?; e=$(( $(date +%s) - s ))',
59
59
  ' rss=$(awk \'/maximum resident set size/ {printf "%d", $1/1048576}\' "$T/err")',
60
60
  // bun test prints its summary on stderr — read both streams.
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env bun
2
+ import { spawn } from 'node:child_process';
3
+ import { readFileSync } from 'node:fs';
4
+ import { release } from 'node:os';
5
+
6
+ export const FILE_TIMEOUT_MS = 300_000;
7
+ export type Execution = { rc: number | null; stdout: string; stderr: string; secs: number; timedOut: boolean };
8
+ export type Executor = (file: string, timeoutMs: number) => Promise<Execution>;
9
+ export type Measurement = {
10
+ file: string; rc: number | null; pass: number | null; fail: number | null; skip: number | null;
11
+ secs: number; platform: string; release: string; verdict: 'pass' | 'fail' | 'skip' | '못 잼';
12
+ };
13
+
14
+ export const TIMEOUT_EXIT_GRACE_MS = 5_000;
15
+
16
+ // The wrapper handles SIGTERM by stopping its detached test group. Do not
17
+ // start another file until the wrapper closes, even after SIGKILL.
18
+ export function execute(
19
+ file: string,
20
+ timeoutMs: number,
21
+ deps: {
22
+ spawnChild?: typeof spawn;
23
+ signalGroup?: (pid: number, signal: NodeJS.Signals) => void;
24
+ graceMs?: number;
25
+ } = {},
26
+ ): Promise<Execution> {
27
+ return new Promise((resolve, reject) => {
28
+ const started = performance.now();
29
+ const child = (deps.spawnChild ?? spawn)('bun', ['run', 'test:deterministic', file], { detached: true, stdio: ['ignore', 'pipe', 'pipe'] });
30
+ let stdout = '';
31
+ let stderr = '';
32
+ let timedOut = false;
33
+ let closed = false;
34
+ let escalation: ReturnType<typeof setTimeout> | undefined;
35
+ let terminationCheck: ReturnType<typeof setTimeout> | undefined;
36
+ const seconds = () => Math.round((performance.now() - started) / 1000 * 100) / 100;
37
+ const signal = (name: NodeJS.Signals) => {
38
+ if (child.pid === undefined) return;
39
+ try { (deps.signalGroup ?? ((pid, sig) => process.kill(-pid, sig)))(child.pid, name); }
40
+ catch (groupError) {
41
+ try { child.kill(name); }
42
+ catch (directError) { stderr += `\n${name} failed: ${String(groupError)}; ${String(directError)}`; }
43
+ }
44
+ };
45
+ // Bun's summary is at the end; bounded capture avoids an unbounded memory cost.
46
+ const collect = (previous: string, chunk: Buffer) => (previous + chunk.toString('utf8')).slice(-256_000);
47
+ child.stdout.on('data', (chunk: Buffer) => { stdout = collect(stdout, chunk); });
48
+ child.stderr.on('data', (chunk: Buffer) => { stderr = collect(stderr, chunk); });
49
+ const graceMs = deps.graceMs ?? TIMEOUT_EXIT_GRACE_MS;
50
+ const timer = setTimeout(() => {
51
+ timedOut = true;
52
+ signal('SIGTERM');
53
+ escalation = setTimeout(() => {
54
+ if (closed) return;
55
+ signal('SIGKILL');
56
+ terminationCheck = setTimeout(() => {
57
+ if (!closed) reject(new Error(`Cannot confirm termination of timed-out test: ${file}; stopping measurements`));
58
+ }, graceMs);
59
+ }, graceMs);
60
+ }, timeoutMs);
61
+ child.on('error', (error) => { stderr += `\n${error.message}`; });
62
+ child.on('close', (code) => {
63
+ closed = true;
64
+ clearTimeout(timer);
65
+ if (escalation) clearTimeout(escalation);
66
+ if (terminationCheck) clearTimeout(terminationCheck);
67
+ resolve({ rc: timedOut ? null : code, stdout, stderr, secs: seconds(), timedOut });
68
+ });
69
+ });
70
+ }
71
+
72
+ export async function measureList(files: readonly string[], runner: Executor = execute): Promise<Measurement[]> {
73
+ const measurements: Measurement[] = [];
74
+ for (const file of files) {
75
+ const result = await runner(file, FILE_TIMEOUT_MS);
76
+ const output = `${result.stdout}\n${result.stderr}`;
77
+ const count = (kind: 'pass' | 'fail' | 'skip'): number | null => {
78
+ const matches = [...output.matchAll(new RegExp(`^\\s*(\\d+) ${kind}\\b`, 'gm'))];
79
+ return matches.length ? Number(matches.at(-1)![1]) : null;
80
+ };
81
+ const pass = result.timedOut ? null : count('pass');
82
+ const fail = result.timedOut ? null : count('fail');
83
+ const skip = result.timedOut ? null : count('skip');
84
+ const measured = pass !== null || fail !== null || skip !== null;
85
+ const verdict = result.timedOut || !measured || result.rc === null ? '못 잼'
86
+ : fail !== null && fail > 0 ? 'fail'
87
+ : result.rc !== 0 ? '못 잼'
88
+ : skip !== null && skip > 0 ? 'skip'
89
+ : pass !== null && pass > 0 ? 'pass' : '못 잼';
90
+ measurements.push({ file, rc: result.rc, pass, fail, skip, secs: result.secs, platform: process.platform, release: release(), verdict });
91
+ }
92
+ return measurements;
93
+ }
94
+
95
+ if (import.meta.main) {
96
+ const args = process.argv.slice(2);
97
+ if (args.length < 1 || args.length > 2 || (args.length === 2 && args[1] !== '--json')) {
98
+ console.error('usage: bun scripts/test-diet/remeasure-list.ts <목록 파일> [--json]');
99
+ process.exitCode = 2;
100
+ } else {
101
+ try {
102
+ const files = readFileSync(args[0]!, 'utf8').split(/\r?\n/).map((line) => line.trim()).filter((line) => line && !line.startsWith('#'));
103
+ if (!files.length) throw new Error('empty test list');
104
+ const results = await measureList(files);
105
+ if (args[1] === '--json') console.log(JSON.stringify(results, null, 2));
106
+ else for (const row of results) console.log([row.file, row.rc ?? 'null', row.pass ?? '?', row.fail ?? '?', row.skip ?? '?', row.secs, row.platform, row.release, row.verdict].join('\t'));
107
+ } catch (error) {
108
+ console.error(error);
109
+ process.exitCode = 2;
110
+ }
111
+ }
112
+ }
@@ -42,7 +42,7 @@ async function runCheck(check: TuiCheck): Promise<Verdict> {
42
42
  else snaps[step.as] = await handle.renderScreen();
43
43
  }
44
44
  // TUI_REGRESS_DUMP=<id> prints that check's screens (to see why a verdict failed).
45
- if (process.env.TUI_REGRESS_DUMP === check.id) for (const [k, v] of Object.entries(snaps)) console.log(`--- ${check.id}:${k}\n${v.split('\n').filter((l) => l.trim()).join('\n')}`);
45
+ if (!json && process.env.TUI_REGRESS_DUMP === check.id) for (const [k, v] of Object.entries(snaps)) console.log(`--- ${check.id}:${k}\n${v.split('\n').filter((l) => l.trim()).join('\n')}`);
46
46
  return check.judge(snaps);
47
47
  } catch (error) {
48
48
  return { ok: false, reason: `실행 오류: ${String(error).slice(0, 120)}` };
@@ -67,5 +67,5 @@ for (const check of checks) {
67
67
  }
68
68
  const fail = results.filter((r) => !r.ok).length;
69
69
  if (json) console.log(JSON.stringify({ results, pass: results.length - fail, fail }));
70
- console.log(`tui-regress: pass ${results.length - fail} · fail ${fail}`);
70
+ else console.log(`tui-regress: pass ${results.length - fail} · fail ${fail}`);
71
71
  process.exit(fail ? 1 : 0);