elanous 0.2.41 → 0.2.43

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 (796) 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/{GiOLWmt4MqDZePubBjA4Q → Om5xS9jpjSXJCeTNGYEi4}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{2fe2c302.41b517f88d6fe502.js → 0966f8a1.745fcd44f64a87ea.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{385e4574.e9886ab32759eda3.js → 0ad6802e.ae7afb63fdcb4491.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/114.2b90424d1a3ce84c.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1151-5c2bb8f002ca2dd6.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1200.6a37c202f9f17e9a.js +226 -0
  9. package/apps/pwa/out/_next/static/chunks/1261-a616d5728e02e624.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1313-19f737e0222c4444.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1357.3bbef3976c37f94a.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/1362-20adddfaf662b0fa.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/{6874.d5cf7eb8edb2cabe.js → 1406.a1dc2ab6f8449374.js} +2 -2
  14. package/apps/pwa/out/_next/static/chunks/1737-9491fc6ab29b9ec6.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1803-4f91a8e7dcaf042c.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{5744.b9415e18ad623100.js → 1961.a81b12872c3e93a9.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/1970cf59.2d4d8ce5d6c81853.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1971-8890f3962ba7ee0a.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/2073-ba274e00e4f9efb4.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/{5471.1e611302ed3a7c53.js → 2144.25b292396712196d.js} +2 -2
  21. package/apps/pwa/out/_next/static/chunks/{3230-49298c3b73ef2268.js → 2268-53861f339e0b65a2.js} +1 -1
  22. package/apps/pwa/out/_next/static/chunks/{9834.63ab2bbc3153172e.js → 2312.0c8b61e22d3136d7.js} +1 -1
  23. package/apps/pwa/out/_next/static/chunks/{1800.f7ff51dc4978a958.js → 2573.387a707f6f9d720c.js} +2 -2
  24. package/apps/pwa/out/_next/static/chunks/273.f156eee28f11af77.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2873.d2140e5a82546401.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/{9048.212083de42d25be3.js → 3072.01338851ca21a6f7.js} +2 -2
  27. package/apps/pwa/out/_next/static/chunks/3091.a5a4143dea33d197.js +90 -0
  28. package/apps/pwa/out/_next/static/chunks/3095.dc44586a5f83b86d.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{2263.e09b6edea33bad2d.js → 3113.d7472bbc27d580c7.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/3228-9650b6447b6fa288.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/3402.44b565b314f2263c.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{addc2b32.8c4ff8f0aefe987d.js → 3557ac4a.c8931684475018ad.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/360.ae9f9f4c33c395e8.js +79 -0
  34. package/apps/pwa/out/_next/static/chunks/3638.80412ea63aae8f3f.js +286 -0
  35. package/apps/pwa/out/_next/static/chunks/{a0a01613.6d1cca322238d7fe.js → 363bfab3.9623b9f89363541f.js} +1 -1
  36. package/apps/pwa/out/_next/static/chunks/3694.e0099884345f0198.js +64 -0
  37. package/apps/pwa/out/_next/static/chunks/3744.54f87db52acfd1ab.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3903.3ef4656c67572764.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3935.16701e33f8982dc9.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3955.6922286237f2ac2b.js +24 -0
  41. package/apps/pwa/out/_next/static/chunks/3969.272ee7f9fd6c62e5.js +34 -0
  42. package/apps/pwa/out/_next/static/chunks/4199.ce86b281fd0a60b7.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4311-6dd3144002cc0c2d.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4426-2b230fad00c88930.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{530.d26346e18089640a.js → 4445.7990c76b3751a918.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4447-14c5161fa59166c7.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4856-b0b8075bba8c53f4.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4870-de370d65e73c0bb5.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4885-2c989165c4b29fad.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4894.fec2ca9e99caefa2.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/5093.8f04b7f8cb899a95.js +94 -0
  52. package/apps/pwa/out/_next/static/chunks/5122-2bb177cebf89e19a.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/5154.5f56dc3902e3d275.js +36 -0
  54. package/apps/pwa/out/_next/static/chunks/529.64ff7257180b2ac9.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5394.5dabeb0c62293a28.js +93 -0
  56. package/apps/pwa/out/_next/static/chunks/5461.08bf2404ff38ec85.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5474-22e08a85583209b2.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/{1219.7e17964e0e7cd8e5.js → 5564.9e72532188f57586.js} +3 -3
  59. package/apps/pwa/out/_next/static/chunks/5567-265df39ed8fe9dcb.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5570-a94ae19811cb2046.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5574-b47c9ef2dceff1fd.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5628.6ddb2d5ffba4ff4c.js +309 -0
  63. package/apps/pwa/out/_next/static/chunks/5730.43d7ccc09988e646.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{1178.1aa9cad0e7695427.js → 5789.2da35c258292e1e5.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/{4133.2056bb4d78f621af.js → 5824.da9527b15a3221e5.js} +1 -1
  66. package/apps/pwa/out/_next/static/chunks/5866.366966af47fdde5d.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/{4527.a69f2894d1bc9f4a.js → 5930.8b4df3b46c32b05a.js} +1 -1
  68. package/apps/pwa/out/_next/static/chunks/5963-c4d8469c52a0828b.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/6001.ec4049ceb3c43418.js +27 -0
  70. package/apps/pwa/out/_next/static/chunks/6120-471f03db1e299c0c.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6175-41479e643aca1878.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6291.a2de4f9787637075.js +104 -0
  73. package/apps/pwa/out/_next/static/chunks/6400-6699907c3537436a.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/6428.1f4327d6ae5fdf9a.js +287 -0
  75. package/apps/pwa/out/_next/static/chunks/644.02cb026fa44bcd0a.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6466-6c87d60d3dd174fb.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/{9507.7026657a2f47eb64.js → 6540.c7bef57ad8f90a87.js} +16 -16
  78. package/apps/pwa/out/_next/static/chunks/6773.d4264665ab31bec0.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6822.3c789f1a8443e774.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/{5574.f35accf4f132b29d.js → 6944.309f4e3ea54d1537.js} +1 -1
  81. package/apps/pwa/out/_next/static/chunks/7261-8ff69d3b2ee671fd.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7266.084c6bbc70035140.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/7271.5c0100e7320aa856.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7429-bf5731358c8f2f68.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7464.01f7a0ae1215fbe7.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7479.0fcad5f37eb64f0c.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7483.427a2fe2049e388d.js +148 -0
  88. package/apps/pwa/out/_next/static/chunks/7502-be74718178e13e56.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7530.0889722b19572065.js +24 -0
  90. package/apps/pwa/out/_next/static/chunks/7645.5b2ee3ad45c55ea3.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7788.7d1c79f1a8e18946.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7900.096f455c7c1efc53.js +77 -0
  93. package/apps/pwa/out/_next/static/chunks/7910-6f139bcafd238b9f.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7966.f71c8958d1637548.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{5947-135e26537d80a6b9.js → 8062-7cd0bcc7f01455ba.js} +3 -3
  96. package/apps/pwa/out/_next/static/chunks/8073.f6cf2f2c71aafbd0.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8201.190b94088980f430.js +74 -0
  98. package/apps/pwa/out/_next/static/chunks/8205.282ca4bb62d54a0a.js +62 -0
  99. package/apps/pwa/out/_next/static/chunks/8313-dfa1021bb58a46d6.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/837-81336ebaca8198a8.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8447.7963352ef5f71b76.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8574-868e8129525ef6d9.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8588.d1c6a2903727ce87.js +149 -0
  104. package/apps/pwa/out/_next/static/chunks/8637.90f92d5c8db4732c.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{2743.5d3f76948be32b34.js → 868.6e953be05bcf6dca.js} +2 -2
  106. package/apps/pwa/out/_next/static/chunks/8706-e1fe0309343a2273.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8749-06384cdfc4520add.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/{5964-7e21164a8f2cf0ce.js → 8861-cc1fa1c7b920fa8e.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/8967-7dfebf710c9dec9d.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{5159.115f1c2ca471386c.js → 8986.8e2e4efbfa655c59.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/8997-3c564dbb3b58b055.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/923.2034d10ae91e9c20.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9312.bc1b89c5d4368033.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/943.39ae5e82f4f1893f.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9469.0500480de55fb205.js +32 -0
  116. package/apps/pwa/out/_next/static/chunks/9770.5f75bc6088b16109.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9810-2543267050e58b82.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9870.8419702475254745.js +8 -0
  119. package/apps/pwa/out/_next/static/chunks/9941-376d1b74d51b01a4.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9958.385434ab04241758.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{b2271e54.c1de3347976e90b0.js → aa57532f.510551854ff239b1.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-deea1450b17cb8dc.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-70985b904f8650ef.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a2e15e33e56a4353.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-fc72ce2db12d6ca9.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-be03e41f9436ebd9.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-35a35999382da3f2.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-3ff5b1e6ca88b848.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-a65101300a0ee5c1.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-3aca5b6d67dba511.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-45b8ab0a71e61314.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-53046e282d4cda8e.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-17809e60e8354c17.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-fd2442d347bf5898.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-e9d720d6fc082e21.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-6b8b4267bab0a677.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-deea1450b17cb8dc.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-8bcf6233ac7c17af.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-7cc25591cfc2126f.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-053e871f35c9beba.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-eff819f0c2d5e084.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-4d7e9d8db5274a87.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-2b2d8f5aa5f69ad4.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-0b8f92c5062e68b1.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1bd9d0fdac2ced3d.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-9ee28f7df07428ea.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-44b7a1ff468c6648.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-cbc6523711dc1b65.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-fdad47899c2695be.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-40f9e19149024298.js → page-79a8b5fee4c20871.js} +1 -1
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-03e8ac9606aeaffb.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-4cd55c55ec287e2f.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-db17b4305404161e.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-30041d848350fd02.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c540da022dbf86b0.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9399efc538da057f.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-a142dfb0331a05f5.js → page-ca2d09128c585ca4.js} +1 -1
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-0e2635aecd343038.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ef7f4399b6b7726e.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-deea1450b17cb8dc.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-caf530535b875468.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-eaa20c1543a5fd8e.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c541eb1b75120f61.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-ab5e213eda9479f4.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-0a815f34367b6db6.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-e858ba0ed9393b68.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-1638ee9dd6e0582f.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-4cf5a399109391f2.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-b4396321238798ec.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-cb72bfd21006781a.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6135d0242afbc434.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a1dccf907eddb856.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{53aeb4ee-51c92f8d683f5220.js → c7945435-b44d4dbe90ba0dcb.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/{2fdf2931.b431eee4fb468bc3.js → cb0f8df8.09a4a6be97e3fc5f.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/{c0c1a699.0ba79f97005965d4.js → d96660fb.cbc21a2a88539dbb.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/ea514caa.05a24f78d9dffe5f.js +122 -0
  177. package/apps/pwa/out/_next/static/chunks/{83184dcd-0ee6247ff41eb3f2.js → fb7d20d5-6892502b6ee39ca6.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/framework-e8a911e19b1be41f.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-7022f418fabba021.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-e5f15df755756a1e.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-4525f91e36940c9b.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-140f0e519c085b0f.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-8f22ef63dcb865b1.js +1 -0
  184. package/apps/pwa/out/_next/static/css/{b9d8151e48998417.css → 62c858ad53854f47.css} +1 -1
  185. package/apps/pwa/out/_next/static/css/d1f8bb401740a549.css +1 -0
  186. package/apps/pwa/out/approvals/index.html +1 -1
  187. package/apps/pwa/out/approvals/index.txt +23 -23
  188. package/apps/pwa/out/autopilot/index.html +1 -1
  189. package/apps/pwa/out/autopilot/index.txt +23 -23
  190. package/apps/pwa/out/board/index.html +1 -1
  191. package/apps/pwa/out/board/index.txt +23 -23
  192. package/apps/pwa/out/botlab/index.html +1 -1
  193. package/apps/pwa/out/botlab/index.txt +22 -22
  194. package/apps/pwa/out/bots/index.html +1 -1
  195. package/apps/pwa/out/bots/index.txt +22 -22
  196. package/apps/pwa/out/ceo/index.html +1 -1
  197. package/apps/pwa/out/ceo/index.txt +23 -23
  198. package/apps/pwa/out/chat/index.html +1 -1
  199. package/apps/pwa/out/chat/index.txt +22 -22
  200. package/apps/pwa/out/consult/index.html +1 -1
  201. package/apps/pwa/out/consult/index.txt +23 -23
  202. package/apps/pwa/out/control/index.html +1 -1
  203. package/apps/pwa/out/control/index.txt +23 -23
  204. package/apps/pwa/out/decisions/index.html +1 -1
  205. package/apps/pwa/out/decisions/index.txt +22 -22
  206. package/apps/pwa/out/design-check/index.html +1 -1
  207. package/apps/pwa/out/design-check/index.txt +23 -23
  208. package/apps/pwa/out/editor/index.html +1 -1
  209. package/apps/pwa/out/editor/index.txt +24 -25
  210. package/apps/pwa/out/exec/index.html +1 -1
  211. package/apps/pwa/out/exec/index.txt +23 -23
  212. package/apps/pwa/out/field/index.html +1 -1
  213. package/apps/pwa/out/field/index.txt +23 -23
  214. package/apps/pwa/out/healthz +1 -1
  215. package/apps/pwa/out/index.html +1 -1
  216. package/apps/pwa/out/index.txt +22 -22
  217. package/apps/pwa/out/inside/index.html +1 -1
  218. package/apps/pwa/out/inside/index.txt +23 -23
  219. package/apps/pwa/out/intake/index.html +1 -1
  220. package/apps/pwa/out/intake/index.txt +23 -23
  221. package/apps/pwa/out/live/index.html +1 -1
  222. package/apps/pwa/out/live/index.txt +24 -25
  223. package/apps/pwa/out/live-run/index.html +1 -1
  224. package/apps/pwa/out/live-run/index.txt +24 -25
  225. package/apps/pwa/out/loops/index.html +1 -1
  226. package/apps/pwa/out/loops/index.txt +22 -22
  227. package/apps/pwa/out/market/index.html +1 -1
  228. package/apps/pwa/out/market/index.txt +22 -22
  229. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  230. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  231. package/apps/pwa/out/morning/index.html +1 -1
  232. package/apps/pwa/out/morning/index.txt +23 -23
  233. package/apps/pwa/out/observatory/index.html +1 -1
  234. package/apps/pwa/out/observatory/index.txt +23 -23
  235. package/apps/pwa/out/ops/checklist/index.html +1 -1
  236. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  237. package/apps/pwa/out/ops/release/index.html +1 -1
  238. package/apps/pwa/out/ops/release/index.txt +22 -22
  239. package/apps/pwa/out/ops/seats/index.html +1 -1
  240. package/apps/pwa/out/ops/seats/index.txt +22 -22
  241. package/apps/pwa/out/outputs/index.html +1 -1
  242. package/apps/pwa/out/outputs/index.txt +22 -22
  243. package/apps/pwa/out/reflection/index.html +1 -1
  244. package/apps/pwa/out/reflection/index.txt +23 -23
  245. package/apps/pwa/out/scheduler/index.html +1 -1
  246. package/apps/pwa/out/scheduler/index.txt +23 -23
  247. package/apps/pwa/out/sessions/index.html +1 -1
  248. package/apps/pwa/out/sessions/index.txt +22 -22
  249. package/apps/pwa/out/settings/devices/index.html +1 -1
  250. package/apps/pwa/out/settings/devices/index.txt +23 -23
  251. package/apps/pwa/out/settings/index.html +1 -1
  252. package/apps/pwa/out/settings/index.txt +23 -23
  253. package/apps/pwa/out/setup/done/index.html +1 -1
  254. package/apps/pwa/out/setup/done/index.txt +23 -23
  255. package/apps/pwa/out/setup/index.html +1 -1
  256. package/apps/pwa/out/setup/index.txt +23 -23
  257. package/apps/pwa/out/share/index.html +1 -1
  258. package/apps/pwa/out/share/index.txt +23 -23
  259. package/apps/pwa/out/showroom/index.html +1 -1
  260. package/apps/pwa/out/showroom/index.txt +22 -22
  261. package/apps/pwa/out/tasks/index.html +1 -1
  262. package/apps/pwa/out/tasks/index.txt +23 -23
  263. package/apps/pwa/out/term/index.html +1 -1
  264. package/apps/pwa/out/term/index.txt +23 -23
  265. package/apps/pwa/out/today/index.html +1 -1
  266. package/apps/pwa/out/today/index.txt +23 -23
  267. package/apps/pwa/out/trace/index.html +1 -1
  268. package/apps/pwa/out/trace/index.txt +23 -23
  269. package/apps/pwa/out/vault/index.html +1 -1
  270. package/apps/pwa/out/vault/index.txt +23 -23
  271. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  272. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  273. package/apps/pwa/out/workflows/index.html +1 -1
  274. package/apps/pwa/out/workflows/index.txt +23 -23
  275. package/apps/pwa/out/workspace/index.html +1 -1
  276. package/apps/pwa/out/workspace/index.txt +23 -23
  277. package/apps/pwa/out/worktrees/index.html +1 -1
  278. package/apps/pwa/out/worktrees/index.txt +23 -23
  279. package/catalog/external-commands.yaml +5 -3
  280. package/catalog/meta/catalogVersion.yaml +2 -1
  281. package/catalog/signing/catalog-signing-public.pem +3 -0
  282. package/docs/goal-context/04-mock-scenarios.md +13 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/heal/heal-loop.yaml +1 -0
  285. package/graphs/intake/intake-daily.yaml +16 -0
  286. package/graphs/intake/news-sources.yaml +1 -0
  287. package/graphs/intake/recipes.yaml +7 -0
  288. package/graphs/overlays/examples/research-runtime-empty-terminal.yaml +28 -0
  289. package/graphs/overlays/stop-heal-ladder.yaml +113 -0
  290. package/graphs/profiles/local.yaml +5 -0
  291. package/graphs/profiles/pod.yaml +4 -0
  292. package/graphs/units/verbs/recipes.yaml +11 -11
  293. package/graphs/work/research-report.yaml +10 -2
  294. package/package.json +6 -2
  295. package/plugins/demo-absorption-briefing/plugin.json +18 -0
  296. package/plugins/demo-absorption-briefing/skills/demo-absorption-briefing/SKILL.md +8 -0
  297. package/plugins/demo-browser-hand/plugin.json +13 -0
  298. package/plugins/demo-browser-hand/skills/demo-browser-hand/SKILL.md +8 -0
  299. package/plugins/demo-linear-secretary/plugin.json +15 -0
  300. package/plugins/demo-linear-secretary/skills/demo-linear-secretary/SKILL.md +8 -0
  301. package/plugins/demo-plugin-wizard/plugin.json +11 -0
  302. package/plugins/demo-plugin-wizard/skills/demo-plugin-wizard/SKILL.md +8 -0
  303. package/plugins/demo-research/plugin.json +16 -0
  304. package/plugins/demo-research/skills/demo-research/SKILL.md +8 -0
  305. package/plugins/demo-video-briefing/plugin.json +15 -0
  306. package/plugins/demo-video-briefing/skills/demo-video-briefing/SKILL.md +8 -0
  307. package/scripts/build-signed-catalog.ts +48 -0
  308. package/scripts/ci-typecheck-main-delta.sh +88 -0
  309. package/scripts/codex-fallback-live-probe.ts +1 -1
  310. package/scripts/demo/demo1104-parallel-scenes.ts +301 -0
  311. package/scripts/demo/demo1104-stage.config.ts +21 -0
  312. package/scripts/demo/demo1104-stage.ts +316 -0
  313. package/scripts/goal-method-audit.ts +17 -1
  314. package/scripts/graph-units/land-enqueue.ts +90 -0
  315. package/scripts/heal/run-role.ts +99 -5
  316. package/scripts/hooks/codex-notify.sh +32 -0
  317. package/scripts/install.sh +10 -38
  318. package/scripts/land-global-checks.ts +6 -1
  319. package/scripts/landing-heal/land-plan.ts +57 -0
  320. package/scripts/lib/decompose-ab.ts +1 -0
  321. package/scripts/lib/fixtures/tui-regress/help-insufficient-commands.txt +15 -0
  322. package/scripts/lib/fixtures/tui-regress/help-live.txt +42 -0
  323. package/scripts/lib/fixtures/tui-regress/help-missing-keys.txt +21 -0
  324. package/scripts/lib/fixtures/tui-regress/help-original.txt +51 -0
  325. package/scripts/lib/fixtures/tui-regress/help-shifted-input.txt +26 -0
  326. package/scripts/lib/tui-regress-checks.ts +33 -13
  327. package/scripts/release-loop/auto-approve-node.ts +1 -1
  328. package/scripts/release-loop/gate-autoheal-sim-evidence.ts +60 -0
  329. package/scripts/release-loop/gate-baseline-receipt.ts +47 -9
  330. package/scripts/release-loop/gate-image-pin.ts +81 -0
  331. package/scripts/release-loop/gate-method.ts +139 -0
  332. package/scripts/release-loop/gate-node-sim.ts +207 -0
  333. package/scripts/release-loop/gate-node.ts +463 -64
  334. package/scripts/release-loop/gate-pod-image-sticky-plan.ts +99 -0
  335. package/scripts/release-loop/gate-radius-live.ts +97 -13
  336. package/scripts/release-loop/gate-shard-dispatch.ts +43 -0
  337. package/scripts/release-loop/gate-traffic-mode.ts +151 -3
  338. package/scripts/release-loop/gate-train-receipts.ts +122 -0
  339. package/scripts/release-loop/node-verdict.ts +38 -25
  340. package/scripts/release-loop/preflight.ts +362 -8
  341. package/scripts/release-loop/resume-release.ts +83 -8
  342. package/scripts/release-loop/unattended-release.ts +20 -9
  343. package/scripts/rhythm/daily.ts +36 -4
  344. package/scripts/rhythm/linear-progress-sync.ts +298 -0
  345. package/scripts/ux-sim.ts +18 -1
  346. package/scripts/video-pipeline.ts +9 -1
  347. package/scripts/warm-pool-provider-config.ts +286 -0
  348. package/skills/omni-crawl/SKILL.md +5 -2
  349. package/skills/omni-crawl/scripts/main.ts +84 -23
  350. package/src/acp/agent-manager.ts +1 -0
  351. package/src/acp/codex-app-server-agent.ts +33 -0
  352. package/src/acp/codex-app-server-client.ts +153 -16
  353. package/src/acp/core-turn-bridge.ts +27 -9
  354. package/src/acp/event-router.ts +20 -1
  355. package/src/acp/server.ts +6 -0
  356. package/src/agent/registry.ts +2 -0
  357. package/src/agent/task-notification.ts +25 -5
  358. package/src/agent/types.ts +6 -0
  359. package/src/agent-mission/browser-roundtrip-coordinator.ts +85 -0
  360. package/src/agent-mission/claude-headless.ts +4 -1
  361. package/src/agent-mission/codex-exec.ts +105 -0
  362. package/src/agent-mission/driver.ts +192 -11
  363. package/src/agent-mission/grok-auth-status.ts +47 -0
  364. package/src/agent-mission/hand-hooks.ts +101 -0
  365. package/src/agent-mission/mission-cli.ts +63 -4
  366. package/src/agent-mission/mission-hand-reply.ts +118 -0
  367. package/src/agent-mission/mission-line.ts +180 -0
  368. package/src/agent-mission/mission-out.ts +833 -0
  369. package/src/agent-mission/tool-install.ts +200 -3
  370. package/src/agent-substrate/context-strategy.ts +4 -4
  371. package/src/agent-substrate/self-review-cli.ts +178 -13
  372. package/src/agents/general-purpose.md +1 -1
  373. package/src/auto-research/research-turn.ts +211 -53
  374. package/src/autopilot/pr-manager.ts +69 -10
  375. package/src/autopilot/pty-control-loop.ts +2 -0
  376. package/src/boot/daemon-tools/self-implement.ts +3 -1
  377. package/src/boot/daemon-tools/web-search.ts +1 -2
  378. package/src/briefing/brief-items.ts +55 -11
  379. package/src/capture/tui-self-report.ts +22 -6
  380. package/src/chat/index.ts +1 -1
  381. package/src/cli/agent-cli.ts +2 -1
  382. package/src/cli/catalog-cli.ts +31 -0
  383. package/src/cli/connector-cli.ts +16 -0
  384. package/src/cli/doctor-fix.ts +2 -2
  385. package/src/cli/fixtures/review-loop-breaker/opwaiver-32646-1694ccc7a170.json +1 -0
  386. package/src/cli/fixtures/review-loop-breaker/opwaiver-32853-bd8f73595c83.json +1 -0
  387. package/src/cli/fixtures/review-loop-breaker/opwaiver-33097-1cc85900413c.json +1 -0
  388. package/src/cli/fixtures/review-loop-breaker/opwaiver-33106-972f31e4a3ca.json +1 -0
  389. package/src/cli/fixtures/review-loop-breaker/opwaiver-33113-3ab51f05968f.json +1 -0
  390. package/src/cli/fixtures/review-loop-breaker/pr-33097-1cc85900413c.json +1 -0
  391. package/src/cli/intake-source-cli.ts +44 -8
  392. package/src/cli/msg-cli.ts +32 -3
  393. package/src/cli/pr-cli.ts +21 -1
  394. package/src/cli/pr-land-heavy-remote.ts +75 -5
  395. package/src/cli/pr-land-overlap-evidence.ts +113 -2
  396. package/src/cli/pr-land-pod-shadow-job.ts +202 -4
  397. package/src/cli/pr-land-pod-shadow.ts +9 -2
  398. package/src/cli/release-checklist-read-cli.ts +57 -19
  399. package/src/cli/release-cli.ts +23 -3
  400. package/src/cli/research-cli.ts +13 -5
  401. package/src/cli/setup-cli.ts +166 -6
  402. package/src/cli/setup-keys.ts +187 -0
  403. package/src/cli/task-plugin-wizard-host.ts +114 -0
  404. package/src/cli/tasks-cli.ts +61 -9
  405. package/src/cli/tui-test-cli.ts +186 -0
  406. package/src/compact/auto.ts +8 -1
  407. package/src/config.ts +4 -2
  408. package/src/connectors/linear-daily-progress.ts +228 -0
  409. package/src/connectors/linear-projector.ts +34 -12
  410. package/src/connectors/linear.ts +151 -7
  411. package/src/control-plane/ledger.ts +52 -2
  412. package/src/control-plane/server.ts +16 -2
  413. package/src/core-turn/deep-turn-bloom.ts +67 -0
  414. package/src/core-turn/research-policy.ts +37 -0
  415. package/src/core-turn/run-core-turn.ts +606 -95
  416. package/src/core-turn/run-goal-loop.ts +18 -0
  417. package/src/core-turn/types.ts +4 -0
  418. package/src/dashboard/chat/acp-chat.ts +10 -0
  419. package/src/dashboard/classic-sidetab-mission-job.ts +161 -0
  420. package/src/dashboard/classic-sidetab-mission-pair.ts +81 -0
  421. package/src/dashboard/classic-sidetab-mission-trio.ts +219 -0
  422. package/src/dashboard/classic-sidetab-mission.ts +347 -0
  423. package/src/dashboard/index.ts +517 -18
  424. package/src/dashboard/input/agent-wake.ts +23 -1
  425. package/src/dashboard/input/chat-main-acp-dispatch.ts +23 -0
  426. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +17 -0
  427. package/src/dashboard/mission-cli-consumer.ts +165 -0
  428. package/src/dashboard/plugin-wizard-runtime.ts +50 -0
  429. package/src/dashboard/plugin-wizard-tool.ts +55 -0
  430. package/src/dashboard/seat-boot-preamble.ts +171 -1
  431. package/src/dashboard/side-basic-runtime.ts +54 -1
  432. package/src/dashboard/sidetab-runtime.ts +90 -1
  433. package/src/dashboard/skill-catalog-preamble.ts +101 -0
  434. package/src/dashboard/skill-detection-runtime.ts +55 -15
  435. package/src/dashboard/slash-runtime/dashboard-handlers.ts +15 -0
  436. package/src/dashboard/terminal-popup-runtime.ts +6 -3
  437. package/src/dashboard/turn-preamble.ts +53 -15
  438. package/src/dashboard/turn-prompt-runtime.ts +4 -2
  439. package/src/decisions/linear-progress-summary.ts +78 -0
  440. package/src/decisions/linear-progress-sync.ts +152 -0
  441. package/src/domains/outbound-alert.ts +49 -11
  442. package/src/domains/telegram-kind-route.ts +16 -9
  443. package/src/graph-runner/arg-allowance.ts +13 -0
  444. package/src/graph-runner/graph-cli.ts +23 -7
  445. package/src/graph-runner/graph-run-api.ts +3 -1
  446. package/src/graph-runner/graph-tick.ts +10 -2
  447. package/src/graph-runner/runner.ts +86 -18
  448. package/src/graph-wizard/mission-compose.ts +407 -12
  449. package/src/grok/agent-search.ts +14 -4
  450. package/src/grok/credential.ts +28 -11
  451. package/src/harness/dispatch-backpressure.ts +54 -1
  452. package/src/harness/dispatch-shadow-compare.ts +74 -0
  453. package/src/harness/harness-cli-command.ts +11 -1
  454. package/src/harness/harness-pod-dispatch.ts +81 -15
  455. package/src/harness/harness-stop.ts +155 -11
  456. package/src/harness/skill-exec.ts +21 -9
  457. package/src/harness/skill-select.ts +1 -1
  458. package/src/hooks/error-report-cloud.ts +101 -0
  459. package/src/hooks/receiver.ts +29 -2
  460. package/src/index.ts +159 -13
  461. package/src/instance/spawn-elanous.ts +6 -4
  462. package/src/intake-plane/actions.ts +354 -0
  463. package/src/intake-plane/adapters/telegram-ambient.ts +34 -18
  464. package/src/intake-plane/intake-sources.ts +78 -8
  465. package/src/intake-plane/items.ts +14 -4
  466. package/src/intake-plane/linear-mission-sync.ts +80 -0
  467. package/src/intake-plane/linear-secretary-runtime.ts +178 -0
  468. package/src/intake-plane/linear-wish.ts +227 -1
  469. package/src/life/life-cli.ts +168 -0
  470. package/src/life/life-kinds.ts +160 -0
  471. package/src/live-supply/budget-consumer.ts +78 -0
  472. package/src/live-supply/read.ts +3 -0
  473. package/src/live-supply/snapshot.ts +45 -0
  474. package/src/llm/provider-credentials.ts +8 -2
  475. package/src/llm.ts +168 -9
  476. package/src/loops/orchestrator/coordinator-shadow.ts +226 -0
  477. package/src/loops/orchestrator/tick.ts +13 -0
  478. package/src/maturity/feature-maturity.ts +4 -4
  479. package/src/msg/msg-sse-server.ts +3 -3
  480. package/src/msg/msg-store.ts +177 -19
  481. package/src/native-tool-catalog.ts +38 -4
  482. package/src/nexus/api/harness-traversal.ts +11 -0
  483. package/src/nexus/api/http-server.ts +37 -1
  484. package/src/nexus/api/mcp-public-allowlist.ts +2 -0
  485. package/src/nexus/index.ts +7 -2
  486. package/src/nexus/outbound/format.ts +9 -0
  487. package/src/nexus/outbound/router.ts +98 -13
  488. package/src/nexus/setup-status.ts +9 -0
  489. package/src/nexus/state/state.ts +3 -0
  490. package/src/oauth/codex-account-store.ts +20 -7
  491. package/src/oauth/codex-owner-mirror.ts +44 -0
  492. package/src/oauth/codex.ts +17 -2
  493. package/src/oauth/fallback-chain.ts +47 -17
  494. package/src/onboarding/first-run-doctor.ts +8 -1
  495. package/src/onboarding/first-run.ts +85 -26
  496. package/src/onboarding/key-setup.ts +103 -0
  497. package/src/onboarding/menu-answer.ts +13 -0
  498. package/src/onboarding/secret-prompt.ts +37 -0
  499. package/src/plugins/install/plugin-install.ts +59 -0
  500. package/src/pr-tool/census.ts +133 -2
  501. package/src/pty-shell/pty-control-ipc.ts +4 -1
  502. package/src/pty-shell/tui-run-state.ts +188 -2
  503. package/src/registry/catalog-server.ts +232 -0
  504. package/src/registry/loader.ts +45 -1
  505. package/src/registry/types.ts +1 -2
  506. package/src/release-loop/checklist-target-path-hint.ts +13 -0
  507. package/src/release-loop/checklist.ts +9 -1
  508. package/src/repl/index.ts +43 -2
  509. package/src/research/axis-fanout.ts +136 -16
  510. package/src/research/bloom-exemplars.ts +3 -1
  511. package/src/research/gap-followup.ts +13 -1
  512. package/src/research/plugin-discovery.ts +36 -14
  513. package/src/research-bridge/invoke.ts +22 -5
  514. package/src/research-bridge/types.ts +2 -0
  515. package/src/self-dev/ask-launch-flow.ts +72 -1
  516. package/src/self-dev/decompose.ts +119 -5
  517. package/src/self-dev/dev-cli.ts +4 -1
  518. package/src/self-dev/dev-pipeline.ts +5 -0
  519. package/src/self-dev/draft-residue.ts +64 -5
  520. package/src/self-dev/graph-front-nodes.ts +2 -1
  521. package/src/self-dev/graph-journey-route.ts +76 -21
  522. package/src/self-dev/launch-preflight-text.ts +5 -6
  523. package/src/self-dev/launch-preflight.ts +58 -0
  524. package/src/self-dev/orchestrate.ts +13 -3
  525. package/src/self-dev/review-provider-fallback.ts +9 -2
  526. package/src/self-dev/run-supervisor.ts +42 -4
  527. package/src/self-dev/run-types.ts +4 -0
  528. package/src/self-dev/shard-aggregate.ts +4 -0
  529. package/src/self-dev/shard-run.ts +36 -15
  530. package/src/self-implement/abandoned-classification.ts +12 -3
  531. package/src/self-implement/budget-gate.ts +7 -0
  532. package/src/self-implement/child-llm-preference.ts +10 -1
  533. package/src/self-implement/doctor-visit.ts +118 -8
  534. package/src/self-implement/elanous-tui-spawn.ts +3 -0
  535. package/src/self-implement/fixtures/tdd-green-missing-passing-child-transcript.txt +2 -0
  536. package/src/self-implement/gate-artifacts.ts +2 -1
  537. package/src/self-implement/goal-author-cli.ts +4 -2
  538. package/src/self-implement/goal-author.ts +684 -7
  539. package/src/self-implement/graph-overlay-yaml.ts +37 -4
  540. package/src/self-implement/graph-overlay.ts +3 -1
  541. package/src/self-implement/graph-profile-yaml.ts +107 -0
  542. package/src/self-implement/graph-yaml.ts +26 -3
  543. package/src/self-implement/headless-elanous-driver.ts +31 -2
  544. package/src/self-implement/heal-intake.ts +112 -4
  545. package/src/self-implement/heal-triage.ts +20 -0
  546. package/src/self-implement/host-regate.ts +27 -4
  547. package/src/self-implement/merge-train.ts +5 -0
  548. package/src/self-implement/off-diff-evidence.ts +249 -5
  549. package/src/self-implement/orchestrator.ts +365 -25
  550. package/src/self-implement/regate-detail.ts +38 -1
  551. package/src/self-implement/rework-child-provider.ts +25 -0
  552. package/src/self-implement/run-chart.ts +122 -0
  553. package/src/self-implement/run-ledger.ts +162 -11
  554. package/src/self-implement/run-stop.ts +188 -4
  555. package/src/self-implement/runtime-overlay-run-steps.ts +95 -0
  556. package/src/self-implement/stop-autoheal.ts +13 -0
  557. package/src/self-implement/tdd-evidence-tags.ts +9 -0
  558. package/src/self-implement/train-gate-receipt.ts +166 -0
  559. package/src/self-implement/train-gate-remote.ts +62 -18
  560. package/src/session/chat.ts +40 -4
  561. package/src/session/session-fanout.ts +2 -0
  562. package/src/session/streaming/acp-stream-sink.ts +2 -1
  563. package/src/session/streaming/chunk-producer.ts +6 -0
  564. package/src/session/streaming/stream-compositor.ts +3 -2
  565. package/src/session-runtime/index.ts +135 -5
  566. package/src/session-runtime/retry-policy.ts +1 -1
  567. package/src/session-runtime/tier-flip.ts +3 -3
  568. package/src/setup/llm-env-detect.ts +3 -0
  569. package/src/setup/service-key-catalog.ts +46 -0
  570. package/src/setup/service-keys.ts +241 -0
  571. package/src/sidetab-core/model.ts +19 -5
  572. package/src/sidetab-core/visible-agent-mission.ts +262 -0
  573. package/src/skills/name-match.ts +20 -0
  574. package/src/skills/tools/agent.ts +53 -6
  575. package/src/skills/tools/omni-search.ts +173 -13
  576. package/src/task-agent/parent-host.ts +10 -0
  577. package/src/task-agent/pod-distributor-entry.ts +3 -0
  578. package/src/task-agent/repair-outcomes.ts +65 -0
  579. package/src/task-agent/task-hand.ts +47 -7
  580. package/src/task-orchestrator/dispatcher.ts +14 -1
  581. package/src/task-orchestrator/linear-capture-events.ts +55 -0
  582. package/src/task-orchestrator/store.ts +16 -5
  583. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +4 -0
  584. package/src/task-orchestrator/surfaces/pod-distributor.ts +48 -0
  585. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +92 -1
  586. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +38 -1
  587. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +113 -14
  588. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +33 -6
  589. package/src/task-orchestrator/surfaces/pod-source-bundle.ts +45 -9
  590. package/src/task-orchestrator/surfaces/pod-source-receive.ts +178 -16
  591. package/src/task-orchestrator/surfaces/pod-source-spec.ts +3 -3
  592. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +2 -0
  593. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +237 -41
  594. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +80 -3
  595. package/src/task-orchestrator/surfaces/self-implement-pod.ts +337 -51
  596. package/src/task-orchestrator/surfaces/self-implement.ts +27 -3
  597. package/src/task-orchestrator/surfaces/warm-reuse-evidence.ts +169 -0
  598. package/src/task-orchestrator/types.ts +14 -0
  599. package/src/telegram.ts +14 -16
  600. package/src/terminal/coding-agent.ts +14 -5
  601. package/src/terminal/session-registry.ts +1 -1
  602. package/src/tokens.ts +35 -2
  603. package/src/tool-hints/gate.ts +1 -0
  604. package/src/tool-runtime/agent-runtime.ts +2 -0
  605. package/src/tool-runtime/browser-hand-runtime.ts +381 -0
  606. package/src/tool-runtime/browser-runtime.ts +2 -1
  607. package/src/tool-runtime/elanous-linear-issue-runtime.ts +76 -0
  608. package/src/tool-runtime/elanous-linear-secretary-runtime.ts +57 -0
  609. package/src/tool-runtime/elanous-skills-list-runtime.ts +5 -1
  610. package/src/tool-runtime/graph-mcp-runtimes.ts +240 -0
  611. package/src/tool-runtime/index.ts +6 -0
  612. package/src/tool-runtime/skill-exec-runtime.ts +33 -13
  613. package/src/tool-runtime/types.ts +4 -0
  614. package/src/tui/entry.ts +38 -5
  615. package/src/tui/sidetab/attach.ts +177 -1
  616. package/src/tui/sidetab/herdr-portal.ts +225 -0
  617. package/src/tui-client/local-chat-turn.ts +26 -13
  618. package/src/tui.ts +22 -0
  619. package/src/user-config.ts +34 -9
  620. package/src/user-intent/types.ts +4 -3
  621. package/src/ux-sim/browser-hand.ts +165 -0
  622. package/src/ux-sim/draft-inventory-builder.ts +198 -0
  623. package/src/ux-sim/fake-browser-page.ts +81 -0
  624. package/src/ux-sim/fake-kubectl.ts +37 -3
  625. package/src/ux-sim/fake-linear-device.ts +31 -0
  626. package/src/ux-sim/fault-pool-cap.ts +11 -6
  627. package/src/ux-sim/graph-engine-sim.ts +47 -0
  628. package/src/ux-sim/linear-secretary.ts +216 -0
  629. package/src/ux-sim/mock-scenario-catalog.json +93 -0
  630. package/src/ux-sim/mock-scenario-catalog.ts +274 -0
  631. package/src/ux-sim/onboarding-first-run-device.ts +31 -21
  632. package/src/ux-sim/scenario.ts +185 -48
  633. package/src/ux-sim/service-key-setup.ts +50 -0
  634. package/src/ux-sim/term-slash-device.ts +74 -0
  635. package/src/ux-sim/turn-throw-sim.ts +31 -0
  636. package/src/version/packed-revision.json +1 -1
  637. package/src/voice/voice-tts-singleton.ts +18 -3
  638. package/src/web-search/exa.ts +77 -0
  639. package/src/web-search/grok.ts +5 -9
  640. package/src/web-search/index.ts +30 -9
  641. package/src/web-search/provider.ts +4 -1
  642. package/src/web-search/x-intent.ts +5 -0
  643. package/apps/pwa/out/_next/static/chunks/1115.434ae2ecb0ad986d.js +0 -149
  644. package/apps/pwa/out/_next/static/chunks/1121.667cec0bcdbb3fdb.js +0 -36
  645. package/apps/pwa/out/_next/static/chunks/1197-54da59d250a6e476.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/1245.1cfd13b26dbd71d6.js +0 -287
  647. package/apps/pwa/out/_next/static/chunks/1494-f93046ff5c5a124d.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/1609.2b312797599b8e45.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/1661.0dd330f3d89f73f3.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/167-0c121e4b47e0f9da.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/1700.cdc2bf8cc685e221.js +0 -90
  652. package/apps/pwa/out/_next/static/chunks/1703-78e46acad29f3cfc.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/1765.679b29625c8e88d4.js +0 -77
  654. package/apps/pwa/out/_next/static/chunks/1971-7efb628c471dc5a0.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/1999-8de7b7bb36801913.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/2073.689dcb2680113d76.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/2198-557d49184104d165.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/221-440ce67fa9f5c839.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/2427-8ed8e98624cbd664.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/2457-725c5827bc003795.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/2491-2718b15a5ccb75a5.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/2527-5c636a43c7cc5dde.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/2692-1027cb16fe4ccf49.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/2773.0e80b9d325fb5635.js +0 -32
  665. package/apps/pwa/out/_next/static/chunks/2873-0f3cb56c8e3528ea.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/3097.864e92bdaa2f4d15.js +0 -79
  667. package/apps/pwa/out/_next/static/chunks/3136-d6870ba63300a93e.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/3173-0289113d434e83b7.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/325-dd9208a1a0ab7ce4.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/3283.528f430dd043fb4e.js +0 -74
  671. package/apps/pwa/out/_next/static/chunks/3295.cc8cb13b8f0dae1a.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/3688-86e3b88abf18cb3b.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/3804-7220467a5473a8df.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/3808.3e1e247ce7bdf889.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/3927.b5473ad109da44c5.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/3934-98ea94832e194796.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/4156.ba4de4a3664f04b4.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/4297-239ca82f293faab0.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/4320-dcc5a7734126f4c9.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/4434.94b4c552a2d91e69.js +0 -148
  681. package/apps/pwa/out/_next/static/chunks/4579.03e4092f73950965.js +0 -226
  682. package/apps/pwa/out/_next/static/chunks/4667.97e31aa38c95c475.js +0 -309
  683. package/apps/pwa/out/_next/static/chunks/4702.4a4adc1f16d7c93b.js +0 -64
  684. package/apps/pwa/out/_next/static/chunks/4815.481501c57b3568d9.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/487-d16e698ef14662d9.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/4888-7a38bf522c9cc6fe.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/5034-30e429d6bb086881.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/5040-35c494e60dadd97d.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/50c6ab1e.81a96e419350909d.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/5154.4b6a836179356f30.js +0 -94
  691. package/apps/pwa/out/_next/static/chunks/5228-a8200df486278f2d.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/5379.97af106d09566f69.js +0 -8
  693. package/apps/pwa/out/_next/static/chunks/5479-b6372e762719f92f.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/5534-699c5cbcbc96c5d7.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/5701.9c4e8f250312eeee.js +0 -24
  696. package/apps/pwa/out/_next/static/chunks/5892.2526d962339662d8.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/5937.c2df9e3447e1f667.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/5941.8210cc93c9202c0a.js +0 -286
  699. package/apps/pwa/out/_next/static/chunks/5975.4004f820ae3cecd5.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/6142-7ccd48795d7abd55.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/6160.bf9177b8c1bfb243.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/6398.71ba0690c8027555.js +0 -27
  703. package/apps/pwa/out/_next/static/chunks/6492.2bd5c10edc1a064e.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/6552.a3840aa7da35ad68.js +0 -62
  705. package/apps/pwa/out/_next/static/chunks/6736.1e36d3ac5fa5e41d.js +0 -24
  706. package/apps/pwa/out/_next/static/chunks/6900.3ccbe069bdd4556a.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/71327eb4.add50b365f94bf3a.js +0 -122
  708. package/apps/pwa/out/_next/static/chunks/7136.deca3e3a2ddaa374.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/7139-ee9f8ed2677a40b3.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/7191.fdc955f7d96064a4.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/7423-e0aa5d9e2962120e.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/7453.afc1ea7e05d56a8c.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/7503-5e6a3d7fe67e4a0c.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/7761-476fd7bf768abd34.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/7975.eafb12097a0a9e62.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/8050-9b364bdef8f71927.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/8152.64e253c35cccfaae.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/8190.620f0231b3924bcb.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/8448.45b6b1f1a99eeb35.js +0 -104
  720. package/apps/pwa/out/_next/static/chunks/8464-e24f10451b658aac.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/8477.e4c944bb3aa5d2f3.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/8710.ca385257d5ca422e.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/8830.627ccf294ec2465c.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/8880.64c445592f04acaf.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/8981.c706964c8ba27aff.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/9053.bd0fffaff8d3f836.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/9161-c66e723d7ec9d682.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/9185.1ecdf9b65c0bb684.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/9356.fccd5f58086b4ff5.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/9446.dc0406109371d329.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/9506.dcf25d467a42627e.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/9541.eb8e2f8480c7feca.js +0 -93
  733. package/apps/pwa/out/_next/static/chunks/9577.ed7582186efa5482.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/9579.4a8169600fff2058.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/9642-ff2e039eb62e3b92.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/9659-8f2323348113ad80.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/9724.4c5623af2db43153.js +0 -34
  738. package/apps/pwa/out/_next/static/chunks/9869.81a1e24ca682d5a0.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-8d9d76ea322d855c.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed2c4e59f9f1fe21.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-2dc99e03c5d76ca0.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/board/page-b5a3a788330e920f.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/app/botlab/page-14949db884bfa672.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea76c85b36388a97.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/ceo/page-01716d20af62d325.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/chat/page-62baf6881a64b1e9.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/consult/page-f89ba590c2af8afa.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/control/page-22f8b0f78d9637e5.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/decisions/page-817f9d7e6820be80.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/design-check/page-ffb9bc0d2650249a.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/editor/page-f6d0e64873c0f629.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/exec/page-8bfa0d4ba23a209d.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/field/page-f5060462249e32c7.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/healthz/route-8d9d76ea322d855c.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/inside/page-b2049f8b1ef79117.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/intake/page-1446c5fa93907f11.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/layout-b48a7a07c5204156.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/live/page-e974b8c4ca47614c.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/live-run/page-8a919b869bd28594.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/loops/page-d31b8de6bfcd72ed.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/market/page-64765f817909db29.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-d128c8569a36ee9b.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/morning/page-b2679d357e9b9270.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/not-found-6fabec98a9e7b269.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/observatory/page-048f30149dcf1349.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-9113181d6b5a2725.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-1e7a755a13227611.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3c8f8b67a203cf07.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/page-18032f5437215062.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/reflection/page-da3b739192fd0ee3.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d332545571bd6fd1.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/sessions/page-5237aa5b3f3b8ec5.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/app/settings/page-d16e56c3989c147e.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6b6593600869e2cd.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/setup/layout-8d9d76ea322d855c.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/setup/page-29e8b8a8396b55cb.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/share/page-b3414d856a1a7e2f.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c3affa52b7ce961b.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f21dddf9f95b6fab.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/term/page-f5a30a24745bf088.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/today/page-8c8569a09b4d4e34.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/trace/page-2ce32722c0243483.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/vault/page-4767b0d9c0a98c6c.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-116ee1339c387a75.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/workflows/page-35e8c50ca4ef7ffc.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/workspace/page-52e17113356bb891.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7458ae05ed2ac1a0.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/framework-ad6c9dd524ad6ef8.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/main-app-2ddd1f2b44d6aa59.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/main-e3d82bdc358d20c5.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/pages/_app-71d5aa3896e1655f.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/pages/_error-03ffc54e00438546.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/webpack-56bb89af5a611d0b.js +0 -1
  794. package/apps/pwa/out/_next/static/css/be9019f696217521.css +0 -1
  795. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +0 -1
  796. /package/apps/pwa/out/_next/static/{GiOLWmt4MqDZePubBjA4Q → Om5xS9jpjSXJCeTNGYEi4}/_ssgManifest.js +0 -0
@@ -0,0 +1,187 @@
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 interface SetupKeysOptions {
16
+ config: UserConfig;
17
+ env?: NodeJS.ProcessEnv;
18
+ cacheDir?: string;
19
+ includeOptional?: boolean;
20
+ /** Existing OAuth fetch injection used by deterministic login simulation. */
21
+ loginWithCodex?: typeof loginWithCodex;
22
+ }
23
+
24
+ function providerForService(id: string): string | undefined {
25
+ switch (id) {
26
+ case 'openai-api': return 'openai';
27
+ case 'anthropic-api': return 'anthropic';
28
+ case 'gemini-api': return 'gemini';
29
+ case 'openrouter': return 'openrouter';
30
+ case 'xai': return 'grok';
31
+ case 'opengateway': return 'opengateway';
32
+ default: return undefined;
33
+ }
34
+ }
35
+
36
+ function providerBaseUrl(config: UserConfig, serviceId: string): string | undefined {
37
+ const provider = providerForService(serviceId);
38
+ if (!provider) return undefined;
39
+ return config.llm.rotation?.find(item => item.provider === provider)?.baseUrl;
40
+ }
41
+
42
+ function renderProviderProposal(config: UserConfig, providers: Awaited<ReturnType<typeof detectProviders>>): string[] {
43
+ const available = providers.filter(provider => provider.available).sort((a, b) => a.rank - b.rank);
44
+ const ordered = [...new Set(available.map(provider => provider.provider))];
45
+ const defaultProvider = ordered.includes(config.llm.provider) ? config.llm.provider : ordered[0];
46
+ const fallback = config.llm.fallbackChain ?? [];
47
+ const suggestion = defaultProvider ? [defaultProvider, ...ordered.filter(name => name !== defaultProvider)] : [];
48
+ return [
49
+ `LLM 감지: ${available.length ? available.map(provider => `${provider.provider}(${provider.auth})`).join(' · ') : '사용 가능한 인증 없음'}`,
50
+ `기본 제안: ${defaultProvider ?? '설정 후 선택'} · 현재 기본: ${config.llm.provider}`,
51
+ `폴백 제안: ${suggestion.length ? suggestion.join(' → ') : '현재 설정 유지'} · 현재 llm.fallbackChain: ${fallback.length ? fallback.join(' → ') : '미설정'}`,
52
+ `역할별 현재 해석: ${MODEL_ROLES.map(role => {
53
+ try {
54
+ const resolved = resolveRoleLlm(role, { config });
55
+ return `${role}=${resolved.provider}/${resolved.model}`;
56
+ } catch {
57
+ return `${role}=미설정`;
58
+ }
59
+ }).join(' · ')}`,
60
+ '위 내용은 제안만 표시하며 roleLlm·llm.fallbackChain을 변경하지 않습니다.',
61
+ ];
62
+ }
63
+
64
+ export function renderServiceKeyStatus(options: { env?: NodeJS.ProcessEnv; cacheDir?: string } = {}): string[] {
65
+ const status = serviceKeyStatus(options);
66
+ return SERVICE_KEY_CATALOG.map(item => {
67
+ const row = status.find(candidate => candidate.id === item.id);
68
+ if (!row) return `${item.label}: 상태 확인 불가`;
69
+ if (item.kind === 'api-key') return `${item.label}: ${row.configured ? '키 있음' : '키 필요'} (${item.envNames.join(', ')})`;
70
+ return `${item.label}: ${item.kind === 'subscription' || item.kind === 'oauth' || item.kind === 'cli' ? '로그인/설치 상태는 별도 감지' : '로컬 도구 확인 필요'}`;
71
+ });
72
+ }
73
+
74
+ export async function importServiceKeys(values: ParsedServiceKeyEnv, io: Pick<SetupKeysIO, 'print'>, options: SetupKeysOptions): Promise<{ stored: string[]; rejected: string[]; unverified: string[] }> {
75
+ const accepted = new Map<string, string>();
76
+ const rejected: string[] = [];
77
+ const unverified: string[] = [];
78
+ const env = options.env ?? process.env;
79
+ for (const [name, value] of values) {
80
+ const item = SERVICE_KEY_CATALOG.find(candidate => candidate.kind === 'api-key' && candidate.envNames.includes(name));
81
+ if (!item) { rejected.push(name); continue; }
82
+ if (env[name]?.trim() === value) io.print(`${name}: 환경에서 이미 제공됨 · 캐시에도 저장합니다 · 값 출력 0`);
83
+ const verification = await verifyServiceKey(item.id, value, {
84
+ env,
85
+ cacheDir: options.cacheDir,
86
+ baseUrl: providerBaseUrl(options.config, item.id),
87
+ });
88
+ if (verification.result === 'verified') accepted.set(name, value);
89
+ else if (verification.result === 'unsupported') {
90
+ accepted.set(name, value);
91
+ unverified.push(name);
92
+ io.print(`${item.label}: 최소 확인을 지원하지 않아 검증 없이 저장합니다 · 값 출력 0`);
93
+ }
94
+ else {
95
+ rejected.push(name);
96
+ io.print(`${item.label}: 검증 ${verification.result}${verification.httpStatus ? ` (HTTP ${verification.httpStatus})` : ''} · 저장 안 함`);
97
+ }
98
+ }
99
+ const saved = accepted.size ? storeServiceKeys(accepted, { env, cacheDir: options.cacheDir }) : { stored: [] };
100
+ if (saved.stored.length) io.print(`저장 완료: ${saved.stored.join(', ')} · 값 출력 0`);
101
+ return { stored: saved.stored, rejected: rejected.sort(), unverified: unverified.sort() };
102
+ }
103
+
104
+ export async function runSetupKeys(io: SetupKeysIO, options: SetupKeysOptions): Promise<{ stored: string[]; skipped: string[] }> {
105
+ const providers = await detectProviders({ env: options.env });
106
+ for (const line of renderProviderProposal(options.config, providers)) io.print(line);
107
+ const { listCodexAccountsInStore } = await import('../oauth/codex-account-store.js');
108
+ const codexAccounts = listCodexAccountsInStore().map(account => account.name);
109
+ io.print(`Codex 계정: ${codexAccounts.length ? codexAccounts.join(', ') : '없음'} · 추가: 별도 CODEX_HOME에서 codex login 후 elanous provider codex account import <이름> --home <홈>`);
110
+ const statuses = serviceKeyStatus({ env: options.env, cacheDir: options.cacheDir });
111
+ const entries = SERVICE_KEY_CATALOG.filter(item => item.kind === 'api-key' && (item.demoRequired || options.includeOptional));
112
+ const stored: string[] = [];
113
+ const skipped: string[] = [];
114
+ for (const item of entries) {
115
+ const status = statuses.find(candidate => candidate.id === item.id);
116
+ if (!status) { io.print(`${item.label}: 상태 확인 불가 · 건너뜀`); skipped.push(item.id); continue; }
117
+ if (status.configured) { io.print(`${item.label}: 이미 설정됨`); continue; }
118
+ const envName = item.envNames[0];
119
+ if (!envName) continue;
120
+ io.print(`${item.label} · ${item.setupUrl} · ${item.demoRequired ? '데모 필요' : '선택'}`);
121
+ if (!io.askSecret) {
122
+ io.print(`${item.label}: 이 입력 화면은 비밀 입력을 지원하지 않습니다 · eln setup keys --paste-env 사용`);
123
+ skipped.push(item.id);
124
+ continue;
125
+ }
126
+ const value = (await io.askSecret(`${envName} (Enter=건너뜀): `)).trim();
127
+ if (!value) { skipped.push(item.id); continue; }
128
+ const result = await importServiceKeys(new Map([[envName, value]]), io, options);
129
+ if (result.stored.includes(envName)) stored.push(envName);
130
+ else skipped.push(item.id);
131
+ }
132
+ for (const line of renderServiceKeyStatus({ env: options.env, cacheDir: options.cacheDir })) io.print(line);
133
+ return { stored, skipped };
134
+ }
135
+
136
+ export const FIRST_RUN_PROVIDER_SETUP_MENU_HEADING = '처음 실행 LLM 설정';
137
+ export const FIRST_RUN_PROVIDER_SETUP_MENU_CHOICES = '1 Codex 구독 로그인 · 2 API 키 입력 · Enter 건너뛰기';
138
+ export const FIRST_RUN_PROVIDER_SETUP_MENU_MAX_MISSES = 3;
139
+
140
+ /** First-run entry: offer the existing Codex device login or the same verified-key flow as `setup keys`. */
141
+ export async function runFirstRunProviderSetup(io: SetupKeysIO, options: SetupKeysOptions): Promise<FirstRunProviderSetupResult> {
142
+ const choices = ['codex-login', 'api-key'] as const;
143
+ let misses = 0;
144
+ let choice: typeof choices[number];
145
+ for (;;) {
146
+ io.print(FIRST_RUN_PROVIDER_SETUP_MENU_HEADING);
147
+ io.print(FIRST_RUN_PROVIDER_SETUP_MENU_CHOICES);
148
+ const parsed = parseMenuAnswer(await io.ask('선택: '), choices);
149
+ if (parsed.kind === 'cancel') return null;
150
+ if (parsed.kind === 'miss') {
151
+ misses += 1;
152
+ if (misses >= FIRST_RUN_PROVIDER_SETUP_MENU_MAX_MISSES) return { kind: 'needs-llm' };
153
+ continue;
154
+ }
155
+ choice = parsed.provider;
156
+ break;
157
+ }
158
+
159
+ if (choice === 'codex-login') {
160
+ try {
161
+ await (options.loginWithCodex ?? loginWithCodex)({ onProgress: (event) => {
162
+ if (event.type === 'user_code') io.print(`Codex 로그인: ${event.loginUrl} · 코드 ${event.userCode}`);
163
+ else if (event.type === 'polling') io.print('Codex 로그인을 기다리는 중…');
164
+ else if (event.type === 'exchanging') io.print('Codex 로그인을 확인하는 중…');
165
+ } });
166
+ io.print('Codex 로그인 완료');
167
+ return 'openai-codex';
168
+ } catch {
169
+ io.print('Codex 로그인을 완료하지 못했습니다. 다시 시도하거나 Enter로 건너뛰세요.');
170
+ return null;
171
+ }
172
+ }
173
+ // Keep the exact environment object through storage and rediscovery: storeServiceKeys
174
+ // writes accepted values into it as well as the protected cache, so a newly entered
175
+ // key is immediately visible to detectProviders and resolveProviderCredential.
176
+ const env = options.env ?? process.env;
177
+ await runSetupKeys(io, { ...options, env });
178
+ // runSetupKeys handles an absent askSecret capability per item (skip + safe guidance);
179
+ // it does not throw or turn the first-run entry into a crash.
180
+ const providers = (await detectProviders({ env }))
181
+ .filter(provider => provider.available && provider.auth === 'apikey');
182
+ const available = [...new Set(providers.map(provider => provider.provider as LLMProviderName))];
183
+ if (!available.length) return null;
184
+ io.print(`기본 공급자 선택: ${available.map((provider, index) => `${index + 1} ${provider}`).join(' · ')}`);
185
+ const answer = (await io.ask('기본 공급자 번호 (Enter=건너뜀): ')).trim();
186
+ return available[Number(answer) - 1] ?? null;
187
+ }
@@ -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
+ }
@@ -23,13 +23,16 @@ import { mapInventory, renderMapReduceTable, type MapInventory, type MapItem, ty
23
23
  import type { MapRecipe, MapRunRow } from '../task-agent/map-run-ledger.js';
24
24
  import { createMapHostLauncher, type HostMapItem } from '../task-agent/map-host-adapter.js';
25
25
  import type { GraphRunOptions, GraphRunState } from '../graph-runner/runner.js';
26
+ import type { PluginWizardDeps } from '../graph-wizard/mission-compose.js';
27
+ import type { TaskPluginWizardHostPorts } from './task-plugin-wizard-host.js';
26
28
  import { parseAskTargetPathHintsResult } from '../self-dev/launch-preflight-text.js';
27
29
  import { effectiveInstanceRoot } from '../instance/resolve.js';
30
+ import type { LaunchRequestDoor } from '../execution-loop/launch-gate.js';
28
31
  import { HAND_MOVE_KINDS, recordHandMove } from '../task-agent/live-move-history.js';
29
32
  import type { TierSizedDecompose } from '../task-agent/tier-split.js';
30
33
  import type { AdvanceMissionResult, MissionDecompose, PieceEvidenceReader } from '../task-agent/mission.js';
31
34
  import { formatSevenVerbLive, formatTaskAgentCover, measureSevenVerbLive, measureTaskAgentCover, type CoverRow, type ImplementCardRunBinding, type ImplementRunMergeEvent, type SevenVerbLive, type TaskAgentCoverInput } from '../task-agent/cover.js';
32
- import { measureRepairOutcomes } from '../task-agent/repair-outcomes.js';
35
+ import { measureRepairOutcomes, measureRepairTierModels } from '../task-agent/repair-outcomes.js';
33
36
  import { LogStore, STORE_SAFETY_MAX, type LogQuery, type LogStoreRow } from '../mss/logging/log-store.js';
34
37
  import { resolveLogTargets } from './logs-cli.js';
35
38
  import { createTasksCliContext, handleError, NEXUS_DOWN, NexusUnavailable, registerTaskAgentSink, registerTaskListCommand, registerTaskShowCommand, registerTasksRoot, request, responseJson, TASK_AGENT_SINK_SURFACE } from './tasks-read-cli.js';
@@ -66,6 +69,22 @@ export interface TasksCliDeps {
66
69
  taskStatePath?: string;
67
70
  /** 조합 선택 시험에서만 그래프 저장소 루트를 바꾼다. */
68
71
  taskCompositionRoot?: string;
72
+ /** Isolated task hand launch-door injection; production uses the hand's instance-scoped default. */
73
+ taskLaunchRequestDoor?: LaunchRequestDoor;
74
+ /** Optional task-hand smart-plugin host bridge; production defaults use shared question/outbound and side-tab adapters. */
75
+ taskPluginWizardDeps?: PluginWizardDeps;
76
+ /** Test-only fake host ports; only consumed by `tasks hand --missing-tool`. */
77
+ taskPluginWizardHostPorts?: TaskPluginWizardHostPorts;
78
+ /** Graph-composition LLM seam for isolated `tasks hand --missing-tool` tests. */
79
+ taskComposeCallLLM?: import('../graph-wizard/generate.js').GraphWizardDeps['callLLM'];
80
+ /** Isolated plugin install root for the task-hand wizard. */
81
+ taskPluginInstallRoot?: string;
82
+ /** Isolated plugin marketplace directory for a task-hand wizard invocation. */
83
+ taskPluginMarketDir?: string;
84
+ /** COORD-ENTRANCE-FOLD test seam; production uses the invoking repository root. */
85
+ coordinatorShadowRoot?: string;
86
+ /** Deterministic task-hand time in isolated tests. */
87
+ taskNow?: () => Date;
69
88
  /** DRAFT-CLAIM-AUTO-2-FU — `tasks hand --draft-claim <pr>` 의 관측·게시·수확 리뷰 포트(시험 주입). 기본 = `defaultDraftClaimGhPorts()`(gh CLI ⊕ 생산 리뷰 러너). */
70
89
  draftClaimGh?: DraftClaimGhPorts;
71
90
  /** logs.db 싱크 등록(시험 주입). 기본 = `registerStandaloneLogSink`. `hand`·`show` 가 부른다. */
@@ -1969,9 +1988,20 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
1969
1988
  if (!existsSync(path)) throw new Error('TA 카드 원장 없음 — 수리 0건으로 판정 불가');
1970
1989
  const tasks = readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(path).tasks;
1971
1990
  if (!tasks || typeof tasks !== 'object' || Array.isArray(tasks)) throw new Error('TA 카드 원장 tasks 없음 — 수리 0건으로 판정 불가');
1972
- const report = measureRepairOutcomes(Object.values(tasks), { since, until });
1973
- if (opts.json) out(JSON.stringify(report));
1974
- else out(`수리 결과(카드 원장) ${report.applied} 적용 · ${report.failed} 실패 · ${report.unconfirmed} 미확정 · 카드 ${report.cards} · 결과 ${report.results} · runId 결손 ${report.missingRunId} · 미지 효과 ${report.unknownEffect} (기간 내 최신 결과 · 판단 로그 아님)`);
1991
+ const cards = Object.values(tasks);
1992
+ const window = { since, until };
1993
+ const report = measureRepairOutcomes(cards, window);
1994
+ const tierModel = measureRepairTierModels(cards, window);
1995
+ if (opts.json) out(JSON.stringify({ ...report,
1996
+ window: { since: new Date(since).toISOString(), until: new Date(until).toISOString() }, tierModel,
1997
+ }));
1998
+ else {
1999
+ out(`수리 결과(카드 원장) ${report.applied} 적용 · ${report.failed} 실패 · ${report.unconfirmed} 미확정 · 카드 ${report.cards} · 결과 ${report.results} · runId 결손 ${report.missingRunId} · 미지 효과 ${report.unknownEffect} (기간 내 최신 결과 · 판단 로그 아님)`);
2000
+ out(`수리 호출 창 ${new Date(since).toISOString()} ≤ at < ${new Date(until).toISOString()} · 시도 ${tierModel.samples} · ${tierModel.measured ? '측정' : '미측정'}`);
2001
+ for (const cell of tierModel.byTierModel) out(`${cell.tier}\t${cell.model}\t${cell.measured ? cell.n : '미측정'}`);
2002
+ out(`Sol 호출 증거 ${tierModel.solCalls.length} · 호출 여부 미측정 ${tierModel.solCallUnmeasured.length}`);
2003
+ for (const call of tierModel.solCalls) out(`Sol\t${call.tier}\t${call.card}\t${call.runId}\t${call.at}`);
2004
+ }
1975
2005
  } catch (error) { out(error instanceof Error ? error.message : '수리 결과 원장 읽기 실패'); process.exitCode = 1; }
1976
2006
  });
1977
2007
 
@@ -2143,6 +2173,8 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
2143
2173
  .option('--goal <id>', '보드 소속 목표 id (task board)')
2144
2174
  .option('--milestone <id>', '보드 소속 이정표 id (task board)')
2145
2175
  .option('--target <dir>', '프로젝트 대상 디렉터리(있어야 한다 · 상대 경로는 절대로 · git 이 아니면 --completion 이 code-pr 밖이어야 한다) — 발사기를 이 디렉터리에서 띄운다')
2176
+ .option('--missing-tool <capability>', '능동 비서가 감지한 빠진 도구 — 마켓/스마트 플러그인 마법사를 같은 task-hand 조합 경로에서 실행')
2177
+ .option('--plugin-market-dir <dir>', '스마트 플러그인 마법사가 읽을 신뢰 마켓 인덱스 디렉터리')
2146
2178
  .option('--live', '실제로 발사한다(기본은 shadow — 명령만 출력)')
2147
2179
  .option('--ta-land', 'TA-LIVE-LAND-2 — 호스트는 재게이트만 하고 병합은 TASK-AGENT 의 propose-land(`pr land --expected-head`)에 맡긴다 · 카드 taLand ⊕ 발사 env ELANOUS_TA_LAND=1 · taskAgent.liveMoves 에 propose-land 가 없으면 종전대로 호스트가 병합')
2148
2180
  .option('--child-llm <provider/model>', 'TASKS-HAND-CHILD-LLM — 구현 자식 LLM(예: grok/grok-4.7) → 발사 인자 --child-llm-provider <provider> --child-llm-model <model> · «첫» `/` 에서만 가른다(모델 id 의 `/` 는 보존) · openrouter 는 모델 id 가 openrouter/ 접두를 포함하므로 전체를 모델로(openrouter/z-ai/glm-5.3 → --child-llm-model openrouter/z-ai/glm-5.3) · 카드 childLlm · 안 주면 명령·카드 무변경')
@@ -2152,7 +2184,7 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
2152
2184
  .option('--tag <k=v>', 'RUN-IDENTITY-TAGS — 출생 신분을 덮는다(class|care|rights|protect 의 k=v · 반복: --tag class=gate --tag protect=true) — 카드 원장 identity 에 남는다', (value: string, previous: string[] | undefined) => [...(previous ?? []), value])
2153
2185
  .option('--draft-claim <pr>', 'DRAFT-CLAIM-AUTO-2-FU — PR 를 관측(gh pr view)해 draftClaim 을 조립해 넘긴다 · 관측한 PR 머리에서 `elanous self review <pr> --json` 로 손 수확을 먼저 확정한다(확정 못 하면 claim 문면을 만들지 않는다) · claim 문면을 실제 PR 댓글로 게시(gh pr comment)한다 · 같은 PR 의 살아 있는 claim 기록(카드 draftClaim)이 있으면 거부한다')
2154
2186
  .option('--json', 'JSON 출력')
2155
- .action(async (text: string | undefined, opts: { seat?: TaskSeat; checklist?: string; version?: string; completion?: CompletionKind; mission?: string; project?: string; target?: string; goal?: string; milestone?: string; live?: boolean; taLand?: boolean; childLlm?: string; childLlmEffort?: string; roleLlm?: string[]; tier?: TaskCard['tier']; tag?: string[]; draftClaim?: string; json?: boolean }) => {
2187
+ .action(async (text: string | undefined, opts: { seat?: TaskSeat; checklist?: string; version?: string; completion?: CompletionKind; mission?: string; project?: string; target?: string; missingTool?: string; pluginMarketDir?: string; goal?: string; milestone?: string; live?: boolean; taLand?: boolean; childLlm?: string; childLlmEffort?: string; roleLlm?: string[]; tier?: TaskCard['tier']; tag?: string[]; draftClaim?: string; json?: boolean }) => {
2156
2188
  const suppliedText = text !== undefined;
2157
2189
  /** RUN-IDENTITY-TAGS — 칸을 찾은 판(출생 신분이 그 판의 칸 우선순위를 읽는다 · 개발 판 밖 칸도). */
2158
2190
  let birthBoardVersion: string | undefined;
@@ -2287,13 +2319,17 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
2287
2319
  if (!repo) throw new Error(`현재 worktree origin이 GitHub 저장소가 아니다: ${origin}`);
2288
2320
  const run = deps.handOpenPrRun ?? ((command: string, args: string[]) => spawnSync(command, args,
2289
2321
  { cwd: process.cwd(), encoding: 'utf8', timeout: 20_000, maxBuffer: 16 * 1024 * 1024 }));
2290
- const listed = run('gh', ['pr', 'list', '--repo', repo, '--state', 'open', '--limit', '500', '--json', 'number,body']);
2322
+ if (!/^[A-Z][A-Z0-9-]{2,}$/.test(opts.checklist)) throw new Error(`체크리스트 칸 ID 형식이 잘못됐다 — 구현 발사 0: ${opts.checklist}`);
2323
+ const search = `in:body "${opts.checklist}"`;
2324
+ const searchLimit = 1000;
2325
+ const listed = run('gh', ['pr', 'list', '--repo', repo, '--state', 'open', '--search', search,
2326
+ '--limit', String(searchLimit), '--json', 'number,body']);
2291
2327
  if (listed.status !== 0) throw new Error(`같은 칸 OPEN PR 조회 실패 — 구현 발사 0: ${opts.checklist}`);
2292
2328
  let rows: unknown;
2293
2329
  try { rows = JSON.parse(listed.stdout); } catch { throw new Error(`OPEN PR 목록 해석 실패 — 구현 발사 0: ${opts.checklist}`); }
2294
- if (!Array.isArray(rows) || rows.length >= 500 || !rows.every((row) =>
2330
+ if (!Array.isArray(rows) || rows.length >= searchLimit || !rows.every((row) =>
2295
2331
  Number.isSafeInteger(doctorObject(row)?.number) && typeof doctorObject(row)?.body === 'string')) {
2296
- throw new Error(`OPEN PR 목록 불완전 — 구현 발사 0: ${opts.checklist}`);
2332
+ throw new Error(`칸 ID 검색 결과 불완전 또는 ${searchLimit}건 상한 — 구현 발사 0: ${opts.checklist}`);
2297
2333
  }
2298
2334
  const openPrs = rows.filter((row) => cellIdFromBody(doctorObject(row)!.body as string) === opts.checklist)
2299
2335
  .map((row) => doctorObject(row)!.number as number);
@@ -2334,8 +2370,14 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
2334
2370
  return;
2335
2371
  }
2336
2372
  }
2373
+ const pluginWizardDeps = opts.missingTool
2374
+ ? deps.taskPluginWizardDeps ?? (await import('./task-plugin-wizard-host.js')).createTaskPluginWizardHostDeps(deps.taskPluginWizardHostPorts)
2375
+ : undefined;
2337
2376
  const handOpts = {
2338
2377
  text: resolved.text,
2378
+ ...(resolved.kind === 'work-order' ? { workOrder: resolved.order } : {}),
2379
+ ...(deps.coordinatorShadowRoot ? { coordinatorShadowRoot: deps.coordinatorShadowRoot } : {}),
2380
+ ...(deps.taskNow ? { now: deps.taskNow } : {}),
2339
2381
  ...(opts.project !== undefined && opts.target !== undefined ? { project: { id: opts.project, target: opts.target } } : {}),
2340
2382
  ...(opts.goal !== undefined ? { goal: opts.goal } : {}),
2341
2383
  ...(opts.milestone !== undefined ? { milestone: opts.milestone } : {}),
@@ -2350,9 +2392,18 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
2350
2392
  ...(opts.roleLlm?.length ? { parentRoleLlm: opts.roleLlm } : {}),
2351
2393
  ...(opts.tier !== undefined ? { tier: opts.tier } : {}),
2352
2394
  ...(opts.tag !== undefined ? { tags: opts.tag } : {}),
2395
+ ...(opts.missingTool && deps.taskComposeCallLLM ? { composeCallLLM: deps.taskComposeCallLLM } : {}),
2353
2396
  ...(birthBoardVersion !== undefined ? { checklistVersion: birthBoardVersion } : {}),
2354
2397
  ...(deps.taskStatePath ? { statePath: deps.taskStatePath } : {}),
2355
2398
  ...(deps.taskCompositionRoot ? { compositionRoot: deps.taskCompositionRoot } : {}),
2399
+ ...(deps.taskLaunchRequestDoor ? { launchRequestDoor: deps.taskLaunchRequestDoor } : {}),
2400
+ ...(opts.missingTool ? { pluginWizard: {
2401
+ missing: opts.missingTool,
2402
+ root: deps.taskPluginInstallRoot ?? effectiveInstanceRoot(),
2403
+ workspace: opts.target ? resolve(opts.target) : process.cwd(),
2404
+ ...(opts.pluginMarketDir ?? deps.taskPluginMarketDir
2405
+ ? { marketDir: resolve(opts.pluginMarketDir ?? deps.taskPluginMarketDir!) } : {}),
2406
+ }, ...(pluginWizardDeps ? { pluginWizardDeps } : {}) } : {}),
2356
2407
  launcher: deps.taskLauncher ?? defaultTaskLauncher,
2357
2408
  };
2358
2409
  // DRAFT-CLAIM-AUTO-2-FU — 생산 배선: `--draft-claim <pr>` 로 관측·게시·수확 리뷰 포트를 끼워 draftClaim(⊕ 손 수확)을
@@ -2398,7 +2449,8 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
2398
2449
  if (result.cwd) out(`(cwd: ${result.cwd})`);
2399
2450
  if (result.card.taLand) out('(ta-land — 발사 env ELANOUS_TA_LAND=1 · 원격 또는 로컬 부모 · taskAgent.liveMoves 에 propose-land 가 있으면 병합은 TASK-AGENT 몫, 없으면 종전대로 호스트 병합)');
2400
2451
  if (!result.launched && result.card.alreadyDoneCandidate) out('(main 증거 통과 — 발사 0 · green 후보만 기록, 주인 판정 대기)');
2401
- else if (!result.launched) out('(shadow — 띄우지 않았다 · 띄우려면 --live)');
2452
+ else if (!result.launched && result.mode === 'shadow') out('(shadow — 띄우지 않았다 · 띄우려면 --live)');
2453
+ else if (!result.launched) out(`(발사되지 않음 — ${result.reason ?? result.move.reason})`);
2402
2454
  }
2403
2455
  } catch (error) {
2404
2456
  out(error instanceof Error ? error.message : '과제 넘기기 실패');
@@ -0,0 +1,186 @@
1
+ import { closeSync, existsSync, mkdirSync, openSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join, resolve } from 'node:path';
3
+ import { spawnSync, type ChildProcess } from 'node:child_process';
4
+ import { getElanousConfigDir } from '../elanous-config-dir.js';
5
+ import { spawnElanous } from '../instance/spawn-elanous.js';
6
+ import { DEFAULT_TUI_TEST_READY_TIMEOUT_MS } from '../self-implement/elanous-tui-spawn.js';
7
+
8
+ export interface TuiTestRunResult {
9
+ readonly worktree: string;
10
+ readonly ptyId: string;
11
+ readonly runId: string;
12
+ readonly nexusUrl: string;
13
+ readonly nexusPid: number;
14
+ readonly snapshotPath: string;
15
+ readonly readyTimeoutMs: number;
16
+ readonly waitedMs: number;
17
+ readonly pwaBuild: 'built' | 'reused' | 'skipped';
18
+ }
19
+
20
+ export interface TuiTestDeps {
21
+ readonly repoRoot?: string;
22
+ readonly now?: () => Date;
23
+ readonly run?: (command: string, args: readonly string[], cwd: string, env?: NodeJS.ProcessEnv, timeoutMs?: number) => { status: number | null; stdout: string; stderr: string; error?: Error };
24
+ readonly fetch?: typeof fetch;
25
+ }
26
+
27
+ const runSync = (command: string, args: readonly string[], cwd: string, env?: NodeJS.ProcessEnv, timeoutMs = 5 * 60_000) => {
28
+ const result = spawnSync(command, [...args], { cwd, env, encoding: 'utf8', timeout: timeoutMs, maxBuffer: 16 * 1024 * 1024 });
29
+ return { status: result.status, stdout: result.stdout ?? '', stderr: result.stderr ?? '', ...(result.error ? { error: result.error } : {}) };
30
+ };
31
+
32
+ export function pwaBuildRequired(pwaDir: string): boolean {
33
+ return !existsSync(join(pwaDir, 'out', 'index.html'));
34
+ }
35
+
36
+ export function pwaBuildDecision(pwaDir: string, withPwaBuild = false): 'build' | 'reuse' | 'skip' {
37
+ if (!pwaBuildRequired(pwaDir)) return 'reuse';
38
+ return withPwaBuild ? 'build' : 'skip';
39
+ }
40
+
41
+ export function buildHeldTuiArgs(entry: string, tuiStateDir: string, readyTimeoutMs: number, cwd: string): string[] {
42
+ return [entry, '--test', 'dev', '--elanous', '--hold', '--json', '--isolated-root', tuiStateDir, '--ready-timeout-ms', String(readyTimeoutMs), '--cwd', cwd];
43
+ }
44
+
45
+ export function parseReadyHeldPty(output: string): { id: string; runId: string } | undefined {
46
+ const rows = JSON.parse(output) as Array<{ id: string; runId?: string; alive: boolean }>;
47
+ const row = rows.find((item) => item.alive && !!item.runId);
48
+ return row?.runId ? { id: row.id, runId: row.runId } : undefined;
49
+ }
50
+
51
+ function checkedRun(deps: TuiTestDeps, command: string, args: readonly string[], cwd: string, env?: NodeJS.ProcessEnv, timeoutMs?: number): string {
52
+ const result = (deps.run ?? runSync)(command, args, cwd, env, timeoutMs);
53
+ if (result.status !== 0) throw new Error(`${command} ${args.join(' ')} failed (status=${result.status}): ${(result.stderr || result.stdout || result.error?.message || 'no diagnostic').trim()}`);
54
+ return result.stdout;
55
+ }
56
+
57
+ async function waitForNexus(logPath: string, child: ChildProcess, deadline: number, fetcher: typeof fetch): Promise<string> {
58
+ let last = 'no response';
59
+ while (Date.now() < deadline) {
60
+ if (child.exitCode !== null) throw new Error(`isolated Nexus exited before readiness (status=${child.exitCode}): ${readFileSync(logPath, 'utf8').slice(-1200)}`);
61
+ const log = existsSync(logPath) ? readFileSync(logPath, 'utf8') : '';
62
+ const port = /(?:http:\/\/(?:0\.0\.0\.0|127\.0\.0\.1):|시험 대역에서 :)([0-9]+)(?: 임대)?/u.exec(log)?.[1];
63
+ if (port) {
64
+ try {
65
+ const response = await fetcher(`http://127.0.0.1:${port}/v1/terminals`, { signal: AbortSignal.timeout(2_000) });
66
+ if (response.status < 500) return `http://127.0.0.1:${port}`;
67
+ last = `HTTP ${response.status}`;
68
+ } catch (error) { last = error instanceof Error ? error.message : String(error); }
69
+ } else if (log) last = log.slice(-500);
70
+ await new Promise((resolveWait) => setTimeout(resolveWait, 250));
71
+ }
72
+ throw new Error(`isolated Nexus did not answer before the shared readiness deadline (${last})`);
73
+ }
74
+
75
+ function launchHeldTui(entry: string, cwd: string, env: NodeJS.ProcessEnv, stateDir: string, deadline: number): ChildProcess {
76
+ const logPath = join(stateDir, 'tui-test-held.log');
77
+ const logFd = openSync(logPath, 'a', 0o600);
78
+ let child: ChildProcess;
79
+ try {
80
+ child = spawnElanous(buildHeldTuiArgs(entry, join(stateDir, '..', '.elanous-test-tui'), Math.max(1, deadline - Date.now()), cwd).slice(1), {
81
+ bin: entry,
82
+ stateDir: join(stateDir, '..', '.elanous-test-tui'),
83
+ cwd, env, detached: true, stdio: ['ignore', logFd, logFd],
84
+ });
85
+ } finally {
86
+ closeSync(logFd);
87
+ }
88
+ child.unref();
89
+ child.once('error', () => {});
90
+ return child;
91
+ }
92
+
93
+ async function waitForHeldTui(entry: string, cwd: string, env: NodeJS.ProcessEnv, stateDir: string, child: ChildProcess, deadline: number, deps: TuiTestDeps): Promise<{ id: string; runId: string }> {
94
+ const logPath = join(stateDir, 'tui-test-held.log');
95
+ const startedAt = Date.now();
96
+ let last = 'PTY registry has no row yet';
97
+ while (Date.now() < deadline) {
98
+ if (child.exitCode !== null) {
99
+ const output = existsSync(logPath) ? readFileSync(logPath, 'utf8') : '';
100
+ throw new Error(`held TUI launcher exited before its PTY was registered (status=${child.exitCode}): ${output.slice(-1200)}`);
101
+ }
102
+ try {
103
+ const output = checkedRun(deps, 'bun', [entry, '--test-state-dir', stateDir, 'pty', 'list', '--json'], cwd, env, Math.min(15_000, Math.max(1, deadline - Date.now())));
104
+ const held = parseReadyHeldPty(output);
105
+ if (held) return held;
106
+ last = 'PTY registry returned no alive held TUI';
107
+ } catch (error) {
108
+ last = error instanceof Error ? error.message : String(error);
109
+ }
110
+ await new Promise((resolveWait) => setTimeout(resolveWait, 1_000));
111
+ }
112
+ if (child.pid !== undefined) {
113
+ try { process.kill(-child.pid, 'SIGTERM'); } catch { /* process may already have exited */ }
114
+ }
115
+ const output = existsSync(logPath) ? readFileSync(logPath, 'utf8') : '';
116
+ throw new Error(`held TUI did not register an alive PTY before the shared deadline (waitedMs=${Date.now() - startedAt}; ${last}): ${output.slice(-1200)}`);
117
+ }
118
+
119
+ export async function runTuiTestUniverse(options: { readyTimeoutMs?: number; withPwaBuild?: boolean } = {}, deps: TuiTestDeps = {}): Promise<TuiTestRunResult> {
120
+ const repoRoot = resolve(deps.repoRoot ?? process.cwd());
121
+ const readyTimeoutMs = options.readyTimeoutMs ?? DEFAULT_TUI_TEST_READY_TIMEOUT_MS;
122
+ if (!Number.isSafeInteger(readyTimeoutMs) || readyTimeoutMs < 1) throw new Error('--ready-timeout-ms must be a positive integer');
123
+ const stamp = (deps.now ?? (() => new Date()))().toISOString().replace(/[-:.]/gu, '').replace('T', '-').replace('Z', 'Z');
124
+ const branch = `codex/tui-test-${stamp}`;
125
+ const worktreeBase = join(getElanousConfigDir(), 'worktrees', 'tui-test');
126
+ const worktree = join(worktreeBase, stamp);
127
+ mkdirSync(worktreeBase, { recursive: true });
128
+
129
+ checkedRun(deps, 'git', ['fetch', 'origin', 'main'], repoRoot, undefined, 60_000);
130
+ checkedRun(deps, 'git', ['worktree', 'add', '-b', branch, worktree, 'origin/main'], repoRoot, undefined, 5 * 60_000);
131
+ const { linkWorktreeDependencies } = await import('../git-fs/worktree.js');
132
+ linkWorktreeDependencies(repoRoot, worktree, ['node_modules']);
133
+
134
+ const pwaDir = join(worktree, 'apps/pwa');
135
+ const pwaDecision = pwaBuildDecision(pwaDir, options.withPwaBuild);
136
+ let pwaBuild: TuiTestRunResult['pwaBuild'] = pwaDecision === 'reuse' ? 'reused' : 'skipped';
137
+ if (pwaDecision === 'build') {
138
+ checkedRun(deps, 'bun', ['install', '--frozen-lockfile'], pwaDir, undefined, 5 * 60_000);
139
+ checkedRun(deps, 'bun', ['run', 'build'], pwaDir, undefined, 10 * 60_000);
140
+ pwaBuild = 'built';
141
+ }
142
+
143
+ const entry = join(worktree, 'bin/elanous.mjs');
144
+ const testStateDir = join(worktree, '.elanous-test');
145
+ const tuiStateDir = join(worktree, '.elanous-test-tui');
146
+ const testEnv = { ...process.env };
147
+ delete testEnv.ELANOUS_STATE_DIR;
148
+ delete testEnv.ELANOUS_CONFIG_DIR;
149
+ delete testEnv.ELANOUS_NEXUS_HEADLESS;
150
+ checkedRun(deps, 'bun', [entry, 'config', 'sync-test', '--state-dir', testStateDir, '--json'], worktree, testEnv, 30_000);
151
+ checkedRun(deps, 'bun', [entry, '--config-dir', testStateDir, 'config', 'set', 'global.nexus.pwa.shareTailnet', 'disabled', '--no-backup'], worktree, testEnv, 30_000);
152
+ mkdirSync(testStateDir, { recursive: true });
153
+ const nexusLogPath = join(testStateDir, 'tui-test-nexus.log');
154
+ const nexusLogFd = openSync(nexusLogPath, 'a');
155
+ const nexusEntry = join(repoRoot, 'bin/elanous.mjs');
156
+ const nexusEnv = { ...testEnv, ELANOUS_CONFIG_DIR: testStateDir, ELANOUS_TOOL_CWD: worktree };
157
+ const nexusProcess = spawnElanous(['--test-state-dir', testStateDir, 'nexus', 'run', '--no-auto-build', '--no-watch', '--no-mcp', '--no-auth', '--http-host', '127.0.0.1', '--tool-cwd', worktree], {
158
+ bin: nexusEntry,
159
+ stateDir: testStateDir,
160
+ cwd: worktree, env: nexusEnv, detached: true, stdio: ['ignore', nexusLogFd, nexusLogFd],
161
+ });
162
+ closeSync(nexusLogFd);
163
+ nexusProcess.unref();
164
+ const readinessDeadline = Date.now() + readyTimeoutMs;
165
+ try {
166
+ const nexusUrl = await waitForNexus(nexusLogPath, nexusProcess, readinessDeadline, deps.fetch ?? fetch);
167
+ const ptyReadyStartedAt = Date.now();
168
+ const launcher = launchHeldTui(entry, worktree, testEnv, testStateDir, readinessDeadline);
169
+ const held = await waitForHeldTui(entry, worktree, testEnv, testStateDir, launcher, readinessDeadline, deps);
170
+ const ptyId = held.id;
171
+
172
+ const isolatedArgs = ['--test-state-dir', testStateDir];
173
+ const ptyList = JSON.parse(checkedRun(deps, 'bun', [entry, ...isolatedArgs, 'pty', 'list', '--json'], worktree, testEnv, 30_000)) as Array<{ id: string; runId?: string; alive: boolean }>;
174
+ const row = ptyList.find((item) => item.id === ptyId && item.alive);
175
+ if (row?.runId !== held.runId) throw new Error(`held PTY ${ptyId} is absent or has a different runId in the same test universe`);
176
+ const snapshot = checkedRun(deps, 'bun', [entry, ...isolatedArgs, 'pty', 'snapshot', ptyId], worktree, testEnv, 30_000);
177
+ const evidenceDir = join(testStateDir, 'evidence');
178
+ const snapshotPath = join(evidenceDir, 'tui-test-snapshot.txt');
179
+ mkdirSync(evidenceDir, { recursive: true });
180
+ writeFileSync(snapshotPath, snapshot, 'utf8');
181
+ return { worktree, ptyId, runId: row.runId, nexusUrl, nexusPid: nexusProcess.pid ?? -1, snapshotPath, readyTimeoutMs, waitedMs: Date.now() - ptyReadyStartedAt, pwaBuild };
182
+ } catch (error) {
183
+ try { checkedRun(deps, 'bun', [entry, '--test-state-dir', testStateDir, 'nexus', 'stop'], worktree, testEnv, 15_000); } catch { /* preserve the primary readiness failure */ }
184
+ throw error;
185
+ }
186
+ }