elanous 0.2.42 → 0.2.44

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 (764) 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/{X1ucLw10Cds_h614NoEnh → HMXsxdy5MIIcHPMHv1wD4}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/08334415.f0e80896acbef722.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/1032-78ba4f6391258cab.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1082-53f86a26e03d309d.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1109-7d0e264f6f2edbc7.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1124-7c26330402481143.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/{2160.a097e7b138ae1c55.js → 118.2a89982fe4276880.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1244.6c435dbf1bf21d8a.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1252.9e665904d3aa3b1a.js +32 -0
  12. package/apps/pwa/out/_next/static/chunks/1266.a46cc33cb6a72d75.js +104 -0
  13. package/apps/pwa/out/_next/static/chunks/1306.967240ede9a0f757.js +24 -0
  14. package/apps/pwa/out/_next/static/chunks/1344.3b95f3bd1b77a3fe.js +94 -0
  15. package/apps/pwa/out/_next/static/chunks/{4043.6b91203436c9c86b.js → 1401.22dfe92640a2b1ac.js} +4 -4
  16. package/apps/pwa/out/_next/static/chunks/1431-f7c78bd5be21e011.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1451-cdd35a8a0b31834b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{6632.0eac1c554f8f2ef3.js → 1694.18debfd77562e56d.js} +2 -2
  19. package/apps/pwa/out/_next/static/chunks/1708-f03d587b7a7545c8.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/1775-fa7152bdeff6c95f.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/178-4da509cd7266672a.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/1850-522de4ee34957210.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/1876-c6f6e0ddcc76c6a1.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/1976.097066b072432242.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/{3507.97e1977bc4d5fb0a.js → 1978.eeb60a606dc5deac.js} +2 -2
  26. package/apps/pwa/out/_next/static/chunks/2043.e233e3b5a3e790f5.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2150.71b94e3348107c83.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2158.ebc6fc5a10280ab7.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2216.802962c04f40a26e.js +64 -0
  30. package/apps/pwa/out/_next/static/chunks/2294.7890edcfa046c97d.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/235.c89aaae4bcd6233a.js +74 -0
  32. package/apps/pwa/out/_next/static/chunks/{5885.0a3e52c8faccec98.js → 239.de075467b5523469.js} +2 -2
  33. package/apps/pwa/out/_next/static/chunks/249.ba7051590d603c8f.js +226 -0
  34. package/apps/pwa/out/_next/static/chunks/2571.a6ac4e26c8618403.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/2610.e149cd564a08913e.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/2705.9816f3c244f8b85f.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/2801.afeb8a4dae22f85f.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/2954.bbefc95d6b20e0d8.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/2e0f720a.a0697c08e3806a60.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3042.96ec235fe41c8d4e.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3097-8e358f158acef46b.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3205-93b1abe28b4fb16a.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3273.b4434f0dcae7eb29.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3311.9cbc43ea0c90d60c.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{1487.2f67b79444062da6.js → 3349.b5f09ee474d9533e.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/3503.a47a9755fb4d97b0.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/3506-5f429b3b7e1392b0.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/3843.bad404d008893291.js +77 -0
  49. package/apps/pwa/out/_next/static/chunks/3877-4b40e530b47e3bf9.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/435-ce2958253cf7de61.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4393.28fa5228d0eec217.js +149 -0
  52. package/apps/pwa/out/_next/static/chunks/4404.7281c847c6e10dfc.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/{8673-bab689a55f7e13b9.js → 4415-b9d6a90960920a4a.js} +3 -3
  54. package/apps/pwa/out/_next/static/chunks/447-5b304de1fe098f43.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/4484-8ebea83d431e6fae.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/{8262.ddc03e06b733f184.js → 4502.bdcc877abd437a05.js} +1 -1
  57. package/apps/pwa/out/_next/static/chunks/4599-f95790fc5c65b8df.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/{1262.e804feb8fd1acb8c.js → 46.57c783fa4884714f.js} +2 -2
  59. package/apps/pwa/out/_next/static/chunks/463-b9114e411f33728e.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/4659.a57d1f0c5d754cd2.js +36 -0
  61. package/apps/pwa/out/_next/static/chunks/4722-a847e7a28115035f.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/{1063.2fb8a9dc55c731f2.js → 4757.67c6d7473a038e78.js} +1 -1
  63. package/apps/pwa/out/_next/static/chunks/4874-c86f878ec4502ad3.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{6377.bc7df239edbff244.js → 4891.3f80ba517a3b2373.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/4998.810ca8833084caa9.js +62 -0
  66. package/apps/pwa/out/_next/static/chunks/4f98febc.ea5841d4d616bfb2.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/{3482.a9ae9d2ad6a5bd97.js → 5052.7dbb12a55d4f18f5.js} +1 -1
  68. package/apps/pwa/out/_next/static/chunks/5166-ca73b3e361085a6d.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/5180-039f4a18b07ad387.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/5232.5a2ce4daf7a9e11d.js +115 -0
  71. package/apps/pwa/out/_next/static/chunks/5439.3fec6dbce29ecb36.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/5612-074d9a5e00dfac6a.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/5675-01989d524a84c505.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/5751.af641a1adf5ec697.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/5758-c6cb98714d18ab0c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/578eded8.b582637306e16964.js +122 -0
  77. package/apps/pwa/out/_next/static/chunks/5790.5eb06a653ebd8571.js +34 -0
  78. package/apps/pwa/out/_next/static/chunks/5853-4033e5bd5afbe06b.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/5904.97d70bb7f46b2db7.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/{3347.f846266b5e5f3ede.js → 5989.7ecd362c5c44b747.js} +3 -3
  81. package/apps/pwa/out/_next/static/chunks/{73d2eb0e.4966ad55293c801a.js → 5a34fb2f.52f1b4e1baebb48a.js} +3 -3
  82. package/apps/pwa/out/_next/static/chunks/{7a98bc80.fa935989e829f9c2.js → 5a5078f8.2099200e5ea95e16.js} +1 -1
  83. package/apps/pwa/out/_next/static/chunks/6036-c302c34ff0b3d410.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/606.ef81c313381f4264.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/616.1af54a928b1ba704.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/6201.bc936f71f613a8e9.js +41 -0
  87. package/apps/pwa/out/_next/static/chunks/6204-fdc86e0e64c4f92d.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/{7411.9b4b8b747dc7b802.js → 6245.1182e007e9d230d9.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/{b450776b.3db34d8d965f82d3.js → 63699a35.17262e162bc514b2.js} +1 -1
  90. package/apps/pwa/out/_next/static/chunks/6420.494801a80030160c.js +27 -0
  91. package/apps/pwa/out/_next/static/chunks/{e8543907.5b040a5f22a0b0e5.js → 6549dad0.2740b25e51bf8f05.js} +1 -1
  92. package/apps/pwa/out/_next/static/chunks/{9427.96aa912ddb5801e0.js → 6881.9e7955847640c7fe.js} +17 -17
  93. package/apps/pwa/out/_next/static/chunks/6931.fcdfb94141e67b3d.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/6991-8e081c6ce38c0ba1.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7010.1bbd17a7f2b3e376.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/7029.d1466acf55fae2ed.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7152-a123aa8e129c131f.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7455.196168fffac3b9c4.js +24 -0
  99. package/apps/pwa/out/_next/static/chunks/7638.6ca4770dd1129138.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/7649-f37d76260e5e2a5a.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/7679.32c40cdd14f20b4a.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/7751.04bfbd16b4c6cd0a.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/7864.b1ff31d4030b8994.js +148 -0
  104. package/apps/pwa/out/_next/static/chunks/7869-c47bd2c075c1fefa.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{8138.6c10b2a356d52fca.js → 8442.2f09ca969d631615.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/8445.2738dbd59a78c78c.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8447.5510c439f9938c6d.js +286 -0
  108. package/apps/pwa/out/_next/static/chunks/{9415.69e4a21c60c7d2db.js → 8551.f762945c2cda2e95.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/8635-57a9d8d9db70f4f1.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/86961958-4b0689a5048f756b.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/8709.3c6019bb18f8554f.js +8 -0
  112. package/apps/pwa/out/_next/static/chunks/8759.c999528a0a907bf6.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{9a852a62-6192a6ea9346ced3.js → 87f498e5-0881de09f2e44707.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/8843.c3197f904c952b81.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/{3d0154af.5331fec737ffe8c3.js → 892fd990.456232f326cc39c2.js} +1 -1
  116. package/apps/pwa/out/_next/static/chunks/8965-135a2c9eaa2464cb.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/8971-8d3b9c96f8a6c958.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9059.c8598d96f8e5e9cd.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9115.90447ae198b84eae.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9147.d9b0a02e0babc9b4.js +93 -0
  121. package/apps/pwa/out/_next/static/chunks/9204-83075f4b70c61cdc.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9244-c32ef14b5dc72bdf.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/930.2a9a30f964350c66.js +90 -0
  124. package/apps/pwa/out/_next/static/chunks/9398.1f56e3f17795f43f.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/9527.3e5ad31c891c5fcb.js +79 -0
  126. package/apps/pwa/out/_next/static/chunks/9571-4ac933e774d1225c.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-9fc644de2d8edae3.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/approvals/page-0c9dace2db62bee8.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f5e65c3dc9d89f2a.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/board/page-2a9c19b9a140b7b1.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/botlab/page-61533ad92141adfb.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/bots/page-112004ced6fd0329.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/ceo/page-f733318c237a49d8.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/chat/page-51ea677d2d33bbc0.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/consult/page-428b41f2f9566e3c.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/control/page-1b29396ea90a61e5.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/decisions/page-cf83ec613ac904bf.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/design-check/page-3f4c0ecbc284bb5f.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/editor/page-b63c322f54f70cc6.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/exec/page-fe328c4ee9aac6b4.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/field/page-bfb855c584f0fb98.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/healthz/route-9fc644de2d8edae3.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/inside/page-47b1710c110eabd7.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/intake/page-42895214458bc6d2.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/layout-d03de0ebd8366e23.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/live/page-3ed6c47e4b1c61c2.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/live-run/page-ae653e9bf261c738.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/loops/page-23f3f0a0209c0ac4.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/market/page-88c691273aae66f9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e187ac52a95538b3.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/morning/page-6e45828daed1295e.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/not-found-edb5d7287bb46186.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/observatory/page-4a7eaacd93c3f6a5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ca073d43d74cc84.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1e9fee67b1199436.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-df1283ea963c6816.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/outputs/page-19fcf8d8301ccd18.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/page-5ab699e0303bbb40.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7cde0d29756984c5.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-9d4c598e8ee22f7a.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/sessions/page-cc1609a71f44ec62.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7659a9a1345bfaa9.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/settings/page-0afef60ecc0c4af5.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-a3553949f8f34f5f.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/setup/layout-9fc644de2d8edae3.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/setup/page-057a69702f3c67c7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/share/page-c0f0e570f3f74c73.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/showroom/page-1825071ae34e3b89.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/tasks/page-6244e3e135d8ccfc.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/term/page-da787e8a10b8a82e.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/today/page-1316d32498e2be42.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/trace/page-4df94572e343de2e.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/vault/page-708969f7475e88c1.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-c58add08c919a1dc.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/workflows/page-a24847f45e5d5bf9.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/app/workspace/page-acfec65a3a60e22e.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-3dfc598e6fbde245.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/framework-c658a626118411b7.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-4c73685fd891445b.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-6310f7e5de7dd01d.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-51c326bf48610be1.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-d0beadf754da59b0.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-acd243bfbf3f6732.js +1 -0
  184. package/apps/pwa/out/_next/static/css/d1f8bb401740a549.css +1 -0
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +23 -23
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +23 -23
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +23 -23
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +22 -22
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +22 -22
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +23 -23
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +22 -22
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +23 -23
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +23 -23
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +22 -22
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +23 -23
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -23
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +23 -23
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +23 -23
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +22 -22
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +23 -23
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +23 -23
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -23
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +22 -22
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +22 -22
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +23 -23
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +23 -23
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +22 -22
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +22 -22
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +22 -22
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +23 -23
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +23 -23
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +22 -22
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +23 -23
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +23 -23
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +23 -23
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +23 -23
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +23 -23
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +22 -22
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +23 -23
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +23 -23
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +23 -23
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +23 -23
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +23 -23
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +23 -23
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +23 -23
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +23 -23
  278. package/catalog/external-commands.yaml +5 -3
  279. package/catalog/meta/catalogVersion.yaml +2 -1
  280. package/catalog/signing/catalog-signing-public.pem +3 -0
  281. package/graphs/intake/intake-daily.yaml +16 -0
  282. package/graphs/intake/news-sources.yaml +1 -0
  283. package/graphs/intake/recipes.yaml +7 -0
  284. package/graphs/overlays/README.md +6 -0
  285. package/graphs/overlays/examples/research-runtime-empty-terminal.yaml +28 -0
  286. package/graphs/profiles/local.yaml +5 -0
  287. package/graphs/profiles/pod.yaml +4 -0
  288. package/graphs/release/release-loop.yaml +33 -17
  289. package/graphs/units/verbs/make-doc.yaml +1 -0
  290. package/package.json +6 -2
  291. package/plugins/demo-absorption-briefing/plugin.json +18 -0
  292. package/plugins/demo-absorption-briefing/skills/demo-absorption-briefing/SKILL.md +8 -0
  293. package/plugins/demo-browser-hand/plugin.json +13 -0
  294. package/plugins/demo-browser-hand/skills/demo-browser-hand/SKILL.md +8 -0
  295. package/plugins/demo-linear-secretary/plugin.json +15 -0
  296. package/plugins/demo-linear-secretary/skills/demo-linear-secretary/SKILL.md +8 -0
  297. package/plugins/demo-plugin-wizard/plugin.json +11 -0
  298. package/plugins/demo-plugin-wizard/skills/demo-plugin-wizard/SKILL.md +8 -0
  299. package/plugins/demo-research/plugin.json +16 -0
  300. package/plugins/demo-research/skills/demo-research/SKILL.md +8 -0
  301. package/plugins/demo-video-briefing/plugin.json +15 -0
  302. package/plugins/demo-video-briefing/skills/demo-video-briefing/SKILL.md +8 -0
  303. package/scripts/bench-metering-plan.ts +229 -0
  304. package/scripts/build-signed-catalog.ts +48 -0
  305. package/scripts/ci-typecheck-main-delta.sh +88 -0
  306. package/scripts/codex-fallback-live-probe.ts +1 -1
  307. package/scripts/demo/demo1104-parallel-host.ts +56 -0
  308. package/scripts/demo/demo1104-parallel-scenes.ts +301 -0
  309. package/scripts/demo/demo1104-parallel.ts +72 -0
  310. package/scripts/demo/demo1104-stage.config.ts +21 -0
  311. package/scripts/demo/demo1104-stage.ts +316 -0
  312. package/scripts/goal-method-audit.ts +17 -1
  313. package/scripts/graph-units/land-enqueue.ts +90 -0
  314. package/scripts/hooks/codex-notify.sh +32 -0
  315. package/scripts/install.sh +10 -38
  316. package/scripts/landing-heal/land-plan.ts +57 -0
  317. package/scripts/public-leak-baseline.txt +0 -1
  318. package/scripts/release-loop/auto-approve-node.ts +1 -1
  319. package/scripts/release-loop/docs-node.ts +4 -2
  320. package/scripts/release-loop/gate-autoheal-sim-evidence.ts +60 -0
  321. package/scripts/release-loop/gate-image-pin.ts +116 -2
  322. package/scripts/release-loop/gate-method.ts +139 -0
  323. package/scripts/release-loop/gate-node.ts +395 -43
  324. package/scripts/release-loop/gate-progress-sim.ts +73 -0
  325. package/scripts/release-loop/gate-traffic-mode.ts +151 -3
  326. package/scripts/release-loop/node-verdict.ts +38 -25
  327. package/scripts/release-loop/notes-repair.ts +18 -1
  328. package/scripts/release-loop/preflight.ts +544 -10
  329. package/scripts/release-loop/render-warm-control-manifest.ts +22 -0
  330. package/scripts/release-loop/resume-release.ts +9 -7
  331. package/scripts/release-loop/resume.ts +13 -4
  332. package/scripts/release-loop/unattended-release.ts +20 -9
  333. package/scripts/release-loop/warm-control-forward.ts +178 -0
  334. package/scripts/retro-cycle.ts +30 -8
  335. package/scripts/rhythm/daily.ts +39 -4
  336. package/scripts/rhythm/linear-progress-sync.ts +311 -0
  337. package/scripts/ux-sim.ts +7 -1
  338. package/scripts/video-pipeline.ts +9 -1
  339. package/scripts/warm-pool-provider-config.ts +35 -7
  340. package/src/acp/agent-manager.ts +1 -0
  341. package/src/acp/codex-app-server-agent.ts +33 -0
  342. package/src/acp/codex-app-server-client.ts +153 -16
  343. package/src/acp/core-turn-bridge.ts +17 -12
  344. package/src/acp/event-router.ts +20 -1
  345. package/src/acp/server.ts +6 -0
  346. package/src/agent-mission/browser-roundtrip-coordinator.ts +85 -0
  347. package/src/agent-mission/claude-headless.ts +4 -1
  348. package/src/agent-mission/codex-exec.ts +105 -0
  349. package/src/agent-mission/driver.ts +192 -11
  350. package/src/agent-mission/grok-auth-status.ts +107 -0
  351. package/src/agent-mission/hand-hooks.ts +101 -0
  352. package/src/agent-mission/mission-cli.ts +56 -21
  353. package/src/agent-mission/mission-hand-reply.ts +118 -0
  354. package/src/agent-mission/mission-line.ts +180 -0
  355. package/src/agent-mission/mission-out.ts +256 -18
  356. package/src/agent-mission/tool-install.ts +122 -11
  357. package/src/agent-substrate/pr-reviewer.ts +147 -11
  358. package/src/agent-substrate/self-review-cli.ts +10 -2
  359. package/src/agents/general-purpose.md +1 -1
  360. package/src/auto-research/research-fanout.ts +221 -0
  361. package/src/auto-research/research-turn.ts +362 -31
  362. package/src/autopilot/mission-codebase-gate.ts +7 -3
  363. package/src/autopilot/pr-manager.ts +31 -3
  364. package/src/boot/daemon-tools/self-implement.ts +3 -1
  365. package/src/boot/daemon-tools/web-search.ts +1 -2
  366. package/src/briefing/brief-items.ts +55 -11
  367. package/src/cli/agent-cli.ts +2 -1
  368. package/src/cli/catalog-cli.ts +31 -0
  369. package/src/cli/connector-cli.ts +16 -0
  370. package/src/cli/control-cli.ts +15 -6
  371. package/src/cli/doctor-fix.ts +2 -2
  372. package/src/cli/intake-source-cli.ts +44 -8
  373. package/src/cli/log-event-names.ts +8 -0
  374. package/src/cli/msg-cli.ts +32 -3
  375. package/src/cli/pr-cli.ts +21 -1
  376. package/src/cli/pr-land-heavy-remote.ts +44 -6
  377. package/src/cli/pr-land-overlap-evidence.ts +13 -1
  378. package/src/cli/pr-land-pod-shadow-job.ts +143 -5
  379. package/src/cli/pr-land-pod-shadow.ts +9 -2
  380. package/src/cli/release-checklist-read-cli.ts +44 -16
  381. package/src/cli/release-cli.ts +23 -3
  382. package/src/cli/research-cli.ts +9 -0
  383. package/src/cli/setup-cli.ts +166 -6
  384. package/src/cli/setup-keys.ts +199 -0
  385. package/src/cli/task-plugin-wizard-host.ts +114 -0
  386. package/src/cli/tasks-cli.ts +54 -9
  387. package/src/cli/tui-test-cli.ts +190 -0
  388. package/src/config.ts +4 -2
  389. package/src/connectors/linear-daily-progress.ts +228 -0
  390. package/src/connectors/linear-projector.ts +34 -12
  391. package/src/connectors/linear.ts +151 -7
  392. package/src/control-plane/ledger.ts +42 -4
  393. package/src/control-plane/member-tokens.ts +25 -2
  394. package/src/control-plane/ports.ts +8 -3
  395. package/src/control-plane/server.ts +26 -5
  396. package/src/core-turn/deep-turn-bloom.ts +67 -0
  397. package/src/core-turn/research-policy.ts +43 -0
  398. package/src/core-turn/run-core-turn.ts +488 -51
  399. package/src/core-turn/types.ts +4 -0
  400. package/src/dashboard/chat/acp-chat.ts +10 -0
  401. package/src/dashboard/classic-sidetab-mission-job.ts +192 -0
  402. package/src/dashboard/classic-sidetab-mission-pair.ts +82 -0
  403. package/src/dashboard/classic-sidetab-mission-trio.ts +242 -0
  404. package/src/dashboard/classic-sidetab-mission.ts +169 -5
  405. package/src/dashboard/index.ts +387 -14
  406. package/src/dashboard/input/chat-main-acp-dispatch.ts +23 -0
  407. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +8 -0
  408. package/src/dashboard/mission-cli-consumer.ts +20 -8
  409. package/src/dashboard/plugin-wizard-runtime.ts +50 -0
  410. package/src/dashboard/plugin-wizard-tool.ts +55 -0
  411. package/src/dashboard/sidetab-runtime.ts +3 -1
  412. package/src/dashboard/terminal-popup-runtime.ts +6 -3
  413. package/src/dashboard/visible-mission-diagnostics.ts +16 -0
  414. package/src/decisions/linear-progress-summary.ts +78 -0
  415. package/src/decisions/linear-progress-sync.ts +152 -0
  416. package/src/domains/outbound-alert.ts +49 -11
  417. package/src/domains/retro-cycle-observation.ts +43 -0
  418. package/src/domains/retro-cycle.ts +13 -2
  419. package/src/domains/retro-proposals.ts +92 -0
  420. package/src/domains/retro-report.ts +6 -1
  421. package/src/domains/telegram-kind-route.ts +16 -9
  422. package/src/graph-runner/arg-allowance.ts +13 -0
  423. package/src/graph-runner/graph-cli.ts +24 -1
  424. package/src/graph-runner/graph-grow-llm.ts +3 -1
  425. package/src/graph-runner/graph-run-api.ts +3 -1
  426. package/src/graph-runner/runner.ts +310 -46
  427. package/src/graph-wizard/mission-compose.ts +407 -12
  428. package/src/harness/dispatch-backpressure.ts +54 -1
  429. package/src/harness/dispatch-shadow-compare.ts +74 -0
  430. package/src/harness/harness-cli-command.ts +15 -3
  431. package/src/harness/harness-pod-dispatch.ts +3 -0
  432. package/src/harness/skill-exec.ts +21 -9
  433. package/src/harness/skill-select.ts +1 -1
  434. package/src/hooks/error-report-cloud.ts +101 -0
  435. package/src/hooks/receiver.ts +29 -2
  436. package/src/index.ts +129 -12
  437. package/src/intake-plane/actions.ts +354 -0
  438. package/src/intake-plane/adapters/telegram-ambient.ts +34 -18
  439. package/src/intake-plane/intake-sources.ts +78 -8
  440. package/src/intake-plane/items.ts +14 -4
  441. package/src/intake-plane/linear-mission-sync.ts +80 -0
  442. package/src/intake-plane/linear-secretary-runtime.ts +178 -0
  443. package/src/intake-plane/linear-wish.ts +227 -1
  444. package/src/life/life-cli.ts +168 -0
  445. package/src/life/life-kinds.ts +160 -0
  446. package/src/live-supply/budget-consumer.ts +78 -0
  447. package/src/live-supply/read.ts +3 -0
  448. package/src/live-supply/snapshot.ts +45 -0
  449. package/src/llm/child-first-llm-observation.ts +112 -0
  450. package/src/llm/provider-credentials.ts +68 -6
  451. package/src/llm/provider-failure-evidence.ts +44 -0
  452. package/src/llm.ts +172 -12
  453. package/src/maturity/feature-maturity.ts +3 -3
  454. package/src/mcp/client.ts +7 -0
  455. package/src/mcp/proxy-runtime.ts +6 -1
  456. package/src/mcp/server.ts +54 -0
  457. package/src/msg/msg-sse-server.ts +3 -3
  458. package/src/msg/msg-store.ts +177 -19
  459. package/src/native-tool-catalog.ts +36 -2
  460. package/src/nexus/api/consult-requests.ts +18 -6
  461. package/src/nexus/api/discord-trigger-bot.ts +6 -6
  462. package/src/nexus/api/graphs-api.ts +4 -2
  463. package/src/nexus/api/grokbot-trigger-bot.ts +206 -0
  464. package/src/nexus/api/http-server.ts +37 -1
  465. package/src/nexus/api/mcp-public-allowlist.ts +2 -0
  466. package/src/nexus/api/telegram-trigger-bot.ts +6 -6
  467. package/src/nexus/boot/register-mcp-clients.ts +114 -8
  468. package/src/nexus/index.ts +22 -2
  469. package/src/nexus/outbound/format.ts +9 -0
  470. package/src/nexus/outbound/grokbot-adapter.ts +71 -0
  471. package/src/nexus/outbound/router.ts +121 -16
  472. package/src/nexus/setup-status.ts +9 -0
  473. package/src/nexus/state/state.ts +3 -0
  474. package/src/oauth/codex-account-store.ts +20 -7
  475. package/src/oauth/codex-owner-mirror.ts +81 -0
  476. package/src/oauth/codex.ts +17 -2
  477. package/src/oauth/fallback-chain.ts +47 -17
  478. package/src/onboarding/first-run-doctor.ts +8 -1
  479. package/src/onboarding/first-run.ts +126 -29
  480. package/src/onboarding/key-setup.ts +103 -0
  481. package/src/onboarding/menu-answer.ts +13 -0
  482. package/src/onboarding/secret-prompt.ts +37 -0
  483. package/src/plugins/install/plugin-install.ts +59 -0
  484. package/src/pr-tool/census.ts +130 -0
  485. package/src/preview/terminal.ts +22 -7
  486. package/src/prompt-enhance/enhance.ts +10 -0
  487. package/src/pty-shell/pty-control-ipc.ts +4 -1
  488. package/src/pty-shell/pty-write-provenance.ts +21 -3
  489. package/src/pty-shell/registry.ts +9 -2
  490. package/src/registry/catalog-server.ts +232 -0
  491. package/src/registry/loader.ts +45 -1
  492. package/src/registry/types.ts +1 -2
  493. package/src/release-loop/proposal-auto-place.ts +83 -0
  494. package/src/research/axis-fanout.ts +79 -29
  495. package/src/research/lenses/second-order.ts +312 -0
  496. package/src/self-dev/ask-launch-flow.ts +72 -1
  497. package/src/self-dev/dev-cli.ts +7 -2
  498. package/src/self-dev/dev-pipeline.ts +5 -0
  499. package/src/self-dev/draft-residue.ts +64 -5
  500. package/src/self-dev/draft-sweep.ts +31 -10
  501. package/src/self-dev/draft-triage-rules.ts +60 -3
  502. package/src/self-dev/graph-front-nodes.ts +2 -1
  503. package/src/self-dev/graph-journey-route.ts +76 -21
  504. package/src/self-dev/launch-preflight.ts +58 -0
  505. package/src/self-dev/orchestrate.ts +1 -1
  506. package/src/self-dev/run-supervisor.ts +152 -2
  507. package/src/self-dev/shard-aggregate.ts +4 -0
  508. package/src/self-dev/shard-run.ts +36 -15
  509. package/src/self-implement/abandoned-classification.ts +12 -3
  510. package/src/self-implement/budget-gate.ts +7 -0
  511. package/src/self-implement/child-llm-preference.ts +10 -1
  512. package/src/self-implement/doctor-visit.ts +30 -8
  513. package/src/self-implement/elanous-tui-spawn.ts +3 -0
  514. package/src/self-implement/fixtures/tdd-green-missing-passing-child-transcript.txt +2 -0
  515. package/src/self-implement/gate-artifacts.ts +2 -1
  516. package/src/self-implement/goal-author-cli.ts +4 -2
  517. package/src/self-implement/goal-author.ts +549 -10
  518. package/src/self-implement/graph-overlay-yaml.ts +181 -4
  519. package/src/self-implement/graph-overlay.ts +3 -1
  520. package/src/self-implement/graph-profile-yaml.ts +107 -0
  521. package/src/self-implement/graph-yaml.ts +94 -5
  522. package/src/self-implement/off-diff-evidence.ts +249 -5
  523. package/src/self-implement/orchestrator.ts +298 -26
  524. package/src/self-implement/run-chart.ts +6 -3
  525. package/src/self-implement/run-ledger.ts +51 -1
  526. package/src/self-implement/runtime-overlay-run-steps.ts +95 -0
  527. package/src/self-implement/tdd-evidence-tags.ts +9 -0
  528. package/src/self-implement/test-scenario-request.ts +37 -6
  529. package/src/self-implement/train-gate-receipt.ts +166 -0
  530. package/src/self-implement/train-gate-remote.ts +62 -18
  531. package/src/session/chat.ts +6 -4
  532. package/src/session/session-fanout.ts +2 -0
  533. package/src/session/streaming/acp-stream-sink.ts +2 -1
  534. package/src/session/streaming/chunk-producer.ts +6 -0
  535. package/src/session/streaming/stream-compositor.ts +3 -2
  536. package/src/session-runtime/index.ts +74 -6
  537. package/src/session-runtime/retry-policy.ts +1 -1
  538. package/src/setup/llm-env-detect.ts +3 -0
  539. package/src/setup/service-key-catalog.ts +46 -0
  540. package/src/setup/service-keys.ts +241 -0
  541. package/src/sidetab-core/model.ts +205 -10
  542. package/src/sidetab-core/visible-agent-mission-pair.ts +51 -0
  543. package/src/sidetab-core/visible-agent-mission.ts +182 -48
  544. package/src/skills/tools/agent.ts +23 -4
  545. package/src/skills/tools/omni-search.ts +127 -27
  546. package/src/task-agent/parent-host.ts +29 -1
  547. package/src/task-agent/recall-inject.ts +98 -0
  548. package/src/task-agent/repair-outcomes.ts +65 -0
  549. package/src/task-agent/task-hand.ts +46 -14
  550. package/src/task-orchestrator/dispatcher.ts +14 -1
  551. package/src/task-orchestrator/linear-capture-events.ts +55 -0
  552. package/src/task-orchestrator/store.ts +16 -5
  553. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +23 -1
  554. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +107 -1
  555. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +113 -14
  556. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +21 -9
  557. package/src/task-orchestrator/surfaces/pod-source-receive.ts +23 -11
  558. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +2 -0
  559. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +1 -1
  560. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +467 -77
  561. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +45 -3
  562. package/src/task-orchestrator/surfaces/self-implement-pod.ts +210 -14
  563. package/src/task-orchestrator/surfaces/self-implement.ts +27 -3
  564. package/src/task-orchestrator/surfaces/warm-reuse-evidence.ts +169 -0
  565. package/src/task-orchestrator/types.ts +14 -0
  566. package/src/telegram.ts +14 -16
  567. package/src/terminal/coding-agent.ts +14 -5
  568. package/src/terminal/session-registry.ts +1 -1
  569. package/src/tool-hints/gate.ts +46 -14
  570. package/src/tool-hints/signals.ts +1 -1
  571. package/src/tool-hints/types.ts +2 -0
  572. package/src/tool-runtime/agent-runtime.ts +1 -0
  573. package/src/tool-runtime/browser-hand-runtime.ts +391 -0
  574. package/src/tool-runtime/browser-runtime.ts +33 -19
  575. package/src/tool-runtime/elanous-linear-issue-runtime.ts +76 -0
  576. package/src/tool-runtime/elanous-linear-secretary-runtime.ts +173 -0
  577. package/src/tool-runtime/graph-mcp-runtimes.ts +240 -0
  578. package/src/tool-runtime/index.ts +6 -0
  579. package/src/tool-runtime/types.ts +5 -0
  580. package/src/tui/entry.ts +51 -8
  581. package/src/tui/sidetab/attach.ts +252 -11
  582. package/src/tui/sidetab/herdr-portal.ts +225 -0
  583. package/src/tui/sidetab/list.ts +3 -2
  584. package/src/tui-client/next-dashboard-runtime.ts +52 -0
  585. package/src/user-config.ts +34 -9
  586. package/src/user-intent/types.ts +4 -3
  587. package/src/ux-sim/browser-hand.ts +165 -0
  588. package/src/ux-sim/draft-inventory-builder.ts +199 -0
  589. package/src/ux-sim/fake-browser-page.ts +81 -0
  590. package/src/ux-sim/fake-linear-device.ts +31 -0
  591. package/src/ux-sim/graph-engine-sim.ts +47 -0
  592. package/src/ux-sim/linear-secretary.ts +208 -0
  593. package/src/ux-sim/mock-scenario-catalog.json +81 -26
  594. package/src/ux-sim/mock-scenario-catalog.ts +175 -5
  595. package/src/ux-sim/onboarding-first-run-device.ts +31 -21
  596. package/src/ux-sim/release-sim-rig.ts +62 -18
  597. package/src/ux-sim/scenario.ts +70 -26
  598. package/src/ux-sim/service-key-setup.ts +113 -0
  599. package/src/ux-sim/term-slash-device.ts +74 -0
  600. package/src/ux-sim/turn-throw-sim.ts +31 -0
  601. package/src/version/packed-revision.json +1 -1
  602. package/src/web-search/exa.ts +77 -0
  603. package/src/web-search/index.ts +30 -9
  604. package/src/web-search/provider.ts +4 -1
  605. package/src/web-search/x-intent.ts +5 -0
  606. package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +0 -36
  608. package/apps/pwa/out/_next/static/chunks/1147-5196d19c222051b3.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/1319.b9b815ae0f181e06.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/1455-530ca16c7e71baff.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/1574.878c18ecc97b1bd4.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +0 -32
  614. package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/1945.7b54990d578c119b.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +0 -286
  620. package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +0 -34
  623. package/apps/pwa/out/_next/static/chunks/2456.b6de0e1c05f28843.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/2690.0521c738b7749931.js +0 -115
  629. package/apps/pwa/out/_next/static/chunks/2974.595d1e29d040cb6a.js +0 -64
  630. package/apps/pwa/out/_next/static/chunks/3207.a756c95e9ec8c3c8.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/3285.89ee2f298682f5e5.js +0 -93
  632. package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +0 -41
  633. package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +0 -24
  635. package/apps/pwa/out/_next/static/chunks/3741.9cf76acaa2ee5298.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/3837.a210d7d0db8d8abd.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +0 -77
  641. package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/4276.336d76d858fcdf1b.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/4320.583cbab64db6be02.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/4770.769c9cd9c7034eba.js +0 -148
  647. package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +0 -74
  648. package/apps/pwa/out/_next/static/chunks/50061469.0326382241ef3b2d.js +0 -122
  649. package/apps/pwa/out/_next/static/chunks/5112.4b9f300124fab7b3.js +0 -149
  650. package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +0 -27
  652. package/apps/pwa/out/_next/static/chunks/53c73f84.373b6160adfa89a4.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/5431-72a1dbde59400691.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/5440-4236de26c5ea5856.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/6131.348b7d6bdcd267ce.js +0 -226
  664. package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +0 -90
  665. package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +0 -104
  671. package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +0 -94
  672. package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/7279-c199ea83f34338fa.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +0 -24
  679. package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +0 -8
  687. package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/8505.fd803c6c33b54cc3.js +0 -79
  689. package/apps/pwa/out/_next/static/chunks/8546-6f03f8ea34dd61d9.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/9211-330b6736a63d4cb3.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/9249.976f1e69a9d80754.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/9353-12bfff0c130104cf.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/9633.ce5bddc56784da72.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/9656-374232558fd528d0.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/9832.f4a98c878ecf2c0a.js +0 -62
  705. package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0e3d7b9421b79dac.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/morning/page-0f291d3c8fd55a3a.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/term/page-bf067887b3307423.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +0 -1
  763. package/apps/pwa/out/_next/static/css/be9019f696217521.css +0 -1
  764. /package/apps/pwa/out/_next/static/{X1ucLw10Cds_h614NoEnh → HMXsxdy5MIIcHPMHv1wD4}/_ssgManifest.js +0 -0
@@ -1,6 +1,6 @@
1
- import { existsSync, readFileSync } from 'node:fs';
1
+ import { accessSync, constants, existsSync, readFileSync } from 'node:fs';
2
2
  import { homedir } from 'node:os';
3
- import { join } from 'node:path';
3
+ import { delimiter, join } from 'node:path';
4
4
  import { createHash } from 'node:crypto';
5
5
  import { addSource, listSources } from '../intake-plane/intake-sources.js';
6
6
  import { effectiveInstanceRoot } from '../instance/resolve.js';
@@ -11,6 +11,18 @@ import { recommendedSetup } from './setup-recommend.js';
11
11
  import { detectSkillCliAuth, type CliAuthStatus } from '../onboarding/cli-auth-status.js';
12
12
  import { debug } from '../debug/log.js';
13
13
  import { getUserConfig, saveUserConfig, userConfigPath, type UserConfig } from '../user-config.js';
14
+ import { collectServiceKeys, printKeySetupReport } from '../onboarding/key-setup.js';
15
+ import { getSecretAsync, setSecretAsync } from '../nexus/config/secrets/index.js';
16
+ import { probeProvider } from '../llm/provider-probe.js';
17
+ import { createSecretPrompt } from '../onboarding/secret-prompt.js';
18
+ import { realIO } from '../onboarding.js';
19
+ import { parseServiceKeyEnv, readMaskedServiceEnvPaste } from '../setup/service-keys.js';
20
+ import { importServiceKeys, renderServiceKeyStatus, runSetupKeys } from './setup-keys.js';
21
+ import { SERVICE_KEY_CATALOG, type ServiceKeyCatalogEntry } from '../setup/llm-env-detect.js';
22
+ import { serviceKeyStatus } from '../setup/service-keys.js';
23
+ import { detectProviders } from '../llm/provider-detect.js';
24
+ import { DEFAULT_PLUGIN_GROUP, defaultPluginStatuses } from '../plugins/install/plugin-install.js';
25
+ import type { DefaultPluginStatus } from '../plugins/install/plugin-install.js';
14
26
 
15
27
  const ELANOUS_LOGIN_COMMAND = 'elanous login openai-codex';
16
28
  const PROVIDER_COMMAND = 'elanous config set llm.provider openai-codex';
@@ -38,11 +50,18 @@ export interface SetupCliDeps extends DoctorOptions {
38
50
  planClaudePluginSetup?: typeof planClaudePluginSetup;
39
51
  applyClaudePluginSetup?: typeof applyClaudePluginSetup;
40
52
  prompt?: (message: string) => Promise<string | undefined>;
53
+ promptSecret?: (message: string) => Promise<string | undefined>;
54
+ getSecretAsync?: typeof getSecretAsync;
55
+ setSecretAsync?: typeof setSecretAsync;
56
+ probeKey?: typeof probeProvider;
41
57
  isStdinTty?: () => boolean;
42
58
  out?: { log: (value: string) => void; error?: (value: string) => void };
43
59
  setExitCode?: (code: number) => void;
44
60
  /** 런타임이 이 config 로 «실제로» 고르는 provider(`decideProviderForConfig().provider`). 시험 seam. */
45
61
  resolveRuntimeProvider?: (config: UserConfig) => string | undefined;
62
+ detectProviders?: typeof detectProviders;
63
+ getServiceKeyStatus?: typeof serviceKeyStatus;
64
+ isCommandAvailable?: (command: string) => boolean;
46
65
  }
47
66
 
48
67
  /** ⛔ 2026-09-23 — provider 단계는 «문자열 비교»가 아니라 ***런타임의 최종 결정***으로 잰다.
@@ -118,6 +137,10 @@ function missingRequiredCommands(doctor: DoctorReport): boolean {
118
137
  return doctor.externalCommands.some((command) => command.status === 'missing' && command.tier === 'required');
119
138
  }
120
139
 
140
+ function missingGitCapability(doctor: DoctorReport): boolean {
141
+ return doctor.externalCommands.some((command) => command.name === 'git' && command.status !== 'found');
142
+ }
143
+
121
144
  function displayCommand(command: string[]): string {
122
145
  return command.map((arg) => /^[A-Za-z0-9_@%+=:,./-]+$/.test(arg)
123
146
  ? arg
@@ -128,7 +151,7 @@ export function formatSetupReport(doctor: DoctorReport, steps: SetupStep[], nonI
128
151
  const elanousLogin = steps[0]!.complete;
129
152
  const provider = steps[1]!.complete;
130
153
  const codexLogin = steps[2]!.complete;
131
- const externalReady = doctor.ok && !missingRequiredCommands(doctor);
154
+ const externalReady = doctor.ok && !missingRequiredCommands(doctor) && !missingGitCapability(doctor);
132
155
  const capabilities = [
133
156
  { name: 'OpenAI Codex-backed elanous sessions', ready: elanousLogin && provider },
134
157
  { name: 'Codex app-server integration', ready: codexLogin && externalReady },
@@ -215,13 +238,82 @@ function formatDefaultBundleProposal(): string[] {
215
238
  ];
216
239
  }
217
240
 
241
+ /** Check the default plugin group's required/optional connector declarations against the runtime catalog. */
242
+ export function validateDefaultPluginServiceKeys(
243
+ group: readonly { id: string; requiredServiceKeys: readonly string[]; optionalServiceKeys: readonly string[] }[] = DEFAULT_PLUGIN_GROUP,
244
+ catalog: readonly Pick<ServiceKeyCatalogEntry, 'id' | 'kind'>[] = SERVICE_KEY_CATALOG,
245
+ ): string[] {
246
+ const errors: string[] = [];
247
+ const catalogIds = new Set<string>();
248
+ for (const item of catalog) {
249
+ if (catalogIds.has(item.id)) errors.push(`중복 서비스 카탈로그 id: ${item.id}`);
250
+ catalogIds.add(item.id);
251
+ }
252
+ for (const plugin of group) {
253
+ const required = new Set<string>();
254
+ const optional = new Set<string>();
255
+ for (const id of plugin.requiredServiceKeys) {
256
+ if (required.has(id)) errors.push(`${plugin.id}: 필수 키 중복 ${id}`);
257
+ required.add(id);
258
+ }
259
+ for (const id of plugin.optionalServiceKeys) {
260
+ if (optional.has(id)) errors.push(`${plugin.id}: 선택 키 중복 ${id}`);
261
+ optional.add(id);
262
+ if (required.has(id)) errors.push(`${plugin.id}: required/optional 중복 ${id}`);
263
+ }
264
+ for (const id of [...required, ...optional]) {
265
+ const item = catalog.find(candidate => candidate.id === id);
266
+ if (!item) errors.push(`${plugin.id}: 서비스 카탈로그에 없는 키 ${id}`);
267
+ else if (item.kind !== 'api-key') errors.push(`${plugin.id}: API 키가 아닌 서비스 참조 ${id} (${item.kind})`);
268
+ }
269
+ }
270
+ return errors;
271
+ }
272
+
273
+ function commandAvailable(command: string): boolean {
274
+ const path = process.env.PATH ?? '';
275
+ return path.split(delimiter).some(directory => {
276
+ try { accessSync(join(directory, command), constants.X_OK); return true; } catch { return false; }
277
+ });
278
+ }
279
+
280
+ function formatDefaultPluginStatuses(statuses: readonly DefaultPluginStatus[]): string[] {
281
+ return [
282
+ 'Setup: 기본 플러그인 묶음 상태 (실제 키·선행 조건)',
283
+ ...statuses.map(plugin => {
284
+ const missing = [
285
+ ...(plugin.missingRequiredKeys.length ? [`필수 키 ${plugin.missingRequiredKeys.join(', ')}`] : []),
286
+ ...(plugin.missingPrerequisites.length ? [`선행 조건 ${plugin.missingPrerequisites.join(', ')}`] : []),
287
+ ];
288
+ const optional = plugin.optionalKeysMissing.length
289
+ ? ` · 선택 키 미설정 ${plugin.optionalKeysMissing.join(', ')}` : '';
290
+ return `${plugin.status === 'ready' ? '✓' : '○'} ${plugin.label}: ${plugin.status}${missing.length ? ` · ${missing.join(' · ')}` : ''}${optional}`;
291
+ }),
292
+ ];
293
+ }
294
+
295
+ async function readDefaultPluginStatuses(deps: SetupCliDeps): Promise<DefaultPluginStatus[]> {
296
+ const catalogErrors = validateDefaultPluginServiceKeys();
297
+ if (catalogErrors.length) throw new Error(`기본 플러그인 서비스 카탈로그 오류: ${catalogErrors.join('; ')}`);
298
+ const keys = (deps.getServiceKeyStatus ?? serviceKeyStatus)()
299
+ .filter(item => item.configured).map(item => item.id);
300
+ const providers = await (deps.detectProviders ?? detectProviders)();
301
+ const prerequisites = new Set<string>();
302
+ if (providers.some(provider => provider.available && provider.auth !== 'agent-cli')) prerequisites.add('llm-provider');
303
+ if ((deps.isCommandAvailable ?? commandAvailable)('aside')) prerequisites.add('aside');
304
+ if ((deps.isCommandAvailable ?? commandAvailable)('claude')) prerequisites.add('claude-cli');
305
+ if ((deps.isCommandAvailable ?? commandAvailable)('gh')) prerequisites.add('github-cli');
306
+ return defaultPluginStatuses({ readyServiceKeyIds: keys, satisfiedPrerequisites: [...prerequisites] });
307
+ }
308
+
218
309
  export function registerSetupCommand(program: Command, deps: SetupCliDeps = {}): void {
219
310
  const out = deps.out ?? { log: (value: string) => console.log(value), error: (value: string) => console.error(value) };
220
311
  const setExitCode = deps.setExitCode ?? ((code: number) => { process.exitCode = code; });
221
312
  const doctorRunner = deps.runDoctor ?? runDoctor;
222
313
  const isFirstRunSetup = (): boolean => deps.firstRunTopics ?? (!deps.getUserConfig && !existsSync(userConfigPath()));
223
- const showDefaultBundleProposal = (): void => {
314
+ const showDefaultBundleProposal = async (): Promise<void> => {
224
315
  for (const line of formatDefaultBundleProposal()) out.log(line);
316
+ for (const line of formatDefaultPluginStatuses(await readDefaultPluginStatuses(deps))) out.log(line);
225
317
  };
226
318
  const showCliSkills = (apply: boolean) => {
227
319
  out.log('Setup: CLI skills (public GitHub repository reads remain available without login)');
@@ -233,6 +325,8 @@ export function registerSetupCommand(program: Command, deps: SetupCliDeps = {}):
233
325
  const rl = createInterface({ input: process.stdin, output: process.stdout });
234
326
  try { return await rl.question(message); } finally { rl.close(); }
235
327
  });
328
+ // API keys must never fall back to the ordinary (echoing) setup prompt.
329
+ const askSecret = deps.promptSecret ?? createSecretPrompt();
236
330
 
237
331
  const setup = program.command('setup')
238
332
  .description('Check OpenAI Codex setup and guide each missing credential step')
@@ -243,7 +337,7 @@ export function registerSetupCommand(program: Command, deps: SetupCliDeps = {}):
243
337
  if (opts.nonInteractive) {
244
338
  out.log(formatSetupReport(doctor, setupSteps(deps), true));
245
339
  showCliSkills(false);
246
- if (isFirstRunSetup()) showDefaultBundleProposal();
340
+ if (isFirstRunSetup()) await showDefaultBundleProposal();
247
341
  for (const line of recommendedSetup((deps.getUserConfig ?? getUserConfig)())) out.log(line);
248
342
  setExitCode(0);
249
343
  return;
@@ -268,7 +362,7 @@ export function registerSetupCommand(program: Command, deps: SetupCliDeps = {}):
268
362
  }
269
363
  out.log(formatSetupReport(doctor, steps, false));
270
364
  showCliSkills(false);
271
- if (isFirstRun) showDefaultBundleProposal();
365
+ if (isFirstRun) await showDefaultBundleProposal();
272
366
  for (const line of recommendedSetup((deps.getUserConfig ?? getUserConfig)())) out.log(line);
273
367
  let configured = (deps.getUserConfig ?? getUserConfig)();
274
368
  if (!configured.starter?.topics && configured.watch?.enabled !== false
@@ -314,6 +408,31 @@ export function registerSetupCommand(program: Command, deps: SetupCliDeps = {}):
314
408
  setExitCode(0);
315
409
  });
316
410
 
411
+ setup.command('service-keys')
412
+ .description('Import and verify service API keys without rendering their values')
413
+ .action(async () => {
414
+ if (!isStdinTty()) {
415
+ (out.error ?? out.log)('키 설정은 stdin TTY가 있는 자리에서만 실행할 수 있다.');
416
+ setExitCode(1);
417
+ return;
418
+ }
419
+ try {
420
+ const results = await collectServiceKeys({
421
+ config: (deps.getUserConfig ?? getUserConfig)(),
422
+ promptSecret: askSecret,
423
+ print: out.log,
424
+ getSecret: deps.getSecretAsync,
425
+ setSecret: deps.setSecretAsync,
426
+ probe: deps.probeKey,
427
+ });
428
+ printKeySetupReport(results, out.log);
429
+ setExitCode(results.some((result) => result.status === 'failed') ? 1 : 0);
430
+ } catch {
431
+ (out.error ?? out.log)('키 설정을 완료하지 못했습니다. 민감한 오류 내용은 숨겼습니다.');
432
+ setExitCode(1);
433
+ }
434
+ });
435
+
317
436
  setup.command('claude-code')
318
437
  .description('Plan or install the elanous Claude Code plugin')
319
438
  .option('--apply', 'Install missing steps and verify the MCP connection')
@@ -365,4 +484,45 @@ export function registerSetupCommand(program: Command, deps: SetupCliDeps = {}):
365
484
  setExitCode(1);
366
485
  }
367
486
  });
487
+
488
+ setup.command('keys')
489
+ .description('Set up service credentials without printing secret values')
490
+ .option('--status', 'Show credential presence only')
491
+ .option('--import-env-file <path>', 'Import catalogued keys from a dotenv file')
492
+ .option('--paste-env', 'Paste a dotenv block into a hidden terminal prompt')
493
+ .option('--all', 'Include optional service keys during interactive setup; --status always shows all services')
494
+ .action(async (opts: { status?: boolean; importEnvFile?: string; pasteEnv?: boolean; all?: boolean }) => {
495
+ const keyConfig = (deps.getUserConfig ?? getUserConfig)();
496
+ const keyOptions = { config: keyConfig, includeOptional: opts.all === true };
497
+ try {
498
+ if (opts.status) {
499
+ if (opts.all) throw new Error('--status already shows the full catalog; omit --all');
500
+ for (const line of renderServiceKeyStatus()) out.log(line);
501
+ for (const line of formatDefaultPluginStatuses(await readDefaultPluginStatuses(deps))) out.log(line);
502
+ setExitCode(0);
503
+ return;
504
+ }
505
+ let text: string | undefined;
506
+ if (opts.importEnvFile) text = readFileSync(opts.importEnvFile, 'utf8');
507
+ else if (opts.pasteEnv) {
508
+ if (!isStdinTty()) throw new Error('hidden paste import requires a terminal');
509
+ text = await readMaskedServiceEnvPaste();
510
+ }
511
+ if (text !== undefined) {
512
+ const parsed = parseServiceKeyEnv(text);
513
+ const result = await importServiceKeys(parsed, { print: (line) => out.log(line) }, keyOptions);
514
+ setExitCode(result.rejected.length ? 1 : 0);
515
+ return;
516
+ }
517
+ if (!isStdinTty()) throw new Error('secret input requires a terminal; use --import-env-file for a protected dotenv file');
518
+ const io = realIO();
519
+ try { await runSetupKeys(io, keyOptions); }
520
+ finally { io.close(); }
521
+ setExitCode(0);
522
+ } catch (error) {
523
+ const message = error instanceof Error ? error.message : 'setup keys failed';
524
+ (out.error ?? out.log)(message.replace(/\r?\n/g, ' '));
525
+ setExitCode(1);
526
+ }
527
+ });
368
528
  }
@@ -0,0 +1,199 @@
1
+ import { SERVICE_KEY_CATALOG } from '../setup/llm-env-detect.js';
2
+ import { serviceKeyStatus, storeServiceKeys, verifyServiceKey, type ParsedServiceKeyEnv } from '../setup/service-keys.js';
3
+ import { detectProviders } from '../llm/provider-detect.js';
4
+ import { loginWithCodex } from '../oauth/codex.js';
5
+ import type { FirstRunProviderSetupResult } from '../onboarding/first-run.js';
6
+ import { MODEL_ROLES, resolveRoleLlm, type LLMProviderName, type UserConfig } from '../user-config.js';
7
+ import { parseMenuAnswer } from '../onboarding/menu-answer.js';
8
+
9
+ export interface SetupKeysIO {
10
+ ask(prompt: string): Promise<string>;
11
+ askSecret?(prompt: string): Promise<string>;
12
+ print(message: string): void;
13
+ }
14
+
15
+ export type SetupKeyProvider = Extract<(typeof SERVICE_KEY_CATALOG)[number], { kind: 'api-key' }>['id'];
16
+ export type SetupKeyValidationResult =
17
+ | { success: true; verification: 'verified' | 'unsupported' }
18
+ | { success: false; reason: 'invalid' | 'rate-limited' | 'unavailable'; httpStatus?: number };
19
+ export type SetupKeyVerifier = (input: { provider: SetupKeyProvider; apiKey: string }) => Promise<SetupKeyValidationResult>;
20
+
21
+ export interface SetupKeysOptions {
22
+ config: UserConfig;
23
+ env?: NodeJS.ProcessEnv;
24
+ cacheDir?: string;
25
+ includeOptional?: boolean;
26
+ /** Existing OAuth fetch injection used by deterministic login simulation. */
27
+ loginWithCodex?: typeof loginWithCodex;
28
+ /** Verification seam for deterministic setup simulations; the production default remains verifyServiceKey. */
29
+ verifier?: SetupKeyVerifier;
30
+ }
31
+
32
+ function providerForService(id: string): string | undefined {
33
+ switch (id) {
34
+ case 'openai-api': return 'openai';
35
+ case 'anthropic-api': return 'anthropic';
36
+ case 'gemini-api': return 'gemini';
37
+ case 'openrouter': return 'openrouter';
38
+ case 'xai': return 'grok';
39
+ case 'opengateway': return 'opengateway';
40
+ default: return undefined;
41
+ }
42
+ }
43
+
44
+ function providerBaseUrl(config: UserConfig, serviceId: string): string | undefined {
45
+ const provider = providerForService(serviceId);
46
+ if (!provider) return undefined;
47
+ return config.llm.rotation?.find(item => item.provider === provider)?.baseUrl;
48
+ }
49
+
50
+ function renderProviderProposal(config: UserConfig, providers: Awaited<ReturnType<typeof detectProviders>>): string[] {
51
+ const available = providers.filter(provider => provider.available).sort((a, b) => a.rank - b.rank);
52
+ const ordered = [...new Set(available.map(provider => provider.provider))];
53
+ const defaultProvider = ordered.includes(config.llm.provider) ? config.llm.provider : ordered[0];
54
+ const fallback = config.llm.fallbackChain ?? [];
55
+ const suggestion = defaultProvider ? [defaultProvider, ...ordered.filter(name => name !== defaultProvider)] : [];
56
+ return [
57
+ `LLM 감지: ${available.length ? available.map(provider => `${provider.provider}(${provider.auth})`).join(' · ') : '사용 가능한 인증 없음'}`,
58
+ `기본 제안: ${defaultProvider ?? '설정 후 선택'} · 현재 기본: ${config.llm.provider}`,
59
+ `폴백 제안: ${suggestion.length ? suggestion.join(' → ') : '현재 설정 유지'} · 현재 llm.fallbackChain: ${fallback.length ? fallback.join(' → ') : '미설정'}`,
60
+ `역할별 현재 해석: ${MODEL_ROLES.map(role => {
61
+ try {
62
+ const resolved = resolveRoleLlm(role, { config });
63
+ return `${role}=${resolved.provider}/${resolved.model}`;
64
+ } catch {
65
+ return `${role}=미설정`;
66
+ }
67
+ }).join(' · ')}`,
68
+ '위 내용은 제안만 표시하며 roleLlm·llm.fallbackChain을 변경하지 않습니다.',
69
+ ];
70
+ }
71
+
72
+ export function renderServiceKeyStatus(options: { env?: NodeJS.ProcessEnv; cacheDir?: string } = {}): string[] {
73
+ const status = serviceKeyStatus(options);
74
+ return SERVICE_KEY_CATALOG.map(item => {
75
+ const row = status.find(candidate => candidate.id === item.id);
76
+ if (!row) return `${item.label}: 상태 확인 불가`;
77
+ if (item.kind === 'api-key') return `${item.label}: ${row.configured ? '키 있음' : '키 필요'} (${item.envNames.join(', ')})`;
78
+ return `${item.label}: ${item.kind === 'subscription' || item.kind === 'oauth' || item.kind === 'cli' ? '로그인/설치 상태는 별도 감지' : '로컬 도구 확인 필요'}`;
79
+ });
80
+ }
81
+
82
+ export async function importServiceKeys(values: ParsedServiceKeyEnv, io: Pick<SetupKeysIO, 'print'>, options: SetupKeysOptions): Promise<{ stored: string[]; rejected: string[]; unverified: string[] }> {
83
+ const accepted = new Map<string, string>();
84
+ const rejected: string[] = [];
85
+ const unverified: string[] = [];
86
+ const env = options.env ?? process.env;
87
+ for (const [name, value] of values) {
88
+ const item = SERVICE_KEY_CATALOG.find(candidate => candidate.kind === 'api-key' && candidate.envNames.includes(name));
89
+ if (!item) { rejected.push(name); continue; }
90
+ if (env[name]?.trim() === value) io.print(`${name}: 환경에서 이미 제공됨 · 캐시에도 저장합니다 · 값 출력 0`);
91
+ const verification = options.verifier
92
+ ? await options.verifier({ provider: item.id as SetupKeyProvider, apiKey: value })
93
+ : await verifyServiceKey(item.id, value, {
94
+ env,
95
+ cacheDir: options.cacheDir,
96
+ baseUrl: providerBaseUrl(options.config, item.id),
97
+ }).then(({ result, httpStatus }): SetupKeyValidationResult => result === 'verified' || result === 'unsupported'
98
+ ? { success: true, verification: result }
99
+ : { success: false, reason: result, ...(httpStatus === undefined ? {} : { httpStatus }) });
100
+ if (verification.success && verification.verification === 'verified') accepted.set(name, value);
101
+ else if (verification.success && verification.verification === 'unsupported') {
102
+ accepted.set(name, value);
103
+ unverified.push(name);
104
+ io.print(`${item.label}: 최소 확인을 지원하지 않아 검증 없이 저장합니다 · 값 출력 0`);
105
+ }
106
+ else {
107
+ rejected.push(name);
108
+ io.print(`${item.label}: 검증 ${verification.reason}${verification.httpStatus ? ` (HTTP ${verification.httpStatus})` : ''} · 저장 안 함`);
109
+ }
110
+ }
111
+ const saved = accepted.size ? storeServiceKeys(accepted, { env, cacheDir: options.cacheDir }) : { stored: [] };
112
+ if (saved.stored.length) io.print(`저장 완료: ${saved.stored.join(', ')} · 값 출력 0`);
113
+ return { stored: saved.stored, rejected: rejected.sort(), unverified: unverified.sort() };
114
+ }
115
+
116
+ export async function runSetupKeys(io: SetupKeysIO, options: SetupKeysOptions): Promise<{ stored: string[]; skipped: string[] }> {
117
+ const providers = await detectProviders({ env: options.env });
118
+ for (const line of renderProviderProposal(options.config, providers)) io.print(line);
119
+ const { listCodexAccountsInStore } = await import('../oauth/codex-account-store.js');
120
+ const codexAccounts = listCodexAccountsInStore().map(account => account.name);
121
+ io.print(`Codex 계정: ${codexAccounts.length ? codexAccounts.join(', ') : '없음'} · 추가: 별도 CODEX_HOME에서 codex login 후 elanous provider codex account import <이름> --home <홈>`);
122
+ const statuses = serviceKeyStatus({ env: options.env, cacheDir: options.cacheDir });
123
+ const entries = SERVICE_KEY_CATALOG.filter(item => item.kind === 'api-key' && (item.demoRequired || options.includeOptional));
124
+ const stored: string[] = [];
125
+ const skipped: string[] = [];
126
+ for (const item of entries) {
127
+ const status = statuses.find(candidate => candidate.id === item.id);
128
+ if (!status) { io.print(`${item.label}: 상태 확인 불가 · 건너뜀`); skipped.push(item.id); continue; }
129
+ if (status.configured) { io.print(`${item.label}: 이미 설정됨`); continue; }
130
+ const envName = item.envNames[0];
131
+ if (!envName) continue;
132
+ io.print(`${item.label} · ${item.setupUrl} · ${item.demoRequired ? '데모 필요' : '선택'}`);
133
+ if (!io.askSecret) {
134
+ io.print(`${item.label}: 이 입력 화면은 비밀 입력을 지원하지 않습니다 · eln setup keys --paste-env 사용`);
135
+ skipped.push(item.id);
136
+ continue;
137
+ }
138
+ const value = (await io.askSecret(`${envName} (Enter=건너뜀): `)).trim();
139
+ if (!value) { skipped.push(item.id); continue; }
140
+ const result = await importServiceKeys(new Map([[envName, value]]), io, options);
141
+ if (result.stored.includes(envName)) stored.push(envName);
142
+ else skipped.push(item.id);
143
+ }
144
+ for (const line of renderServiceKeyStatus({ env: options.env, cacheDir: options.cacheDir })) io.print(line);
145
+ return { stored, skipped };
146
+ }
147
+
148
+ export const FIRST_RUN_PROVIDER_SETUP_MENU_HEADING = '처음 실행 LLM 설정';
149
+ export const FIRST_RUN_PROVIDER_SETUP_MENU_CHOICES = '1 Codex 구독 로그인 · 2 API 키 입력 · Enter 건너뛰기';
150
+ export const FIRST_RUN_PROVIDER_SETUP_MENU_MAX_MISSES = 3;
151
+
152
+ /** First-run entry: offer the existing Codex device login or the same verified-key flow as `setup keys`. */
153
+ export async function runFirstRunProviderSetup(io: SetupKeysIO, options: SetupKeysOptions): Promise<FirstRunProviderSetupResult> {
154
+ const choices = ['codex-login', 'api-key'] as const;
155
+ let misses = 0;
156
+ let choice: typeof choices[number];
157
+ for (;;) {
158
+ io.print(FIRST_RUN_PROVIDER_SETUP_MENU_HEADING);
159
+ io.print(FIRST_RUN_PROVIDER_SETUP_MENU_CHOICES);
160
+ const parsed = parseMenuAnswer(await io.ask('선택: '), choices);
161
+ if (parsed.kind === 'cancel') return null;
162
+ if (parsed.kind === 'miss') {
163
+ misses += 1;
164
+ if (misses >= FIRST_RUN_PROVIDER_SETUP_MENU_MAX_MISSES) return { kind: 'needs-llm' };
165
+ continue;
166
+ }
167
+ choice = parsed.provider;
168
+ break;
169
+ }
170
+
171
+ if (choice === 'codex-login') {
172
+ try {
173
+ await (options.loginWithCodex ?? loginWithCodex)({ onProgress: (event) => {
174
+ if (event.type === 'user_code') io.print(`Codex 로그인: ${event.loginUrl} · 코드 ${event.userCode}`);
175
+ else if (event.type === 'polling') io.print('Codex 로그인을 기다리는 중…');
176
+ else if (event.type === 'exchanging') io.print('Codex 로그인을 확인하는 중…');
177
+ } });
178
+ io.print('Codex 로그인 완료');
179
+ return 'openai-codex';
180
+ } catch {
181
+ io.print('Codex 로그인을 완료하지 못했습니다. 다시 시도하거나 Enter로 건너뛰세요.');
182
+ return null;
183
+ }
184
+ }
185
+ // Keep the exact environment object through storage and rediscovery: storeServiceKeys
186
+ // writes accepted values into it as well as the protected cache, so a newly entered
187
+ // key is immediately visible to detectProviders and resolveProviderCredential.
188
+ const env = options.env ?? process.env;
189
+ await runSetupKeys(io, { ...options, env });
190
+ // runSetupKeys handles an absent askSecret capability per item (skip + safe guidance);
191
+ // it does not throw or turn the first-run entry into a crash.
192
+ const providers = (await detectProviders({ env }))
193
+ .filter(provider => provider.available && provider.auth === 'apikey');
194
+ const available = [...new Set(providers.map(provider => provider.provider as LLMProviderName))];
195
+ if (!available.length) return null;
196
+ io.print(`기본 공급자 선택: ${available.map((provider, index) => `${index + 1} ${provider}`).join(' · ')}`);
197
+ const answer = (await io.ask('기본 공급자 번호 (Enter=건너뜀): ')).trim();
198
+ return available[Number(answer) - 1] ?? null;
199
+ }
@@ -0,0 +1,114 @@
1
+ import { isAbsolute, relative, resolve, sep } from 'node:path';
2
+ import { realpath } from 'node:fs/promises';
3
+ import { startClassicMissionCli } from '../dashboard/mission-cli-consumer.js';
4
+ import type { MissionCliConsumerDeps } from '../dashboard/mission-cli-consumer.js';
5
+ import { requestQuestion, getDefaultQuestionChannels } from '../hitl/question.js';
6
+ import type { QuestionChannel } from '../hitl/question.js';
7
+ import { sendOutbound } from '../domains/outbound-alert.js';
8
+ import type { AskUserQuestionRequest, AskUserQuestionResult } from '../ask-user-question/types.js';
9
+ import { PLUGIN_WIZARD_MARKET_QUESTION } from '../graph-wizard/mission-compose.js';
10
+ import type { PluginMaker, PluginWizardDeps } from '../graph-wizard/mission-compose.js';
11
+
12
+ export interface TaskPluginWizardHostResult {
13
+ ok: boolean;
14
+ content?: string;
15
+ error?: string;
16
+ }
17
+
18
+ export interface TaskPluginWizardHostPorts {
19
+ questionChannels?: () => QuestionChannel[];
20
+ sendReport?: (report: string, kind: 'report') => Promise<unknown> | unknown;
21
+ searchMarket?: PluginWizardDeps['searchMarket'];
22
+ missionConsumerDeps?: MissionCliConsumerDeps;
23
+ runMission?: (request: { maker: PluginMaker; prompt: string }) => Promise<TaskPluginWizardHostResult>;
24
+ runMissionPair?: (request: { makers: readonly PluginMaker[]; prompt: string }) => Promise<Partial<Record<PluginMaker, TaskPluginWizardHostResult>>>;
25
+ onEvent?: PluginWizardDeps['onEvent'];
26
+ }
27
+
28
+ async function runClassicMission(maker: PluginMaker, prompt: string, deps?: MissionCliConsumerDeps): Promise<TaskPluginWizardHostResult> {
29
+ const started = await startClassicMissionCli({ agent: maker, prompt }, deps);
30
+ const result = 'completion' in started ? await started.completion : started;
31
+ return { ok: result.ok, ...(result.content ? { content: result.content } : {}), ...(result.error ? { error: result.error } : {}) };
32
+ }
33
+
34
+ function questionRequest(questions: readonly string[]): AskUserQuestionRequest {
35
+ return {
36
+ questions: questions.map((question, index) => ({
37
+ id: `plugin_wizard_${index + 1}`,
38
+ header: '플러그인',
39
+ question,
40
+ options: question.trim() === PLUGIN_WIZARD_MARKET_QUESTION
41
+ ? [
42
+ { label: '마켓', description: '신뢰된 마켓 후보를 먼저 찾아 시험합니다.' },
43
+ { label: '사이드탭', description: 'Claude와 Codex에 같은 작업을 맡겨 비교합니다.' },
44
+ ]
45
+ : [
46
+ { label: '기본안', description: '마법사가 미션과 도구 이름에서 기본 구현을 정합니다.' },
47
+ { label: '직접 입력', description: '원하는 기능을 직접 적습니다.' },
48
+ ],
49
+ includeOther: true,
50
+ })),
51
+ };
52
+ }
53
+
54
+ function answerMap(result: AskUserQuestionResult): Record<string, string> | undefined {
55
+ const answers: Record<string, string> = {};
56
+ for (const [id, raw] of Object.entries(result.answers)) {
57
+ const typed = result.otherText?.[id]?.trim();
58
+ const value = typed || (Array.isArray(raw) ? raw.join(', ') : raw);
59
+ if (typeof value === 'string' && value.trim()) answers[id] = value.trim();
60
+ }
61
+ return Object.keys(answers).length ? answers : undefined;
62
+ }
63
+
64
+ async function pluginSpec(content: string | undefined, workspace: string): Promise<string> {
65
+ const spec = content?.match(/(?:^|\r?\n)PLUGIN_SPEC=([^\r\n]+)\s*$/m)?.[1]?.trim();
66
+ if (!spec || !isAbsolute(spec)) throw new Error('Claude/Codex 결과에 절대경로 PLUGIN_SPEC이 없습니다');
67
+ const [workspacePath, pluginPath] = await Promise.all([realpath(resolve(workspace)), realpath(resolve(spec))]);
68
+ const fromWorkspace = relative(workspacePath, pluginPath);
69
+ if (!fromWorkspace || fromWorkspace === '..' || fromWorkspace.startsWith(`..${sep}`) || isAbsolute(fromWorkspace)) {
70
+ throw new Error('Claude/Codex PLUGIN_SPEC은 세션 작업실 안의 경로여야 합니다');
71
+ }
72
+ return pluginPath;
73
+ }
74
+
75
+ /** Wire the plugin wizard onto existing question, outbound, and classic side-tab host abstractions. */
76
+ export function createTaskPluginWizardHostDeps(ports: TaskPluginWizardHostPorts = {}): PluginWizardDeps {
77
+ const ask = async (request: AskUserQuestionRequest): Promise<AskUserQuestionResult> => {
78
+ const response = await requestQuestion({ request, channels: ports.questionChannels?.() ?? getDefaultQuestionChannels() });
79
+ return response.result;
80
+ };
81
+ const sendReport = ports.sendReport ?? ((report: string, kind: 'report') => sendOutbound(report, kind));
82
+ const runMission = ports.runMission ?? ((request: { maker: PluginMaker; prompt: string }) =>
83
+ runClassicMission(request.maker, request.prompt, ports.missionConsumerDeps));
84
+
85
+ return {
86
+ ask: async (questions) => answerMap(await ask(questionRequest(questions))),
87
+ // When omitted, composePluginMission uses its built-in trusted-market search.
88
+ ...(ports.searchMarket ? { searchMarket: ports.searchMarket } : {}),
89
+ develop: async ({ maker, goal, workspace }) => {
90
+ const prompt = [goal, '', `세션 작업실: ${workspace}`,
91
+ '플러그인을 작업실 안에 만들고, 끝에 PLUGIN_SPEC=<absolute plugin directory> 한 줄을 정확히 출력해 주세요.'].join('\n');
92
+ const result = await runMission({ maker, prompt });
93
+ if (!result.ok) throw new Error(result.error ?? `${maker} side-tab mission failed`);
94
+ return { spec: await pluginSpec(result.content, workspace) };
95
+ },
96
+ ...(ports.runMissionPair ? {
97
+ developPair: async ({ makers, goal, workspace }: { makers: readonly PluginMaker[]; goal: string; workspace: string }) => {
98
+ const prompt = [goal, '', `세션 작업실: ${workspace}`,
99
+ '플러그인을 작업실 안에 만들고, 끝에 PLUGIN_SPEC=<absolute plugin directory> 한 줄을 정확히 출력해 주세요.'].join('\n');
100
+ const results = await ports.runMissionPair!({ makers, prompt });
101
+ const specs: Partial<Record<PluginMaker, { spec: string }>> = {};
102
+ for (const maker of makers) {
103
+ const result = results[maker];
104
+ if (!result?.ok) continue;
105
+ try { specs[maker] = { spec: await pluginSpec(result.content, workspace) }; }
106
+ catch { /* one malformed maker result must not discard the other maker's candidate */ }
107
+ }
108
+ return specs;
109
+ },
110
+ } : {}),
111
+ notify: async (report) => { await sendReport(report, 'report'); },
112
+ ...(ports.onEvent ? { onEvent: ports.onEvent } : {}),
113
+ };
114
+ }