elanous 0.2.6 → 0.2.8

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 (517) hide show
  1. package/.env.example +10 -7
  2. package/README.md +4 -0
  3. package/apps/pwa/out/404/index.html +1 -1
  4. package/apps/pwa/out/404.html +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1201-09613bce624467c0.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1377-1efeffbbac0963ff.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1470.98a6ab61ccb4131c.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/{3995-bee512a7063036ce.js → 2375-cb6debea56cce4fb.js} +1 -1
  12. package/apps/pwa/out/_next/static/chunks/2415.ed6428ff334c7ce2.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/2929-617f1e66a55be184.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/2977-e38442e86289f1d3.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/2982-2a2df543be3d2e5a.js +25 -0
  16. package/apps/pwa/out/_next/static/chunks/{8d0d9faf-97887ff99713b84e.js → 2ea96958-e8c7e112de50b067.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/{5329.8b7e4bca684b6eec.js → 3403.4bc97b4066945a94.js} +2 -2
  18. package/apps/pwa/out/_next/static/chunks/3441-a1dd4acfeda14488.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/{7633.0654fe6ea259c1ee.js → 4323.c5dfb6f503304775.js} +1 -1
  22. package/apps/pwa/out/_next/static/chunks/4836-3084c58c1725a40b.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{2984-977cfa339fcd65a5.js → 5080-1613752891fcadb4.js} +3 -3
  24. package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/{763-7d0e1913b5074e98.js → 5791-bb82743fa6299562.js} +1 -1
  26. package/apps/pwa/out/_next/static/chunks/{4240-7153881b0b377306.js → 6062-73e68343a9814f6a.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/6090-85a3f05f954e5697.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/6284-69db415193d5f8bd.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/6320-baac91d68843a9a6.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/6416-505ba707cacafbba.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/7032-f4ef698518fba61c.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/7647.2fcd30d894d5ee30.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/{91ff6dda-3b33d42d20657429.js → 8046cadf-211ca3c0e00f2b72.js} +1 -1
  38. package/apps/pwa/out/_next/static/chunks/8067-d976b441a104ab74.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/8142-744998d65d7bb17e.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/8519-5632377cce994f86.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/8619-4365e03a2862830f.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/8894-7317998f6cb97d8c.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/9454-a3e0953307216c58.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/9651-3cd291a6fa1370d2.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/9740-8f5ff96c522b5f55.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/ae787e4c-f2998de7f1ba72a4.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/app/approvals/page-9aa47b0bc6d570ff.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f4d2ecbbae6088d6.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/app/board/page-2053e49930c82748.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/app/botlab/page-d4b6df905f185055.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/app/bots/page-a70ba27c33003dd0.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/app/chat/page-186fc6952f027acc.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/app/consult/page-18166f885d831d3e.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/app/control/page-1c9d6cfe68b121c2.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/app/design-check/page-cbbe03c0da7b081a.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/app/editor/page-c108ff1fdb665c97.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/app/exec/page-147a328753d983e2.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/app/field/page-799395a9df7d95aa.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/app/intake/page-6a8158b71d1fe9d7.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/app/layout-9567560270857531.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/app/live/page-e7ed3d010153d818.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/app/market/page-c0c0d19d51342d3e.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-2e002ad8faa43291.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/app/morning/page-b672e02e4bec8deb.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/app/not-found-1ba4a5d857276334.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/app/observatory/page-9db2226f38c542fb.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/app/page-70ee65f5f7a151dc.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/app/reflection/page-0bb8e43203efb23b.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-092e1bcf27d751cc.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/app/sessions/page-eb52580c4b75b905.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7464c1987dd76e6d.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/app/settings/page-e573437b0a1c728f.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-294300625e49e4d3.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/app/setup/page-085847b088675978.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/app/share/page-9fe9d38c36999eb4.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/app/showroom/page-d8ab4d1489223459.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/app/tasks/page-6141f67f531d8b6a.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/app/term/page-295a02b1026b8255.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/app/trace/page-1eb9a0e1e054209d.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/app/vault/page-82efa177a30f3741.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d0be51cec4f62606.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/app/workflows/page-2e367075ffdbc062.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/app/workspace/page-647ed2b66c1d49f1.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-ba058c56e38f2792.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/main-app-6870f30ea99f8346.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/{webpack-37b8bf78a3c6eec5.js → webpack-e5bea36f183b25e6.js} +1 -1
  95. package/apps/pwa/out/_next/static/css/5ef72a618a8994f3.css +1 -0
  96. package/apps/pwa/out/_next/static/lywc8m_HDzH9MKSDQhyEj/_buildManifest.js +1 -0
  97. package/apps/pwa/out/approvals/index.html +1 -1
  98. package/apps/pwa/out/approvals/index.txt +22 -22
  99. package/apps/pwa/out/autopilot/index.html +1 -1
  100. package/apps/pwa/out/autopilot/index.txt +22 -22
  101. package/apps/pwa/out/board/index.html +1 -1
  102. package/apps/pwa/out/board/index.txt +22 -22
  103. package/apps/pwa/out/botlab/index.html +1 -1
  104. package/apps/pwa/out/botlab/index.txt +21 -21
  105. package/apps/pwa/out/bots/index.html +1 -1
  106. package/apps/pwa/out/bots/index.txt +21 -21
  107. package/apps/pwa/out/chat/index.html +1 -1
  108. package/apps/pwa/out/chat/index.txt +21 -21
  109. package/apps/pwa/out/consult/index.html +1 -0
  110. package/apps/pwa/out/consult/index.txt +32 -0
  111. package/apps/pwa/out/control/index.html +1 -1
  112. package/apps/pwa/out/control/index.txt +22 -22
  113. package/apps/pwa/out/design-check/index.html +1 -1
  114. package/apps/pwa/out/design-check/index.txt +22 -22
  115. package/apps/pwa/out/editor/index.html +1 -1
  116. package/apps/pwa/out/editor/index.txt +22 -22
  117. package/apps/pwa/out/exec/index.html +1 -0
  118. package/apps/pwa/out/exec/index.txt +32 -0
  119. package/apps/pwa/out/field/index.html +1 -0
  120. package/apps/pwa/out/field/index.txt +32 -0
  121. package/apps/pwa/out/healthz +1 -1
  122. package/apps/pwa/out/index.html +1 -1
  123. package/apps/pwa/out/index.txt +21 -21
  124. package/apps/pwa/out/intake/index.html +1 -1
  125. package/apps/pwa/out/intake/index.txt +22 -22
  126. package/apps/pwa/out/live/index.html +1 -1
  127. package/apps/pwa/out/live/index.txt +22 -22
  128. package/apps/pwa/out/market/index.html +1 -1
  129. package/apps/pwa/out/market/index.txt +21 -21
  130. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  131. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  132. package/apps/pwa/out/morning/index.html +1 -1
  133. package/apps/pwa/out/morning/index.txt +22 -22
  134. package/apps/pwa/out/observatory/index.html +1 -1
  135. package/apps/pwa/out/observatory/index.txt +22 -22
  136. package/apps/pwa/out/reflection/index.html +1 -1
  137. package/apps/pwa/out/reflection/index.txt +22 -22
  138. package/apps/pwa/out/scheduler/index.html +1 -1
  139. package/apps/pwa/out/scheduler/index.txt +22 -22
  140. package/apps/pwa/out/sessions/index.html +1 -1
  141. package/apps/pwa/out/sessions/index.txt +21 -21
  142. package/apps/pwa/out/settings/devices/index.html +1 -1
  143. package/apps/pwa/out/settings/devices/index.txt +22 -22
  144. package/apps/pwa/out/settings/index.html +1 -1
  145. package/apps/pwa/out/settings/index.txt +22 -22
  146. package/apps/pwa/out/setup/done/index.html +1 -1
  147. package/apps/pwa/out/setup/done/index.txt +22 -22
  148. package/apps/pwa/out/setup/index.html +1 -1
  149. package/apps/pwa/out/setup/index.txt +22 -22
  150. package/apps/pwa/out/share/index.html +1 -1
  151. package/apps/pwa/out/share/index.txt +22 -22
  152. package/apps/pwa/out/showroom/index.html +1 -1
  153. package/apps/pwa/out/showroom/index.txt +21 -21
  154. package/apps/pwa/out/tasks/index.html +1 -1
  155. package/apps/pwa/out/tasks/index.txt +22 -22
  156. package/apps/pwa/out/term/index.html +1 -1
  157. package/apps/pwa/out/term/index.txt +22 -22
  158. package/apps/pwa/out/trace/index.html +1 -1
  159. package/apps/pwa/out/trace/index.txt +22 -22
  160. package/apps/pwa/out/vault/index.html +1 -1
  161. package/apps/pwa/out/vault/index.txt +22 -22
  162. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  163. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  164. package/apps/pwa/out/workflows/index.html +1 -1
  165. package/apps/pwa/out/workflows/index.txt +22 -22
  166. package/apps/pwa/out/workspace/index.html +1 -1
  167. package/apps/pwa/out/workspace/index.txt +22 -22
  168. package/apps/pwa/out/worktrees/index.html +1 -1
  169. package/apps/pwa/out/worktrees/index.txt +22 -22
  170. package/bin/elanous.cjs +107 -0
  171. package/graphs/field/field-feed.yaml +24 -0
  172. package/graphs/field/recipes.yaml +12 -0
  173. package/graphs/landing/landing-heal.yaml +3 -1
  174. package/graphs/landing/recipes.yaml +3 -0
  175. package/graphs/release/recipes.yaml +10 -0
  176. package/graphs/release/release-loop.yaml +10 -3
  177. package/graphs/test-diet/recipes.yaml +9 -0
  178. package/graphs/test-diet/test-diet.yaml +22 -0
  179. package/package.json +6 -5
  180. package/persona-presets/_index.yaml +10 -0
  181. package/persona-presets/_schema.json +146 -0
  182. package/persona-presets/dana.yaml +26 -0
  183. package/persona-presets/haru.yaml +27 -0
  184. package/persona-presets/kai.yaml +27 -0
  185. package/persona-presets/leo.yaml +27 -0
  186. package/persona-presets/mira.yaml +30 -0
  187. package/persona-presets/nari.yaml +27 -0
  188. package/persona-presets/sora.yaml +27 -0
  189. package/persona-presets/yuna.yaml +27 -0
  190. package/plugins/card-followup/README.md +13 -4
  191. package/plugins/card-followup/graphs/card-followup.yaml +3 -1
  192. package/plugins/card-followup/graphs/recipes.yaml +5 -1
  193. package/plugins/card-followup/graphs/run-step.ts +122 -18
  194. package/plugins/card-followup/graphs/sales-strategy.ts +173 -0
  195. package/plugins/card-followup/plugin.json +1 -1
  196. package/plugins/doc-draft/README.md +13 -0
  197. package/plugins/doc-draft/examples/brief-sample.json +8 -0
  198. package/plugins/doc-draft/graphs/doc-draft.yaml +14 -0
  199. package/plugins/doc-draft/graphs/recipes.yaml +9 -0
  200. package/plugins/doc-draft/graphs/run-step.ts +113 -0
  201. package/plugins/doc-draft/plugin.json +24 -0
  202. package/plugins/geo-check/README.md +3 -1
  203. package/plugins/geo-check/graphs/run-step.ts +58 -13
  204. package/plugins/geo-check/plugin.json +1 -1
  205. package/plugins/job-coach/.codex-plugin/plugin.json +1 -1
  206. package/plugins/job-coach/README.md +1 -1
  207. package/plugins/job-coach/graphs/run-step.ts +2 -2
  208. package/plugins/job-coach/plugin.json +1 -1
  209. package/plugins/job-coach/plugin.ts +1 -1
  210. package/scripts/affinity/endcard.sh +3 -2
  211. package/scripts/affinity/reframe.sh +3 -1
  212. package/scripts/ci-public-export-leak-gate.ts +48 -0
  213. package/scripts/codex-quota-alert.ts +122 -258
  214. package/scripts/coord-tracks.json +4 -4
  215. package/scripts/field-feed/deliver-node.ts +57 -0
  216. package/scripts/field-feed/feed-node.ts +67 -0
  217. package/scripts/field-feed/lib.ts +164 -0
  218. package/scripts/field-feed/reel-node.ts +24 -0
  219. package/scripts/field-feed/start.ts +62 -0
  220. package/scripts/fixtures/vflow-sample.ndjson +6 -0
  221. package/scripts/install.sh +109 -21
  222. package/scripts/landing-heal/clean-checkout.ts +114 -0
  223. package/scripts/landing-heal/run-mission.ts +38 -3
  224. package/scripts/lib/pwa-scenarios/scenarios.ts +2 -1
  225. package/scripts/persona-presets/lint.ts +79 -0
  226. package/scripts/public-export.ts +8 -4
  227. package/scripts/release-loop/baseline-from-logs.ts +92 -0
  228. package/scripts/release-loop/checklist-gate-node.ts +2 -2
  229. package/scripts/release-loop/env-known-failures.ts +31 -0
  230. package/scripts/release-loop/gate-node.ts +108 -22
  231. package/scripts/release-loop/known-issues-node.ts +159 -0
  232. package/scripts/release-loop/npm-publish-node.ts +124 -0
  233. package/scripts/release-loop/ops-upgrade-node.ts +95 -0
  234. package/scripts/release-loop/publish-node.ts +23 -1
  235. package/scripts/release-loop/release-readiness.ts +58 -0
  236. package/scripts/release-loop/shard-plan.ts +17 -0
  237. package/scripts/release-loop/unattended-release.ts +93 -0
  238. package/scripts/storyboard/storyboard.ts +167 -0
  239. package/scripts/test-diet/lib.ts +88 -0
  240. package/scripts/test-diet/node.ts +102 -0
  241. package/scripts/ux/measure-first-text.ts +102 -0
  242. package/scripts/vflow-collect.ts +20 -7
  243. package/scripts/vflow-search.ts +73 -0
  244. package/scripts/video-free-line-test-walker.ts +36 -0
  245. package/scripts/video-pipeline.ts +2 -2
  246. package/skills/explainer-video/SKILL.md +12 -9
  247. package/skills/explainer-video/engine/build.mjs +1 -1
  248. package/skills/explainer-video/engine/reel.mjs +138 -31
  249. package/skills/explainer-video/engine/reel.sh +2 -1
  250. package/skills/explainer-video/examples/elanous-0.2.5/script.json +1 -1
  251. package/skills/grill-me/SKILL.md +1 -1
  252. package/skills/omni-digest/docs/diagrams/noncode-terminal-promotion-path-2026-08-13.mmd +1 -1
  253. package/src/a2a/server.ts +2 -0
  254. package/src/acp/auth-methods.ts +30 -0
  255. package/src/acp/elanous-aware-peers.ts +30 -0
  256. package/src/acp/server.ts +96 -20
  257. package/src/agent/monad-agent-turn.ts +25 -6
  258. package/src/agent/shared-app-tools.ts +5 -3
  259. package/src/agent-substrate/review-intent.ts +6 -2
  260. package/src/agent-substrate/shard-boundary-intent.ts +70 -0
  261. package/src/auth/github-app-token.ts +4 -1
  262. package/src/autopilot/track-agent-shadow.ts +151 -0
  263. package/src/autopilot/track-agent.ts +23 -3
  264. package/src/boot/acp-server-help.ts +16 -0
  265. package/src/boot/daemon-prompt-turn.ts +31 -10
  266. package/src/boot/daemon-tools/index.ts +7 -1
  267. package/src/budget/codex-credit-pace.ts +84 -0
  268. package/src/budget/codex-credit-plan.ts +154 -0
  269. package/src/budget/codex-reset-credit-state.ts +2 -0
  270. package/src/channel-import/detect.ts +191 -0
  271. package/src/channel-import/run.ts +111 -0
  272. package/src/chat/chat-cli.ts +4 -1
  273. package/src/chat/short-question.ts +40 -0
  274. package/src/cli/agent-cli.ts +24 -15
  275. package/src/cli/ask-bare.ts +42 -0
  276. package/src/cli/cli-user-error.ts +25 -0
  277. package/src/cli/codex-credit-plan-view.ts +25 -0
  278. package/src/cli/config-test-sync.ts +4 -0
  279. package/src/cli/decisions-cli.ts +13 -3
  280. package/src/cli/dependence-gauge.ts +237 -0
  281. package/src/cli/doctor-bundle.ts +128 -0
  282. package/src/cli/doctor-cli.ts +41 -1
  283. package/src/cli/doctor-local-llm.ts +95 -0
  284. package/src/cli/doctor-modes.ts +48 -0
  285. package/src/cli/import-cli.ts +60 -0
  286. package/src/cli/intake-cli.ts +12 -2
  287. package/src/cli/intake-source-cli.ts +58 -0
  288. package/src/cli/machine-cli.ts +23 -0
  289. package/src/cli/mcp-login.ts +13 -4
  290. package/src/cli/msg-cli.ts +137 -0
  291. package/src/cli/persona-cli.ts +116 -0
  292. package/src/cli/plugin-cli.ts +25 -0
  293. package/src/cli/pr-cli.ts +36 -0
  294. package/src/cli/provider-cli.ts +5 -0
  295. package/src/cli/release-cli.ts +50 -8
  296. package/src/cli/release-run-if-ready.ts +48 -0
  297. package/src/cli/setup-cli.ts +27 -6
  298. package/src/cli/setup-recommend.ts +8 -0
  299. package/src/cli/skills-cli.ts +173 -0
  300. package/src/cli/start-cli.ts +13 -4
  301. package/src/cli/usage-cli.ts +11 -1
  302. package/src/codex/setup.ts +37 -16
  303. package/src/dashboard/index.ts +18 -2
  304. package/src/dashboard/slash-runtime/dashboard-handlers.ts +2 -2
  305. package/src/dashboard/slash-runtime/help-from-registry.ts +4 -2
  306. package/src/decisions/decision-cards.ts +291 -0
  307. package/src/decisions/decision-ledger.ts +5 -2
  308. package/src/decisions/discord-decision-cards.ts +133 -0
  309. package/src/decisions/telegram-decision-cards.ts +100 -0
  310. package/src/directives/version-at.ts +77 -0
  311. package/src/discord.ts +73 -6
  312. package/src/domains/core-tools.ts +37 -14
  313. package/src/domains/outbound-alert.ts +94 -12
  314. package/src/domains/repeated-failure.ts +1 -1
  315. package/src/error-report/report.ts +200 -0
  316. package/src/exec-requests/planner.ts +146 -0
  317. package/src/exec-requests/runner.ts +378 -0
  318. package/src/exec-requests/store.ts +78 -0
  319. package/src/field/field-feed-auto.ts +48 -0
  320. package/src/field/field-media.ts +8 -3
  321. package/src/field/field-reel.ts +203 -0
  322. package/src/grok/credential.ts +7 -5
  323. package/src/harness/aside-run-status.ts +33 -0
  324. package/src/harness/browser-verify.ts +48 -17
  325. package/src/harness/harness-cli-command.ts +25 -3
  326. package/src/harness/image-load-state.ts +21 -0
  327. package/src/harness/process-garbage.ts +45 -0
  328. package/src/hooks/error-report.ts +210 -0
  329. package/src/hooks/receiver.ts +41 -1
  330. package/src/import/apply.ts +128 -0
  331. package/src/import/plan.ts +197 -0
  332. package/src/index.ts +168 -21
  333. package/src/input-core/text-entry.ts +13 -5
  334. package/src/instance/leader.ts +13 -1
  335. package/src/intake-plane/collect-github.ts +5 -3
  336. package/src/intake-plane/collect-telegram-saved.ts +15 -3
  337. package/src/intake-plane/discord-seat-work.ts +56 -0
  338. package/src/intake-plane/intake-sources.ts +202 -0
  339. package/src/intake-plane/items.ts +28 -12
  340. package/src/intake-plane/seat-answer.ts +96 -0
  341. package/src/intake-plane/seat-doc-route.ts +221 -0
  342. package/src/intake-plane/submit-intake-work.ts +9 -1
  343. package/src/intake-plane/telegram-seat-work.ts +72 -0
  344. package/src/llm/model-defaults.ts +24 -1
  345. package/src/llm.ts +5 -4
  346. package/src/machines/machine-ledger.ts +127 -0
  347. package/src/market/pack-internal-refs.ts +28 -0
  348. package/src/market/publish.ts +31 -4
  349. package/src/maturity/feature-maturity.ts +65 -0
  350. package/src/model-tier/turn-tier.ts +24 -0
  351. package/src/msg/msg-store.ts +149 -0
  352. package/src/native-tool-catalog.ts +2 -1
  353. package/src/nexus/api/chat-fast-path-config.ts +28 -0
  354. package/src/nexus/api/consult-requests.ts +128 -0
  355. package/src/nexus/api/discord-trigger-bot.ts +3 -0
  356. package/src/nexus/api/error-reports.ts +108 -0
  357. package/src/nexus/api/exec-requests.ts +51 -0
  358. package/src/nexus/api/field-uploads.ts +40 -3
  359. package/src/nexus/api/graph-approvals-feed.ts +140 -0
  360. package/src/nexus/api/graph-approvals.ts +71 -4
  361. package/src/nexus/api/http-server.ts +82 -8
  362. package/src/nexus/api/outbound-report.ts +7 -0
  363. package/src/nexus/api/running-runs-background.ts +68 -0
  364. package/src/nexus/api/running-runs-child.ts +6 -0
  365. package/src/nexus/api/seat-requests.ts +254 -0
  366. package/src/nexus/api/share-captures.ts +91 -0
  367. package/src/nexus/api/skill-problems.ts +56 -0
  368. package/src/nexus/api/terminals.ts +24 -8
  369. package/src/nexus/api/trace-run-scan.ts +37 -0
  370. package/src/nexus/api/trace.ts +19 -3
  371. package/src/nexus/index.ts +28 -1
  372. package/src/nexus/setup-status.ts +11 -7
  373. package/src/notify/llm-budget-alert.ts +16 -10
  374. package/src/oauth/browser-availability.ts +14 -0
  375. package/src/oauth/codex-account-rotation.ts +26 -4
  376. package/src/oauth/codex-account-store.ts +20 -2
  377. package/src/oauth/codex-browser-login.ts +173 -0
  378. package/src/oauth/codex-quota-policy.ts +16 -0
  379. package/src/oauth/codex.ts +4 -1
  380. package/src/oauth/fallback-chain.ts +5 -5
  381. package/src/oauth/store.ts +42 -5
  382. package/src/onboarding/continue-here.ts +34 -0
  383. package/src/onboarding/entry-hints.ts +8 -0
  384. package/src/onboarding/full-screen-io.ts +35 -3
  385. package/src/onboarding/help/skills.md +1 -1
  386. package/src/onboarding/non-interactive.ts +1 -0
  387. package/src/onboarding/subscription-hint.ts +27 -0
  388. package/src/onboarding/web-first.ts +90 -0
  389. package/src/onboarding.ts +287 -26
  390. package/src/persona/presets.ts +105 -0
  391. package/src/plugins/maker/node-install.ts +92 -0
  392. package/src/plugins/maker/node-maker.ts +139 -0
  393. package/src/plugins/maker/plugin-maker.ts +19 -7
  394. package/src/policy/llm-policy.ts +268 -0
  395. package/src/prompt-library/session-guidance.ts +7 -1
  396. package/src/prompt-library/universal-preamble.ts +2 -2
  397. package/src/relay/relay-cli.ts +20 -0
  398. package/src/relay/relay-server.ts +220 -0
  399. package/src/release-loop/checklist.ts +37 -13
  400. package/src/self-dev/decompose.ts +1 -0
  401. package/src/self-dev/dev-pipeline.ts +6 -3
  402. package/src/self-dev/orchestrate.ts +18 -11
  403. package/src/self-dev/run-record-mirror.ts +44 -0
  404. package/src/self-dev/run-store.ts +12 -3
  405. package/src/self-implement/harness-policy-gates.ts +4 -1
  406. package/src/self-implement/report-origin.ts +12 -1
  407. package/src/session/chat.ts +17 -5
  408. package/src/shell-env-bootstrap.ts +44 -7
  409. package/src/skills/connect-claude-plugin.ts +142 -0
  410. package/src/skills/connect.ts +70 -0
  411. package/src/skills/index.ts +29 -1
  412. package/src/skills/repair.ts +124 -0
  413. package/src/skills/runner.ts +11 -2
  414. package/src/skills/shared-agent-skill-roots.ts +25 -0
  415. package/src/skills/trigger-extract.ts +1 -1
  416. package/src/steward/failure-streak.ts +78 -0
  417. package/src/steward/steward-cards.ts +24 -0
  418. package/src/steward/triage-budget.ts +127 -0
  419. package/src/steward/triage-plan.ts +75 -0
  420. package/src/steward/triage.ts +244 -42
  421. package/src/task-cards/card-store.ts +1 -1
  422. package/src/task-orchestrator/surfaces/pod-command-job.ts +16 -8
  423. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +11 -5
  424. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +68 -0
  425. package/src/task-orchestrator/surfaces/self-implement-pod.ts +78 -4
  426. package/src/telegram-commands.ts +13 -0
  427. package/src/telegram.ts +72 -2
  428. package/src/tool-runtime/elanous-skills-list-runtime.ts +3 -3
  429. package/src/tool-runtime/self-cognition-runtimes.ts +160 -2
  430. package/src/user-config.ts +189 -15
  431. package/src/version/packed-revision.json +1 -1
  432. package/src/video-pipeline/recipes/character.ts +42 -5
  433. package/src/video-pipeline/recipes/ffmpeg.ts +1 -1
  434. package/src/video-pipeline/recipes/free-line.ts +16 -3
  435. package/src/video-pipeline/recipes/remote.ts +7 -1
  436. package/src/video-pipeline/vflow-reference.ts +109 -0
  437. package/apps/pwa/out/_next/static/chunks/1169-696263ac7af8c4d4.js +0 -1
  438. package/apps/pwa/out/_next/static/chunks/1883.c91a2648af4842fd.js +0 -1
  439. package/apps/pwa/out/_next/static/chunks/1947-9d64872eeb9cfdec.js +0 -1
  440. package/apps/pwa/out/_next/static/chunks/2808-dc06482994b40f70.js +0 -1
  441. package/apps/pwa/out/_next/static/chunks/3165-95515ca5f299a120.js +0 -1
  442. package/apps/pwa/out/_next/static/chunks/3190-e9282753e7ebde85.js +0 -1
  443. package/apps/pwa/out/_next/static/chunks/4259-99614149577e77cb.js +0 -1
  444. package/apps/pwa/out/_next/static/chunks/4283-329eabeaf233e6cd.js +0 -1
  445. package/apps/pwa/out/_next/static/chunks/4328-cb5058b1acc2de5e.js +0 -25
  446. package/apps/pwa/out/_next/static/chunks/4801-ecee6ef62b349b18.js +0 -1
  447. package/apps/pwa/out/_next/static/chunks/5110-8058791dd25a2e14.js +0 -1
  448. package/apps/pwa/out/_next/static/chunks/5330-c41e9670f594c38f.js +0 -1
  449. package/apps/pwa/out/_next/static/chunks/5423-e95fd125d1794349.js +0 -1
  450. package/apps/pwa/out/_next/static/chunks/5478-b5eae07dc79ea619.js +0 -1
  451. package/apps/pwa/out/_next/static/chunks/5787-96ee6642b9a661e5.js +0 -1
  452. package/apps/pwa/out/_next/static/chunks/6448-79d72368589f98bc.js +0 -1
  453. package/apps/pwa/out/_next/static/chunks/6522-9866c002b5531836.js +0 -1
  454. package/apps/pwa/out/_next/static/chunks/6729-b4a558b7aa891e0c.js +0 -1
  455. package/apps/pwa/out/_next/static/chunks/6969-cb03f9410b7d2e03.js +0 -1
  456. package/apps/pwa/out/_next/static/chunks/7007-3b9861091bb8dd21.js +0 -1
  457. package/apps/pwa/out/_next/static/chunks/7930-8dc7e20fc6fc19ca.js +0 -1
  458. package/apps/pwa/out/_next/static/chunks/8071-187edbc22a86741f.js +0 -1
  459. package/apps/pwa/out/_next/static/chunks/8198-d4101ad70cb9a579.js +0 -1
  460. package/apps/pwa/out/_next/static/chunks/8250.4a2c5553a07cdf47.js +0 -1
  461. package/apps/pwa/out/_next/static/chunks/8293-123b91e7b0330dc0.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/8296-d6d5d87dfa911d41.js +0 -1
  463. package/apps/pwa/out/_next/static/chunks/8305-603963c33ee8eec3.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/8612-4a0066f20951b8fd.js +0 -1
  465. package/apps/pwa/out/_next/static/chunks/9181-cf4e1b61c4783f92.js +0 -1
  466. package/apps/pwa/out/_next/static/chunks/9262-26c2ecbd5a67e4a2.js +0 -1
  467. package/apps/pwa/out/_next/static/chunks/9328-45abdebce4fbecb7.js +0 -1
  468. package/apps/pwa/out/_next/static/chunks/9355-dbc67205adf8745f.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/9763.255b90dd69875689.js +0 -1
  470. package/apps/pwa/out/_next/static/chunks/9933-66d31ec25c0231af.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-bd06fb55f4da0381.js +0 -1
  472. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4e586142da455a25.js +0 -1
  473. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-889ad5cddcf45b0d.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/app/board/page-47ba401d56572c27.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/app/botlab/page-0b54f9c83458e038.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/app/bots/page-4fcc296ef6c8ed90.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/app/chat/page-fe9fda494a87f4e5.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/app/control/page-f9642e25ce129590.js +0 -1
  479. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e1063e8ba5f3e2e7.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/app/editor/page-9d0df30027d8aa9d.js +0 -1
  481. package/apps/pwa/out/_next/static/chunks/app/healthz/route-bd06fb55f4da0381.js +0 -1
  482. package/apps/pwa/out/_next/static/chunks/app/intake/page-d97adf2c9455b8d0.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/app/layout-236b80d202110362.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/app/live/page-21a30f35f1a276ad.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/app/market/page-b1a5be357c4fa25d.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1705a60303f7f573.js +0 -1
  487. package/apps/pwa/out/_next/static/chunks/app/morning/page-76b337c11ad0e237.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/app/not-found-7c0f85fbb56f64c6.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/app/observatory/page-65ca16b20617b44d.js +0 -1
  490. package/apps/pwa/out/_next/static/chunks/app/page-e7f9b8fc29411c1d.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/app/reflection/page-92ea6213d1aeec04.js +0 -1
  492. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-a913a005aacb5476.js +0 -1
  493. package/apps/pwa/out/_next/static/chunks/app/sessions/page-2d78804a40dfdef6.js +0 -1
  494. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-08a99148e780ac00.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/app/settings/page-deb674e7ed36f815.js +0 -1
  496. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-49f8de0534d192d7.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/app/setup/layout-bd06fb55f4da0381.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/app/setup/page-ba162a28d2176e18.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/app/share/page-1ff1a37b550ab41a.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/app/showroom/page-ccaa698f56c0fbdb.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/app/tasks/page-53b944082de1d7db.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/app/term/page-9b70adf1552789bf.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/app/trace/page-30d482aa63241fe8.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/app/vault/page-aecf786f54651d8a.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6ab9b62c7b6e08f2.js +0 -1
  506. package/apps/pwa/out/_next/static/chunks/app/workflows/page-08949735455e0c9a.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/app/workspace/page-a1479005234a46c2.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c3890e90bd232732.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/beb5cf10-9adcc10b83930090.js +0 -1
  510. package/apps/pwa/out/_next/static/chunks/framework-d68d41c88e05c801.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/main-app-11c63971b7a9593b.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/main-d09452353bd0d9cc.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/pages/_app-184d727cebeca767.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/pages/_error-21bbbbac99b720b1.js +0 -1
  515. package/apps/pwa/out/_next/static/css/eaa74e8bb2f62269.css +0 -1
  516. package/apps/pwa/out/_next/static/qMI0jnlZaBjjm4aIDYNGM/_buildManifest.js +0 -1
  517. /package/apps/pwa/out/_next/static/{qMI0jnlZaBjjm4aIDYNGM → lywc8m_HDzH9MKSDQhyEj}/_ssgManifest.js +0 -0
@@ -0,0 +1,173 @@
1
+ // SK2 — `elanous skills repair`: 색인이 못 읽은 스킬을 보여 주고, 확인([y/N])한 것만 그 자리에서 고친다.
2
+ import type { Command } from 'commander';
3
+ import { createInterface } from 'node:readline/promises';
4
+ import { getSkillIndex, resetSkillIndex, skillIndexProblems } from '../skills/index.js';
5
+ import { applySkillRepair, planSkillRepair, skillRepairNotice } from '../skills/repair.js';
6
+ import { CONNECT_AGENTS, connectPrompt, connectSkillRoot, planConnect, withConnectedSource, withoutSources, type ConnectAgent } from '../skills/connect.js';
7
+ import { debug } from '../debug/log.js';
8
+ import { resolve } from 'node:path';
9
+ import { claudePluginPrompt, isClaudePluginDir, mcpEnableHint, planClaudePlugin, readClaudePlugin } from '../skills/connect-claude-plugin.js';
10
+
11
+ async function ask(question: string, defaultYes = false): Promise<boolean> {
12
+ if (!process.stdin.isTTY) return false;
13
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
14
+ try {
15
+ const answer = (await rl.question(question)).trim();
16
+ return answer === '' ? defaultYes : /^(y|yes|예|네)$/i.test(answer);
17
+ }
18
+ finally { rl.close(); }
19
+ }
20
+
21
+ /** EN9 — `elanous connect <claude|codex>`: find the skills that agent already uses and register their folder (no copy). */
22
+ export function registerConnectCommand(program: Command): void {
23
+ program.command('connect <agent>')
24
+ .description(`Use the skills you already have in another agent (${CONNECT_AGENTS.join(' | ')}) or a Claude Code plugin folder — registers in place, never copies; plugin MCP servers are added switched off`)
25
+ .option('--yes', 'Register without asking')
26
+ .option('--json', 'Print the plan as JSON and change nothing')
27
+ .option('--undo', 'Stop using that folder (the files stay where they are)')
28
+ .action(async (agentArg: string, opts: { yes?: boolean; json?: boolean; undo?: boolean }) => {
29
+ const agent = agentArg.toLowerCase() as ConnectAgent;
30
+ if (!CONNECT_AGENTS.includes(agent) && isClaudePluginDir(resolve(agentArg))) {
31
+ await connectClaudePlugin(resolve(agentArg), opts);
32
+ return;
33
+ }
34
+ if (!CONNECT_AGENTS.includes(agent)) {
35
+ console.error(`지원하는 에이전트: ${CONNECT_AGENTS.join(', ')} · 또는 Claude 플러그인 폴더(.claude-plugin/plugin.json) (받은 값: ${agentArg})`);
36
+ process.exitCode = 2;
37
+ return;
38
+ }
39
+ const { defaultSkillDirs, getUserConfig, saveUserConfig } = await import('../user-config.js');
40
+ const cfg = getUserConfig();
41
+ if (opts.undo) {
42
+ const root = connectSkillRoot(agent);
43
+ const sources = withoutSources(cfg.skills.sources, [root]);
44
+ if (sources.length === (cfg.skills.sources ?? []).length) { console.log(`연결된 적이 없습니다(${root}).`); return; }
45
+ saveUserConfig({ ...cfg, skills: { ...cfg.skills, sources } });
46
+ resetSkillIndex();
47
+ debug.log('skills.connect', 'undone', { agent });
48
+ console.log(`연결을 끊었습니다. 파일은 그대로 있습니다(${root}).`);
49
+ return;
50
+ }
51
+ const plan = planConnect(agent, defaultSkillDirs(cfg));
52
+ debug.log('skills.connect', 'plan', { agent, state: plan.state, count: 'skills' in plan ? plan.skills.length : 0 });
53
+ if (opts.json) { console.log(JSON.stringify(plan, null, 2)); return; }
54
+ const prompt = connectPrompt(plan);
55
+ if (plan.state !== 'new') { console.log(prompt); return; }
56
+ if (!opts.yes) {
57
+ if (!process.stdin.isTTY) { console.log(`${prompt.split('\n')[0]}\n가져오려면: elanous connect ${agent} --yes`); return; }
58
+ if (!(await ask(prompt, true))) { console.log('가져오지 않았습니다. 나중에: elanous connect ' + agent); return; }
59
+ } else {
60
+ console.log(prompt.split('\n')[0]);
61
+ }
62
+ const next = { ...cfg, skills: { ...cfg.skills, sources: withConnectedSource(cfg.skills.sources, plan.root, agent) } };
63
+ saveUserConfig(next);
64
+ resetSkillIndex();
65
+ const index = getSkillIndex(defaultSkillDirs(next));
66
+ const problems = skillIndexProblems().filter((p) => p.dir === plan.root);
67
+ const usable = plan.skills.length - problems.length;
68
+ debug.log('skills.connect', 'registered', { agent, found: plan.skills.length, problems: problems.length, indexed: index.length });
69
+ console.log(`연결했습니다 — ${usable}개를 바로 쓸 수 있습니다. 끊으려면: elanous connect ${agent} --undo`);
70
+ const notice = skillRepairNotice(problems);
71
+ if (notice) console.log(notice);
72
+ });
73
+ }
74
+
75
+ export function registerSkillsCommands(program: Command): void {
76
+ const skills = program.command('skills').description('Check and repair installed skills');
77
+ skills.command('sources')
78
+ .description('List every skill folder elanous reads, in order (preset · shared · connected · package)')
79
+ .option('--json', 'JSON output')
80
+ .action(async (opts: { json?: boolean }) => {
81
+ const { resolveSkillSources } = await import('../user-config.js');
82
+ const { existsSync } = await import('node:fs');
83
+ const sources = resolveSkillSources().map((source) => ({ ...source, exists: existsSync(source.path) }));
84
+ debug.log('skills.sources', 'listed', { count: sources.length, kinds: sources.map((source) => source.kind) });
85
+ if (opts.json) { console.log(JSON.stringify(sources, null, 2)); return; }
86
+ const width = Math.max(10, ...sources.map((source) => source.id.length));
87
+ for (const source of sources) {
88
+ console.log(`${source.enabled ? '●' : '○'} ${source.id.padEnd(width)} ${source.kind.padEnd(9)} ${source.path}${source.exists ? '' : ' (없음)'}`);
89
+ }
90
+ console.log('묶음 스킬(패키지 skills/)은 늘 마지막에 읽습니다. 다른 에이전트 스킬 더하기: elanous connect claude|codex|<플러그인 폴더>');
91
+ });
92
+ skills.command('repair')
93
+ .description('List skills that could not be read and repair the ones that can be fixed (asks first)')
94
+ .option('--yes', 'Repair every fixable skill without asking')
95
+ .action(async (opts: { yes?: boolean }) => {
96
+ getSkillIndex();
97
+ const problems = skillIndexProblems();
98
+ if (!problems.length) { console.log('모든 스킬을 읽었습니다. 고칠 것이 없습니다.'); return; }
99
+ console.log(`스킬 ${problems.length}개를 읽지 못했습니다.`);
100
+ // ER1 — operations hears about it too (consented · scrubbed).
101
+ try {
102
+ const { reportError } = await import('../error-report/report.js');
103
+ for (const p of problems.slice(0, 3)) await reportError({ code: 'skill-index', message: `${p.name}: ${p.code ?? ''} ${p.error}`.trim(), surface: 'cli' });
104
+ } catch { /* reporting is advisory */ }
105
+ let fixed = 0;
106
+ for (const problem of problems) {
107
+ const plan = planSkillRepair(problem);
108
+ console.log(`\n· ${problem.name} — ${problem.error.split('\n')[0]}`);
109
+ if (plan.kind === 'permission' || plan.kind === 'manual') { console.log(` ${plan.hint}`); continue; }
110
+ const what = plan.kind === 'fixable-permission' ? '읽기 권한을 켭니다' : `${plan.keys.join(', ')} 를 한 줄로 고칩니다(원본은 .bak 으로 남김)`;
111
+ if (!opts.yes && !(await ask(` ${what}. 고칠까요? [y/N] `))) { console.log(' 건너뜀'); continue; }
112
+ const result = applySkillRepair(plan);
113
+ if (result.ok) { fixed += 1; console.log(` 고쳤습니다 — ${result.path}`); }
114
+ else console.log(` 고치지 못했습니다(${result.reason}) — 원래대로 되돌렸습니다.`);
115
+ }
116
+ console.log(`\n${fixed}개를 고쳤습니다.`);
117
+ if (fixed < problems.length) process.exitCode = 1;
118
+ });
119
+ }
120
+
121
+ /** EN8 — a Claude Code plugin folder: skills join `skills.sources[]` (kind connected) in place, `.mcp.json` servers join `mcp.servers[]` switched off. */
122
+ async function connectClaudePlugin(dir: string, opts: { yes?: boolean; json?: boolean; undo?: boolean }): Promise<void> {
123
+ const { defaultSkillDirs, getUserConfig, saveUserConfig } = await import('../user-config.js');
124
+ const cfg = getUserConfig();
125
+ let plugin;
126
+ try { plugin = readClaudePlugin(dir); }
127
+ catch (error) {
128
+ console.error(`플러그인 정보를 읽지 못했습니다(.claude-plugin/plugin.json): ${error instanceof Error ? error.message : String(error)}`);
129
+ process.exitCode = 1;
130
+ return;
131
+ }
132
+ const rawMcp = (cfg.raw.mcp && typeof cfg.raw.mcp === 'object' && !Array.isArray(cfg.raw.mcp) ? cfg.raw.mcp : {}) as Record<string, unknown>;
133
+ const rawServers = (Array.isArray(rawMcp.servers) ? rawMcp.servers : []) as Array<Record<string, unknown>>;
134
+ const writeServers = (servers: Array<Record<string, unknown>>) => ({ ...cfg.raw, mcp: { ...rawMcp, servers } });
135
+ if (opts.undo) {
136
+ const ids = new Set(plugin.mcp.map((server) => server.id));
137
+ const sources = withoutSources(cfg.skills.sources, plugin.skillRoots);
138
+ const servers = rawServers.filter((row) => !ids.has(row.id as string));
139
+ if (sources.length === (cfg.skills.sources ?? []).length && servers.length === rawServers.length) { console.log(`연결된 적이 없습니다(${plugin.name}).`); return; }
140
+ saveUserConfig({ ...cfg, raw: writeServers(servers), skills: { ...cfg.skills, sources } });
141
+ resetSkillIndex();
142
+ debug.log('skills.connect', 'undone', { plugin: plugin.name });
143
+ console.log(`«${plugin.name}» 연결을 끊었습니다. 파일은 그대로 있습니다(${plugin.root}).`);
144
+ return;
145
+ }
146
+ const plan = planClaudePlugin(plugin, defaultSkillDirs(cfg), rawServers.map((row) => row.id as string));
147
+ debug.log('skills.connect', 'plan', { plugin: plugin.name, state: plan.state, skills: plugin.skills.length, mcp: plugin.mcp.length, skipped: plugin.skipped.length });
148
+ if (opts.json) { console.log(JSON.stringify(plan, null, 2)); return; }
149
+ const prompt = claudePluginPrompt(plan);
150
+ if (plan.state !== 'new') { console.log(prompt); return; }
151
+ const firstLines = prompt.slice(0, prompt.lastIndexOf('\n'));
152
+ if (!opts.yes) {
153
+ if (!process.stdin.isTTY) { console.log(`${firstLines}\n가져오려면: elanous connect ${plugin.root} --yes`); return; }
154
+ if (!(await ask(prompt, true))) { console.log(`가져오지 않았습니다. 나중에: elanous connect ${plugin.root}`); return; }
155
+ } else {
156
+ console.log(firstLines);
157
+ }
158
+ const sources = plan.newSkillRoots.reduce((list, root, i) => withConnectedSource(list, root, `plugin:${plugin.name}${i ? `:${i + 1}` : ''}`), cfg.skills.sources ?? []);
159
+ const servers = [...rawServers, ...plan.newMcp];
160
+ saveUserConfig({ ...cfg, raw: writeServers(servers), skills: { ...cfg.skills, sources } });
161
+ resetSkillIndex();
162
+ const next = { ...cfg, skills: { ...cfg.skills, sources } };
163
+ getSkillIndex(defaultSkillDirs(next));
164
+ const problems = skillIndexProblems().filter((p) => plugin.skillRoots.includes(p.dir));
165
+ debug.log('skills.connect', 'registered', { plugin: plugin.name, skills: plugin.skills.length, problems: problems.length, mcp: plan.newMcp.length });
166
+ console.log(`연결했습니다 — 스킬 ${plugin.skills.length - problems.length}개를 바로 쓸 수 있습니다. 끊으려면: elanous connect ${plugin.root} --undo`);
167
+ const notice = skillRepairNotice(problems);
168
+ if (notice) console.log(notice);
169
+ if (plan.newMcp.length) {
170
+ console.log(`MCP 서버 ${plan.newMcp.length}개를 꺼진 채로 등록했습니다. 믿을 수 있는 것만 켜 주세요(켠 뒤 데몬 재시작):`);
171
+ for (const line of mcpEnableHint(plan.newMcp, servers)) console.log(line);
172
+ }
173
+ }
@@ -5,6 +5,8 @@ import type { DetectedProvider } from '../llm/provider-detect.js';
5
5
  import { resolveUsableLlm, type UsableLlm } from '../llm/usable-llm.js';
6
6
  import { resolveDaemonEndpoint, type DaemonEndpoint, type ResolveDaemonEndpointOpts } from '../nexus/daemon-endpoint.js';
7
7
  import { runBgLaunch } from './bg-launch.js';
8
+ import { browserUnavailableReason } from '../oauth/browser-availability.js';
9
+ import { debug } from '../debug/log.js';
8
10
 
9
11
  export interface StartOptions {
10
12
  gui?: boolean;
@@ -63,6 +65,8 @@ export interface StartDeps {
63
65
  openTui?: (json: boolean) => Promise<number>;
64
66
  sleep?: (ms: number) => Promise<void>;
65
67
  output?: (line: string) => void;
68
+ browserEnv?: NodeJS.ProcessEnv;
69
+ browserPlatform?: NodeJS.Platform;
66
70
  /** Test seam — daemon address. `null` means this universe has no daemon (do not guess a port).
67
71
  * Called again after a launch so the opened address is the daemon that was just started. */
68
72
  resolveEndpoint?: (opts?: ResolveDaemonEndpointOpts) => DaemonEndpoint | null;
@@ -193,10 +197,15 @@ export async function runStart(options: StartOptions = {}, deps: StartDeps = {})
193
197
  if (!openUrl) {
194
198
  record('open-gui', 'failed', 'Daemon address unknown');
195
199
  } else {
196
- try {
197
- if (await (deps.openGui ?? defaultOpenGui)(openUrl)) surface = 'gui';
198
- } catch { /* A browser is optional; retain the URL for manual opening. */ }
199
- record('open-gui', surface === 'gui' ? 'done' : 'failed', surface === 'gui' ? `Opened ${openUrl}` : `Open manually: ${openUrl}`);
200
+ const why = browserUnavailableReason(deps.browserEnv ?? process.env, deps.browserPlatform ?? process.platform);
201
+ if (why) {
202
+ debug.log('browser.open', 'skipped', { reason: why.includes('ssh') ? 'ssh' : 'no-display' });
203
+ } else {
204
+ try {
205
+ if (await (deps.openGui ?? defaultOpenGui)(openUrl)) surface = 'gui';
206
+ } catch { /* A browser is optional; retain the URL for manual opening. */ }
207
+ }
208
+ record('open-gui', surface === 'gui' ? 'done' : why ? 'skipped' : 'failed', surface === 'gui' ? `Opened ${openUrl}` : `Open manually: ${openUrl}${why ? ` — ${why}` : ''}`);
200
209
  }
201
210
  record('open-tui', 'skipped', 'GUI selected');
202
211
  } else {
@@ -12,9 +12,13 @@ import { consumeCodexResetCredits, listCodexResetCredits } from '../budget/codex
12
12
  import { rollupRunUsage, type RunUsageInput } from '../budget/run-usage-rollup.js';
13
13
  import { LogStore, logsDbPath, type LogQuery, type LogStoreRow } from '../mss/logging/log-store.js';
14
14
  import { LOGS_SINCE_OPTION, parseSince } from './logs-cli.js';
15
+ import { formatCodexCreditPlan, type CodexCreditPlan } from '../budget/codex-credit-plan.js';
16
+ import { codexCreditPlanFromDisk } from './codex-credit-plan-view.js';
15
17
 
16
18
  export interface UsageCliDeps {
17
19
  readonly collect?: typeof collectUnifiedUsage;
20
+ /** Codex credit plan (disk only). Returns null when it cannot be read. */
21
+ readonly creditPlan?: () => CodexCreditPlan | null;
18
22
  readonly out?: { log: (s: string) => void };
19
23
  /** Read-only LogStore query seam; returns stored llm-usage rows, newest first. */
20
24
  readonly readRunLogs?: (query: LogQuery) => LogStoreRow[];
@@ -61,6 +65,10 @@ function usageData(row: LogStoreRow): RunUsageInput | null {
61
65
  } catch { return null; }
62
66
  }
63
67
 
68
+ function defaultCreditPlan(): CodexCreditPlan | null {
69
+ try { return codexCreditPlanFromDisk(); } catch { return null; }
70
+ }
71
+
64
72
  export function registerUsageCommand(program: Command, deps: UsageCliDeps = {}): void {
65
73
  const out = deps.out ?? { log: (s: string) => console.log(s) };
66
74
  const collect = deps.collect ?? collectUnifiedUsage;
@@ -71,11 +79,13 @@ export function registerUsageCommand(program: Command, deps: UsageCliDeps = {}):
71
79
  .option('--json', 'JSON 출력 — 자격 값은 없다')
72
80
  .action(async (opts: { json?: boolean }) => {
73
81
  const report = await collect();
82
+ const creditPlan = (deps.creditPlan ?? defaultCreditPlan)();
74
83
  if (opts.json) {
75
- out.log(JSON.stringify(report, null, 2));
84
+ out.log(JSON.stringify({ ...report, codexCreditPlan: creditPlan }, null, 2));
76
85
  return;
77
86
  }
78
87
  out.log(formatUnifiedUsage(report));
88
+ if (creditPlan) out.log(['', 'codex 크레딧', ...formatCodexCreditPlan(creditPlan).map((l) => ` ${l}`)].join('\n'));
79
89
  });
80
90
 
81
91
  usage
@@ -62,14 +62,35 @@ export interface CodexSetupResult {
62
62
 
63
63
  // ── Picker helpers (shared with onboarding) ──────────────────────────
64
64
 
65
- export async function pickCodexAuthMode(io: WizardIO): Promise<CodexAuthMode> {
66
- const existing = loadTokens('openai-codex');
67
- if (existing) {
68
- const exp = existing.tokens.expiresAt;
69
- const when = exp != null
70
- ? (Date.now() > exp ? 'EXPIRED' : `${Math.round((exp - Date.now()) / 60000)}min left`)
71
- : 'no expiry tracked';
72
- io.print(` OAuth tokens already on file (${when}).`);
65
+ export interface CodexAuthModeDeps {
66
+ loadTokens?: typeof loadTokens;
67
+ /** OB1 — a codex CLI login (~/.codex/auth.json) the runtime already uses; default = `inspectSubscription`. */
68
+ hasCodexCliLogin?: () => boolean;
69
+ }
70
+
71
+ export async function pickCodexAuthMode(io: WizardIO, deps: CodexAuthModeDeps = {}): Promise<CodexAuthMode> {
72
+ const existing = (deps.loadTokens ?? loadTokens)('openai-codex');
73
+ // OB1 (10-01): a user already signed in to the codex CLI was sent through the device-code flow again,
74
+ // because only elanous's own token store counted. The runtime reads ~/.codex/auth.json, so it counts too.
75
+ // Same judgment as the runtime (`codexOAuthAvailable` in llm.ts) — two judgments drifting apart was the bug.
76
+ const codexCli = !existing && (deps.hasCodexCliLogin ?? (() => {
77
+ try {
78
+ const { codexOAuthAvailable } = require('../llm.js') as typeof import('../llm.js');
79
+ return codexOAuthAvailable();
80
+ } catch { return false; }
81
+ }))();
82
+ if (existing || codexCli) {
83
+ if (existing) {
84
+ const exp = existing.tokens.expiresAt;
85
+ const left = exp != null ? exp - Date.now() : null;
86
+ const when = left == null ? '만료 시각 모름'
87
+ : left <= 0 ? '만료됨'
88
+ : left >= 86_400_000 ? `약 ${Math.round(left / 86_400_000)}일 남음`
89
+ : left >= 3_600_000 ? `약 ${Math.round(left / 3_600_000)}시간 남음` : `약 ${Math.max(1, Math.round(left / 60_000))}분 남음`;
90
+ io.print(` 이미 로그인돼 있습니다(${when}).`);
91
+ } else {
92
+ io.print(' Codex CLI 에 있는 ChatGPT/Codex 로그인을 찾았습니다(~/.codex/auth.json).');
93
+ }
73
94
  // Sprint 11 — chooseFrom Yes/No so fullScreenIO renders the arrow
74
95
  // picker (with 'y'/'n' + 한글 자모 quick-pick from PR #986 + #988)
75
96
  // instead of a bare text input. The runner distinguishes 'oauth-keep'
@@ -77,10 +98,10 @@ export async function pickCodexAuthMode(io: WizardIO): Promise<CodexAuthMode> {
77
98
  // rotation on an unnecessary refresh).
78
99
  const keep = await chooseFrom<boolean>(
79
100
  io,
80
- 'Keep using existing OAuth tokens?',
101
+ '지금 로그인을 그대로 쓸까요?',
81
102
  [
82
- { key: 'y', label: 'Yes — keep them', value: true },
83
- { key: 'n', label: 'No — re-run device-code flow', value: false },
103
+ { key: 'y', label: '예 — 그대로 씁니다', value: true },
104
+ { key: 'n', label: '아니오 — 다시 로그인합니다', value: false },
84
105
  ],
85
106
  { defaultIndex: 0 },
86
107
  undefined,
@@ -246,18 +267,18 @@ async function runCodexSetupImpl(
246
267
  let apiKey: string | undefined = initial.llm.apiKey;
247
268
 
248
269
  if (authMode === 'oauth') {
249
- io.print(' Launching device-code flow…');
270
+ io.print(' 코드로 로그인합니다…');
250
271
  try {
251
272
  await loginWithCodex({
252
273
  onProgress: (p) => {
253
274
  if (p.type === 'user_code') {
254
275
  io.print('');
255
- io.print(` 1) Open in any browser: ${p.loginUrl}`);
256
- io.print(` 2) Enter code: ${p.userCode}`);
276
+ io.print(` 1) 아무 브라우저에서 열기: ${p.loginUrl}`);
277
+ io.print(` 2) 코드 입력: ${p.userCode}`);
257
278
  io.print('');
258
- io.print(' Waiting for sign-in…');
279
+ io.print(' 로그인을 기다리는 중…');
259
280
  }
260
- if (p.type === 'saved') io.print(' Signed in. Tokens saved.');
281
+ if (p.type === 'saved') io.print(' 로그인했습니다. 저장했습니다.');
261
282
  },
262
283
  fetchImpl: opts.fetchImpl,
263
284
  sleepImpl: opts.sleepImpl,
@@ -725,7 +725,8 @@ import { SELF_IMPLEMENT_TOOL_NAMES } from '../boot/daemon-tools/self-implement-n
725
725
  import { FOLD_LIMITS, type FoldMode } from '../log-entry.js';
726
726
  import { renderToolCallEvent, renderToolResultVariants } from '../chat/tool-render/index.js';
727
727
  import { FoldStack } from '../fold-stack.js';
728
- import { getSkillIndex, reloadSkillIndex, applySkillFilter } from '../skills/index.js';
728
+ import { getSkillIndex, reloadSkillIndex, applySkillFilter, skillIndexProblems } from '../skills/index.js';
729
+ import { skillRepairNotice } from '../skills/repair.js';
729
730
  import type { DetectResult } from '../skills/router.js';
730
731
  import { detectUrlRoute } from '../skills/url-router.js';
731
732
  import {
@@ -7190,6 +7191,21 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
7190
7191
  // and after each user-initiated skill cursor change.
7191
7192
  const skillView: SkillViewState = createSkillViewState(LOCAL_SKILLS_DIR);
7192
7193
  try { refreshSkills(skillView); refreshSkillFiles(skillView); } catch { /* missing root fine */ }
7194
+ // SK2 — a skill the index could not read is a one-line notice with the repair command, never a crash.
7195
+ try {
7196
+ getSkillIndex();
7197
+ const problems = skillIndexProblems();
7198
+ const notice = skillRepairNotice(problems);
7199
+ if (notice) chatLines.push(C.info(notice));
7200
+ // ER1 — tell operations too (consented · scrubbed · async); a kept unsent report is retried once a day.
7201
+ void import('../error-report/report.js').then(async ({ reportError, retryPendingErrorReport }) => {
7202
+ await retryPendingErrorReport();
7203
+ for (const p of problems.slice(0, 3)) {
7204
+ const outcome = await reportError({ code: 'skill-index', message: `${p.name}: ${p.code ?? ''} ${p.error}`.trim(), surface: 'tui' });
7205
+ if (outcome.sent && outcome.reportId) { chatLines.push(C.muted(` 운영팀에 알렸습니다 (보고 번호 ${outcome.reportId})`)); }
7206
+ }
7207
+ }).catch(() => { /* reporting never breaks the dashboard */ });
7208
+ } catch { /* the notice is advisory */ }
7193
7209
 
7194
7210
  // Scratch visibility (Phase S5). When closed, the workingDir
7195
7211
  // layouts drop the scratch cell so the remaining panes expand
@@ -16779,7 +16795,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
16779
16795
  preferHistoryArrowKeys: slashQuickMode,
16780
16796
  history: inputHistory,
16781
16797
  placeholder: anyProviderAvailable()
16782
- ? '/command, or type a question (inline /path/to.pdf to attach)'
16798
+ ? '말 한 줄로 시작 — 질문하거나 «하니스로 구현 …» · /command · /path/to.pdf 첨부'
16783
16799
  : '/quit /clear (run `elanous setup` — no LLM provider available)',
16784
16800
  debugLog: debug.enabled ? (event, label, payload) => debug.log(event, label, payload) : undefined,
16785
16801
  textInputOpts: {
@@ -1370,8 +1370,8 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
1370
1370
  ctx.attachmentRowMap.clear();
1371
1371
  ctx.clearLogSearch();
1372
1372
  ctx.clearLogFilter();
1373
- ctx.pushDebugLine(ctx.muted('Status cleared'));
1374
- ctx.chatLines.push(ctx.muted('Status cleared'));
1373
+ ctx.pushDebugLine(ctx.muted('Chat log cleared'));
1374
+ ctx.chatLines.push(ctx.muted('Chat log cleared'));
1375
1375
  ctx.setChatScrollOffset(-1);
1376
1376
  });
1377
1377
 
@@ -3,7 +3,9 @@ import { visibleWidth } from '../../tui.js';
3
3
 
4
4
  const ESSENTIAL_KEYS = [
5
5
  ['Enter', 'Send message'],
6
- ['Esc', 'Clear input / close help modal'],
6
+ // U1 · 2026-10-02 — stopping and queueing while an answer streams were missing from help (same line count:
7
+ // the modal has a row budget and falls back to the chat log when it is exceeded).
8
+ ['Esc', 'Stop the answer (Esc again = rewind) · clear input / close help'],
7
9
  ['Ctrl+U', 'Clear text before cursor'],
8
10
  ['Ctrl+W', 'Delete previous word'],
9
11
  ['Ctrl+← / →', 'Move by word'],
@@ -11,7 +13,7 @@ const ESSENTIAL_KEYS = [
11
13
  ['Home / End', 'Move to start / end of line'],
12
14
  ['Ctrl+A / E', 'Move to start / end of line'],
13
15
  ['PgUp / PgDn', 'Scroll chat log'],
14
- ['Ctrl+↑', 'Recall sent line while streaming'],
16
+ ['Ctrl+↑', 'Recall a queued line (Enter while answering queues it)'],
15
17
  ] as const;
16
18
 
17
19
  function fitLine(text: string, width: number): string {