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
@@ -28,7 +28,7 @@
28
28
  // daemon exit.
29
29
 
30
30
  import type { McpServerSpec } from '../../user-config.js';
31
- import { McpClient, McpConnectionError, type McpToolCallResult } from '../../mcp/client.js';
31
+ import { McpClient, McpConnectionError, type McpTool, type McpToolCallResult } from '../../mcp/client.js';
32
32
  import {
33
33
  createMcpProxyRuntime,
34
34
  createMcpToolAuthorizer,
@@ -36,13 +36,13 @@ import {
36
36
  import { registerToolRuntime, unregisterToolRuntime } from '../../tool-runtime/registry.js';
37
37
  import { debug, redactSecretText } from '../../debug/log.js';
38
38
  import { elanousStateRoot } from '../../autopilot/state-paths.js';
39
- import { spawn as nodeSpawn } from 'node:child_process';
39
+ import { spawn as nodeSpawn, type ChildProcess } from 'node:child_process';
40
40
  import { listNodeKinds } from '../../graph-kinds/registry.js';
41
41
  import { syncInstalledPluginNodes } from '../../graph-kinds/installed-plugin-nodes.js';
42
42
  import { listInstalledPlugins } from '../../plugins/install/plugin-install.js';
43
43
  import { pluginEnv, credentialStatus } from '../../plugins/install/plugin-credentials.js';
44
- import { existsSync, realpathSync } from 'node:fs';
45
- import { resolve, sep } from 'node:path';
44
+ import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from 'node:fs';
45
+ import { join, resolve, sep } from 'node:path';
46
46
 
47
47
  export interface McpClientsHandle {
48
48
  /** Live clients (one per successfully started server). */
@@ -56,6 +56,9 @@ export interface McpClientsHandle {
56
56
  // ⇒ 노출하지 않는다. 허가 상태는 「등록된 런타임이 거부하나」로 «행동»으로 관측한다.
57
57
  /** Stop all clients gracefully and revoke this handle's grants. Safe to call multiple times. */
58
58
  shutdown(): Promise<void>;
59
+ /** 동기 마지막 수단 — 프로세스 exit 훅은 `await` 할 수 없다. 살아 있는 자식에
60
+ * SIGTERM 만 «즉시» 쏘고 신호를 보낸 수를 돌려준다(유예·SIGKILL 은 `shutdown` 몫). */
61
+ terminateChildrenSync?(): number;
59
62
  }
60
63
 
61
64
  export interface McpServerBootResult {
@@ -65,6 +68,10 @@ export interface McpServerBootResult {
65
68
  status: 'ready' | 'disabled' | 'failed';
66
69
  /** Number of tools registered from this server. 0 unless status=='ready'. */
67
70
  toolCount: number;
71
+ /** When status=='ready' under `lazy`: the tools above were announced from the
72
+ * cached tool index and the child has NOT been spawned yet — the first
73
+ * `callTool` on one of them spawns it (once). Absent = spawned eagerly. */
74
+ deferred?: boolean;
68
75
  /** When status=='failed', the error message captured (string only —
69
76
  * callers should not depend on Error identity). */
70
77
  reason?: string;
@@ -126,8 +133,33 @@ export interface RegisterMcpClientsOpts {
126
133
  setTimeoutFn?: (cb: () => void, ms: number) => { unref?(): void };
127
134
  /** Test seam — replaces `clearTimeout`. */
128
135
  clearTimeoutFn?: (handle: { unref?(): void }) => void;
136
+ /** CLASSIC-IDLE-MCP-LAZY (0.2.35) — classic TUI 백그라운드 경량화.
137
+ * true 면 자식은 «기동 때»가 아니라 «첫 도구 호출» 때 한 번 뜬다.
138
+ * 그 전까지 알리는 툴 «목록»은 지난 부팅이 적어 둔 인덱스
139
+ * (`MCP_TOOL_INDEX_FILENAME`) 그대로다 — 목록·권한은 무변경.
140
+ * 인덱스가 없는 서버(콜드 스타트)는 종전대로 즉시 기동하고 인덱스를 적는다. */
141
+ lazy?: boolean;
142
+ /** `lazy` 가 읽고 쓰는 툴 인덱스. 기본은 상태 루트의 `mcp-tool-index.json`. */
143
+ toolIndexStore?: McpToolIndexStore;
144
+ /** `lazy` 자식의 SIGTERM→SIGKILL 유예(ms). 기본 2500 — 종료 3초 계약 안쪽. */
145
+ lazyShutdownGraceMs?: number;
129
146
  }
130
147
 
148
+ /** 한 서버가 지난 부팅에서 알린 툴 목록. `mcp-tool-index.json` 의 값. */
149
+ export type McpToolIndex = Record<string, McpTool[]>;
150
+
151
+ /** 툴 목록 캐시의 읽기/쓰기 자리 — 테스트가 임시 저장소로 갈아 끼운다. */
152
+ export interface McpToolIndexStore {
153
+ read(): McpToolIndex;
154
+ write(index: McpToolIndex): void;
155
+ }
156
+
157
+ export const MCP_TOOL_INDEX_FILENAME = 'mcp-tool-index.json';
158
+
159
+ /** 지연 기동 자식의 정리 유예. `McpClient` 기본 5000ms 는 「SIGTERM 3초 안에
160
+ * 안 끝남」이던 classic 종료 계약을 넘긴다 — 2500ms 면 SIGKILL 까지 3초 안쪽. */
161
+ const DEFAULT_LAZY_SHUTDOWN_GRACE_MS = 2500;
162
+
131
163
  const DEFAULT_HANDSHAKE_TIMEOUT_MS = 8000;
132
164
 
133
165
  /** Race `op` against a timeout. Resolves to `op` on success; rejects
@@ -151,6 +183,60 @@ function withTimeout<T>(
151
183
  });
152
184
  }
153
185
 
186
+ type DeferredInner = Pick<McpClient, 'start' | 'listTools' | 'callTool' | 'dispose'>;
187
+
188
+ /** 첫 도구 호출까지 자식을 띄우지 않는 MCP 클라이언트 프록시.
189
+ * - `callTool` 이 «한 번» 기동하고 동시 호출은 같은 기동을 기다린다.
190
+ * - 기동 실패는 캐시하지 않는다 — 자식이 늦게 뜨면 다음 호출이 다시 시도한다.
191
+ * - `dispose()` 는 진행 중 기동을 먼저 기다린다 — 자식이 새지 않는다. */
192
+ class DeferredMcpClient implements DeferredInner {
193
+ private pending: Promise<void> | null = null;
194
+ private started = false;
195
+ private disposed = false;
196
+
197
+ constructor(
198
+ private readonly inner: DeferredInner,
199
+ private readonly boot: () => Promise<void>,
200
+ private readonly serverId: string,
201
+ ) {}
202
+
203
+ get spawned(): boolean { return this.started; }
204
+
205
+ async start(): Promise<void> { await this.ensureStarted(); }
206
+
207
+ async listTools(): Promise<McpTool[]> {
208
+ await this.ensureStarted();
209
+ return this.inner.listTools();
210
+ }
211
+
212
+ async callTool(name: string, args: Record<string, unknown>): Promise<McpToolCallResult> {
213
+ await this.ensureStarted();
214
+ // ⚠️ 기동 «뒤»의 inner.callTool 을 부른다 — 자격증명 마스킹 래퍼가
215
+ // createClient 직후 client.callTool 에 씌워지므로 그 래퍼를 탄다.
216
+ return this.inner.callTool(name, args);
217
+ }
218
+
219
+ async dispose(): Promise<void> {
220
+ this.disposed = true;
221
+ if (this.pending) {
222
+ try { await this.pending; } catch { /* 기동 실패는 정리를 막지 않는다 */ }
223
+ }
224
+ try { await this.inner.dispose(); } catch { /* dispose() is best-effort */ }
225
+ }
226
+
227
+ private async ensureStarted(): Promise<void> {
228
+ if (this.disposed) {
229
+ throw new Error(`mcp.${this.serverId}: lazy client was disposed before its first tool call`);
230
+ }
231
+ if (this.started) return;
232
+ if (!this.pending) {
233
+ this.pending = this.boot().then(() => { this.started = true; });
234
+ this.pending.catch(() => { this.pending = null; });
235
+ }
236
+ await this.pending;
237
+ }
238
+ }
239
+
154
240
  export interface McpBootLogger {
155
241
  info(line: string): void;
156
242
  warn(line: string): void;
@@ -196,6 +282,9 @@ export async function registerMcpClients(
196
282
  debug.log('mcp.client.boot', event, { id, ...safe });
197
283
  } catch { /* logger must never throw the boot */ }
198
284
  };
285
+ // 이 부팅이 띄운 자식들. 지연 기동이면 «첫 도구 호출» 뒤에야 채워지고,
286
+ // 프로세스가 그냥 죽는 경로(exit 훅)에서는 여기 남은 자식에 SIGTERM 을 쏜다.
287
+ const spawnedChildren = new Set<ChildProcess>();
199
288
  const createClient =
200
289
  opts.createClient ??
201
290
  ((spec: McpServerSpec) => {
@@ -221,6 +310,8 @@ export async function registerMcpClients(
221
310
  const selected = commandOwners.length === 1 && owners.length === 1 && owners[0] === commandOwners[0]
222
311
  ? commandOwners[0] : undefined;
223
312
  return new McpClient({ id: spec.id, command: spec.command, logger: bootLogger(spec.id),
313
+ // 지연 기동이면 정리 유예를 좁힌다 — classic 종료는 3초 안에 끝나야 한다.
314
+ ...(opts.lazy === true ? { shutdownGraceMs: opts.lazyShutdownGraceMs ?? DEFAULT_LAZY_SHUTDOWN_GRACE_MS } : {}),
224
315
  spawn: (cmd, args) => {
225
316
  const declaredEnv = [...new Set(listInstalledPlugins(root).map(item => item.name))]
226
317
  .flatMap(name => credentialStatus(name, root).fields.map(field => field.env));
@@ -234,7 +325,10 @@ export async function registerMcpClients(
234
325
  Object.assign(childEnv, env);
235
326
  injectedValuesByServer.set(spec.id, Object.values(env));
236
327
  }
237
- return nodeSpawn(cmd, args, { stdio: ['pipe', 'pipe', 'pipe'], env: childEnv });
328
+ const child = nodeSpawn(cmd, args, { stdio: ['pipe', 'pipe', 'pipe'], env: childEnv });
329
+ spawnedChildren.add(child);
330
+ child.once('exit', () => { spawnedChildren.delete(child); });
331
+ return child;
238
332
  },
239
333
  });
240
334
  });
@@ -252,6 +346,66 @@ export async function registerMcpClients(
252
346
  const perServer: Record<string, McpServerBootResult> = {};
253
347
  let registered = 0;
254
348
 
349
+ // ── CLASSIC-IDLE-MCP-LAZY ────────────────────────────────────────────────
350
+ // classic TUI 는 MCP 서버 둘(xcodebuildmcp · aside mcp)을 «기동 때» 띄워
351
+ // 상주시켰다 — TUI 하나당 node⊕aside 자손 RSS 약 267MB, SIGTERM 3초 안에
352
+ // 안 끝남(0.2.35 OP 실측). ⇒ `lazy` 면 자식은 «첫 도구 호출» 때 한 번 뜨고,
353
+ // 그 전에 알리는 툴 «목록»은 지난 부팅이 적어 둔 인덱스 그대로다.
354
+ const lazy = opts.lazy === true;
355
+ const toolIndexStore = lazy ? (opts.toolIndexStore ?? defaultMcpToolIndexStore()) : undefined;
356
+ const toolIndex: McpToolIndex = toolIndexStore ? readToolIndex(toolIndexStore) : {};
357
+ const deferredClients: DeferredMcpClient[] = [];
358
+ const lazyToolsFor = (serverId: string): McpTool[] | undefined => {
359
+ if (!lazy) return undefined;
360
+ const cached = toolIndex[serverId];
361
+ return cached && cached.length > 0 ? cached : undefined;
362
+ };
363
+ const recordToolIndex = (serverId: string, tools: readonly McpTool[]): void => {
364
+ if (!toolIndexStore) return;
365
+ toolIndex[serverId] = [...tools];
366
+ toolIndexStore.write(toolIndex);
367
+ };
368
+ const logLazyBoot = (
369
+ serverId: string,
370
+ reason: 'deferred' | 'first-call' | 'no-index',
371
+ toolCount?: number,
372
+ ): void => {
373
+ try {
374
+ debug.log('mcp.client', 'lazy-boot', {
375
+ server: serverId,
376
+ reason,
377
+ ...(toolCount === undefined ? {} : { toolCount }),
378
+ });
379
+ } catch { /* logger must never throw the boot */ }
380
+ };
381
+ /** 허가 관문 보고 — 지연·즉시 두 경로가 «같은 문면»을 낸다. */
382
+ const reportAuthorization = (serverId: string, tools: readonly { name: string }[]): void => {
383
+ const grantedCount = tools.filter((t) => authorizer.isGranted(serverId, t.name)).length;
384
+ if (tools.length > 0 && grantedCount === 0) {
385
+ logger.warn(
386
+ // ⛔ 접두 «라벨»도 같은 문자열이다 — 본문만 이스케이프하면 개행이 여기로 샌다.
387
+ `[nexus] mcp-client ${JSON.stringify(serverId)}: ${tools.length} tool(s) registered but NONE authorized — every call will be denied. ` +
388
+ // ⛔ 「복사해 붙일 수 있게」라고 말하려면 «붙일 수 있는 것»을 줘야 한다.
389
+ // ⇒ 서버 항목 «전체»를 흉내 내지 말고 ***더할 필드 한 줄***만 준다.
390
+ `Add this field to the ${JSON.stringify(serverId)} entry of mcp.servers in your elanous config: ` +
391
+ `"authorizedTools": [${tools.slice(0, 3).map((t) => JSON.stringify(t.name)).join(', ')}]`,
392
+ );
393
+ } else if (grantedCount < tools.length) {
394
+ logger.warn(
395
+ `[nexus] mcp-client ${JSON.stringify(serverId)}: ${tools.length} tool(s) registered but only ${grantedCount} authorized — unlisted tool calls will be denied.`,
396
+ );
397
+ }
398
+ debug.log('mcp.authorization', 'boot-summary', {
399
+ serverId,
400
+ toolCount: tools.length,
401
+ grantedCount,
402
+ });
403
+ logger.info(
404
+ `[nexus] mcp-client connected: ${serverId} (${tools.length} tool${tools.length === 1 ? '' : 's'}` +
405
+ `${grantedCount === tools.length ? '' : ` · ${grantedCount} authorized`})`,
406
+ );
407
+ };
408
+
255
409
  if (opts.servers.some(spec => spec.transport === 'stdio') && !opts.createClient) {
256
410
  try { syncInstalledPluginNodes(elanousStateRoot()); }
257
411
  catch (error) { debug.log('graph.kinds', 'installed-sync-failed', { reason: String(error) }); }
@@ -280,6 +434,45 @@ export async function registerMcpClients(
280
434
  }
281
435
  };
282
436
  }
437
+ const announced = lazyToolsFor(spec.id);
438
+ if (lazy && !announced) logLazyBoot(spec.id, 'no-index');
439
+ if (announced) {
440
+ // ⭐ 지연 기동 — 여기서 자식은 «하나도» 안 뜬다. 허가는 즉시 경로와
441
+ // 같은 관문에 미리 넣고, 등록하는 툴은 지난 부팅이 알린 목록 그대로다.
442
+ for (const toolName of spec.authorizedTools ?? []) {
443
+ authorizer.grant({ serverId: spec.id, toolName });
444
+ }
445
+ const deferred = new DeferredMcpClient(client, async () => {
446
+ await withTimeout(`mcp.${spec.id}.start`, () => client!.start(), serverHandshakeTimeoutMs, setTimeoutFn, clearTimeoutFn);
447
+ const live = await withTimeout(
448
+ `mcp.${spec.id}.listTools`,
449
+ () => client!.listTools(),
450
+ serverHandshakeTimeoutMs,
451
+ setTimeoutFn,
452
+ clearTimeoutFn,
453
+ );
454
+ // 이제 자식이 있다 — 리소스 경로·종료 스냅샷이 보는 clients 에 넣는다.
455
+ clients.push(client!);
456
+ recordToolIndex(spec.id, live);
457
+ logLazyBoot(spec.id, 'first-call', live.length);
458
+ }, spec.id);
459
+ deferredClients.push(deferred);
460
+ for (const t of announced) {
461
+ const runtime = createMcpProxyRuntime({
462
+ serverId: spec.id,
463
+ mcpTool: t,
464
+ client: deferred,
465
+ authorizer,
466
+ });
467
+ register(runtime);
468
+ registeredIds.push(runtime.id);
469
+ registered += 1;
470
+ }
471
+ perServer[spec.id] = { status: 'ready', toolCount: announced.length, deferred: true };
472
+ reportAuthorization(spec.id, announced);
473
+ logLazyBoot(spec.id, 'deferred', announced.length);
474
+ continue;
475
+ }
283
476
  await withTimeout(`mcp.${spec.id}.start`, () => client!.start(), serverHandshakeTimeoutMs, setTimeoutFn, clearTimeoutFn);
284
477
  const tools = await withTimeout(
285
478
  `mcp.${spec.id}.listTools`,
@@ -304,37 +497,14 @@ export async function registerMcpClients(
304
497
  }
305
498
  clients.push(client);
306
499
  perServer[spec.id] = { status: 'ready', toolCount: tools.length };
500
+ // 콜드 스타트(인덱스 없음) 1회 뒤에는 다음 부팅이 지연 기동할 수 있게 적어 둔다.
501
+ if (lazy) recordToolIndex(spec.id, tools);
307
502
  // ⛔⭐ **금지에는 «길»을 붙인다.** 허가 관문은 fail-closed 라 `authorizedTools` 를
308
503
  // 안 적은 서버의 툴은 «전부» 거부된다 — 그것이 의도지만, 조용하면 사용자는
309
504
  // ***「어제 되던 툴이 오늘 안 된다」***만 겪고 이유도 고치는 법도 모른다.
310
505
  // ⇒ 붙었는데 허가가 «하나도 없는» 서버는 이름을 대고 «무엇을 적어야 하는지»까지 말한다.
311
506
  // ⚠️ 부팅을 막지는 않는다 — 이 배선의 계약은 「한 서버가 실패해도 계속」이다.
312
- const grantedCount = tools.filter((t) => authorizer.isGranted(spec.id, t.name)).length;
313
- if (tools.length > 0 && grantedCount === 0) {
314
- logger.warn(
315
- // ⛔ 접두 «라벨»도 같은 문자열이다 — 본문만 이스케이프하면 개행이 여기로 샌다.
316
- `[nexus] mcp-client ${JSON.stringify(spec.id)}: ${tools.length} tool(s) registered but NONE authorized — every call will be denied. ` +
317
- // ⛔ 「복사해 붙일 수 있게」라고 말하려면 «붙일 수 있는 것»을 줘야 한다.
318
- // 초판은 `{"id":…, ..., "authorizedTools":[…]}` 를 줬는데 그 `...` 때문에
319
- // «유효한 JSON 이 아니었다» — 말과 산출이 어긋났다(리뷰가 잡음).
320
- // ⇒ 서버 항목 «전체»를 흉내 내지 말고 ***더할 필드 한 줄***만 준다.
321
- `Add this field to the ${JSON.stringify(spec.id)} entry of mcp.servers in your elanous config: ` +
322
- `"authorizedTools": [${tools.slice(0, 3).map((t) => JSON.stringify(t.name)).join(', ')}]`,
323
- );
324
- } else if (grantedCount < tools.length) {
325
- logger.warn(
326
- `[nexus] mcp-client ${JSON.stringify(spec.id)}: ${tools.length} tool(s) registered but only ${grantedCount} authorized — unlisted tool calls will be denied.`,
327
- );
328
- }
329
- debug.log('mcp.authorization', 'boot-summary', {
330
- serverId: spec.id,
331
- toolCount: tools.length,
332
- grantedCount,
333
- });
334
- logger.info(
335
- `[nexus] mcp-client connected: ${spec.id} (${tools.length} tool${tools.length === 1 ? '' : 's'}` +
336
- `${grantedCount === tools.length ? '' : ` · ${grantedCount} authorized`})`,
337
- );
507
+ reportAuthorization(spec.id, tools);
338
508
  } catch (err) {
339
509
  // ⛔⭐ **이 줄은 「방어적 no-op」이 아니다.** try 블록이 등록 «루프»까지 감싸므로,
340
510
  // 툴 3개 중 2개까지 `register()` 가 성공한 뒤 3번째가 던지면 ***이미 등록된 두 개가
@@ -381,6 +551,19 @@ export async function registerMcpClients(
381
551
  async shutdown() {
382
552
  // Snapshot + clear so a re-entrant call (e.g. SIGTERM races) is a no-op.
383
553
  const snapshot = clients.splice(0);
554
+ // 아직 «안 뜬» 지연 클라이언트도 여기서 내린다 — 기동 중이면 그 기동을
555
+ // 기다렸다가 내리므로 자식이 새지 않는다. 이미 뜬 것은 snapshot 이 맡는다.
556
+ const pendingDeferred = deferredClients.splice(0).filter((d) => !d.spawned);
557
+ // ⭐ 자식에게 SIGTERM 을 «먼저» 보낸다 — 유예(지연 기동 기본 2500ms)가 지나면
558
+ // SIGKILL 이라 종료 전체가 3초 안에 끝난다. 등록·허가 걷기는 그 뒤.
559
+ const teardown = [
560
+ ...snapshot.map((c) =>
561
+ c.dispose().catch(() => {
562
+ /* dispose() is best-effort; swallow */
563
+ }),
564
+ ),
565
+ ...pendingDeferred.map((d) => d.dispose().catch(() => { /* 아직 안 뜬 클라이언트 */ })),
566
+ ];
384
567
  for (const spec of opts.servers) authorizer.revokeServer(spec.id);
385
568
  // ⭐ 등록도 «되돌린다». 데몬 종료 때는 어차피 프로세스가 죽으니 무해하고,
386
569
  // 재장전 때는 ***이 줄이 없으면 다음 등록이 전부 id 충돌로 죽는다***.
@@ -389,18 +572,60 @@ export async function registerMcpClients(
389
572
  for (const id of ids) {
390
573
  try { unregister(id); } catch { /* best-effort */ }
391
574
  }
392
- await Promise.all(
393
- snapshot.map((c) =>
394
- c.dispose().catch(() => {
395
- /* dispose() is best-effort; swallow */
396
- }),
397
- ),
398
- );
575
+ await Promise.all(teardown);
399
576
  injectedValuesByServer.clear();
400
577
  },
578
+ terminateChildrenSync(): number {
579
+ let signalled = 0;
580
+ for (const child of [...spawnedChildren]) {
581
+ spawnedChildren.delete(child);
582
+ try {
583
+ if (child.exitCode === null && child.signalCode === null && child.kill('SIGTERM')) signalled += 1;
584
+ } catch {
585
+ /* 이미 죽은 자식 — 쏠 대상이 없다 */
586
+ }
587
+ }
588
+ return signalled;
589
+ },
590
+ };
591
+ }
592
+
593
+ /** 기본 툴 인덱스 저장소 — `<state>/mcp-tool-index.json`.
594
+ * ⚠️ 읽기·쓰기 모두 «부팅을 막지 않는다»: 깨진 JSON 은 빈 인덱스(콜드 스타트)로
595
+ * 떨어지고, 쓰기 실패는 debug 한 줄만 남긴다. */
596
+ export function defaultMcpToolIndexStore(root: string = elanousStateRoot()): McpToolIndexStore {
597
+ const file = join(root, MCP_TOOL_INDEX_FILENAME);
598
+ return {
599
+ read(): McpToolIndex {
600
+ try {
601
+ const parsed: unknown = JSON.parse(readFileSync(file, 'utf8'));
602
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return {};
603
+ const index: McpToolIndex = {};
604
+ for (const [serverId, tools] of Object.entries(parsed as Record<string, unknown>)) {
605
+ if (!Array.isArray(tools)) continue;
606
+ const kept = tools.filter((tool): tool is McpTool =>
607
+ !!tool && typeof tool === 'object' && typeof (tool as { name?: unknown }).name === 'string');
608
+ if (kept.length > 0) index[serverId] = kept;
609
+ }
610
+ return index;
611
+ } catch { return {}; }
612
+ },
613
+ write(index: McpToolIndex): void {
614
+ try {
615
+ mkdirSync(root, { recursive: true });
616
+ writeFileSync(file, `${JSON.stringify(index, null, 2)}\n`, 'utf8');
617
+ } catch (error) {
618
+ try { debug.log('mcp.client', 'tool-index-write-failed', { reason: String(error) }); }
619
+ catch { /* logger must never throw the boot */ }
620
+ }
621
+ },
401
622
  };
402
623
  }
403
624
 
625
+ function readToolIndex(store: McpToolIndexStore): McpToolIndex {
626
+ try { return store.read(); } catch { return {}; }
627
+ }
628
+
404
629
  function defaultLogger(): McpBootLogger {
405
630
  return {
406
631
  info: (line) => console.info(line),
@@ -1,7 +1,7 @@
1
1
  import type { WizardIO } from '../../onboarding.js';
2
2
  import type { SetupCheckResult } from '../setup-status.js';
3
3
  import type { TailscaleProbe } from './tailscale-probe.js';
4
- import { createManagementStarterContract } from '../../persona/presets.js';
4
+ import { clonePreset, createManagementStarterContract, type PersonaPreset, type PersonaWriteOptions, type PersonaWriteResult } from '../../persona/presets.js';
5
5
 
6
6
  export interface FirstBootWizardDeps {
7
7
  io: WizardIO;
@@ -39,9 +39,12 @@ export type FirstBootResult =
39
39
 
40
40
  /** 직업 질문 답의 정규화 — «1»·«경영»·«management» 는 경영,
41
41
  * 나머지(빈 답 포함)는 일반(현재 첫 실행 동작 유지). */
42
- export function normalizeOccupationChoice(input: string): 'management' | 'general' {
42
+ export type OccupationChoice = 'management' | 'marketing' | 'general';
43
+
44
+ export function normalizeOccupationChoice(input: string): OccupationChoice {
43
45
  const v = input.trim().toLowerCase();
44
46
  if (v === '1' || v === '경영' || v === 'management') return 'management';
47
+ if (v === '3' || v === '마케팅' || v === 'marketing') return 'marketing';
45
48
  return 'general';
46
49
  }
47
50
 
@@ -108,6 +111,45 @@ function printPwaSetupBanner(deps: FirstBootWizardDeps): void {
108
111
  deps.io.print('');
109
112
  }
110
113
 
114
+ /** 0.2.35 PERSONA-STARTER-FU — 첫 실행 «마케팅» 스타터 계약 원본. 경계 계약상
115
+ * 완료 경계 코드(first-boot-wizard.ts) 안에서 기존 clonePreset 파이프라인으로
116
+ * persona store 에 정확히 한 장 쓴다. */
117
+ const MARKETING_STARTER_PRESET: PersonaPreset = {
118
+ personaId: 'starter-marketing',
119
+ displayName: '마케팅 스타터',
120
+ names: ['마케팅 스타터', '마케팅', 'starter-marketing'],
121
+ role: '마케팅 파트너',
122
+ title: '첫 실행 스타터',
123
+ oneLine: '고객·메시지·채널을 같이 세우는 짝.',
124
+ voice: {
125
+ rule: '짧고 단정하게 — 고객 말로 먼저, 근거 한 줄.',
126
+ examples: [
127
+ '이번 주 메시지는 하나로 좁힙니다 — 첫 화면에서 5초 안에 남는 문장.',
128
+ '그 채널은 도달 근거가 부족합니다 — 가장 싼 실험부터 하시죠.',
129
+ ],
130
+ },
131
+ tasks: [
132
+ { when: '아침 루프', what: '채널 반응·미결 발행물을 한 화면에 모아 첫 판단을 준다' },
133
+ { when: '메시지가 갈릴 때', what: '후보 문장을 셋으로 좁혀 고객·채널·되돌림 수단을 나란히 놓는다' },
134
+ { when: '주간 정산', what: '지난 발행과 실제 반응을 대조해 다음 메시지 기준을 고친다' },
135
+ ],
136
+ tools: [],
137
+ firstQuestions: [
138
+ '지금 가장 급한 고객 메시지는 무엇인가요?',
139
+ '이번 주에 꼭 내보낼 채널이 있나요?',
140
+ ],
141
+ doesNot: [
142
+ '고객 개인정보를 외부에 전송하지 않는다',
143
+ '합의되지 않은 광고·발행을 대신 실행하지 않는다',
144
+ ],
145
+ forWhom: '처음 elanous 를 여는 마케터 — 고객·메시지·채널을 함께 시작하려는 사람.',
146
+ };
147
+
148
+ /** 첫 실행 «마케팅» 선택이 부르는 유일한 제작 입구 — 스타터 계약 한 장을 persona store 에 쓴다. */
149
+ export function createMarketingStarterContract(opts: PersonaWriteOptions = {}): PersonaWriteResult {
150
+ return clonePreset(MARKETING_STARTER_PRESET, MARKETING_STARTER_PRESET.displayName, opts);
151
+ }
152
+
111
153
  /** 0.2.29 PERSONA-STARTER — 직업 질문. «경영»이면 경영 스타터 계약 한 장을
112
154
  * 만들고, 일반이면 계약 없이 현재 흐름 그대로. 계약 생성이 실패해도
113
155
  * wizard 결과는 completed 로 유지한다(fail-soft). */
@@ -120,20 +162,26 @@ async function askOccupationAndCreateStarter(
120
162
  io.print('');
121
163
  io.print(' 어떤 일을 하세요? 고르면 스타터 계약 한 장을 만듭니다.');
122
164
  io.print(' 1) 경영 — 방향·판단·운영을 함께 세우는 경영 스타터');
165
+ io.print(' 3) 마케팅 — 고객·메시지·채널을 함께 세우는 마케팅 스타터');
123
166
  io.print(' 2) 일반 — 지금처럼 계속 (스타터 계약 없이)');
124
167
  let answer: string;
125
168
  try {
126
- answer = await io.ask(' 선택 (1/2 · Enter=일반): ');
169
+ answer = await io.ask(' 선택 (1/2/3 · Enter=일반): ');
127
170
  } catch (err) {
128
171
  out.error(`first-boot wizard: occupation question failed: ${(err as Error).message}`);
129
172
  return undefined;
130
173
  }
131
- if (normalizeOccupationChoice(answer) !== 'management') return undefined;
174
+ const choice = normalizeOccupationChoice(answer);
175
+ if (choice === 'general') return undefined;
132
176
  try {
133
- const written = createManagementStarterContract(
134
- deps.starterContractDir ? { dir: deps.starterContractDir } : {},
135
- );
136
- io.print(` ✓ 경영 스타터 계약이 만들어졌습니다: ${written.path}`);
177
+ const written = choice === 'management'
178
+ ? createManagementStarterContract(
179
+ deps.starterContractDir ? { dir: deps.starterContractDir } : {},
180
+ )
181
+ : createMarketingStarterContract(
182
+ deps.starterContractDir ? { dir: deps.starterContractDir } : {},
183
+ );
184
+ io.print(` ✓ ${choice === 'management' ? '경영' : '마케팅'} 스타터 계약이 만들어졌습니다: ${written.path}`);
137
185
  return { personaId: written.personaId, displayName: written.displayName, path: written.path };
138
186
  } catch (err) {
139
187
  out.error(`first-boot wizard: starter contract failed: ${(err as Error).message}`);
@@ -458,6 +458,10 @@ export async function loadFreshCodexAuthState(
458
458
  });
459
459
  return state;
460
460
  }
461
+ if (process.env.ELANOUS_REMOTE_CODEX_ACCESS_ONLY === '1') {
462
+ observeCodexAuth('no-credential', { storeKey: account.storeKey, mirrorPath: mirrorPath ?? null, reason: 'access-only-expiring' });
463
+ return null;
464
+ }
461
465
  observeCodexAuth('refresh-start', {
462
466
  storeKey: account.storeKey, remainingSeconds: remainingSeconds(state),
463
467
  mirrorPath: mirrorPath ?? null, bufferMs: CODEX_REFRESH_BUFFER_MS,
@@ -602,6 +606,9 @@ export async function refreshCodexAccountHome(
602
606
  now?: () => number;
603
607
  } = {},
604
608
  ): Promise<CodexAccountRefreshResult> {
609
+ if (process.env.ELANOUS_REMOTE_CODEX_ACCESS_ONLY === '1') {
610
+ return { ok: false, kind: 'no-tokens', message: '원격 access 미러는 refresh 권한이 없다' };
611
+ }
605
612
  // ⛔ The CEO's default account (~/.codex) is shared with the official CLI — refreshing it here
606
613
  // rotates the refresh token out from under that CLI. Named accounts only.
607
614
  if (name === DEFAULT_CODEX_ACCOUNT) {
@@ -1,6 +1,7 @@
1
1
  import * as readline from 'node:readline/promises';
2
2
  import { detectProviders, type DetectedProvider } from '../llm/provider-detect.js';
3
3
  import { debug } from '../debug/log.js';
4
+ import { detectLocale, type Locale } from '../expression/locale.js';
4
5
  import { unattendedNextStepLine } from './entry-hints.js';
5
6
  import { resolveProviderCredential } from '../llm/provider-credentials.js';
6
7
  import {
@@ -13,6 +14,8 @@ export interface FirstRunDeps {
13
14
  path?: string;
14
15
  detectProviders?: () => Promise<DetectedProvider[]>;
15
16
  isTTY?: boolean;
17
+ /** Locale for user-facing wording; defaults to the shared ambient decision (detectLocale). */
18
+ locale?: Locale;
16
19
  chooseProvider?: (detected: readonly LLMProviderName[]) => Promise<LLMProviderName | null>;
17
20
  print?: (message: string) => void;
18
21
  saveConfig?: (config: UserConfig, path: string) => void;
@@ -44,12 +47,21 @@ export function parseMenuAnswer(answer: string, choices: readonly LLMProviderNam
44
47
  return provider !== undefined ? { kind: 'chosen', provider } : { kind: 'miss' };
45
48
  }
46
49
 
50
+ /**
51
+ * The fixed choice line of the first-run menu (`1 Codex, 2 Grok, 3 Claude`).
52
+ * Single source of the wording: the prompt below renders it, and the ux-sim
53
+ * first-run device asserts against it, so a wording change cannot drift apart.
54
+ */
55
+ export function formatProviderMenu(choices: readonly LLMProviderName[]): string {
56
+ return choices.map((name, i) => `${i + 1} ${CHOICE_LABEL[name] ?? name}`).join(', ');
57
+ }
58
+
47
59
  export async function promptProviderMenu(
48
60
  ask: (prompt: string) => Promise<string>,
49
61
  detected: readonly LLMProviderName[] = [],
50
62
  ): Promise<LLMProviderName | null> {
51
63
  const choices = orderProviderChoices(detected);
52
- const menu = choices.map((name, i) => `${i + 1} ${CHOICE_LABEL[name] ?? name}`).join(', ');
64
+ const menu = formatProviderMenu(choices);
53
65
  for (;;) {
54
66
  const parsed = parseMenuAnswer(await ask(`Choose LLM (${menu}; Enter to cancel): `), choices);
55
67
  if (parsed.kind === 'chosen') return parsed.provider;
@@ -66,7 +78,23 @@ async function chooseProvider(detected: readonly LLMProviderName[] = []): Promis
66
78
  }
67
79
  }
68
80
 
69
- const detectionLabel = (provider: string) => `${provider === 'openai-codex' ? 'codex' : provider} 구독`;
81
+ /** User-facing first-run fallback wording, routed by the shared locale decision (detectLocale). */
82
+ const FIRST_RUN_TEXT = {
83
+ ko: {
84
+ detectedPrefix: '감지: ',
85
+ subscription: ' 구독',
86
+ needsLlm: 'eln setup llm 으로 고르세요',
87
+ claudeNoPath: 'claude-code 구독은 구독으로 쓸 수 있는 경로가 없어 자동 선택하지 않음',
88
+ multipleDetected: '둘 이상 감지되어 고르세요',
89
+ },
90
+ en: {
91
+ detectedPrefix: 'detected: ',
92
+ subscription: ' subscription',
93
+ needsLlm: 'pick a provider via eln setup llm',
94
+ claudeNoPath: 'claude-code subscription has no usable path in elanous; not auto-selecting',
95
+ multipleDetected: 'more than one detected; pick one',
96
+ },
97
+ } as const;
70
98
 
71
99
  export async function runFirstRun(deps: FirstRunDeps = {}): Promise<{
72
100
  outcome: 'ready' | 'needs-llm' | 'cancelled'; provider?: string; inputs: number;
@@ -74,6 +102,9 @@ export async function runFirstRun(deps: FirstRunDeps = {}): Promise<{
74
102
  const path = deps.path ?? userConfigPath();
75
103
  const cfg = deps.config ?? getUserConfig(path);
76
104
  const print = deps.print ?? console.log;
105
+ const text = FIRST_RUN_TEXT[(deps.locale ?? detectLocale()) === 'en' ? 'en' : 'ko'];
106
+ const detectionLabel = (provider: string) =>
107
+ `${provider === 'openai-codex' ? 'codex' : provider}${text.subscription}`;
77
108
  let detected: DetectedProvider[] = [];
78
109
  try { detected = await (deps.detectProviders ?? detectProviders)(); }
79
110
  catch { /* Detection is advisory; a TTY can still choose. */ }
@@ -93,9 +124,9 @@ export async function runFirstRun(deps: FirstRunDeps = {}): Promise<{
93
124
  // claude-code is detected but has no subscription path in elanous: mapping it to the 'anthropic'
94
125
  // API-key provider would save a provider whose first call fails for a subscription-only user.
95
126
  const usable = SUBSCRIPTION_PRIORITY.filter((name) => providers.includes(name));
96
- const detectionLine = (outcome: string) => `감지: ${providers.map(detectionLabel).join(' · ')} → ${outcome}`;
127
+ const detectionLine = (outcome: string) => `${text.detectedPrefix}${providers.map(detectionLabel).join(' · ')} → ${outcome}`;
97
128
  const needsLlm = (inputs: number, extra: string[] = []) => {
98
- print('eln setup llm 으로 고르세요');
129
+ print(text.needsLlm);
99
130
  for (const line of extra) print(line);
100
131
  observe('needs-llm', inputs);
101
132
  return { outcome: 'needs-llm' as const, inputs };
@@ -106,8 +137,8 @@ export async function runFirstRun(deps: FirstRunDeps = {}): Promise<{
106
137
  if (!provider) {
107
138
  if (providers.length > 0) {
108
139
  print(detectionLine(usable.length === 0
109
- ? 'claude-code 구독은 구독으로 쓸 수 있는 경로가 없어 자동 선택하지 않음'
110
- : '둘 이상 감지되어 고르세요'));
140
+ ? text.claudeNoPath
141
+ : text.multipleDetected));
111
142
  }
112
143
  if ((deps.isTTY ?? process.stdin.isTTY) !== true) {
113
144
  // FIRST-CHAT-NONTTY — bare `elanous` with no TTY gets the same one-line next step as the other entrances.