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
@@ -1,7 +1,6 @@
1
1
  import { debug } from '../debug/log.js';
2
- import type { ModelRole } from '../user-config.js';
3
- import type { ResolveRoleProviderFn, StreamLlmFn, ProviderRegistry } from './runtime-callables.js';
4
- import { extractJsonBlock } from './decompose.js';
2
+ import type { ResolveRoleProviderFn, StreamLlmFn } from './runtime-callables.js';
3
+ import { judge } from '../llm/judge-layer.js';
5
4
  import {
6
5
  INTAKE_FRONT_ROUTE_TRACKS,
7
6
  type IntakeFrontRouteDecision,
@@ -14,17 +13,6 @@ interface ClassifierDeps {
14
13
  minConfidence?: number;
15
14
  }
16
15
 
17
- function loadRoleProvider(): ResolveRoleProviderFn {
18
- const { resolveRoleLlm } = require('../user-config.js') as {
19
- resolveRoleLlm: (role: ModelRole) => { provider: string; model: string };
20
- };
21
- const { PROVIDERS } = require('../llm.js') as { PROVIDERS: ProviderRegistry };
22
- return (role) => {
23
- const resolved = resolveRoleLlm(role);
24
- return { provider: PROVIDERS[resolved.provider] ?? { name: resolved.provider }, model: resolved.model };
25
- };
26
- }
27
-
28
16
  /** Classify only after the deterministic front-route rules return rule-unknown. */
29
17
  export async function classifyIntakeFrontRoute(
30
18
  text: string,
@@ -43,32 +31,38 @@ export async function classifyIntakeFrontRoute(
43
31
  const failed = (cause: string) => finish('ask-human', 0, `classifier-failed:${cause}`, 'failed');
44
32
 
45
33
  try {
46
- const rolePick = (deps.resolveRoleProvider ?? loadRoleProvider())('classify');
47
- provider = rolePick.provider.name;
48
- const streamLLM = deps.streamLLM ?? (require('../llm.js') as { streamLLM: StreamLlmFn }).streamLLM;
49
- const response = await streamLLM([
50
- { role: 'system', content: [
51
- 'Classify the intake text into exactly one track:',
52
- 'absorb: read, save, or summarize external material.',
53
- 'tasks: a list of independent to-dos.',
54
- 'graph: an implementation or multi-step workflow request.',
55
- 'ask-human: ambiguous intent requiring human choice.',
56
- 'Return only one JSON object: {"track":"...","confidence":0.0,"reason":"..."}. Confidence must be between 0 and 1.',
57
- ].join('\n') },
58
- { role: 'user', content: text },
59
- ], () => {}, { provider: rolePick.provider, ...(rolePick.model ? { model: rolePick.model } : {}), usageRole: 'classify' });
60
-
61
- // 실제 모델은 JSON 을 ```json 펜스로 감싸거나 앞뒤에 말을 붙이곤 한다 — 같은 디렉토리의 다른 호출자와 같은 관대한 추출을 쓴다.
62
- const parsed: unknown = extractJsonBlock(response);
63
- if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) return failed('invalid-json');
64
- const candidate = parsed as Record<string, unknown>;
65
- if (typeof candidate.track !== 'string' ||
66
- !(INTAKE_FRONT_ROUTE_TRACKS as readonly string[]).includes(candidate.track)) return failed('invalid-track');
67
- if (typeof candidate.confidence !== 'number' || !Number.isFinite(candidate.confidence) ||
68
- candidate.confidence < 0 || candidate.confidence > 1) return failed('invalid-confidence');
69
- if (typeof candidate.reason !== 'string') return failed('invalid-reason');
34
+ const decision = await judge({
35
+ site: 'intake.front-route',
36
+ prompt: text,
37
+ messages: [
38
+ { role: 'system', content: [
39
+ 'Classify the intake text into exactly one track:',
40
+ 'absorb: read, save, or summarize external material.',
41
+ 'tasks: a list of independent to-dos.',
42
+ 'graph: an implementation or multi-step workflow request.',
43
+ 'ask-human: ambiguous intent requiring human choice.',
44
+ 'Return only one JSON object: {"track":"...","confidence":0.0,"reason":"..."}. Confidence must be between 0 and 1.',
45
+ ].join('\n') },
46
+ { role: 'user', content: text },
47
+ ],
48
+ streamLLM: deps.streamLLM,
49
+ resolveRoleProvider: deps.resolveRoleProvider,
50
+ schema: (parsed) => {
51
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) return null;
52
+ const candidate = parsed as Record<string, unknown>;
53
+ if (typeof candidate.track !== 'string' ||
54
+ !(INTAKE_FRONT_ROUTE_TRACKS as readonly string[]).includes(candidate.track)) return null;
55
+ if (typeof candidate.confidence !== 'number' || !Number.isFinite(candidate.confidence) ||
56
+ candidate.confidence < 0 || candidate.confidence > 1) return null;
57
+ if (typeof candidate.reason !== 'string') return null;
58
+ return { track: candidate.track as IntakeFrontRouteTrack, confidence: candidate.confidence, reason: candidate.reason };
59
+ },
60
+ });
61
+ provider = decision.ok ? decision.provider : provider;
62
+ if (!decision.ok) return failed(decision.reason === 'schema' ? 'invalid-json' : 'llm-error');
63
+ const candidate = decision.value;
70
64
 
71
- const track = candidate.track as IntakeFrontRouteTrack;
65
+ const track = candidate.track;
72
66
  const confidence = candidate.confidence;
73
67
  if (confidence < (deps.minConfidence ?? 0.6)) {
74
68
  return finish('ask-human', confidence, `classifier-low-confidence:${track}`, 'low-confidence');
@@ -0,0 +1,30 @@
1
+ import { debug } from '../debug/log.js';
2
+ import { resolveMention, type PersonaSource } from '../persona/mention-parser.js';
3
+ import type { PersonaProfile } from '../persona/types.js';
4
+
5
+ export interface PersonaAnswerDeps {
6
+ complete?: (prompt: string) => Promise<string>;
7
+ }
8
+
9
+ /** Resolve the registry mention first, then an exact display name. */
10
+ export function resolvePersonaAddress(name: string, source: PersonaSource): PersonaProfile | null {
11
+ const mention = resolveMention(name, source);
12
+ if (mention) return mention;
13
+ const needle = name.replace(/^@/, '').toLocaleLowerCase();
14
+ return source.list().find((persona) => persona.displayName.toLocaleLowerCase() === needle) ?? null;
15
+ }
16
+
17
+ async function defaultComplete(prompt: string): Promise<string> {
18
+ const { streamLLM } = await import('../llm.js');
19
+ const { tierModel } = await import('../llm/model-defaults.js');
20
+ return streamLLM([{ role: 'user', content: prompt }], () => {}, { model: tierModel('better') });
21
+ }
22
+
23
+ export async function answerAsPersona(persona: PersonaProfile, question: string, deps: PersonaAnswerDeps = {}): Promise<string> {
24
+ const prompt = `${persona.systemPrompt ?? `너는 ${persona.displayName} 이다`}\n\n## 질문\n${question}`;
25
+ const raw = await (deps.complete ?? defaultComplete)(prompt);
26
+ const answer = `@${persona.displayName}\n${raw.trim()}`;
27
+ const text = Array.from(answer).slice(0, 3_500).join('');
28
+ debug.log('persona.address', 'answered', { personaId: persona.personaId, chars: Array.from(text).length });
29
+ return text;
30
+ }
@@ -305,7 +305,14 @@ export function buildRealIntakeCallables(
305
305
  };
306
306
 
307
307
  const decompose: DecomposeMemoCallable = (args) => promptCallable(args);
308
- const categorize: CategorizeCallable = (args) => promptCallable(args);
308
+ const categorize: CategorizeCallable = async (args) => {
309
+ const text = await streamLLM([{ role: 'user', content: args.prompt }], () => {}, {
310
+ ...(args.provider ? { provider: providers[args.provider] } : {}),
311
+ ...(args.model ? { model: args.model } : {}),
312
+ ...(args.signal ? { signal: args.signal } : {}), usageRole: 'classify',
313
+ });
314
+ return { text, modelId: args.model };
315
+ };
309
316
  const align: AlignCallable = (args) => promptCallable(args);
310
317
 
311
318
  /** Synth callable — wraps R3 `synthWorkflowFromIntent`. Hands it a
@@ -1,11 +1,15 @@
1
1
  import { debug } from '../debug/log.js';
2
2
  import { telegramDecisionOwner } from '../decisions/telegram-decision-cards.js';
3
3
  import { canonicalSeatId } from '../msg/msg-store.js';
4
+ import { awaitGlobalPersonaLoad, getGlobalPersonaRegistry } from '../persona/global-registry.js';
5
+ import type { PersonaSource } from '../persona/mention-parser.js';
4
6
  import { dispatchCeoTask, type CeoCommandDeps } from '../seat-dispatch/ceo-commands.js';
5
7
  import { ceoTaskDeps, classifyCeoIntent } from '../seat-dispatch/ceo-intent.js';
8
+ import { askSeat, parseSeatAsk, type SeatAskDeps } from '../seat-dispatch/seat-ask.js';
6
9
  import { parseSeatAddress, resolveSeat } from '../seat-address/seat-address.js';
7
10
  import { getUserConfig, type UserConfig } from '../user-config.js';
8
11
  import { answerAsSeat } from './seat-answer.js';
12
+ import { answerAsPersona, resolvePersonaAddress, type PersonaAnswerDeps } from './persona-answer.js';
9
13
  import {
10
14
  submitIntakeWork,
11
15
  type SubmitIntakeWorkDeps,
@@ -16,8 +20,12 @@ export interface TelegramSeatWorkDeps extends SubmitIntakeWorkDeps {
16
20
  submit?: typeof submitIntakeWork;
17
21
  config?: UserConfig;
18
22
  answer?: typeof answerAsSeat;
23
+ personaSource?: PersonaSource;
24
+ personaAnswer?: typeof answerAsPersona;
25
+ personaAnswerDeps?: PersonaAnswerDeps;
19
26
  dispatch?: typeof dispatchCeoTask;
20
27
  commandDeps?: CeoCommandDeps;
28
+ askDeps?: SeatAskDeps;
21
29
  }
22
30
 
23
31
  /** Addressed work preserves graph intake except for one owner's private seat request. */
@@ -38,6 +46,14 @@ export async function handleTelegramSeatWork(
38
46
  return result.reply;
39
47
  };
40
48
  if (!text.startsWith('@')) {
49
+ if (parseSeatAsk(text)) {
50
+ const auth = owner();
51
+ if (!auth) return null;
52
+ if (!deps.askDeps) throw new Error('seat ask delivery unavailable');
53
+ return askSeat(text, { channel: 'telegram', chatId: msg.chatId, messageId: msg.messageId,
54
+ ...(msg.threadId ? { threadId: msg.threadId } : {}), ...(msg.botId ? { botId: msg.botId } : {}) },
55
+ deps.commandDeps ?? ceoTaskDeps(auth.cfg, auth.id), deps.askDeps);
56
+ }
41
57
  if (!text.trim() || /^\s*[/@@]/.test(text)) return null;
42
58
  const auth = owner();
43
59
  const configured = (auth?.cfg.raw?.seatDispatch as { defaultSeat?: unknown } | undefined)?.defaultSeat;
@@ -47,23 +63,41 @@ export async function handleTelegramSeatWork(
47
63
  const id = canonicalSeatId(seat.id);
48
64
  return ['OP', 'TC', 'MK', 'UX'].includes(id) ? sendTask(id, text, auth!.cfg, auth!.id) : null;
49
65
  }
50
- const address = parseSeatAddress(text);
66
+ const address = parseSeatAddress(text.replace(/^(@[A-Za-z][A-Za-z0-9_-]*(?:,@?[A-Za-z][A-Za-z0-9_-]*)*)/, (prefix) => prefix.replaceAll(',@', ',')));
51
67
  if (!address) return null;
52
68
 
53
69
  const seats = address.seats.map((name) => ({ name, seat: resolveSeat(name) }));
54
70
  const names = address.seats;
55
71
  debug.log('seat-address.telegram', 'parsed', { seats: names });
56
- const unknown = seats.filter(({ seat }) => !seat).map(({ name }) => `@${name}`);
72
+ const hasUnresolved = seats.some(({ seat }) => !seat);
73
+ const auth = hasUnresolved ? owner() : null;
74
+ if (hasUnresolved && auth && !deps.personaSource) await awaitGlobalPersonaLoad();
75
+ const source = hasUnresolved && auth ? (deps.personaSource ?? getGlobalPersonaRegistry()) : null;
76
+ const addressed = seats.map(({ name, seat }) => ({
77
+ name, seat, persona: !seat && source ? resolvePersonaAddress(name, source) : null,
78
+ }));
79
+ const unknown = addressed.filter(({ seat, persona }) => !seat && (!persona || !auth)).map(({ name }) => `@${name}`);
57
80
  if (unknown.length) {
58
81
  debug.log('seat-address.telegram', 'rejected', { seats: names, reason: 'unknown-seat' });
59
82
  return `어느 좌석을 말씀하시나요? ${unknown.join(', ')}은(는) 등록된 좌석이 아닙니다. 좌석을 확인해 다시 보내 주세요.`;
60
83
  }
84
+ const personas = addressed.filter(({ persona }) => persona);
85
+ if (personas.length && addressed.length !== 1) {
86
+ debug.log('persona.address', 'rejected', { reason: 'mixed' });
87
+ return '페르소나는 한 번에 하나만 부를 수 있습니다';
88
+ }
61
89
  const body = address.body.trim();
62
90
  if (!body) {
63
91
  debug.log('seat-address.telegram', 'rejected', { seats: names, reason: 'empty-body' });
64
92
  return '어떤 일을 맡길까요? 좌석 주소 뒤에 요청 내용을 적어 다시 보내 주세요.';
65
93
  }
66
94
 
95
+ if (personas.length === 1 && personas[0]?.persona) {
96
+ const { name, persona } = personas[0];
97
+ debug.log('persona.address', 'resolved', { name, personaId: persona.personaId });
98
+ return (deps.personaAnswer ?? answerAsPersona)(persona, body, deps.personaAnswerDeps);
99
+ }
100
+
67
101
  if (seats.length === 1 && seats[0]?.seat) {
68
102
  const auth = owner();
69
103
  const seatId = canonicalSeatId(seats[0].seat.id);
@@ -0,0 +1,33 @@
1
+ import { debug } from '../debug/log.js';
2
+ import { CardStore } from '../task-cards/card-store.js';
3
+
4
+ export function createWishCard(
5
+ { text, source, ref }: { text: string; source: 'telegram' | 'pwa' | 'tui'; ref: string },
6
+ store: CardStore = new CardStore(),
7
+ ): { cardId: string; title: string; created: boolean } {
8
+ const title = text.trim().split(/\r?\n/, 1)[0]!.trim().slice(0, 80);
9
+ if (!title) throw new Error('소원 글을 입력하세요');
10
+ if (!ref?.trim()) throw new Error('소원 참조가 필요합니다');
11
+ const goalId = `wish:${source}:${ref}`;
12
+ const old = store.listCards().find(card => card.goalId === goalId);
13
+ const card = old ?? store.createCard({ goalId, title });
14
+ const hasIntakeSection = card.sections.some(section => section.key === 'intake:wish:0');
15
+ const created = !old && !hasIntakeSection;
16
+ // A prior attempt may have created the card but stopped before writing its intake section. The card's first
17
+ // title wins: a retry with the same ref but a different request must not put a contradicting body on it
18
+ // (review must-fix) — keep the first title and record only that the retried text did not match.
19
+ if (!hasIntakeSection) {
20
+ const sameRequest = !old || title === card.title;
21
+ store.appendSection(card.id, {
22
+ key: 'intake:wish:0',
23
+ owner: 'steward',
24
+ content: JSON.stringify({
25
+ source, ref, title: card.title, text: sameRequest ? text : null, at: new Date().toISOString(),
26
+ ...(old ? { recovered: true } : {}), ...(sameRequest ? {} : { mismatch: true }),
27
+ }),
28
+ });
29
+ if (!sameRequest) debug.log('intake.wish', 'recovered-mismatch', { source, cardId: card.id });
30
+ }
31
+ debug.log('intake.wish', created ? 'created' : 'duplicate', { source, cardId: card.id });
32
+ return { cardId: card.id, title: card.title, created };
33
+ }
@@ -0,0 +1,67 @@
1
+ import { readdirSync, readFileSync, statSync, type Dirent } from 'node:fs';
2
+ import { basename, join, relative } from 'node:path';
3
+ import { CardStore } from '../task-cards/card-store.js';
4
+
5
+ export interface WishScanResult {
6
+ added: number;
7
+ updated: number;
8
+ skipped: number;
9
+ }
10
+
11
+ /** Import markdown notes without writing to the Wish folder. The card event log retains intake revisions. */
12
+ export function scanWishFolder({ dir, store }: { dir: string; store: CardStore }): WishScanResult {
13
+ let rootEntries: Dirent[];
14
+ try {
15
+ if (!statSync(dir).isDirectory()) throw new Error('not a directory');
16
+ rootEntries = readdirSync(dir, { withFileTypes: true });
17
+ } catch (error) {
18
+ if (error instanceof Error && (error.message === 'not a directory' ||
19
+ ('code' in error && (error.code === 'ENOENT' || error.code === 'ENOTDIR')))) {
20
+ throw new Error(`Wish 폴더를 찾지 못했습니다: ${dir}`);
21
+ }
22
+ throw error;
23
+ }
24
+
25
+ const paths: string[] = [];
26
+ const collect = (entries: typeof rootEntries, base: string) => {
27
+ for (const entry of entries) {
28
+ if (entry.name.startsWith('.')) continue;
29
+ const path = join(base, entry.name);
30
+ if (entry.isFile() && entry.name.endsWith('.md') && entry.name !== 'README.md') paths.push(path);
31
+ }
32
+ };
33
+ collect(rootEntries, dir);
34
+ for (const entry of rootEntries) {
35
+ if (entry.isDirectory() && !entry.name.startsWith('.')) {
36
+ const subdir = join(dir, entry.name);
37
+ collect(readdirSync(subdir, { withFileTypes: true }), subdir);
38
+ }
39
+ }
40
+ paths.sort();
41
+
42
+ const cards = new Map(store.listCards().map(card => [card.goalId, card]));
43
+ const result: WishScanResult = { added: 0, updated: 0, skipped: 0 };
44
+ for (const path of paths) {
45
+ const relPath = relative(dir, path).split('\\').join('/');
46
+ const goalId = `wish:${relPath}`;
47
+ const mtime = statSync(path).mtimeMs;
48
+ const old = cards.get(goalId);
49
+ const intakeSections = old?.sections.filter(section => section.key.startsWith('intake:wish:')) ?? [];
50
+ const lastIntake = intakeSections.at(-1);
51
+ if (lastIntake && JSON.parse(lastIntake.content).mtime === mtime) {
52
+ result.skipped++;
53
+ continue;
54
+ }
55
+ const title = /^# (.+)$/m.exec(readFileSync(path, 'utf8'))?.[1]?.trim() || basename(path, '.md');
56
+ const card = old ?? store.createCard({ goalId, title });
57
+ const intake = { source: 'wish', path: relPath, mtime, title };
58
+ store.appendSection(card.id, {
59
+ key: `intake:wish:${intakeSections.length}`,
60
+ owner: 'steward',
61
+ content: JSON.stringify(intake),
62
+ });
63
+ if (old) result.updated++;
64
+ else result.added++;
65
+ }
66
+ return result;
67
+ }
@@ -21,8 +21,10 @@
21
21
 
22
22
  import { TaskStore } from '../task-orchestrator/store.js';
23
23
  import { createMission, listMissions, normalizeMissionSource, generateMissionSlug, type MissionSource } from '../autopilot/mission-registry.js';
24
- import { triageGoal, defaultTriageClassify, type TriageCallable } from '../autopilot/triage.js';
25
- import { resolveDomain, defaultDomainClassify, type DomainClassify } from '../autopilot/domain/resolve.js';
24
+ import { triageGoal, isExecutionModel, type TriageCallable } from '../autopilot/triage.js';
25
+ import { resolveDomain, buildDomainPrompt, type DomainClassify } from '../autopilot/domain/resolve.js';
26
+ import { judge } from '../llm/judge-layer.js';
27
+ import type { ResolveRoleProviderFn, StreamLlmFn } from '../intake-plane/runtime-callables.js';
26
28
  import { isDomain } from '../autopilot/domain/types.js';
27
29
  import { autoDecomposeMission, shouldPhaseDecompose } from '../autopilot/mission-engine.js';
28
30
  import { saveMissionOrigin, type MissionOrigin } from '../autopilot/mission-origin.js';
@@ -54,12 +56,14 @@ export interface SubmitIntentInput {
54
56
  origin?: MissionOrigin;
55
57
  /** id title 생성 seam(테스트 격리·luna 우회). 없으면 generateMissionSlug(luna) 디폴트. */
56
58
  slugFn?: (goal: string) => Promise<string>;
57
- /** ★ triage 분류 seam(테스트 격리·luna 우회·2026-07-16). 없으면 defaultTriageClassify(luna) —
59
+ /** ★ triage 분류 seam(테스트 격리·luna 우회·2026-07-16). 없으면 classify 역할 judge —
58
60
  * 단 NODE_ENV=test 는 미주입(휴리스틱 baseline)으로 실 LLM 호출 방지. */
59
61
  triageClassify?: TriageCallable;
60
- /** ★ 도메인 분류 seam(테스트 격리·luna 우회·2026-07-20). 없으면 defaultDomainClassify(luna) —
62
+ /** ★ 도메인 분류 seam(테스트 격리·luna 우회·2026-07-20). 없으면 classify 역할 judge —
61
63
  * 단 NODE_ENV=test 는 미주입(키워드 baseline)으로 실 LLM 호출 방지. */
62
64
  domainClassify?: DomainClassify;
65
+ /** Injectable transport for testing the production judge path without network access. */
66
+ judgeDeps?: { streamLLM: StreamLlmFn; resolveRoleProvider: ResolveRoleProviderFn };
63
67
  }
64
68
 
65
69
  export type SubmitIntentResult =
@@ -132,14 +136,30 @@ export async function submitIntent(input: SubmitIntentInput): Promise<SubmitInte
132
136
  // 도메인 맥락 해소(§3.8·D5) — 키워드가 모호하면 최근 미션 도메인으로 기울인다
133
137
  // ("반도체 조사"→최근 투자 활동이면 investment). high 면 키워드 그대로.
134
138
  const recentDomains = listMissions(store, { limit: 8 }).map((r) => r.domain).filter(isDomain);
135
- // ★ triage(luna 주도·tier semantic 판정) + 도메인 해소 + LLM(luna) slug 를 병렬로(hot-path 무증가).
136
- // triageClassify 미주입 & test 면 휴리스틱 baseline(실 LLM 우회). 운영은 defaultTriageClassify(luna).
139
+ // ★ triage(classify 역할·tier semantic 판정) + 도메인 해소 + LLM slug 를 병렬로(hot-path 무증가).
140
+ // triageClassify 미주입 & test 면 휴리스틱 baseline(실 LLM 우회).
137
141
  const triageClassify = input.triageClassify
138
- ?? (process.env.NODE_ENV === 'test' ? undefined : defaultTriageClassify);
139
- // ★ 도메인도 luna 승격(2026-07-20) — 키워드는 주제 vs 행위유형을 못 갈라 "요약 기능 구현" 을
140
- // business(리서치·PR없음)로 오라우팅. luna 가 semantic 판정(강앵커 high 는 키워드 신뢰).
142
+ ?? (process.env.NODE_ENV === 'test' && !input.judgeDeps ? undefined : async (prompt: string) => {
143
+ const decision = await judge({ site: 'intent.triage', prompt, ...input.judgeDeps, schema: (value) => {
144
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return null;
145
+ const row = value as Record<string, unknown>;
146
+ if (!isExecutionModel(row.executionModel) || (row.tier !== 'light' && row.tier !== 'heavy') ||
147
+ (row.rationale !== undefined && typeof row.rationale !== 'string')) return null;
148
+ return row;
149
+ } });
150
+ return decision.ok ? JSON.stringify(decision.value) : '';
151
+ });
152
+ // ★ 도메인도 의미 판정(2026-07-20) — 키워드는 주제 vs 행위유형을 못 갈라 "요약 기능 구현" 을
153
+ // business(리서치·PR없음)로 오라우팅. judge 가 semantic 판정(강앵커 high 는 키워드 신뢰).
141
154
  const domainClassify = input.domainClassify
142
- ?? (process.env.NODE_ENV === 'test' ? undefined : defaultDomainClassify);
155
+ ?? (process.env.NODE_ENV === 'test' && !input.judgeDeps ? undefined : async (goal, ctx) => {
156
+ const decision = await judge({ site: 'intent.domain', prompt: buildDomainPrompt(goal, ctx), ...input.judgeDeps, schema: (value) => {
157
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return null;
158
+ const domain = (value as Record<string, unknown>).domain;
159
+ return isDomain(domain) ? domain : null;
160
+ } });
161
+ return decision.ok ? decision.value : null;
162
+ });
143
163
  const [resolved, slug, triage] = await Promise.all([
144
164
  resolveDomain(marker.goal, { recentDomains, classify: domainClassify }),
145
165
  (input.slugFn ?? generateMissionSlug)(marker.goal),
@@ -13,6 +13,7 @@ import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
13
13
  import { dirname, join } from 'node:path';
14
14
  import { elanousStateRoot } from '../autopilot/state-paths.js';
15
15
  import { debug } from '../debug/log.js';
16
+ import { publishInsideEvent } from '../nexus/api/inside-events.js';
16
17
  import { prodInstanceRoot } from '../instance/resolve.js';
17
18
 
18
19
  export const LIVE_DETAIL_DEFAULT_TTL_MIN = 30;
@@ -170,6 +171,10 @@ export function emitDecision(event: DecisionEvent, opts: DetailReadOptions = {})
170
171
  ...(parentRunId ? { parentRunId } : {}),
171
172
  ...(shard ? { shard } : {}),
172
173
  });
174
+ publishInsideEvent({ kind: 'pty.decision', decisionKind: event.kind, what: event.what,
175
+ reason: event.reason, purpose: event.purpose, target: event.target,
176
+ ...(runId ? { runId } : {}), ...(event.phase ? { phase: event.phase } : {}),
177
+ ...(parentRunId ? { parentRunId } : {}), ...(shard ? { shard } : {}) });
173
178
  return true;
174
179
  }
175
180
 
@@ -0,0 +1,57 @@
1
+ import { markdownSection, parseGoalType, tracedPathReferences, verbatimOriginalAsk } from '../self-implement/goal-author.js';
2
+ import { lookupLlmTierSpec } from '../model-tier/llm-tier-map.js';
3
+ import type { GoalType } from '../self-implement/goal-author.js';
4
+ import type { ModelTier } from '../model-tier/types.js';
5
+ import { ROLE_MODEL_DEFAULTS, type RoleLlmResolution } from '../user-config.js';
6
+
7
+ export interface DifficultySignals {
8
+ targetPathCount: number;
9
+ decisionSignalCount: number;
10
+ expectedChangedFileCount: number | null;
11
+ goalType: GoalType | null;
12
+ }
13
+
14
+ export type DifficultyLevel = 'small' | 'medium' | 'large';
15
+
16
+ /** Count declared target paths and authored decision signals without counting quoted run history. */
17
+ export function goalDifficultySignals(document: string): DifficultySignals {
18
+ const ask = verbatimOriginalAsk(document);
19
+ const targetLine = (ask ?? document).split(/\r?\n/)
20
+ .map((line) => /^대상 경로:\s*(.+)$/.exec(line)?.[1])
21
+ .find((line) => line !== undefined);
22
+ const namedPaths = targetLine?.split(' · ').map((path) => path.trim().replace(/^`|`$/g, '')).filter(Boolean) ?? [];
23
+ const paths = namedPaths.length ? namedPaths : tracedPathReferences(document).map(({ path }) => path);
24
+ const signals = markdownSection(document, '판정 신호') ?? '';
25
+ const candidates = signals.split(/\r?\n/).filter((line) => /^\s*- Candidate decision signal:\s*$/.test(line)).length;
26
+ const expectedResults = signals.split(/\r?\n/).filter((line) => /^\s*- Expected result:\s*\S/.test(line)).length;
27
+ const countLine = (ask ?? document).split(/\r?\n/).find((line) => /^\s*(?:-\s*)?(?:예상 (?:변경|바뀌는) 파일 수|Expected changed files(?: count)?):\s*\d+\s*$/i.test(line));
28
+ const expectedChangedFileCount = countLine ? Number(countLine.split(':').at(-1)!.trim()) : null;
29
+ return {
30
+ targetPathCount: new Set(paths).size,
31
+ decisionSignalCount: Math.max(candidates, expectedResults),
32
+ expectedChangedFileCount,
33
+ goalType: parseGoalType(document),
34
+ };
35
+ }
36
+
37
+ export function classifyGoalDifficulty(signals: DifficultySignals): DifficultyLevel {
38
+ const { targetPathCount, decisionSignalCount, expectedChangedFileCount, goalType } = signals;
39
+ if (targetPathCount > 5 || decisionSignalCount > 5 || (expectedChangedFileCount ?? 0) > 5) return 'large';
40
+ if (goalType === 'implement' && targetPathCount === 1 && decisionSignalCount === 1) return 'small';
41
+ return 'medium';
42
+ }
43
+
44
+ /** Only the baseline role default is adjustable; explicit roleLlm and older config/env layers win. */
45
+ export function implementDifficultyTier(level: DifficultyLevel, role: RoleLlmResolution): ModelTier | undefined {
46
+ if (role.source !== 'default') return undefined;
47
+ return level === 'small' ? 'budget' : level === 'large' ? 'best' : ROLE_MODEL_DEFAULTS.implement.tier;
48
+ }
49
+
50
+ export function resolveImplementDifficulty(role: RoleLlmResolution, level: DifficultyLevel): RoleLlmResolution {
51
+ const tier = implementDifficultyTier(level, role);
52
+ return tier === undefined ? role : {
53
+ ...role,
54
+ model: lookupLlmTierSpec(role.provider, tier).model,
55
+ tier,
56
+ };
57
+ }
@@ -0,0 +1,101 @@
1
+ import { debug } from '../debug/log.js';
2
+ import { resolveRoleLlm, type UserConfig } from '../user-config.js';
3
+ import type { ResolveRoleProviderFn, StreamLlmFn } from '../intake-plane/runtime-callables.js';
4
+
5
+ interface JudgeReply {
6
+ text: string;
7
+ promptTokens?: number;
8
+ completionTokens?: number;
9
+ costUsd?: number;
10
+ modelId?: string;
11
+ }
12
+
13
+ interface JudgeOptions<T = string> {
14
+ site: string;
15
+ prompt: string;
16
+ messages?: Array<{ role: 'user' | 'system' | 'assistant'; content: string }>;
17
+ /** Return null when the parsed decision is not usable. */
18
+ schema?: (value: unknown) => T | null;
19
+ signal?: AbortSignal;
20
+ /** Injectable transport for callers with an existing LLM callable. */
21
+ call?: (args: { prompt: string; signal?: AbortSignal; provider: string; model: string }) => Promise<JudgeReply>;
22
+ streamLLM?: StreamLlmFn;
23
+ resolveRoleProvider?: ResolveRoleProviderFn;
24
+ /** Optional config slice for deterministic role resolution in isolated callers. */
25
+ config?: UserConfig;
26
+ }
27
+
28
+ type JudgeResult<T> =
29
+ | { ok: true; value: T; reply: JudgeReply; provider: string; model: string }
30
+ | { ok: false; reason: 'call'; error: unknown }
31
+ | { ok: false; reason: 'schema'; rawText: string };
32
+
33
+ /** Marks a judge call that ran on an injected transport with no configured provider. */
34
+ export const UNRESOLVED = 'unresolved';
35
+
36
+ function parseJson(text: string): unknown {
37
+ const trimmed = text.trim();
38
+ const fence = trimmed.match(/```(?:json)?\s*\n([\s\S]*?)```/);
39
+ const candidate = fence ? fence[1]!.trim() : trimmed;
40
+ try { return JSON.parse(candidate); } catch { /* Models can prefix a JSON object with prose. */ }
41
+ const start = candidate.indexOf('{');
42
+ const end = candidate.lastIndexOf('}');
43
+ if (start < 0 || end <= start) return null;
44
+ try { return JSON.parse(candidate.slice(start, end + 1)); } catch { return null; }
45
+ }
46
+
47
+ /** One role-scoped classification call; errors and invalid decisions leave rule fallback to the caller. */
48
+ export async function judge<T = string>(opts: JudgeOptions<T>): Promise<JudgeResult<T>> {
49
+ const started = Date.now();
50
+ let provider = '';
51
+ let model = '';
52
+ let ok = false;
53
+ try {
54
+ const picked = opts.resolveRoleProvider?.('classify');
55
+ if (picked) {
56
+ provider = picked.provider.name;
57
+ model = picked.model ?? '';
58
+ } else {
59
+ try {
60
+ const resolved = resolveRoleLlm('classify', opts.config ? { config: opts.config } : {});
61
+ provider = resolved.provider;
62
+ model = resolved.model;
63
+ } catch (error) {
64
+ // An injected transport does not need a configured provider; a real call still fails as before.
65
+ if (!opts.call || (error as Error | undefined)?.name !== 'NoLlmProviderAvailableError') throw error;
66
+ provider = UNRESOLVED;
67
+ model = UNRESOLVED;
68
+ try { debug.log('llm.judge', 'provider-unresolved', { site: opts.site }); } catch { /* fail-soft */ }
69
+ }
70
+ }
71
+ const messages = opts.messages ?? [{ role: 'user' as const, content: opts.prompt }];
72
+ let reply: JudgeReply;
73
+ if (opts.call) {
74
+ reply = await opts.call({ prompt: opts.prompt, signal: opts.signal, provider, model });
75
+ } else {
76
+ const llm = picked && opts.streamLLM ? undefined : await import('../llm.js');
77
+ const transportProvider = picked?.provider ?? llm?.PROVIDERS[provider];
78
+ if (!transportProvider) throw new Error(`Unknown classify provider: ${provider}`);
79
+ const streamOpts = { ...(model ? { model } : {}), ...(opts.signal ? { signal: opts.signal } : {}), usageRole: 'classify' as const };
80
+ if (opts.streamLLM) {
81
+ reply = { text: await opts.streamLLM(messages, () => {}, {
82
+ ...streamOpts, provider: transportProvider as ReturnType<ResolveRoleProviderFn>['provider'],
83
+ }) };
84
+ } else {
85
+ const registeredProvider = llm?.PROVIDERS[provider];
86
+ if (!llm || !registeredProvider) throw new Error(`Unknown classify provider: ${provider}`);
87
+ reply = { text: await llm.streamLLM(messages, () => {}, { ...streamOpts, provider: registeredProvider }) };
88
+ }
89
+ }
90
+ const value = opts.schema ? opts.schema(parseJson(reply.text)) : reply.text as T;
91
+ if (value === null || value === undefined) return { ok: false, reason: 'schema', rawText: reply.text };
92
+ ok = true;
93
+ return { ok: true, value, reply, provider, model };
94
+ } catch (error) {
95
+ return { ok: false, reason: 'call', error };
96
+ } finally {
97
+ try {
98
+ debug.log('llm.judge', 'call', { site: opts.site, provider, model, ms: Date.now() - started, ok });
99
+ } catch { /* Observation must not turn an undecided call into an exception. */ }
100
+ }
101
+ }