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
@@ -1316,6 +1316,129 @@ export function typecheckDispatchFlags(flags: GateRemoteFlags, env: NodeJS.Proce
1316
1316
  ? { ...flags, remote: 'node-b' } : flags;
1317
1317
  }
1318
1318
 
1319
+ // ── WSL-GATE-ENV (0.2.36) — base 환경 해석 · 원격 push 실패 «원인» 보고 ─────────────────────────
1320
+ // 🩸 wsl·node-c 가 «같은 head·base» 를 쟀는데 introduced·preexisting 이 갈렸고, 남는 출력은
1321
+ // `push-failed rc=128: …` 한 줄이었다. 그 한 줄로는 «미러 쓰기 권한» 인지 «base 가 달랐다» 인지
1322
+ // 읽을 수 없었고, base env 가 원격에 무엇으로 전달됐는지도 어디에도 찍히지 않았다.
1323
+ // ⇒ (1) 원격 디스패치마다 base env 를 `ref@sha` 로 «풀어서» 한 줄 찍는다 — 두 호스트가 같은 줄을
1324
+ // 찍는 것이 교차 측정의 전제다. (2) push 실패는 rc·문면으로 «권한/자격증명» 과 «그 밖»을 가르고
1325
+ // 처방을 같이 찍는다. (3) base ref 를 이 트리에서 풀 수 없으면 원격을 «띄우지 않고» 멈춘다 —
1326
+ // 다른 base 로 잰 판정을 두 호스트가 «같다»고 믿게 만든 것이 이 칸의 사고였다.
1327
+ // ⛔ 로컬 경로(--local · Pod · CI)의 출력·원장 형식은 건드리지 않는다 — 아래 줄은 원격 디스패치 안에서만 나온다.
1328
+ const BASE_ENV_KEYS = ['NODE_OPTIONS', 'TSC_BASE_REF', 'TSC_HEAP_MB'] as const;
1329
+
1330
+ export interface RemoteBaseEnv {
1331
+ /** 원격으로 push 해 sha 로 받아야 하는 ref. TSC_BASE_REF 가 없으면 비어 있다(merge-base 는 HEAD 의 조상이라 HEAD 와 함께 간다). */
1332
+ refs: string[];
1333
+ /** 무엇을 base 로 골랐나 — TSC_BASE_REF 의 ref 이름, 없으면 `merge-base(origin/main)`. */
1334
+ baseLabel: string;
1335
+ /** base 를 이 트리에서 푼 sha — 두 호스트가 같은 값을 찍어야 교차 측정이 성립한다. */
1336
+ baseSha?: string;
1337
+ /** 원격 명령에 전달하는 env 키들. */
1338
+ keys: string[];
1339
+ /** 원격 명령 앞에 붙일 `KEY=VALUE`. TSC_BASE_REF 는 «항상» 이 트리에서 고정한 sha 로 넘긴다
1340
+ * (ref 는 dispatch 가 push 한 sha · 없으면 merge-base sha) — 원격이 제 origin/main 으로 다시 풀지 않는다. */
1341
+ forward: (sha: (ref: string) => string) => string[];
1342
+ /** 이 트리에서 base 를 sha 로 고정할 수 없을 때의 사유 — 있으면 원격 디스패치를 멈춘다. */
1343
+ failure?: string;
1344
+ }
1345
+
1346
+ const firstErrorLine = (thrown: unknown): string => (thrown instanceof Error ? thrown.message : String(thrown)).split('\n')[0].trim();
1347
+
1348
+ export function remoteBaseEnv(
1349
+ env: NodeJS.ProcessEnv,
1350
+ resolve: (ref: string) => string = (ref) => execFileSync('git', ['rev-parse', '--verify', '--quiet', ref], { encoding: 'utf8' }).trim(),
1351
+ mergeBase: () => string = () => execFileSync('git', ['merge-base', 'HEAD', 'origin/main'], { encoding: 'utf8' }).trim(),
1352
+ ): RemoteBaseEnv {
1353
+ const baseRef = env.TSC_BASE_REF;
1354
+ let baseSha: string | undefined;
1355
+ let failure: string | undefined;
1356
+ if (baseRef) {
1357
+ try { baseSha = resolve(baseRef) || undefined; } catch (thrown) {
1358
+ failure = `TSC_BASE_REF=${baseRef} 를 이 트리에서 sha 로 풀 수 없다 (${firstErrorLine(thrown) || 'git rev-parse 실패'})`;
1359
+ }
1360
+ if (!baseSha && !failure) failure = `TSC_BASE_REF=${baseRef} 를 이 트리에서 sha 로 풀 수 없다 (git rev-parse 빈 출력)`;
1361
+ } else {
1362
+ // TSC_BASE_REF 가 없으면 원격 쪽 기본(merge-base(origin/main))을 «여기서» 미리 풀어 sha 로 못 박는다 —
1363
+ // 원격 미러의 origin/main 은 이 트리와 다를 수 있다(같은 head 인데 base 가 갈린 이 칸의 사고 · 리뷰 r1 must-fix).
1364
+ try { baseSha = mergeBase() || undefined; } catch (thrown) {
1365
+ failure = `merge-base(HEAD, origin/main) 을 이 트리에서 풀 수 없다 (${firstErrorLine(thrown) || 'git merge-base 실패'})`;
1366
+ }
1367
+ if (!baseSha && !failure) failure = 'merge-base(HEAD, origin/main) 을 이 트리에서 풀 수 없다 (git merge-base 빈 출력)';
1368
+ }
1369
+ const passKeys = BASE_ENV_KEYS.filter((key) => key !== 'TSC_BASE_REF' && env[key]);
1370
+ return {
1371
+ refs: baseRef ? [baseRef] : [],
1372
+ baseLabel: baseRef || 'merge-base(origin/main)',
1373
+ baseSha,
1374
+ keys: ['TSC_BASE_REF', ...passKeys],
1375
+ forward: (sha) => [`TSC_BASE_REF=${baseRef ? sha(baseRef) : baseSha}`, ...passKeys.map((key) => `${key}=${env[key]}`)],
1376
+ failure,
1377
+ };
1378
+ }
1379
+
1380
+ /** 두 호스트가 같은 head·base 를 쟀는지 «눈으로» 비교할 수 있는 한 줄. 호스트 이름만 다르다. */
1381
+ export function describeRemoteBaseEnv(env: RemoteBaseEnv, host: string): string {
1382
+ const base = `${env.baseLabel}@${env.baseSha ?? '미해석'}`;
1383
+ return `[tsc-gate] base env [${host}] — base=${base} · refs=${env.refs.length} · forward=${env.keys.join(',') || '없음'}`;
1384
+ }
1385
+
1386
+ export type RemoteInfraCause = 'base-env' | 'push-permission' | 'push-failed' | 'other';
1387
+
1388
+ export interface RemoteDiagnosis { cause: RemoteInfraCause; message: string; hints: string[] }
1389
+
1390
+ /** push 거부 문면에서 «미러 쓰기 권한·자격증명» 을 가리키는 신호. */
1391
+ export const PUSH_PERMISSION_SIGNAL = /permission denied|publickey|could not read (?:Username|Password)|authentication failed|host key verification failed|access denied|terminal prompts disabled/i;
1392
+
1393
+ export const BASE_ENV_HINTS = [
1394
+ 'base 는 두 호스트가 «같은 커밋» 이어야 한다 — 위 base= 줄에서 @뒤 sha 가 같은지 먼저 본다.',
1395
+ 'TSC_BASE_REF 는 양쪽 트리에 존재하는 ref(또는 sha)로 준다 — 한쪽에만 있는 브랜치면 introduced 가 갈린다.',
1396
+ ];
1397
+
1398
+ export function baseEnvDiagnosis(env: RemoteBaseEnv, host: string): RemoteDiagnosis | undefined {
1399
+ if (!env.failure) return undefined;
1400
+ return { cause: 'base-env', message: `${env.failure} — ${host} 를 띄우지 않는다`, hints: BASE_ENV_HINTS };
1401
+ }
1402
+
1403
+ export function formatRemoteDiagnosis(diagnosis: RemoteDiagnosis): string[] {
1404
+ return [
1405
+ `[tsc-gate] ⛔ 원격 판정 실패 원인 [${diagnosis.cause}] — ${diagnosis.message}`,
1406
+ ...diagnosis.hints.map((hint) => `[tsc-gate] ${hint}`),
1407
+ ];
1408
+ }
1409
+
1410
+ export function diagnoseRemoteOutcome(
1411
+ outcome: { kind: 'ran' | 'busy' | 'infra'; reason?: string },
1412
+ host: string,
1413
+ env: RemoteBaseEnv,
1414
+ ): RemoteDiagnosis | undefined {
1415
+ const base = baseEnvDiagnosis(env, host);
1416
+ if (base) return base;
1417
+ if (outcome.kind !== 'infra') return undefined;
1418
+ const reason = outcome.reason ?? '';
1419
+ const push = /^push-failed rc=(\d+)/.exec(reason);
1420
+ if (!push) return {
1421
+ cause: 'other',
1422
+ message: `원격 판정 인프라 실패 — ${reason}`,
1423
+ hints: [`같은 head·base 인데 이 호스트에서만 실패하면 위 base env 줄을 호스트끼리 비교한다.`],
1424
+ };
1425
+ const rc = Number(push[1]);
1426
+ if (rc === 128 && PUSH_PERMISSION_SIGNAL.test(reason)) return {
1427
+ cause: 'push-permission',
1428
+ message: `원격 push 거부 rc=128 — ${host} 미러에 쓰기 권한/자격증명이 없다`,
1429
+ hints: [
1430
+ `호스트 접근부터 확인: ssh -o BatchMode=yes ${host} true (rc=0 이어야 한다 — 아니면 키·호스트 항목 문제다)`,
1431
+ `미러 쓰기 확인: ssh ${host} -- 'test -w <mirror>.git' — 권한이 없으면 ELANOUS_GATE_REMOTE_MIRROR 로 쓰기 가능한 미러를 준다`,
1432
+ 'push 는 자격증명이 없으면 «터미널 프롬프트 없이» 죽는다 — 대화형 ssh 로 한 번 손으로 push 해 rc 를 본다.',
1433
+ ],
1434
+ };
1435
+ return {
1436
+ cause: 'push-failed',
1437
+ message: `원격 push 실패 rc=${rc} — ${host}`,
1438
+ hints: [`push 출력: ${reason}`, '미러 경로·디스크 여유를 확인하고, 반복되면 같은 트리에서 손으로 push 해 원문을 남긴다.'],
1439
+ };
1440
+ }
1441
+
1319
1442
  if (import.meta.main) void (async () => {
1320
1443
  // GATE-REMOTE (10-06): the only accepted arguments are the dispatch flags `--remote [host]` / `--local` — they choose
1321
1444
  // «where» the same commit is measured, never «what» (the base stays merge-base(origin/main) on both sides).
@@ -1333,15 +1456,26 @@ if (import.meta.main) void (async () => {
1333
1456
  const repo = sh('git rev-parse --show-toplevel').trim();
1334
1457
  const onMbp = forbidFullTypecheckOnLocal(process.env, hostname(), repo);
1335
1458
  const dispatchFlags = typecheckDispatchFlags(flags, process.env, hostname(), repo);
1336
- const baseRef = process.env.TSC_BASE_REF;
1337
- const passEnv = (sha: (ref: string) => string) => (['NODE_OPTIONS', 'TSC_BASE_REF', 'TSC_HEAP_MB'] as const).filter((key) => process.env[key])
1338
- .map((key) => `${key}=${key === 'TSC_BASE_REF' && baseRef !== 'origin/main' ? sha(baseRef!) : process.env[key]}`);
1459
+ const baseEnv = remoteBaseEnv(process.env);
1460
+ // 원격만 재는 자리에서 base ref 를 «이 트리에서» 못 풀면, 두 호스트가 «다른 base» 로 잰 판정을
1461
+ // «같은 답»처럼 찍게 된다 — 그래서 띄우지 않고 멈춘다(원인과 처방을 남긴다). --local 은 그대로 간다.
1462
+ if (baseEnv.failure && dispatchFlags.remote !== undefined && !flags.local) {
1463
+ for (const line of formatRemoteDiagnosis(baseEnvDiagnosis(baseEnv, dispatchFlags.remote === true ? '기본 원격' : dispatchFlags.remote)!)) console.error(line);
1464
+ console.error('[tsc-gate] ⇒ 원격을 띄우지 않는다. base 를 양쪽 호스트가 «같이» 푸는 ref/sha 로 고친 뒤 다시 돌려라.');
1465
+ process.exit(2);
1466
+ }
1339
1467
  // exitCode, not exit(): piped stdout/stderr drain before the process ends.
1340
1468
  process.exitCode = await dispatchHeavyCheck({
1341
1469
  tool: 'ci-typecheck-changed', repo, flags: dispatchFlags, explicitRemoteOnly: dispatchFlags.remote !== undefined,
1342
1470
  stableCheckout: true, installPwa: true,
1343
- remoteArgv: (sha) => { const vars = passEnv(sha); return [...(vars.length ? ['env', ...vars] : []), 'bun', 'run', 'scripts/ci-typecheck-changed.ts', '--local']; },
1344
- refs: baseRef ? [baseRef] : [],
1471
+ remoteArgv: (sha) => { const vars = baseEnv.forward(sha); return [...(vars.length ? ['env', ...vars] : []), 'bun', 'run', 'scripts/ci-typecheck-changed.ts', '--local']; },
1472
+ refs: baseEnv.refs,
1473
+ // 원격 판정이 «무엇으로» 났는지 호스트마다 같은 문면으로 남긴다 — 교차 측정의 대조 줄.
1474
+ onRemoteOutcome: (outcome, host) => {
1475
+ console.error(describeRemoteBaseEnv(baseEnv, host));
1476
+ const diagnosis = diagnoseRemoteOutcome(outcome, host, baseEnv);
1477
+ if (diagnosis) for (const line of formatRemoteDiagnosis(diagnosis)) console.error(line);
1478
+ },
1345
1479
  runLocal: () => { runGate({ forbidFullLocal: onMbp }); return 0; },
1346
1480
  });
1347
1481
  })();
@@ -21,9 +21,17 @@ export interface RolePack {
21
21
 
22
22
  const KNOWHOW_PATH = 'docs/roles/OP/KNOWHOW.md';
23
23
 
24
+ /**
25
+ * 카드 제목 문법은 src/seat-loop/knowhow-lint.ts 의 CARD_HEADING 과 같아야 한다.
26
+ * 다르면 린트가 카드로 못 본 제목이 자를 때 조용히 사라지거나, 번호만 잘려 엉뚱한 아이디로 제외 기록에 남는다.
27
+ */
28
+ const CARD_HEADING = /^[ \t]{0,3}##\s+(K-[A-Za-z]+(?:-[A-Za-z]{1,4})?-\d+)(?=$|\s|:|—)(.*)$/u;
29
+ const CARD_HEADING_LIKE = /^[ \t]{0,3}##\s*(K-[^\s:]*)/iu;
30
+ const SECTION_HEADING = /^[ \t]{0,3}##\s/u;
31
+
24
32
  /**
25
33
  * KNOWHOW.md 를 `##` 제목 단위 카드로 자른다(코드 울타리 안은 본문으로 본다).
26
- * 유효한 `## K-<role>-<number>` 제목을 가진 카드만 반환한다.
34
+ * 린트 문법을 지킨 `## K-<role>-<number>` 제목만 카드로 반환하고, 카드처럼 보이지만 문법을 벗어난 제목은 파일 단위 린트처럼 실패한다.
27
35
  */
28
36
  export function splitKnowhowCards(body: string): Array<{ id: string; title: string; text: string }> {
29
37
  const segments: Array<{ heading: string | null; lines: string[] }> = [{ heading: null, lines: [] }];
@@ -40,7 +48,7 @@ export function splitKnowhowCards(body: string): Array<{ id: string; title: stri
40
48
  segments.at(-1)!.lines.push(line);
41
49
  continue;
42
50
  }
43
- if (/^##\s/u.test(line)) {
51
+ if (SECTION_HEADING.test(line)) {
44
52
  segments.push({ heading: line, lines: [] });
45
53
  continue;
46
54
  }
@@ -49,9 +57,14 @@ export function splitKnowhowCards(body: string): Array<{ id: string; title: stri
49
57
  const cards: Array<{ id: string; title: string; text: string }> = [];
50
58
  for (const segment of segments) {
51
59
  if (!segment.heading) continue;
52
- const heading = segment.heading.match(/^##\s+(K-[A-Za-z]+-\d+)\s*(.*)$/u);
53
- if (!heading) continue;
54
- cards.push({ id: heading[1]!, title: heading[2]!.trim(), text: [segment.heading, ...segment.lines].join('\n') });
60
+ const heading = segment.heading.match(CARD_HEADING);
61
+ if (!heading) {
62
+ // 카드처럼 보이는 제목이 문법을 벗어나면 통과도 제외 기록도 불가능하다 — 조용히 빼지 않고 그 자리에서 실패한다.
63
+ const like = segment.heading.match(CARD_HEADING_LIKE);
64
+ if (like) throw new KnowhowLintError(KNOWHOW_PATH, like[1]!, '카드 제목 형식이 K-<자리>-<번호>를 벗어남');
65
+ continue;
66
+ }
67
+ cards.push({ id: heading[1]!, title: heading[2]!.replace(/^[:\s—]+/u, '').trim(), text: [segment.heading, ...segment.lines].join('\n') });
55
68
  }
56
69
  return cards;
57
70
  }
@@ -141,7 +154,7 @@ export function buildCoordRolePackManifest(role: RolePackRole, root = resolve(im
141
154
  // The pack body is inline. Source docs only contribute hashes, so an installed package without them still builds.
142
155
  const present = SOURCE_PATHS.filter((path) => existsSync(resolve(repo, path)));
143
156
  const missingSources = SOURCE_PATHS.filter((path) => !present.includes(path));
144
- const sources = present.map((path) => ({ path, sha256: sha256(readFileSync(resolve(repo, path), 'utf8')) }));
157
+ const sources: RolePack['sources'] = present.map((path) => ({ path, sha256: sha256(readFileSync(resolve(repo, path), 'utf8')) }));
145
158
  const knowhow = collectVerifiedKnowhow(repo);
146
159
  if (knowhow.fileBody !== null) sources.push({ path: KNOWHOW_PATH, sha256: sha256(knowhow.fileBody) });
147
160
  const packageJson = resolve(repo, 'package.json');
@@ -0,0 +1,416 @@
1
+ #!/usr/bin/env bun
2
+ // FIRST10-GATE (0.2.36 first measurable slice) — a local, one-record stopwatch for a
3
+ // fresh public install → first-run → first useful answer. UX runs this on an isolated
4
+ // Mac account against the exact PR head; the recorder never claims the full macOS card
5
+ // green by itself — a run without a real useful answer records `unmeasured`/`failed`,
6
+ // never `pass`.
7
+ //
8
+ // Wraps scripts/install.sh UNEDITED (--prefix/--source, ELANOUS_INSTALL_LANG, and
9
+ // ELANOUS_INSTALL_INTERACTIVE/--no-setup for non-interactive runs) and the installed
10
+ // CLI's non-TTY first-run path (src/onboarding/first-chat-gate.ts → runFirstRun,
11
+ // rc=2 on needs-llm). Phase boundaries are the runFirstRun outcomes
12
+ // ('ready'|'needs-llm'|'cancelled') and the onboarding.first-run/first-chat ledger events.
13
+ import { spawnSync } from 'node:child_process';
14
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
15
+ import { dirname, resolve } from 'node:path';
16
+
17
+ export interface IsolationInput {
18
+ home: string;
19
+ prefix: string;
20
+ stateDir: string;
21
+ realHome?: string;
22
+ xdgDataHome?: string;
23
+ }
24
+
25
+ export type IsolationResult = { ok: true } | { ok: false; reason: string };
26
+
27
+ const under = (path: string, root: string): boolean =>
28
+ path === root || path.startsWith(`${root}/`);
29
+
30
+ /** Refuse operating default paths; only an isolated HOME/PREFIX/ELANOUS_STATE_DIR may run. */
31
+ export function validateIsolation(input: IsolationInput): IsolationResult {
32
+ const realHome = resolve(input.realHome ?? process.env.FIRST10_GATE_REAL_HOME ?? process.env.HOME ?? '');
33
+ if (!realHome) return { ok: false, reason: '⛔ real HOME is unknown — pass --home for an isolated home' };
34
+ const home = resolve(input.home);
35
+ const prefix = resolve(input.prefix);
36
+ const stateDir = resolve(input.stateDir);
37
+ const xdgDataHome = input.xdgDataHome ?? process.env.XDG_DATA_HOME;
38
+ const operatingDefaultPrefixes = [
39
+ resolve(xdgDataHome ?? `${realHome}/.local/share`, 'elanous'),
40
+ resolve(`${realHome}/.local/share`, 'elanous'),
41
+ ];
42
+ // install.sh line 38: default PREFIX is ${XDG_DATA_HOME:-$HOME/.local/share}/elanous — refuse it.
43
+ if (operatingDefaultPrefixes.some((p) => prefix === p)) {
44
+ return { ok: false, reason: `⛔ refusing the operating default prefix ${prefix} — pass an isolated --prefix` };
45
+ }
46
+ if (home === realHome) return { ok: false, reason: `⛔ --home must be an isolated home, not the operating HOME ${realHome}` };
47
+ // install.sh lines 243-246: a PATH block pointing at a different installation prefix must
48
+ // never be silently reused — a prefix outside the isolated home is exactly that case.
49
+ if (!under(prefix, home)) {
50
+ return { ok: false, reason: `⛔ prefix ${prefix} is outside the isolated home ${home} (different installation prefix)` };
51
+ }
52
+ const operatingStateDirs = [resolve(`${realHome}/.elanous`), resolve(`${process.env.HOME ?? realHome}/.elanous`)];
53
+ // The operating prod state dir (~/.elanous) must never receive measurement writes.
54
+ if (operatingStateDirs.some((s) => stateDir === s)) {
55
+ return { ok: false, reason: `⛔ refusing the operating state dir ${stateDir} — pass an isolated --state-dir` };
56
+ }
57
+ if (!under(stateDir, home)) {
58
+ return { ok: false, reason: `⛔ state dir ${stateDir} is outside the isolated home ${home}` };
59
+ }
60
+ return { ok: true };
61
+ }
62
+
63
+ export type FirstRunOutcome = 'ready' | 'needs-llm' | 'cancelled' | 'unknown';
64
+
65
+ export type UsefulResult = 'measured' | 'unmeasured' | 'failed';
66
+
67
+ /** outcome ≠ ready → unmeasured/failed; ready alone is NOT a useful result without answer evidence. */
68
+ export function mapOutcomeToUsefulResult(
69
+ { outcome, answerEvidence }: { outcome: FirstRunOutcome; answerEvidence?: string | null },
70
+ ): UsefulResult {
71
+ if (answerEvidence && outcome === 'ready') return 'measured';
72
+ if (outcome === 'needs-llm') return 'failed';
73
+ return 'unmeasured';
74
+ }
75
+
76
+ const SECRET_PATTERNS: readonly RegExp[] = [
77
+ /\bsk-[A-Za-z0-9_-]{8,}\b/g,
78
+ /\bgh[pousr]_[A-Za-z0-9]{16,}\b/g,
79
+ /\bBearer\s+[A-Za-z0-9._-]+/gi,
80
+ /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{5,}\b/g,
81
+ /((?:api[_-]?key|token|secret|password|credential)["'=:\s]+)[^\s'"",}]+/gi,
82
+ ];
83
+
84
+ /** Secret hygiene (first-run.test.ts: tokens never appear in captured output). */
85
+ export function scrubSecrets(text: string): string {
86
+ let out = text;
87
+ for (const pattern of SECRET_PATTERNS) {
88
+ out = out.replace(pattern, (match, ...rest) => {
89
+ const prefix = typeof rest[0] === 'string' ? rest[0] : '';
90
+ return prefix ? `${prefix}[REDACTED]` : '[REDACTED]';
91
+ });
92
+ }
93
+ return out;
94
+ }
95
+
96
+ export interface PhaseRecord {
97
+ rc: number | null;
98
+ stdout: string;
99
+ stderr: string;
100
+ elapsedMonotonicMs: number;
101
+ }
102
+
103
+ export interface RecordSource {
104
+ kind: 'url' | 'tarball' | 'checkout';
105
+ ref: string;
106
+ tarballSha256?: string;
107
+ }
108
+
109
+ export interface RecorderRecord {
110
+ schema: 'first10-gate/1';
111
+ mode: 'dry' | 'real';
112
+ createdAt: string;
113
+ locale: 'ko' | 'en';
114
+ source: RecordSource;
115
+ cliVersion?: string;
116
+ installMetadata?: { version?: string; versionDir?: string; source?: string; installedAt?: string; commit?: string };
117
+ phases: { install: PhaseRecord; firstRun?: PhaseRecord };
118
+ errorCount: number;
119
+ /** 600-second decision: null when the phase timings are incomplete or the run is a dry rehearsal. */
120
+ decision600s: 'within' | 'over' | null;
121
+ missingFields: string[];
122
+ /** Evidence reference for the first usable answer (a real reply line, never a fixture). */
123
+ answerEvidence: string | null;
124
+ usefulResult: UsefulResult;
125
+ }
126
+
127
+ export interface BuildRecordInput {
128
+ locale: 'ko' | 'en';
129
+ source: RecordSource;
130
+ cliVersion?: string;
131
+ installMetadata?: RecorderRecord['installMetadata'];
132
+ phases: { install: PhaseRecord; firstRun?: PhaseRecord };
133
+ answerEvidence?: string | null;
134
+ createdAt?: string;
135
+ }
136
+
137
+ const ERROR_LINE = /⛔|error|failed|fatal|panic/i;
138
+
139
+ const countErrors = (phases: BuildRecordInput['phases']): number =>
140
+ Object.values(phases).reduce(
141
+ (n, phase) =>
142
+ n + (phase
143
+ ? phase.stderr.split('\n').filter((line) => ERROR_LINE.test(line)).length + (phase.rc !== 0 && phase.rc !== null ? 1 : 0)
144
+ : 0),
145
+ 0,
146
+ );
147
+
148
+ /** One JSON record: phase timings, rc/stdout/stderr, locale, source, CLI version, error count, 600s decision. */
149
+ export function buildRecord(input: BuildRecordInput): RecorderRecord {
150
+ const missingFields: string[] = [];
151
+ if (!input.cliVersion) missingFields.push('cliVersion');
152
+ if (!input.phases.firstRun) missingFields.push('phases.firstRun');
153
+ if (!input.phases.install.stdout && !input.phases.install.stderr) missingFields.push('phases.install.output');
154
+ if (!input.answerEvidence) missingFields.push('answerEvidence');
155
+ if (input.source.kind === 'tarball' && !input.source.tarballSha256) missingFields.push('source.tarballSha256');
156
+ const firstRunRc = input.phases.firstRun?.rc;
157
+ const outcome: FirstRunOutcome = !input.phases.firstRun
158
+ ? 'unknown'
159
+ : firstRunRc === 0 ? 'ready' : firstRunRc === 2 ? 'needs-llm' : firstRunRc === null ? 'cancelled' : 'unknown';
160
+ const mode: RecorderRecord['mode'] =
161
+ input.phases.install.rc === 0 && input.phases.install.stdout === '[dry-run]' ? 'dry' : 'real';
162
+ // A dry rehearsal's 0 ms phase timings are placeholders, never measurements — a positive
163
+ // 600 s decision ("within") must not be published from them (review ta-20261022-e0a4f8 mustFix 2).
164
+ if (mode === 'dry') missingFields.push('decision600s');
165
+ const totalMs =
166
+ input.phases.install.elapsedMonotonicMs + (input.phases.firstRun?.elapsedMonotonicMs ?? 0);
167
+ const decision600s: RecorderRecord['decision600s'] =
168
+ mode === 'dry' ? null
169
+ : input.phases.firstRun
170
+ ? (totalMs <= 600_000 ? 'within' : 'over')
171
+ : null;
172
+ const record: RecorderRecord = {
173
+ schema: 'first10-gate/1',
174
+ mode,
175
+ createdAt: input.createdAt ?? new Date().toISOString(),
176
+ locale: input.locale,
177
+ source: input.source,
178
+ ...(input.cliVersion ? { cliVersion: input.cliVersion } : {}),
179
+ ...(input.installMetadata ? { installMetadata: input.installMetadata } : {}),
180
+ phases: input.phases as RecorderRecord['phases'],
181
+ errorCount: countErrors(input.phases),
182
+ decision600s,
183
+ missingFields,
184
+ answerEvidence: input.answerEvidence ? scrubSecrets(input.answerEvidence) : null,
185
+ // A dry rehearsal never measures a real useful result — 'unmeasured', never 'pass'.
186
+ usefulResult: mode === 'dry'
187
+ ? 'unmeasured'
188
+ : mapOutcomeToUsefulResult({ outcome, answerEvidence: input.answerEvidence }),
189
+ };
190
+ // Scrub each string field individually — never the serialized JSON, where an
191
+ // escaped quote (stderr `token=abc"`) would leave a bare quote and break JSON.parse.
192
+ const scrubPhase = (p: PhaseRecord): PhaseRecord =>
193
+ ({ ...p, stdout: scrubSecrets(p.stdout), stderr: scrubSecrets(p.stderr) });
194
+ return {
195
+ ...record,
196
+ source: { ...record.source, ref: scrubSecrets(record.source.ref) },
197
+ phases: {
198
+ install: scrubPhase(record.phases.install),
199
+ ...(record.phases.firstRun ? { firstRun: scrubPhase(record.phases.firstRun) } : {}),
200
+ },
201
+ };
202
+ }
203
+
204
+ export interface CliArgs {
205
+ record: string;
206
+ home?: string;
207
+ prefix: string;
208
+ stateDir?: string;
209
+ source?: string;
210
+ lang: 'ko' | 'en';
211
+ dry: boolean;
212
+ answerEvidence?: string;
213
+ help: boolean;
214
+ }
215
+
216
+ const HELP = `Usage: bun scripts/first10-gate.ts --record PATH --home PATH --prefix PATH --state-dir PATH [--source PATH.tgz|URL] [--lang ko|en] [--answer-evidence TEXT] [--dry] [--help]
217
+
218
+ FIRST10-GATE — one JSON stopwatch record for install → first-run → first useful answer.
219
+ --record PATH where to write the single JSON record (required)
220
+ --home PATH isolated HOME for the measurement run (required, must not be the operating HOME)
221
+ --prefix PATH isolated installation prefix (required; the operating default
222
+ \${XDG_DATA_HOME:-\$HOME/.local/share}/elanous is refused)
223
+ --state-dir PATH isolated ELANOUS_STATE_DIR (required; the operating ~/.elanous is refused)
224
+ --source PATH.tgz|URL passed through to scripts/install.sh (--source), recorded as provenance
225
+ --lang ko|en one locale per run (ELANOUS_INSTALL_LANG) — ko and en runs are recorded separately
226
+ --answer-evidence TEXT evidence reference for the first usable answer; without it the run is unmeasured
227
+ --dry dry rehearsal: no real install.sh spawn; the record is marked mode "dry" and
228
+ usefulResult stays unmeasured — never pass
229
+ --help, -h show this help
230
+
231
+ Wraps scripts/install.sh unedited with --prefix/--source, ELANOUS_INSTALL_LANG and
232
+ ELANOUS_INSTALL_INTERACTIVE=0/--no-setup for non-interactive measurement runs.
233
+ The first-run phase invokes the installed CLI's non-TTY first-chat gate
234
+ (src/onboarding/first-chat-gate.ts → runFirstRun): rc=0 outcome 'ready', rc=2 'needs-llm'.
235
+ This recorder never claims the full macOS 600 s card green — UX runs the exact PR head on
236
+ mbp in two fresh isolated homes (ko/en) and attaches the screen recording and answer evidence.
237
+ `;
238
+
239
+ function parseArgs(argv: string[]): CliArgs {
240
+ const args: CliArgs = { record: '', prefix: '', lang: 'en', dry: false, help: false };
241
+ for (let i = 0; i < argv.length; i++) {
242
+ const a = argv[i];
243
+ const next = (): string => { const v = argv[++i]; if (v === undefined) throw new Error(`⛔ ${a} needs a value`); return v; };
244
+ switch (a) {
245
+ case '--help': case '-h': args.help = true; return args;
246
+ case '--record': args.record = next(); break;
247
+ case '--home': args.home = next(); break;
248
+ case '--prefix': args.prefix = next(); break;
249
+ case '--state-dir': args.stateDir = next(); break;
250
+ case '--source': args.source = next(); break;
251
+ case '--lang': {
252
+ const lang = next(); if (lang !== 'ko' && lang !== 'en') throw new Error('⛔ --lang must be ko or en'); args.lang = lang; break;
253
+ }
254
+ case '--answer-evidence': args.answerEvidence = next(); break;
255
+ case '--dry': args.dry = true; break;
256
+ default: throw new Error(`⛔ unknown argument: ${a}`);
257
+ }
258
+ }
259
+ if (!args.record) throw new Error('⛔ --record is required');
260
+ if (!args.prefix) throw new Error('⛔ --prefix is required');
261
+ if (!args.home) throw new Error('⛔ --home is required');
262
+ if (!args.stateDir) throw new Error('⛔ --state-dir is required');
263
+ return args;
264
+ }
265
+
266
+ interface InstallJson {
267
+ version?: string;
268
+ versionDir?: string;
269
+ source?: string;
270
+ installedAt?: string;
271
+ commit?: string;
272
+ }
273
+
274
+ const readInstallJson = (prefix: string): InstallJson | undefined => {
275
+ const path = resolve(prefix, 'install.json');
276
+ if (!existsSync(path)) return undefined;
277
+ try {
278
+ return JSON.parse(readFileSync(path, 'utf8')) as InstallJson;
279
+ } catch {
280
+ return undefined;
281
+ }
282
+ };
283
+
284
+ /** Repository root = parent of this script's own directory (<repo>/scripts → <repo>). */
285
+ export const repoRootOf = (): string => resolve(import.meta.dir, '..');
286
+
287
+ /** sha256 of a file, cross-platform: sha256sum, then macOS `shasum -a 256`; '' if neither exists. */
288
+ export const sha256 = (path: string): string => {
289
+ // macOS has no sha256sum by default — fall back to `shasum -a 256` (and shasum
290
+ // to shasum-compatible coreutils `sha256` no-op is not attempted).
291
+ for (const cmd of ['sha256sum', 'shasum -a 256']) {
292
+ const [bin, ...rest] = cmd.split(' ');
293
+ const r = spawnSync(bin, [...rest, path], { encoding: 'utf8' });
294
+ if (r.status === 0) {
295
+ const sum = r.stdout.trim().split(/\s+/)[0] ?? '';
296
+ if (sum) return sum;
297
+ }
298
+ }
299
+ // Neither hasher exists: empty string — callers must record this as missing.
300
+ return '';
301
+ };
302
+
303
+ function sourceOf(source: string | undefined, installMetadata: InstallJson | undefined): RecordSource {
304
+ if (source) {
305
+ if (/^https?:\/\//.test(source)) return { kind: 'url', ref: source };
306
+ if (!existsSync(source)) return { kind: 'tarball', ref: resolve(source) };
307
+ const tarballSha256 = sha256(source);
308
+ return tarballSha256 ? { kind: 'tarball', ref: resolve(source), tarballSha256 } : { kind: 'tarball', ref: resolve(source) };
309
+ }
310
+ const metaSource = installMetadata?.source;
311
+ if (metaSource && /^https?:\/\//.test(metaSource)) return { kind: 'url', ref: metaSource };
312
+ return { kind: 'checkout', ref: metaSource ?? (process.cwd()) };
313
+ }
314
+
315
+ /** URL sources are passed through verbatim; only local file paths are resolve()d. */
316
+ export const installSourceArg = (source: string): string =>
317
+ /^https?:\/\//.test(source) ? source : resolve(source);
318
+
319
+ export function runInstallPhase(args: CliArgs, repoRoot: string): PhaseRecord {
320
+ if (args.dry) {
321
+ // Dry rehearsal: no real spawn — the record is marked mode "dry" so it can never be
322
+ // conflated with a real useful result.
323
+ return { rc: 0, stdout: '[dry-run]', stderr: '', elapsedMonotonicMs: 0 };
324
+ }
325
+ if (!existsSync(resolve(repoRoot, 'scripts/install.sh'))) {
326
+ return {
327
+ rc: 127,
328
+ stdout: '',
329
+ stderr: `⛔ scripts/install.sh not found under ${repoRoot} — not a real install run`,
330
+ elapsedMonotonicMs: 0,
331
+ };
332
+ }
333
+ const installer = resolve(repoRoot, 'scripts/install.sh');
334
+ const env = {
335
+ ...process.env,
336
+ HOME: resolve(args.home!),
337
+ ELANOUS_STATE_DIR: resolve(args.stateDir!),
338
+ ELANOUS_INSTALL_LANG: args.lang,
339
+ ELANOUS_INSTALL_INTERACTIVE: '0',
340
+ };
341
+ const started = performance.now();
342
+ const r = spawnSync('bash', [installer, '--prefix', resolve(args.prefix), '--no-setup', '--no-modify-path', ...(args.source ? ['--source', installSourceArg(args.source)] : [])], {
343
+ encoding: 'utf8', env, maxBuffer: 16 * 1024 * 1024,
344
+ });
345
+ return {
346
+ rc: r.status,
347
+ stdout: r.stdout ?? '',
348
+ stderr: r.stderr ?? '',
349
+ elapsedMonotonicMs: Math.round(performance.now() - started),
350
+ };
351
+ }
352
+
353
+ function runFirstRunPhase(args: CliArgs, install: PhaseRecord): PhaseRecord | undefined {
354
+ if (args.dry) return { rc: 2, stdout: '[dry-run]', stderr: '[dry-run] first-run not measured', elapsedMonotonicMs: 0 };
355
+ if (install.rc !== 0) return undefined;
356
+ const cli = resolve(args.prefix, 'bin/elanous');
357
+ if (!existsSync(cli)) return undefined;
358
+ const env = {
359
+ ...process.env,
360
+ HOME: resolve(args.home!),
361
+ ELANOUS_STATE_DIR: resolve(args.stateDir!),
362
+ ELANOUS_INSTALL_LANG: args.lang,
363
+ };
364
+ const started = performance.now();
365
+ // The installed CLI's non-TTY first-chat gate: rc=2 means runFirstRun outcome 'needs-llm'.
366
+ const r = spawnSync('bash', [cli], { encoding: 'utf8', env, maxBuffer: 16 * 1024 * 1024 });
367
+ return {
368
+ rc: r.status,
369
+ stdout: r.stdout ?? '',
370
+ stderr: r.stderr ?? '',
371
+ elapsedMonotonicMs: Math.round(performance.now() - started),
372
+ };
373
+ }
374
+
375
+ export function main(argv: string[]): number {
376
+ let args: CliArgs;
377
+ try {
378
+ args = parseArgs(argv);
379
+ } catch (e) {
380
+ process.stderr.write(`${(e as Error).message}\n\n${HELP}`);
381
+ return 2;
382
+ }
383
+ if (args.help) {
384
+ process.stdout.write(HELP);
385
+ return 0;
386
+ }
387
+ const isolation = validateIsolation({ home: args.home!, prefix: args.prefix, stateDir: args.stateDir! });
388
+ if (!isolation.ok) {
389
+ process.stderr.write(`${isolation.reason}\n`);
390
+ return 2;
391
+ }
392
+ // Repository root = parent of this script's own directory (<repo>/scripts → <repo>),
393
+ // so runInstallPhase spawns the real <repo>/scripts/install.sh, never <repo>/scripts/scripts/install.sh.
394
+ const repoRoot = repoRootOf();
395
+ const installPhase = runInstallPhase(args, repoRoot);
396
+ const installMetadata = readInstallJson(args.prefix);
397
+ const firstRunPhase = runFirstRunPhase(args, installPhase);
398
+ const record = buildRecord({
399
+ locale: args.lang,
400
+ source: sourceOf(args.source, installMetadata),
401
+ cliVersion: installMetadata?.version,
402
+ installMetadata,
403
+ phases: { install: installPhase, ...(firstRunPhase ? { firstRun: firstRunPhase } : {}) },
404
+ answerEvidence: args.answerEvidence ?? null,
405
+ });
406
+ const out = resolve(args.record);
407
+ mkdirSync(dirname(out), { recursive: true });
408
+ writeFileSync(out, `${JSON.stringify(record, null, 2)}\n`);
409
+ process.stdout.write(`${out}: usefulResult=${record.usefulResult} decision600s=${record.decision600s ?? 'n/a'} missingFields=${record.missingFields.join(',') || '-'}\n`);
410
+ return 0;
411
+ }
412
+
413
+ if (import.meta.main) {
414
+ process.exit(main(process.argv.slice(2)));
415
+ }
416
+