elanous 0.2.34 → 0.2.36

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 (802) 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/chunks/{abb4b98b.163e0f56e84ae35d.js → 053a429e.9a63436527cc751c.js} +1 -1
  4. package/apps/pwa/out/_next/static/chunks/109.f196abf3484bb97f.js +287 -0
  5. package/apps/pwa/out/_next/static/chunks/1201.afbfc5b1c5e5cbe4.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1517.9275b89572098ff3.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1574.ad11f8db8396ab45.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1614.7a8c5c40aee0261f.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/1871-f1eb29d8dbb4065b.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/190.285c832bd9626f8c.js +64 -0
  11. package/apps/pwa/out/_next/static/chunks/2193.0ea24c4a7aa1d004.js +36 -0
  12. package/apps/pwa/out/_next/static/chunks/223-ad865c1e80491d78.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/2265-f0d90b6dbec05f81.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/2267.eb4a62a209f09ec4.js +149 -0
  15. package/apps/pwa/out/_next/static/chunks/2341-86cd06c0cf01aa33.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/2352.9abc42422bade876.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/2397-c1653a816061842d.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/2500.cbc1257b774aae52.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/{6086.913a69e6fa3e4a8b.js → 2683.c9773a0c589b031b.js} +4 -4
  20. package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +24 -0
  21. package/apps/pwa/out/_next/static/chunks/{5576-82d3703636d5c4b9.js → 275-02ea4c2a33980422.js} +3 -3
  22. package/apps/pwa/out/_next/static/chunks/{ffdc3a04.b9c23c1b28dd4a96.js → 2812ca6a.3b9f4a7a08885744.js} +1 -1
  23. package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2941.3c3546f96bc6efa7.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +24 -0
  26. package/apps/pwa/out/_next/static/chunks/{9550.d5f76828f972058c.js → 2986.45d7652e4f13557e.js} +2 -2
  27. package/apps/pwa/out/_next/static/chunks/3031-85328a92fcce4da6.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/{8817.61bb7ffbba502ecb.js → 3136.30aaaa5fa03662a3.js} +1 -1
  29. package/apps/pwa/out/_next/static/chunks/{9131-fce7256c4180c4a5.js → 3148-98efd4869d660a87.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/{3498.cf2a15a8a9e5b926.js → 3155.2587a55196ecb394.js} +3 -3
  31. package/apps/pwa/out/_next/static/chunks/3277.785db1cf09f98601.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/3320-f9c77381f85a2c0a.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/{3103.84470c8445962f04.js → 3324.a09703033abcbd2f.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/3386-91049feabff9a94e.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/339.80afb7e8839372af.js +8 -0
  36. package/apps/pwa/out/_next/static/chunks/3410.7f9af5ab77cbe65f.js +115 -0
  37. package/apps/pwa/out/_next/static/chunks/{3819.163d4777f0a597f6.js → 3538.a445e50bb359d068.js} +2 -2
  38. package/apps/pwa/out/_next/static/chunks/3540c645.2595a6af01a97672.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3621.581b2054cc14bee4.js +286 -0
  40. package/apps/pwa/out/_next/static/chunks/3676.8c28d16fd84ca843.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/{3414.172ad4ca2d9b08e8.js → 3727.7949ccaacaa71242.js} +2 -2
  42. package/apps/pwa/out/_next/static/chunks/375-b84540853523fe52.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3757-180308bc61021b05.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +74 -0
  45. package/apps/pwa/out/_next/static/chunks/3840-5825d56d46976a92.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{9b48c871.204d5d13e7809bd0.js → 3a3d9966.cc4d4585a2708e7c.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/4067-bf9aa60547972937.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4116.a84a92a2492c080e.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4176.e5729c93c29151eb.js +104 -0
  51. package/apps/pwa/out/_next/static/chunks/4227-e6c84686bc8946ca.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/{6740.43de73fc427c9fe2.js → 4286.b70c4520306817e8.js} +1 -1
  53. package/apps/pwa/out/_next/static/chunks/4304.e9b2512834a9e23e.js +23 -0
  54. package/apps/pwa/out/_next/static/chunks/4327.b9e08a71c0009348.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{8548.036c344973968847.js → 4615.8525eb0add35eba6.js} +1 -1
  56. package/apps/pwa/out/_next/static/chunks/4946.bd106eafd668f248.js +148 -0
  57. package/apps/pwa/out/_next/static/chunks/{3411-f87314c6c66ebc73.js → 5085-bce4904931767ca6.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/5125.2eb9968b83767193.js +93 -0
  59. package/apps/pwa/out/_next/static/chunks/5128-75b733fd74a9a1eb.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/{3110.0a7065f25c841818.js → 528.38ce20ef8aa251ff.js} +16 -16
  61. package/apps/pwa/out/_next/static/chunks/5489f3fe.4bb1458b09f6dead.js +122 -0
  62. package/apps/pwa/out/_next/static/chunks/{1644.35dd25240ae24e4b.js → 552.b7d061ad91eeac51.js} +2 -2
  63. package/apps/pwa/out/_next/static/chunks/5560-2a4648f6a30f16e7.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{3837.722e053fb9f321ad.js → 5711.957b095705c12560.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/{2124.ed5bf480cea7f85b.js → 575.d929793a53f27c4b.js} +1 -1
  66. package/apps/pwa/out/_next/static/chunks/5772-e29e14f8ff127122.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5887.5b2f5b44ce0f7e9a.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5899-4c112a2d908cf97f.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{7562.948255cbc3e79d33.js → 599.c39c571b6733f2a2.js} +2 -2
  70. package/apps/pwa/out/_next/static/chunks/6041.1b65efb796ebc2a5.js +79 -0
  71. package/apps/pwa/out/_next/static/chunks/6057-765c0a26028c86b2.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6142.f289e0d039f453a6.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6199-6bcd61d2a3910e04.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/6236.cdf7293e710a9b2d.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/6387-237e079dac9a3ae6.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6448-b6d272d074276e14.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/6466-92e65a48490b68a9.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/6566.926a1d1b7c911442.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6580-cdc0e4a634ce4708.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/6659-b242dc31b20b3f29.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6690.c5d9b321b1f79384.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/671-e9b6ad0c771c5514.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6862.bcbf89dd0f4496b3.js +27 -0
  84. package/apps/pwa/out/_next/static/chunks/6912-7b375ee48732c767.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/{5446.edf141cff9ef647d.js → 6925.562d532110879886.js} +1 -1
  86. package/apps/pwa/out/_next/static/chunks/{7005.1623d2aea78eb85f.js → 6943.c6b24124853a47b2.js} +1 -1
  87. package/apps/pwa/out/_next/static/chunks/727.7deb87749b0a343a.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/{8368.014caa8de2f5af34.js → 7481.39f7a4654907bf6e.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/7545.b1aa42cd15503319.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7551-416d298c2dc4a9ab.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/{2554.3b5e200f5f5cfcd6.js → 771.c3cdb6c1f7f47c02.js} +16 -16
  92. package/apps/pwa/out/_next/static/chunks/7784.1f0ac4a16d190cf4.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7870-309de463786ac1fc.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7888-e29b151bb6a3bb8b.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{3121.779fafe3e44612c5.js → 7891.03f910124a737985.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/7905-6ba78d9234608f79.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8037.e254fd797aa224d1.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8207.f527886b7c464529.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/856.50bda61439d465e6.js +62 -0
  100. package/apps/pwa/out/_next/static/chunks/{9a8cb466.cc9fc9e6e46038aa.js → 873d6c12.09bd499f57171543.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/{7431.3051e9b8a4372d2d.js → 8904.7d51af2dc033965c.js} +2 -2
  102. package/apps/pwa/out/_next/static/chunks/9031-92e9b487edb681ee.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/9060.5410d9f6a95f6287.js +90 -0
  104. package/apps/pwa/out/_next/static/chunks/914.8abefd48d579547b.js +94 -0
  105. package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/{1895-60ed0e341c658bd4.js → 9250-072df22eaadaa6b5.js} +1 -1
  107. package/apps/pwa/out/_next/static/chunks/9289.3e92f278821e18e0.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9319.7816d3cc741cd34f.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9327-e016bb9f1674d24f.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/9365.3de48bf75193ff9a.js +77 -0
  111. package/apps/pwa/out/_next/static/chunks/9383.5b5e9aa56b5fea97.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9387-cb929573ef436f39.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9489.c27becacc3283dec.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/{2547.dd27303624cb4da8.js → 9514.131c52cc75fe6439.js} +1 -1
  115. package/apps/pwa/out/_next/static/chunks/9536.28962663c7734376.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9686-12286f5bbf15a5a0.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9776.289d40cc5a4c342a.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9789.60f723d18097ec30.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/989.f0c17523c5e61f65.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9972-1df393aa8d4f7d52.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9f31e478.fefcbcd3c388ebc5.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-96750aba7430959f.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4105e5bbbb043024.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5d4fa75c2acb113e.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-a79a9bdb3b2142bf.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-f1c2047484992a35.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-15ffc49b2d8c70e2.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-67d53a3fc8734135.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-e30c8dc696491336.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-2136e04fa77696e2.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-fecd2814790c2e12.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-280aa4a98fc5bb44.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-c14e96b65fb4b883.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-187dac74825ed6bf.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-6bc7246ea8c92448.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/{page-4fb31eb476dcbad3.js → page-083747f1d4518f61.js} +1 -1
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-96750aba7430959f.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-15ca95a16ec96e1f.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-a8ac031b3810eb64.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-8835f93110494cda.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-e2de2e59111c9aad.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f2b2e4bf6e981450.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-5b92b7f75df20948.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-468eddf2b1a84ecb.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-2af16e62c12f22df.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-18b40867a77a5793.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-fe934f2979f5a4a2.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-3eec435537357170.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ff88cbfd2aa99fc8.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a5b39fb780c70ab5.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ae465dde1d1b3933.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-e7abc34a48a6f71e.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-cab9674fde9ead26.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1da49bc8712284d0.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5e8aa657551ac912.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-fcc36f36c6dc1fe2.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d22db22f2a7296ca.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-d12dc7b1773878f0.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-99debec9ea7fbec0.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-96750aba7430959f.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-2a088a78bad7e924.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-2e8ed57db7e69993.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-4b3a16213c2ae8fe.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f098747ddf38c98b.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-c15958835534404b.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-68279e3c843c1fd7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-a34a74453367a39d.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-8767a7db2155a5bd.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-bd5976683460d7f2.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b7364835e7f2ef54.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-311af16b3ee0ffca.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fb670757274ae990.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{5014f970-22bef0b5210f7d60.js → ccae1c4b-0cf414f5eff1b10d.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/{4fa33ebd.21c1bd5b294496e6.js → ceba0382.650712b56b85b582.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/da5ecc5c-b005ad8cac737d57.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/f9a61e4d.1fc2c1dbdd49fe46.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/framework-6d497cbf1eef04c6.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-app-012f5edec932f337.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-da5aeb809edc94a2.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-5ee319af6f749dfe.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-4bc84653a718d6c6.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-8a96cf6775c73d6e.js +1 -0
  183. package/apps/pwa/out/_next/static/{L04y73dlwKeTW-GetaTF3 → uC-N0emedeNOFuaBQFv-I}/_buildManifest.js +1 -1
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +22 -22
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +22 -22
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +22 -22
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +21 -21
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +21 -21
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +22 -22
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +21 -21
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +22 -22
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +22 -22
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +21 -21
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +22 -22
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +22 -22
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +22 -22
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +22 -22
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +21 -21
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +21 -21
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +22 -22
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +22 -22
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +22 -22
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +21 -21
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +21 -21
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +22 -22
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +22 -22
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +21 -21
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +21 -21
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +21 -21
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +22 -22
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +22 -22
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +21 -21
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +22 -22
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +22 -22
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +22 -22
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +22 -22
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +22 -22
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +21 -21
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +22 -22
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +22 -22
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +22 -22
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +22 -22
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +22 -22
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +22 -22
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +22 -22
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +22 -22
  277. package/bin/elanous.mjs +3 -2
  278. package/catalog/providers/opengateway.yaml +25 -0
  279. package/docs/goal-context/01-goal-authoring-checks.md +8 -0
  280. package/docs/goal-context/03-verification-menu.md +24 -0
  281. package/docs/goal-context/04-mock-scenarios.md +100 -0
  282. package/docs/goal-context/05-authoring-lessons.jsonl +47 -0
  283. package/docs/goal-context/README.md +7 -0
  284. package/graphs/catalog/catalog.yaml +1 -1
  285. package/graphs/default-loop.yaml +63 -4
  286. package/graphs/document-loop.yaml +51 -3
  287. package/graphs/implement-loop.yaml +77 -4
  288. package/graphs/journey/ta-journey.yaml +11 -1
  289. package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
  290. package/graphs/journey/units/author-dialogue/observe.ts +96 -0
  291. package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
  292. package/graphs/operate-loop.yaml +51 -3
  293. package/graphs/release/recipes.yaml +6 -0
  294. package/graphs/release/release-loop.yaml +17 -4
  295. package/graphs/research-loop.yaml +137 -3
  296. package/graphs/test-diet/test-diet.yaml +3 -0
  297. package/graphs/wizard/recipes.yaml +44 -0
  298. package/graphs/wizard/wizard-loop.yaml +44 -0
  299. package/graphs/work/research-report.yaml +2 -0
  300. package/package.json +1 -1
  301. package/scripts/ci-typecheck-changed.ts +139 -5
  302. package/scripts/coord-role-pack.ts +19 -6
  303. package/scripts/first10-gate.ts +416 -0
  304. package/scripts/fleet/wsl-node-setup.sh +432 -0
  305. package/scripts/hq/standby-snapshot.ts +17 -12
  306. package/scripts/release-loop/docs-land-node.ts +21 -5
  307. package/scripts/release-loop/docs-node.ts +204 -8
  308. package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
  309. package/scripts/release-loop/gate-node.ts +427 -72
  310. package/scripts/release-loop/gate-partial.ts +65 -11
  311. package/scripts/release-loop/gate-radius-live.ts +177 -0
  312. package/scripts/release-loop/gate-radius-shadow.ts +1 -1
  313. package/scripts/release-loop/node-verdict.ts +14 -1
  314. package/scripts/release-loop/npm-publish-node.ts +66 -12
  315. package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
  316. package/scripts/release-loop/pwa-remote.ts +166 -0
  317. package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
  318. package/scripts/release-loop/resume-cap.ts +14 -34
  319. package/scripts/release-loop/resume-release.ts +78 -15
  320. package/scripts/release-loop/traffic-node.ts +59 -0
  321. package/scripts/release-loop/traffic-transition.ts +159 -0
  322. package/scripts/release-loop/unattended-release.ts +2 -0
  323. package/scripts/rhythm/daily.ts +137 -3
  324. package/scripts/test-diet/lib.ts +6 -1
  325. package/scripts/test-diet/node.ts +194 -13
  326. package/scripts/ux-sim.ts +92 -0
  327. package/skills/README.md +1 -0
  328. package/src/acp/core-turn-bridge.ts +48 -6
  329. package/src/agent/delegate-hint.ts +16 -0
  330. package/src/agent/runner.ts +82 -2
  331. package/src/agent/self-ambient-cache.ts +8 -0
  332. package/src/agent/task-notification.ts +56 -10
  333. package/src/agent/types.ts +4 -0
  334. package/src/agent-substrate/acp-reviewer.ts +39 -4
  335. package/src/agent-substrate/pr-reviewer.ts +72 -3
  336. package/src/agent-substrate/review-intent.ts +29 -2
  337. package/src/agent-substrate/review-observation.ts +3 -0
  338. package/src/agent-substrate/self-review-cli.ts +229 -28
  339. package/src/autopilot/mission-codebase-gate.ts +141 -12
  340. package/src/autopilot/pr-manager.ts +240 -41
  341. package/src/boot/daemon-tools/self-implement.ts +1 -0
  342. package/src/budget/run-usage-rollup.ts +1 -0
  343. package/src/budget/usage-outcomes.ts +8 -4
  344. package/src/capture/tui-self-report.ts +102 -0
  345. package/src/chat/goal-continue-verdict.ts +41 -0
  346. package/src/chat/index.ts +30 -6
  347. package/src/chat/internal-turn-origin.ts +1 -0
  348. package/src/chat/paste-fold.ts +86 -0
  349. package/src/chat/pickers/modal-runtime.ts +10 -27
  350. package/src/chat/tool-render/block.ts +32 -0
  351. package/src/chat/tool-render/dispatch.ts +2 -20
  352. package/src/chat/tool-render/result-text.ts +98 -0
  353. package/src/chat/turn-typeahead.ts +70 -7
  354. package/src/cli/agent-cli.ts +13 -2
  355. package/src/cli/config-audit.ts +119 -0
  356. package/src/cli/doctor-cli.ts +26 -1
  357. package/src/cli/guardian-cli.ts +10 -0
  358. package/src/cli/herdr-cli.ts +34 -0
  359. package/src/cli/light-entry-route.ts +50 -7
  360. package/src/cli/log-event-names.ts +2 -0
  361. package/src/cli/make-cli.ts +247 -11
  362. package/src/cli/msg-cli.ts +117 -3
  363. package/src/cli/pod-cli.ts +77 -3
  364. package/src/cli/pr-cli.ts +34 -18
  365. package/src/cli/pr-land-base-read.ts +11 -2
  366. package/src/cli/pr-land-heavy-remote.ts +6 -3
  367. package/src/cli/pr-land-overlap-evidence.ts +23 -4
  368. package/src/cli/pr-land-pod-shadow-job.ts +3 -0
  369. package/src/cli/pr-land-recovery.ts +117 -1
  370. package/src/cli/pty-takeover-cli.ts +8 -7
  371. package/src/cli/release-checklist-read-cli.ts +79 -0
  372. package/src/cli/release-cli.ts +92 -106
  373. package/src/cli/release-single-flight.ts +1 -1
  374. package/src/cli/remote-resolve.ts +1 -1
  375. package/src/cli/root-tui-entry.ts +48 -0
  376. package/src/cli/sim-cli.ts +22 -0
  377. package/src/cli/tasks-card-show.ts +162 -0
  378. package/src/cli/tasks-cli.ts +1065 -338
  379. package/src/cli/tasks-read-cli.ts +197 -0
  380. package/src/cli/usage-cli.ts +13 -11
  381. package/src/clipboard/history.ts +179 -13
  382. package/src/config.ts +8 -1
  383. package/src/core-turn/run-core-turn.ts +4 -2
  384. package/src/core-turn/run-goal-loop.ts +73 -16
  385. package/src/core-turn/types.ts +6 -1
  386. package/src/dashboard/chat/acp-chat.ts +8 -0
  387. package/src/dashboard/context/keys.ts +8 -31
  388. package/src/dashboard/index.ts +280 -59
  389. package/src/dashboard/input/agent-wake.ts +7 -1
  390. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +146 -3
  391. package/src/dashboard/input/chat-main-slash-command.ts +4 -2
  392. package/src/dashboard/input/goal-continue.ts +210 -0
  393. package/src/dashboard/input/goal-interim.ts +2 -0
  394. package/src/dashboard/input/internal-turn.ts +2 -8
  395. package/src/dashboard/input/seat-autowake.ts +9 -7
  396. package/src/dashboard/input/turn-autoheal.ts +52 -0
  397. package/src/dashboard/render/theme-resolver.ts +33 -4
  398. package/src/dashboard/seat-boot-preamble.ts +132 -5
  399. package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
  400. package/src/dashboard/slash-runtime/dashboard-handlers.ts +3 -2
  401. package/src/dashboard/slash-runtime/model-choices.ts +15 -0
  402. package/src/dashboard/stale-install-check.ts +3 -99
  403. package/src/debug/batch-queue.ts +119 -0
  404. package/src/debug/tui-log-tag.ts +67 -0
  405. package/src/display/agent-surface.ts +7 -0
  406. package/src/domains/schedule-registry.ts +16 -2
  407. package/src/domains/standalone-log-sink.ts +15 -2
  408. package/src/esc-abort-gate.ts +69 -0
  409. package/src/git-fs/idle-refresh.ts +76 -0
  410. package/src/git-fs/index.ts +18 -7
  411. package/src/git-fs/worktree.ts +137 -5
  412. package/src/graph-kinds/registry.ts +2 -2
  413. package/src/graph-runner/graph-cli.ts +18 -0
  414. package/src/graph-runner/runner.ts +173 -21
  415. package/src/graph-wizard/generate.ts +108 -4
  416. package/src/graph-wizard/steps.ts +15 -0
  417. package/src/grok/credential.ts +10 -3
  418. package/src/grounding/proactive-ground.ts +86 -0
  419. package/src/harness/control-inbox.ts +49 -1
  420. package/src/harness/harness-cli-command.ts +163 -35
  421. package/src/harness/harness-incidents.ts +85 -1
  422. package/src/harness/launch-utterance-ledger.ts +208 -0
  423. package/src/harness/pod-control-send.ts +33 -5
  424. package/src/harness/self-send-remote.ts +69 -0
  425. package/src/harness/self-send-routing-guard.ts +6 -0
  426. package/src/harness/self-send-target.ts +4 -3
  427. package/src/impl-discipline/detector.ts +16 -4
  428. package/src/impl-discipline/system-prompt.ts +11 -0
  429. package/src/impl-discipline/types.ts +2 -2
  430. package/src/index.ts +822 -154
  431. package/src/input-core/context-key-runtime.ts +21 -0
  432. package/src/intake-plane/already-built-hint.ts +4 -2
  433. package/src/intake-plane/requirement-funnel.ts +29 -1
  434. package/src/light-cli.ts +32 -11
  435. package/src/llm/opengateway-models.ts +11 -0
  436. package/src/llm/provider-credentials.ts +14 -0
  437. package/src/llm/provider-detect.ts +8 -1
  438. package/src/llm/runtime-model-family.ts +2 -1
  439. package/src/llm-wellformed.ts +70 -0
  440. package/src/llm.ts +247 -59
  441. package/src/loops/msg-wake.ts +35 -39
  442. package/src/loops/orchestrator/inbox.ts +59 -11
  443. package/src/loops/orchestrator/knowhow-pack.ts +364 -0
  444. package/src/loops/orchestrator/tick.ts +5 -1
  445. package/src/maturity/feature-maturity.ts +1 -1
  446. package/src/model-tier/llm-tier-map.ts +15 -1
  447. package/src/models/prompts.ts +17 -2
  448. package/src/msg/msg-post-office.ts +116 -0
  449. package/src/mss/logging/log-store.ts +79 -22
  450. package/src/native-tool-catalog.ts +15 -1
  451. package/src/nexus/api/decisions-route.ts +38 -18
  452. package/src/nexus/api/graph-wizard-api.ts +20 -2
  453. package/src/nexus/api/loop-resources.ts +13 -1
  454. package/src/nexus/boot/register-mcp-clients.ts +263 -38
  455. package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
  456. package/src/oauth/codex.ts +7 -0
  457. package/src/onboarding/first-run.ts +37 -6
  458. package/src/onboarding/web-first.ts +43 -11
  459. package/src/ops/overview-collect.ts +30 -9
  460. package/src/ops/overview.ts +22 -9
  461. package/src/persona/loader.ts +11 -0
  462. package/src/persona/types.ts +8 -0
  463. package/src/pr-tool/census.ts +261 -27
  464. package/src/prompt-library/session-guidance.ts +14 -0
  465. package/src/provider-summary.ts +8 -0
  466. package/src/pty-shell/herdr-agent-report.ts +118 -9
  467. package/src/pty-shell/herdr-prompt.ts +266 -0
  468. package/src/pty-shell/pty-control-ipc.ts +151 -8
  469. package/src/pty-shell/pty-manifest.ts +7 -0
  470. package/src/pty-shell/pty-special-keys.ts +42 -2
  471. package/src/pty-shell/stale-install-check.ts +99 -0
  472. package/src/pty-shell/tui-run-state.ts +14 -2
  473. package/src/release-loop/auto-start.ts +20 -2
  474. package/src/release-loop/checklist.ts +100 -4
  475. package/src/release-loop/landed-but-yellow.ts +129 -5
  476. package/src/release-loop/light-rc.ts +1 -0
  477. package/src/release-loop/rehearsal.ts +37 -21
  478. package/src/repl/index.ts +192 -17
  479. package/src/repl/ops-msg-bridge.ts +32 -0
  480. package/src/seat-loop/knowhow-lint.ts +1 -1
  481. package/src/self-dev/ask-launch-flow.ts +44 -5
  482. package/src/self-dev/cli-help-text.ts +17 -0
  483. package/src/self-dev/decompose-proposal.ts +172 -20
  484. package/src/self-dev/decompose.ts +61 -0
  485. package/src/self-dev/dev-cli.ts +48 -12
  486. package/src/self-dev/dev-pipeline.ts +8 -2
  487. package/src/self-dev/draft-residue.ts +37 -1
  488. package/src/self-dev/draft-sweep.ts +137 -11
  489. package/src/self-dev/draft-triage-rules.ts +138 -0
  490. package/src/self-dev/fleet-reduce.ts +3 -2
  491. package/src/self-dev/glm-credential-guard.ts +77 -0
  492. package/src/self-dev/graph-front-nodes.ts +112 -0
  493. package/src/self-dev/graph-journey-nodes.ts +2 -0
  494. package/src/self-dev/graph-journey-route.ts +12 -2
  495. package/src/self-dev/harness-run-cli.ts +3 -15
  496. package/src/self-dev/orchestrate-cli-text.ts +10 -0
  497. package/src/self-dev/orchestrate-cli.ts +68 -3
  498. package/src/self-dev/orchestrate.ts +116 -17
  499. package/src/self-dev/review-provider-fallback.ts +35 -1
  500. package/src/self-dev/run-supervisor.ts +55 -2
  501. package/src/self-dev/run-types.ts +1 -1
  502. package/src/self-dev/self-orchestrate-runtime.ts +1 -11
  503. package/src/self-dev/shard-aggregate.ts +42 -5
  504. package/src/self-dev/shard-run.ts +8 -1
  505. package/src/self-health/autoheal.ts +153 -0
  506. package/src/self-health/signatures.ts +6 -0
  507. package/src/self-implement/blocked-draft-policy.ts +20 -0
  508. package/src/self-implement/classify-shadow.ts +3 -7
  509. package/src/self-implement/device-first.ts +116 -0
  510. package/src/self-implement/doctor-visit.ts +257 -2
  511. package/src/self-implement/evidence-command-budget.ts +80 -0
  512. package/src/self-implement/gate-baseline.ts +56 -17
  513. package/src/self-implement/gate-cli.ts +1 -0
  514. package/src/self-implement/gate-remote.ts +31 -20
  515. package/src/self-implement/goal-author-cli.ts +1 -0
  516. package/src/self-implement/goal-author-decompose.ts +534 -45
  517. package/src/self-implement/goal-author.ts +282 -7
  518. package/src/self-implement/goal-elaborate.ts +449 -0
  519. package/src/self-implement/goal-refine.ts +273 -0
  520. package/src/self-implement/graph-overlay-yaml.ts +14 -3
  521. package/src/self-implement/graph-variant.ts +40 -6
  522. package/src/self-implement/headless-elanous-driver.ts +19 -3
  523. package/src/self-implement/off-diff-evidence.ts +58 -6
  524. package/src/self-implement/orchestrator.ts +370 -62
  525. package/src/self-implement/pod-warm-pool-profile.ts +1 -0
  526. package/src/self-implement/pwa-import-graph.ts +1 -1
  527. package/src/self-implement/rework-budget-judgment.ts +5 -8
  528. package/src/self-implement/rework-policy.ts +30 -0
  529. package/src/self-implement/run-ledger.ts +108 -0
  530. package/src/self-implement/run-stop.ts +10 -1
  531. package/src/self-implement/run-ttl.ts +38 -24
  532. package/src/self-implement/running-runs.ts +29 -1
  533. package/src/self-implement/scope-adjacency.ts +115 -0
  534. package/src/self-implement/seams.ts +187 -28
  535. package/src/self-implement/stop-autoheal.ts +87 -1
  536. package/src/self-implement/wiring-check.ts +358 -0
  537. package/src/session-runtime/index.ts +1 -1
  538. package/src/setup/llm-env-detect.ts +5 -0
  539. package/src/shell-env-bootstrap.ts +11 -4
  540. package/src/skills/runner.ts +4 -2
  541. package/src/skills/tools/agent.ts +408 -40
  542. package/src/skills/tools/msg-ask.ts +100 -0
  543. package/src/skills/tools/ops-ledger.ts +2 -1
  544. package/src/skills/tools/schedule-wakeup.ts +23 -4
  545. package/src/skills/tools/shell.ts +61 -6
  546. package/src/skills/tools/terminal-modal-inject.ts +1 -2
  547. package/src/skills/tools/terminal-modal.ts +10 -8
  548. package/src/skills/url-router.ts +41 -1
  549. package/src/smart-wizard/run.ts +66 -0
  550. package/src/status/bar.ts +34 -6
  551. package/src/status/status-provider-info.ts +37 -6
  552. package/src/steward/hold-hygiene.ts +24 -6
  553. package/src/steward/rejudge-tick.ts +10 -2
  554. package/src/steward/ta-repair-event-collect.ts +17 -6
  555. package/src/steward/triage-budget.ts +194 -0
  556. package/src/steward/triage.ts +20 -3
  557. package/src/task-agent/actions.ts +72 -2
  558. package/src/task-agent/green-sweep.ts +4 -0
  559. package/src/task-agent/land-queue.ts +21 -8
  560. package/src/task-agent/live-moves.ts +182 -10
  561. package/src/task-agent/mission.ts +30 -0
  562. package/src/task-agent/parent-host.ts +123 -3
  563. package/src/task-agent/rejudge-on-head.ts +15 -0
  564. package/src/task-agent/repair-cycle.ts +138 -32
  565. package/src/task-agent/repair-next-move.ts +31 -3
  566. package/src/task-agent/repair-outcomes.ts +29 -0
  567. package/src/task-agent/repair-worker.ts +14 -4
  568. package/src/task-agent/shadow.ts +48 -4
  569. package/src/task-agent/task-card-prefix.ts +2 -0
  570. package/src/task-agent/task-hand.ts +525 -57
  571. package/src/task-agent/task-parent-role-llm.ts +36 -0
  572. package/src/task-agent/tier-split.ts +196 -0
  573. package/src/task-agent/work-order-build.ts +2 -0
  574. package/src/task-agent/work-order.ts +3 -2
  575. package/src/task-orchestrator/generator-prompt.ts +60 -11
  576. package/src/task-orchestrator/surfaces/pod-account-broker.ts +42 -0
  577. package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
  578. package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
  579. package/src/task-orchestrator/surfaces/pod-command-job.ts +130 -11
  580. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
  581. package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
  582. package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
  583. package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
  584. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +19 -2
  585. package/src/task-orchestrator/surfaces/pod-pool.ts +76 -4
  586. package/src/task-orchestrator/surfaces/pod-provenance.ts +82 -0
  587. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +18 -3
  588. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +16 -0
  589. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +224 -0
  590. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +201 -0
  591. package/src/task-orchestrator/surfaces/pod-si-warm-provider.ts +444 -0
  592. package/src/task-orchestrator/surfaces/pod-si-warm-runner.ts +387 -0
  593. package/src/task-orchestrator/surfaces/pod-si-warm-transport.ts +157 -0
  594. package/src/task-orchestrator/surfaces/pod-source-receive.ts +18 -0
  595. package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
  596. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +6 -2
  597. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +7 -0
  598. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +521 -40
  599. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
  600. package/src/task-orchestrator/surfaces/self-implement-pod.ts +759 -50
  601. package/src/task-orchestrator/surfaces/self-implement.ts +65 -2
  602. package/src/tool-runtime/index.ts +15 -2
  603. package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
  604. package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
  605. package/src/tty-foreground.ts +155 -0
  606. package/src/tui/README.md +2 -0
  607. package/src/tui/chat/background-job-status.ts +54 -0
  608. package/src/tui/chat/goal-interim.ts +173 -0
  609. package/src/tui/chat/log-view.ts +267 -0
  610. package/src/tui/chat/self-health-status.ts +232 -0
  611. package/src/tui/entry.ts +695 -0
  612. package/src/tui/input/composer.ts +151 -0
  613. package/src/tui/seat-mail-boot.ts +59 -0
  614. package/src/tui/slash/compact-command.ts +7 -0
  615. package/src/tui/slash/compact.ts +94 -0
  616. package/src/tui/slash/new-session.ts +35 -0
  617. package/src/tui/slash/resume.ts +75 -0
  618. package/src/tui-client/local-chat-turn.ts +282 -0
  619. package/src/tui-client/local-harness-command.ts +63 -0
  620. package/src/tui-client/local-provider-command.ts +184 -0
  621. package/src/tui-client/next-dashboard-runtime.ts +8 -0
  622. package/src/tui-client/next-loop-command.ts +70 -0
  623. package/src/tui-client/next-wakeup.ts +191 -0
  624. package/src/tui.ts +37 -0
  625. package/src/ui/modal-adapter.ts +2 -2
  626. package/src/user-config.ts +4 -2
  627. package/src/ux-sim/classic-tui-seat-scenarios.ts +516 -0
  628. package/src/ux-sim/cli-config-audit-device.ts +121 -0
  629. package/src/ux-sim/dashboard-event-loop-stall-monitor-device.ts +238 -0
  630. package/src/ux-sim/event-monkey.ts +379 -0
  631. package/src/ux-sim/fake-bin.ts +87 -7
  632. package/src/ux-sim/fake-herdr.ts +238 -0
  633. package/src/ux-sim/fake-llm.ts +111 -6
  634. package/src/ux-sim/fault-glm-no-credential.ts +116 -0
  635. package/src/ux-sim/fault-nextmove-dispatch.ts +367 -0
  636. package/src/ux-sim/fault-pod-codex-503.ts +211 -0
  637. package/src/ux-sim/fault-scope-escape-lift.ts +216 -0
  638. package/src/ux-sim/fault-tui-400-autoheal.ts +297 -0
  639. package/src/ux-sim/goal-device.ts +619 -0
  640. package/src/ux-sim/in-process-cli.ts +22 -5
  641. package/src/ux-sim/mock-authoring-first-run-child.ts +35 -0
  642. package/src/ux-sim/mock-authoring-first-run.ts +97 -0
  643. package/src/ux-sim/mock-seat-pty-frame-child.ts +29 -0
  644. package/src/ux-sim/mock-seat-pty-frame.ts +297 -0
  645. package/src/ux-sim/mock-seat-pty-sequence-child.ts +21 -0
  646. package/src/ux-sim/mock-seat-pty-sequence.ts +206 -0
  647. package/src/ux-sim/next-tui-seat-scenarios.ts +631 -0
  648. package/src/ux-sim/onboarding-first-run-device.ts +269 -0
  649. package/src/ux-sim/pty-key-modifiers-device.ts +85 -0
  650. package/src/ux-sim/subagent-tools-device.ts +81 -0
  651. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +250 -0
  652. package/src/ux-sim/tty-foreground-steal-child.ts +21 -0
  653. package/src/version/packed-revision.json +1 -1
  654. package/apps/pwa/out/_next/static/chunks/1162.c69abda138c7ce43.js +0 -79
  655. package/apps/pwa/out/_next/static/chunks/1449-1fede62af84c3e43.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/1598-13fc845935e816df.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/1639.62c5e16fa20d242f.js +0 -94
  658. package/apps/pwa/out/_next/static/chunks/1661-adb8b2babc9aaf8c.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/2147.107c0fc6146fb15a.js +0 -23
  660. package/apps/pwa/out/_next/static/chunks/2202-ef1c9b000c3074fc.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/2247.1e326638ee43e672.js +0 -115
  662. package/apps/pwa/out/_next/static/chunks/2268.56e1e3d58180abae.js +0 -8
  663. package/apps/pwa/out/_next/static/chunks/2469-606819c812414021.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/2593.e53c1620c0bb3599.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/2690.e96671114222676a.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/2898-79ee1a5cc0cd9d13.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/298.26099a9f65e5c8ff.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/2987-30cf9c2eb7b8bdd5.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/2992.51fc2a7295bd8139.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/3001-5a52788c813b6113.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/3014-291245fba9df7b5b.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/3068.ee78201f0251a18d.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/3083.cd399a17e9365f78.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/3117-e1c474683fd1f824.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/3251-2c17bd5a91f8de2e.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/326.3fb32322bb2ddf6d.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/3421-7ff7fbaa156985a7.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/381.f55dc63ea87735e6.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/4129-ab0a6189f1778633.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/4361.93d14ba594b3a035.js +0 -104
  681. package/apps/pwa/out/_next/static/chunks/4364.7a7eb19cceb67d2f.js +0 -286
  682. package/apps/pwa/out/_next/static/chunks/4406.d71f506f7c3ee9d3.js +0 -149
  683. package/apps/pwa/out/_next/static/chunks/4461.2ad1514180ae7e29.js +0 -148
  684. package/apps/pwa/out/_next/static/chunks/4479.bd309cbe0e3842ee.js +0 -64
  685. package/apps/pwa/out/_next/static/chunks/4522-05966f777d66d13b.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/4543-9a3e9812e845de65.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/4557.f8f1d84a0d90d590.js +0 -74
  688. package/apps/pwa/out/_next/static/chunks/4589-79b11542179ef58c.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/4633-9f8f9f88ffbb8f5c.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/4831.23af4d10c0697b5e.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/4983.5951b85724f61f2a.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/5028-f0722e6114c313e7.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/5249.96a848656b582a93.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/5311.16e0ffbfa5468b80.js +0 -62
  695. package/apps/pwa/out/_next/static/chunks/5489.ec2dd1b5272a19dc.js +0 -24
  696. package/apps/pwa/out/_next/static/chunks/559.df87695df637920c.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/5618-5c88f2f70178c4ad.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/5764.05487bf0b73ddb6b.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/5930.e678826c3f831aab.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/5dfb57f7.f2e3305326202474.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/6053-d893974de92e6198.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/6200-cefd6f33f59d765e.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/6314-edeba650ae686ac9.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/6316-bc9a9b74d7842d79.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/6476-13b9779b73528008.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/666-04db3ac4c8e3c66f.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/670.682e55106ef915a6.js +0 -77
  708. package/apps/pwa/out/_next/static/chunks/6816.b7ba9d0a1a4a46a7.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/690-fbbcc777f189af37.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/6989.0d3d4020e5cb3df6.js +0 -90
  711. package/apps/pwa/out/_next/static/chunks/7193-cf355cca5ba6c5d5.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/7217-d17393fe7af78fa6.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/7232.24edbd938a69c8d0.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/7295cd1e.b4b557908888eeee.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/7323.adb02de21991883c.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/7386.5d8e7e42e818dfb6.js +0 -287
  717. package/apps/pwa/out/_next/static/chunks/7448.478958ffbbba0ac0.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/7537.ba2208c5c656b8a3.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/7596-962ae6db6cfc9c83.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/7671.cff51beac212a2ba.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/7883.3916734ee16d3e58.js +0 -27
  722. package/apps/pwa/out/_next/static/chunks/7952.b192c31b6a0e00cc.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/801.5b24e81eded22d1b.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/8176.8c9a8613f5a01ac1.js +0 -36
  725. package/apps/pwa/out/_next/static/chunks/819e78a6.fa3dd7f7da19bf61.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/8220-78978450c3183d8d.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/8221-eb60b5bc692a3361.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/826.e9a26064f474949e.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/8459-a351487a4480f584.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/8482-75823d513a4ce151.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/8488.8da515248cda3f3a.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/8584.388a1779d9b203af.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/8637.a55e098e61ffefb8.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/9207-8e6a12db30373f32.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/9263-00ae932c62696a86.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/9318.caafc3a130e8769c.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/932.da3fb55951882562.js +0 -93
  738. package/apps/pwa/out/_next/static/chunks/9433.002f8426ac75b6b7.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/9464.dd631a5a14b1d660.js +0 -24
  740. package/apps/pwa/out/_next/static/chunks/9739.8d5f36ac67a3b236.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/9743.beeabb9d5f86abe4.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/9843-a23d3f32dc43f715.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/994-28211077c7c587d5.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-3b4c947f174e33d8.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/approvals/page-369d5ce99483f859.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-63c0ed0eb26e5fce.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/board/page-62802c6003bc85cc.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ecb41560d4e77be9.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/bots/page-7b65ad8130c93e95.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/ceo/page-8755477c15a9060c.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/chat/page-5725447dd972c471.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/consult/page-b979de0591a69375.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/control/page-6d0796bf4633751a.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/decisions/page-59c31dc0394e67b4.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/design-check/page-12dfc95f6cc5c718.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/editor/page-25788244e66aa4dd.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/exec/page-a2555dc705466322.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/healthz/route-3b4c947f174e33d8.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/inside/page-578729adbeaa40cb.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/intake/page-a1d20fffbec35205.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/layout-4a558f94516b8004.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/live/page-9e3834705b86145e.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/live-run/page-d7bff0f0905a662c.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/loops/page-cb1c5fe746ea4014.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/market/page-9ee320507356582a.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66fd183b74835886.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/morning/page-3272a064a01a9927.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/not-found-f281b7a7f6ef2529.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/observatory/page-d45a65f8b7124fcd.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-e9c1fe684dd19a66.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-b8322932fc6e34de.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-82c66d9af2290575.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/app/outputs/page-63c6752009c97b05.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/page-bb33d42ebc358aec.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7e4c9379197d7214.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-38bf1e9a7001732b.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/sessions/page-2e5b752012389d56.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-398c0faa173203f7.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/settings/page-002f53a965b6445c.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7f75997f61a26269.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/setup/layout-3b4c947f174e33d8.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/setup/page-05631753294f23fb.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/share/page-edd700fd2cc3d7f8.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/showroom/page-105f83ecb4594365.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/tasks/page-5823e87d2017f19c.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/term/page-df3445b207ceceab.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/today/page-b51ca09566c03de7.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/app/trace/page-8aacd5ded5dbac60.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/app/vault/page-bae3365a0b3c6a8e.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ed52b48ff1aa7fd.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b6f8cad35fe00946.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6d25ceda500d2457.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-b6401a5f2c962fe8.js +0 -1
  794. package/apps/pwa/out/_next/static/chunks/ebf6cf5e.0d2f887b040e80fb.js +0 -122
  795. package/apps/pwa/out/_next/static/chunks/f09ec7d7-d29abe23edcbb193.js +0 -1
  796. package/apps/pwa/out/_next/static/chunks/framework-9322cb8a56ac081c.js +0 -1
  797. package/apps/pwa/out/_next/static/chunks/main-2fbab294e49a1561.js +0 -1
  798. package/apps/pwa/out/_next/static/chunks/main-app-f36729f56621a8f3.js +0 -1
  799. package/apps/pwa/out/_next/static/chunks/pages/_app-2a62e450b47c6114.js +0 -1
  800. package/apps/pwa/out/_next/static/chunks/pages/_error-5e17f7b445f34d43.js +0 -1
  801. package/apps/pwa/out/_next/static/chunks/webpack-b4263e2190ea7adf.js +0 -1
  802. /package/apps/pwa/out/_next/static/{L04y73dlwKeTW-GetaTF3 → uC-N0emedeNOFuaBQFv-I}/_ssgManifest.js +0 -0
package/src/index.ts CHANGED
@@ -1,22 +1,13 @@
1
1
  #!/usr/bin/env bun
2
2
  // cron/launchd 최소 PATH 에서도 내부 gh/git subprocess 를 찾도록 PATH 를 먼저 보강(무음실패 근본·2026-07-25).
3
3
  import './ensure-bin-path.js';
4
+ import './instance/resolve.js';
4
5
  import { WORKFLOW_NODE_VARIANT_KEYS } from './workflow-runtime/schema.js';
5
6
  import { accessSync, constants as fsConstants, existsSync, lstatSync, readFileSync, readlinkSync, realpathSync, statSync } from 'node:fs';
6
7
  import type { SelfDevRunParticipant, SelfDevRunState } from './self-dev/run-store.js';
7
8
  import { applyConfigDirFlagFromArgv } from './cli/config-dir-flag.js';
8
9
  import { LOGS_SINCE_OPTION, registerLogsCommands } from './cli/logs-cli.js';
9
- import { registerDocsCommands } from './cli/docs-cli.js';
10
- import { registerBenchCommands } from './cli/bench-cli.js';
11
- import { registerRetroCommands } from './cli/retro-cli.js';
12
- import { registerMemoryCommands } from './cli/memory-cli.js';
13
- import { registerA2ACommands } from './cli/a2a-cli.js';
14
- import { registerPluginCommands } from './cli/plugin-cli.js';
15
- import { registerMakeCommand } from './cli/make-cli.js';
16
- import { registerConnectCommand, registerSkillsCommands } from './cli/skills-cli.js';
17
- import { registerImportCommand } from './cli/import-cli.js';
18
- import { registerPersonaCommands } from './cli/persona-cli.js';
19
- import { registerFleetCommands } from './cli/fleet-cli.js';
10
+
20
11
  import { readPipedStdin } from './cli/piped-stdin.js';
21
12
  import { writeStdoutJson } from './cli/stdout-json.js';
22
13
  import { writeStdoutFully } from './cli/stdout-flush.js';
@@ -28,77 +19,26 @@ import { ensureRunIdentity, getHarnessSpace, normalizeSpaceId } from './harness/
28
19
  // ⇒ «정적» import 로 올린다. 이 모듈은 부작용이 없어 부팅 비용이 사실상 0 이다.
29
20
  import { installDevCompletionGuard } from './self-dev/dev-completion-guard.js';
30
21
  import { formatOrchestrateResultLine } from './self-dev/orchestrate-summary-line.js';
31
- import { buildOrchestrateDecomposePrepareArgs, normalizeOrchestrateRequest, splitOrchestrateGoalTexts } from './self-dev/self-orchestrate-runtime.js';
22
+ import { normalizeOrchestrateRequest, splitOrchestrateGoalTexts } from './self-dev/orchestrate-cli-text.js';
23
+ import { DEV_PLAN_REPLACEMENT, formatDevPlanOptionHelp, HARNESS_RUN_DEPRECATION_HELP } from './self-dev/cli-help-text.js';
32
24
  import { CLI_ENTRANCE_BASELINE, evaluateCommandEntranceBaseline } from './self-dev/entrance-baseline.js';
33
25
  import { CLI_HARNESS_DOGFOOD_ENTRANCE, CLI_HARNESS_ORCHESTRATE_ENTRANCE, describeEntranceCommand, listEntrancesWithModelExposure, renderLaunchEntrances, summarizeEntrances, type EntranceId } from './self-dev/entrance-registry.js';
34
26
  import { isOldDoorInternalCall, refuseOldDoor } from './self-dev/old-door.js';
35
27
  import { collectCommandEntrances, renderCommandEntrances } from './self-dev/entrance-inventory.js';
36
28
  import { isGoalAuthorFileName } from './self-implement/goal-document.js';
37
29
  import { DEV_PIPELINE_SINK_SURFACE } from './self-implement/self-cli-sink-surface.js';
38
- import { registerPrivateLedgerCommands } from './cli/private-ledger-commands.js';
39
- import { registerKnowCommand } from './cli/know-cli.js';
40
- import { registerSeatRequestsCommands } from './cli/seat-requests-cli.js';
41
- import { registerSeatBootCommands } from './cli/seat-cli.js';
30
+
42
31
  import { applyTestStateDirFlagFromArgv } from './cli/test-state-dir-flag.js';
43
32
  import { applyTestFlagFromArgv, observeTestFlagOwnership, uncoveredTestFlagPaths, staleTestFlagPaths } from './cli/test-flag.js';
44
- import { registerPtyTakeoverCommands } from './cli/pty-takeover-cli.js';
45
- import { registerPtyRecordCommand } from './cli/pty-record-cli.js';
46
- import { registerLeaderCommands } from './cli/leader-cli.js';
47
- import { registerRepoCommands } from './cli/repo-cli.js';
48
- import { registerAgentCommands, runChatTurnCli, emitDetachedProgress } from './cli/agent-cli.js';
49
- export { runChatTurnCli, buildCliAgentTools, setCliAgentDispatchForTesting, emitDetachedProgress, emitHarnessFeedbackProgress } from './cli/agent-cli.js';
50
- import { registerOpsCommands } from './cli/ops-cli.js';
51
- import { registerOutputsCommands } from './cli/outputs-cli.js';
52
- import { registerPublishCommands } from './cli/publish-cli.js';
53
- import { registerAutopilotCommands } from './cli/autopilot-cli.js';
54
- import { registerRoleCommands } from './cli/role-cli.js';
55
- import { registerMachineCommands } from './cli/machine-cli.js';
33
+
56
34
  import { recordImagePinFromConfigSet, registerImageCommands } from './cli/image-cli.js';
57
- import { registerAgentEnvCommands } from './cli/agent-env-cli.js';
58
- import { registerScheduleCommands } from './cli/schedule-cli.js';
59
- import { registerGuardianCommands } from './cli/guardian-cli.js';
35
+
60
36
  export { runSchedule, scheduleCreatePlan } from './cli/schedule-cli.js';
61
37
  export type { ScheduleDispatch } from './cli/schedule-cli.js';
62
38
  import { registerReviewLoopOptions, buildReviewLoopOpts } from './agent-mission/review-loop-cli.js';
63
- import { registerCapabilitiesCommand } from './agent-mission/capabilities-cli.js';
64
- import { registerSupervisorMetricsCommand } from './agent-mission/supervisor-metrics-cli.js';
65
- import { agentBackendNames } from './agent-mission/driver.js';
66
- import { registerWhereCommand } from './cli/where-cli.js';
67
- import { registerShadowCommand } from './cli/shadow-cli.js';
68
- import { registerLlmDetectCommand } from './cli/llm-detect-cli.js';
69
- import { registerStorageDetectCommand } from './cli/storage-cli.js';
70
- import { registerPodCommands } from './cli/pod-cli.js';
71
- import { registerBrowserAnnotateCommand } from './cli/browser-annotate-cli.js';
72
- import { registerPendingQuestionsCommand } from './cli/pending-questions-cli.js';
73
- import { registerUsageCommand } from './cli/usage-cli.js';
74
- import { registerUsageDailyCommand } from './cli/usage-daily-cli.js';
75
- import { registerLiveCommands } from './cli/live-cli.js';
76
- import { registerResearchCommand } from './cli/research-cli.js';
77
- import { registerReleaseCommands } from './cli/release-cli.js';
78
- import { registerFreezeCommands } from './cli/freeze-cli.js';
79
- import { registerFlowCommands } from './cli/flow-cli.js';
80
- import { registerModelWatchCommand } from './cli/model-watch-cli.js';
81
- import { registerIntakeCommands } from './cli/intake-cli.js';
82
- import { registerTasksCommands } from './cli/tasks-cli.js';
83
- import { registerBriefCommands } from './cli/brief-cli.js';
84
- import { registerNotifyCommand } from './cli/notify-cli.js';
85
- import { registerAwayCommand } from './cli/away-cli.js';
86
- import { registerLabelsCommands } from './cli/labels-cli.js';
87
- import { registerMsgCommands } from './cli/msg-cli.js';
88
- import { registerDoctorCommand } from './cli/doctor-cli.js';
89
- import { registerProviderCommands } from './cli/provider-cli.js';
39
+
90
40
  export { buildCodexAccountImportGuidance, setCodexAccountLogSinkModuleForTesting } from './cli/provider-cli.js';
91
- import { registerControlCommands } from './cli/control-cli.js';
92
- import { registerHooksCommands } from './cli/hooks-cli.js';
93
- import { registerSetupCommand } from './cli/setup-cli.js';
94
- import { registerStartCommand } from './cli/start-cli.js';
95
- import { registerGroundingSourcesCli } from './grounding/sources-cli.js';
96
- import { registerGraphCommands } from './graph-runner/graph-cli.js';
97
- import { registerLoopCommands } from './loops/loop-cli.js';
98
- import { registerResourceCommands } from './cli/resource-cli.js';
99
- import { registerHqMovePlanCommand } from './hq/hq.js';
100
- import { registerCardCommand } from './task-cards/card-cli.js';
101
- import { registerLaunchHeadCommands } from './launch-head/launch-head-cli.js';
41
+
102
42
  import { acpServerHelpText } from './boot/acp-server-help.js';
103
43
  // IMPORTANT: parse `--config-dir <dir>` + `--test-state-dir <dir>`
104
44
  // BEFORE Commander loads — the resolvers are read at module-init
@@ -116,54 +56,314 @@ applyTestFlagFromArgv();
116
56
  // test-instance default so scoped storage commands stay inside that directory.
117
57
  applyConfigDirFlagFromArgv();
118
58
 
59
+ // Only unambiguous root commands take the small registrar path. Root help,
60
+ // unknown commands and unrecognized global flags keep the complete tree.
61
+ const INDEX_FAST_ROOTS = new Set(['a2a', 'agent-env', 'away', 'bench', 'brief', 'card', 'connect', 'control', 'docs', 'doctor', 'fleet', 'flow', 'freeze', 'graph', 'guardian', 'import', 'intake', 'know', 'labels', 'launch-head', 'leader', 'live', 'llm', 'loop', 'machine', 'make', 'memory', 'msg', 'notify', 'ops', 'outputs', 'plugin', 'pod', 'provider', 'pty', 'publish', 'questions', 'relay', 'release', 'repo', 'research', 'resource', 'retro', 'role', 'schedule', 'seat', 'shadow', 'skills', 'start', 'storage', 'tasks', 'where']);
62
+ function selectedIndexFastRoot(args: readonly string[]): string | undefined {
63
+ if (process.env.ELANOUS_TEST_FLAG_AUDIT === '1') return undefined;
64
+ let index = 0;
65
+ while (index < args.length && args[index]?.startsWith('-')) {
66
+ const flag = args[index]!;
67
+ index++;
68
+ if (flag === '--test' || flag.startsWith('--test=')) continue;
69
+ if (flag === '--config-dir' || flag === '--test-state-dir') {
70
+ if (!args[index] || args[index]!.startsWith('-')) return undefined;
71
+ index++;
72
+ continue;
73
+ }
74
+ if (flag.startsWith('--config-dir=') || flag.startsWith('--test-state-dir=')) continue;
75
+ return undefined;
76
+ }
77
+ const root = args[index];
78
+ // We cannot know every registrar's local options before it is loaded. Keep
79
+ // only universally recognized help (and where's measured JSON action) on
80
+ // the small path; all other options take the complete parser.
81
+ const fastOptions = new Set(root === 'where' ? ['--help', '-h', '--json'] : ['--help', '-h']);
82
+ if (args.slice(index + 1).some((arg) => arg.startsWith('-') && !fastOptions.has(arg))) return undefined;
83
+ return root && INDEX_FAST_ROOTS.has(root) ? root : undefined;
84
+ }
85
+ // An explicit `--tui next` launch does not dispatch a CLI subcommand. Keep command
86
+ // registrars out of the first-frame path while retaining the full tree for
87
+ // help, unknown commands and unrecognized global flags.
88
+ function selectedIndexNextTuiRoot(args: readonly string[]): '__tui_next__' | undefined {
89
+ const rootTui = extractRootTuiEntry(args);
90
+ if (rootTui.error || rootTui.entry !== 'next') return undefined;
91
+ const remaining = rootTui.args.filter((arg) => arg !== '--test' && !arg.startsWith('--test='));
92
+ return remaining.length === 0 ? '__tui_next__' : undefined;
93
+ }
94
+ // Test files import this module to inspect the complete Commander tree. An
95
+ // empty test-runner argv also looks like a bare next launch, so only the real
96
+ // CLI entry may take the next-only registrar path.
97
+ const isCliEntry = import.meta.main || /[\\/]bin[\\/]elanous\.mjs$/.test(process.argv[1] ?? '');
98
+ const INDEX_FAST_ROOT = selectedIndexFastRoot(process.argv.slice(2))
99
+ ?? (isCliEntry ? selectedIndexNextTuiRoot(process.argv.slice(2)) : undefined);
100
+ // Keep the historical index exports without forcing the agent engine into
101
+ // unrelated CLI commands at module load time.
102
+ export const runChatTurnCli: typeof import('./cli/agent-cli.js').runChatTurnCli =
103
+ async (...args) => (await import('./cli/agent-cli.js')).runChatTurnCli(...args);
104
+ export const buildCliAgentTools: typeof import('./cli/agent-cli.js').buildCliAgentTools =
105
+ (...args) => (require('./cli/agent-cli.js') as typeof import('./cli/agent-cli.js')).buildCliAgentTools(...args);
106
+ export const setCliAgentDispatchForTesting: typeof import('./cli/agent-cli.js').setCliAgentDispatchForTesting =
107
+ (...args) => (require('./cli/agent-cli.js') as typeof import('./cli/agent-cli.js')).setCliAgentDispatchForTesting(...args);
108
+ export const emitDetachedProgress: typeof import('./cli/agent-cli.js').emitDetachedProgress =
109
+ (...args) => (require('./cli/agent-cli.js') as typeof import('./cli/agent-cli.js')).emitDetachedProgress(...args);
110
+ export const emitHarnessFeedbackProgress: typeof import('./cli/agent-cli.js').emitHarnessFeedbackProgress =
111
+ (...args) => (require('./cli/agent-cli.js') as typeof import('./cli/agent-cli.js')).emitHarnessFeedbackProgress(...args);
112
+
113
+ // Selected root imports only its registrar; complete help and unknown routes load all.
114
+ const registerDocsCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'docs'
115
+ ? (() => undefined)
116
+ : (require('./cli/docs-cli.js') as typeof import('./cli/docs-cli.js')).registerDocsCommands) as typeof import('./cli/docs-cli.js').registerDocsCommands;
117
+ const registerBenchCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'bench'
118
+ ? (() => undefined)
119
+ : (require('./cli/bench-cli.js') as typeof import('./cli/bench-cli.js')).registerBenchCommands) as typeof import('./cli/bench-cli.js').registerBenchCommands;
120
+ const registerRetroCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'retro'
121
+ ? (() => undefined)
122
+ : (require('./cli/retro-cli.js') as typeof import('./cli/retro-cli.js')).registerRetroCommands) as typeof import('./cli/retro-cli.js').registerRetroCommands;
123
+ const registerMemoryCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'memory'
124
+ ? (() => undefined)
125
+ : (require('./cli/memory-cli.js') as typeof import('./cli/memory-cli.js')).registerMemoryCommands) as typeof import('./cli/memory-cli.js').registerMemoryCommands;
126
+ const registerA2ACommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'a2a'
127
+ ? (() => undefined)
128
+ : (require('./cli/a2a-cli.js') as typeof import('./cli/a2a-cli.js')).registerA2ACommands) as typeof import('./cli/a2a-cli.js').registerA2ACommands;
129
+ const registerPluginCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'plugin'
130
+ ? (() => undefined)
131
+ : (await import('./cli/plugin-cli.js')).registerPluginCommands) as typeof import('./cli/plugin-cli.js').registerPluginCommands;
132
+ const registerMakeCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'make'
133
+ ? (() => undefined)
134
+ : (require('./cli/make-cli.js') as typeof import('./cli/make-cli.js')).registerMakeCommand) as typeof import('./cli/make-cli.js').registerMakeCommand;
135
+ const registerConnectCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'connect'
136
+ ? (() => undefined)
137
+ : (require('./cli/skills-cli.js') as typeof import('./cli/skills-cli.js')).registerConnectCommand) as typeof import('./cli/skills-cli.js').registerConnectCommand;
138
+ const registerSkillsCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'skills'
139
+ ? (() => undefined)
140
+ : (require('./cli/skills-cli.js') as typeof import('./cli/skills-cli.js')).registerSkillsCommands) as typeof import('./cli/skills-cli.js').registerSkillsCommands;
141
+ const registerImportCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'import'
142
+ ? (() => undefined)
143
+ : (require('./cli/import-cli.js') as typeof import('./cli/import-cli.js')).registerImportCommand) as typeof import('./cli/import-cli.js').registerImportCommand;
144
+ const registerPersonaCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
145
+ ? (() => undefined)
146
+ : (await import('./cli/persona-cli.js')).registerPersonaCommands) as typeof import('./cli/persona-cli.js').registerPersonaCommands;
147
+ const registerFleetCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'fleet'
148
+ ? (() => undefined)
149
+ : (require('./cli/fleet-cli.js') as typeof import('./cli/fleet-cli.js')).registerFleetCommands) as typeof import('./cli/fleet-cli.js').registerFleetCommands;
150
+ const registerPrivateLedgerCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
151
+ ? (() => undefined)
152
+ : (require('./cli/private-ledger-commands.js') as typeof import('./cli/private-ledger-commands.js')).registerPrivateLedgerCommands) as typeof import('./cli/private-ledger-commands.js').registerPrivateLedgerCommands;
153
+ const registerKnowCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'know'
154
+ ? (() => undefined)
155
+ : (require('./cli/know-cli.js') as typeof import('./cli/know-cli.js')).registerKnowCommand) as typeof import('./cli/know-cli.js').registerKnowCommand;
156
+ const registerSeatRequestsCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'seat'
157
+ ? (() => undefined)
158
+ : (require('./cli/seat-requests-cli.js') as typeof import('./cli/seat-requests-cli.js')).registerSeatRequestsCommands) as typeof import('./cli/seat-requests-cli.js').registerSeatRequestsCommands;
159
+ const registerSeatBootCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'seat'
160
+ ? (() => undefined)
161
+ : (require('./cli/seat-cli.js') as typeof import('./cli/seat-cli.js')).registerSeatBootCommands) as typeof import('./cli/seat-cli.js').registerSeatBootCommands;
162
+ const registerPtyTakeoverCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'pty'
163
+ ? (() => undefined)
164
+ : (require('./cli/pty-takeover-cli.js') as typeof import('./cli/pty-takeover-cli.js')).registerPtyTakeoverCommands) as typeof import('./cli/pty-takeover-cli.js').registerPtyTakeoverCommands;
165
+ const registerPtyRecordCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'pty'
166
+ ? (() => undefined)
167
+ : (require('./cli/pty-record-cli.js') as typeof import('./cli/pty-record-cli.js')).registerPtyRecordCommand) as typeof import('./cli/pty-record-cli.js').registerPtyRecordCommand;
168
+ const registerLeaderCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'leader'
169
+ ? (() => undefined)
170
+ : (require('./cli/leader-cli.js') as typeof import('./cli/leader-cli.js')).registerLeaderCommands) as typeof import('./cli/leader-cli.js').registerLeaderCommands;
171
+ const registerRepoCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'repo'
172
+ ? (() => undefined)
173
+ : (require('./cli/repo-cli.js') as typeof import('./cli/repo-cli.js')).registerRepoCommands) as typeof import('./cli/repo-cli.js').registerRepoCommands;
174
+ const registerOpsCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'ops'
175
+ ? (() => undefined)
176
+ : (require('./cli/ops-cli.js') as typeof import('./cli/ops-cli.js')).registerOpsCommands) as typeof import('./cli/ops-cli.js').registerOpsCommands;
177
+ const registerOutputsCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'outputs'
178
+ ? (() => undefined)
179
+ : (require('./cli/outputs-cli.js') as typeof import('./cli/outputs-cli.js')).registerOutputsCommands) as typeof import('./cli/outputs-cli.js').registerOutputsCommands;
180
+ const registerPublishCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'publish'
181
+ ? (() => undefined)
182
+ : (require('./cli/publish-cli.js') as typeof import('./cli/publish-cli.js')).registerPublishCommands) as typeof import('./cli/publish-cli.js').registerPublishCommands;
183
+ const registerAutopilotCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
184
+ ? (() => undefined)
185
+ : (require('./cli/autopilot-cli.js') as typeof import('./cli/autopilot-cli.js')).registerAutopilotCommands) as typeof import('./cli/autopilot-cli.js').registerAutopilotCommands;
186
+ const registerRoleCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'role'
187
+ ? (() => undefined)
188
+ : (require('./cli/role-cli.js') as typeof import('./cli/role-cli.js')).registerRoleCommands) as typeof import('./cli/role-cli.js').registerRoleCommands;
189
+ const registerMachineCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'machine'
190
+ ? (() => undefined)
191
+ : (require('./cli/machine-cli.js') as typeof import('./cli/machine-cli.js')).registerMachineCommands) as typeof import('./cli/machine-cli.js').registerMachineCommands;
192
+ const registerAgentEnvCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'agent-env'
193
+ ? (() => undefined)
194
+ : (require('./cli/agent-env-cli.js') as typeof import('./cli/agent-env-cli.js')).registerAgentEnvCommands) as typeof import('./cli/agent-env-cli.js').registerAgentEnvCommands;
195
+ const registerScheduleCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'schedule'
196
+ ? (() => undefined)
197
+ : (require('./cli/schedule-cli.js') as typeof import('./cli/schedule-cli.js')).registerScheduleCommands) as typeof import('./cli/schedule-cli.js').registerScheduleCommands;
198
+ const registerGuardianCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'guardian'
199
+ ? (() => undefined)
200
+ : (require('./cli/guardian-cli.js') as typeof import('./cli/guardian-cli.js')).registerGuardianCommands) as typeof import('./cli/guardian-cli.js').registerGuardianCommands;
201
+ const registerCapabilitiesCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
202
+ ? (() => undefined)
203
+ : (require('./agent-mission/capabilities-cli.js') as typeof import('./agent-mission/capabilities-cli.js')).registerCapabilitiesCommand) as typeof import('./agent-mission/capabilities-cli.js').registerCapabilitiesCommand;
204
+ const registerSupervisorMetricsCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
205
+ ? (() => undefined)
206
+ : (require('./agent-mission/supervisor-metrics-cli.js') as typeof import('./agent-mission/supervisor-metrics-cli.js')).registerSupervisorMetricsCommand) as typeof import('./agent-mission/supervisor-metrics-cli.js').registerSupervisorMetricsCommand;
207
+ const registerWhereCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'where'
208
+ ? (() => undefined)
209
+ : (require('./cli/where-cli.js') as typeof import('./cli/where-cli.js')).registerWhereCommand) as typeof import('./cli/where-cli.js').registerWhereCommand;
210
+ const registerShadowCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'shadow'
211
+ ? (() => undefined)
212
+ : (require('./cli/shadow-cli.js') as typeof import('./cli/shadow-cli.js')).registerShadowCommand) as typeof import('./cli/shadow-cli.js').registerShadowCommand;
213
+ const registerLlmDetectCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'llm'
214
+ ? (() => undefined)
215
+ : (require('./cli/llm-detect-cli.js') as typeof import('./cli/llm-detect-cli.js')).registerLlmDetectCommand) as typeof import('./cli/llm-detect-cli.js').registerLlmDetectCommand;
216
+ const registerStorageDetectCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'storage'
217
+ ? (() => undefined)
218
+ : (require('./cli/storage-cli.js') as typeof import('./cli/storage-cli.js')).registerStorageDetectCommand) as typeof import('./cli/storage-cli.js').registerStorageDetectCommand;
219
+ const registerPodCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'pod'
220
+ ? (() => undefined)
221
+ : (require('./cli/pod-cli.js') as typeof import('./cli/pod-cli.js')).registerPodCommands) as typeof import('./cli/pod-cli.js').registerPodCommands;
222
+ const registerBrowserAnnotateCommand = (require('./cli/browser-annotate-cli.js') as typeof import('./cli/browser-annotate-cli.js')).registerBrowserAnnotateCommand;
223
+ const registerPendingQuestionsCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'questions'
224
+ ? (() => undefined)
225
+ : (require('./cli/pending-questions-cli.js') as typeof import('./cli/pending-questions-cli.js')).registerPendingQuestionsCommand) as typeof import('./cli/pending-questions-cli.js').registerPendingQuestionsCommand;
226
+ const registerUsageCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
227
+ ? (() => undefined)
228
+ : (require('./cli/usage-cli.js') as typeof import('./cli/usage-cli.js')).registerUsageCommand) as typeof import('./cli/usage-cli.js').registerUsageCommand;
229
+ const registerUsageDailyCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
230
+ ? (() => undefined)
231
+ : (require('./cli/usage-daily-cli.js') as typeof import('./cli/usage-daily-cli.js')).registerUsageDailyCommand) as typeof import('./cli/usage-daily-cli.js').registerUsageDailyCommand;
232
+ const registerLiveCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'live'
233
+ ? (() => undefined)
234
+ : (require('./cli/live-cli.js') as typeof import('./cli/live-cli.js')).registerLiveCommands) as typeof import('./cli/live-cli.js').registerLiveCommands;
235
+ const registerResearchCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'research'
236
+ ? (() => undefined)
237
+ : (require('./cli/research-cli.js') as typeof import('./cli/research-cli.js')).registerResearchCommand) as typeof import('./cli/research-cli.js').registerResearchCommand;
238
+ const registerReleaseCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'release'
239
+ ? (() => undefined)
240
+ : (require('./cli/release-cli.js') as typeof import('./cli/release-cli.js')).registerReleaseCommands) as typeof import('./cli/release-cli.js').registerReleaseCommands;
241
+ const registerFreezeCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'freeze'
242
+ ? (() => undefined)
243
+ : (require('./cli/freeze-cli.js') as typeof import('./cli/freeze-cli.js')).registerFreezeCommands) as typeof import('./cli/freeze-cli.js').registerFreezeCommands;
244
+ // TUI-HERDR-NAMED-AGENT (10-22): `herdr prompt` — herdr agent prompt rejects custom-reported agents.
245
+ const registerHerdrCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
246
+ ? (() => undefined)
247
+ : (require('./cli/herdr-cli.js') as typeof import('./cli/herdr-cli.js')).registerHerdrCommands) as typeof import('./cli/herdr-cli.js').registerHerdrCommands;
248
+ const registerFlowCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'flow'
249
+ ? (() => undefined)
250
+ : (require('./cli/flow-cli.js') as typeof import('./cli/flow-cli.js')).registerFlowCommands) as typeof import('./cli/flow-cli.js').registerFlowCommands;
251
+ const registerModelWatchCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
252
+ ? (() => undefined)
253
+ : (require('./cli/model-watch-cli.js') as typeof import('./cli/model-watch-cli.js')).registerModelWatchCommand) as typeof import('./cli/model-watch-cli.js').registerModelWatchCommand;
254
+ const registerIntakeCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'intake'
255
+ ? (() => undefined)
256
+ : (require('./cli/intake-cli.js') as typeof import('./cli/intake-cli.js')).registerIntakeCommands) as typeof import('./cli/intake-cli.js').registerIntakeCommands;
257
+ const registerTasksCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'tasks'
258
+ ? (() => undefined)
259
+ : (require('./cli/tasks-cli.js') as typeof import('./cli/tasks-cli.js')).registerTasksCommands) as typeof import('./cli/tasks-cli.js').registerTasksCommands;
260
+ const registerBriefCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'brief'
261
+ ? (() => undefined)
262
+ : (await import('./cli/brief-cli.js')).registerBriefCommands) as typeof import('./cli/brief-cli.js').registerBriefCommands;
263
+ const registerNotifyCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'notify'
264
+ ? (() => undefined)
265
+ : (require('./cli/notify-cli.js') as typeof import('./cli/notify-cli.js')).registerNotifyCommand) as typeof import('./cli/notify-cli.js').registerNotifyCommand;
266
+ const registerAwayCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'away'
267
+ ? (() => undefined)
268
+ : (await import('./cli/away-cli.js')).registerAwayCommand) as typeof import('./cli/away-cli.js').registerAwayCommand;
269
+ const registerLabelsCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'labels'
270
+ ? (() => undefined)
271
+ : (require('./cli/labels-cli.js') as typeof import('./cli/labels-cli.js')).registerLabelsCommands) as typeof import('./cli/labels-cli.js').registerLabelsCommands;
272
+ const registerMsgCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'msg'
273
+ ? (() => undefined)
274
+ : (require('./cli/msg-cli.js') as typeof import('./cli/msg-cli.js')).registerMsgCommands) as typeof import('./cli/msg-cli.js').registerMsgCommands;
275
+ const registerDoctorCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'doctor'
276
+ ? (() => undefined)
277
+ : (require('./cli/doctor-cli.js') as typeof import('./cli/doctor-cli.js')).registerDoctorCommand) as typeof import('./cli/doctor-cli.js').registerDoctorCommand;
278
+ const registerProviderCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'provider'
279
+ ? (() => undefined)
280
+ : (require('./cli/provider-cli.js') as typeof import('./cli/provider-cli.js')).registerProviderCommands) as typeof import('./cli/provider-cli.js').registerProviderCommands;
281
+ const registerAgentCommands = (INDEX_FAST_ROOT
282
+ ? (() => undefined)
283
+ : (require('./cli/agent-cli.js') as typeof import('./cli/agent-cli.js')).registerAgentCommands) as typeof import('./cli/agent-cli.js').registerAgentCommands;
284
+ const registerControlCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'control'
285
+ ? (() => undefined)
286
+ : (require('./cli/control-cli.js') as typeof import('./cli/control-cli.js')).registerControlCommands) as typeof import('./cli/control-cli.js').registerControlCommands;
287
+ const registerHooksCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
288
+ ? (() => undefined)
289
+ : (require('./cli/hooks-cli.js') as typeof import('./cli/hooks-cli.js')).registerHooksCommands) as typeof import('./cli/hooks-cli.js').registerHooksCommands;
290
+ const registerSetupCommand = (INDEX_FAST_ROOT === '__tui_next__'
291
+ ? (() => undefined)
292
+ : (require('./cli/setup-cli.js') as typeof import('./cli/setup-cli.js')).registerSetupCommand) as typeof import('./cli/setup-cli.js').registerSetupCommand;
293
+ const registerStartCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'start'
294
+ ? (() => undefined)
295
+ : (require('./cli/start-cli.js') as typeof import('./cli/start-cli.js')).registerStartCommand) as typeof import('./cli/start-cli.js').registerStartCommand;
296
+ const registerGroundingSourcesCli = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
297
+ ? (() => undefined)
298
+ : (require('./grounding/sources-cli.js') as typeof import('./grounding/sources-cli.js')).registerGroundingSourcesCli) as typeof import('./grounding/sources-cli.js').registerGroundingSourcesCli;
299
+ const registerGraphCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'graph'
300
+ ? (() => undefined)
301
+ : (require('./graph-runner/graph-cli.js') as typeof import('./graph-runner/graph-cli.js')).registerGraphCommands) as typeof import('./graph-runner/graph-cli.js').registerGraphCommands;
302
+ const registerLoopCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'loop'
303
+ ? (() => undefined)
304
+ : (require('./loops/loop-cli.js') as typeof import('./loops/loop-cli.js')).registerLoopCommands) as typeof import('./loops/loop-cli.js').registerLoopCommands;
305
+ const registerResourceCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'resource'
306
+ ? (() => undefined)
307
+ : (require('./cli/resource-cli.js') as typeof import('./cli/resource-cli.js')).registerResourceCommands) as typeof import('./cli/resource-cli.js').registerResourceCommands;
308
+ const registerHqMovePlanCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
309
+ ? (() => undefined)
310
+ : (require('./hq/hq.js') as typeof import('./hq/hq.js')).registerHqMovePlanCommand) as typeof import('./hq/hq.js').registerHqMovePlanCommand;
311
+ const registerCardCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'card'
312
+ ? (() => undefined)
313
+ : (require('./task-cards/card-cli.js') as typeof import('./task-cards/card-cli.js')).registerCardCommand) as typeof import('./task-cards/card-cli.js').registerCardCommand;
314
+ const registerLaunchHeadCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'launch-head'
315
+ ? (() => undefined)
316
+ : (require('./launch-head/launch-head-cli.js') as typeof import('./launch-head/launch-head-cli.js')).registerLaunchHeadCommands) as typeof import('./launch-head/launch-head-cli.js').registerLaunchHeadCommands;
317
+ const registerIngestTokenCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
318
+ ? (() => undefined)
319
+ : (require('./cli/ingest-token-cli.js') as typeof import('./cli/ingest-token-cli.js')).registerIngestTokenCommands) as typeof import('./cli/ingest-token-cli.js').registerIngestTokenCommands;
320
+ const registerMcpGatewayCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
321
+ ? (() => undefined)
322
+ : (require('./cli/mcp-gateway-cli.js') as typeof import('./cli/mcp-gateway-cli.js')).registerMcpGatewayCommands) as typeof import('./cli/mcp-gateway-cli.js').registerMcpGatewayCommands;
323
+ const registerRelayCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'relay'
324
+ ? (() => undefined)
325
+ : (require('./relay/relay-cli.js') as typeof import('./relay/relay-cli.js')).registerRelayCommand) as typeof import('./relay/relay-cli.js').registerRelayCommand;
326
+
327
+
119
328
  import { Command, Option } from 'commander';
120
329
  import { filterCliRootHelp } from './maturity/cli-maturity.js';
121
330
  import type { AdPipelinePlan, AdPipelineResult } from './ad-pipeline/run.js';
122
331
  import type { AcpPermissionApprover } from './acp/client.js';
123
332
  import { runGitCommand } from './git-fs/runner.js';
124
333
  import { debug, redactSecretText, redactSecrets } from './debug/log.js';
125
- import { installHarnessCliCommand, type HarnessAskSayChildLlmOptions, type HarnessAskSayOptions, type HarnessPlanOptions } from './harness/harness-cli-command.js';
334
+ import type { HarnessAskSayChildLlmOptions, HarnessAskSayOptions, HarnessPlanOptions } from './harness/harness-cli-command.js';
126
335
  import { CliUserError, formatCliUserError, isCliUserError } from './cli/cli-user-error.js';
127
336
  import { classifyFriendlyError, formatFriendlyError } from './cli/friendly-errors.js';
128
337
  import { detectLocale } from './expression/locale.js';
129
- import { dispatchSolveMission } from './skills/tools/solve-mission.js';
130
338
  import { performBrowserAction, type BrowserActionDeps, type BrowserActionResult } from './harness/browser-act.js';
131
339
  import { decideTypeAction, type TypeActionDecision, type TypeTarget } from './harness/browser-act-type.js';
132
- import { resolveSelfSendTarget } from './harness/self-send-target.js';
133
340
  import { awaitGlobalPersonaLoad, describeMissingPersona, getGlobalPersonaRegistry } from './persona/global-registry.js';
134
- import { HARNESS_RUN_DEPRECATION_HELP } from './self-dev/harness-run-cli.js';
135
- import { DEV_PLAN_REPLACEMENT, formatDevPlanOptionHelp } from './self-dev/dev-cli.js';
136
341
  import type { InventoryMeta, SortKey } from './llm/local-manager/benchmark/scores.js';
137
342
  import { syncServers, SERVICE_NAMES } from './config.js';
138
343
  import { getLocalSkills, executeSync } from './sync.js';
139
- import { showSyncSelector, showSyncProgress } from './selector.js'; // kept for CLI sync subcommand
140
344
  import { inspectRemote } from './inspect.js';
141
345
  import { showRecentHistory, showSessionDetail, showSkillDetail, showTargetDetail, showStatus } from './history.js';
142
- import { showDashboard } from './dashboard/index.js';
143
346
  import { initTui, closeTui } from './tui.js';
347
+ import { effectiveRootTuiEntry, extractRootTuiEntry } from './cli/root-tui-entry.js';
144
348
  import * as ui from './ui.js';
145
- import { DEFAULT_REVIEW_BACKEND } from './agent-substrate/acp-reviewer.js';
146
349
  import type { ReviewResult } from './agent-substrate/pr-reviewer.js';
147
350
  import type { ReviewVerdict } from './agent-mission/review-loop.js';
148
351
  import type { SyncMode } from './types.js';
149
- import { runOnboarding, runOnboardingStep, runOnboardingNonInteractive, needsOnboarding, needsFirstRun, handleOnboardingRefusal, type OnboardingStepId } from './onboarding.js';
150
- import { firstChatGate } from './onboarding/first-chat-gate.js';
352
+ import type { OnboardingStepId } from './onboarding.js';
151
353
  import {
152
354
  getUserConfig, reloadUserConfig, userConfigPath, saveUserConfig,
153
355
  backupUserConfig, backupConfigPath, addRotationEntry, type RotationEntry,
154
356
  resolveRoleLlm,
155
357
  } from './user-config.js';
156
358
  import { reviewReasoningEffort } from './model-tier/review-effort.js';
157
- import { isKeylessProvider, resolveProviderCredential } from './llm/provider-credentials.js';
359
+ import { configuredOpenGatewayKeys, isKeylessProvider, resolveProviderCredential } from './llm/provider-credentials.js';
158
360
  import {
159
361
  listSessions, loadSession, deleteSession, resolveSessionId,
160
362
  setActiveSessionId, getActiveSessionId,
161
363
  lastConversationMessage, isSessionSource,
162
364
  } from './session/index.js';
163
365
  import { requestSessionTurnControl } from './session/session-turn-control.js';
164
- import { ensureCliSession, sessionBudget } from './session/chat.js';
165
366
  import { suggestProjectForFolder } from './project/project-store.js';
166
- import { botFromConfig, TelegramBot } from './telegram.js';
167
367
  import { acquireTelegramLock, TelegramLockError, defaultLockPath, safeReadLock } from './telegram-lock.js';
168
368
  import { basename, join as _joinPath, resolve } from 'node:path';
169
369
  import * as nodeReadline from 'node:readline/promises';
@@ -189,14 +389,13 @@ import { renderKeyHelp, CONTEXT_LABELS, type KeyContext } from './keybindings.js
189
389
  import { auditKeybindings, renderKeymapAudit } from './keymap-audit.js';
190
390
  import { runCodexSetup } from './codex/setup.js';
191
391
  import { renderAllModels } from './codex/models.js';
192
- import { realIO } from './onboarding.js';
193
392
  import { inspectActiveProvider, oneLineProvider } from './provider-summary.js';
194
393
  import { renderStatusLines, renderPrimaryStatus, renderSecondaryStatus } from './status/bar.js';
195
394
  import { initSessionWorkingDir } from './session/working-dir.js';
196
395
  import { rewriteBareNexusToStatus } from './cli/nexus-entry.js';
197
- import { registerIngestTokenCommands } from './cli/ingest-token-cli.js';
198
- import { registerMcpGatewayCommands } from './cli/mcp-gateway-cli.js';
199
- import { registerRelayCommand } from './relay/relay-cli.js';
396
+
397
+
398
+
200
399
  import type { ReviewImage } from './agent-substrate/pr-reviewer.js';
201
400
  import {
202
401
  describeMissionRouting,
@@ -218,6 +417,8 @@ function resolveCliDirOption(dir: string): string {
218
417
  import { cliVersion, setInstallMetadataRootForTesting } from './version/code-revision.js';
219
418
  export { cliVersion, setInstallMetadataRootForTesting };
220
419
 
420
+
421
+
221
422
  export const program = new Command();
222
423
  program.enablePositionalOptions();
223
424
 
@@ -242,6 +443,7 @@ program.command('preview <target>')
242
443
  export { SELF_SEND_RECENT_FRAME_WINDOW_MS, SELF_SEND_STALE_HEARTBEAT_MS, formatSelfSendCandidateDisplay } from './harness/self-send-decide.js';
243
444
  export type { SelfSendCandidate, SelfSendCandidateDisplay } from './harness/self-send-decide.js';
244
445
  import { decideSelfSend, type SelfSendCandidate } from './harness/self-send-decide.js';
446
+ import { mayLookupRemotePodRun } from './harness/self-send-routing-guard.js';
245
447
  type RunDevAskBuildDevCliSpec = typeof import('./self-dev/dev-cli.js')['buildDevCliSpec'];
246
448
  type RunDevAskExecuteDevSelfRun = typeof import('./self-dev/dev-cli.js')['executeDevSelfRun'];
247
449
  type RunDevAskStartDraftTriage = typeof import('./self-dev/dev-cli.js')['startDraftTriage'];
@@ -379,8 +581,12 @@ async function runDefaultAskFileLaunchFlow(
379
581
  import('node:path'),
380
582
  import('./self-dev/entrance-registry.js'),
381
583
  ]);
382
- const askText = readFileSync(askPath, 'utf8');
584
+ // Read the source bytes ONCE: the same bytes feed the ledger and the launch flow (a read failure → launch 0).
585
+ const askBytes = readFileSync(askPath);
586
+ const askText = askBytes.toString('utf8');
383
587
  if (!askText.trim()) throw new Error('--ask 파일 입력이 비었다');
588
+ const { newLaunchUtteranceId, recordLaunchUtterance } = await import('./harness/launch-utterance-ledger.js');
589
+ recordLaunchUtterance({ source: 'ask-file', utterance: askText, rawBytes: askBytes, launchId: newLaunchUtteranceId() });
384
590
  const askIo = await import('./self-dev/ask-launch-io.js');
385
591
  const askLogRows = await askIo.readAskPreflightLogRows();
386
592
  const askLaunchPrep = (await import('./self-dev/launch-preflight.js')).prepareAskLaunch(
@@ -401,7 +607,7 @@ async function runDefaultAskFileLaunchFlow(
401
607
  print: (line) => console.error(line),
402
608
  log: (event, data, level) => debug.log('dev-pipeline', event, data, { level }),
403
609
  readLine: (prompt) => readStdinLine(prompt),
404
- readFile: (file) => readFileSync(file, 'utf8'),
610
+ readFile: (file) => file === askPath ? askText : readFileSync(file, 'utf8'),
405
611
  writeFile: (file, data) => writeFileSync(file, data, 'utf8'),
406
612
  cwd: () => process.cwd(),
407
613
  now: () => Date.now(),
@@ -1049,6 +1255,7 @@ registerKnowCommand(program);
1049
1255
  registerNotifyCommand(program);
1050
1256
  registerAwayCommand(program);
1051
1257
  registerFreezeCommands(program);
1258
+ registerHerdrCommands(program);
1052
1259
  registerFlowCommands(program);
1053
1260
  // HQ-HB · HQ-FENCE (10-04): one writer across mbp · node-b · cloud-vm — lease on the arbiter, 2-of-3 quorum, generation fencing.
1054
1261
  const hqCmd = program.command('hq').description('본부 임대 — 하트비트·중재·단일 작성자 래퍼');
@@ -1383,14 +1590,16 @@ registerDoctorCommand(program);
1383
1590
  registerControlCommands(program);
1384
1591
  registerHooksCommands(program);
1385
1592
  registerSetupCommand(program);
1386
- program.commands.find(command => command.name() === 'setup')!
1387
- .option('--terminal', 'Run the terminal onboarding wizard')
1388
- .hook('preAction', async (_command, action) => {
1389
- if (action.name() === 'setup' && action.opts().terminal) {
1390
- const completed = await runOnboardingForCli();
1391
- process.exit(completed ? 0 : (process.exitCode || 2));
1392
- }
1393
- });
1593
+ if (INDEX_FAST_ROOT !== '__tui_next__') {
1594
+ program.commands.find(command => command.name() === 'setup')!
1595
+ .option('--terminal', 'Run the terminal onboarding wizard')
1596
+ .hook('preAction', async (_command, action) => {
1597
+ if (action.name() === 'setup' && action.opts().terminal) {
1598
+ const completed = await runOnboardingForCli();
1599
+ process.exit(completed ? 0 : (process.exitCode || 2));
1600
+ }
1601
+ });
1602
+ }
1394
1603
  registerStartCommand(program);
1395
1604
  registerGroundingSourcesCli(program);
1396
1605
  registerGraphCommands(program);
@@ -1601,6 +1810,8 @@ program
1601
1810
  )
1602
1811
  // Documentation-only — `readDashboardNameFlag` 가 Commander «전»에 argv 에서 걷어낸다.
1603
1812
  .option('--name <name>', '대시보드 TUI 의 PTY 행(tui:<pid>)에 별명을 달고 뜬다 — `elanous pty list` 에 보이고 `pty snapshot <name>` 으로 부른다. 뜬 뒤 바꾸려면 `elanous pty rename <ref> <name>`.')
1813
+ .option('--legacy', '기존 대시보드 TUI로 시작한다(--tui classic 의 짧은 표기). 기본 진입도 기존 대시보드이며 새 TUI는 --tui next 로만 연다.')
1814
+ .option('--tui <mode>', '루트 TUI를 명시한다(classic|next). 기본은 classic이고 새 TUI는 --tui next 로 연다. --legacy는 classic의 짧은 표기다.')
1604
1815
  .option('--help-all', '시스템 명령을 제외한 모든 최상위 명령 표시');
1605
1816
  program.addHelpText('after', acpServerHelpText());
1606
1817
 
@@ -2430,7 +2641,8 @@ async function runHarnessMissionLoop(
2430
2641
  }
2431
2642
  }
2432
2643
 
2433
- const harnessCmd = installHarnessCliCommand(program, {
2644
+ const harnessCmd = (INDEX_FAST_ROOT ? new Command('harness')
2645
+ : (require('./harness/harness-cli-command.js') as typeof import('./harness/harness-cli-command.js')).installHarnessCliCommand(program, {
2434
2646
  registerSink: async (surface) => { await (await import('./domains/standalone-log-sink.js')).registerStandaloneLogSink(surface); },
2435
2647
  resolveSurface: async () => {
2436
2648
  const { getHarnessSpace, harnessSpaceSurface } = await import('./harness/harness-space.js');
@@ -2444,9 +2656,65 @@ const harnessCmd = installHarnessCliCommand(program, {
2444
2656
  // (그 함수는 planStaged dispatch → 대표 2026-09-04 은퇴한 staged 하니스로 간다).
2445
2657
  // ⇒ 즉 이 «한 줄»이 은퇴를 되돌린다. 주입 자리는 시험용으로 남는다.
2446
2658
  mission: async (missionId, opts) => {
2447
- await dispatchSolveMission({ mission_id: missionId, ...opts });
2659
+ await (await import('./skills/tools/solve-mission.js')).dispatchSolveMission({ mission_id: missionId, ...opts });
2448
2660
  },
2449
2661
  missionLoop: runHarnessMissionLoop,
2662
+ }));
2663
+
2664
+ let podAskSnapshot: string | undefined;
2665
+ let podAskSnapshotCleanup: (() => void) | undefined;
2666
+ harnessCmd.hook('preAction', async (_parent, action) => {
2667
+ if (action.name() === 'ask' && action.opts().substrate === 'pod' && typeof action.args[0] === 'string' && !isGoalAuthorFileName(basename(action.args[0]))) {
2668
+ // Read the source once; onPod and its orchestrator consume the same private snapshot.
2669
+ const askBytes = readFileSync(action.args[0]!);
2670
+ const askText = askBytes.toString('utf8');
2671
+ if (!askText.trim()) throw new Error('--ask 파일 입력이 비었다');
2672
+ const { mkdtempSync, writeFileSync, rmSync } = await import('node:fs');
2673
+ const { tmpdir } = await import('node:os');
2674
+ const { join } = await import('node:path');
2675
+ const snapshotDir = mkdtempSync(join(tmpdir(), 'elanous-ask-snapshot-'));
2676
+ try {
2677
+ const snapshot = join(snapshotDir, basename(action.args[0]!));
2678
+ writeFileSync(snapshot, askBytes, { mode: 0o600 });
2679
+ podAskSnapshot = snapshotDir;
2680
+ podAskSnapshotCleanup = () => {
2681
+ try { rmSync(snapshotDir, { recursive: true, force: true }); }
2682
+ catch (error) { console.error(`[launch-utterance] snapshot cleanup failed: ${String(error)}`); }
2683
+ };
2684
+ process.once('exit', podAskSnapshotCleanup);
2685
+ action.processedArgs[0] = snapshot;
2686
+ } catch (error) {
2687
+ rmSync(snapshotDir, { recursive: true, force: true });
2688
+ throw error;
2689
+ }
2690
+ const { newLaunchUtteranceId, recordLaunchUtterance } = await import('./harness/launch-utterance-ledger.js');
2691
+ recordLaunchUtterance({ source: 'ask-file', utterance: askText, rawBytes: askBytes, launchId: newLaunchUtteranceId() });
2692
+ return;
2693
+ }
2694
+ if (action.name() !== 'say') return;
2695
+ try {
2696
+ const { consumeHandLaunchId, recordLaunchUtterance } = await import('./harness/launch-utterance-ledger.js');
2697
+ const argv = (action.args as string[]).map(String);
2698
+ if (argv.length === 0) return; // nothing was received — no empty start row
2699
+ // New ID per process; only the explicit hand→say pair (same sentence sha ⊕ same run) inherits, once —
2700
+ // and then records the hand's exact original text (recovers a failed hand-parent append in this instance).
2701
+ const { launchId, utterance } = consumeHandLaunchId(argv.join(' '), process.env);
2702
+ recordLaunchUtterance({ source: 'say', utterance, argv, launchId, dryRun: action.opts().dryRun === true });
2703
+ } catch (error) {
2704
+ try { debug.log('harness.launch-utterance', 'prepare-failed', { operation: 'say-hook', reason: String(error) }, { level: 'warn' }); } catch { /* fail-soft */ }
2705
+ }
2706
+ });
2707
+ harnessCmd.hook('postAction', async (_parent, action) => {
2708
+ if (action.name() !== 'ask' || !podAskSnapshot) return;
2709
+ try {
2710
+ const { rmSync } = await import('node:fs');
2711
+ rmSync(podAskSnapshot, { recursive: true, force: true });
2712
+ if (podAskSnapshotCleanup) process.removeListener('exit', podAskSnapshotCleanup);
2713
+ podAskSnapshot = undefined;
2714
+ podAskSnapshotCleanup = undefined;
2715
+ } catch (error) {
2716
+ console.error(`[launch-utterance] snapshot cleanup failed: ${String(error)}`);
2717
+ }
2450
2718
  });
2451
2719
 
2452
2720
  // (internal) 데몬이 dev-harness 를 subprocess 로 위임(#24 A) — 하니스 동기 op 가 데몬 이벤트루프를
@@ -2484,6 +2752,7 @@ harnessCmd
2484
2752
  try { process.stdout.write(line, () => process.exit(code)); }
2485
2753
  catch { process.exit(code); }
2486
2754
  };
2755
+ const { emitDetachedProgress } = await import('./cli/agent-cli.js');
2487
2756
  const detachedCtx = {
2488
2757
  cwd: process.cwd(),
2489
2758
  signal: new AbortController().signal,
@@ -3216,6 +3485,7 @@ export async function runHarnessOrchestrateExecution(
3216
3485
  const { prepareOrchestrateDecomposeGoals } = await import('./self-dev/self-orchestrate-runtime.js');
3217
3486
  return prepareOrchestrateDecomposeGoals(input as never) as Promise<HarnessOrchestratePreparedGoals>;
3218
3487
  });
3488
+ const { buildOrchestrateDecomposePrepareArgs } = await import('./self-dev/self-orchestrate-runtime.js');
3219
3489
  const prepared = await prepareGoals(buildOrchestrateDecomposePrepareArgs({
3220
3490
  request,
3221
3491
  goals,
@@ -4446,7 +4716,7 @@ selfCmd
4446
4716
  .option('--fixed-shard-distribution', '--shards N 과 함께만: RSS 사전 측정 없이 정렬된 파일을 N 조각에 라운드로빈 고정 배정한다(opt-in · 메모리 보증 아님 · 조각 타임아웃/OOM = unmeasured)')
4447
4717
  .option('--include-importers', '변경 모듈을 가져오는 importer 시험도 실행한다 (기본 caller 한도 밖까지)')
4448
4718
  .option('--remote [host]', 'GATE-REMOTE — 같은 커밋을 원격 호스트(기본 config gateRemote.host=node-b)에서 돌리고 결과만 가져온다(깨끗한 트리 · --pr 은 로컬)')
4449
- .option('--local', '원격 자동 분배(로컬 1분 부하 > gateRemote.loadThreshold=20)를 끄고 로컬에서 돌린다')
4719
+ .option('--local', '원격 실행을 끄고 명시적으로 로컬에서 돌린다')
4450
4720
  .option('--artifact-dir <dir>', '조각별 지금/기준 JUnit ⊕ summary.json 을 이 디렉토리에 남긴다(판정 불변 · JUnit 은 --shards 경로만 · 원격 실행이면 그 호스트에서 가져온다)')
4451
4721
  .action(async (opts: { changed?: boolean; base?: string; pr?: string; shards?: string | boolean; fixedShardDistribution?: boolean; includeImporters?: boolean; remote?: string | boolean; local?: boolean; artifactDir?: string }) => {
4452
4722
  if (!opts.changed && opts.shards === undefined) { ui.error('self gate requires --changed or --shards'); process.exitCode = 2; return; }
@@ -4482,8 +4752,8 @@ selfCmd
4482
4752
  if (topLevel.status !== 0) throw new Error(`git rev-parse --show-toplevel failed: ${topLevel.stderr.trim() || `rc=${topLevel.status}`}`);
4483
4753
  const repo = topLevel.stdout.trim();
4484
4754
  // Only a committed --base range is reproducible on another host: the default mode measures uncommitted files, --pr
4485
- // reads files through gh on this host, and the remote checkout runs from the repository root — automatic placement
4486
- // falls back locally; an explicit --remote reports that this check was not measured.
4755
+ // reads files through gh on this host, and the remote checkout runs from the repository root — these cases
4756
+ // fall back locally for automatic placement; an explicitly requested remote run is unmeasured.
4487
4757
  const { realpathSync } = await import('node:fs');
4488
4758
  const localOnlyReason = opts.pr ? 'self gate --pr reads PR files through gh on this host'
4489
4759
  : !opts.base ? 'self gate without --base measures uncommitted files on this host'
@@ -4516,7 +4786,7 @@ selfCmd
4516
4786
  if (outcome.kind === 'ran') {
4517
4787
  target.fetch = fetchRemoteGateArtifacts({ host, remoteDir: target.dir, localDir: resolveArtifactDir(opts.artifactDir!, process.cwd()), ssh: runner.ssh });
4518
4788
  } else if (outcome.kind === 'infra') {
4519
- // The run may have started before it broke — remove the host-side dir; automatic placement's local fallback writes its own.
4789
+ // The run may have started before it broke — remove the host-side dir; remote failure stays unmeasured.
4520
4790
  try { runner.ssh(host, remoteArtifactCleanupScript(target.dir), 30_000); } catch { /* best effort */ }
4521
4791
  }
4522
4792
  }) satisfies NonNullable<import('./self-implement/gate-remote.js').DispatchOptions['onRemoteOutcome']>,
@@ -4524,12 +4794,14 @@ selfCmd
4524
4794
  });
4525
4795
  } catch (error) {
4526
4796
  const reason = error instanceof Error ? error.message : String(error);
4527
- if (opts.remote !== undefined) {
4528
- ui.error(`self gate remote unmeasured — ${reason.replace(/\s+/g, ' ').trim()}`);
4529
- process.exitCode = 1;
4530
- } else {
4797
+ if (opts.local) {
4531
4798
  ui.error(`self gate dispatch failed: ${reason}`);
4532
4799
  process.exitCode = runLocal();
4800
+ } else {
4801
+ ui.error(opts.remote !== undefined
4802
+ ? `self gate remote unmeasured — ${reason.replace(/\s+/g, ' ').trim()}`
4803
+ : `self gate dispatch failed: ${reason}`);
4804
+ process.exitCode = 1;
4533
4805
  }
4534
4806
  }
4535
4807
  // 원격에서 돌았으면 그 호스트의 산출을 가져와 같은 꼴로 썼다 — 못 가져왔으면 «조용히» 비우지 않고 summary 에 이유를 적는다(판정 불변).
@@ -4756,7 +5028,7 @@ const selfOrchestrateCmd = selfCmd
4756
5028
  .option('--no-pod-rebuild', 'pod: 이미지 판(elanous.commit)이 HEAD 와 달라도 다시 굽지 않는다 — 측정은 «이미지 판»을 잰다')
4757
5029
  .option('--pod-pass-env <keys>', 'pod: 호스트 env 에서 Pod 로 넘길 키(쉼표) — 예 OPENROUTER_API_KEY,ANTHROPIC_API_KEY(벤치마크 과금 경로)')
4758
5030
  .option('--bench-arms <spec>', 'pod 벤치마크: 골 1개를 팔마다 «라벨 한 줄만 다르게» 복제해 동시에 — "id=provider[:model][@KEY+KEY];…" (예 codex=openai-codex;or-kimi=openrouter:openrouter/moonshotai/kimi-k3@OPENROUTER_API_KEY) · --auto-merge 거부 · RFC fleet 슈퍼바이저 §A3')
4759
- .addOption(new Option('--child-llm-provider <id>', 'pod: 구현 자식 LLM provider(openai-codex|grok|openrouter|anthropic|bedrock|glm) — 하니스 --child-llm-provider 가 이 자리로 온다(10-05)').hideHelp())
5031
+ .addOption(new Option('--child-llm-provider <id>', 'pod: 구현 자식 LLM provider(openai-codex|grok|openrouter|opengateway|anthropic|bedrock|glm) — 하니스 --child-llm-provider 가 이 자리로 온다(10-05)').hideHelp())
4760
5032
  .addOption(new Option('--child-llm-model <id>', 'pod: 구현 자식 LLM model(--child-llm-provider 와 함께)').hideHelp())
4761
5033
  .addOption(new Option('--child-llm-effort <level>', 'pod: 구현 자식 추론 노력(--child-llm-provider 와 함께)').hideHelp())
4762
5034
  .option('--help-all', '모든 orchestrate 옵션 표시')
@@ -4834,7 +5106,7 @@ const selfOrchestrateCmd = selfCmd
4834
5106
  let parentRequest: string | undefined;
4835
5107
  const request = normalizeOrchestrateRequest(joined);
4836
5108
  if (opts.decompose) parentRequest = request;
4837
- const { prepareOrchestrateDecomposeGoals } = await import('./self-dev/self-orchestrate-runtime.js');
5109
+ const { prepareOrchestrateDecomposeGoals, buildOrchestrateDecomposePrepareArgs } = await import('./self-dev/self-orchestrate-runtime.js');
4838
5110
  const prepared = await prepareOrchestrateDecomposeGoals(buildOrchestrateDecomposePrepareArgs({
4839
5111
  request,
4840
5112
  goals: goalTexts.map((feature) => ({ feature, ...promoteDefaults })),
@@ -4939,7 +5211,7 @@ const selfOrchestrateCmd = selfCmd
4939
5211
  let podSpawn: import('./task-orchestrator/surfaces/self-implement.js').SelfImplementJobSpawn | undefined;
4940
5212
  let podTargets: { context: string; namespace: string }[] | undefined;
4941
5213
  if (substrate === 'pod') {
4942
- const { podSelfImplementSpawn, podSubstrateReady, defaultKubectl } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
5214
+ const { podSubstrateReady, defaultKubectl } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
4943
5215
  const poolMod = await import('./task-orchestrator/surfaces/pod-pool.js');
4944
5216
  const { harnessLaunchPolicyConfig } = await import('./harness/harness-substrate-default.js');
4945
5217
  const launchPolicy = harnessLaunchPolicyConfig();
@@ -5046,11 +5318,24 @@ const selfOrchestrateCmd = selfCmd
5046
5318
  const grokKeyNames = ['XAI_API_KEY', 'GROK_API_KEY', 'GROK_CODE_XAI_API_KEY'];
5047
5319
  // 명시 계정은 사람의 선택 — 공급자 폴백과 계정 브로커를 우회한다.
5048
5320
  const explicitPodAccount = (opts as { podAccount?: string }).podAccount;
5049
- const ownerMirrorAccount = process.env.ELANOUS_REMOTE_CODEX_ACCOUNT?.trim();
5321
+ const ownerMirrorRaw = process.env.ELANOUS_REMOTE_CODEX_ACCOUNTS;
5322
+ let ownerMirrorAccounts: import('./task-orchestrator/surfaces/pod-account-broker.js').OwnerCodexMirrorAccount[] | undefined;
5323
+ if (ownerMirrorRaw !== undefined) {
5324
+ try { ownerMirrorAccounts = (await import('./task-orchestrator/surfaces/pod-account-broker.js')).parseOwnerCodexMirrorAccounts(ownerMirrorRaw); }
5325
+ catch { ui.error('pod: HQ Codex 미러 계정 목록이 유효하지 않다'); process.exit(2); }
5326
+ const { freshOwnerCodexMirrorAccounts } = await import('./task-orchestrator/surfaces/pod-account-broker.js');
5327
+ const fresh = freshOwnerCodexMirrorAccounts(ownerMirrorAccounts);
5328
+ for (const { account } of ownerMirrorAccounts.filter(({ account }) => !fresh.some((item) => item.account === account))) {
5329
+ debug.log('self-implement.pod', 'owner-access-mirror-excluded', { account, reason: 'access-expiring' });
5330
+ }
5331
+ ownerMirrorAccounts = fresh;
5332
+ if (fresh.length === 0) { ui.error('pod: HQ Codex 미러 access token 이 모두 3시간 안에 만료된다'); process.exit(2); }
5333
+ }
5334
+ const ownerMirrorAccount = ownerMirrorAccounts?.[0]?.account ?? process.env.ELANOUS_REMOTE_CODEX_ACCOUNT?.trim();
5050
5335
  const childProvider = opts as { childLlmProvider?: string };
5051
5336
  const requestedChildProvider = childProvider.childLlmProvider?.trim();
5052
- if (ownerMirrorAccount && explicitPodAccount && explicitPodAccount !== ownerMirrorAccount) {
5053
- ui.error(`pod: HQ 미러 계정은 ${ownerMirrorAccount} 인데 --pod-account ${explicitPodAccount} 을 사용할 수 없다`);
5337
+ if (ownerMirrorAccount && explicitPodAccount && !(ownerMirrorAccounts?.some(({ account }) => account === explicitPodAccount) ?? explicitPodAccount === ownerMirrorAccount)) {
5338
+ ui.error(`pod: HQ 미러 계정 목록에 --pod-account ${explicitPodAccount} 이 없다`);
5054
5339
  process.exit(2);
5055
5340
  }
5056
5341
  if (ownerMirrorAccount && requestedChildProvider && requestedChildProvider !== 'openai-codex') {
@@ -5101,7 +5386,7 @@ const selfOrchestrateCmd = selfCmd
5101
5386
  ? 'pod: --child-llm-model/--child-llm-effort 는 --child-llm-provider 와 함께'
5102
5387
  : named && benchArms
5103
5388
  ? 'pod: --child-llm-provider 는 --bench-arms 와 함께 못 쓴다(팔마다 모델이 하나다)'
5104
- : (named === 'grok' || named === 'openrouter' || named === 'anthropic' || named === 'bedrock' || named === 'glm') && explicitPodAccount
5389
+ : (named === 'grok' || named === 'openrouter' || named === 'opengateway' || named === 'anthropic' || named === 'bedrock' || named === 'glm') && explicitPodAccount
5105
5390
  ? `pod: --child-llm-provider ${named} 은 --pod-account 와 함께 못 쓴다(그것은 codex 계정을 고정한다)`
5106
5391
  : undefined;
5107
5392
  if (refuse) { ui.error(refuse); debug.log('self-implement.pod', 'child-provider-refused', { provider: named ?? null, reason: refuse }); process.exit(2); }
@@ -5163,19 +5448,27 @@ const selfOrchestrateCmd = selfCmd
5163
5448
  if (namedChild === 'openrouter' && !openrouterKeyPresent) {
5164
5449
  try { openrouterKeyPresent = Boolean(readPodKeyFile(podJoin(podHome(), '.cache', 'openrouter_api_key'), 'utf8').trim()); } catch { /* missing host cache */ }
5165
5450
  }
5451
+ const openGatewayKeyPresent = namedChild === 'opengateway' && Boolean(
5452
+ (await import('./config.js')).getOpenGatewayApiKey()?.trim()
5453
+ || configuredOpenGatewayKeys(getUserConfig().llm).length);
5166
5454
  // POD-ANTHROPIC-PROVIDER — 제품 자격 해석(`getAnthropicApiKey` · 키 캐시 → env)으로 «있나»만 본다(값은 안 싣는다).
5167
5455
  const anthropicKeyPresent = namedChild === 'anthropic' && Boolean((await import('./config.js')).getAnthropicApiKey()?.trim());
5168
5456
  const namedChildDecision = podNamedChildProvider(namedChild, {
5169
5457
  grokSubscription: namedChild === 'grok' && credential?.kind === 'subscription' && (grokSubscriptionUsable || namedGrokUsable().usable),
5170
5458
  grokApiKey: credential?.kind === 'api_key' && grokApiKeyOptIn,
5171
5459
  openrouterKey: openrouterKeyPresent,
5460
+ openGatewayKey: openGatewayKeyPresent,
5172
5461
  anthropicKey: anthropicKeyPresent,
5173
5462
  }, (opts as { childLlmModel?: string }).childLlmModel);
5174
5463
  if (namedChildDecision.refuse) { ui.error(namedChildDecision.refuse); debug.log('self-implement.pod', 'child-provider-refused', { provider: namedChild, reason: namedChildDecision.refuse }); process.exit(2); }
5175
5464
  // A named codex child must stay codex — the plan may not fall back to grok (post-review must-fix).
5176
5465
  const namedCodex = namedChildDecision.provider === 'openai-codex';
5177
5466
  let planCandidates = inspectCodexRotation().candidates;
5178
- if (ownerMirrorAccount) {
5467
+ if (ownerMirrorAccounts) {
5468
+ const { selectOwnerCodexMirrorCandidates } = await import('./task-orchestrator/surfaces/pod-account-broker.js');
5469
+ try { planCandidates = selectOwnerCodexMirrorCandidates(planCandidates, ownerMirrorAccounts); }
5470
+ catch { ui.error('pod: HQ Codex 미러 계정 일부가 원격 auth-store 후보에 없다'); process.exit(2); }
5471
+ } else if (ownerMirrorAccount) {
5179
5472
  const used = process.env.ELANOUS_REMOTE_CODEX_USED_PERCENT;
5180
5473
  const parsedUsed = used && used !== 'unknown' ? Number(used) : undefined;
5181
5474
  const threshold = Number(process.env.ELANOUS_REMOTE_CODEX_THRESHOLD_PERCENT);
@@ -5187,12 +5480,14 @@ const selfOrchestrateCmd = selfCmd
5187
5480
  planCandidates = ownerCodexMirrorCandidate(planCandidates, ownerMirrorAccount, parsedUsed !== undefined && Number.isFinite(parsedUsed) ? parsedUsed : undefined);
5188
5481
  if (planCandidates.length === 0) { ui.error(`pod: HQ Codex 미러 계정 ${ownerMirrorAccount} 이 원격 auth-store 후보에 없다`); process.exit(2); }
5189
5482
  }
5190
- const plan: import('./task-orchestrator/surfaces/pod-account-broker.js').PodProviderPlan | null = namedChildDecision.provider === 'openrouter' || namedChildDecision.provider === 'anthropic' || namedChildDecision.provider === 'bedrock' || namedChildDecision.provider === 'glm' ? null : namedChildDecision.provider === 'grok'
5483
+ const plan: import('./task-orchestrator/surfaces/pod-account-broker.js').PodProviderPlan | null = namedChildDecision.provider === 'openrouter' || namedChildDecision.provider === 'opengateway' || namedChildDecision.provider === 'anthropic' || namedChildDecision.provider === 'bedrock' || namedChildDecision.provider === 'glm' ? null : namedChildDecision.provider === 'grok'
5191
5484
  ? { provider: 'grok', excluded: [], grokSubscriptionEligible: credential?.kind === 'subscription' }
5192
5485
  : planPodProvider({
5193
5486
  codexCandidates: planCandidates,
5194
5487
  // Per-account caps (대표 default:97) override the Pod default cap — without them default was dropped at 60%.
5195
- thresholdPercentByAccount: ownerMirrorAccount
5488
+ thresholdPercentByAccount: ownerMirrorAccounts
5489
+ ? Object.fromEntries(ownerMirrorAccounts.map(({ account, thresholdPercent }) => [account, thresholdPercent]))
5490
+ : ownerMirrorAccount
5196
5491
  ? { [ownerMirrorAccount]: Number(process.env.ELANOUS_REMOTE_CODEX_THRESHOLD_PERCENT) }
5197
5492
  : launchPolicy.llm?.codexAccountRotationThresholdPercentByAccount,
5198
5493
  // 대표 한도 정책 한 값(`llm.codexQuotaPolicy`) — 크레딧·폴백을 같이 정한다.
@@ -5213,7 +5508,7 @@ const selfOrchestrateCmd = selfCmd
5213
5508
  })() } : {}),
5214
5509
  });
5215
5510
  if (plan?.provider === null) { ui.error(`pod: 쓸 codex 계정이 없다 — ${plan.reasons.join(' · ')}${namedCodex ? ' · child provider 를 openai-codex 로 지정해 grok 으로 넘기지 않는다' : ''} · 계정을 명시하려면 --pod-account <이름>`); process.exit(2); }
5216
- podProvider = namedChildDecision.provider === 'openrouter' || namedChildDecision.provider === 'anthropic' || namedChildDecision.provider === 'bedrock' || namedChildDecision.provider === 'glm' ? namedChildDecision.provider : plan!.provider!;
5511
+ podProvider = namedChildDecision.provider === 'openrouter' || namedChildDecision.provider === 'opengateway' || namedChildDecision.provider === 'anthropic' || namedChildDecision.provider === 'bedrock' || namedChildDecision.provider === 'glm' ? namedChildDecision.provider : plan!.provider!;
5217
5512
  if (plan?.provider === 'openai-codex') {
5218
5513
  accountBroker = makePodAccountBroker({ usable: plan.accounts, excluded: plan.excluded });
5219
5514
  rotationAccounts = plan.accounts;
@@ -5226,6 +5521,10 @@ const selfOrchestrateCmd = selfCmd
5226
5521
  const model = (opts as { childLlmModel?: string }).childLlmModel!.trim();
5227
5522
  debug.log('self-implement.pod', 'provider-named', { provider: 'openrouter', model, openrouterKeyPresent: true });
5228
5523
  if (!opts.json) ui.info(`[pod] child provider = openrouter(모델 ${model}) — 발사 인자로 지정됨`);
5524
+ } else if (namedChildDecision.provider === 'opengateway') {
5525
+ const model = (opts as { childLlmModel?: string }).childLlmModel!.trim();
5526
+ debug.log('self-implement.pod', 'provider-named', { provider: 'opengateway', model, openGatewayKeyPresent: true, billing: 'api-key' });
5527
+ if (!opts.json) ui.info(`[pod] child provider = opengateway(모델 ${model}) — 발사 인자로 지정됨 · API 키 과금`);
5229
5528
  } else if (namedChildDecision.provider === 'anthropic') {
5230
5529
  const model = (opts as { childLlmModel?: string }).childLlmModel?.trim() || null;
5231
5530
  // ⓔ 과금 관측 — anthropic 은 API 키 과금(구독 아님). 새 예산 체계는 없다 · 관측 한 줄만.
@@ -5254,7 +5553,7 @@ const selfOrchestrateCmd = selfCmd
5254
5553
  if (!opts.json) ui.info(`[pod] 쓸 codex 계정 없음(${plan.excluded.map((x) => `${x.name}: ${x.why}`).join(' · ')}) → grok 으로(모델 ${model})`);
5255
5554
  }
5256
5555
  }
5257
- const passEnv = podProvider === 'grok' ? requestedPassEnv.filter((key) => !grokKeyNames.includes(key)) : podProvider === 'openrouter' ? [...new Set([...requestedPassEnv, 'OPENROUTER_API_KEY'])] : podProvider === 'anthropic' ? [...new Set([...requestedPassEnv, 'ANTHROPIC_API_KEY'])] : requestedPassEnv;
5556
+ const passEnv = podProvider === 'grok' ? requestedPassEnv.filter((key) => !grokKeyNames.includes(key)) : podProvider === 'openrouter' ? [...new Set([...requestedPassEnv, 'OPENROUTER_API_KEY'])] : podProvider === 'opengateway' ? [...new Set([...requestedPassEnv, 'OPENGATEWAY_API_KEY'])] : podProvider === 'anthropic' ? [...new Set([...requestedPassEnv, 'ANTHROPIC_API_KEY'])] : requestedPassEnv;
5258
5557
  const podSourceSpec = (opts as { podSource?: string }).podSource;
5259
5558
  const repairBaseHead = (opts as { repairCommitOnly?: string }).repairCommitOnly;
5260
5559
  if (repairBaseHead && (!/^pr:[1-9]\d*$/.test(podSourceSpec ?? '') || !/^[0-9a-f]{40}$/.test(repairBaseHead) || opts.autoMerge || opts.openPr || goalTexts.length !== 1)) {
@@ -5287,7 +5586,8 @@ const selfOrchestrateCmd = selfCmd
5287
5586
  const { benchPodSpawn } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
5288
5587
  podSpawn = benchPodSpawn(benchArms, podBase);
5289
5588
  } else {
5290
- podSpawn = podSelfImplementSpawn(podBase);
5589
+ podSpawn = await (await import('./task-orchestrator/surfaces/pod-si-warm-entry.js'))
5590
+ .podSpawnWithSiWarm(podBase);
5291
5591
  }
5292
5592
  podTargets = poolMembers.length > 0
5293
5593
  ? poolMembers.map(({ context }) => ({ context, namespace: 'elanous-test' }))
@@ -5561,9 +5861,37 @@ selfCmd
5561
5861
  .option('--include-stale', '모호한 대상 목록에 오래된 마지막 프레임 후보도 표시')
5562
5862
  .option('--read-wait <seconds>', '--memo·--stop 뒤 자식이 읽을 때까지 기다리는 최대 초(0 = 기다리지 않음)', '10')
5563
5863
  .action(async (space: string | undefined, opts: { stop?: boolean; memo?: string; run?: string; includeStale?: boolean; readWait?: string }) => {
5864
+ let remoteLookupFailure = '';
5865
+ let remoteChildUnconfirmed = false;
5866
+ // A TA parent lives on its recorded host. Its Pod fragment and control inbox are
5867
+ // deliberately absent from HQ state, so a local screen lookup cannot route it.
5868
+ if (opts.run !== undefined && space === undefined && mayLookupRemotePodRun(process.env)) {
5869
+ const { findRemotePodCardForRun, remotePodControlForOptions, RemotePodOwnershipAmbiguousError, sendRemotePodRun } = await import('./harness/self-send-remote.js');
5870
+ let card: ReturnType<typeof findRemotePodCardForRun>['card'] = null;
5871
+ try {
5872
+ ({ card, remoteChildUnconfirmed } = findRemotePodCardForRun(opts.run));
5873
+ } catch (error) {
5874
+ if (error instanceof RemotePodOwnershipAmbiguousError) {
5875
+ process.stderr.write(`${error.message}\n`);
5876
+ process.exit(1);
5877
+ }
5878
+ remoteLookupFailure = error instanceof Error ? error.message : String(error);
5879
+ }
5880
+ if (card) {
5881
+ try {
5882
+ const result = sendRemotePodRun(card, opts.run, remotePodControlForOptions(opts));
5883
+ if (result.stderr) process.stderr.write(result.stderr);
5884
+ process.stdout.write(result.stdout);
5885
+ return;
5886
+ } catch (error) {
5887
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
5888
+ process.exit(1);
5889
+ }
5890
+ }
5891
+ }
5564
5892
  const { classifyRunScreenMissing, queryRunScreenKey, listRunLedgers } = await import('./self-implement/run-ledger.js');
5565
5893
  const { getPtyManifest, listPtyManifestRows } = await import('./pty-shell/pty-manifest.js');
5566
- const { readPodFragment, podFragmentFinished, listPodFragmentsForRun, dispatchPodSelfSend } = await import('./harness/self-send-target.js');
5894
+ const { readPodFragment, podFragmentFinished, listPodFragmentsForRun, dispatchPodSelfSend, resolveSelfSendTarget } = await import('./harness/self-send-target.js');
5567
5895
  const { listHarnessScreens, readHarnessHeartbeat } = await import('./harness/harness-screen.js');
5568
5896
  const decision = decideSelfSend({ space, opts, now: Date.now() }, {
5569
5897
  resolveRunScreen: (runId) => {
@@ -5594,6 +5922,8 @@ selfCmd
5594
5922
  });
5595
5923
  if (decision.kind === 'refuse') {
5596
5924
  process.stderr.write(decision.message);
5925
+ if (remoteLookupFailure) process.stderr.write(`원격 TA 카드 조회 실패: ${remoteLookupFailure}\n`);
5926
+ else if (remoteChildUnconfirmed) process.stderr.write(`원격 Pod 자식 소유 미확인: ${opts.run}의 카드 연결은 HQ 미러에서 확인되지 않았습니다. 활성 원격 카드 하나에 자식 ID가 없으므로 그 카드의 부모 runId 또는 미러 동기화를 확인하세요.\n`);
5597
5927
  process.exit(decision.exitCode);
5598
5928
  }
5599
5929
  const target = decision.spaceId;
@@ -5604,9 +5934,18 @@ selfCmd
5604
5934
  if (hasMemo) {
5605
5935
  if (!opts.memo || /[\r\n]/.test(opts.memo)) throw new Error('control inbox memo must be a non-empty single line');
5606
5936
  const urgent = opts.memo.startsWith('[urgent] ');
5607
- dispatchPodSelfSend(target, { memo: { version: 1, kind: 'supervisor', urgency: urgent ? 'urgent' : 'normal', body: urgent ? opts.memo.slice('[urgent] '.length) : opts.memo } });
5608
- } else dispatchPodSelfSend(target, { stop: true });
5609
- ui.info(`Pod 조각에 ${hasMemo ? '감독 메모' : 'soft stop'} 기록: ${target} (${record?.job ?? 'finished'})`);
5937
+ const { parsePodReadWait } = await import('./harness/pod-control-send.js');
5938
+ const boundedWait = parsePodReadWait(opts.readWait ?? '10');
5939
+ const receipt = dispatchPodSelfSend(target, { memo: { version: 1, kind: 'supervisor', urgency: urgent ? 'urgent' : 'normal', body: urgent ? opts.memo.slice('[urgent] '.length) : opts.memo } }, undefined, undefined, boundedWait);
5940
+ if (!receipt) throw new Error(`self send 대상 Pod 조각 기록 없음: ${target}`);
5941
+ ui.info(`Pod 조각에 감독 메모 기록: ${target} (${record?.job ?? 'finished'})`);
5942
+ ui.info(receipt?.memoRecord
5943
+ ? `${receipt.read ? '자식이 메모 기록을 수거함' : boundedWait > 0 ? '대기 중 읽음 미관측' : '읽음 미관측 (대기 0초)'}: ${receipt.memoRecord}`
5944
+ : 'Pod 메모 전송 확인 · 읽음 미관측 (원격 응답에 record id 없음)');
5945
+ } else {
5946
+ if (!dispatchPodSelfSend(target, { stop: true })) throw new Error(`self send 대상 Pod 조각 기록 없음: ${target}`);
5947
+ ui.info(`Pod 조각에 soft stop 기록: ${target} (${record?.job ?? 'finished'})`);
5948
+ }
5610
5949
  return;
5611
5950
  } catch (error) {
5612
5951
  process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
@@ -5892,7 +6231,7 @@ selfCmd
5892
6231
  .option('--acp', '⭐ ACP(독립 프로세스)로 리뷰 — API 대신 선택한 ACP 백엔드로 독립 리뷰')
5893
6232
  .option('--acp-model <alias>', 'ACP 모델 tier (지정 시 고정, 생략 시 선택한 백엔드 기본값)')
5894
6233
  .option('--acp-backend <id>', 'ACP 백엔드 id (기본: 설정 acp.reviewBackend, 없으면 공유 기본값)')
5895
- .option('--acp-timeout <sec>', 'ACP 리뷰 1턴 최대 대기 초(초과 시 cancel·기본 300)', '300')
6234
+ .option('--acp-timeout <sec>', 'ACP 리뷰 1턴 최대 대기 초(초과 시 cancel·기본 claude 600 · 그 외 300)')
5896
6235
  .option('--context <path>', '리뷰어가 함께 판단할 레포 상대 파일 경로(반복 가능)', (value: string, previous: string[] = []) => [...previous, value])
5897
6236
  .option('--context-text <text>', '리뷰어가 함께 판단할 텍스트(반복 가능)', (value: string, previous: string[] = []) => [...previous, value])
5898
6237
  .option('--json', '구조화 출력 {pr, verdict, mustFix, shouldFix, reviewed}')
@@ -5908,10 +6247,10 @@ selfCmd
5908
6247
  const { spawnSync } = await import('node:child_process');
5909
6248
  const { reviewPullRequest, renderReview } = await import('./agent-substrate/pr-reviewer.js');
5910
6249
  const { createRepositoryReferencedFileReader } = await import('./self-implement/goal-file-reader.js');
5911
- const { streamLLM, getProvider } = await import('./llm.js');
6250
+ const { streamLLM, getProvider, getProviderForConfig } = await import('./llm.js');
5912
6251
  const { registerStandaloneLogSink } = await import('./domains/standalone-log-sink.js');
5913
6252
  const { debug } = await import('./debug/log.js');
5914
- const { runSelfReviewCliCommand, reviewerContextArgs, selfReviewJsonLine } = await import('./agent-substrate/self-review-cli.js');
6253
+ const { apiReviewModelFromRoleSpec, runSelfReviewCliCommand, reviewerContextArgs, selfReviewJsonLine } = await import('./agent-substrate/self-review-cli.js');
5915
6254
  const { subscriptionReviewerAvailability } = await import('./self-dev/review-provider-fallback.js');
5916
6255
  const { makeLazyAcpReviewLLM: makeRoleAcpReviewLLM } = await import('./agent-substrate/acp-reviewer.js');
5917
6256
  const { getOpenRouterApiKey: getOpenRouterApiKeyForReview } = await import('./config.js');
@@ -5922,8 +6261,12 @@ selfCmd
5922
6261
  // The seam decides whether it applies (only without an explicit reviewer flag).
5923
6262
  const { loadLlmPolicy, resolveSubscriptionReviewer } = await import('./policy/llm-policy.js');
5924
6263
  const roleReviewerSelection = resolveSubscriptionReviewer(loadLlmPolicy(), getUserConfig().roleLlm);
6264
+ const reviewRoleSpec = getUserConfig().roleLlm?.review;
6265
+ const configuredReviewModel = apiReviewModelFromRoleSpec(reviewRoleSpec);
5925
6266
  const { results, failed } = await runSelfReviewCliCommand(prArgs, {
5926
6267
  ...opts,
6268
+ ...(configuredReviewModel ? { configuredReviewModel } : {}),
6269
+ ...(configuredReviewModel && reviewRoleSpec?.provider ? { configuredReviewProvider: reviewRoleSpec.provider } : {}),
5927
6270
  ...(configuredAcpBackend ? { configuredAcpBackend } : {}),
5928
6271
  ...(roleReviewerSelection ? { roleReviewer: roleReviewerSelection.spec } : {}),
5929
6272
  ...(contextOrder.length > 0 ? { contextOrder } : {}),
@@ -5947,15 +6290,29 @@ selfCmd
5947
6290
  // 명시 `--model` 이면 provider 를 그 모델의 것으로 «고정»한다 — 라우터 폴백(grok 등)으로 조용히 넘어가지 않고 오류로 낸다.
5948
6291
  makeApiLlm: (model, o) => {
5949
6292
  const effort = reviewReasoningEffort(resolveRoleLlm('review'));
5950
- return (prompt: string) =>
5951
- streamLLM([{ role: 'user', content: prompt }], () => {}, {
6293
+ return (prompt: string) => {
6294
+ let configuredProvider;
6295
+ if (o?.providerName) {
6296
+ try {
6297
+ const config = getUserConfig();
6298
+ configuredProvider = getProviderForConfig({ ...config, llm: { ...config.llm, provider: o.providerName } }, model);
6299
+ } catch (error) {
6300
+ debug.log('self-review', 'role-review-config-provider-error', {
6301
+ provider: o.providerName, model, source: 'roleLlm.review',
6302
+ reason: error instanceof Error ? error.message : String(error),
6303
+ }, { level: 'error' });
6304
+ throw error;
6305
+ }
6306
+ }
6307
+ return streamLLM([{ role: 'user', content: prompt }], () => {}, {
5952
6308
  model,
5953
6309
  // ⛔ 어댑터 기본 2048 은 리뷰 응답을 자른다(VERDICT/MUST-FIX 줄이 잘리면 reviewed=false 로 접힌다).
5954
6310
  maxTokens: 16_000,
5955
- ...(o?.pinProvider ? { provider: getProvider(model) } : {}),
6311
+ ...(configuredProvider ? { provider: configuredProvider } : o?.pinProvider ? { provider: getProvider(model) } : {}),
5956
6312
  ...(o?.onResolved ? { onResolvedProvider: o.onResolved } : {}),
5957
6313
  ...(effort ? { reasoningEffort: effort } : {}),
5958
6314
  });
6315
+ };
5959
6316
  },
5960
6317
  makeAcpLlm: (o) => {
5961
6318
  // ⚠️ 동기 팩토리라 여기서 동적 import 를 쓸 수 없다 — 지연 로드해 첫 호출에 붙인다.
@@ -6508,7 +6865,8 @@ program.command('env').description('환경 감지')
6508
6865
  // src/agent-mission/·관측 카테고리 agent-mission·U1 핸드오프 용어와 정합) — 최상위 `agent`(single-turn
6509
6866
  // chat-with-tools)가 이미 점유해 충돌하므로 그 이름은 못 쓴다. 기존 cron/스크립트(`elanous codex review-watch`
6510
6867
  // 등)는 commander alias 로 그대로 resolvable(하위호환 불변). 상태경로 codex-mission 은 별도로 보존(아래 락/DB).
6511
- const agentBackendHelpNames = agentBackendNames();
6868
+ const agentBackendHelpNames = INDEX_FAST_ROOT ? []
6869
+ : (require('./agent-mission/driver.js') as typeof import('./agent-mission/driver.js')).agentBackendNames();
6512
6870
  const agentBackendHelpList = agentBackendHelpNames.map((name, index) => index === 0 ? `${name}[디폴트]` : name).join('·');
6513
6871
  const agentCmd = program
6514
6872
  .command('agent-mission')
@@ -6896,7 +7254,7 @@ agentCmd
6896
7254
  let initialReviewer: ((pr: string) => Promise<{ verdict: import('./agent-mission/review-loop.js').ReviewVerdict; asks: string[] } | null>) | undefined;
6897
7255
  if (opts.autoInitialReview === true && opts.dryRun !== true) {
6898
7256
  const { reviewDiffBudgetObservation, reviewPullRequest } = await import('./agent-substrate/pr-reviewer.js');
6899
- const { makeAcpReviewLLM } = await import('./agent-substrate/acp-reviewer.js');
7257
+ const { makeAcpReviewLLM, DEFAULT_REVIEW_BACKEND } = await import('./agent-substrate/acp-reviewer.js');
6900
7258
  const { mapReviewToInjected } = await import('./agent-mission/pr-review-watch.js');
6901
7259
  const { execFileSync } = await import('node:child_process');
6902
7260
  const { lookupPrGoalAcceptance } = await import('./self-implement/run-ledger.js');
@@ -6958,6 +7316,7 @@ agentCmd
6958
7316
  .command('setup')
6959
7317
  .description('One command: OAuth / API-key auth + model picker + save config')
6960
7318
  .action(async () => {
7319
+ const { realIO } = await import('./onboarding.js');
6961
7320
  const io = realIO();
6962
7321
  try {
6963
7322
  await runCodexSetup({ io });
@@ -7758,7 +8117,7 @@ const selfDevCmd = program
7758
8117
  humanReadableOutput: !opts.json,
7759
8118
  gitResidueSnapshot: { path: gitResiduePath, observation: gitResidue },
7760
8119
  }, {
7761
- runChatTurn: (text, chat) => runChatTurnCli({
8120
+ runChatTurn: async (text, chat) => (await import('./cli/agent-cli.js')).runChatTurnCli({
7762
8121
  cfg: reloadUserConfig(),
7763
8122
  userText: text,
7764
8123
  explicitSessionId: chat.session,
@@ -8089,7 +8448,9 @@ configCmd
8089
8448
  }
8090
8449
  // IMAGE-LEDGER-TAGS: the baseline pin (the rail sets it through this command) goes into the image ledger.
8091
8450
  if (recordImagePinFromConfigSet(path, parsed) === 'recorded') ui.info(`image ledger: baseline ${String(parsed).slice(0, 12)} · keep=pin`);
8092
- ui.info(`set ${path} = ${JSON.stringify(parsed)}`);
8451
+ // CFG-STORE2-HISTORY-REVERT — set 줄도 «가림 자»를 지난다: 비밀 경로·비밀 모양 값은 MASK(원문 미노출).
8452
+ // 비밀이 아닌 값의 출력은 종전 그대로(JSON.stringify(parsed) == JSON.stringify(maskDeep(parsed))).
8453
+ ui.info(`set ${path} = ${JSON.stringify((await import('./cli/config-audit.js')).maskConfigDisplayValue(path, parsed))}`);
8093
8454
  });
8094
8455
 
8095
8456
  configCmd
@@ -8118,6 +8479,70 @@ configCmd
8118
8479
  ui.info(`unset ${path}`);
8119
8480
  });
8120
8481
 
8482
+ // ── config audit history / revert (CFG-STORE2-HISTORY-REVERT · 0.2.36 · 2026-10-22) ──
8483
+ // CFG-STORE2 가 set/unset 마다 남긴 원장을 «읽어서» 되돌린다. 원장은 append 전용 —
8484
+ // 되돌림도 새 행 하나(why='config revert')로만 남고, 이전 행은 절대 고치지 않는다.
8485
+ // 계산 = src/cli/config-audit.ts(planConfigRevert · formatConfigHistory · configDomainOf).
8486
+ configCmd
8487
+ .command('history <path>')
8488
+ .description('CFG-STORE2 — 한 키의 감사 이력(변경 전후 값·by·why). 비밀은 가려서 보여준다.')
8489
+ .option('--json', 'JSON 출력')
8490
+ .action(async (path: string, opts: { json?: boolean }) => {
8491
+ const { configDomainOf, formatConfigHistory, readConfigHistory } = await import('./cli/config-audit.js');
8492
+ const rows = readConfigHistory(path);
8493
+ if (opts.json) {
8494
+ await writeStdoutJson(`${JSON.stringify({ key: path, domain: configDomainOf(path), rows }, null, 2)}\n`);
8495
+ return;
8496
+ }
8497
+ await writeStdoutJson(`${formatConfigHistory(path, rows)}\n`);
8498
+ });
8499
+
8500
+ configCmd
8501
+ .command('revert <path>')
8502
+ .description('CFG-STORE2 — 그 키의 마지막 변경을 되돌린다(원장은 지우지 않고 새 행을 append).')
8503
+ .option('--no-backup', "Don't write config.json.bak before saving")
8504
+ .option('--json', 'JSON 출력')
8505
+ .action(async (path: string, opts: { backup?: boolean; json?: boolean }) => {
8506
+ const { configDomainOf, containsMaskValue, MASK, planConfigRevert, recordConfigRevert } = await import('./cli/config-audit.js');
8507
+ const plan = planConfigRevert(path);
8508
+ if (plan.status === 'no-history') {
8509
+ ui.error(`revert ${path} — 감사 이력 없음(되돌릴 변경이 없다)`);
8510
+ process.exit(1);
8511
+ }
8512
+ if (plan.status === 'masked') {
8513
+ ui.error(`revert ${path} — 이전 값이 ${MASK} 라 원문 복원 불가(원문은 원장에 남기지 않는다). 그 키를 직접 set 하라.`);
8514
+ process.exit(1);
8515
+ }
8516
+ if (plan.status === 'already') {
8517
+ ui.info(`revert ${path} — 마지막 변경이 값 변화 없음 (no-op)`);
8518
+ return;
8519
+ }
8520
+ const cfg = getUserConfig() as unknown as Record<string, unknown>;
8521
+ const prev = getConfigPath(cfg, path); // 되돌림도 한 번의 변경 — 그 «전» 값을 남긴다
8522
+ if (opts.backup !== false) backupUserConfig(userConfigPath());
8523
+ if (plan.value === undefined) unsetConfigPath(cfg, path);
8524
+ else setConfigPath(cfg, path, plan.value);
8525
+ saveUserConfig(cfg as unknown as ReturnType<typeof getUserConfig>);
8526
+ reloadUserConfig();
8527
+ // set/unset 과 대칭 — 저장 후 재읽기로 «실제로 복원됐는지» 검증(조용한 성공 금지).
8528
+ // 가림 자가 값으로 되쓰였는지도 본다: 오염값끼리는 직렬화 비교가 같아 조용히 통과한다.
8529
+ const after = getConfigPath(getUserConfig() as unknown as Record<string, unknown>, path);
8530
+ if (containsMaskValue(after)) {
8531
+ console.error(`⚠️ revert ${path} — 복원 값에 가림 자(${MASK})가 섞였다(원문 복원 불가). 그 키를 직접 set 하라.`);
8532
+ process.exit(1);
8533
+ }
8534
+ if (JSON.stringify(after) !== JSON.stringify(plan.value)) {
8535
+ console.error(`⚠️ revert ${path} — 저장 후 값 미반영(직렬화 드롭). 읽힌값=${JSON.stringify(after)}`);
8536
+ process.exit(1);
8537
+ }
8538
+ const row = recordConfigRevert({ key: path, prev, next: plan.value, why: 'config revert' });
8539
+ if (opts.json) {
8540
+ await writeStdoutJson(`${JSON.stringify({ key: path, domain: configDomainOf(path), row }, null, 2)}\n`);
8541
+ return;
8542
+ }
8543
+ ui.info(`revert ${path} = ${JSON.stringify(plan.value ?? null)} (domain=${configDomainOf(path)})`);
8544
+ });
8545
+
8121
8546
  // ── config drift / explain (CFG-STORE1 · 0.2.20 · 2026-10-08) — 읽기 전용 «유효 config ⊕ 출처» ──
8122
8547
  // 집(~/.elanous)과 파생 시험 우주(<트리>/.elanous-test) config 사본의 드리프트를 한 명령으로.
8123
8548
  // ⛔ 쓰기 0 · 못 읽음 ≠ 같음 · 비밀 값 가림. 계산 = src/cli/config-drift.ts.
@@ -8306,7 +8731,7 @@ program
8306
8731
  return;
8307
8732
  }
8308
8733
  const cfg = reloadUserConfig();
8309
- await runChatTurnCli({
8734
+ await (await import('./cli/agent-cli.js')).runChatTurnCli({
8310
8735
  cfg,
8311
8736
  userText: parts.join(' '),
8312
8737
  explicitSessionId: opts.session,
@@ -8426,6 +8851,7 @@ program
8426
8851
  .option('--config <path>', 'Load answers from a JSON answer file (overrides interactive prompts)')
8427
8852
  .option('--non-interactive', 'Run without prompts — resolve all answers from --config + env vars')
8428
8853
  .action(async (step: string | undefined, opts: { config?: string; nonInteractive?: boolean }) => {
8854
+ const { runOnboarding, runOnboardingStep, runOnboardingNonInteractive } = await import('./onboarding.js');
8429
8855
  // C-4e (cleanup ROADMAP 2026-05-08) restricted `elanous setup <step>`
8430
8856
  // to llm/skills/obsidian. Telegram/Discord setup migrated to NEXUS
8431
8857
  // — `elanous channel-setup --platform telegram|discord` (Track Q).
@@ -8699,7 +9125,8 @@ sessionCmd
8699
9125
  sessionCmd
8700
9126
  .command('new')
8701
9127
  .description('Create a fresh session and mark it active')
8702
- .action(() => {
9128
+ .action(async () => {
9129
+ const { ensureCliSession } = await import('./session/chat.js');
8703
9130
  const cfg = getUserConfig();
8704
9131
  const s = ensureCliSession(cfg);
8705
9132
  setActiveSessionId(s.id);
@@ -8728,7 +9155,8 @@ sessionCmd
8728
9155
  .command('show [prefix]')
8729
9156
  .description('Print the messages of a session (default: active)')
8730
9157
  .option('--include-tools', 'Include tool-call telemetry (role:tool · 실제 호출 도구·args·result 추적)')
8731
- .action((prefix: string | undefined, opts: { includeTools?: boolean }) => {
9158
+ .action(async (prefix: string | undefined, opts: { includeTools?: boolean }) => {
9159
+ const { sessionBudget } = await import('./session/chat.js');
8732
9160
  const id = prefix ? resolveSessionId(prefix) : getActiveSessionId();
8733
9161
  if (!id) { ui.error('no session'); process.exit(1); }
8734
9162
  const loaded = loadSession(id);
@@ -9147,6 +9575,7 @@ async function runFirstSetupForCli(cfg: ReturnType<typeof getUserConfig>, announ
9147
9575
  }
9148
9576
 
9149
9577
  async function runOnboardingForCli(): Promise<boolean> {
9578
+ const { runOnboarding, handleOnboardingRefusal } = await import('./onboarding.js');
9150
9579
  try {
9151
9580
  await runOnboarding();
9152
9581
  return true;
@@ -9191,7 +9620,7 @@ program
9191
9620
  }
9192
9621
  if (opts.tools) announceChatToolsCompatibility();
9193
9622
  const cfg = getUserConfig();
9194
- if (await firstChatGate(cfg, {
9623
+ if (await (await import('./onboarding/first-chat-gate.js')).firstChatGate(cfg, {
9195
9624
  isTTY: process.stdin.isTTY === true,
9196
9625
  runFirstRun: async (deps) => (await import('./onboarding/first-run.js')).runFirstRun(deps),
9197
9626
  runInteractive: () => {
@@ -9222,7 +9651,7 @@ program
9222
9651
  // 단일 턴 엔진(runChatTurnCli)은 cfg-바인딩 클로저로 주입(순환 회피). opts→DevChatOpts 매핑은 seam.
9223
9652
  const { runChatCliCommand } = await import('./chat/chat-cli.js');
9224
9653
  await runChatCliCommand(parts.join(' '), opts, {
9225
- runChatTurn: (text, chat) => runChatTurnCli({
9654
+ runChatTurn: async (text, chat) => (await import('./cli/agent-cli.js')).runChatTurnCli({
9226
9655
  cfg: refreshed,
9227
9656
  userText: text,
9228
9657
  explicitSessionId: chat.session,
@@ -9267,7 +9696,15 @@ program
9267
9696
  process.exit(2);
9268
9697
  }
9269
9698
  const cfg = getUserConfig();
9270
- if (needsOnboarding(cfg)) {
9699
+ if ((await import('./onboarding.js')).needsOnboarding(cfg)) {
9700
+ // Machine mode contract: stdout carries JSONL only. An onboarding
9701
+ // banner there corrupts the stream (`invalid REPL JSONL response`
9702
+ // in the TUI parent). Fail fast on stderr instead of launching an
9703
+ // interactive wizard on a pipe.
9704
+ if (opts.json === true || opts.stdinJsonl === true) {
9705
+ process.stderr.write('No config yet — run `elanous` once interactively (onboarding) before using repl --json / --stdin-jsonl.\n');
9706
+ process.exit(2);
9707
+ }
9271
9708
  if (cfg.onboarding.webFirst === false) ui.info('No config yet — launching setup wizard first.');
9272
9709
  if (!await runFirstSetupForCli(cfg, true)) return;
9273
9710
  }
@@ -11613,6 +12050,7 @@ function writeSyncFailure(message: string): void {
11613
12050
  }
11614
12051
 
11615
12052
  async function runSyncFlow(fromDashboard: boolean): Promise<void> {
12053
+ const { showSyncSelector, showSyncProgress } = await import('./selector.js');
11616
12054
  let result: Awaited<ReturnType<typeof showSyncSelector>>;
11617
12055
  try {
11618
12056
  result = await showSyncSelector(fromDashboard);
@@ -11741,6 +12179,12 @@ export function filterDashboardArgs(rawArgs: readonly string[], resumeFlagIdx?:
11741
12179
  }
11742
12180
 
11743
12181
  async function main(): Promise<void> {
12182
+ // TUI-BOOT-TIMING-HOLES — «프로세스→sink» 구간(10:40 실측 9.3s). 그 9.3s 의 대부분은 이 모듈이
12183
+ // import 되는 동안(모듈 로드) 흐르므로, main() 진입만 재면 구간을 잘라 먹는다. `performance.now()`
12184
+ // 의 기준점은 프로세스 시작(`performance.timeOrigin`)이라 sink 등록 직전의 «절대값» 이 곧
12185
+ // 프로세스→sink 다. main() 진입 시각은 그 안에서 «어느 몫이 엔트리 코드인지» 가르는 두 번째 값.
12186
+ // 발행은 sink 등록 뒤로 미룬다(등록 전 debug.log 는 no-op).
12187
+ const bootMainEnteredAt = performance.now();
11744
12188
  // WD1 — seed the session working directory from the launch cwd.
11745
12189
  // Every later-phase subsystem reads via getSessionCwd() instead of
11746
12190
  // process.cwd(). Subcommand dispatch (program.parseAsync) runs
@@ -11778,6 +12222,15 @@ async function main(): Promise<void> {
11778
12222
 
11779
12223
  let rawArgs = process.argv.slice(2);
11780
12224
 
12225
+ // The root flag can follow other launch options, but never a subcommand.
12226
+ const rootTui = extractRootTuiEntry(rawArgs);
12227
+ if (rootTui.error) {
12228
+ console.error(rootTui.error);
12229
+ process.exitCode = 1;
12230
+ return;
12231
+ }
12232
+ rawArgs = rootTui.args;
12233
+
11781
12234
  rawArgs = rewriteBareNexusToStatus({ rawArgs });
11782
12235
 
11783
12236
  // A leading --rich was a dashboard launch flag. The dashboard no longer
@@ -11921,6 +12374,9 @@ async function main(): Promise<void> {
11921
12374
  const resolved = await resolveRemoteTarget({});
11922
12375
  if (resolved) remote = resolved;
11923
12376
  }
12377
+ // Bare entry is classic. The next TUI has no remote transport yet;
12378
+ // an explicit --tui next still reports the unsupported combination below.
12379
+ const tuiEntry = effectiveRootTuiEntry(rootTui, Boolean(remote));
11924
12380
 
11925
12381
  // Root dashboard resume accepts `--resume`. Only a
11926
12382
  // leading launch flag is owned here: a subcommand's `-r` stays
@@ -11985,8 +12441,13 @@ async function main(): Promise<void> {
11985
12441
  // (e.g. `session watch --debug`), stripping them here would silently
11986
12442
  // eat that subcommand's own option before commander ever sees it.
11987
12443
  const args = filterDashboardArgs(rawArgs, resumeFlagIdx);
12444
+ if (tuiEntry === 'next' && rootTui.explicit && args.length > 0) {
12445
+ console.error('elanous: --tui next is a standalone TUI entry, not a subcommand option');
12446
+ process.exitCode = 1;
12447
+ return;
12448
+ }
11988
12449
 
11989
- // Bare `elanous` (no subcommand) → the dashboard, always. The former
12450
+ // Bare `elanous` (no subcommand) → classic dashboard; next TUI only via `--tui next`. The former
11990
12451
  // `global.entry.defaultMode` switch (which could route here to the
11991
12452
  // headless NEXUS daemon) was removed 2026-07-24: T3/T4 deleted the
11992
12453
  // NEXUS interactive TUI, so every non-dashboard route was a dead-end
@@ -12048,7 +12509,7 @@ async function main(): Promise<void> {
12048
12509
  // Bare entry only requires an LLM; detailed setup stays behind `eln setup`.
12049
12510
  const firstRunStartedAt = Date.now();
12050
12511
  const cfg = getUserConfig();
12051
- if (needsFirstRun(cfg)) {
12512
+ if ((await import('./onboarding.js')).needsFirstRun(cfg)) {
12052
12513
  if (cfg.onboarding.webFirst !== false) {
12053
12514
  const { runWebFirstSetup } = await import('./onboarding/web-first.js');
12054
12515
  if (await runWebFirstSetup({ config: cfg, startedAt: firstRunStartedAt, startIfMissing: false }) === 'link-shown') return;
@@ -12098,7 +12559,20 @@ async function main(): Promise<void> {
12098
12559
  // PR#4622(self utterance CLI)·session-cli 미러. fail-open·비블로킹.
12099
12560
  const bootTimer = (await import('./dashboard/boot-timing.js')).createBootTimer();
12100
12561
  bootTimer.begin();
12562
+ // 창은 sink 등록 «직전» 에 닫는다(등록 전 debug.log 는 no-op 이라 발행은 등록 뒤).
12563
+ const procToLogSinkMs = performance.now();
12564
+ const mainEnterToLogSinkMs = procToLogSinkMs - bootMainEnteredAt;
12101
12565
  try { await (await import('./domains/standalone-log-sink.js')).registerStandaloneLogSink('tui'); } catch { /* fail-open */ }
12566
+ debug.log('tui.boot', 'phase', {
12567
+ phase: 'proc-to-log-sink',
12568
+ ms: Math.round(procToLogSinkMs),
12569
+ from: 'process-start',
12570
+ });
12571
+ debug.log('tui.boot', 'phase', {
12572
+ phase: 'main-enter-to-log-sink',
12573
+ ms: Math.round(mainEnterToLogSinkMs),
12574
+ from: 'main-entry',
12575
+ });
12102
12576
  bootTimer.phase('log-sink');
12103
12577
  // P3(대표 2026-07-26) — footgun 관측을 logs.db 에 도달시킨다. 초반(arg 파싱 前) warnProdSpawnFootgun 은
12104
12578
  // StoreSink 등록 前이라 debug.log 가 logs.db 미도달이었다(순서 갭). sink 등록 직후 관측만 재발행(stderr 중복 X).
@@ -12125,20 +12599,214 @@ async function main(): Promise<void> {
12125
12599
  }
12126
12600
  }
12127
12601
  bootTimer.begin();
12128
- await showDashboard({
12129
- ...dashboardOpts,
12130
- onFirstFrameRendered: () => {
12131
- bootTimer.phase('show-dashboard');
12132
- bootTimer.done();
12133
- },
12602
+ if (tuiEntry === 'next') {
12603
+ if (remote) {
12604
+ console.error('elanous: --tui next currently reads local sessions only; drop it (classic is the default) for remote attach');
12605
+ process.exitCode = 1;
12606
+ return;
12607
+ }
12608
+ if ((process.stdout.columns || 0) < 20 || (process.stdout.rows || 0) < 6) {
12609
+ console.error('elanous: --tui next requires at least 20 columns and 6 rows');
12610
+ process.exitCode = 1;
12611
+ return;
12612
+ }
12613
+ const { showNextTui } = await import('./tui/entry.js');
12614
+ await showNextTui({ resumeSessionId });
12615
+ bootTimer.phase('show-next');
12616
+ bootTimer.done();
12617
+ } else {
12618
+ const { showDashboard } = await import('./dashboard/index.js');
12619
+ await showDashboard({
12620
+ ...dashboardOpts,
12621
+ // TUI-BOOT-TIMING-HOLES — show 동기 셋업(2.3s)은 종전 첫 프레임 신호 하나에 묶여 안 보였다.
12622
+ // bootTimer 는 createBootTimer 시점부터 재므로, dashboard 가 잰 «진입~첫 프레임» 값을 그대로
12623
+ // 이벤트로 남긴다(요약 phase 회계는 종전 그대로 보존).
12624
+ onSyncSetupComplete: (ms: number) => {
12625
+ debug.log('tui.boot', 'show-dashboard-setup', { ms: Math.round(ms) });
12626
+ },
12627
+ onFirstFrameRendered: () => {
12628
+ bootTimer.phase('show-dashboard');
12629
+ bootTimer.done();
12630
+ },
12631
+ });
12632
+ closeTui();
12633
+ }
12634
+ // TUI-H9-ACTIVE-SESSION-ID — 기동 뒤 설치본/체크아웃이 움직였으면 «이 TUI 가 지금 보여 주던 대화»
12635
+ // 로 스스로 다시 뜬다. 확인이 안 되면 다시 뜨지 않고 이유를 남긴다(전역 최신·기동 resume 으로 메우지 않는다).
12636
+ await exitTuiRun();
12637
+ }
12638
+
12639
+ // ── TUI-H9-ACTIVE-SESSION-ID · 0.2.36 — 재기동은 «이 TUI 의 활성 대화» 로만 ──
12640
+ //
12641
+ // #30046 의 H9 배선은 재기동 세션을 `resumeSessionId ?? getActiveSessionId() ?? listSessions()[0]?.id`
12642
+ // 로 골랐다 — 기동 때의 resume 값이 이후의 활성 세션보다 우선했고, 활성 id 가 없으면 전역 최신(다른
12643
+ // 자리의 맥락일 수 있다)을 집어 왔다. 여기서는 ①이 TUI 가 화면으로 확인한 대화(tui-self-report 의
12644
+ // 소유 기록)와 ②지금 집중된 활성 id 가 «같고» ③그 대화가 저장소에 실재할 때만 재기동한다. 하나라도
12645
+ // 어긋나면 다시 뜨지 않고 이유를 남긴다 — 비슷한 id 로 메우지 않는다.
12646
+
12647
+ /**
12648
+ * TUI 종료 경계 — 재기동 «요청»(`requestTuiSelfRestart`)이 있고 판이 낡았으면 «이 TUI 의 활성 대화» 로
12649
+ * 자식을 띄우고, 부모는 그 종료 코드로 끝난다. 요청이 없으면(사용자 `q`/Ctrl+Q) 낡음을 재지도 않고
12650
+ * 지금처럼 0 으로 끝난다 — 종료 의도를 재기동으로 바꾸지 않는다.
12651
+ * 강제 종료는 그대로다: 대시보드의 배경 타이머(clipboard poller·shimmer/blink)가 Bun 이벤트 루프를
12652
+ * 붙잡아 `q`/Ctrl+Q 뒤에도 터미널이 멈춘 채 남는다.
12653
+ */
12654
+ export async function exitTuiRun(
12655
+ deps: TuiSelfRestartDeps & {
12656
+ readonly exit?: (code: number) => never;
12657
+ /** 재기동 요청 — 기본 = `takeTuiSelfRestartRequest()`(한 번 읽고 지운다). */
12658
+ readonly takeRestartRequest?: () => { readonly reason: string } | null;
12659
+ } = {},
12660
+ ): Promise<void> {
12661
+ const exit = deps.exit ?? ((code: number): never => process.exit(code));
12662
+ const take = deps.takeRestartRequest
12663
+ ?? (await import('./capture/tui-self-report.js')).takeTuiSelfRestartRequest;
12664
+ const request = take();
12665
+ if (!request) {
12666
+ try {
12667
+ (deps.log ?? ((event: string, detail: Record<string, unknown>) => debug.log('tui.self-restart', event, detail)))(
12668
+ 'skip', { reason: 'no-restart-request' },
12669
+ );
12670
+ } catch { /* 관측 실패가 종료를 막지 않는다 */ }
12671
+ exit(0);
12672
+ }
12673
+ const selfRestart = await runTuiSelfRestartOnStaleBuild(deps);
12674
+ if (selfRestart.outcome === 'relaunch') {
12675
+ // 자식이 화면을 이어받았다 — 부모는 자식 종료 코드로 끝난다.
12676
+ exit(selfRestart.exitCode ?? 0);
12677
+ }
12678
+ exit(0);
12679
+ }
12680
+
12681
+ export interface TuiSelfRestartResult {
12682
+ readonly outcome: 'skip' | 'blocked' | 'relaunch';
12683
+ readonly reason: string;
12684
+ readonly sessionId?: string;
12685
+ readonly argv?: readonly string[];
12686
+ readonly exitCode?: number;
12687
+ }
12688
+
12689
+ export interface TuiSelfRestartDeps {
12690
+ /** 재기동 자식의 스크립트 경로 — 기본 = `process.argv[1]`(배포 엔트리). */
12691
+ readonly scriptPath?: string;
12692
+ /** 사용자 인자 — 기본 = `process.argv.slice(2)`. 이전 `--resume`/`--continue` 는 걷어내고 우리 id 만 싣는다. */
12693
+ readonly args?: readonly string[];
12694
+ /** 낡음 판정 — 기본 = `judgeBuildStaleness(runningBuild ⊕ readCurrentInstallRecord ⊕ readCheckoutHead)`. */
12695
+ readonly stale?: () => { readonly stale: boolean | null; readonly reason: string };
12696
+ /** 이 TUI 가 화면으로 확인한 대화 — 기본 = 소유 기록(`getTuiOwnedSession`). */
12697
+ readonly owned?: () => { readonly sessionId: string; readonly at: number } | null;
12698
+ /** 지금 집중된 활성 대화 id — 기본 = `getActiveSessionId()`. */
12699
+ readonly liveActiveSessionId?: () => string | null;
12700
+ /** 그 id 의 대화가 실재하나 — 기본 = `loadSession(id) !== null`. */
12701
+ readonly sessionExists?: (sessionId: string) => boolean;
12702
+ /** 관측 전용 — «전역 최신»이 무엇이든 재기동 id 는 여기서 고르지 않는다(로그·사유 문면에만 적는다). */
12703
+ readonly globalLatestSessionId?: () => string | null;
12704
+ readonly spawnChild?: (command: string, argv: readonly string[], env: Record<string, string>) => Promise<number>;
12705
+ readonly log?: (event: string, detail: Record<string, unknown>) => void;
12706
+ }
12707
+
12708
+ /** 한 런의 재기동 세대 상한 — 재기동한 자식이 또 낡아도 여기서 멈춘다(무한 재기동 방지). */
12709
+ const TUI_SELF_RESTART_MAX_GENERATION = 3;
12710
+
12711
+ /** 재기동 자식에게 넘길 argv — 이 TUI 의 활성 대화만 `--resume` 으로 싣는다. */
12712
+ export function planTuiRestartArgv(input: {
12713
+ readonly scriptPath: string;
12714
+ readonly args: readonly string[];
12715
+ readonly sessionId: string;
12716
+ }): string[] {
12717
+ const kept: string[] = [];
12718
+ for (let i = 0; i < input.args.length; i += 1) {
12719
+ const arg = input.args[i]!;
12720
+ if (arg === '--resume') {
12721
+ // 값 없는 `--resume` 뒤에 오는 플래그는 값이 아니다 — 삼키지 않는다.
12722
+ const next = input.args[i + 1];
12723
+ if (next !== undefined && !next.startsWith('-')) i += 1;
12724
+ continue;
12725
+ }
12726
+ if (arg === '--continue' || arg.startsWith('--resume=') || arg.startsWith('--continue=')) continue;
12727
+ kept.push(arg);
12728
+ }
12729
+ return [input.scriptPath, ...kept, '--resume', input.sessionId];
12730
+ }
12731
+
12732
+ /**
12733
+ * 낡은 판에서 TUI 를 스스로 다시 띄운다 — 이 TUI 가 보여 주던 대화로만.
12734
+ * 확인 실패는 «재기동 안 함» 이고 그 이유가 로그·stderr 로 남는다.
12735
+ */
12736
+ export async function runTuiSelfRestartOnStaleBuild(deps: TuiSelfRestartDeps = {}): Promise<TuiSelfRestartResult> {
12737
+ const report = deps.log ?? ((event: string, detail: Record<string, unknown>) => debug.log('tui.self-restart', event, detail));
12738
+ const { judgeBuildStaleness, readCheckoutHead, readCurrentInstallRecord, runningBuild } = await import('./pty-shell/tui-run-state.js');
12739
+ const staleness = (deps.stale ?? (() => {
12740
+ const build = runningBuild();
12741
+ const checkoutHead = build.source === 'checkout' && build.codeRoot ? readCheckoutHead(build.codeRoot) : undefined;
12742
+ return judgeBuildStaleness({ build, installed: readCurrentInstallRecord(), ...(checkoutHead ? { checkoutHead } : {}) });
12743
+ }))();
12744
+ if (staleness.stale !== true) {
12745
+ report('skip', { reason: staleness.reason });
12746
+ return { outcome: 'skip', reason: staleness.reason };
12747
+ }
12748
+ const generation = Number.parseInt(process.env.ELANOUS_TUI_RESTART_GEN ?? '0', 10) || 0;
12749
+ const tuiReport = await import('./capture/tui-self-report.js');
12750
+ const store = await import('./session/index.js');
12751
+ const owned = (deps.owned ?? tuiReport.getTuiOwnedSession)();
12752
+ const liveActiveSessionId = (deps.liveActiveSessionId ?? store.getActiveSessionId)();
12753
+ const globalLatestSessionId = (deps.globalLatestSessionId
12754
+ ?? (() => { try { return store.listSessions({ limit: 1 })[0]?.id ?? null; } catch { return null; } }))();
12755
+ if (generation >= TUI_SELF_RESTART_MAX_GENERATION) {
12756
+ report('blocked', { reason: 'generation-limit', generation, staleReason: staleness.reason });
12757
+ console.error(`elanous: 설치본이 바뀌었지만 이 런은 이미 ${generation}번 다시 떴다 — 자동 재기동을 멈춘다(수동으로 다시 열어라).`);
12758
+ return { outcome: 'blocked', reason: 'generation-limit' };
12759
+ }
12760
+ const decision = tuiReport.decideTuiRestartSession({
12761
+ owned,
12762
+ liveActiveSessionId,
12763
+ sessionExists: deps.sessionExists ?? ((id: string) => { try { return store.loadSession(id) !== null; } catch { return false; } }),
12764
+ });
12765
+ if (!decision.ok) {
12766
+ report('blocked', {
12767
+ reason: decision.reason,
12768
+ staleReason: staleness.reason,
12769
+ ownedSessionId: owned?.sessionId ?? null,
12770
+ liveActiveSessionId,
12771
+ globalLatestSessionId,
12772
+ generation,
12773
+ });
12774
+ console.error(`elanous: 설치본이 바뀌었지만 이 TUI 의 활성 대화를 확인하지 못해 다시 뜨지 않았다(${decision.reason}) — 다시 열면 지금 화면의 대화로 이어진다.`);
12775
+ return { outcome: 'blocked', reason: decision.reason };
12776
+ }
12777
+ const argv = planTuiRestartArgv({
12778
+ scriptPath: deps.scriptPath ?? process.argv[1] ?? '',
12779
+ args: deps.args ?? process.argv.slice(2),
12780
+ sessionId: decision.sessionId,
12781
+ });
12782
+ const env: Record<string, string> = {};
12783
+ for (const [key, value] of Object.entries(process.env)) if (typeof value === 'string') env[key] = value;
12784
+ env.ELANOUS_TUI_RESTART_GEN = String(generation + 1);
12785
+ report('relaunch', {
12786
+ sessionId: decision.sessionId,
12787
+ claimedAt: decision.claimedAt,
12788
+ staleReason: staleness.reason,
12789
+ generation,
12790
+ argv,
12791
+ globalLatestSessionId,
12792
+ });
12793
+ console.error(`elanous: 설치본이 바뀌어 이 TUI 의 대화(${decision.sessionId})로 다시 뜬다${globalLatestSessionId && globalLatestSessionId !== decision.sessionId ? ` — 전역 최신 ${globalLatestSessionId} 은 싣지 않는다` : ''}.`);
12794
+ const exitCode = await (deps.spawnChild ?? defaultTuiSelfRestartSpawn)(process.execPath, argv, env);
12795
+ return { outcome: 'relaunch', reason: staleness.reason, sessionId: decision.sessionId, argv, exitCode };
12796
+ }
12797
+
12798
+ /** 재기동 자식 — 같은 터미널(stdio inherit)을 물려받는다. 부모는 자식 종료를 기다린 뒤 그 코드로 끝난다. */
12799
+ async function defaultTuiSelfRestartSpawn(command: string, argv: readonly string[], env: Record<string, string>): Promise<number> {
12800
+ const childProcess = await import('node:child_process');
12801
+ const child: import('node:child_process').ChildProcess = childProcess.spawn(
12802
+ command,
12803
+ [...argv],
12804
+ { stdio: 'inherit', env: env as NodeJS.ProcessEnv },
12805
+ );
12806
+ return await new Promise<number>((resolve) => {
12807
+ child.on('error', () => resolve(1));
12808
+ child.on('exit', (code, signal) => resolve(typeof code === 'number' ? code : signal ? 1 : 0));
12134
12809
  });
12135
- closeTui();
12136
- // Force exit: the dashboard starts background timers (clipboard
12137
- // poller, shimmer/blink animations) that keep the Bun event loop
12138
- // alive even after the TUI tears down. Without this hard exit,
12139
- // `q` / Ctrl+Q would leave the user staring at a wedged terminal
12140
- // until they sent SIGINT.
12141
- process.exit(0);
12142
12810
  }
12143
12811
 
12144
12812
  /**