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,4 +1,4 @@
1
- // PS1 — `elanous persona list|add|show`: 프리셋(persona-presets/)을 보고, 골라서 «내 페르소나»를 만들고, 만든 것을 본다.
1
+ // `elanous persona list|add|edit|show`: 프리셋을 보고, 내 페르소나를 만들고 꾸민다.
2
2
  // 만든 페르소나는 기존 페르소나 저장소(resolveStatePersonaDir · Discord·PWA 가 읽는 곳)의 `<id>.yaml` 한 파일이다.
3
3
  import type { Command } from 'commander';
4
4
  import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
@@ -7,7 +7,8 @@ import { parse as parseYaml } from 'yaml';
7
7
  import { debug } from '../debug/log.js';
8
8
  import { parsePersonaYaml } from '../persona/loader.js';
9
9
  import { resolveRepositoryPersonaDir, resolveStatePersonaDir } from '../persona/global-registry.js';
10
- import { choosePersonaId, describePreset, findPreset, loadPresetIndex, loadPresets, presetToProfileYaml } from '../persona/presets.js';
10
+ import { UnknownPersonaSchemaKeyError, choosePersonaId, clonePreset, describePreset, editPersona, findPreset, loadPresetIndex, loadPresets, presetToProfileYaml } from '../persona/presets.js';
11
+ import { addTeamSet, listTeamSets, removeTeamSet } from '../persona/team-set.js';
11
12
 
12
13
  interface StoredPersona { personaId: string; displayName: string; description?: string; preset?: string; title?: string; path: string }
13
14
 
@@ -36,8 +37,52 @@ function takenIds(stateDir: string): Set<string> {
36
37
  return ids;
37
38
  }
38
39
 
40
+ function mapping(value: unknown): value is Record<string, unknown> {
41
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
42
+ }
43
+
44
+ function setEdit(edits: Record<string, unknown>, assignment: string): void {
45
+ const equals = assignment.indexOf('=');
46
+ if (equals < 0) throw new Error(`--set requires key=value: ${assignment}`);
47
+ const key = assignment.slice(0, equals);
48
+ const parts = key.split('.');
49
+ if (parts.some((part) => !part || ['__proto__', 'prototype', 'constructor'].includes(part))) {
50
+ throw new UnknownPersonaSchemaKeyError(key);
51
+ }
52
+ const value: unknown = parseYaml(assignment.slice(equals + 1));
53
+ let target = edits;
54
+ for (const part of parts.slice(0, -1)) {
55
+ if (!Object.hasOwn(target, part)) target[part] = {};
56
+ if (!mapping(target[part])) throw new Error(`--set key conflicts with a scalar: ${key}`);
57
+ target = target[part];
58
+ }
59
+ target[parts.at(-1)!] = value;
60
+ }
61
+
62
+ function editOptions(fromFile: string | undefined, assignments: readonly string[]): Record<string, unknown> {
63
+ const parsed: unknown = fromFile ? parseYaml(readFileSync(fromFile, 'utf8')) : {};
64
+ if (!mapping(parsed)) throw new Error('--from-file must contain a YAML mapping');
65
+ const edits = { ...parsed };
66
+ for (const assignment of assignments) setEdit(edits, assignment);
67
+ return edits;
68
+ }
69
+
39
70
  export function registerPersonaCommands(program: Command): void {
40
- const persona = program.command('persona').description('Persona presets — AI coworkers you pick and customise (list · add · show)');
71
+ const team = program.command('team-set').description('Install, remove and list persona team sets');
72
+ team.command('add <file>').description('Install a YAML team set').action((file: string) => {
73
+ try { const result = addTeamSet(file); console.log(`Installed team-set ${result['team-set']}`); }
74
+ catch (error) { console.error(error instanceof Error ? error.message : String(error)); process.exitCode = 1; }
75
+ });
76
+ team.command('remove <name>').description('Remove an installed team set').action((name: string) => {
77
+ try { removeTeamSet(name); console.log(`Removed team-set ${name}`); }
78
+ catch (error) { console.error(error instanceof Error ? error.message : String(error)); process.exitCode = 1; }
79
+ });
80
+ team.command('list').description('List installed team sets').action(() => {
81
+ try { for (const item of listTeamSets()) console.log(`${item['team-set']} ${item.members.map((member) => `${member.persona} (${member.title})`).join(', ')}`); }
82
+ catch (error) { console.error(error instanceof Error ? error.message : String(error)); process.exitCode = 1; }
83
+ });
84
+
85
+ const persona = program.command('persona').description('Persona presets — AI coworkers you pick and customise (list · add · edit · show)');
41
86
 
42
87
  persona.command('list')
43
88
  .description('List the persona presets, then the personas you have made')
@@ -49,7 +94,7 @@ export function registerPersonaCommands(program: Command): void {
49
94
  if (opts.json) { console.log(JSON.stringify({ presets: presets.map((p) => ({ id: p.personaId, displayName: p.displayName, role: p.role, oneLine: p.oneLine })), mine }, null, 2)); return; }
50
95
  if (!presets.length) console.log('페르소나 프리셋을 찾지 못했습니다(persona-presets/ 가 이 설치본에 없습니다).');
51
96
  else {
52
- console.log('프리셋 — 골라서 내 페르소나로 만들기: elanous persona add <프리셋> [--name <이름>]');
97
+ console.log('프리셋 — 골라서 내 페르소나로 만들기: elanous persona add <이름> [--from <프리셋>]');
53
98
  const width = Math.max(...presets.map((p) => p.personaId.length));
54
99
  for (const p of presets) console.log(` ${p.personaId.padEnd(width)} ${p.displayName} — ${p.role} · ${p.oneLine}`);
55
100
  }
@@ -60,19 +105,40 @@ export function registerPersonaCommands(program: Command): void {
60
105
  }
61
106
  });
62
107
 
63
- persona.command('add <preset>')
64
- .description('Make your own persona from a preset (id, name or role) — the preset file is not changed')
108
+ persona.command('add <name>')
109
+ .description('Make your own persona from a preset — the preset file is not changed')
110
+ .option('--from <preset>', 'Preset to clone (defaults to the named preset)')
65
111
  .option('--name <name>', 'What to call it (default: the preset’s first name)')
112
+ .option('--as <name>', 'Clone this preset under a new, unique name')
66
113
  .option('--title <title>', 'Optional title, e.g. CMO')
67
114
  .option('--json', 'JSON output')
68
- .action((query: string, opts: { name?: string; title?: string; json?: boolean }) => {
115
+ .action((query: string, opts: { from?: string; name?: string; as?: string; title?: string; json?: boolean }) => {
69
116
  const presets = loadPresets();
70
- const preset = findPreset(presets, query);
117
+ const presetQuery = opts.from ?? query;
118
+ const preset = findPreset(presets, presetQuery);
71
119
  if (!preset) {
72
- console.error(`프리셋 «${query}» 을 찾지 못했습니다. 있는 것: ${presets.map((p) => p.personaId).join(', ')}`);
120
+ console.error(`프리셋 «${presetQuery}» 을 찾지 못했습니다. 있는 것: ${presets.map((p) => p.personaId).join(', ')}`);
73
121
  process.exitCode = 1;
74
122
  return;
75
123
  }
124
+ if (opts.as !== undefined || opts.from !== undefined) {
125
+ try {
126
+ if (opts.from !== undefined && (opts.as !== undefined || opts.name !== undefined || opts.title !== undefined)) throw new Error('--from cannot be combined with --as, --name or --title');
127
+ if (opts.as !== undefined && (opts.name !== undefined || opts.title !== undefined)) throw new Error('--as cannot be combined with --name or --title');
128
+ const result = clonePreset(preset, opts.from !== undefined ? query : opts.as!);
129
+ debug.log('persona.cli', 'cloned', { preset: preset.personaId, personaId: result.personaId });
130
+ if (opts.json) console.log(JSON.stringify({ personaId: result.personaId, displayName: result.displayName, preset: preset.personaId, path: result.path }, null, 2));
131
+ else {
132
+ console.log(`만들었습니다 — ${result.displayName} (id ${result.personaId} · 프리셋 ${preset.personaId})`);
133
+ console.log(` 처음 묻는 것: ${preset.firstQuestions.join(' / ')}`);
134
+ console.log(` 보기: elanous persona show ${result.personaId}`);
135
+ }
136
+ } catch (err) {
137
+ console.error(err instanceof Error ? err.message : String(err));
138
+ process.exitCode = 1;
139
+ }
140
+ return;
141
+ }
76
142
  const dir = resolveStatePersonaDir();
77
143
  const personaId = choosePersonaId(preset, opts.name, takenIds(dir));
78
144
  const yaml = presetToProfileYaml(preset, loadPresetIndex().common, { personaId, ...(opts.name ? { name: opts.name } : {}), ...(opts.title ? { title: opts.title } : {}) });
@@ -89,6 +155,29 @@ export function registerPersonaCommands(program: Command): void {
89
155
  console.log(` 보기: elanous persona show ${personaId}`);
90
156
  });
91
157
 
158
+ persona.command('edit <name>')
159
+ .description('Edit a saved persona (schema fields only; the preset source is not changed)')
160
+ .option('--set <key=value>', 'Set a field (repeatable; YAML values)', (value: string, values: string[]) => [...values, value], [] as string[])
161
+ .option('--from-file <path>', 'Load edits from a YAML mapping')
162
+ .option('--dry-run', 'Validate and preview without writing')
163
+ .option('--json', 'JSON output')
164
+ .action((name: string, opts: { set: string[]; fromFile?: string; dryRun?: boolean; json?: boolean }) => {
165
+ try {
166
+ if (!opts.fromFile && !opts.set.length) throw new Error('persona edit requires --set or --from-file');
167
+ const result = editPersona(name, editOptions(opts.fromFile, opts.set), { dryRun: opts.dryRun });
168
+ debug.log('persona.cli', opts.dryRun ? 'edit-dry-run' : 'edited', { personaId: result.personaId });
169
+ if (opts.json) console.log(JSON.stringify(result, null, 2));
170
+ else {
171
+ console.log(`${opts.dryRun ? '미리 보기' : '수정했습니다'} — ${result.displayName} (id ${result.personaId})`);
172
+ console.log(result.yaml);
173
+ console.log(` 파일: ${result.path}`);
174
+ }
175
+ } catch (err) {
176
+ console.error(err instanceof Error ? err.message.replace(/\s+/g, ' ').trim() : String(err));
177
+ process.exitCode = err instanceof UnknownPersonaSchemaKeyError ? 2 : 1;
178
+ }
179
+ });
180
+
92
181
  persona.command('show <name>')
93
182
  .description('Show one of your personas (id or name), or a preset')
94
183
  .option('--json', 'JSON output')
@@ -12,6 +12,7 @@ import { OFFICIAL_INDEX_KEYS } from '../market/official-keys.js';
12
12
  import { installPlugin, listInstalledPlugins, PluginInstallError, removePlugin, type InstallEvent } from '../plugins/install/plugin-install.js';
13
13
  import { credentialStatus, setPluginCredentials } from '../plugins/install/plugin-credentials.js';
14
14
  import { makePlugin } from '../plugins/maker/plugin-maker.js';
15
+ import { registerStandaloneLogSink } from '../domains/standalone-log-sink.js';
15
16
  import { addAndInstallNode } from '../plugins/maker/node-install.js';
16
17
 
17
18
  function keys(): ReadonlyArray<{ keyId: string; publicKey: string }> {
@@ -56,34 +57,42 @@ function safeCause(error: unknown): string {
56
57
  return redactSecretText(error.message.replace(/https?:\/\/[^\s"'<>]+/gi, '[redacted URL]'));
57
58
  }
58
59
 
60
+ export async function runPluginMake(request: string, opts: { name?: string; dir?: string; draftFile?: string; run?: boolean; marketBundleDir?: string; input?: string; json?: boolean } = {}): Promise<void> {
61
+ try {
62
+ await registerStandaloneLogSink('cli');
63
+ const result = await makePlugin({ request, name: opts.name, parentDir: opts.dir, draftFile: opts.draftFile, run: opts.run, marketBundleDir: opts.marketBundleDir,
64
+ ...(opts.input === undefined ? {} : { input: JSON.parse(opts.input) as unknown }) });
65
+ debug.flush();
66
+ if (opts.json) stdout.write(JSON.stringify(result) + '\n');
67
+ else {
68
+ console.log(`뼈대 ${result.timings.scaffold}ms · 작성 ${result.timings.write}ms`);
69
+ console.log(`검증 오류 ${result.errors.length} · ${result.timings.validate}ms${result.timings.repair === undefined ? '' : ` · 수리 ${result.timings.repair}ms`}`);
70
+ console.log(`설치 ${result.status === 'draft' || result.timings.install === 0 ? '미실행' : result.status === 'failed' && result.timings.run === undefined ? '실패' : '완료'} · ${result.timings.install}ms (${result.dir})`);
71
+ if (result.status === 'draft') console.log('연구 초안만 생성됨 — 요청 처리 단계 구현 후 별도로 검증·설치 필요');
72
+ if (result.marketBundle) console.log(`마켓 꾸러미 ${result.marketBundle.path} · ${result.marketBundle.signature} · 게시 안 함`);
73
+ if (opts.run) console.log(`실행 ${result.runStatus ?? '미실행'} · ${result.timings.run ?? 0}ms`);
74
+ for (const error of result.errors) console.error(error);
75
+ }
76
+ if (result.status === 'failed') process.exitCode = 1;
77
+ } catch (error) {
78
+ const message = error instanceof Error ? error.message : String(error);
79
+ if (opts.json) stdout.write(JSON.stringify({ status: 'failed', errors: [message] }) + '\n');
80
+ else console.error(`plugin make failed: ${message}`);
81
+ process.exitCode = 1;
82
+ }
83
+ }
84
+
59
85
  export function registerPluginCommands(program: Command): void {
60
86
  const plugin = program.command('plugin').description('Install and manage Elanous plugins');
61
- plugin.command('make <request>').description('Write, validate and install a local graph plugin from one request')
87
+ plugin.command('make <request>').description('Write, validate and install a local graph plugin, or generate an uninstalled research draft')
62
88
  .option('--name <slug>', 'Local plugin name')
63
89
  .option('--dir <parent>', 'Parent directory (default: instance plugins-local)')
64
- .option('--run', 'Run the installed graph')
90
+ .option('--draft-file <path>', 'Generate an uninstalled research draft with connector and skill definitions')
91
+ .option('--run', 'Run the installed graph (not available for research drafts)')
92
+ .option('--market-bundle-dir <path>', 'Bundle installed plugin for human review; never publish')
65
93
  .option('--input <json>', 'JSON input for --run')
66
94
  .option('--json', 'Print the result as JSON')
67
- .action(async (request: string, opts: { name?: string; dir?: string; run?: boolean; input?: string; json?: boolean }) => {
68
- try {
69
- const result = await makePlugin({ request, name: opts.name, parentDir: opts.dir, run: opts.run,
70
- ...(opts.input === undefined ? {} : { input: JSON.parse(opts.input) as unknown }) });
71
- if (opts.json) stdout.write(JSON.stringify(result) + '\n');
72
- else {
73
- console.log(`뼈대 ${result.timings.scaffold}ms · 작성 ${result.timings.write}ms`);
74
- console.log(`검증 오류 ${result.errors.length} · ${result.timings.validate}ms${result.timings.repair === undefined ? '' : ` · 수리 ${result.timings.repair}ms`}`);
75
- console.log(`설치 ${result.timings.install === 0 && result.status === 'failed' ? '미실행' : result.status === 'failed' && result.timings.run === undefined ? '실패' : '완료'} · ${result.timings.install}ms (${result.dir})`);
76
- if (opts.run) console.log(`실행 ${result.runStatus ?? '미실행'} · ${result.timings.run ?? 0}ms`);
77
- for (const error of result.errors) console.error(error);
78
- }
79
- if (result.status === 'failed') process.exitCode = 1;
80
- } catch (error) {
81
- const message = error instanceof Error ? error.message : String(error);
82
- if (opts.json) stdout.write(JSON.stringify({ status: 'failed', errors: [message] }) + '\n');
83
- else console.error(`plugin make failed: ${message}`);
84
- process.exitCode = 1;
85
- }
86
- });
95
+ .action(runPluginMake);
87
96
  plugin.command('node').description('Manage plugin workflow nodes')
88
97
  .command('add <dir> <request>').description('Write, validate and install a workflow node in a plugin')
89
98
  .option('--kind <slug>', 'Workflow node kind')
@@ -3,10 +3,11 @@
3
3
 
4
4
  import type { Command } from 'commander';
5
5
  import { debug } from '../debug/log.js';
6
+ import { readPodMemoryAdvice } from './pod-memory-advice.js';
6
7
  import { getUserConfig } from '../user-config.js';
7
8
  import { listCodexAccountsInStore } from '../oauth/codex-account-store.js';
8
9
  import { parsePodPool, resolvePodPoolSpec, type PoolKubectl } from '../task-orchestrator/surfaces/pod-pool.js';
9
- import { leaseKubectl, measurePoolLease, recommendConcurrency, type PoolLeaseMeasure } from '../task-orchestrator/surfaces/pod-lease.js';
10
+ import { leaseKubectl, measurePoolLease, probePoolDns, recommendConcurrency, type PoolLeaseMeasure, type PoolDnsProbe } from '../task-orchestrator/surfaces/pod-lease.js';
10
11
  import { POD_COMMAND_DEADLINE_SECONDS, runPodCommand, type PodCommandResult, type RunPodCommandOptions } from '../task-orchestrator/surfaces/pod-command-job.js';
11
12
 
12
13
  export interface PodCliIo {
@@ -19,9 +20,12 @@ export interface PodCliDeps {
19
20
  io?: PodCliIo;
20
21
  run?: (options: RunPodCommandOptions) => Promise<PodCommandResult>;
21
22
  kubectl?: PoolKubectl;
23
+ dns?: (context: string, kubectl: PoolKubectl) => PoolDnsProbe;
22
24
  accounts?: () => number;
23
25
  perAccount?: () => number;
24
26
  poolSpec?: (explicit?: string) => string | null;
27
+ harnessPool?: () => string | undefined;
28
+ memoryAdvice?: (logsDb?: string) => ReturnType<typeof readPodMemoryAdvice>;
25
29
  }
26
30
 
27
31
  const HELP = `elanous pod run [--pool <스펙>] [--skill <이름,…>] [--llm grok] [--clone] [--deadline <초>] -- <명령…>
@@ -36,19 +40,37 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
36
40
  };
37
41
  const run = deps.run ?? ((options: RunPodCommandOptions) => runPodCommand(options));
38
42
  const pod = program.command('pod').description('Pod 명령 Job — 하니스 없이 명령 하나를 돌리고 산출을 돌려받는다');
39
- pod.command('lease').description('Pod 풀의 읽기 전용 동시 실행 권장')
43
+ pod.command('memory').description('실측 기반 Pod 메모리 권고 (읽기 전용)')
44
+ .command('advise').description('골 종류별 standard 16Gi / high 32Gi 권고와 근거')
45
+ .option('--json', '권고와 측정 근거를 JSON 으로')
46
+ .option('--logs-db <path>', '기존 logs.db 경로')
47
+ .action((opts: { json?: boolean; logsDb?: string }) => {
48
+ try {
49
+ const advice = (deps.memoryAdvice ?? readPodMemoryAdvice)(opts.logsDb);
50
+ if (opts.json) io.log(JSON.stringify(advice));
51
+ else for (const row of advice.byGoalType) io.log(`${row.goalType}: ${row.recommended} ${row.limit} · ${row.reason}`);
52
+ io.exit(0);
53
+ } catch (err) {
54
+ io.error(err instanceof Error ? err.message : String(err));
55
+ io.exit(1);
56
+ }
57
+ });
58
+ pod.command('lease').description('Pod 풀 동시 실행 권장 (DNS 점검용 Pod 를 잠깐 만들었다 지움)')
40
59
  .command('status').description('지금 추가로 쏠 수 있는 Pod 골과 제한 근거')
41
- .option('--pool <spec>', '풀 스펙 — 컨텍스트[@ssh호스트][:상한] 쉼표')
60
+ .option('--pool <spec>', '풀 스펙 — 컨텍스트[@ssh호스트][:상한][#레지스트리:포트] 쉼표')
42
61
  .option('--json', '표 대신 동일 측정값을 JSON 으로')
43
62
  .action((opts: { pool?: string; json?: boolean }) => {
44
63
  try {
45
64
  const kubectl = deps.kubectl ?? leaseKubectl;
46
- const spec = (deps.poolSpec ?? ((explicit?: string) => resolvePodPoolSpec(explicit)))(opts.pool);
65
+ const spec = (deps.poolSpec ?? ((explicit?: string) => resolvePodPoolSpec(explicit, process.env, () => {
66
+ const config = deps.harnessPool ? null : getUserConfig();
67
+ return (deps.harnessPool?.() ?? config?.harness?.podPool) || config?.pod?.pool;
68
+ })))(opts.pool);
47
69
  // No pool configured: mirror the Pod launch fallback to kubectl's current context.
48
70
  const current = spec ? null : kubectl(['config', 'current-context']);
49
71
  const context = spec ?? (current?.status === 0 ? current.stdout.trim() : '');
50
72
  const members = context ? parsePodPool(context) : [];
51
- const measure: PoolLeaseMeasure = members.length ? measurePoolLease(members, { kubectl }) : { members: [] };
73
+ const measure: PoolLeaseMeasure = members.length ? measurePoolLease(members, { kubectl, dns: (context) => (deps.dns ?? probePoolDns)(context, kubectl) }) : { members: [] };
52
74
  let accounts: number | null = null;
53
75
  let accountReason: string | null = null;
54
76
  try { accounts = (deps.accounts ?? (() => listCodexAccountsInStore().length))(); }
@@ -57,17 +79,20 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
57
79
  const decision = recommendConcurrency(measure, { capacity: members.reduce((sum, m) => sum + m.capacity, 0), accounts: accounts ?? -1, perAccount });
58
80
  if (!context) { decision.recommended = null; decision.limitedBy = null; decision.reason = '측정 불가: cluster (current context)'; }
59
81
  const result = { pool: spec, ...measure, accounts, perAccount, ...decision };
60
- debug.log('pod.lease', 'status', { pool: spec ? members.map((m) => ({ capacity: m.capacity })) : null, running: decision.running, pending: decision.pending, recommended: decision.recommended, limitedBy: decision.limitedBy });
82
+ debug.log('pod.lease', 'status', { pool: spec ? members.map((m) => ({ capacity: m.capacity })) : null, running: decision.running, pending: decision.pending, unleasedRunning: decision.unleasedRunning, recommended: decision.recommended, limitedBy: decision.limitedBy });
61
83
  if (opts.json) io.log(JSON.stringify(result));
62
84
  else {
85
+ io.log(`풀: ${(spec ?? context) || '?'}`);
63
86
  io.log('컨텍스트 | 상한 | Running | Pending | 메모리(상한 합/할당 가능) | CPU(할당 가능)');
64
87
  for (const m of measure.members) {
65
88
  const mem = (v: number | null) => v === null ? '?' : `${(v / 1024 ** 3).toFixed(1)}Gi`;
66
89
  io.log(`${m.context} | ${m.capacity} | ${m.running ?? '?'} | ${m.pending ?? '?'} | ${mem(m.memoryLimitBytes)}/${mem(m.allocatableMemoryBytes)} | ${m.allocatableCpuMillicores === null ? '?' : m.allocatableCpuMillicores / 1000}${m.reason ? ` (${m.reason})` : ''}`);
67
90
  }
68
91
  io.log(`권장 지금 ${decision.recommended ?? '?'} 개 더 (limitedBy=${decision.limitedBy ?? 'unknown'})${decision.reason ? ` · ${decision.reason}` : ''}`);
69
- io.log(`capacity: ${decision.capacitySlots ?? '?'} 칸 (상한 ${members.reduce((sum, m) => sum + m.capacity, 0)} − Running ${decision.running ?? '?'} − Pending ${decision.pending ?? '?'})`);
92
+ io.log(`임대 없는 실행 ${decision.unleasedRunning ?? '?'}`);
93
+ io.log(`capacity: ${decision.capacitySlots ?? '?'} 칸 (상한 ${members.reduce((sum, m) => sum + m.capacity, 0)} − Running ${decision.running ?? '?'} − Pending ${decision.pending ?? '?'}; 권장 수에서 건강한 멤버의 임대 없는 실행 차감)`);
70
94
  io.log(`memory: ${decision.memorySlots ?? '?'} 칸 (할당 가능 − Running 하니스 상한 합; 골당 16Gi · 모든 네임스페이스의 노드별 기존 예약을 반영해 배치 가능 ${decision.placeableSlots ?? '?'} 칸)`);
95
+ io.log(`lite: ${decision.liteMemorySlots ?? '?'} 칸 (같은 여유를 lite 골 2Gi 로 센 값 · 관측만 — 권장 수는 위 standard 기준)`);
71
96
  io.log(`accounts (관측만 · 상한 아님): ${decision.accountSlots ?? '?'} 칸 (${accounts ?? '?'} × ${perAccount} − Running ${decision.running ?? '?'})${accountReason ? ` · ${accountReason}` : ''}`);
72
97
  }
73
98
  io.exit(0);
@@ -78,14 +103,15 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
78
103
  });
79
104
  pod.command('run')
80
105
  .description(HELP)
81
- .option('--pool <spec>', '풀 스펙 — 컨텍스트[@ssh호스트][:상한] 쉼표')
106
+ .option('--pool <spec>', '풀 스펙 — 컨텍스트[@ssh호스트][:상한][#레지스트리:포트] 쉼표')
82
107
  .option('--skill <names>', '스킬 이름(쉼표). 그 스킬 .env 만 Secret 으로 싣는다')
83
108
  .option('--llm <provider>', 'grok 만 허용 — access 사본(refresh 없음)')
84
109
  .option('--clone', '저장소를 clone 한다(비공개 · GitHub 토큰이 런 Secret 으로 간다 · 명시할 때만). 기본은 clone 없이 ~/work 에서 이미지의 elanous 로')
85
110
  .option('--deadline <seconds>', `Job 수명 상한(초). 생략 시 ${POD_COMMAND_DEADLINE_SECONDS}`)
86
111
  .allowUnknownOption(true)
87
112
  .allowExcessArguments(true)
88
- .action(async (opts: { pool?: string; skill?: string; llm?: string; clone?: boolean; deadline?: string }, command: Command) => {
113
+ .option('--lite', '네트워크 스킬(omni-crawl·omni-digest)만 쓰는 명령 — 작은 이미지 ⊕ 2Gi 한도(POD7 · clone 불가)')
114
+ .action(async (opts: { pool?: string; skill?: string; llm?: string; clone?: boolean; deadline?: string; lite?: boolean }, command: Command) => {
89
115
  const argv = process.argv.slice(2);
90
116
  const sep = argv.indexOf('--');
91
117
  const fromArgv = sep >= 0 ? argv.slice(sep + 1) : [];
@@ -117,6 +143,7 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
117
143
  ...(skills.length ? { skills } : {}),
118
144
  ...(opts.llm === 'grok' ? { llm: 'grok' as const } : {}),
119
145
  ...(opts.clone ? { clone: true } : {}),
146
+ ...(opts.lite ? { lite: true } : {}),
120
147
  ...(deadlineSeconds !== undefined ? { deadlineSeconds } : {}),
121
148
  });
122
149
  if (result.image) io.error(`[pod] image ${result.image} · job ${result.job}`);
@@ -0,0 +1,35 @@
1
+ import { readPodMemoryMeasurement, type MemoryMeasurement } from '../../scripts/measure-pod-memory-by-goal.js';
2
+
3
+ export type PodMemoryAdvice = {
4
+ window: MemoryMeasurement['window'];
5
+ sources: MemoryMeasurement['sources'];
6
+ byGoalType: Array<{
7
+ goalType: MemoryMeasurement['byGoalType'][number]['goalType'];
8
+ recommended: 'standard' | 'high';
9
+ limit: '16Gi' | '32Gi';
10
+ reason: string;
11
+ evidence: MemoryMeasurement['byGoalType'][number];
12
+ }>;
13
+ };
14
+
15
+ /** Advice only: the launch selector and its configuration remain independent. */
16
+ export function advisePodMemory(measurement: MemoryMeasurement): PodMemoryAdvice {
17
+ return {
18
+ window: measurement.window,
19
+ sources: measurement.sources,
20
+ byGoalType: measurement.byGoalType.map((evidence) => {
21
+ const high = evidence.oomKilled > 0 || (evidence.peakMiB.p95 !== null && evidence.peakMiB.p95 >= 16 * 1024);
22
+ const reason = evidence.oomKilled > 0
23
+ ? `${evidence.oomKilled}/${evidence.runs} OOMKilled; measured peak p50=${evidence.peakMiB.p50 ?? 'n/a'} MiB, p95=${evidence.peakMiB.p95 ?? 'n/a'} MiB (${evidence.measured}/${evidence.runs} measured)`
24
+ : evidence.measured === 0
25
+ ? `No measured peaks (${evidence.missingPeak}/${evidence.runs} missing); standard is provisional, not evidence of safety`
26
+ : `Measured peak p50=${evidence.peakMiB.p50} MiB, p95=${evidence.peakMiB.p95} MiB (${evidence.measured}/${evidence.runs} measured, ${evidence.missingPeak} missing); ${high ? 'at or above' : 'below'} 16Gi`;
27
+ return { goalType: evidence.goalType, recommended: high ? 'high' as const : 'standard' as const,
28
+ limit: high ? '32Gi' as const : '16Gi' as const, reason, evidence };
29
+ }),
30
+ };
31
+ }
32
+
33
+ export function readPodMemoryAdvice(path?: string): PodMemoryAdvice {
34
+ return advisePodMemory(readPodMemoryMeasurement(path));
35
+ }
package/src/cli/pr-cli.ts CHANGED
@@ -18,7 +18,7 @@ import { runMockModuleRestoreGate } from '../../scripts/ci-mock-module-restore-g
18
18
  import { runModelHardcodeGate } from '../../scripts/ci-model-hardcode-gate.js';
19
19
  import { runDaemonPortGate } from '../../scripts/ci-daemon-port-gate.js';
20
20
  import { runPublicLeakGate } from '../../scripts/ci-public-leak-gate.js';
21
- import { exportLeakCheck, type ExportLeakCheck } from '../../scripts/ci-public-export-leak-gate.js';
21
+ import { exportLeakCheck, publicExportChangedFiles, type ExportLeakCheck } from '../../scripts/ci-public-export-leak-gate.js';
22
22
  import { checkCommands, extractElanousCommands, type Finding as DocsCliFinding } from '../../scripts/docs-cli-check.js';
23
23
  import { runTestInterferenceGate } from '../../scripts/ci-test-interference-gate.js';
24
24
  import { isGoalDocumentFileName } from '../self-implement/goal-document.js';
@@ -104,7 +104,7 @@ export interface PrLandDeps {
104
104
  runMockModuleRestoreGate?: (out: { log: (message: string) => void; error: (message: string) => void }) => boolean;
105
105
  runModelHardcodeGate?: (out: { log: (message: string) => void; error: (message: string) => void }) => boolean;
106
106
  runDaemonPortGate?: (out: { log: (message: string) => void; error: (message: string) => void }) => boolean;
107
- /** 공개 유출 래칫(경고 전용) — 반환 0 통과 · 1 늘었다 · 2 못 쟀다. */
107
+ /** 공개 유출 래칫(경고 전용) — 반환 0 동일 · 1 늘었다 · 2 못 쟀다 · 3 줄었다. */
108
108
  runPublicLeakGate?: (changedFiles: readonly string[], out: { log: (message: string) => void; error: (message: string) => void }) => number;
109
109
  /** Test seam — the post-transform export leak check on changed files. */
110
110
  runExportLeakCheck?: (changedFiles: readonly string[], cwd: string) => ExportLeakCheck;
@@ -275,8 +275,10 @@ export function runPrLandIsolationGate(
275
275
 
276
276
  /** ⭐ 2026-09-24 — 공개 유출 래칫은 «경고만» 낸다(착지를 막지 않는다 · 막는 것은 공개 결정 뒤 · 채널 합의).
277
277
  * 계기: 기준선 뒤 3시간 만에 🅢 착지분에서 유출 증가 다섯을 이 게이트가 잡았다 — 착지 순간에 보여야 그 자리에서 고친다. */
278
- function runPrLandPublicLeakGate(changedFiles: readonly string[], out: { log: (message: string) => void; error: (message: string) => void }): number {
279
- return runPublicLeakGate({ args: ['--changed-files', ...changedFiles], log: out.log, error: out.log });
278
+ function runPrLandPublicLeakGate(changedFiles: readonly string[], out: { log: (message: string) => void; error: (message: string) => void }, cwd: string, baselineRef: string): number {
279
+ const top = runGitCommand(cwd, ['rev-parse', '--show-toplevel'], { encoding: 'utf-8' });
280
+ if (top.status !== 0 || !String(top.stdout ?? '').trim()) return 2;
281
+ return runPublicLeakGate({ args: ['--changed-files', ...changedFiles], root: String(top.stdout).trim(), baselineRef, log: out.log, error: out.log });
280
282
  }
281
283
 
282
284
  /** The prepare check on this landing's changed files — scripts/ci-public-export-leak-gate.ts. */
@@ -285,23 +287,49 @@ export function runPrLandExportLeakCheck(changedFiles: readonly string[], cwd: s
285
287
  return exportLeakCheck(changedFiles, top.status === 0 && String(top.stdout ?? '').trim() ? String(top.stdout).trim() : cwd);
286
288
  }
287
289
 
288
- /** Blocks the landing when changed files would leak into the public export, unless allowPublicLeak. Returns false to stop. */
290
+ /** Blocks changed public files that leak or cannot be measured. */
289
291
  export function exportLeakBlock(
290
292
  changedFiles: readonly string[] | undefined,
291
293
  check: () => ExportLeakCheck,
292
294
  allow: boolean,
293
295
  out: { log: (message: string) => void; error: (message: string) => void },
296
+ cwd: string = process.cwd(),
294
297
  ): boolean {
295
298
  if (!changedFiles || changedFiles.length === 0) return true;
296
299
  let result: ExportLeakCheck;
297
- try { result = check(); } catch (error) { result = { measured: false, hits: [], detail: error instanceof Error ? error.message : String(error) }; }
298
- record('public-export-leak', result.measured ? result.hits.length === 0 || allow : true, { measured: result.measured, hits: result.hits.length, allowed: allow && result.hits.length > 0 });
299
- if (!result.measured) { out.log(`⚠ public-export-leak: 못 쟀다(${result.detail ?? '?'}) — 착지는 막지 않는다. 확인: bun scripts/public-export.ts --leak-check --files <파일…>`); return true; }
300
- if (result.hits.length === 0) { out.log('✓ public-export-leak: 바뀐 파일이 공개본에 사적 흔적을 싣지 않는다(prepare 와 같은 변환 뒤).'); return true; }
300
+ try { result = check(); } catch { result = { measured: false, hits: [], detail: '검사 실행 실패' }; }
301
+ let publicFiles: string[] = [];
302
+ if (!result.measured) {
303
+ try { publicFiles = publicExportChangedFiles(changedFiles, cwd); }
304
+ catch { publicFiles = [...changedFiles]; } // A missing/invalid manifest cannot prove these files are private.
305
+ }
306
+ const applicable = result.hits.filter((hit) => hit.marker !== 'skill-boundary' || changedFiles.includes(hit.file));
307
+ const missingReason: ExportLeakCheck['hits'][number][] = [];
308
+ const blockedHits: ExportLeakCheck['hits'][number][] = [];
309
+ let allowed = 0;
310
+ for (const hit of applicable) {
311
+ let lines: string[];
312
+ try { lines = readFileSync(join(cwd, hit.file), 'utf8').split(/\r?\n/); }
313
+ catch { blockedHits.push(hit); continue; }
314
+ const notes = [lines[hit.line - 1], lines[hit.line - 2]].filter((line): line is string => line !== undefined)
315
+ .map((line) => /(?:\/\/|\/\*|\*|#|<!--)\s*public-export-allow:\s*(.*)/u.exec(line));
316
+ if (notes.some((note) => note?.[1]?.replace(/(?:\*\/|-->)\s*$/u, '').trim())) { allowed++; continue; }
317
+ blockedHits.push(hit);
318
+ if (notes.some(Boolean)) missingReason.push(hit);
319
+ }
320
+ const blocked = (!result.measured && publicFiles.length > 0) || (blockedHits.length > 0 && !allow);
321
+ record('public-export-leak', !blocked, { measured: result.measured, hits: applicable.length, allowed });
322
+ debug.log('pr.land', 'leak-gate', { blocked, hits: applicable.map(({ file, marker }) => ({ file, marker })), measured: result.measured, allowed });
323
+ if (!result.measured) {
324
+ const write = blocked ? out.error : out.log;
325
+ write(`${blocked ? '✗' : '⚠'} public-export-leak: 못 쟀다${blocked ? ' — 막는다' : ' — 공개 대상 변경 없음'}(${result.detail ?? '?'}) · 확인: bun scripts/public-export.ts --leak-check --json --all --files <파일…>`);
326
+ return !blocked;
327
+ }
328
+ if (blockedHits.length === 0) { out.log('✓ public-export-leak: 바뀐 파일이 공개본에 사적 흔적을 싣지 않는다(prepare 와 같은 변환 뒤).'); return true; }
301
329
  const write = allow ? out.log : out.error;
302
- write(`${allow ? '⚠' : '✗'} public-export-leak: 바뀐 파일 ${result.hits.length}곳이 공개본에 사적 흔적을 싣는다 — 다음 release prepare 가 여기서 실패한다:`);
303
- for (const h of result.hits.slice(0, 20)) write(` ${h.file}:${h.line} ${h.marker}`);
304
- if (result.hits.length > 20) write(` … 외 ${result.hits.length - 20}곳`);
330
+ write(`${allow ? '⚠' : '✗'} public-export-leak: 바뀐 파일 ${blockedHits.length}곳이 공개본에 사적 흔적을 싣는다 — 다음 release prepare 가 여기서 실패한다:`);
331
+ for (const hit of blockedHits.slice(0, 20)) write(` ${hit.file}:${hit.line} · ${hit.marker}${missingReason.includes(hit) ? ' · 사유 없음' : ''}`);
332
+ if (blockedHits.length > 20) write(` … 외 ${blockedHits.length - 20}곳`);
305
333
  write(' 확인: bun scripts/public-export.ts --leak-check --all --files <파일…>');
306
334
  if (allow) { out.log(' --allow-public-leak 로 넘긴다(이유는 --land-reason).'); return true; }
307
335
  out.error(' 고치거나, 공개본과 무관한 것이 확실하면 --allow-public-leak --land-reason "<이유>" 로 넘긴다.');
@@ -322,8 +350,12 @@ export function publicLeakWarning(
322
350
  record('public-leak-gate', true, { warnOnly: true, measured: false });
323
351
  return;
324
352
  }
325
- record('public-leak-gate', true, { warnOnly: true, measured: rc !== 2, grew: rc === 1 });
353
+ record('public-leak-gate', true, { warnOnly: true, measured: rc !== 2, grew: rc === 1, shrank: rc === 3 });
326
354
  if (rc === 0) { out.log('✓ public-leak-gate(경고 전용): 공개 유출이 늘지 않았다.'); return; }
355
+ if (rc === 3) {
356
+ for (const line of captured.filter((l) => /→/.test(l))) out.log(`✓ public-leak-gate(경고 전용): 공개 유출이 줄었다 · 기준선 --update 권장 — ${line.trim()}`);
357
+ return;
358
+ }
327
359
  if (rc === 1) {
328
360
  out.log('⚠ public-leak-gate(경고 전용 · 착지는 막지 않는다): 공개 유출이 늘었다 —');
329
361
  for (const line of captured.filter((l) => /→/.test(l))) out.log(` ${line.trim()}`);
@@ -1031,6 +1063,10 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1031
1063
  out.error('✗ body: --body와 --body-file은 함께 사용할 수 없습니다.');
1032
1064
  return 1;
1033
1065
  }
1066
+ if (opts.allowPublicLeak && !opts.landReason?.trim()) {
1067
+ out.error('✗ public-export-leak: --allow-public-leak 에는 --land-reason "<이유>" 가 필요합니다.');
1068
+ return 1;
1069
+ }
1034
1070
  if (opts.includeActiveRunFiles && opts.excludeActiveRunFiles) {
1035
1071
  out.error('✗ active-run-files: --include-active-run-files와 --exclude-active-run-files는 함께 사용할 수 없습니다.');
1036
1072
  return 1;
@@ -1343,8 +1379,8 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1343
1379
 
1344
1380
  const changedPaths = currentChangePaths(run, cwd, staged, base, out);
1345
1381
  nextMdWarning(body ?? '', changedPaths, out);
1346
- publicLeakWarning(changedPaths, deps.runPublicLeakGate ?? runPrLandPublicLeakGate, out);
1347
- if (!exportLeakBlock(changedPaths, () => (deps.runExportLeakCheck ?? runPrLandExportLeakCheck)(changedPaths ?? [], cwd), opts.allowPublicLeak === true, out)) return 1;
1382
+ publicLeakWarning(changedPaths, deps.runPublicLeakGate ?? ((files, sink) => runPrLandPublicLeakGate(files, sink, cwd, base)), out);
1383
+ if (!exportLeakBlock(changedPaths, () => (deps.runExportLeakCheck ?? runPrLandExportLeakCheck)(changedPaths ?? [], cwd), opts.allowPublicLeak === true, out, cwd)) return 1;
1348
1384
  if (publicDocPaths(changedPaths, () => true).length > 0) {
1349
1385
  const top = run('git', ['rev-parse', '--show-toplevel'], { cwd });
1350
1386
  const docsRoot = top.ok && top.out.trim() ? top.out.trim() : cwd;