elanous 0.2.29 → 0.2.32

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 (775) 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 → IVKr3AlRUVLKsw2fh7eXF}/_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-98b64172bc1efe77.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/69-0a2c8209c6d4a158.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/{1852.7f7b53991fcb99ef.js → 7502.ccd5b8065545edd0.js} +2 -2
  94. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +8 -0
  95. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{6534.1ab00f370db7b105.js → 7862.30a8d6482bb238eb.js} +1 -1
  97. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{285adb1a.5654e605dddf86d2.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +24 -0
  110. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/{1516.dfaceff3fd2d0e0d.js → 9138.b6e80031afb1d973.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{9907.49be0fcadaf214b5.js → 9221.7d22eaf353a2d4e7.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/{8767-2f6a634f5abeaa01.js → 9279-d28c5b7754d010ae.js} +1 -1
  116. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/{3160-95c96f4d2a21dd26.js → 9398-6aed28f0a96d0d6f.js} +1 -1
  118. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{328bb3ab-6628a1114fe3fb3b.js → 997ce8a5-2ad501927003b41b.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/{6853.cc5174a9dee59593.js → 9989.3694300e5f000b14.js} +1 -1
  123. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/control/page-a27b1e5a0d1b308f.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/morning/page-32866485913d6a04.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-8c66a3b24a745630.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/{page-29900ed0011b2c83.js → page-c219f2ed171131be.js} +1 -1
  163. package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/term/page-04d00ae9b0890349.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/{425cfc4d.fb91158e3971c39f.js → b313b242.cb1265eea908db61.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +122 -0
  176. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +1 -0
  184. package/apps/pwa/out/_next/static/css/b5d88eba78a3d7bf.css +1 -0
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +23 -23
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +23 -23
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +23 -23
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +22 -22
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +22 -22
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +23 -23
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +22 -22
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +23 -23
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +23 -23
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +22 -22
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +23 -23
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -23
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +23 -23
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +23 -23
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +22 -22
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +23 -23
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +26 -23
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -23
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +22 -22
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +22 -22
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +23 -23
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +23 -23
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +22 -22
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +22 -22
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +22 -22
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +23 -23
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +23 -23
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +22 -22
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +23 -23
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +23 -23
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +23 -23
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +23 -23
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +23 -23
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +22 -22
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +23 -23
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +23 -23
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +23 -23
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +23 -23
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +23 -23
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +23 -23
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +23 -23
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +23 -23
  278. package/bin/elanous.mjs +7 -3
  279. package/graphs/context/nightly-condense.yaml +1 -0
  280. package/graphs/implement-loop.yaml +5 -0
  281. package/graphs/intake/intake-daily.yaml +8 -1
  282. package/graphs/intake/recipes.yaml +5 -0
  283. package/graphs/lecture/lecture-note.yaml +2 -2
  284. package/graphs/ops/harness-gc.yaml +1 -0
  285. package/graphs/release/recipes.yaml +3 -0
  286. package/graphs/release/release-loop.yaml +9 -5
  287. package/graphs/units/recipes.yaml +3 -0
  288. package/graphs/units/release-gate-recheck.yaml +15 -0
  289. package/package.json +2 -1
  290. package/scripts/check-native-tool-wiring.ts +3 -2
  291. package/scripts/ci-android-unit-tests.ts +16 -0
  292. package/scripts/ci-typecheck-changed.ts +63 -10
  293. package/scripts/coord-channel-watch.sh +22 -16
  294. package/scripts/coord-role-pack.ts +81 -2
  295. package/scripts/cron-run.ts +96 -3
  296. package/scripts/detect-test-interference.ts +38 -5
  297. package/scripts/gate-pr-cache.ts +65 -0
  298. package/scripts/gh-surface/capture.ts +126 -0
  299. package/scripts/gh-surface/gh +40 -0
  300. package/scripts/import-graph-scc.ts +38 -0
  301. package/scripts/install.ps1 +19 -0
  302. package/scripts/intake-social.ts +181 -0
  303. package/scripts/lecture-note/node.ts +71 -4
  304. package/scripts/lib/android-toolchain.ts +32 -0
  305. package/scripts/lib/deterministic-env.ts +62 -0
  306. package/scripts/lib/gate-test-env.ts +19 -0
  307. package/scripts/measure-goal-grounding-corpus.ts +2 -1
  308. package/scripts/measure-si-task-cpu.ts +143 -0
  309. package/scripts/ratchets/test-interference-patterns.allowlist.txt +255 -0
  310. package/scripts/ratchets/test-interference-patterns.ts +367 -0
  311. package/scripts/release-loop/cut-branch.ts +4 -3
  312. package/scripts/release-loop/export-check-node.ts +0 -1
  313. package/scripts/release-loop/fixtures/warm-failure-assertion/sample.junit.xml +8 -0
  314. package/scripts/release-loop/fixtures/warm-job-029/sample.json +1 -0
  315. package/scripts/release-loop/fixtures/warm-job-029/sample.junit.xml +10 -0
  316. package/scripts/release-loop/gate-closure.ts +12 -8
  317. package/scripts/release-loop/gate-diff.ts +1 -1
  318. package/scripts/release-loop/gate-host-mirror.ts +66 -0
  319. package/scripts/release-loop/gate-node.ts +523 -75
  320. package/scripts/release-loop/gate-partial.ts +106 -9
  321. package/scripts/release-loop/gate-pr-cache.ts +66 -0
  322. package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
  323. package/scripts/release-loop/gate-r2-verdict.ts +189 -0
  324. package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
  325. package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
  326. package/scripts/release-loop/import-graph-scc-run.ts +54 -0
  327. package/scripts/release-loop/import-graph-scc.ts +215 -0
  328. package/scripts/release-loop/node-verdict.ts +2 -0
  329. package/scripts/release-loop/prepare-node.ts +102 -4
  330. package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
  331. package/scripts/release-loop/resume-release.ts +33 -4
  332. package/scripts/release-loop/resume.ts +13 -5
  333. package/scripts/release-loop/spawn-lane.ts +2 -19
  334. package/scripts/release-loop/tui-sim-node.ts +3 -2
  335. package/scripts/release-loop/unattended-release.ts +16 -0
  336. package/scripts/test-deterministic.ts +5 -61
  337. package/scripts/train-reach-grouping.ts +48 -0
  338. package/scripts/tsc-incremental-cache.ts +86 -0
  339. package/scripts/tsc-incremental-diagnostics.ts +76 -0
  340. package/scripts/tsc-main-safety-net.ts +2 -2
  341. package/src/acp/client.ts +4 -1
  342. package/src/acp/core-turn-bridge.ts +65 -8
  343. package/src/acp/elanous-extensions.ts +3 -0
  344. package/src/acp/server.ts +3 -0
  345. package/src/acp/tool-trace.ts +186 -11
  346. package/src/ad-pipeline/run.ts +4 -2
  347. package/src/agent/runner.ts +169 -3
  348. package/src/agent/self-ambient-cache.ts +156 -0
  349. package/src/agent/self-ambient.ts +8 -1
  350. package/src/agent/subagent-callable.ts +3 -2
  351. package/src/agent/task-notification.ts +5 -0
  352. package/src/agent-mission/review-loop.ts +6 -3
  353. package/src/agent-substrate/acp-implementer.ts +14 -2
  354. package/src/agent-substrate/pr-reviewer.ts +14 -0
  355. package/src/agent-substrate/self-review-cli.ts +30 -4
  356. package/src/ask-user-question/tool.ts +22 -0
  357. package/src/autopilot/build/llm-conflict-merge.ts +56 -10
  358. package/src/autopilot/pr-manager.ts +80 -7
  359. package/src/briefing/brief-items.ts +24 -22
  360. package/src/capture/frame-state-detect.ts +39 -0
  361. package/src/capture/tui-self-report.ts +149 -6
  362. package/src/chat/chat-cli.ts +10 -2
  363. package/src/chat/index.ts +138 -26
  364. package/src/chat/input-control-key.ts +5 -3
  365. package/src/chat/pickers/modal-runtime.ts +6 -0
  366. package/src/chat/pickers/modals.ts +8 -2
  367. package/src/chat/tool-interrupt-behavior.ts +38 -0
  368. package/src/chat/tool-render/dispatch.ts +5 -1
  369. package/src/chat/turn-typeahead.ts +75 -20
  370. package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
  371. package/src/cli/agent-cli.ts +41 -13
  372. package/src/cli/ask-bare.ts +1 -0
  373. package/src/cli/config-audit.ts +123 -0
  374. package/src/cli/decisions-cli.ts +80 -6
  375. package/src/cli/import-cli.ts +12 -0
  376. package/src/cli/log-event-names.ts +17 -0
  377. package/src/cli/mcp-login.ts +21 -5
  378. package/src/cli/msg-cli.ts +89 -0
  379. package/src/cli/pod-cli.ts +14 -3
  380. package/src/cli/pr-cli.ts +273 -81
  381. package/src/cli/pr-land-base-read.ts +34 -0
  382. package/src/cli/pr-land-heavy-remote.ts +82 -26
  383. package/src/cli/pr-land-overlap-evidence.ts +109 -11
  384. package/src/cli/pr-land-pod-shadow-job.ts +106 -0
  385. package/src/cli/pr-land-pod-shadow.ts +16 -3
  386. package/src/cli/pr-land-refusal.ts +20 -5
  387. package/src/cli/pr-land-virtual-rebase.ts +108 -0
  388. package/src/cli/pty-takeover-cli.ts +88 -14
  389. package/src/cli/release-cli.ts +80 -14
  390. package/src/cli/seat-cli.ts +138 -3
  391. package/src/cli/self-update.ts +5 -2
  392. package/src/cli/sim-cli.ts +18 -0
  393. package/src/cli/tasks-cli.ts +97 -19
  394. package/src/context-bus/context-first.ts +13 -0
  395. package/src/context-bus/context-now.ts +13 -2
  396. package/src/context-bus/ops-events.ts +79 -0
  397. package/src/control-plane/lease-holder.ts +12 -8
  398. package/src/control-plane/ledger.ts +163 -4
  399. package/src/control-plane/server.ts +91 -11
  400. package/src/core-turn/run-core-turn.ts +2 -0
  401. package/src/core-turn/run-goal-loop.ts +243 -3
  402. package/src/core-turn/seat-turn-cap.ts +79 -0
  403. package/src/core-turn/short-question.ts +38 -6
  404. package/src/core-turn/types.ts +6 -0
  405. package/src/dashboard/acp-active-model.ts +42 -1
  406. package/src/dashboard/acp-boot.ts +3 -0
  407. package/src/dashboard/background-jobs-status.ts +66 -0
  408. package/src/dashboard/index.ts +339 -657
  409. package/src/dashboard/input/agent-wake.ts +242 -0
  410. package/src/dashboard/input/chat-main-entry-runtime.ts +6 -1
  411. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +4 -1
  412. package/src/dashboard/input/chat-main-session.ts +8 -1
  413. package/src/dashboard/input/chat-main-turn.ts +12 -3
  414. package/src/dashboard/input/compact-prepass-recovery.ts +33 -0
  415. package/src/dashboard/input/external-input-host.ts +49 -9
  416. package/src/dashboard/input/internal-turn.ts +261 -0
  417. package/src/dashboard/input/mouse-wiring.ts +108 -11
  418. package/src/dashboard/input/seat-autowake.ts +318 -0
  419. package/src/dashboard/input/turn-steer-bridge.ts +70 -0
  420. package/src/dashboard/log-click-runtime.ts +118 -2
  421. package/src/dashboard/loop-scheduler.ts +72 -0
  422. package/src/dashboard/seat-boot-preamble.ts +18 -0
  423. package/src/dashboard/skill-runtime.ts +2 -0
  424. package/src/dashboard/slash-runtime/dashboard-handlers.ts +126 -1181
  425. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
  426. package/src/dashboard/slash-runtime/index.ts +13 -0
  427. package/src/dashboard/turn-busy-teardown.ts +50 -0
  428. package/src/dashboard/turn-preamble.ts +116 -40
  429. package/src/dashboard/turn-session-layers.ts +4 -2
  430. package/src/dashboard/turn-start-segments.ts +222 -0
  431. package/src/decisions/decision-ledger.ts +45 -4
  432. package/src/discord-self-message.ts +4 -4
  433. package/src/display/prompt-row-owner.ts +146 -0
  434. package/src/display/resize-listener.ts +33 -2
  435. package/src/domains/release-tool.ts +18 -1
  436. package/src/field-note/transcribe.ts +17 -0
  437. package/src/fold-stack.ts +4 -2
  438. package/src/git-fs/index.ts +263 -36
  439. package/src/github/remote-call.ts +81 -0
  440. package/src/goals/registry.ts +46 -6
  441. package/src/goals/types.ts +7 -1
  442. package/src/graph-runner/runner.ts +1 -0
  443. package/src/grok/credential.ts +26 -0
  444. package/src/harness/gate-reserve.ts +87 -0
  445. package/src/harness/harness-clean.ts +2 -1
  446. package/src/harness/harness-cli-command.ts +52 -5
  447. package/src/harness/harness-gc.ts +2 -1
  448. package/src/harness/harness-incidents.ts +70 -20
  449. package/src/harness/harness-pod-dispatch.ts +87 -10
  450. package/src/harness/harness-queue.ts +68 -4
  451. package/src/harness/harness-stop.ts +4 -3
  452. package/src/harness/harness-substrate-default.ts +78 -7
  453. package/src/harness/harness-worktree-auto.ts +2 -1
  454. package/src/harness/harness-worktrees.ts +3 -2
  455. package/src/hooks/dispatch.ts +2 -1
  456. package/src/index.ts +156 -27
  457. package/src/input/external-input-queue.ts +64 -7
  458. package/src/intake-plane/slash.ts +14 -3
  459. package/src/keybindings.ts +4 -1
  460. package/src/llm/route-decision.ts +36 -0
  461. package/src/llm/tool-loop-steered-rejection.ts +41 -0
  462. package/src/llm-request-shape.ts +209 -0
  463. package/src/llm.ts +301 -283
  464. package/src/loops/consensus.ts +348 -0
  465. package/src/loops/msg-wake.ts +206 -4
  466. package/src/loops/observe.ts +19 -3
  467. package/src/loops/orchestrator/tick.ts +88 -12
  468. package/src/loops/orchestrator/traffic.ts +64 -1
  469. package/src/loops/registry.ts +30 -0
  470. package/src/market/signed-index.ts +14 -0
  471. package/src/maturity/feature-maturity.ts +1 -1
  472. package/src/mcp/mcp-oauth.ts +54 -5
  473. package/src/models/prompts.ts +28 -0
  474. package/src/msg/msg-sse-client.ts +223 -0
  475. package/src/msg/msg-store.ts +86 -2
  476. package/src/mss/logging/log-store.ts +225 -1
  477. package/src/mss/logging/render-categories.ts +5 -0
  478. package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
  479. package/src/nexus/api/http-server.ts +54 -15
  480. package/src/nexus/api/loop-resources.ts +19 -3
  481. package/src/nexus/api/ops-api.ts +11 -0
  482. package/src/nexus/daemon-thin-inventory.md +37 -0
  483. package/src/nexus/index.ts +70 -0
  484. package/src/nexus/state/state.ts +1 -0
  485. package/src/oauth/store.ts +32 -7
  486. package/src/onboarding/first-run.ts +28 -3
  487. package/src/ops/overview-cache.ts +16 -4
  488. package/src/ops/overview.ts +59 -2
  489. package/src/ops/resources.ts +82 -0
  490. package/src/plugins/maker/connector-maker.ts +41 -0
  491. package/src/plugins/maker/skill-maker.ts +42 -0
  492. package/src/pr-tool/census.ts +303 -0
  493. package/src/pr-tool/inflight-registry.ts +143 -0
  494. package/src/prompt-library/chat-conciseness.ts +13 -0
  495. package/src/prompt-library/universal-preamble.ts +10 -5
  496. package/src/pty-shell/pty-manifest.ts +12 -3
  497. package/src/pty-shell/tui-run-state.ts +34 -3
  498. package/src/release-loop/gate-host-reservation.ts +97 -0
  499. package/src/release-loop/landing-freeze.ts +5 -0
  500. package/src/release-loop/light-rc.ts +5 -2
  501. package/src/release-loop/placement.ts +92 -1
  502. package/src/release-loop/rehearsal-shard-plan.ts +149 -0
  503. package/src/release-loop/rehearsal.ts +73 -17
  504. package/src/repl/index.ts +20 -2
  505. package/src/seat-loop/seat-knowhow.ts +282 -0
  506. package/src/seat-loop/seat-loop.ts +41 -2
  507. package/src/seat-loop/traffic-signal.ts +5 -1
  508. package/src/self-dev/ask-launch-flow.ts +37 -3
  509. package/src/self-dev/decompose-compose-graph.ts +28 -27
  510. package/src/self-dev/decompose-proposal.ts +53 -38
  511. package/src/self-dev/decompose.ts +17 -0
  512. package/src/self-dev/dev-pipeline.ts +31 -2
  513. package/src/self-dev/draft-residue.ts +267 -33
  514. package/src/self-dev/draft-sweep.ts +59 -4
  515. package/src/self-dev/external-call-zero.ts +77 -0
  516. package/src/self-dev/launch-preflight-text.ts +6 -0
  517. package/src/self-dev/launch-preflight.ts +25 -3
  518. package/src/self-dev/local-supervisor-judge.ts +185 -0
  519. package/src/self-dev/run-supervisor.ts +229 -19
  520. package/src/self-dev/run-types.ts +20 -0
  521. package/src/self-dev/shard-aggregate.ts +13 -2
  522. package/src/self-dev/shard-plan.ts +56 -1
  523. package/src/self-dev/shard-run.ts +207 -12
  524. package/src/self-dev/spawn-lane-files.ts +19 -0
  525. package/src/self-implement/app-api-budget.ts +51 -11
  526. package/src/self-implement/config-gate.ts +2 -1
  527. package/src/self-implement/elanous-tui-spawn.ts +14 -0
  528. package/src/self-implement/expose-gate.ts +2 -1
  529. package/src/self-implement/follow-up-placement.ts +79 -0
  530. package/src/self-implement/gate-artifacts.ts +416 -0
  531. package/src/self-implement/gate-baseline.ts +96 -5
  532. package/src/self-implement/gate-cli.ts +207 -17
  533. package/src/self-implement/gate-remote.ts +136 -26
  534. package/src/self-implement/gate-scenario.ts +85 -0
  535. package/src/self-implement/goal-author.ts +160 -8
  536. package/src/self-implement/graph-authority.ts +38 -6
  537. package/src/self-implement/graph-overlay-condition.ts +92 -1
  538. package/src/self-implement/heal-triage.ts +79 -0
  539. package/src/self-implement/host-regate.ts +97 -7
  540. package/src/self-implement/orchestrator.ts +115 -134
  541. package/src/self-implement/pr-title.ts +123 -0
  542. package/src/self-implement/run-checkpoint.ts +235 -0
  543. package/src/self-implement/run-ledger.ts +162 -15
  544. package/src/self-implement/run-stop.ts +4 -3
  545. package/src/self-implement/run-ttl.ts +28 -4
  546. package/src/self-implement/seams.ts +2 -0
  547. package/src/self-implement/shadow-stage.ts +7 -6
  548. package/src/self-implement/stop-autoheal.ts +2 -1
  549. package/src/self-implement/train-gate-remote.ts +37 -8
  550. package/src/self-implement/train-reach-grouping.ts +157 -0
  551. package/src/self-implement/train-scenario-layers.ts +133 -0
  552. package/src/self-implement/uncommitted-work.ts +2 -0
  553. package/src/session/pending-input.ts +19 -0
  554. package/src/session/session-start.ts +224 -0
  555. package/src/session-runtime/index.ts +22 -267
  556. package/src/session-runtime/parallel-dispatch.ts +22 -5
  557. package/src/shell-runner/background-surface.ts +15 -5
  558. package/src/skills/tools/agent.ts +39 -6
  559. package/src/skills/tools/dev-harness.ts +6 -4
  560. package/src/skills/tools/list-dir.ts +11 -0
  561. package/src/skills/tools/schedule-wakeup.ts +408 -0
  562. package/src/skills/tools/shell.ts +246 -4
  563. package/src/status/bar.ts +26 -0
  564. package/src/steward/digest-delivery.ts +118 -0
  565. package/src/steward/hold-hygiene.ts +120 -0
  566. package/src/steward/resync-tick.ts +114 -23
  567. package/src/steward/ta-repair-event-collect.ts +158 -0
  568. package/src/steward/triage.ts +10 -0
  569. package/src/surface/shell-runner-boot.ts +5 -2
  570. package/src/task-agent/card-evidence.ts +25 -1
  571. package/src/task-agent/green-sweep.ts +8 -3
  572. package/src/task-agent/judge.ts +76 -0
  573. package/src/task-agent/land-queue.ts +79 -0
  574. package/src/task-agent/live-moves.ts +30 -9
  575. package/src/task-agent/postland-card.ts +5 -0
  576. package/src/task-agent/prelaunch-already-done.ts +98 -0
  577. package/src/task-agent/real-launch-guard.ts +37 -0
  578. package/src/task-agent/rejudge-on-head.ts +89 -12
  579. package/src/task-agent/remote-rejudge-bind.ts +28 -8
  580. package/src/task-agent/repair-cycle.ts +45 -7
  581. package/src/task-agent/repair-worker.ts +7 -0
  582. package/src/task-agent/run-identity.ts +200 -0
  583. package/src/task-agent/shadow.ts +50 -3
  584. package/src/task-agent/task-hand.ts +182 -5
  585. package/src/task-agent/train-landing.ts +77 -0
  586. package/src/task-agent/work-order.ts +104 -0
  587. package/src/task-orchestrator/surfaces/pod-command-job.ts +151 -37
  588. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
  589. package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
  590. package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
  591. package/src/task-orchestrator/surfaces/pod-install-slots.ts +121 -9
  592. package/src/task-orchestrator/surfaces/pod-lease.ts +118 -6
  593. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +1 -1
  594. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
  595. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +27 -0
  596. package/src/task-orchestrator/surfaces/pod-pool.ts +3 -1
  597. package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
  598. package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +67 -0
  599. package/src/task-orchestrator/surfaces/pod-source-receive.ts +19 -3
  600. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +141 -0
  601. package/src/task-orchestrator/surfaces/pod-warm-ta-shadow.ts +85 -0
  602. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +525 -0
  603. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
  604. package/src/task-orchestrator/surfaces/pod-warm-worker-runner.ts +90 -0
  605. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +362 -0
  606. package/src/task-orchestrator/surfaces/self-implement-pod.ts +138 -19
  607. package/src/telegram.ts +2 -4
  608. package/src/tui/chat/execution-badge.ts +5 -1
  609. package/src/tui/input/pickers.ts +732 -0
  610. package/src/tui/input-lag-probe.ts +230 -0
  611. package/src/tui/slash/mission.ts +492 -0
  612. package/src/tui/slash/term.ts +877 -0
  613. package/src/tui-client/dashboard-session.ts +9 -0
  614. package/src/tui.ts +52 -0
  615. package/src/user-config/gemini-server-tools.ts +9 -0
  616. package/src/user-config.ts +53 -16
  617. package/src/util/spawn-sync-output.ts +7 -0
  618. package/src/ux-sim/fake-bin.ts +154 -0
  619. package/src/ux-sim/fake-clock.ts +36 -0
  620. package/src/ux-sim/headless-tui.ts +72 -0
  621. package/src/ux-sim/in-process-cli.ts +2 -1
  622. package/src/ux-sim/scenario.ts +255 -0
  623. package/src/ux-sim/temp-git-remote.ts +82 -0
  624. package/src/version/packed-revision.json +1 -1
  625. package/src/video-pipeline/recipes/vlog.ts +25 -7
  626. package/apps/pwa/out/_next/static/chunks/1015-9cba22a5a4554797.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +0 -8
  630. package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +0 -34
  632. package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +0 -286
  635. package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +0 -24
  636. package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +0 -36
  639. package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +0 -64
  641. package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +0 -115
  647. package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +0 -90
  651. package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +0 -94
  662. package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +0 -62
  668. package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +0 -27
  671. package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +0 -104
  672. package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +0 -93
  673. package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +0 -24
  676. package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +0 -2
  678. package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +0 -148
  679. package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +0 -149
  680. package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +0 -79
  682. package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +0 -287
  688. package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +0 -77
  695. package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +0 -74
  698. package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +0 -226
  703. package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +0 -32
  705. package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/a435ad95.577add051b4facb2.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/app/botlab/page-a5635eba0d73b84e.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/loops/page-8aaa6dedc4c10dfb.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/morning/page-33bf667a5fb297bf.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/term/page-9eb56166774eb256.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9f92737b8766009a.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +0 -122
  768. package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +0 -1
  774. package/apps/pwa/out/_next/static/css/72becfd42807b50d.css +0 -1
  775. /package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → IVKr3AlRUVLKsw2fh7eXF}/_ssgManifest.js +0 -0
package/src/index.ts CHANGED
@@ -6,6 +6,7 @@ import { accessSync, constants as fsConstants, existsSync, lstatSync, readFileSy
6
6
  import type { SelfDevRunParticipant, SelfDevRunState } from './self-dev/run-store.js';
7
7
  import { applyConfigDirFlagFromArgv } from './cli/config-dir-flag.js';
8
8
  import { LOGS_SINCE_OPTION, registerLogsCommands } from './cli/logs-cli.js';
9
+ import { registerSimCommands } from './cli/sim-cli.js';
9
10
  import { registerDocsCommands } from './cli/docs-cli.js';
10
11
  import { registerBenchCommands } from './cli/bench-cli.js';
11
12
  import { registerRetroCommands } from './cli/retro-cli.js';
@@ -489,7 +490,17 @@ async function executeHarnessSelfRun(
489
490
  runId: string,
490
491
  startDraftTriage: typeof import('./self-dev/dev-cli.js')['startDraftTriage'],
491
492
  startDraftTriageOptions?: RunDevAskStartDraftTriageOptions,
493
+ entranceId?: EntranceId,
492
494
  ): Promise<Awaited<ReturnType<RunDevAskRunDevPipeline>>> {
495
+ // TA harness say/ask may be decomposed into parallel text goals before
496
+ // runDevPipeline reads the authored file. Check the original GOAL here,
497
+ // before any orchestrator or Pod child can be dispatched.
498
+ const isGoalFile = existsSync(input);
499
+ if (process.env.ELANOUS_TASK_CARD_ID?.trim() || isGoalFile) {
500
+ const { preflightGoalDoneBoundary } = await import('./self-dev/dev-pipeline.js');
501
+ preflightGoalDoneBoundary({ file: isGoalFile ? input : '<harness request>' }, isGoalFile ? readFileSync(input, 'utf8') : input,
502
+ process.env.ELANOUS_TASK_CARD_ID, entranceId, isGoalFile ? 'goal' : 'request');
503
+ }
493
504
  startDraftTriage(runId, startDraftTriageOptions);
494
505
  // 정지 요청의 «신선도» 기준 — 첫 런 «전»에 잰다(첫 런 도중의 정지도 이 호출의 것이다).
495
506
  const invocationStartedAtMs = Date.now();
@@ -651,6 +662,11 @@ async function runDevAskFromAskFile(askPath: string, opts: HarnessAskSayChildLlm
651
662
  },
652
663
  );
653
664
  if (flowResult.kind !== 'launch') {
665
+ // ⭐ 프리플라이트 거절은 «자식 결과» 봉투로 마지막 JSON 행을 남긴다 — Pod 원장(pod-failure-reason.nestedPodResult)이
666
+ // {ok, kind, result:{stage, blockers}} 중첩 행에서 사유 코드·검사 이름·경로를 읽는다. 나머지 중단은 기존대로 조용히 exit(1).
667
+ if (opts.json && flowResult.kind === 'stopped-by-preflight') {
668
+ await writeStdoutJson(`${JSON.stringify({ ok: false, kind: 'self', result: { stage: 'preflight-blocked', ok: false, blockers: flowResult.blockers } })}\n`);
669
+ }
654
670
  runDevAskFromGoalFileDeps.setExitCode(1);
655
671
  return;
656
672
  }
@@ -677,6 +693,7 @@ async function runDevAskFromAskFile(askPath: string, opts: HarnessAskSayChildLlm
677
693
  identity.runId,
678
694
  startDraftTriage,
679
695
  startDraftTriageOptions,
696
+ CLI_HARNESS_ASK_ENTRANCE.id,
680
697
  );
681
698
  const ok = devResultOk(result);
682
699
  if (opts.json) {
@@ -782,6 +799,7 @@ async function runDevAskFromGoalFile(goalPath: string, opts: HarnessAskSayChildL
782
799
  identity.runId,
783
800
  startDraftTriage,
784
801
  startDraftTriageOptions,
802
+ CLI_HARNESS_ASK_ENTRANCE.id,
785
803
  );
786
804
  const ok = devResultOk(result);
787
805
  if (opts.json) {
@@ -886,6 +904,7 @@ async function runDevSayFromWords(
886
904
  identity.runId,
887
905
  startDraftTriage,
888
906
  startDraftTriageOptions,
907
+ entrance,
889
908
  );
890
909
  const ok = devResultOk(result);
891
910
  if (opts.json) {
@@ -4319,10 +4338,15 @@ selfCmd
4319
4338
  .option('--base <ref>', '커밋됐지만 PR 없는 변경의 비교 기준(ref...HEAD)')
4320
4339
  .option('--pr <number>', '열린 PR 번호에서 gh pr view files로 변경 파일을 읽는다')
4321
4340
  .option('--shards [number]', '메모리 예산에 맞춰 시험을 별도 프로세스로 분할한다 (기본 2)')
4341
+ .option('--fixed-shard-distribution', '--shards N 과 함께만: RSS 사전 측정 없이 정렬된 파일을 N 조각에 라운드로빈 고정 배정한다(opt-in · 메모리 보증 아님 · 조각 타임아웃/OOM = unmeasured)')
4342
+ .option('--include-importers', '변경 모듈을 가져오는 importer 시험도 실행한다 (기본 caller 한도 밖까지)')
4322
4343
  .option('--remote [host]', 'GATE-REMOTE — 같은 커밋을 원격 호스트(기본 config gateRemote.host=node-b)에서 돌리고 결과만 가져온다(깨끗한 트리 · --pr 은 로컬)')
4323
4344
  .option('--local', '원격 자동 분배(로컬 1분 부하 > gateRemote.loadThreshold=20)를 끄고 로컬에서 돌린다')
4324
- .action(async (opts: { changed?: boolean; base?: string; pr?: string; shards?: string | boolean; remote?: string | boolean; local?: boolean }) => {
4345
+ .option('--artifact-dir <dir>', '조각별 지금/기준 JUnit ⊕ summary.json 을 이 디렉토리에 남긴다(판정 불변 · JUnit 은 --shards 경로만 · 원격 실행이면 그 호스트에서 가져온다)')
4346
+ .action(async (opts: { changed?: boolean; base?: string; pr?: string; shards?: string | boolean; fixedShardDistribution?: boolean; includeImporters?: boolean; remote?: string | boolean; local?: boolean; artifactDir?: string }) => {
4325
4347
  if (!opts.changed && opts.shards === undefined) { ui.error('self gate requires --changed or --shards'); process.exitCode = 2; return; }
4348
+ if (opts.fixedShardDistribution && opts.shards === undefined) { ui.error('self gate: --fixed-shard-distribution requires --shards <n>'); process.exitCode = 2; return; }
4349
+ if (opts.artifactDir !== undefined && !opts.artifactDir.trim()) { ui.error('self gate: --artifact-dir needs a non-empty directory'); process.exitCode = 2; return; }
4326
4350
  // The root strips `--local` from argv anywhere (remote-bookmark attach · src/cli/remote-resolve.ts) before Commander
4327
4351
  // sees it, so this subcommand reads it from the untouched process.argv.
4328
4352
  opts.local = !!opts.local || process.argv.slice(2).includes('--local');
@@ -4332,10 +4356,13 @@ selfCmd
4332
4356
  if (!isValidGateHost(opts.remote)) { ui.error(`self gate: invalid --remote host: ${opts.remote}`); process.exitCode = 2; return; }
4333
4357
  }
4334
4358
  const shards = opts.shards === undefined ? undefined : opts.shards === true ? 2 : Number(opts.shards);
4359
+ let ranLocal = false;
4360
+ let remoteArtifacts: { dir: string; fetch?: { ok: true; summaryPath: string; junitFiles: string[]; remoteDirKept: boolean } | { ok: false; reason: string } } | { unsupported: true } | undefined;
4335
4361
  const runLocal = () => {
4362
+ ranLocal = true;
4336
4363
  try {
4337
4364
  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 });
4365
+ 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
4366
  console.log(result.lines.join('\n'));
4340
4367
  return result.exitCode;
4341
4368
  } catch (error) {
@@ -4344,29 +4371,80 @@ selfCmd
4344
4371
  }
4345
4372
  };
4346
4373
  try {
4347
- const { dispatchHeavyCheck } = await import('./self-implement/gate-remote.js');
4374
+ const { dispatchHeavyCheck, remoteSelfGateArgv } = await import('./self-implement/gate-remote.js');
4348
4375
  const { runGitCommand } = await import('./git-fs/runner.js');
4349
4376
  const topLevel = runGitCommand(process.cwd(), ['rev-parse', '--show-toplevel'], { encoding: 'utf8' });
4350
4377
  if (topLevel.status !== 0) throw new Error(`git rev-parse --show-toplevel failed: ${topLevel.stderr.trim() || `rc=${topLevel.status}`}`);
4351
4378
  const repo = topLevel.stdout.trim();
4352
4379
  // 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.
4380
+ // reads files through gh on this host, and the remote checkout runs from the repository root — automatic placement
4381
+ // falls back locally; an explicit --remote reports that this check was not measured.
4354
4382
  const { realpathSync } = await import('node:fs');
4355
4383
  const localOnlyReason = opts.pr ? 'self gate --pr reads PR files through gh on this host'
4356
4384
  : !opts.base ? 'self gate without --base measures uncommitted files on this host'
4357
4385
  : realpathSync(repo) !== realpathSync(process.cwd()) ? 'self gate run from a sub-directory' : undefined;
4386
+ // SIDE-VERIFY-GATE-SHARDS ② — the host writes its artifacts outside its scratch tree (which its trap removes) and we
4387
+ // fetch them back after the run. Only when the measured commit knows --artifact-dir: an unknown option would kill the
4388
+ // remote CLI and change the verdict itself.
4389
+ if (opts.artifactDir !== undefined) {
4390
+ const { remoteCommitSupportsArtifactDir, newRemoteArtifactDir } = await import('./self-implement/gate-artifacts.js');
4391
+ remoteArtifacts = remoteCommitSupportsArtifactDir(repo) ? { dir: newRemoteArtifactDir() } : { unsupported: true };
4392
+ }
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
- 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)] : [])];
4394
+ const remoteArgv = (sha: (ref: string) => string) => remoteSelfGateArgv({
4395
+ changed: opts.changed, base: opts.base, shards, fixedShardDistribution: opts.fixedShardDistribution,
4396
+ includeImporters: opts.includeImporters,
4397
+ // A measured commit without this option rejects it (exit ≠ 0) — read as not passed, never as a silent measured run.
4398
+ artifactDir: remoteArtifacts && 'dir' in remoteArtifacts ? remoteArtifacts.dir : undefined,
4399
+ }, sha);
4400
+ const { gateHostReservationRoot } = await import('./release-loop/gate-host-reservation.js');
4361
4401
  process.exitCode = await dispatchHeavyCheck({
4362
- tool: 'self-gate', repo, installPwa: true, remoteArgv, refs: opts.base ? [opts.base] : [],
4402
+ tool: 'self-gate', repo, installPwa: true, remoteArgv, refs: opts.base ? [opts.base] : [], reservationRoot: gateHostReservationRoot(),
4363
4403
  localOnlyReason,
4404
+ explicitRemoteOnly: opts.remote !== undefined, reportRemoteHost: true,
4364
4405
  flags: { remote: typeof opts.remote === 'string' ? opts.remote : opts.remote ? true : undefined, local: !!opts.local },
4365
4406
  runLocal,
4407
+ ...(remoteArtifacts && 'dir' in remoteArtifacts && opts.artifactDir !== undefined ? {
4408
+ onRemoteOutcome: ((outcome, host, runner) => {
4409
+ const { fetchRemoteGateArtifacts, remoteArtifactCleanupScript, resolveArtifactDir } = require('./self-implement/gate-artifacts.js') as typeof import('./self-implement/gate-artifacts.js');
4410
+ const target = remoteArtifacts as { dir: string; fetch?: { ok: true; summaryPath: string; junitFiles: string[]; remoteDirKept: boolean } | { ok: false; reason: string } };
4411
+ if (outcome.kind === 'ran') {
4412
+ target.fetch = fetchRemoteGateArtifacts({ host, remoteDir: target.dir, localDir: resolveArtifactDir(opts.artifactDir!, process.cwd()), ssh: runner.ssh });
4413
+ } else if (outcome.kind === 'infra') {
4414
+ // The run may have started before it broke — remove the host-side dir; automatic placement's local fallback writes its own.
4415
+ try { runner.ssh(host, remoteArtifactCleanupScript(target.dir), 30_000); } catch { /* best effort */ }
4416
+ }
4417
+ }) satisfies NonNullable<import('./self-implement/gate-remote.js').DispatchOptions['onRemoteOutcome']>,
4418
+ } : {}),
4366
4419
  });
4367
4420
  } catch (error) {
4368
- ui.error(`self gate dispatch failed: ${error instanceof Error ? error.message : String(error)}`);
4369
- process.exitCode = runLocal();
4421
+ const reason = error instanceof Error ? error.message : String(error);
4422
+ if (opts.remote !== undefined) {
4423
+ ui.error(`self gate remote unmeasured — ${reason.replace(/\s+/g, ' ').trim()}`);
4424
+ process.exitCode = 1;
4425
+ } else {
4426
+ ui.error(`self gate dispatch failed: ${reason}`);
4427
+ process.exitCode = runLocal();
4428
+ }
4429
+ }
4430
+ // 원격에서 돌았으면 그 호스트의 산출을 가져와 같은 꼴로 썼다 — 못 가져왔으면 «조용히» 비우지 않고 summary 에 이유를 적는다(판정 불변).
4431
+ if (opts.artifactDir !== undefined && !ranLocal) {
4432
+ const fetched = remoteArtifacts && 'dir' in remoteArtifacts ? remoteArtifacts.fetch : undefined;
4433
+ try {
4434
+ if (fetched?.ok) {
4435
+ console.log(`artifacts: ${fetched.summaryPath} (junit ${fetched.junitFiles.length} · fetched from remote)`);
4436
+ if (fetched.remoteDirKept) console.log(`⚠ artifacts: 원격 산출 디렉토리를 못 지웠다 — ${(remoteArtifacts as { dir: string }).dir} (판정은 그대로다)`);
4437
+ }
4438
+ else {
4439
+ const reason = remoteArtifacts && 'unsupported' in remoteArtifacts ? 'remote-unsupported' as const : 'remote-fetch-failed' as const;
4440
+ if (reason === 'remote-fetch-failed') console.log(`⚠ artifacts: 원격 산출을 못 가져왔다 — ${fetched && !fetched.ok ? fetched.reason : 'no remote fetch ran'} (판정은 그대로다)`);
4441
+ const { writeRemoteUnavailableGateArtifacts } = await import('./self-implement/gate-artifacts.js');
4442
+ const written = writeRemoteUnavailableGateArtifacts(opts.artifactDir, process.cwd(), opts.base, Number(process.exitCode ?? 0), reason);
4443
+ console.log(`artifacts: ${written.summaryPath} (junit 0 · unavailable=${reason})`);
4444
+ }
4445
+ } catch (error) {
4446
+ console.log(`⚠ artifacts: ${opts.artifactDir} 에 못 썼다 — ${error instanceof Error ? error.message : String(error)} (판정은 그대로다)`);
4447
+ }
4370
4448
  }
4371
4449
  });
4372
4450
 
@@ -6098,6 +6176,7 @@ async function loadJevAccessOrExit(): Promise<import('./decide/jev.js').JevAcces
6098
6176
  registerIntakeCommands(program);
6099
6177
 
6100
6178
  registerLogsCommands(program);
6179
+ registerSimCommands(program);
6101
6180
 
6102
6181
  // ── ad (marketing-ad pipeline entrance) ──
6103
6182
  /** ⛔ 「있다」와 「읽을 수 있는 파일이다」는 다른 값 — 디렉토리·권한 없는 파일을 실사로 읽지 않는다. */
@@ -7505,7 +7584,7 @@ const selfDevCmd = program
7505
7584
  cfg: reloadUserConfig(),
7506
7585
  userText: text,
7507
7586
  explicitSessionId: chat.session,
7508
- reuseActive: !chat.forceNew,
7587
+ reuseActive: chat.continueActive === true,
7509
7588
  forceNew: chat.forceNew === true,
7510
7589
  json: chat.json === true,
7511
7590
  enableTools: chat.enableTools,
@@ -7790,7 +7869,7 @@ configCmd
7790
7869
  .command('set <path> <value>')
7791
7870
  .description('Set a dotted config path. Value is parsed as JSON when possible.')
7792
7871
  .option('--no-backup', "Don't write config.json.bak before saving")
7793
- .action((path: string, value: string, opts: { backup?: boolean }) => {
7872
+ .action(async (path: string, value: string, opts: { backup?: boolean }) => {
7794
7873
  const parsed = parseConfigValue(value);
7795
7874
  const cfg = getUserConfig() as unknown as Record<string, unknown>;
7796
7875
  const previousProvider = getConfigPath(cfg, 'llm.provider');
@@ -7809,6 +7888,7 @@ configCmd
7809
7888
  : undefined;
7810
7889
 
7811
7890
  if (opts.backup !== false) backupUserConfig(userConfigPath());
7891
+ const prev = getConfigPath(cfg, path); // CFG-STORE2 감사 이력 — 변경 «전» 값
7812
7892
  setConfigPath(cfg, path, parsed);
7813
7893
  if (credential?.apiKey && (credential.source === 'rotation' || credential.source === 'env')) {
7814
7894
  setConfigPath(cfg, 'llm.apiKey', credential.apiKey);
@@ -7822,6 +7902,8 @@ configCmd
7822
7902
  console.error(`⚠️ set ${path} — 저장 후 값 미반영(직렬화 드롭). 읽힌값=${JSON.stringify(after)}`);
7823
7903
  process.exit(1);
7824
7904
  }
7905
+ // CFG-STORE2 — 저장 «성공» 뒤 감사 이력 한 줄 · fail-open(기록 실패가 set 을 막지 않는다).
7906
+ 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
7907
  if (credential?.apiKey && (credential.source === 'rotation' || credential.source === 'env')) {
7826
7908
  ui.info(`provider credential updated: ${parsed} via ${credential.source} (${credential.apiKey.length} chars)`);
7827
7909
  } else if (credential?.source === 'none' && !isKeylessProvider(nextProvider)) {
@@ -7836,9 +7918,10 @@ configCmd
7836
7918
  .command('unset <path>')
7837
7919
  .description('Remove a dotted config path (set 의 역 · 배열 인덱스 지원). 이미 없으면 no-op.')
7838
7920
  .option('--no-backup', "Don't write config.json.bak before saving")
7839
- .action((path: string, opts: { backup?: boolean }) => {
7921
+ .action(async (path: string, opts: { backup?: boolean }) => {
7840
7922
  const cfg = getUserConfig() as unknown as Record<string, unknown>;
7841
- if (getConfigPath(cfg, path) === undefined) {
7923
+ const prev = getConfigPath(cfg, path); // CFG-STORE2 감사 이력 — 삭제 «전» 값
7924
+ if (prev === undefined) {
7842
7925
  ui.info(`unset ${path} — 이미 없음 (no-op)`);
7843
7926
  return;
7844
7927
  }
@@ -7852,6 +7935,8 @@ configCmd
7852
7935
  console.error(`⚠️ unset ${path} — 삭제 후에도 값 잔존. 남은값=${JSON.stringify(after)}`);
7853
7936
  process.exit(1);
7854
7937
  }
7938
+ // CFG-STORE2 — 삭제 저장 «성공» 뒤 감사 이력 한 줄 · fail-open(기록 실패가 unset 을 막지 않는다).
7939
+ 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
7940
  ui.info(`unset ${path}`);
7856
7941
  });
7857
7942
 
@@ -8050,6 +8135,7 @@ program
8050
8135
  reuseActive: opts.reuse === true,
8051
8136
  forceNew: false,
8052
8137
  json: opts.json === true,
8138
+ surface: 'ask',
8053
8139
  });
8054
8140
  });
8055
8141
 
@@ -8900,15 +8986,26 @@ function announceChatToolsCompatibility(): void {
8900
8986
 
8901
8987
  // ── chat (single-turn helper, non-TUI) ──
8902
8988
  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.')
8989
+ .command('chat [text...]')
8990
+ .description('Send one message in a new session (or a continued one with --continue/--resume/--session) and print the reply')
8991
+ .option('--new', 'Start a new session (the default since 0.2.31 — kept for compatibility)')
8992
+ .option('--continue', 'Continue the active session instead of starting a new one')
8993
+ .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.')
8994
+ .option('--session <id>', 'Continue an explicit session (id or unique prefix). Overrides --new, --continue and --resume.')
8907
8995
  .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
8996
  .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
8997
  .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
8998
  .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 }) => {
8999
+ .action(async (rawParts: string[], opts: { new?: boolean; continue?: boolean; resume?: string | boolean; session?: string; json?: boolean; tools?: boolean; goalLoop?: boolean; implement?: boolean }) => {
9000
+ // TUI-H8-FOLLOW ② — `chat --resume "질문"` 에서 Commander 가 질문 첫 낱말을 세션 id 로 먹지 않게.
9001
+ const { splitResumeArgument } = await import('./session/session-start.js');
9002
+ const split = splitResumeArgument(opts.resume, rawParts ?? [], 'chat', process.argv.slice(2));
9003
+ opts.resume = split.resume;
9004
+ const parts = split.parts;
9005
+ if (parts.length === 0) {
9006
+ console.error("error: missing required argument 'text'");
9007
+ process.exit(1);
9008
+ }
8912
9009
  if (getHarnessSpace() && opts.tools && opts.goalLoop && !opts.implement) {
8913
9010
  process.stderr.write('Harness chat goal-loop requires `dev --implement`; use that implementation entrypoint instead.\n');
8914
9011
  process.exitCode = 1;
@@ -8951,7 +9048,7 @@ program
8951
9048
  cfg: refreshed,
8952
9049
  userText: text,
8953
9050
  explicitSessionId: chat.session,
8954
- reuseActive: !chat.forceNew,
9051
+ reuseActive: chat.continueActive === true,
8955
9052
  forceNew: chat.forceNew === true,
8956
9053
  json: chat.json === true,
8957
9054
  enableTools: chat.enableTools,
@@ -8963,8 +9060,10 @@ program
8963
9060
  // ── repl (sticky multi-turn REPL) ──
8964
9061
  program
8965
9062
  .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')
9063
+ .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.')
9064
+ .option('--new', 'Start a new session at boot (the default since 0.2.31 — kept for compatibility)')
9065
+ .option('--continue', 'Continue the active session at boot instead of starting a new one')
9066
+ .option('--resume [id]', 'Continue a session at boot: the given id (or unique prefix), or the active session when no id is given')
8968
9067
  .option('--session <id>', 'Resume an explicit session (id or unique prefix)')
8969
9068
  .option('--scenario <path>', 'Run a YAML multi-turn scenario before handing back to interactive (or exit)')
8970
9069
  .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 +9074,8 @@ program
8975
9074
  .option('--stdin-jsonl', 'Force JSONL-on-stdin mode even when stdin is a TTY (useful for testing automation paths)')
8976
9075
  .action(async (opts: {
8977
9076
  new?: boolean;
9077
+ continue?: boolean;
9078
+ resume?: string | boolean;
8978
9079
  session?: string;
8979
9080
  scenario?: string;
8980
9081
  replay?: string;
@@ -8999,8 +9100,9 @@ program
8999
9100
  const exitAfterScenario = opts.exitAfterScenario === undefined ? exitDefault : opts.exitAfterScenario;
9000
9101
  const code = await runRepl({
9001
9102
  cfg: refreshed,
9002
- initialSessionId: opts.session,
9103
+ initialSessionId: opts.session ?? (typeof opts.resume === 'string' ? opts.resume : undefined),
9003
9104
  forceNew: opts.new === true,
9105
+ continueActive: opts.continue === true || opts.resume === true,
9004
9106
  enableTools: opts.tools !== false,
9005
9107
  scenarioPath: opts.scenario,
9006
9108
  replaySessionId: opts.replay,
@@ -11432,7 +11534,14 @@ voiceCmd
11432
11534
  });
11433
11535
 
11434
11536
  // ── Default: Dashboard (no subcommand) ──
11435
- const DASHBOARD_FLAGS = new Set(['--debug', '--chat-only', '--chat', '--yolo', '--benchmark']);
11537
+ const DASHBOARD_FLAGS = new Set(['--debug', '--chat-only', '--chat', '--yolo', '--benchmark', '--continue']);
11538
+
11539
+ /** 대표 #73 — `--resume` 뒤 토큰이 세션 id 인가(없거나 다른 플래그면 «id 없는 이어하기» = 최신 세션). */
11540
+ export function rootResumeIdAt(rawArgs: readonly string[], resumeFlagIdx: number): string | undefined {
11541
+ if (resumeFlagIdx < 0) return undefined;
11542
+ const next = rawArgs[resumeFlagIdx + 1];
11543
+ return next !== undefined && !next.startsWith('-') ? next : undefined;
11544
+ }
11436
11545
 
11437
11546
  export function filterDashboardArgs(rawArgs: readonly string[], resumeFlagIdx?: number): string[] {
11438
11547
  const rootResumeFlagIdx = resumeFlagIdx ?? rawArgs.findIndex((arg, index) =>
@@ -11447,7 +11556,8 @@ export function filterDashboardArgs(rawArgs: readonly string[], resumeFlagIdx?:
11447
11556
  return rawArgs.filter((a, i) => {
11448
11557
  if (!leadsWithSubcommand && (DASHBOARD_FLAGS.has(a) || a === '--rich')) return false;
11449
11558
  if (!leadsWithSubcommand && i === rootResumeFlagIdx) return false;
11450
- if (!leadsWithSubcommand && rootResumeFlagIdx >= 0 && i === rootResumeFlagIdx + 1) return false;
11559
+ if (!leadsWithSubcommand && rootResumeFlagIdx >= 0 && i === rootResumeFlagIdx + 1
11560
+ && rootResumeIdAt(rawArgs, rootResumeFlagIdx) !== undefined) return false;
11451
11561
  return true;
11452
11562
  });
11453
11563
  }
@@ -11645,13 +11755,32 @@ async function main(): Promise<void> {
11645
11755
  // 🩹 옛 손버릇은 `readRemoteFlag` 쪽 오류 문면이 «갈 곳을 말해» 받는다.
11646
11756
  arg === '--resume' && rawArgs.slice(0, index).every((prior) => prior.startsWith('-')),
11647
11757
  );
11648
- const resumeFromFlag = resumeFlagIdx >= 0 ? rawArgs[resumeFlagIdx + 1] : undefined;
11758
+ const resumeFromFlag = rootResumeIdAt(rawArgs, resumeFlagIdx);
11649
11759
  // Step 5 PR γ — env read routes through readDeprecatedEnv so the
11650
11760
  // user gets a one-shot deprecation warning when the env override
11651
11761
  // drives the resume path. CLI flag wins outright (no warning).
11652
11762
  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;
11763
+ // 대표 #73 — 인자 없는 `elanous` 는 새 세션. 이어하기는 `--resume <id>` · id 없는 `--resume` · `--continue`(= 최신 세션)일 때만.
11764
+ const leadsWithSubcommandForResume = rawArgs.length > 0 && !rawArgs[0]!.startsWith('-');
11765
+ const continueLatest = !leadsWithSubcommandForResume
11766
+ && (rawArgs.includes('--continue') || (resumeFlagIdx >= 0 && resumeFromFlag === undefined));
11767
+ // 우선순위: `--resume <id>` > `--continue`·id 없는 `--resume`(최신) > (폐기 예정) ELANOUS_RESUME_SESSION.
11768
+ // ⛔ 명시 인자가 있으면 환경변수가 이기지 않는다(TUI-H8 r1 must-fix).
11769
+ const { resolveLatestSessionId, resolveRootResumeSessionId } = await import('./session/session-start.js');
11770
+ const rootResume = resolveRootResumeSessionId({
11771
+ ...(resumeFromFlag !== undefined ? { flagId: resumeFromFlag } : {}),
11772
+ continueLatest,
11773
+ // 명시 인자가 있으면 env 를 «읽지도» 않는다(폐기 경고가 명시 이어하기에 섞이지 않게).
11774
+ readEnvId: () => readDeprecatedEnvForResume('ELANOUS_RESUME_SESSION').value ?? null,
11775
+ latest: () => resolveLatestSessionId({
11776
+ activeSessionId: () => getActiveSessionId(),
11777
+ latestSessionId: () => listSessions({ limit: 1 })[0]?.id ?? null,
11778
+ // TUI-H8-FOLLOW ① — 활성 표지가 사라진 세션이면 최신 세션으로(#28509 리뷰 should-fix).
11779
+ sessionExists: (id) => loadSession(id) !== null,
11780
+ }),
11781
+ });
11782
+ if (rootResume.source === 'continue-none') console.log('[elanous] --continue: 이어갈 세션이 없다 — 새 세션으로 시작한다');
11783
+ const resumeSessionId = rootResume.sessionId;
11655
11784
 
11656
11785
  // user-config can opt into benchmark mode persistently
11657
11786
  // (`dashboard.benchmark: true`) so callers don't have to retype the
@@ -12,6 +12,14 @@
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)에게 알린다.
18
+ // - ⏹ 원시 pty 길(TUI-STOP-RAW-PTY): `pty text pty_<id> /stop --enter`·tmux 처럼 TUI 를 띄운 «PTY 자체»에 쓰면
19
+ // 이 라우터를 안 지나 stdin 으로 들어오고, 턴 중 typeahead 가 «대기(응답 뒤)»에 쌓았다(10-17 재점검).
20
+ // ⇒ 턴 중 스트리밍 리스너가 stdin «한 청크»가 정확히 `/stop⏎`·`/esc⏎` 이면 `routeRawPtyStop` 으로 같은 `routeStop` 을 부른다.
21
+ // 키보드는 한 키씩 오고 붙여넣기는 봉투에 싸이므로, 한 청크에 온 «글 한 줄 ⊕ Enter» 는 바깥 주입이다.
22
+ // 턴 밖·Enter 없음·그 밖의 글은 종전대로 키로 흐른다(관측 `path: 'raw-pty'` · 제어 IPC 는 `'control-ipc'`).
15
23
  //
16
24
  // ⚠️ herdr/tmux 처럼 «터미널 자체»에 쓰는 길은 키보드와 구별할 수 없다 — 이 라우터는
17
25
  // elanous 제어 IPC(`pty text`) 경로만 가른다.
@@ -33,11 +41,17 @@ export interface ExternalInputHost {
33
41
  hasPendingKeys(): boolean;
34
42
  /** 별도 메시지로 제출한다. 못 보냈으면 false(항목은 대기열에 남는다). */
35
43
  submit(text: string, source: InputSourceRef): boolean;
36
- /** 대기열이 바뀌었다 — 화면 표지를 다시 그린다. */
37
- onQueueChange?(pending: readonly ExternalInputItem[], event: 'queued' | 'delivered'): void;
44
+ /** 지금 턴을 ESC 와 같은 경로로 멈춘다. 멈출 턴(escGate)이 없으면 false. 없으면 외부 stop 은 «턴 없음»으로 처리. */
45
+ requestStop?(): boolean;
46
+ /** 외부 stop 의 결과 표지(채팅 로그 한 줄). */
47
+ onExternalStop?(result: 'stopped' | 'no-turn' | 'failed'): void;
48
+ /** 대기열의 현재 상태가 바뀌었다 — 화면 표지를 다시 그린다. */
49
+ onQueueChange?(pending: readonly ExternalInputItem[]): void;
38
50
  }
39
51
 
40
- export type ExternalInputRoute = 'passthrough' | 'submitted' | 'queued';
52
+ export type ExternalInputRoute = 'passthrough' | 'submitted' | 'queued' | 'stopped';
53
+ /** 외부 stop 이 들어온 길 — 제어 IPC(`tui:<pid>` · 이 라우터) / 원시 pty(stdin 한 청크). */
54
+ export type ExternalStopPath = 'control-ipc' | 'raw-pty';
41
55
  export type ExternalInputDecision = 'passthrough' | 'submit-now' | 'queue' | 'reject';
42
56
 
43
57
  const EXTERNAL_INPUT_SOURCE: InputSourceRef = { kind: 'terminal', provider: 'pty' };
@@ -57,6 +71,11 @@ export function parseExternalTextLine(chars: string): { text: string; submit: bo
57
71
  return { text, submit };
58
72
  }
59
73
 
74
+ /** 외부 «멈춰» 명령인가 — 정확히 `/stop` 또는 `/esc`(앞뒤 공백·대소문자 변형은 일반 글). */
75
+ export function isExternalStopCommand(text: string): boolean {
76
+ return text === '/stop' || text === '/esc';
77
+ }
78
+
60
79
  /** 라우팅 판정(순수). */
61
80
  export function decideExternalInputRoute(input: {
62
81
  line: { text: string; submit: boolean } | null;
@@ -102,11 +121,14 @@ export interface ExternalInputQueueDeps {
102
121
  /** 펌프 스케줄러 — 정지 함수를 돌려준다. 시험이 손으로 돌린다. */
103
122
  schedule?: (tick: () => void, ms: number) => () => void;
104
123
  log?: (event: string, data: Record<string, unknown>) => void;
124
+ /** 외부 stop 관측 — 기본 `debug.log('tui.input', …)`. */
125
+ logInput?: (event: string, data: Record<string, unknown>) => void;
105
126
  }
106
127
 
107
128
  export function createExternalInputQueue(deps: ExternalInputQueueDeps = {}) {
108
129
  const now = deps.now ?? Date.now;
109
130
  const log = deps.log ?? ((event, data) => debug.log('tui.external-input', event, data));
131
+ const logInput = deps.logInput ?? ((event, data) => debug.log('tui.input', event, data));
110
132
  const schedule = deps.schedule ?? ((tick, ms) => {
111
133
  const t = setInterval(tick, ms);
112
134
  (t as { unref?: () => void }).unref?.();
@@ -118,8 +140,8 @@ export function createExternalInputQueue(deps: ExternalInputQueueDeps = {}) {
118
140
  // 경고는 머리 항목 «하나»에 한 번 — 머리가 실제로 바뀔 때만 다시 경고할 수 있다(제출 실패로 남은 같은 머리는 유지).
119
141
  let staleTurnWarnedHead: ExternalInputItem | null = null;
120
142
 
121
- const notify = (event: 'queued' | 'delivered'): void => {
122
- try { host?.onQueueChange?.(pending, event); } catch { /* fail-soft — 표지 실패가 입력을 막지 않는다 */ }
143
+ const notify = (): void => {
144
+ try { host?.onQueueChange?.(pending); } catch { /* fail-soft — 표지 실패가 입력을 막지 않는다 */ }
123
145
  };
124
146
  const ensurePump = (): void => {
125
147
  if (pending.length > 0 && !stopPump) stopPump = schedule(pump, PUMP_MS);
@@ -148,16 +170,33 @@ export function createExternalInputQueue(deps: ExternalInputQueueDeps = {}) {
148
170
  if (!ok) { log('deliver-failed', { length: head.text.length, pending: pending.length }); return false; }
149
171
  pending = pending.slice(1);
150
172
  log('delivered', { length: head.text.length, waitedMs: now() - head.at, pending: pending.length });
151
- notify('delivered');
173
+ notify();
152
174
  ensurePump();
153
175
  return true;
154
176
  }
155
177
 
178
+ /** ⏹ 외부 stop — 대기열을 건너뛰고 지금 턴의 escGate 로. 대기열은 건드리지 않는다. */
179
+ function routeStop(h: ExternalInputHost, text: string, path: ExternalStopPath): ExternalInputRoute {
180
+ let turnActive = false;
181
+ try { turnActive = h.isTurnActive(); } catch { turnActive = false; }
182
+ let stopped = false;
183
+ if (turnActive && h.requestStop) {
184
+ try { stopped = h.requestStop(); } catch { stopped = false; }
185
+ }
186
+ logInput('external-stop', { hadTurn: turnActive, stopped, command: text, pending: pending.length, path });
187
+ const result = stopped ? 'stopped' : turnActive ? 'failed' : 'no-turn';
188
+ try { h.onExternalStop?.(result); } catch { /* fail-soft */ }
189
+ if (result === 'no-turn') throw new Error('tui-stop-no-active-turn');
190
+ if (result === 'failed') throw new Error('tui-stop-undelivered');
191
+ return 'stopped';
192
+ }
193
+
156
194
  return {
157
195
  register(next: ExternalInputHost): () => void {
158
196
  host = next;
159
197
  log('host-registered', { pending: pending.length });
160
198
  ensurePump();
199
+ if (pending.length > 0) notify();
161
200
  return () => {
162
201
  if (host !== next) return;
163
202
  host = null;
@@ -169,6 +208,7 @@ export function createExternalInputQueue(deps: ExternalInputQueueDeps = {}) {
169
208
  // `pty key`(input-key)는 «키»다 — 공백·`j` 처럼 출력 가능한 키도 종전대로 넣는다.
170
209
  if (keyCommandDepth > 0) return 'passthrough';
171
210
  const line = parseExternalTextLine(chars);
211
+ if (line && host && isExternalStopCommand(line.text)) return routeStop(host, line.text, 'control-ipc');
172
212
  let turnActive = false; let composer: string | undefined; let pendingKeys = false;
173
213
  if (host && line) {
174
214
  try { turnActive = host.isTurnActive(); composer = host.composerText(); pendingKeys = host.hasPendingKeys(); }
@@ -197,10 +237,26 @@ export function createExternalInputQueue(deps: ExternalInputQueueDeps = {}) {
197
237
  }
198
238
  pending = [...pending, { text: line!.text, at: now() }];
199
239
  log('route', { ...base, route: 'queued', pending: pending.length });
200
- notify('queued');
240
+ notify();
201
241
  ensurePump();
202
242
  return 'queued';
203
243
  },
244
+ /**
245
+ * ⏹ 원시 pty 길 — 턴 중 stdin «한 청크»가 정확히 `/stop⏎`·`/esc⏎` 이면 `routeStop` 으로 보내고 true(키로 흘리지 않는다).
246
+ * 턴 밖·호스트 없음·Enter 없음·그 밖의 글은 false — 호출측이 종전대로 키를 넣는다.
247
+ */
248
+ routeRawStop(chunk: string): boolean {
249
+ const h = host;
250
+ if (!h) return false;
251
+ const line = parseExternalTextLine(chunk);
252
+ if (!line?.submit || !isExternalStopCommand(line.text)) return false;
253
+ let turnActive = false;
254
+ try { turnActive = h.isTurnActive(); } catch { turnActive = false; }
255
+ if (!turnActive) return false;
256
+ // 'failed'(중단 경로 없음)도 소비한다 — 표지(Esc 로 멈춰 주세요)는 routeStop 이 이미 남겼다.
257
+ try { routeStop(h, line.text, 'raw-pty'); } catch { /* 결과는 이벤트·표지로 남았다 */ }
258
+ return true;
259
+ },
204
260
  pump,
205
261
  pending: (): readonly ExternalInputItem[] => pending,
206
262
  };
@@ -217,3 +273,4 @@ const shared = createExternalInputQueue();
217
273
 
218
274
  export function registerExternalInputHost(host: ExternalInputHost): () => void { return shared.register(host); }
219
275
  export function routeExternalInput(chars: string): ExternalInputRoute { return shared.route(chars); }
276
+ export function routeRawPtyStop(chunk: string): boolean { return shared.routeRawStop(chunk); }
@@ -497,9 +497,20 @@ export async function resolveIntakeSlash(
497
497
  reason: target.ok ? undefined : target.reason,
498
498
  });
499
499
  if (!target.ok) return { output: target.reason, action: 'noop', session };
500
- const runPipeline = deps.runPipeline ?? runIntakePipelinePhases;
501
- const pipelineCallables = deps.pipelineCallables ?? buildRealIntakeCallables();
502
- const pipeline = await runPipeline({ rawText: session.raw.rawText, intakeId }, pipelineCallables);
500
+ // Injected runPipeline ignores callables; skip eager
501
+ // buildRealIntakeCallables() so a keyless HOME does not throw
502
+ // NoLlmProviderAvailableError before the injected pipeline runs.
503
+ // When runPipeline is absent, keep resolving callables the same way
504
+ // so a real keyless user setup error still comes from the builder.
505
+ const pipeline = deps.runPipeline
506
+ ? await deps.runPipeline(
507
+ { rawText: session.raw.rawText, intakeId },
508
+ deps.pipelineCallables ?? {},
509
+ )
510
+ : await runIntakePipelinePhases(
511
+ { rawText: session.raw.rawText, intakeId },
512
+ deps.pipelineCallables ?? buildRealIntakeCallables(),
513
+ );
503
514
  const tasks = pipeline.enriched.missions.flatMap((mission) => mission.tasks);
504
515
  if (tasks.length === 0) {
505
516
  return {
@@ -104,11 +104,14 @@ export const KEYBINDINGS: KeyBinding[] = [
104
104
 
105
105
  // ── Chat input ───────────────────────────────────────────
106
106
  { keys: ['Enter'], action: 'Submit message or slash command', context: 'input' },
107
- { keys: ['Shift+Enter', 'Ctrl+J'], action: 'Insert newline', context: 'input' },
107
+ { keys: ['Shift+Enter', 'Alt+Enter', 'Ctrl+J'], action: 'Insert newline', context: 'input', note: 'Shift+Enter 가 안 되는 터미널은 Alt+Enter / Ctrl+J' },
108
108
  { keys: ['Ctrl+Shift+V'], action: 'Paste clipboard image', context: 'input' },
109
109
  { keys: ['Ctrl+T'], action: 'Toggle → pane mode', context: 'input', note: 'also Ctrl+M on Kitty-protocol terminals' },
110
110
  { keys: ['Tab'], action: 'Autocomplete slash command / path', context: 'input' },
111
111
  { keys: ['Esc'], action: 'Abort current stream or exit input', context: 'input' },
112
+ { keys: ['Enter (while answering)'], action: 'Queue message — inserted at the next tool boundary', context: 'input', note: '10-14 steer' },
113
+ { keys: ['Enter on empty input (while answering)'], action: 'Push queued messages now — interrupt if running tools are cancelable, else first at next boundary', context: 'input', note: '10-14 steer' },
114
+ { keys: ['Ctrl+↑'], action: 'Recall all queued messages into the input', context: 'input', note: '10-14 — was last one only' },
112
115
 
113
116
  // ── Browsers (files / obsidian / skills) ─────────────────
114
117
  { keys: ['j', '↓'], action: 'Move cursor down', context: 'browser' },
@@ -40,12 +40,48 @@ const lastBySurface = new Map<string, RouteDecision>();
40
40
 
41
41
  export function recordCurrentRouteDecision(surface: string, decision: RouteDecision): void {
42
42
  lastBySurface.set(surface, decision);
43
+ // 새 턴의 결정이 서면 지난 턴의 «실제 실행»은 더는 이 턴의 것이 아니다.
44
+ executionBySurface.delete(surface);
43
45
  }
44
46
 
45
47
  export function currentRouteDecision(surface: string): RouteDecision | null {
46
48
  return lastBySurface.get(surface) ?? null;
47
49
  }
48
50
 
51
+ /** 이번 턴에 «실제로» 응답한 공급자·모델(TUI-MODEL-BADGE-ACTUAL · 10-16).
52
+ * 결정(`RouteDecision`)은 턴 «시작»에 고른 값이고, 폴백 체인이 다른 공급자로 넘기면 실제는 달라진다.
53
+ * ACP 사용량 봉투(`routeProvider`·`model`)로 들어온다 — 이 표면이 결정을 세운 in-process 세션만 적는다.
54
+ * ⚠️ 지금 읽는 곳은 완료 배지뿐이다. 상태줄·`/model` «지금:» 의 원천 통일은 후속 칸 TUI-MODEL-BADGE-SOURCE. */
55
+ export interface RouteExecution {
56
+ provider?: string;
57
+ model: string;
58
+ }
59
+
60
+ const executionBySurface = new Map<string, RouteExecution>();
61
+
62
+ export function recordRouteExecution(surface: string, execution: RouteExecution): void {
63
+ executionBySurface.set(surface, execution);
64
+ }
65
+
66
+ export function currentRouteExecution(surface: string): RouteExecution | null {
67
+ return executionBySurface.get(surface) ?? null;
68
+ }
69
+
70
+ /** 표면의 결정·실행을 비운다(세션 핀은 사람의 선택이라 남긴다) — 짝이 안 맞는 턴(원격 등)에서 지난 «A → B» 가
71
+ * 다시 보이지 않게 한다(r5 리뷰). */
72
+ export function clearSurfaceRouteDecision(surface: string): void {
73
+ lastBySurface.delete(surface);
74
+ executionBySurface.delete(surface);
75
+ }
76
+
77
+ /** 턴이 고른 모델과 실제로 응답한 모델이 다르면 «처음 → 실제», 아니면 null(꾸미지 않는다). */
78
+ export function routeFallbackLabel(surface: string): string | null {
79
+ const decision = lastBySurface.get(surface);
80
+ const execution = executionBySurface.get(surface);
81
+ if (!decision?.model || !execution?.model || execution.model === decision.model) return null;
82
+ return `${decision.model} → ${execution.model}`;
83
+ }
84
+
49
85
  /** A `/model` choice scoped to this process's surface (TUI-MODEL-SESSION-SCOPE · 10-14).
50
86
  * It reaches the turn as `explicitModel`, so it wins over the Codex tier policy —
51
87
  * a config-only `llm.model` change is ignored by that policy (10-14 OPT: `/model luna`