elanous 0.2.29 → 0.2.31

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 (709) 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/{cIpv5nU9AycwYWZI9H589 → LSXfY0u9QtfDbejY0Ukf_}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{058a98ba.7eb28d5e6dc03565.js → 0bb0ff36.b8d418980951e5ba.js} +7 -7
  5. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +27 -0
  8. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +287 -0
  9. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +62 -0
  10. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/{6013-2f769370d8b4c2c6.js → 1335-6731f392c35216eb.js} +3 -3
  12. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/{8332.6f0f49df772e163b.js → 1654.32de4b324981a188.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/1834-50625904996a8fa8.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +149 -0
  17. package/apps/pwa/out/_next/static/chunks/{8795.32573a185af18c7b.js → 1913.7cc6fb6055b1ed3f.js} +2 -2
  18. package/apps/pwa/out/_next/static/chunks/{419.736c0d6f426249a7.js → 2001.6c7e0fd02190886c.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{6767.1fcfc9b8be83975f.js → 2213.2ccbada92c33ea0f.js} +16 -16
  24. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/{4759.1f76713aefb87db5.js → 2871.0bca6137343b3f76.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/{6776.06ff1e3b464cc607.js → 2898.fd781bc7cf01a7b7.js} +1 -1
  29. package/apps/pwa/out/_next/static/chunks/{1782-59db1b5aa06df38a.js → 2940-619bfd8ef337c611.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/{8471.8d2a8c74f09c36ff.js → 2985.39ccdecd36848b12.js} +4 -4
  31. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +115 -0
  32. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +64 -0
  33. package/apps/pwa/out/_next/static/chunks/{bc324b7c.02a09dd93f6a399b.js → 3267c0e6.d34854e7b3984a6e.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/3278.2e5d15b53a4091c8.js +2 -0
  35. package/apps/pwa/out/_next/static/chunks/{7725-4f83d5541fbdb81b.js → 3541-ce3a5424ed5ad7f1.js} +1 -1
  36. package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3902.e1e71aaac850a045.js +34 -0
  39. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/{46bd8bea.2f4b4099172fcdb7.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
  41. package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/{1142.65d002789ab3af7d.js → 4174.92ed04922709ac9e.js} +2 -2
  43. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +36 -0
  45. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +286 -0
  49. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +77 -0
  50. package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +226 -0
  51. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +79 -0
  53. package/apps/pwa/out/_next/static/chunks/5173-233188df2f42c626.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +148 -0
  57. package/apps/pwa/out/_next/static/chunks/5307.60f2209e809bd627.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{3396-97b97928c49190c9.js → 5458-16cd7a2b51b74c8c.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/{3403.7199205e65124486.js → 5525.86debf231e181813.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{9143.ff14585db1d275ff.js → 5543.a438b8ab5a13ea47.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +74 -0
  65. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +94 -0
  67. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{8398.73a19b39715eda04.js → 6092.a7f99e68b188ca66.js} +1 -1
  70. package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/{5591.a35e7a217734a8b9.js → 6157.0c9af021de4fb31b.js} +2 -2
  72. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/{7375.050ea0d72968e49f.js → 6433.fc573af22bbc9ab7.js} +17 -17
  75. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +90 -0
  77. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +32 -0
  78. package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +104 -0
  80. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +24 -0
  85. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +93 -0
  86. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{1852.7f7b53991fcb99ef.js → 7502.ccd5b8065545edd0.js} +2 -2
  93. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +8 -0
  94. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{6534.1ab00f370db7b105.js → 7862.30a8d6482bb238eb.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/{285adb1a.5654e605dddf86d2.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/8097-92f87bd108322f66.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +24 -0
  109. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{1516.dfaceff3fd2d0e0d.js → 9138.b6e80031afb1d973.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/{9907.49be0fcadaf214b5.js → 9221.7d22eaf353a2d4e7.js} +1 -1
  113. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/{8767-2f6a634f5abeaa01.js → 9279-d28c5b7754d010ae.js} +1 -1
  115. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{3160-95c96f4d2a21dd26.js → 9398-6aed28f0a96d0d6f.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/{328bb3ab-6628a1114fe3fb3b.js → 997ce8a5-2ad501927003b41b.js} +1 -1
  121. package/apps/pwa/out/_next/static/chunks/{6853.cc5174a9dee59593.js → 9989.3694300e5f000b14.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-bf3634a117322df7.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-3535a4a69f1fafaa.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-b9f51447f757fbf2.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-a5635eba0d73b84e.js → page-2ebb8fd59b9461f9.js} +1 -1
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-a2fc4e49a4fa4ba8.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-5a503541353e60a8.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-6025101384e361a5.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-f4b630cc8b5273cd.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-a645f00a06483e9a.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-61ac22cbab1ee4ec.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e9bab7413b028b28.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-c992eafe028b642e.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-e547e6ce55f1fb33.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-d27e1b9850fd54bf.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-805ac2e137b7a121.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-0fec29c7ba01894b.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-339a07410cd6f36b.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-349f2752d8cd37ad.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-d5c6dcf31c25cecc.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-2fd93ed8c9f16580.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-9b564dbff0fefc35.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-62f4475d3c38fb9b.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-814ba51385225776.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-397d479626e5a459.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-af1bba4e3251b728.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ad3be5e7d3fdce9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-f219ccdbc0bf27df.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4da93ad35d4a8d28.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-456666766e5ce6fc.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-7404e377e8adb8c5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-14456240ed2a36ad.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-3a658d5fa6d16a25.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-0157de6e85f8bb6b.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-0a07363b130182a1.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-841d73d4ac44ed49.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6f43a3d1146e6377.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/{page-29900ed0011b2c83.js → page-521ee23ac8c0abfa.js} +1 -1
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-a9992ee285efaa83.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-3d48e85fa89ec04f.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d2ced71132fac9b2.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-f08358bdf251adb9.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-233c71cd5f68f0d7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-70151d78de2f375e.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-dcac33a3e2cb72c0.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/{page-9f92737b8766009a.js → page-149dc1caba411bb9.js} +1 -1
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0448145ccd5c45c1.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-9cb0c444903da65d.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-17e504c396e0e389.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{425cfc4d.fb91158e3971c39f.js → b313b242.cb1265eea908db61.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +122 -0
  175. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +1 -0
  183. package/apps/pwa/out/_next/static/css/{72becfd42807b50d.css → 3f5fc6f96e2cf7b2.css} +1 -1
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +23 -23
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +23 -23
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +23 -23
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +22 -22
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +22 -22
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +23 -23
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +22 -22
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +23 -23
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +23 -23
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +22 -22
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +23 -23
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +23 -23
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +23 -23
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +23 -23
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +22 -22
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +22 -22
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +23 -23
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +23 -23
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +23 -23
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +22 -22
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +22 -22
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +23 -23
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +23 -23
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +22 -22
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +22 -22
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +22 -22
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +23 -23
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +23 -23
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +22 -22
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +23 -23
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +23 -23
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +23 -23
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +23 -23
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +23 -23
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +22 -22
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +23 -23
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +23 -23
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +23 -23
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +23 -23
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +23 -23
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +23 -23
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +23 -23
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +23 -23
  277. package/bin/elanous.mjs +7 -3
  278. package/graphs/context/nightly-condense.yaml +1 -0
  279. package/graphs/intake/intake-daily.yaml +8 -1
  280. package/graphs/intake/recipes.yaml +5 -0
  281. package/graphs/lecture/lecture-note.yaml +2 -2
  282. package/graphs/ops/harness-gc.yaml +1 -0
  283. package/graphs/release/recipes.yaml +3 -0
  284. package/graphs/release/release-loop.yaml +9 -5
  285. package/graphs/units/recipes.yaml +3 -0
  286. package/graphs/units/release-gate-recheck.yaml +15 -0
  287. package/package.json +2 -1
  288. package/scripts/check-native-tool-wiring.ts +3 -2
  289. package/scripts/ci-android-unit-tests.ts +16 -0
  290. package/scripts/ci-typecheck-changed.ts +37 -9
  291. package/scripts/coord-channel-watch.sh +22 -16
  292. package/scripts/coord-role-pack.ts +81 -2
  293. package/scripts/cron-run.ts +96 -3
  294. package/scripts/detect-test-interference.ts +38 -5
  295. package/scripts/gate-pr-cache.ts +65 -0
  296. package/scripts/gh-surface/capture.ts +126 -0
  297. package/scripts/gh-surface/gh +40 -0
  298. package/scripts/import-graph-scc.ts +38 -0
  299. package/scripts/install.ps1 +19 -0
  300. package/scripts/intake-social.ts +181 -0
  301. package/scripts/lecture-note/node.ts +71 -4
  302. package/scripts/lib/android-toolchain.ts +32 -0
  303. package/scripts/lib/deterministic-env.ts +62 -0
  304. package/scripts/lib/gate-test-env.ts +19 -0
  305. package/scripts/measure-goal-grounding-corpus.ts +2 -1
  306. package/scripts/ratchets/test-interference-patterns.allowlist.txt +257 -0
  307. package/scripts/ratchets/test-interference-patterns.ts +367 -0
  308. package/scripts/release-loop/cut-branch.ts +4 -3
  309. package/scripts/release-loop/export-check-node.ts +0 -1
  310. package/scripts/release-loop/fixtures/warm-failure-assertion/sample.junit.xml +8 -0
  311. package/scripts/release-loop/fixtures/warm-job-029/sample.json +1 -0
  312. package/scripts/release-loop/fixtures/warm-job-029/sample.junit.xml +10 -0
  313. package/scripts/release-loop/gate-closure.ts +12 -8
  314. package/scripts/release-loop/gate-diff.ts +1 -1
  315. package/scripts/release-loop/gate-host-mirror.ts +66 -0
  316. package/scripts/release-loop/gate-node.ts +523 -75
  317. package/scripts/release-loop/gate-partial.ts +106 -9
  318. package/scripts/release-loop/gate-pr-cache.ts +66 -0
  319. package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
  320. package/scripts/release-loop/gate-r2-verdict.ts +189 -0
  321. package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
  322. package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
  323. package/scripts/release-loop/import-graph-scc-run.ts +54 -0
  324. package/scripts/release-loop/import-graph-scc.ts +215 -0
  325. package/scripts/release-loop/node-verdict.ts +2 -0
  326. package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
  327. package/scripts/release-loop/resume-release.ts +33 -4
  328. package/scripts/release-loop/resume.ts +13 -5
  329. package/scripts/release-loop/spawn-lane.ts +2 -19
  330. package/scripts/release-loop/tui-sim-node.ts +3 -2
  331. package/scripts/release-loop/unattended-release.ts +16 -0
  332. package/scripts/test-deterministic.ts +5 -61
  333. package/scripts/train-reach-grouping.ts +48 -0
  334. package/scripts/tsc-incremental-cache.ts +86 -0
  335. package/scripts/tsc-incremental-diagnostics.ts +76 -0
  336. package/scripts/tsc-main-safety-net.ts +2 -2
  337. package/src/acp/client.ts +4 -1
  338. package/src/acp/core-turn-bridge.ts +50 -5
  339. package/src/ad-pipeline/run.ts +4 -2
  340. package/src/agent/runner.ts +169 -3
  341. package/src/agent/subagent-callable.ts +3 -2
  342. package/src/agent-mission/review-loop.ts +6 -3
  343. package/src/agent-substrate/acp-implementer.ts +14 -2
  344. package/src/agent-substrate/pr-reviewer.ts +12 -0
  345. package/src/agent-substrate/self-review-cli.ts +30 -4
  346. package/src/autopilot/pr-manager.ts +62 -7
  347. package/src/briefing/brief-items.ts +24 -22
  348. package/src/capture/tui-self-report.ts +15 -0
  349. package/src/chat/chat-cli.ts +10 -2
  350. package/src/chat/index.ts +77 -11
  351. package/src/chat/input-control-key.ts +5 -3
  352. package/src/chat/tool-interrupt-behavior.ts +38 -0
  353. package/src/chat/tool-render/dispatch.ts +5 -1
  354. package/src/chat/turn-typeahead.ts +75 -20
  355. package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
  356. package/src/cli/agent-cli.ts +41 -13
  357. package/src/cli/config-audit.ts +123 -0
  358. package/src/cli/decisions-cli.ts +80 -6
  359. package/src/cli/log-event-names.ts +7 -0
  360. package/src/cli/mcp-login.ts +21 -5
  361. package/src/cli/msg-cli.ts +88 -0
  362. package/src/cli/pr-cli.ts +214 -57
  363. package/src/cli/pr-land-heavy-remote.ts +2 -2
  364. package/src/cli/pr-land-overlap-evidence.ts +63 -9
  365. package/src/cli/pr-land-pod-shadow-job.ts +83 -0
  366. package/src/cli/pr-land-pod-shadow.ts +16 -3
  367. package/src/cli/pr-land-virtual-rebase.ts +108 -0
  368. package/src/cli/release-cli.ts +80 -14
  369. package/src/cli/seat-cli.ts +138 -3
  370. package/src/cli/self-update.ts +5 -2
  371. package/src/cli/tasks-cli.ts +97 -19
  372. package/src/context-bus/context-first.ts +13 -0
  373. package/src/context-bus/context-now.ts +13 -2
  374. package/src/context-bus/ops-events.ts +75 -0
  375. package/src/control-plane/lease-holder.ts +12 -8
  376. package/src/control-plane/ledger.ts +163 -4
  377. package/src/control-plane/server.ts +91 -11
  378. package/src/core-turn/run-core-turn.ts +1 -0
  379. package/src/core-turn/run-goal-loop.ts +222 -3
  380. package/src/core-turn/seat-turn-cap.ts +79 -0
  381. package/src/core-turn/short-question.ts +38 -6
  382. package/src/core-turn/types.ts +3 -0
  383. package/src/dashboard/acp-boot.ts +3 -0
  384. package/src/dashboard/index.ts +224 -615
  385. package/src/dashboard/input/chat-main-entry-runtime.ts +1 -1
  386. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +4 -1
  387. package/src/dashboard/input/chat-main-session.ts +8 -1
  388. package/src/dashboard/input/chat-main-turn.ts +12 -3
  389. package/src/dashboard/input/compact-prepass-recovery.ts +33 -0
  390. package/src/dashboard/input/external-input-host.ts +26 -0
  391. package/src/dashboard/input/internal-turn.ts +261 -0
  392. package/src/dashboard/input/seat-autowake.ts +318 -0
  393. package/src/dashboard/input/turn-steer-bridge.ts +70 -0
  394. package/src/dashboard/loop-scheduler.ts +72 -0
  395. package/src/dashboard/seat-boot-preamble.ts +18 -0
  396. package/src/dashboard/skill-runtime.ts +2 -0
  397. package/src/dashboard/slash-runtime/dashboard-handlers.ts +126 -1181
  398. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
  399. package/src/dashboard/slash-runtime/index.ts +13 -0
  400. package/src/dashboard/turn-busy-teardown.ts +50 -0
  401. package/src/decisions/decision-ledger.ts +45 -4
  402. package/src/discord-self-message.ts +4 -4
  403. package/src/domains/release-tool.ts +18 -1
  404. package/src/field-note/transcribe.ts +17 -0
  405. package/src/github/remote-call.ts +81 -0
  406. package/src/goals/registry.ts +46 -6
  407. package/src/goals/types.ts +7 -1
  408. package/src/graph-runner/runner.ts +1 -0
  409. package/src/grok/credential.ts +26 -0
  410. package/src/harness/harness-clean.ts +2 -1
  411. package/src/harness/harness-cli-command.ts +52 -5
  412. package/src/harness/harness-gc.ts +2 -1
  413. package/src/harness/harness-incidents.ts +57 -20
  414. package/src/harness/harness-pod-dispatch.ts +87 -10
  415. package/src/harness/harness-queue.ts +53 -4
  416. package/src/harness/harness-stop.ts +4 -3
  417. package/src/harness/harness-substrate-default.ts +78 -7
  418. package/src/harness/harness-worktree-auto.ts +2 -1
  419. package/src/harness/harness-worktrees.ts +3 -2
  420. package/src/hooks/dispatch.ts +2 -1
  421. package/src/index.ts +152 -25
  422. package/src/input/external-input-queue.ts +33 -1
  423. package/src/intake-plane/slash.ts +14 -3
  424. package/src/keybindings.ts +4 -1
  425. package/src/llm/tool-loop-steered-rejection.ts +33 -0
  426. package/src/llm.ts +138 -19
  427. package/src/loops/consensus.ts +348 -0
  428. package/src/loops/msg-wake.ts +206 -4
  429. package/src/loops/observe.ts +19 -3
  430. package/src/loops/orchestrator/tick.ts +64 -10
  431. package/src/loops/orchestrator/traffic.ts +64 -1
  432. package/src/loops/registry.ts +30 -0
  433. package/src/market/signed-index.ts +14 -0
  434. package/src/mcp/mcp-oauth.ts +54 -5
  435. package/src/models/prompts.ts +28 -0
  436. package/src/msg/msg-sse-client.ts +223 -0
  437. package/src/msg/msg-store.ts +86 -2
  438. package/src/mss/logging/log-store.ts +225 -1
  439. package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
  440. package/src/nexus/api/http-server.ts +54 -15
  441. package/src/nexus/api/loop-resources.ts +19 -3
  442. package/src/nexus/api/ops-api.ts +11 -0
  443. package/src/nexus/daemon-thin-inventory.md +37 -0
  444. package/src/nexus/index.ts +70 -0
  445. package/src/nexus/state/state.ts +1 -0
  446. package/src/oauth/store.ts +32 -7
  447. package/src/onboarding/first-run.ts +28 -3
  448. package/src/ops/overview-cache.ts +16 -4
  449. package/src/ops/resources.ts +82 -0
  450. package/src/plugins/maker/connector-maker.ts +41 -0
  451. package/src/plugins/maker/skill-maker.ts +42 -0
  452. package/src/pr-tool/census.ts +288 -0
  453. package/src/prompt-library/chat-conciseness.ts +13 -0
  454. package/src/prompt-library/universal-preamble.ts +10 -5
  455. package/src/release-loop/gate-host-reservation.ts +97 -0
  456. package/src/release-loop/landing-freeze.ts +5 -0
  457. package/src/release-loop/light-rc.ts +5 -2
  458. package/src/release-loop/placement.ts +92 -1
  459. package/src/release-loop/rehearsal-shard-plan.ts +149 -0
  460. package/src/release-loop/rehearsal.ts +73 -17
  461. package/src/repl/index.ts +20 -2
  462. package/src/seat-loop/seat-knowhow.ts +282 -0
  463. package/src/seat-loop/seat-loop.ts +41 -2
  464. package/src/seat-loop/traffic-signal.ts +3 -0
  465. package/src/self-dev/ask-launch-flow.ts +24 -3
  466. package/src/self-dev/decompose-compose-graph.ts +28 -27
  467. package/src/self-dev/decompose-proposal.ts +53 -38
  468. package/src/self-dev/decompose.ts +17 -0
  469. package/src/self-dev/dev-pipeline.ts +31 -2
  470. package/src/self-dev/draft-residue.ts +24 -9
  471. package/src/self-dev/draft-sweep.ts +59 -4
  472. package/src/self-dev/external-call-zero.ts +77 -0
  473. package/src/self-dev/launch-preflight-text.ts +6 -0
  474. package/src/self-dev/launch-preflight.ts +25 -3
  475. package/src/self-dev/local-supervisor-judge.ts +185 -0
  476. package/src/self-dev/run-supervisor.ts +229 -19
  477. package/src/self-dev/run-types.ts +20 -0
  478. package/src/self-dev/shard-aggregate.ts +13 -2
  479. package/src/self-dev/shard-plan.ts +47 -0
  480. package/src/self-dev/shard-run.ts +112 -10
  481. package/src/self-dev/spawn-lane-files.ts +19 -0
  482. package/src/self-implement/app-api-budget.ts +51 -11
  483. package/src/self-implement/config-gate.ts +2 -1
  484. package/src/self-implement/expose-gate.ts +2 -1
  485. package/src/self-implement/gate-artifacts.ts +405 -0
  486. package/src/self-implement/gate-cli.ts +201 -16
  487. package/src/self-implement/gate-remote.ts +110 -25
  488. package/src/self-implement/gate-scenario.ts +85 -0
  489. package/src/self-implement/goal-author.ts +160 -8
  490. package/src/self-implement/graph-authority.ts +38 -6
  491. package/src/self-implement/graph-overlay-condition.ts +92 -1
  492. package/src/self-implement/heal-triage.ts +79 -0
  493. package/src/self-implement/host-regate.ts +61 -3
  494. package/src/self-implement/orchestrator.ts +14 -123
  495. package/src/self-implement/pr-title.ts +123 -0
  496. package/src/self-implement/run-checkpoint.ts +235 -0
  497. package/src/self-implement/run-ledger.ts +155 -10
  498. package/src/self-implement/run-stop.ts +4 -3
  499. package/src/self-implement/run-ttl.ts +28 -4
  500. package/src/self-implement/seams.ts +2 -0
  501. package/src/self-implement/shadow-stage.ts +7 -6
  502. package/src/self-implement/stop-autoheal.ts +2 -1
  503. package/src/self-implement/train-gate-remote.ts +37 -8
  504. package/src/self-implement/train-reach-grouping.ts +157 -0
  505. package/src/self-implement/train-scenario-layers.ts +133 -0
  506. package/src/self-implement/uncommitted-work.ts +2 -0
  507. package/src/session/pending-input.ts +19 -0
  508. package/src/session/session-start.ts +224 -0
  509. package/src/session-runtime/parallel-dispatch.ts +22 -5
  510. package/src/skills/tools/dev-harness.ts +6 -4
  511. package/src/skills/tools/shell.ts +1 -1
  512. package/src/steward/resync-tick.ts +114 -23
  513. package/src/steward/ta-repair-event-collect.ts +158 -0
  514. package/src/task-agent/card-evidence.ts +25 -1
  515. package/src/task-agent/green-sweep.ts +8 -3
  516. package/src/task-agent/judge.ts +76 -0
  517. package/src/task-agent/land-queue.ts +79 -0
  518. package/src/task-agent/live-moves.ts +30 -9
  519. package/src/task-agent/postland-card.ts +5 -0
  520. package/src/task-agent/prelaunch-already-done.ts +98 -0
  521. package/src/task-agent/real-launch-guard.ts +37 -0
  522. package/src/task-agent/rejudge-on-head.ts +89 -12
  523. package/src/task-agent/remote-rejudge-bind.ts +28 -8
  524. package/src/task-agent/repair-cycle.ts +45 -7
  525. package/src/task-agent/repair-worker.ts +7 -0
  526. package/src/task-agent/run-identity.ts +200 -0
  527. package/src/task-agent/shadow.ts +50 -3
  528. package/src/task-agent/task-hand.ts +158 -5
  529. package/src/task-agent/train-landing.ts +77 -0
  530. package/src/task-agent/work-order.ts +104 -0
  531. package/src/task-orchestrator/surfaces/pod-command-job.ts +88 -28
  532. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
  533. package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
  534. package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
  535. package/src/task-orchestrator/surfaces/pod-install-slots.ts +121 -9
  536. package/src/task-orchestrator/surfaces/pod-lease.ts +20 -6
  537. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
  538. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +27 -0
  539. package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
  540. package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +63 -0
  541. package/src/task-orchestrator/surfaces/pod-source-receive.ts +19 -3
  542. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +141 -0
  543. package/src/task-orchestrator/surfaces/pod-warm-ta-shadow.ts +85 -0
  544. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
  545. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +208 -0
  546. package/src/task-orchestrator/surfaces/self-implement-pod.ts +132 -15
  547. package/src/telegram.ts +2 -4
  548. package/src/tui/input/pickers.ts +732 -0
  549. package/src/tui/slash/mission.ts +492 -0
  550. package/src/tui/slash/term.ts +877 -0
  551. package/src/tui-client/dashboard-session.ts +9 -0
  552. package/src/tui.ts +48 -0
  553. package/src/user-config/gemini-server-tools.ts +9 -0
  554. package/src/user-config.ts +53 -16
  555. package/src/util/spawn-sync-output.ts +7 -0
  556. package/src/ux-sim/fake-bin.ts +154 -0
  557. package/src/ux-sim/fake-clock.ts +36 -0
  558. package/src/ux-sim/headless-tui.ts +72 -0
  559. package/src/ux-sim/in-process-cli.ts +2 -1
  560. package/src/ux-sim/temp-git-remote.ts +82 -0
  561. package/src/version/packed-revision.json +1 -1
  562. package/src/video-pipeline/recipes/vlog.ts +25 -7
  563. package/apps/pwa/out/_next/static/chunks/1015-9cba22a5a4554797.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +0 -8
  567. package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +0 -34
  569. package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +0 -286
  572. package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +0 -24
  573. package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +0 -36
  576. package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +0 -64
  578. package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +0 -115
  584. package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +0 -90
  588. package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +0 -94
  599. package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +0 -62
  605. package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +0 -27
  608. package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +0 -104
  609. package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +0 -93
  610. package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +0 -24
  613. package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +0 -2
  615. package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +0 -148
  616. package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +0 -149
  617. package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +0 -79
  619. package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +0 -287
  625. package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +0 -77
  632. package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +0 -74
  635. package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +0 -226
  640. package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +0 -32
  642. package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/a435ad95.577add051b4facb2.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/loops/page-8aaa6dedc4c10dfb.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/morning/page-33bf667a5fb297bf.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/term/page-9eb56166774eb256.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +0 -122
  703. package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +0 -1
  709. /package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → LSXfY0u9QtfDbejY0Ukf_}/_ssgManifest.js +0 -0
@@ -1,6 +1,7 @@
1
1
  import { spawnSync } from 'node:child_process';
2
2
  import { readFileSync } from 'node:fs';
3
3
  import { join } from 'node:path';
4
+ import { loadavg, cpus, freemem } from 'node:os';
4
5
  import { effectiveInstanceRoot, prodInstanceRoot, treeDerivedRootFor } from '../instance/resolve.js';
5
6
  import { getElanousConfigDirOverride } from '../elanous-config-dir.js';
6
7
  import { buildUserConfig, getUserConfig, type UserConfig } from '../user-config.js';
@@ -99,6 +100,60 @@ export interface AutoSubstrateDecision {
99
100
  reason: string;
100
101
  }
101
102
 
103
+ export interface AutoSubstrateReadDeps {
104
+ loadavg?: typeof loadavg;
105
+ cpus?: typeof cpus;
106
+ freemem?: typeof freemem;
107
+ podAdmission?: () => AutoSubstrateSignals['podAdmission'];
108
+ localLaneOpen?: () => boolean;
109
+ /** Resolved by the launch decision, using its flag → env → config → context precedence. */
110
+ pool?: string | null;
111
+ config?: Pick<UserConfig, 'harness' | 'pod'>;
112
+ measurePoolLease?: typeof import('../task-orchestrator/surfaces/pod-lease.js').measurePoolLease;
113
+ }
114
+
115
+ /** Read Pod admission using the same pool, usage and account inputs as dispatch backpressure. */
116
+ function readAutoPodAdmission(deps: AutoSubstrateReadDeps): AutoSubstrateSignals['podAdmission'] {
117
+ // Keep Pod lease dependencies lazy for local-only launches.
118
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
119
+ const { leaseKubectl, measurePoolLease, recommendConcurrency } = require('../task-orchestrator/surfaces/pod-lease.js') as typeof import('../task-orchestrator/surfaces/pod-lease.js');
120
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
121
+ const { parsePodPool, resolvePodPoolSpec } = require('../task-orchestrator/surfaces/pod-pool.js') as typeof import('../task-orchestrator/surfaces/pod-pool.js');
122
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
123
+ const { listCodexAccountsInStore } = require('../oauth/codex-account-store.js') as typeof import('../oauth/codex-account-store.js');
124
+ // A direct collector call can resolve its own pool. The launch resolver passes a string or null
125
+ // explicitly so it never substitutes another universe's pool when the launch pool is unreadable.
126
+ const fallback = deps.pool === undefined ? (deps.config ?? getUserConfig()) : null;
127
+ const spec = fallback ? resolvePodPoolSpec(undefined, process.env, () => fallback.harness?.podPool ?? fallback.pod?.pool) : null;
128
+ const current = fallback && !spec ? leaseKubectl(['config', 'current-context']) : null;
129
+ const pool = deps.pool === undefined ? (spec ?? (current?.status === 0 ? current.stdout.trim() : null)) : deps.pool;
130
+ if (!pool) return null;
131
+ const members = parsePodPool(pool);
132
+ const measure = (deps.measurePoolLease ?? measurePoolLease)(members, { measureUsage: true, skipDnsProbe: true });
133
+ let accounts = -1;
134
+ try { accounts = listCodexAccountsInStore().length; } catch { /* Accounts are only observed, not a limit. */ }
135
+ const { recommended, limitedBy } = recommendConcurrency(measure, {
136
+ capacity: members.reduce((sum, member) => sum + member.capacity, 0),
137
+ accounts, perAccount: (deps.config ?? getUserConfig()).pod?.lease?.perAccount ?? 4,
138
+ });
139
+ return recommended === null || limitedBy === null ? null : { recommended, limitedBy };
140
+ }
141
+
142
+ /** Collect observations on the launch host; an unreadable Pod recommendation is not a refusal. */
143
+ export function readAutoSubstrateSignals(deps: AutoSubstrateReadDeps = {}): AutoSubstrateSignals {
144
+ let podAdmission: AutoSubstrateSignals['podAdmission'];
145
+ try { podAdmission = (deps.podAdmission ?? (() => readAutoPodAdmission(deps)))() ?? null; }
146
+ catch { podAdmission = null; }
147
+ if (podAdmission?.recommended === null || podAdmission?.limitedBy === null) podAdmission = null;
148
+ return {
149
+ load1: (deps.loadavg ?? loadavg)()[0],
150
+ cores: (deps.cpus ?? cpus)().length,
151
+ availableMemoryBytes: (deps.freemem ?? freemem)(),
152
+ podAdmission,
153
+ localLaneOpen: deps.localLaneOpen?.() ?? false,
154
+ };
155
+ }
156
+
102
157
  export interface NextLocalLaneCapInput {
103
158
  current: number;
104
159
  wanted: number;
@@ -194,28 +249,44 @@ export function checkHarnessPodPool(pool: string, run?: PoolKubectl): HarnessPoo
194
249
  export function resolveHarnessSubstrate({ flag, config, env, currentContext = () => {
195
250
  const result = spawnSync('kubectl', ['config', 'current-context'], { encoding: 'utf8', timeout: 5000 });
196
251
  return result.status === 0 ? result.stdout?.trim() : undefined;
197
- }, autoSignals, poolCheck = checkHarnessPodPool }: {
252
+ }, autoSignals, readAutoSignals, autoReadDeps, poolCheck = checkHarnessPodPool }: {
198
253
  flag?: { substrate?: HarnessSubstrate | 'auto'; podPool?: string };
199
254
  config?: Pick<UserConfig, 'harness' | 'pod'>;
200
255
  env?: NodeJS.ProcessEnv;
201
256
  currentContext?: () => string | undefined;
202
257
  /** Signals must come from the launch host and Pod admission, not a worktree's cached config. */
203
258
  autoSignals?: AutoSubstrateSignals;
259
+ /** Inject the collector at the decision boundary; explicit requests never invoke it. */
260
+ readAutoSignals?: () => AutoSubstrateSignals;
261
+ /** Inject measurement dependencies without bypassing the default collector or pool selection. */
262
+ autoReadDeps?: Omit<AutoSubstrateReadDeps, 'pool' | 'config' | 'podAdmission'>;
204
263
  /** POD-POOL-UNCAPPED-SPEC — pre-launch check of the implicit kube context; tests inject it instead of shelling out. */
205
264
  poolCheck?: (pool: string) => HarnessPoolCheck;
206
265
  }): ResolvedHarnessSubstrate {
207
266
  const requested = flag?.substrate ?? config?.harness?.substrate ?? 'local';
208
267
  if (requested !== 'local' && requested !== 'pod' && requested !== 'auto') throw new Error('harness.substrate: local, pod 또는 auto 만 허용한다');
209
268
  const source = flag?.substrate ? 'flag' : config?.harness?.substrate ? 'config' : 'default';
210
- // Missing signals mean admission was not observed, not that the Pod has room.
211
- const decision = requested === 'auto' ? routeAutoSubstrate(autoSignals ?? {
212
- podAdmission: null, load1: null, cores: null, availableMemoryBytes: null, localLaneOpen: false,
213
- }) : null;
269
+ const explicit = flag?.podPool?.trim() || env?.ELANOUS_POD_POOL?.trim() || config?.harness?.podPool?.trim() || config?.pod?.pool?.trim();
270
+ // Reuse the same pool choice for admission and launch; do not fall back to a different universe's pool.
271
+ let implicit: string | undefined;
272
+ let contextRead = false;
273
+ const selectedPool = () => {
274
+ if (explicit) return explicit;
275
+ if (!contextRead) { implicit = currentContext()?.trim(); contextRead = true; }
276
+ return implicit;
277
+ };
278
+ const signals = requested === 'auto'
279
+ ? (autoSignals ?? (readAutoSignals ?? (() => readAutoSubstrateSignals({ ...autoReadDeps, pool: selectedPool() ?? null, config })))())
280
+ : null;
281
+ if (signals && autoSignals === undefined) debug.log('harness.substrate', 'auto-signals', {
282
+ load1: signals.load1, cores: signals.cores, availableMemoryBytes: signals.availableMemoryBytes,
283
+ podAdmission: signals.podAdmission, localLaneOpen: signals.localLaneOpen,
284
+ });
285
+ const decision = signals ? routeAutoSubstrate(signals) : null;
214
286
  const substrate: HarnessSubstrate = requested === 'auto' ? decision!.substrate : requested;
215
287
  if (decision) debug.log('harness.substrate', 'route', { substrate, reason: decision.reason, source });
216
288
  if (substrate === 'local') return { substrate, pool: null, source };
217
- const explicit = flag?.podPool?.trim() || env?.ELANOUS_POD_POOL?.trim() || config?.harness?.podPool?.trim() || config?.pod?.pool?.trim();
218
- const pool = explicit || currentContext()?.trim();
289
+ const pool = selectedPool();
219
290
  if (!pool) throw new Error(`harness.substrate=${decision ? `auto→pod(${decision.reason})` : 'pod'}: Pod 풀 또는 현재 컨텍스트에 닿지 못했다 — 풀을 설정하거나 \`--substrate local\` 로 명시하라`);
220
291
  // POD-POOL-UNCAPPED-SPEC — an explicit pool is the operator's own statement and gets `checkPodPool` at the launch
221
292
  // site (`src/index.ts` self orchestrate · `src/loops/orchestrator/tick.ts` · `pod-command-job.ts`). The implicit
@@ -1,4 +1,5 @@
1
1
  import { spawnSync } from 'node:child_process';
2
+ import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
2
3
  import { readFileSync } from 'node:fs';
3
4
  import { resolveMainRepoRoot, type HarnessWorktreeCommand } from '../git-fs/worktree.js';
4
5
  import { goalTitleFromDocument } from '../self-implement/seams.js';
@@ -25,7 +26,7 @@ interface DevWorktreeGoal {
25
26
  }
26
27
 
27
28
  function git(cwd: string, args: string[]): string {
28
- const result = spawnSync('git', args, { cwd, encoding: 'utf8' });
29
+ const result = spawnSync('git', args, { cwd, encoding: 'utf8', maxBuffer: SPAWN_SYNC_MAX_BUFFER });
29
30
  if (result.status !== 0) {
30
31
  const message = (result.stderr || result.stdout || '').trim() || `git exited ${result.status}`;
31
32
  throw new Error(`dev auto-worktree inspection failed — ${message}`);
@@ -1,4 +1,5 @@
1
1
  import { spawnSync } from 'node:child_process';
2
+ import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
2
3
  import { resolve } from 'node:path';
3
4
  import { debug } from '../debug/log.js';
4
5
  import { gitStdout, type GitRunner } from './harness-clean.js';
@@ -146,7 +147,7 @@ export function renderHarnessWorktreesReport(report: WorktreeAssessmentReport, r
146
147
 
147
148
  export type GhWorktreeRunner = (args: string[], cwd: string) => { status: number | null; stdout: string };
148
149
  const defaultGhRunner: GhWorktreeRunner = (args, cwd) => {
149
- const result = spawnSync('gh', args, { cwd, encoding: 'utf8', timeout: 25_000 });
150
+ const result = spawnSync('gh', args, { cwd, encoding: 'utf8', timeout: 25_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
150
151
  return { status: result.status, stdout: result.stdout ?? '' };
151
152
  };
152
153
 
@@ -366,7 +367,7 @@ export function execHarnessWorktrees(deps: {
366
367
  progress?: (line: string) => void;
367
368
  } = {}): WorktreeAssessmentReport {
368
369
  const run: GitRunner = deps.run ?? ((args) => {
369
- const result = spawnSync('git', args, { encoding: 'utf8', timeout: 25_000 });
370
+ const result = spawnSync('git', args, { encoding: 'utf8', timeout: 25_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
370
371
  return { status: result.status, stdout: result.stdout ?? '', stderr: result.stderr ?? '' };
371
372
  });
372
373
  const worktrees = listRegisteredWorktrees(run);
@@ -24,7 +24,8 @@ const DEFAULT_SEAT_ROUTES = [
24
24
  * So a delivered card with the seat loop off is not retried (the card waits in the inbox), and a shadow loop's wake is
25
25
  * recorded as `wake_status = 'shadow'` — visible as «not executed», not mistaken for a real run. */
26
26
  export async function dispatchHook(event: QueuedHook, root: string, config: EventsConfig,
27
- wake: HookWake = seat => runSeatLoopOnce(seat, { root, config: getUserConfig().loops?.seat ?? { mode: 'off' } }),
27
+ // Autonomous hook wake: the needs-owner hold stays on (NEEDS-OWNER-BOUNDARY).
28
+ wake: HookWake = seat => runSeatLoopOnce(seat, { root, needsOwnerGate: true, config: getUserConfig().loops?.seat ?? { mode: 'off' } }),
28
29
  now: () => number = Date.now): Promise<void> {
29
30
  const key = `${event.provider}:${event.eventId}`;
30
31
  const route = config.routes.find(candidate => candidate.source === event.provider && candidate.kind === event.kind);
package/src/index.ts CHANGED
@@ -489,7 +489,17 @@ async function executeHarnessSelfRun(
489
489
  runId: string,
490
490
  startDraftTriage: typeof import('./self-dev/dev-cli.js')['startDraftTriage'],
491
491
  startDraftTriageOptions?: RunDevAskStartDraftTriageOptions,
492
+ entranceId?: EntranceId,
492
493
  ): Promise<Awaited<ReturnType<RunDevAskRunDevPipeline>>> {
494
+ // TA harness say/ask may be decomposed into parallel text goals before
495
+ // runDevPipeline reads the authored file. Check the original GOAL here,
496
+ // before any orchestrator or Pod child can be dispatched.
497
+ const isGoalFile = existsSync(input);
498
+ if (process.env.ELANOUS_TASK_CARD_ID?.trim() || isGoalFile) {
499
+ const { preflightGoalDoneBoundary } = await import('./self-dev/dev-pipeline.js');
500
+ preflightGoalDoneBoundary({ file: isGoalFile ? input : '<harness request>' }, isGoalFile ? readFileSync(input, 'utf8') : input,
501
+ process.env.ELANOUS_TASK_CARD_ID, entranceId, isGoalFile ? 'goal' : 'request');
502
+ }
493
503
  startDraftTriage(runId, startDraftTriageOptions);
494
504
  // 정지 요청의 «신선도» 기준 — 첫 런 «전»에 잰다(첫 런 도중의 정지도 이 호출의 것이다).
495
505
  const invocationStartedAtMs = Date.now();
@@ -651,6 +661,11 @@ async function runDevAskFromAskFile(askPath: string, opts: HarnessAskSayChildLlm
651
661
  },
652
662
  );
653
663
  if (flowResult.kind !== 'launch') {
664
+ // ⭐ 프리플라이트 거절은 «자식 결과» 봉투로 마지막 JSON 행을 남긴다 — Pod 원장(pod-failure-reason.nestedPodResult)이
665
+ // {ok, kind, result:{stage, blockers}} 중첩 행에서 사유 코드·검사 이름·경로를 읽는다. 나머지 중단은 기존대로 조용히 exit(1).
666
+ if (opts.json && flowResult.kind === 'stopped-by-preflight') {
667
+ await writeStdoutJson(`${JSON.stringify({ ok: false, kind: 'self', result: { stage: 'preflight-blocked', ok: false, blockers: flowResult.blockers } })}\n`);
668
+ }
654
669
  runDevAskFromGoalFileDeps.setExitCode(1);
655
670
  return;
656
671
  }
@@ -677,6 +692,7 @@ async function runDevAskFromAskFile(askPath: string, opts: HarnessAskSayChildLlm
677
692
  identity.runId,
678
693
  startDraftTriage,
679
694
  startDraftTriageOptions,
695
+ CLI_HARNESS_ASK_ENTRANCE.id,
680
696
  );
681
697
  const ok = devResultOk(result);
682
698
  if (opts.json) {
@@ -782,6 +798,7 @@ async function runDevAskFromGoalFile(goalPath: string, opts: HarnessAskSayChildL
782
798
  identity.runId,
783
799
  startDraftTriage,
784
800
  startDraftTriageOptions,
801
+ CLI_HARNESS_ASK_ENTRANCE.id,
785
802
  );
786
803
  const ok = devResultOk(result);
787
804
  if (opts.json) {
@@ -886,6 +903,7 @@ async function runDevSayFromWords(
886
903
  identity.runId,
887
904
  startDraftTriage,
888
905
  startDraftTriageOptions,
906
+ entrance,
889
907
  );
890
908
  const ok = devResultOk(result);
891
909
  if (opts.json) {
@@ -4319,10 +4337,15 @@ selfCmd
4319
4337
  .option('--base <ref>', '커밋됐지만 PR 없는 변경의 비교 기준(ref...HEAD)')
4320
4338
  .option('--pr <number>', '열린 PR 번호에서 gh pr view files로 변경 파일을 읽는다')
4321
4339
  .option('--shards [number]', '메모리 예산에 맞춰 시험을 별도 프로세스로 분할한다 (기본 2)')
4340
+ .option('--fixed-shard-distribution', '--shards N 과 함께만: RSS 사전 측정 없이 정렬된 파일을 N 조각에 라운드로빈 고정 배정한다(opt-in · 메모리 보증 아님 · 조각 타임아웃/OOM = unmeasured)')
4341
+ .option('--include-importers', '변경 모듈을 가져오는 importer 시험도 실행한다 (기본 caller 한도 밖까지)')
4322
4342
  .option('--remote [host]', 'GATE-REMOTE — 같은 커밋을 원격 호스트(기본 config gateRemote.host=node-b)에서 돌리고 결과만 가져온다(깨끗한 트리 · --pr 은 로컬)')
4323
4343
  .option('--local', '원격 자동 분배(로컬 1분 부하 > gateRemote.loadThreshold=20)를 끄고 로컬에서 돌린다')
4324
- .action(async (opts: { changed?: boolean; base?: string; pr?: string; shards?: string | boolean; remote?: string | boolean; local?: boolean }) => {
4344
+ .option('--artifact-dir <dir>', '조각별 지금/기준 JUnit ⊕ summary.json 을 이 디렉토리에 남긴다(판정 불변 · JUnit 은 --shards 경로만 · 원격 실행이면 그 호스트에서 가져온다)')
4345
+ .action(async (opts: { changed?: boolean; base?: string; pr?: string; shards?: string | boolean; fixedShardDistribution?: boolean; includeImporters?: boolean; remote?: string | boolean; local?: boolean; artifactDir?: string }) => {
4325
4346
  if (!opts.changed && opts.shards === undefined) { ui.error('self gate requires --changed or --shards'); process.exitCode = 2; return; }
4347
+ if (opts.fixedShardDistribution && opts.shards === undefined) { ui.error('self gate: --fixed-shard-distribution requires --shards <n>'); process.exitCode = 2; return; }
4348
+ if (opts.artifactDir !== undefined && !opts.artifactDir.trim()) { ui.error('self gate: --artifact-dir needs a non-empty directory'); process.exitCode = 2; return; }
4326
4349
  // The root strips `--local` from argv anywhere (remote-bookmark attach · src/cli/remote-resolve.ts) before Commander
4327
4350
  // sees it, so this subcommand reads it from the untouched process.argv.
4328
4351
  opts.local = !!opts.local || process.argv.slice(2).includes('--local');
@@ -4332,10 +4355,13 @@ selfCmd
4332
4355
  if (!isValidGateHost(opts.remote)) { ui.error(`self gate: invalid --remote host: ${opts.remote}`); process.exitCode = 2; return; }
4333
4356
  }
4334
4357
  const shards = opts.shards === undefined ? undefined : opts.shards === true ? 2 : Number(opts.shards);
4358
+ let ranLocal = false;
4359
+ let remoteArtifacts: { dir: string; fetch?: { ok: true; summaryPath: string; junitFiles: string[]; remoteDirKept: boolean } | { ok: false; reason: string } } | { unsupported: true } | undefined;
4335
4360
  const runLocal = () => {
4361
+ ranLocal = true;
4336
4362
  try {
4337
4363
  const { runSelfGateCli } = require('./self-implement/gate-cli.js') as typeof import('./self-implement/gate-cli.js');
4338
- const result = runSelfGateCli(process.cwd(), { base: opts.base, pr: opts.pr, shards });
4364
+ const result = runSelfGateCli(process.cwd(), { base: opts.base, pr: opts.pr, shards, ...(opts.fixedShardDistribution ? { fixedShardDistribution: true } : {}), includeImporterTests: !!opts.includeImporters, ...(opts.artifactDir !== undefined ? { artifactDir: opts.artifactDir } : {}) });
4339
4365
  console.log(result.lines.join('\n'));
4340
4366
  return result.exitCode;
4341
4367
  } catch (error) {
@@ -4350,23 +4376,74 @@ selfCmd
4350
4376
  if (topLevel.status !== 0) throw new Error(`git rev-parse --show-toplevel failed: ${topLevel.stderr.trim() || `rc=${topLevel.status}`}`);
4351
4377
  const repo = topLevel.stdout.trim();
4352
4378
  // Only a committed --base range is reproducible on another host: the default mode measures uncommitted files, --pr
4353
- // reads files through gh on this host, and the remote checkout runs from the repository root — those stay local.
4379
+ // reads files through gh on this host, and the remote checkout runs from the repository root — automatic placement
4380
+ // falls back locally; an explicit --remote reports that this check was not measured.
4354
4381
  const { realpathSync } = await import('node:fs');
4355
4382
  const localOnlyReason = opts.pr ? 'self gate --pr reads PR files through gh on this host'
4356
4383
  : !opts.base ? 'self gate without --base measures uncommitted files on this host'
4357
4384
  : realpathSync(repo) !== realpathSync(process.cwd()) ? 'self gate run from a sub-directory' : undefined;
4385
+ // SIDE-VERIFY-GATE-SHARDS ② — the host writes its artifacts outside its scratch tree (which its trap removes) and we
4386
+ // fetch them back after the run. Only when the measured commit knows --artifact-dir: an unknown option would kill the
4387
+ // remote CLI and change the verdict itself.
4388
+ if (opts.artifactDir !== undefined) {
4389
+ const { remoteCommitSupportsArtifactDir, newRemoteArtifactDir } = await import('./self-implement/gate-artifacts.js');
4390
+ remoteArtifacts = remoteCommitSupportsArtifactDir(repo) ? { dir: newRemoteArtifactDir() } : { unsupported: true };
4391
+ }
4392
+ const remoteArtifactArgs = remoteArtifacts && 'dir' in remoteArtifacts ? ['--artifact-dir', remoteArtifacts.dir] : [];
4358
4393
  // origin/main is pinned to this machine's origin/main on the host; any other base is passed as its resolved sha.
4359
4394
  const remoteArgv = (sha: (ref: string) => string) => ['bun', 'bin/elanous.mjs', 'self', 'gate', '--local', ...(opts.changed ? ['--changed'] : []),
4360
- ...(opts.base ? ['--base', opts.base === 'origin/main' ? opts.base : sha(opts.base)] : []), ...(shards !== undefined ? ['--shards', String(shards)] : [])];
4395
+ ...(opts.base ? ['--base', opts.base === 'origin/main' ? opts.base : sha(opts.base)] : []), ...(shards !== undefined ? ['--shards', String(shards)] : []),
4396
+ // A measured commit without this option rejects it (exit ≠ 0) — read as not passed, never as a silent measured run.
4397
+ ...(opts.fixedShardDistribution ? ['--fixed-shard-distribution'] : []),
4398
+ ...(opts.includeImporters ? ['--include-importers'] : []), ...remoteArtifactArgs];
4399
+ const { gateHostReservationRoot } = await import('./release-loop/gate-host-reservation.js');
4361
4400
  process.exitCode = await dispatchHeavyCheck({
4362
- tool: 'self-gate', repo, installPwa: true, remoteArgv, refs: opts.base ? [opts.base] : [],
4401
+ tool: 'self-gate', repo, installPwa: true, remoteArgv, refs: opts.base ? [opts.base] : [], reservationRoot: gateHostReservationRoot(),
4363
4402
  localOnlyReason,
4403
+ explicitRemoteOnly: opts.remote !== undefined, reportRemoteHost: true,
4364
4404
  flags: { remote: typeof opts.remote === 'string' ? opts.remote : opts.remote ? true : undefined, local: !!opts.local },
4365
4405
  runLocal,
4406
+ ...(remoteArtifacts && 'dir' in remoteArtifacts && opts.artifactDir !== undefined ? {
4407
+ onRemoteOutcome: ((outcome, host, runner) => {
4408
+ const { fetchRemoteGateArtifacts, remoteArtifactCleanupScript, resolveArtifactDir } = require('./self-implement/gate-artifacts.js') as typeof import('./self-implement/gate-artifacts.js');
4409
+ const target = remoteArtifacts as { dir: string; fetch?: { ok: true; summaryPath: string; junitFiles: string[]; remoteDirKept: boolean } | { ok: false; reason: string } };
4410
+ if (outcome.kind === 'ran') {
4411
+ target.fetch = fetchRemoteGateArtifacts({ host, remoteDir: target.dir, localDir: resolveArtifactDir(opts.artifactDir!, process.cwd()), ssh: runner.ssh });
4412
+ } else if (outcome.kind === 'infra') {
4413
+ // The run may have started before it broke — remove the host-side dir; automatic placement's local fallback writes its own.
4414
+ try { runner.ssh(host, remoteArtifactCleanupScript(target.dir), 30_000); } catch { /* best effort */ }
4415
+ }
4416
+ }) satisfies NonNullable<import('./self-implement/gate-remote.js').DispatchOptions['onRemoteOutcome']>,
4417
+ } : {}),
4366
4418
  });
4367
4419
  } catch (error) {
4368
- ui.error(`self gate dispatch failed: ${error instanceof Error ? error.message : String(error)}`);
4369
- process.exitCode = runLocal();
4420
+ const reason = error instanceof Error ? error.message : String(error);
4421
+ if (opts.remote !== undefined) {
4422
+ ui.error(`self gate remote unmeasured — ${reason.replace(/\s+/g, ' ').trim()}`);
4423
+ process.exitCode = 1;
4424
+ } else {
4425
+ ui.error(`self gate dispatch failed: ${reason}`);
4426
+ process.exitCode = runLocal();
4427
+ }
4428
+ }
4429
+ // 원격에서 돌았으면 그 호스트의 산출을 가져와 같은 꼴로 썼다 — 못 가져왔으면 «조용히» 비우지 않고 summary 에 이유를 적는다(판정 불변).
4430
+ if (opts.artifactDir !== undefined && !ranLocal) {
4431
+ const fetched = remoteArtifacts && 'dir' in remoteArtifacts ? remoteArtifacts.fetch : undefined;
4432
+ try {
4433
+ if (fetched?.ok) {
4434
+ console.log(`artifacts: ${fetched.summaryPath} (junit ${fetched.junitFiles.length} · fetched from remote)`);
4435
+ if (fetched.remoteDirKept) console.log(`⚠ artifacts: 원격 산출 디렉토리를 못 지웠다 — ${(remoteArtifacts as { dir: string }).dir} (판정은 그대로다)`);
4436
+ }
4437
+ else {
4438
+ const reason = remoteArtifacts && 'unsupported' in remoteArtifacts ? 'remote-unsupported' as const : 'remote-fetch-failed' as const;
4439
+ if (reason === 'remote-fetch-failed') console.log(`⚠ artifacts: 원격 산출을 못 가져왔다 — ${fetched && !fetched.ok ? fetched.reason : 'no remote fetch ran'} (판정은 그대로다)`);
4440
+ const { writeRemoteUnavailableGateArtifacts } = await import('./self-implement/gate-artifacts.js');
4441
+ const written = writeRemoteUnavailableGateArtifacts(opts.artifactDir, process.cwd(), opts.base, Number(process.exitCode ?? 0), reason);
4442
+ console.log(`artifacts: ${written.summaryPath} (junit 0 · unavailable=${reason})`);
4443
+ }
4444
+ } catch (error) {
4445
+ console.log(`⚠ artifacts: ${opts.artifactDir} 에 못 썼다 — ${error instanceof Error ? error.message : String(error)} (판정은 그대로다)`);
4446
+ }
4370
4447
  }
4371
4448
  });
4372
4449
 
@@ -7505,7 +7582,7 @@ const selfDevCmd = program
7505
7582
  cfg: reloadUserConfig(),
7506
7583
  userText: text,
7507
7584
  explicitSessionId: chat.session,
7508
- reuseActive: !chat.forceNew,
7585
+ reuseActive: chat.continueActive === true,
7509
7586
  forceNew: chat.forceNew === true,
7510
7587
  json: chat.json === true,
7511
7588
  enableTools: chat.enableTools,
@@ -7790,7 +7867,7 @@ configCmd
7790
7867
  .command('set <path> <value>')
7791
7868
  .description('Set a dotted config path. Value is parsed as JSON when possible.')
7792
7869
  .option('--no-backup', "Don't write config.json.bak before saving")
7793
- .action((path: string, value: string, opts: { backup?: boolean }) => {
7870
+ .action(async (path: string, value: string, opts: { backup?: boolean }) => {
7794
7871
  const parsed = parseConfigValue(value);
7795
7872
  const cfg = getUserConfig() as unknown as Record<string, unknown>;
7796
7873
  const previousProvider = getConfigPath(cfg, 'llm.provider');
@@ -7809,6 +7886,7 @@ configCmd
7809
7886
  : undefined;
7810
7887
 
7811
7888
  if (opts.backup !== false) backupUserConfig(userConfigPath());
7889
+ const prev = getConfigPath(cfg, path); // CFG-STORE2 감사 이력 — 변경 «전» 값
7812
7890
  setConfigPath(cfg, path, parsed);
7813
7891
  if (credential?.apiKey && (credential.source === 'rotation' || credential.source === 'env')) {
7814
7892
  setConfigPath(cfg, 'llm.apiKey', credential.apiKey);
@@ -7822,6 +7900,8 @@ configCmd
7822
7900
  console.error(`⚠️ set ${path} — 저장 후 값 미반영(직렬화 드롭). 읽힌값=${JSON.stringify(after)}`);
7823
7901
  process.exit(1);
7824
7902
  }
7903
+ // CFG-STORE2 — 저장 «성공» 뒤 감사 이력 한 줄 · fail-open(기록 실패가 set 을 막지 않는다).
7904
+ try { (await import('./cli/config-audit.js')).recordConfigChange({ key: path, prev, next: parsed, why: 'config set' }); } catch (err) { ui.warn(`config 감사 이력 기록 실패(무시): ${err instanceof Error ? err.message : String(err)}`); }
7825
7905
  if (credential?.apiKey && (credential.source === 'rotation' || credential.source === 'env')) {
7826
7906
  ui.info(`provider credential updated: ${parsed} via ${credential.source} (${credential.apiKey.length} chars)`);
7827
7907
  } else if (credential?.source === 'none' && !isKeylessProvider(nextProvider)) {
@@ -7836,9 +7916,10 @@ configCmd
7836
7916
  .command('unset <path>')
7837
7917
  .description('Remove a dotted config path (set 의 역 · 배열 인덱스 지원). 이미 없으면 no-op.')
7838
7918
  .option('--no-backup', "Don't write config.json.bak before saving")
7839
- .action((path: string, opts: { backup?: boolean }) => {
7919
+ .action(async (path: string, opts: { backup?: boolean }) => {
7840
7920
  const cfg = getUserConfig() as unknown as Record<string, unknown>;
7841
- if (getConfigPath(cfg, path) === undefined) {
7921
+ const prev = getConfigPath(cfg, path); // CFG-STORE2 감사 이력 — 삭제 «전» 값
7922
+ if (prev === undefined) {
7842
7923
  ui.info(`unset ${path} — 이미 없음 (no-op)`);
7843
7924
  return;
7844
7925
  }
@@ -7852,6 +7933,8 @@ configCmd
7852
7933
  console.error(`⚠️ unset ${path} — 삭제 후에도 값 잔존. 남은값=${JSON.stringify(after)}`);
7853
7934
  process.exit(1);
7854
7935
  }
7936
+ // CFG-STORE2 — 삭제 저장 «성공» 뒤 감사 이력 한 줄 · fail-open(기록 실패가 unset 을 막지 않는다).
7937
+ try { (await import('./cli/config-audit.js')).recordConfigChange({ key: path, prev, why: 'config unset' }); } catch (err) { ui.warn(`config 감사 이력 기록 실패(무시): ${err instanceof Error ? err.message : String(err)}`); }
7855
7938
  ui.info(`unset ${path}`);
7856
7939
  });
7857
7940
 
@@ -8050,6 +8133,7 @@ program
8050
8133
  reuseActive: opts.reuse === true,
8051
8134
  forceNew: false,
8052
8135
  json: opts.json === true,
8136
+ surface: 'ask',
8053
8137
  });
8054
8138
  });
8055
8139
 
@@ -8900,15 +8984,26 @@ function announceChatToolsCompatibility(): void {
8900
8984
 
8901
8985
  // ── chat (single-turn helper, non-TUI) ──
8902
8986
  program
8903
- .command('chat <text...>')
8904
- .description('Send one message in the active session (or a new one) and print the reply')
8905
- .option('--new', 'Force a new session instead of using the active one')
8906
- .option('--session <id>', 'Continue an explicit session (id or unique prefix). Overrides --new and active session.')
8987
+ .command('chat [text...]')
8988
+ .description('Send one message in a new session (or a continued one with --continue/--resume/--session) and print the reply')
8989
+ .option('--new', 'Start a new session (the default since 0.2.31 — kept for compatibility)')
8990
+ .option('--continue', 'Continue the active session instead of starting a new one')
8991
+ .option('--resume [id]', 'Continue a session: the given id (or unique prefix), or the active session when no id is given. A word after --resume that is not session-id shaped (hex uuid) is read as the prompt, not the id.')
8992
+ .option('--session <id>', 'Continue an explicit session (id or unique prefix). Overrides --new, --continue and --resume.')
8907
8993
  .option('--json', 'Emit a single JSON line {sessionId, provider, model, reply, logPath, budget} instead of streaming text + ui.info trailer. Stable shape for LLM self-spawn.')
8908
8994
  .option('--tools', 'Enable the tool-loop path (Read/Grep/Glob/ListDir/Edit/Write + Bash). Default off — chat is text-only by default for backward compatibility. `elanous agent` is a thin wrapper that flips this on.')
8909
8995
  .option('--goal-loop', 'Arm the across-turn goal loop (runGoalLoop): wrap the tool-loop so the model keeps iterating until the goal is complete (GOAL-COMPLETE evidence gate) or maxIterations. Requires --tools. Same engine as ACP/dashboard (재발명 없음). Config `llm.goalLoop.enabled` also arms it.')
8910
8996
  .option('--implement', 'Bypass the harness goal-loop guard for the legacy implementation child entrypoint')
8911
- .action(async (parts: string[], opts: { new?: boolean; session?: string; json?: boolean; tools?: boolean; goalLoop?: boolean; implement?: boolean }) => {
8997
+ .action(async (rawParts: string[], opts: { new?: boolean; continue?: boolean; resume?: string | boolean; session?: string; json?: boolean; tools?: boolean; goalLoop?: boolean; implement?: boolean }) => {
8998
+ // TUI-H8-FOLLOW ② — `chat --resume "질문"` 에서 Commander 가 질문 첫 낱말을 세션 id 로 먹지 않게.
8999
+ const { splitResumeArgument } = await import('./session/session-start.js');
9000
+ const split = splitResumeArgument(opts.resume, rawParts ?? [], 'chat', process.argv.slice(2));
9001
+ opts.resume = split.resume;
9002
+ const parts = split.parts;
9003
+ if (parts.length === 0) {
9004
+ console.error("error: missing required argument 'text'");
9005
+ process.exit(1);
9006
+ }
8912
9007
  if (getHarnessSpace() && opts.tools && opts.goalLoop && !opts.implement) {
8913
9008
  process.stderr.write('Harness chat goal-loop requires `dev --implement`; use that implementation entrypoint instead.\n');
8914
9009
  process.exitCode = 1;
@@ -8951,7 +9046,7 @@ program
8951
9046
  cfg: refreshed,
8952
9047
  userText: text,
8953
9048
  explicitSessionId: chat.session,
8954
- reuseActive: !chat.forceNew,
9049
+ reuseActive: chat.continueActive === true,
8955
9050
  forceNew: chat.forceNew === true,
8956
9051
  json: chat.json === true,
8957
9052
  enableTools: chat.enableTools,
@@ -8963,8 +9058,10 @@ program
8963
9058
  // ── repl (sticky multi-turn REPL) ──
8964
9059
  program
8965
9060
  .command('repl')
8966
- .description('Sticky multi-turn REPL — same session across turns, no per-turn process boot. Drives chat / agent / scenario from one shell. Uses --new for a fresh session, --session <id> to resume, --scenario <yaml> for a scripted run, JSONL on stdin for piped automation.')
8967
- .option('--new', 'Force a new session at boot instead of resuming the active one')
9061
+ .description('Sticky multi-turn REPL — same session across turns, no per-turn process boot. Drives chat / agent / scenario from one shell. Boots a new session by default; --continue/--resume continue the active one, --session <id> resumes an explicit one, --scenario <yaml> for a scripted run, JSONL on stdin for piped automation.')
9062
+ .option('--new', 'Start a new session at boot (the default since 0.2.31 — kept for compatibility)')
9063
+ .option('--continue', 'Continue the active session at boot instead of starting a new one')
9064
+ .option('--resume [id]', 'Continue a session at boot: the given id (or unique prefix), or the active session when no id is given')
8968
9065
  .option('--session <id>', 'Resume an explicit session (id or unique prefix)')
8969
9066
  .option('--scenario <path>', 'Run a YAML multi-turn scenario before handing back to interactive (or exit)')
8970
9067
  .option('--replay <session-id>', 'Re-execute the user prompts from a previous session in a fresh REPL run. User prompts are extracted in order and fed through the same dispatcher as --scenario; assistant/tool messages and attachments are dropped. Mutually exclusive with --scenario.')
@@ -8975,6 +9072,8 @@ program
8975
9072
  .option('--stdin-jsonl', 'Force JSONL-on-stdin mode even when stdin is a TTY (useful for testing automation paths)')
8976
9073
  .action(async (opts: {
8977
9074
  new?: boolean;
9075
+ continue?: boolean;
9076
+ resume?: string | boolean;
8978
9077
  session?: string;
8979
9078
  scenario?: string;
8980
9079
  replay?: string;
@@ -8999,8 +9098,9 @@ program
8999
9098
  const exitAfterScenario = opts.exitAfterScenario === undefined ? exitDefault : opts.exitAfterScenario;
9000
9099
  const code = await runRepl({
9001
9100
  cfg: refreshed,
9002
- initialSessionId: opts.session,
9101
+ initialSessionId: opts.session ?? (typeof opts.resume === 'string' ? opts.resume : undefined),
9003
9102
  forceNew: opts.new === true,
9103
+ continueActive: opts.continue === true || opts.resume === true,
9004
9104
  enableTools: opts.tools !== false,
9005
9105
  scenarioPath: opts.scenario,
9006
9106
  replaySessionId: opts.replay,
@@ -11432,7 +11532,14 @@ voiceCmd
11432
11532
  });
11433
11533
 
11434
11534
  // ── Default: Dashboard (no subcommand) ──
11435
- const DASHBOARD_FLAGS = new Set(['--debug', '--chat-only', '--chat', '--yolo', '--benchmark']);
11535
+ const DASHBOARD_FLAGS = new Set(['--debug', '--chat-only', '--chat', '--yolo', '--benchmark', '--continue']);
11536
+
11537
+ /** 대표 #73 — `--resume` 뒤 토큰이 세션 id 인가(없거나 다른 플래그면 «id 없는 이어하기» = 최신 세션). */
11538
+ export function rootResumeIdAt(rawArgs: readonly string[], resumeFlagIdx: number): string | undefined {
11539
+ if (resumeFlagIdx < 0) return undefined;
11540
+ const next = rawArgs[resumeFlagIdx + 1];
11541
+ return next !== undefined && !next.startsWith('-') ? next : undefined;
11542
+ }
11436
11543
 
11437
11544
  export function filterDashboardArgs(rawArgs: readonly string[], resumeFlagIdx?: number): string[] {
11438
11545
  const rootResumeFlagIdx = resumeFlagIdx ?? rawArgs.findIndex((arg, index) =>
@@ -11447,7 +11554,8 @@ export function filterDashboardArgs(rawArgs: readonly string[], resumeFlagIdx?:
11447
11554
  return rawArgs.filter((a, i) => {
11448
11555
  if (!leadsWithSubcommand && (DASHBOARD_FLAGS.has(a) || a === '--rich')) return false;
11449
11556
  if (!leadsWithSubcommand && i === rootResumeFlagIdx) return false;
11450
- if (!leadsWithSubcommand && rootResumeFlagIdx >= 0 && i === rootResumeFlagIdx + 1) return false;
11557
+ if (!leadsWithSubcommand && rootResumeFlagIdx >= 0 && i === rootResumeFlagIdx + 1
11558
+ && rootResumeIdAt(rawArgs, rootResumeFlagIdx) !== undefined) return false;
11451
11559
  return true;
11452
11560
  });
11453
11561
  }
@@ -11645,13 +11753,32 @@ async function main(): Promise<void> {
11645
11753
  // 🩹 옛 손버릇은 `readRemoteFlag` 쪽 오류 문면이 «갈 곳을 말해» 받는다.
11646
11754
  arg === '--resume' && rawArgs.slice(0, index).every((prior) => prior.startsWith('-')),
11647
11755
  );
11648
- const resumeFromFlag = resumeFlagIdx >= 0 ? rawArgs[resumeFlagIdx + 1] : undefined;
11756
+ const resumeFromFlag = rootResumeIdAt(rawArgs, resumeFlagIdx);
11649
11757
  // Step 5 PR γ — env read routes through readDeprecatedEnv so the
11650
11758
  // user gets a one-shot deprecation warning when the env override
11651
11759
  // drives the resume path. CLI flag wins outright (no warning).
11652
11760
  const { readDeprecatedEnv: readDeprecatedEnvForResume } = await import('./control-client/env-resolver.js');
11653
- const resumeFromEnv = readDeprecatedEnvForResume('ELANOUS_RESUME_SESSION').value;
11654
- const resumeSessionId = (resumeFromFlag ?? resumeFromEnv ?? '').trim() || undefined;
11761
+ // 대표 #73 — 인자 없는 `elanous` 는 새 세션. 이어하기는 `--resume <id>` · id 없는 `--resume` · `--continue`(= 최신 세션)일 때만.
11762
+ const leadsWithSubcommandForResume = rawArgs.length > 0 && !rawArgs[0]!.startsWith('-');
11763
+ const continueLatest = !leadsWithSubcommandForResume
11764
+ && (rawArgs.includes('--continue') || (resumeFlagIdx >= 0 && resumeFromFlag === undefined));
11765
+ // 우선순위: `--resume <id>` > `--continue`·id 없는 `--resume`(최신) > (폐기 예정) ELANOUS_RESUME_SESSION.
11766
+ // ⛔ 명시 인자가 있으면 환경변수가 이기지 않는다(TUI-H8 r1 must-fix).
11767
+ const { resolveLatestSessionId, resolveRootResumeSessionId } = await import('./session/session-start.js');
11768
+ const rootResume = resolveRootResumeSessionId({
11769
+ ...(resumeFromFlag !== undefined ? { flagId: resumeFromFlag } : {}),
11770
+ continueLatest,
11771
+ // 명시 인자가 있으면 env 를 «읽지도» 않는다(폐기 경고가 명시 이어하기에 섞이지 않게).
11772
+ readEnvId: () => readDeprecatedEnvForResume('ELANOUS_RESUME_SESSION').value ?? null,
11773
+ latest: () => resolveLatestSessionId({
11774
+ activeSessionId: () => getActiveSessionId(),
11775
+ latestSessionId: () => listSessions({ limit: 1 })[0]?.id ?? null,
11776
+ // TUI-H8-FOLLOW ① — 활성 표지가 사라진 세션이면 최신 세션으로(#28509 리뷰 should-fix).
11777
+ sessionExists: (id) => loadSession(id) !== null,
11778
+ }),
11779
+ });
11780
+ if (rootResume.source === 'continue-none') console.log('[elanous] --continue: 이어갈 세션이 없다 — 새 세션으로 시작한다');
11781
+ const resumeSessionId = rootResume.sessionId;
11655
11782
 
11656
11783
  // user-config can opt into benchmark mode persistently
11657
11784
  // (`dashboard.benchmark: true`) so callers don't have to retype the
@@ -12,6 +12,9 @@
12
12
  // - Enter 없는 글: 빈 composer 면 종전대로 채우고, 바쁘면(턴 중·버퍼에 글자) «거부»한다 —
13
13
  // 나중에 사용자 composer 에 채우면 다시 섞이므로 대기시키지 않는다(IPC 가 실패로 정산 → rc≠0).
14
14
  // 대기열은 «턴이 끝나고 composer 가 비었을 때» 한 건씩 나간다 — 사용자 버퍼는 건드리지 않는다.
15
+ // - ⏹ 정확히 `/stop`·`/esc` 인 글(TUI-STOP-INPUT-BYPASS · #68): 대기열을 «건너뛰고» 지금 턴의 ESC 중단 경로
16
+ // (`requestStop` → 대시보드 escGate)를 바로 부른다. 대기 중인 일반 항목은 그대로·순서대로 남는다.
17
+ // 턴이 없으면 아무것도 안 하고 `tui-stop-no-active-turn`(멈출 길이 없으면 `tui-stop-undelivered`)으로 던져 바깥 호출자(rc≠0)에게 알린다.
15
18
  //
16
19
  // ⚠️ herdr/tmux 처럼 «터미널 자체»에 쓰는 길은 키보드와 구별할 수 없다 — 이 라우터는
17
20
  // elanous 제어 IPC(`pty text`) 경로만 가른다.
@@ -33,11 +36,15 @@ export interface ExternalInputHost {
33
36
  hasPendingKeys(): boolean;
34
37
  /** 별도 메시지로 제출한다. 못 보냈으면 false(항목은 대기열에 남는다). */
35
38
  submit(text: string, source: InputSourceRef): boolean;
39
+ /** 지금 턴을 ESC 와 같은 경로로 멈춘다. 멈출 턴(escGate)이 없으면 false. 없으면 외부 stop 은 «턴 없음»으로 처리. */
40
+ requestStop?(): boolean;
41
+ /** 외부 stop 의 결과 표지(채팅 로그 한 줄). */
42
+ onExternalStop?(result: 'stopped' | 'no-turn' | 'failed'): void;
36
43
  /** 대기열이 바뀌었다 — 화면 표지를 다시 그린다. */
37
44
  onQueueChange?(pending: readonly ExternalInputItem[], event: 'queued' | 'delivered'): void;
38
45
  }
39
46
 
40
- export type ExternalInputRoute = 'passthrough' | 'submitted' | 'queued';
47
+ export type ExternalInputRoute = 'passthrough' | 'submitted' | 'queued' | 'stopped';
41
48
  export type ExternalInputDecision = 'passthrough' | 'submit-now' | 'queue' | 'reject';
42
49
 
43
50
  const EXTERNAL_INPUT_SOURCE: InputSourceRef = { kind: 'terminal', provider: 'pty' };
@@ -57,6 +64,11 @@ export function parseExternalTextLine(chars: string): { text: string; submit: bo
57
64
  return { text, submit };
58
65
  }
59
66
 
67
+ /** 외부 «멈춰» 명령인가 — 정확히 `/stop` 또는 `/esc`(앞뒤 공백·대소문자 변형은 일반 글). */
68
+ export function isExternalStopCommand(text: string): boolean {
69
+ return text === '/stop' || text === '/esc';
70
+ }
71
+
60
72
  /** 라우팅 판정(순수). */
61
73
  export function decideExternalInputRoute(input: {
62
74
  line: { text: string; submit: boolean } | null;
@@ -102,11 +114,14 @@ export interface ExternalInputQueueDeps {
102
114
  /** 펌프 스케줄러 — 정지 함수를 돌려준다. 시험이 손으로 돌린다. */
103
115
  schedule?: (tick: () => void, ms: number) => () => void;
104
116
  log?: (event: string, data: Record<string, unknown>) => void;
117
+ /** 외부 stop 관측 — 기본 `debug.log('tui.input', …)`. */
118
+ logInput?: (event: string, data: Record<string, unknown>) => void;
105
119
  }
106
120
 
107
121
  export function createExternalInputQueue(deps: ExternalInputQueueDeps = {}) {
108
122
  const now = deps.now ?? Date.now;
109
123
  const log = deps.log ?? ((event, data) => debug.log('tui.external-input', event, data));
124
+ const logInput = deps.logInput ?? ((event, data) => debug.log('tui.input', event, data));
110
125
  const schedule = deps.schedule ?? ((tick, ms) => {
111
126
  const t = setInterval(tick, ms);
112
127
  (t as { unref?: () => void }).unref?.();
@@ -153,6 +168,22 @@ export function createExternalInputQueue(deps: ExternalInputQueueDeps = {}) {
153
168
  return true;
154
169
  }
155
170
 
171
+ /** ⏹ 외부 stop — 대기열을 건너뛰고 지금 턴의 escGate 로. 대기열은 건드리지 않는다. */
172
+ function routeStop(h: ExternalInputHost, text: string): ExternalInputRoute {
173
+ let turnActive = false;
174
+ try { turnActive = h.isTurnActive(); } catch { turnActive = false; }
175
+ let stopped = false;
176
+ if (turnActive && h.requestStop) {
177
+ try { stopped = h.requestStop(); } catch { stopped = false; }
178
+ }
179
+ logInput('external-stop', { hadTurn: turnActive, stopped, command: text, pending: pending.length });
180
+ const result = stopped ? 'stopped' : turnActive ? 'failed' : 'no-turn';
181
+ try { h.onExternalStop?.(result); } catch { /* fail-soft */ }
182
+ if (result === 'no-turn') throw new Error('tui-stop-no-active-turn');
183
+ if (result === 'failed') throw new Error('tui-stop-undelivered');
184
+ return 'stopped';
185
+ }
186
+
156
187
  return {
157
188
  register(next: ExternalInputHost): () => void {
158
189
  host = next;
@@ -169,6 +200,7 @@ export function createExternalInputQueue(deps: ExternalInputQueueDeps = {}) {
169
200
  // `pty key`(input-key)는 «키»다 — 공백·`j` 처럼 출력 가능한 키도 종전대로 넣는다.
170
201
  if (keyCommandDepth > 0) return 'passthrough';
171
202
  const line = parseExternalTextLine(chars);
203
+ if (line && host && isExternalStopCommand(line.text)) return routeStop(host, line.text);
172
204
  let turnActive = false; let composer: string | undefined; let pendingKeys = false;
173
205
  if (host && line) {
174
206
  try { turnActive = host.isTurnActive(); composer = host.composerText(); pendingKeys = host.hasPendingKeys(); }