elanous 0.2.29 → 0.2.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (709) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → LSXfY0u9QtfDbejY0Ukf_}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{058a98ba.7eb28d5e6dc03565.js → 0bb0ff36.b8d418980951e5ba.js} +7 -7
  5. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +27 -0
  8. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +287 -0
  9. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +62 -0
  10. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/{6013-2f769370d8b4c2c6.js → 1335-6731f392c35216eb.js} +3 -3
  12. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/{8332.6f0f49df772e163b.js → 1654.32de4b324981a188.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/1834-50625904996a8fa8.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +149 -0
  17. package/apps/pwa/out/_next/static/chunks/{8795.32573a185af18c7b.js → 1913.7cc6fb6055b1ed3f.js} +2 -2
  18. package/apps/pwa/out/_next/static/chunks/{419.736c0d6f426249a7.js → 2001.6c7e0fd02190886c.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{6767.1fcfc9b8be83975f.js → 2213.2ccbada92c33ea0f.js} +16 -16
  24. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/{4759.1f76713aefb87db5.js → 2871.0bca6137343b3f76.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/{6776.06ff1e3b464cc607.js → 2898.fd781bc7cf01a7b7.js} +1 -1
  29. package/apps/pwa/out/_next/static/chunks/{1782-59db1b5aa06df38a.js → 2940-619bfd8ef337c611.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/{8471.8d2a8c74f09c36ff.js → 2985.39ccdecd36848b12.js} +4 -4
  31. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +115 -0
  32. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +64 -0
  33. package/apps/pwa/out/_next/static/chunks/{bc324b7c.02a09dd93f6a399b.js → 3267c0e6.d34854e7b3984a6e.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/3278.2e5d15b53a4091c8.js +2 -0
  35. package/apps/pwa/out/_next/static/chunks/{7725-4f83d5541fbdb81b.js → 3541-ce3a5424ed5ad7f1.js} +1 -1
  36. package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3902.e1e71aaac850a045.js +34 -0
  39. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/{46bd8bea.2f4b4099172fcdb7.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
  41. package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/{1142.65d002789ab3af7d.js → 4174.92ed04922709ac9e.js} +2 -2
  43. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +36 -0
  45. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +286 -0
  49. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +77 -0
  50. package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +226 -0
  51. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +79 -0
  53. package/apps/pwa/out/_next/static/chunks/5173-233188df2f42c626.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +148 -0
  57. package/apps/pwa/out/_next/static/chunks/5307.60f2209e809bd627.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{3396-97b97928c49190c9.js → 5458-16cd7a2b51b74c8c.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/{3403.7199205e65124486.js → 5525.86debf231e181813.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{9143.ff14585db1d275ff.js → 5543.a438b8ab5a13ea47.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +74 -0
  65. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +94 -0
  67. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{8398.73a19b39715eda04.js → 6092.a7f99e68b188ca66.js} +1 -1
  70. package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/{5591.a35e7a217734a8b9.js → 6157.0c9af021de4fb31b.js} +2 -2
  72. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/{7375.050ea0d72968e49f.js → 6433.fc573af22bbc9ab7.js} +17 -17
  75. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +90 -0
  77. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +32 -0
  78. package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +104 -0
  80. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +24 -0
  85. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +93 -0
  86. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{1852.7f7b53991fcb99ef.js → 7502.ccd5b8065545edd0.js} +2 -2
  93. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +8 -0
  94. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{6534.1ab00f370db7b105.js → 7862.30a8d6482bb238eb.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/{285adb1a.5654e605dddf86d2.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/8097-92f87bd108322f66.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +24 -0
  109. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{1516.dfaceff3fd2d0e0d.js → 9138.b6e80031afb1d973.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/{9907.49be0fcadaf214b5.js → 9221.7d22eaf353a2d4e7.js} +1 -1
  113. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/{8767-2f6a634f5abeaa01.js → 9279-d28c5b7754d010ae.js} +1 -1
  115. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{3160-95c96f4d2a21dd26.js → 9398-6aed28f0a96d0d6f.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/{328bb3ab-6628a1114fe3fb3b.js → 997ce8a5-2ad501927003b41b.js} +1 -1
  121. package/apps/pwa/out/_next/static/chunks/{6853.cc5174a9dee59593.js → 9989.3694300e5f000b14.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-bf3634a117322df7.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-3535a4a69f1fafaa.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-b9f51447f757fbf2.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-a5635eba0d73b84e.js → page-2ebb8fd59b9461f9.js} +1 -1
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-a2fc4e49a4fa4ba8.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-5a503541353e60a8.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-6025101384e361a5.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-f4b630cc8b5273cd.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-a645f00a06483e9a.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-61ac22cbab1ee4ec.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e9bab7413b028b28.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-c992eafe028b642e.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-e547e6ce55f1fb33.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-d27e1b9850fd54bf.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-805ac2e137b7a121.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-0fec29c7ba01894b.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-339a07410cd6f36b.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-349f2752d8cd37ad.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-d5c6dcf31c25cecc.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-2fd93ed8c9f16580.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-9b564dbff0fefc35.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-62f4475d3c38fb9b.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-814ba51385225776.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-397d479626e5a459.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-af1bba4e3251b728.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ad3be5e7d3fdce9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-f219ccdbc0bf27df.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4da93ad35d4a8d28.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-456666766e5ce6fc.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-7404e377e8adb8c5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-14456240ed2a36ad.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-3a658d5fa6d16a25.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-0157de6e85f8bb6b.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-0a07363b130182a1.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-841d73d4ac44ed49.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6f43a3d1146e6377.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/{page-29900ed0011b2c83.js → page-521ee23ac8c0abfa.js} +1 -1
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-a9992ee285efaa83.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-3d48e85fa89ec04f.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d2ced71132fac9b2.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-f08358bdf251adb9.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-233c71cd5f68f0d7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-70151d78de2f375e.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-dcac33a3e2cb72c0.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/{page-9f92737b8766009a.js → page-149dc1caba411bb9.js} +1 -1
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0448145ccd5c45c1.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-9cb0c444903da65d.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-17e504c396e0e389.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{425cfc4d.fb91158e3971c39f.js → b313b242.cb1265eea908db61.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +122 -0
  175. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +1 -0
  183. package/apps/pwa/out/_next/static/css/{72becfd42807b50d.css → 3f5fc6f96e2cf7b2.css} +1 -1
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +23 -23
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +23 -23
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +23 -23
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +22 -22
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +22 -22
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +23 -23
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +22 -22
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +23 -23
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +23 -23
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +22 -22
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +23 -23
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +23 -23
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +23 -23
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +23 -23
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +22 -22
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +22 -22
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +23 -23
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +23 -23
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +23 -23
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +22 -22
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +22 -22
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +23 -23
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +23 -23
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +22 -22
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +22 -22
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +22 -22
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +23 -23
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +23 -23
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +22 -22
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +23 -23
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +23 -23
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +23 -23
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +23 -23
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +23 -23
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +22 -22
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +23 -23
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +23 -23
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +23 -23
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +23 -23
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +23 -23
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +23 -23
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +23 -23
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +23 -23
  277. package/bin/elanous.mjs +7 -3
  278. package/graphs/context/nightly-condense.yaml +1 -0
  279. package/graphs/intake/intake-daily.yaml +8 -1
  280. package/graphs/intake/recipes.yaml +5 -0
  281. package/graphs/lecture/lecture-note.yaml +2 -2
  282. package/graphs/ops/harness-gc.yaml +1 -0
  283. package/graphs/release/recipes.yaml +3 -0
  284. package/graphs/release/release-loop.yaml +9 -5
  285. package/graphs/units/recipes.yaml +3 -0
  286. package/graphs/units/release-gate-recheck.yaml +15 -0
  287. package/package.json +2 -1
  288. package/scripts/check-native-tool-wiring.ts +3 -2
  289. package/scripts/ci-android-unit-tests.ts +16 -0
  290. package/scripts/ci-typecheck-changed.ts +37 -9
  291. package/scripts/coord-channel-watch.sh +22 -16
  292. package/scripts/coord-role-pack.ts +81 -2
  293. package/scripts/cron-run.ts +96 -3
  294. package/scripts/detect-test-interference.ts +38 -5
  295. package/scripts/gate-pr-cache.ts +65 -0
  296. package/scripts/gh-surface/capture.ts +126 -0
  297. package/scripts/gh-surface/gh +40 -0
  298. package/scripts/import-graph-scc.ts +38 -0
  299. package/scripts/install.ps1 +19 -0
  300. package/scripts/intake-social.ts +181 -0
  301. package/scripts/lecture-note/node.ts +71 -4
  302. package/scripts/lib/android-toolchain.ts +32 -0
  303. package/scripts/lib/deterministic-env.ts +62 -0
  304. package/scripts/lib/gate-test-env.ts +19 -0
  305. package/scripts/measure-goal-grounding-corpus.ts +2 -1
  306. package/scripts/ratchets/test-interference-patterns.allowlist.txt +257 -0
  307. package/scripts/ratchets/test-interference-patterns.ts +367 -0
  308. package/scripts/release-loop/cut-branch.ts +4 -3
  309. package/scripts/release-loop/export-check-node.ts +0 -1
  310. package/scripts/release-loop/fixtures/warm-failure-assertion/sample.junit.xml +8 -0
  311. package/scripts/release-loop/fixtures/warm-job-029/sample.json +1 -0
  312. package/scripts/release-loop/fixtures/warm-job-029/sample.junit.xml +10 -0
  313. package/scripts/release-loop/gate-closure.ts +12 -8
  314. package/scripts/release-loop/gate-diff.ts +1 -1
  315. package/scripts/release-loop/gate-host-mirror.ts +66 -0
  316. package/scripts/release-loop/gate-node.ts +523 -75
  317. package/scripts/release-loop/gate-partial.ts +106 -9
  318. package/scripts/release-loop/gate-pr-cache.ts +66 -0
  319. package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
  320. package/scripts/release-loop/gate-r2-verdict.ts +189 -0
  321. package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
  322. package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
  323. package/scripts/release-loop/import-graph-scc-run.ts +54 -0
  324. package/scripts/release-loop/import-graph-scc.ts +215 -0
  325. package/scripts/release-loop/node-verdict.ts +2 -0
  326. package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
  327. package/scripts/release-loop/resume-release.ts +33 -4
  328. package/scripts/release-loop/resume.ts +13 -5
  329. package/scripts/release-loop/spawn-lane.ts +2 -19
  330. package/scripts/release-loop/tui-sim-node.ts +3 -2
  331. package/scripts/release-loop/unattended-release.ts +16 -0
  332. package/scripts/test-deterministic.ts +5 -61
  333. package/scripts/train-reach-grouping.ts +48 -0
  334. package/scripts/tsc-incremental-cache.ts +86 -0
  335. package/scripts/tsc-incremental-diagnostics.ts +76 -0
  336. package/scripts/tsc-main-safety-net.ts +2 -2
  337. package/src/acp/client.ts +4 -1
  338. package/src/acp/core-turn-bridge.ts +50 -5
  339. package/src/ad-pipeline/run.ts +4 -2
  340. package/src/agent/runner.ts +169 -3
  341. package/src/agent/subagent-callable.ts +3 -2
  342. package/src/agent-mission/review-loop.ts +6 -3
  343. package/src/agent-substrate/acp-implementer.ts +14 -2
  344. package/src/agent-substrate/pr-reviewer.ts +12 -0
  345. package/src/agent-substrate/self-review-cli.ts +30 -4
  346. package/src/autopilot/pr-manager.ts +62 -7
  347. package/src/briefing/brief-items.ts +24 -22
  348. package/src/capture/tui-self-report.ts +15 -0
  349. package/src/chat/chat-cli.ts +10 -2
  350. package/src/chat/index.ts +77 -11
  351. package/src/chat/input-control-key.ts +5 -3
  352. package/src/chat/tool-interrupt-behavior.ts +38 -0
  353. package/src/chat/tool-render/dispatch.ts +5 -1
  354. package/src/chat/turn-typeahead.ts +75 -20
  355. package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
  356. package/src/cli/agent-cli.ts +41 -13
  357. package/src/cli/config-audit.ts +123 -0
  358. package/src/cli/decisions-cli.ts +80 -6
  359. package/src/cli/log-event-names.ts +7 -0
  360. package/src/cli/mcp-login.ts +21 -5
  361. package/src/cli/msg-cli.ts +88 -0
  362. package/src/cli/pr-cli.ts +214 -57
  363. package/src/cli/pr-land-heavy-remote.ts +2 -2
  364. package/src/cli/pr-land-overlap-evidence.ts +63 -9
  365. package/src/cli/pr-land-pod-shadow-job.ts +83 -0
  366. package/src/cli/pr-land-pod-shadow.ts +16 -3
  367. package/src/cli/pr-land-virtual-rebase.ts +108 -0
  368. package/src/cli/release-cli.ts +80 -14
  369. package/src/cli/seat-cli.ts +138 -3
  370. package/src/cli/self-update.ts +5 -2
  371. package/src/cli/tasks-cli.ts +97 -19
  372. package/src/context-bus/context-first.ts +13 -0
  373. package/src/context-bus/context-now.ts +13 -2
  374. package/src/context-bus/ops-events.ts +75 -0
  375. package/src/control-plane/lease-holder.ts +12 -8
  376. package/src/control-plane/ledger.ts +163 -4
  377. package/src/control-plane/server.ts +91 -11
  378. package/src/core-turn/run-core-turn.ts +1 -0
  379. package/src/core-turn/run-goal-loop.ts +222 -3
  380. package/src/core-turn/seat-turn-cap.ts +79 -0
  381. package/src/core-turn/short-question.ts +38 -6
  382. package/src/core-turn/types.ts +3 -0
  383. package/src/dashboard/acp-boot.ts +3 -0
  384. package/src/dashboard/index.ts +224 -615
  385. package/src/dashboard/input/chat-main-entry-runtime.ts +1 -1
  386. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +4 -1
  387. package/src/dashboard/input/chat-main-session.ts +8 -1
  388. package/src/dashboard/input/chat-main-turn.ts +12 -3
  389. package/src/dashboard/input/compact-prepass-recovery.ts +33 -0
  390. package/src/dashboard/input/external-input-host.ts +26 -0
  391. package/src/dashboard/input/internal-turn.ts +261 -0
  392. package/src/dashboard/input/seat-autowake.ts +318 -0
  393. package/src/dashboard/input/turn-steer-bridge.ts +70 -0
  394. package/src/dashboard/loop-scheduler.ts +72 -0
  395. package/src/dashboard/seat-boot-preamble.ts +18 -0
  396. package/src/dashboard/skill-runtime.ts +2 -0
  397. package/src/dashboard/slash-runtime/dashboard-handlers.ts +126 -1181
  398. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
  399. package/src/dashboard/slash-runtime/index.ts +13 -0
  400. package/src/dashboard/turn-busy-teardown.ts +50 -0
  401. package/src/decisions/decision-ledger.ts +45 -4
  402. package/src/discord-self-message.ts +4 -4
  403. package/src/domains/release-tool.ts +18 -1
  404. package/src/field-note/transcribe.ts +17 -0
  405. package/src/github/remote-call.ts +81 -0
  406. package/src/goals/registry.ts +46 -6
  407. package/src/goals/types.ts +7 -1
  408. package/src/graph-runner/runner.ts +1 -0
  409. package/src/grok/credential.ts +26 -0
  410. package/src/harness/harness-clean.ts +2 -1
  411. package/src/harness/harness-cli-command.ts +52 -5
  412. package/src/harness/harness-gc.ts +2 -1
  413. package/src/harness/harness-incidents.ts +57 -20
  414. package/src/harness/harness-pod-dispatch.ts +87 -10
  415. package/src/harness/harness-queue.ts +53 -4
  416. package/src/harness/harness-stop.ts +4 -3
  417. package/src/harness/harness-substrate-default.ts +78 -7
  418. package/src/harness/harness-worktree-auto.ts +2 -1
  419. package/src/harness/harness-worktrees.ts +3 -2
  420. package/src/hooks/dispatch.ts +2 -1
  421. package/src/index.ts +152 -25
  422. package/src/input/external-input-queue.ts +33 -1
  423. package/src/intake-plane/slash.ts +14 -3
  424. package/src/keybindings.ts +4 -1
  425. package/src/llm/tool-loop-steered-rejection.ts +33 -0
  426. package/src/llm.ts +138 -19
  427. package/src/loops/consensus.ts +348 -0
  428. package/src/loops/msg-wake.ts +206 -4
  429. package/src/loops/observe.ts +19 -3
  430. package/src/loops/orchestrator/tick.ts +64 -10
  431. package/src/loops/orchestrator/traffic.ts +64 -1
  432. package/src/loops/registry.ts +30 -0
  433. package/src/market/signed-index.ts +14 -0
  434. package/src/mcp/mcp-oauth.ts +54 -5
  435. package/src/models/prompts.ts +28 -0
  436. package/src/msg/msg-sse-client.ts +223 -0
  437. package/src/msg/msg-store.ts +86 -2
  438. package/src/mss/logging/log-store.ts +225 -1
  439. package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
  440. package/src/nexus/api/http-server.ts +54 -15
  441. package/src/nexus/api/loop-resources.ts +19 -3
  442. package/src/nexus/api/ops-api.ts +11 -0
  443. package/src/nexus/daemon-thin-inventory.md +37 -0
  444. package/src/nexus/index.ts +70 -0
  445. package/src/nexus/state/state.ts +1 -0
  446. package/src/oauth/store.ts +32 -7
  447. package/src/onboarding/first-run.ts +28 -3
  448. package/src/ops/overview-cache.ts +16 -4
  449. package/src/ops/resources.ts +82 -0
  450. package/src/plugins/maker/connector-maker.ts +41 -0
  451. package/src/plugins/maker/skill-maker.ts +42 -0
  452. package/src/pr-tool/census.ts +288 -0
  453. package/src/prompt-library/chat-conciseness.ts +13 -0
  454. package/src/prompt-library/universal-preamble.ts +10 -5
  455. package/src/release-loop/gate-host-reservation.ts +97 -0
  456. package/src/release-loop/landing-freeze.ts +5 -0
  457. package/src/release-loop/light-rc.ts +5 -2
  458. package/src/release-loop/placement.ts +92 -1
  459. package/src/release-loop/rehearsal-shard-plan.ts +149 -0
  460. package/src/release-loop/rehearsal.ts +73 -17
  461. package/src/repl/index.ts +20 -2
  462. package/src/seat-loop/seat-knowhow.ts +282 -0
  463. package/src/seat-loop/seat-loop.ts +41 -2
  464. package/src/seat-loop/traffic-signal.ts +3 -0
  465. package/src/self-dev/ask-launch-flow.ts +24 -3
  466. package/src/self-dev/decompose-compose-graph.ts +28 -27
  467. package/src/self-dev/decompose-proposal.ts +53 -38
  468. package/src/self-dev/decompose.ts +17 -0
  469. package/src/self-dev/dev-pipeline.ts +31 -2
  470. package/src/self-dev/draft-residue.ts +24 -9
  471. package/src/self-dev/draft-sweep.ts +59 -4
  472. package/src/self-dev/external-call-zero.ts +77 -0
  473. package/src/self-dev/launch-preflight-text.ts +6 -0
  474. package/src/self-dev/launch-preflight.ts +25 -3
  475. package/src/self-dev/local-supervisor-judge.ts +185 -0
  476. package/src/self-dev/run-supervisor.ts +229 -19
  477. package/src/self-dev/run-types.ts +20 -0
  478. package/src/self-dev/shard-aggregate.ts +13 -2
  479. package/src/self-dev/shard-plan.ts +47 -0
  480. package/src/self-dev/shard-run.ts +112 -10
  481. package/src/self-dev/spawn-lane-files.ts +19 -0
  482. package/src/self-implement/app-api-budget.ts +51 -11
  483. package/src/self-implement/config-gate.ts +2 -1
  484. package/src/self-implement/expose-gate.ts +2 -1
  485. package/src/self-implement/gate-artifacts.ts +405 -0
  486. package/src/self-implement/gate-cli.ts +201 -16
  487. package/src/self-implement/gate-remote.ts +110 -25
  488. package/src/self-implement/gate-scenario.ts +85 -0
  489. package/src/self-implement/goal-author.ts +160 -8
  490. package/src/self-implement/graph-authority.ts +38 -6
  491. package/src/self-implement/graph-overlay-condition.ts +92 -1
  492. package/src/self-implement/heal-triage.ts +79 -0
  493. package/src/self-implement/host-regate.ts +61 -3
  494. package/src/self-implement/orchestrator.ts +14 -123
  495. package/src/self-implement/pr-title.ts +123 -0
  496. package/src/self-implement/run-checkpoint.ts +235 -0
  497. package/src/self-implement/run-ledger.ts +155 -10
  498. package/src/self-implement/run-stop.ts +4 -3
  499. package/src/self-implement/run-ttl.ts +28 -4
  500. package/src/self-implement/seams.ts +2 -0
  501. package/src/self-implement/shadow-stage.ts +7 -6
  502. package/src/self-implement/stop-autoheal.ts +2 -1
  503. package/src/self-implement/train-gate-remote.ts +37 -8
  504. package/src/self-implement/train-reach-grouping.ts +157 -0
  505. package/src/self-implement/train-scenario-layers.ts +133 -0
  506. package/src/self-implement/uncommitted-work.ts +2 -0
  507. package/src/session/pending-input.ts +19 -0
  508. package/src/session/session-start.ts +224 -0
  509. package/src/session-runtime/parallel-dispatch.ts +22 -5
  510. package/src/skills/tools/dev-harness.ts +6 -4
  511. package/src/skills/tools/shell.ts +1 -1
  512. package/src/steward/resync-tick.ts +114 -23
  513. package/src/steward/ta-repair-event-collect.ts +158 -0
  514. package/src/task-agent/card-evidence.ts +25 -1
  515. package/src/task-agent/green-sweep.ts +8 -3
  516. package/src/task-agent/judge.ts +76 -0
  517. package/src/task-agent/land-queue.ts +79 -0
  518. package/src/task-agent/live-moves.ts +30 -9
  519. package/src/task-agent/postland-card.ts +5 -0
  520. package/src/task-agent/prelaunch-already-done.ts +98 -0
  521. package/src/task-agent/real-launch-guard.ts +37 -0
  522. package/src/task-agent/rejudge-on-head.ts +89 -12
  523. package/src/task-agent/remote-rejudge-bind.ts +28 -8
  524. package/src/task-agent/repair-cycle.ts +45 -7
  525. package/src/task-agent/repair-worker.ts +7 -0
  526. package/src/task-agent/run-identity.ts +200 -0
  527. package/src/task-agent/shadow.ts +50 -3
  528. package/src/task-agent/task-hand.ts +158 -5
  529. package/src/task-agent/train-landing.ts +77 -0
  530. package/src/task-agent/work-order.ts +104 -0
  531. package/src/task-orchestrator/surfaces/pod-command-job.ts +88 -28
  532. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
  533. package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
  534. package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
  535. package/src/task-orchestrator/surfaces/pod-install-slots.ts +121 -9
  536. package/src/task-orchestrator/surfaces/pod-lease.ts +20 -6
  537. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
  538. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +27 -0
  539. package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
  540. package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +63 -0
  541. package/src/task-orchestrator/surfaces/pod-source-receive.ts +19 -3
  542. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +141 -0
  543. package/src/task-orchestrator/surfaces/pod-warm-ta-shadow.ts +85 -0
  544. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
  545. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +208 -0
  546. package/src/task-orchestrator/surfaces/self-implement-pod.ts +132 -15
  547. package/src/telegram.ts +2 -4
  548. package/src/tui/input/pickers.ts +732 -0
  549. package/src/tui/slash/mission.ts +492 -0
  550. package/src/tui/slash/term.ts +877 -0
  551. package/src/tui-client/dashboard-session.ts +9 -0
  552. package/src/tui.ts +48 -0
  553. package/src/user-config/gemini-server-tools.ts +9 -0
  554. package/src/user-config.ts +53 -16
  555. package/src/util/spawn-sync-output.ts +7 -0
  556. package/src/ux-sim/fake-bin.ts +154 -0
  557. package/src/ux-sim/fake-clock.ts +36 -0
  558. package/src/ux-sim/headless-tui.ts +72 -0
  559. package/src/ux-sim/in-process-cli.ts +2 -1
  560. package/src/ux-sim/temp-git-remote.ts +82 -0
  561. package/src/version/packed-revision.json +1 -1
  562. package/src/video-pipeline/recipes/vlog.ts +25 -7
  563. package/apps/pwa/out/_next/static/chunks/1015-9cba22a5a4554797.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +0 -8
  567. package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +0 -34
  569. package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +0 -286
  572. package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +0 -24
  573. package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +0 -36
  576. package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +0 -64
  578. package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +0 -115
  584. package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +0 -90
  588. package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +0 -94
  599. package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +0 -62
  605. package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +0 -27
  608. package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +0 -104
  609. package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +0 -93
  610. package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +0 -24
  613. package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +0 -2
  615. package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +0 -148
  616. package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +0 -149
  617. package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +0 -79
  619. package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +0 -287
  625. package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +0 -77
  632. package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +0 -74
  635. package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +0 -226
  640. package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +0 -32
  642. package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/a435ad95.577add051b4facb2.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/loops/page-8aaa6dedc4c10dfb.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/morning/page-33bf667a5fb297bf.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/term/page-9eb56166774eb256.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +0 -122
  703. package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +0 -1
  709. /package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → LSXfY0u9QtfDbejY0Ukf_}/_ssgManifest.js +0 -0
@@ -17,6 +17,7 @@ import { DEFAULT_BRANCH_WORKTREE_BASE } from '../git-fs/worktree.js';
17
17
  import { isElanousRuntimeArtifactPath } from '../self-implement/gate-scope.js';
18
18
  import { isTransientExecutionFailure } from '../self-dev/execution-transient.js';
19
19
  import { withGhRestFallback } from './gh-rest-fallback.js';
20
+ import { cellIdFromBody, guardNewPr, parseDiffHunks, readOpenPrs, recordGuardUnmeasured, type GuardVerdict, type Seat } from '../pr-tool/census.js';
20
21
 
21
22
  /** ★ stderr 캡처(대표 2026-07-21·관측 갭) — 종전엔 stdout 만 담아 git/gh 실패 사유가 소실됐다
22
23
  * (705308: makePr 실패가 bare null 로 뭉뚱그려져 triage 가 "인증·네트워크"로 환각 오라우팅).
@@ -99,6 +100,8 @@ export interface UpsertPrInput {
99
100
  draft?: boolean;
100
101
  /** PR 라벨 — 신규 생성 시 `--label`, 재사용 시 `--add-label` 로 부착(무인 리뷰 진입 라벨이 재실행에도 유지). */
101
102
  labels?: readonly string[];
103
+ /** Harness caller's seat; stamped on newly created PRs for later census. */
104
+ seat?: Seat;
102
105
  /** 기존 PR 재사용 시 남길 코멘트(재구현 반영 안내·비평 해소). */
103
106
  reuseComment?: string;
104
107
  /**
@@ -115,7 +118,7 @@ export interface UpsertPrResult { url: string; reused: boolean }
115
118
  * 나머지 reason(add/commit/push/gh)은 진짜 실패로 detail(stderr)과 함께 관측·pr-failed. */
116
119
  export type UpsertPrOutcome =
117
120
  | { ok: true; url: string; reused: boolean; labelsApplied?: boolean; labelsOmitted?: boolean }
118
- | { ok: false; reason: 'add' | 'commit' | 'base' | 'noop' | 'push' | 'gh'; detail: string };
121
+ | { ok: false; reason: 'add' | 'commit' | 'base' | 'noop' | 'push' | 'gh' | 'guard'; detail: string };
119
122
 
120
123
  /** 관측된 문면 두 가지:
121
124
  * could not add label: 'auto-review' not found
@@ -312,9 +315,29 @@ function isTransientPushFailure(detail: string): boolean {
312
315
  return isTransientExecutionFailure(pushFailureMessageForTransientCheck(detail));
313
316
  }
314
317
 
318
+ function seatFromEnvironment(): Seat | null {
319
+ // Production launchers stamp this in harness-pod-dispatch.ts and harness-cli-command.ts.
320
+ const value = process.env.ELANOUS_HARNESS_SEAT;
321
+ return value === 'OP' || value === 'TC' || value === 'MK' || value === 'UX' ? value : null;
322
+ }
323
+
324
+ function defaultPrCreateGuard(input: { cwd: string; base: string | undefined; seat: Seat | null; body: string }, run: CmdRunner): GuardVerdict {
325
+ if (!input.base) return guardNewPr({ files: null, seat: input.seat }, { status: 'unknown', reason: '비교 base 없음' });
326
+ const diff = run('git', ['-C', input.cwd, 'diff', '--name-only', '-z', `${input.base}...HEAD`]);
327
+ const files = diff.ok ? diff.out.split('\0').filter(Boolean) : null;
328
+ const patch = run('git', ['-C', input.cwd, 'diff', '--unified=0', `${input.base}...HEAD`]);
329
+ if (!patch.ok) return guardNewPr({ files: null, seat: input.seat }, { status: 'unknown', reason: `후보 수정 줄 조회 실패: ${patch.err || patch.out}` });
330
+ return guardNewPr({ files, seat: input.seat, cellId: cellIdFromBody(input.body), hunks: parseDiffHunks(patch.out) }, readOpenPrs(run, { cwd: input.cwd, ...(files ? { candidateFiles: files } : {}) }));
331
+ }
332
+
315
333
  /** ★ PR 매니저 팩토리(대표 2026-07-12) — CmdRunner 주입(테스트 스텁). 실 배선은 기본 러너. */
316
- export function makePrManager(runner: CmdRunner = defaultCmdRunner): PrManager {
334
+ export function makePrManager(
335
+ runner: CmdRunner = defaultCmdRunner,
336
+ createGuard?: (input: { cwd: string; base: string | undefined; seat: Seat | null; body: string }, run: CmdRunner) => GuardVerdict,
337
+ recordUnmeasured: typeof recordGuardUnmeasured = recordGuardUnmeasured,
338
+ ): PrManager {
317
339
  const run = withGhRestFallback(runner);
340
+ const checkCreate = createGuard ?? (runner === defaultCmdRunner ? defaultPrCreateGuard : undefined);
318
341
  const findPrForBranchOutcome = (branch: string, cwd?: string): FindPrForBranchOutcome => {
319
342
  // ⛔ 표식은 base 를 「생략했다」는 뜻이지 브랜치 이름이 아니다. 그대로 `gh --head` 로 넘기면
320
343
  // gh 가 `no pull requests found for branch "elanous:default-branch"` 를 stderr 로 뱉는다.
@@ -499,8 +522,8 @@ export function makePrManager(runner: CmdRunner = defaultCmdRunner): PrManager {
499
522
  // 트림은 신규 경로(resolveDeliverableBase)와 동일하게 — 공백 전용 base 는 미지정으로 본다(리뷰 should-fix).
500
523
  const explicitBase = input.base?.trim();
501
524
  if (explicitBase && !isBranchSelfRef(explicitBase, input.branch)) editArgs.push('--base', prBaseFromComparison(explicitBase));
502
- for (const label of input.labels ?? []) if (label.trim()) editArgs.push('--add-label', label.trim());
503
- const edited = run('gh', editArgs, opts);
525
+ for (const label of new Set((input.labels ?? []).map(label => label.trim()).filter(Boolean))) editArgs.push('--add-label', label);
526
+ let edited = run('gh', editArgs, opts);
504
527
  if (!edited.ok) return { ok: false, reason: 'gh', detail: detailOf(edited) || 'gh pr edit 실패' };
505
528
  if (input.draft !== undefined) {
506
529
  // 현재 draft 상태 조회 — 조회 실패/비정상 출력은 fail-closed(요청 draft 를 적용 못했는데
@@ -522,13 +545,43 @@ export function makePrManager(runner: CmdRunner = defaultCmdRunner): PrManager {
522
545
  if (input.reuseComment) run('gh', ['pr', 'comment', existing.url, '--body', input.reuseComment], opts);
523
546
  return { ok: true, url: existing.url, reused: true };
524
547
  }
548
+ let guardUnmeasured = false;
549
+ if (checkCreate) {
550
+ const seat = input.seat ?? seatFromEnvironment();
551
+ const verdict = checkCreate({ cwd, base: comparisonBase, seat, body: input.body }, run);
552
+ if (verdict.status === 'unknown' && verdict.reasons.length === 1 && verdict.reasons[0]?.code === 'inventory-unknown') {
553
+ const inPod = process.env.ELANOUS_SUBSTRATE === 'pod'
554
+ || Object.keys(process.env).some(key => key.startsWith('ELANOUS_POD_'));
555
+ if (inPod) {
556
+ // Pod state and mailbox are local to this Job. Count and alert only
557
+ // in the host parent, where the shared instance root is authoritative.
558
+ debug.log('pr-tool.open-guard', 'pod-unmeasured', { seat, reason: verdict.reasons[0].detail });
559
+ } else {
560
+ const count = recordUnmeasured({ seat, reason: verdict.reasons[0].detail });
561
+ if (count.blocked) {
562
+ const alert = run('eln', ['msg', 'post', '--from', seat ?? 'HARNESS', '--to', 'OP', '--kind', 'alert', '--body', `PR open-guard 판정 불가 1시간 ${count.count}회 · 새 PR 차단 · ${count.reason ?? verdict.reasons[0].detail}`]);
563
+ if (!alert.ok) debug.log('pr-tool.open-guard', 'op-alert-failed', { seat, reason: alert.err || alert.out || 'eln msg post 실패' });
564
+ return { ok: false, reason: 'guard', detail: `inventory-unknown: 1시간 ${count.count}회 · 새 PR 차단${count.reason ? ` (${count.reason})` : ''}` };
565
+ }
566
+ }
567
+ guardUnmeasured = true;
568
+ } else if (verdict.status !== 'allow') {
569
+ return { ok: false, reason: 'guard', detail: verdict.reasons.map(reason => `${reason.code}: ${reason.detail}${reason.prs?.length ? ` (${reason.prs.map(number => `#${number}`).join(', ')})` : ''}`).join('; ') };
570
+ }
571
+ }
525
572
  const createArgs = ['pr', 'create', '--head', input.branch, '--title', input.title, '--body', input.body];
526
573
  if (prBase) createArgs.push('--base', prBase);
527
574
  if (input.draft) createArgs.push('--draft');
528
- const requestedLabels = (input.labels ?? []).map((label) => label.trim()).filter(Boolean);
575
+ const seat = input.seat ?? seatFromEnvironment();
576
+ const requiredLabels = [...(seat ? [`seat:${seat}`] : []), ...(guardUnmeasured ? ['pr-guard:unmeasured'] : [])];
577
+ const requestedLabels = [...new Set([...(input.labels ?? []), ...requiredLabels].map((label) => label.trim()).filter(Boolean))];
529
578
  const labeledArgs = [...createArgs];
530
579
  for (const label of requestedLabels) labeledArgs.push('--label', label);
531
- const created = run('gh', labeledArgs, opts);
580
+ let created = run('gh', labeledArgs, opts);
581
+ if (!created.ok && requiredLabels.length && isLabelNotFoundFailure(created, requiredLabels)) {
582
+ for (const label of requiredLabels) run('gh', ['label', 'create', label, '--color', 'BFDADC'], opts);
583
+ created = run('gh', labeledArgs, opts);
584
+ }
532
585
  if (created.ok && created.out) {
533
586
  return {
534
587
  ok: true,
@@ -538,7 +591,9 @@ export function makePrManager(runner: CmdRunner = defaultCmdRunner): PrManager {
538
591
  };
539
592
  }
540
593
  if (requestedLabels.length > 0 && isLabelNotFoundFailure(created, requestedLabels)) {
541
- const retry = run('gh', createArgs, opts);
594
+ const retryArgs = [...createArgs];
595
+ for (const label of requiredLabels) retryArgs.push('--label', label);
596
+ const retry = run('gh', retryArgs, opts);
542
597
  if (retry.ok && retry.out) {
543
598
  debug.log('autopilot.pr-manager', 'create.labels-omitted', {
544
599
  branch: input.branch,
@@ -105,6 +105,25 @@ function needsDecision(item: BriefItem, today: string): boolean {
105
105
  return item.priority === 'P0' || (item.deadline !== null && deadlineDate(item.deadline) === today);
106
106
  }
107
107
 
108
+ /**
109
+ * Reorder BRIEF_DOMAINS from already-recorded weekly action rates.
110
+ * Domains with total>0 sort by action rate (not raw event count).
111
+ * Domains with total=0 keep their relative fixed BRIEF_DOMAINS order.
112
+ * Missing rate data returns the default BRIEF_DOMAINS order unchanged.
113
+ */
114
+ export function orderBriefDomains(actions?: BriefWeeklyActions | null): BriefDomain[] {
115
+ if (actions == null) return [...BRIEF_DOMAINS];
116
+ const byKind = actions.byKind;
117
+ if (!BRIEF_DOMAINS.some(domain => (byKind[domain]?.total ?? 0) > 0)) return [...BRIEF_DOMAINS];
118
+ return [...BRIEF_DOMAINS].sort((a, b) => {
119
+ const xTotal = byKind[a]?.total ?? 0;
120
+ const yTotal = byKind[b]?.total ?? 0;
121
+ const xRate = xTotal > 0 ? byKind[a]!.rate : 0;
122
+ const yRate = yTotal > 0 ? byKind[b]!.rate : 0;
123
+ return yRate - xRate || BRIEF_DOMAINS.indexOf(a) - BRIEF_DOMAINS.indexOf(b);
124
+ });
125
+ }
126
+
108
127
  /** Unsent decisions needing immediate delivery, using the same KST deadline rule as slot pages. */
109
128
  export function pendingRealtime(items: readonly BriefItem[], now: Date): BriefItem[] {
110
129
  const today = dateKey(now, { timeZone: KST });
@@ -113,8 +132,9 @@ export function pendingRealtime(items: readonly BriefItem[], now: Date): BriefIt
113
132
 
114
133
  /**
115
134
  * One briefing page. Item text is copied verbatim.
116
- * Order: decisions due (P0, then a deadline of today) → domain groups →
117
- * duplicate claims dropped (same normalized sentence, most urgent kept).
135
+ * Order: decisions due (P0, then a deadline of today) → domain groups ordered
136
+ * by recorded weekly action rate (sampled high-rate first; zero-sample kinds
137
+ * keep BRIEF_DOMAINS order) → duplicate claims dropped (same normalized sentence, most urgent kept).
118
138
  */
119
139
  export function composeBriefMarkdown(items: readonly BriefItem[], slot: BriefSlot, now: Date): string {
120
140
  return composeBriefPage(items, slot, now).markdown;
@@ -124,7 +144,6 @@ export function composeBriefMarkdown(items: readonly BriefItem[], slot: BriefSlo
124
144
  export function composeBriefPage(
125
145
  items: readonly BriefItem[], slot: BriefSendSlot, now: Date,
126
146
  actions?: BriefWeeklyActions,
127
- observedKinds?: ReadonlySet<BriefDomain>,
128
147
  ): { markdown: string; ids: number[] } {
129
148
  const today = dateKey(now, { timeZone: KST });
130
149
  // A duplicate left out of a delivered page stays unsent in the ledger, but must not reappear on a later page.
@@ -151,17 +170,7 @@ export function composeBriefPage(
151
170
  for (const item of decisions) lines.push(itemLine(item));
152
171
  lines.push('');
153
172
  }
154
- const domains = [...BRIEF_DOMAINS];
155
- // Measured action leads. An unobserved kind keeps its normal position; a sent-but-unobserved
156
- // item is not evidence of being ignored. Keep every domain heading in this first slice.
157
- if (actions && Object.values(actions.byKind).some(count => count.acted > 0)) {
158
- domains.sort((a, b) => {
159
- const x = actions.byKind[a], y = actions.byKind[b];
160
- const xRate = observedKinds?.has(a) ? x.rate : 0;
161
- const yRate = observedKinds?.has(b) ? y.rate : 0;
162
- return yRate - xRate || BRIEF_DOMAINS.indexOf(a) - BRIEF_DOMAINS.indexOf(b);
163
- });
164
- }
173
+ const domains = orderBriefDomains(actions);
165
174
  for (const domain of domains) {
166
175
  const group = unique.filter(item => item.domain === domain && !decisionIds.has(item.id));
167
176
  if (group.length === 0) continue;
@@ -463,14 +472,7 @@ export class BriefItemsLedger {
463
472
  this.log('briefing.items', 'requirement-funnel-failed', { slot, error: error instanceof Error ? error.message : String(error) });
464
473
  }
465
474
  }
466
- const since = this.weekStart(now);
467
- const until = now.toISOString();
468
- const observedKinds = new Set((db.query(`SELECT DISTINCT i.domain FROM items i
469
- JOIN reactions r ON r.item_id = i.id
470
- WHERE r.reacted_at >= ? AND r.reacted_at <= ? AND EXISTS (
471
- SELECT 1 FROM sends s WHERE s.item_id = i.id AND s.sent_at >= ? AND s.sent_at <= ?
472
- )`).all(since, until, since, until) as Array<{ domain: BriefDomain }>).map(row => row.domain));
473
- const composed = composeBriefPage([...items, ...funnelItems], slot, now, this.weeklyActionsFromDb(db, now), observedKinds);
475
+ const composed = composeBriefPage([...items, ...funnelItems], slot, now, this.weeklyActionsFromDb(db, now));
474
476
  // Ephemeral funnel lines appear on the page but have no ledger row to mark sent.
475
477
  const page = { markdown: composed.markdown, ids: composed.ids.filter(id => id > 0) };
476
478
  const candidates = (slot === 'realtime' ? pendingRealtime(items, now) : items.filter(item => item.sent_at === null && beforeSlot(item.created_at, slot, now))).length;
@@ -185,6 +185,8 @@ export interface TuiSelfReportDeps {
185
185
  reportControlCleanupFailure?: (stage: TuiControlCleanupStage, error: unknown) => void;
186
186
  /** 행 등록 직후 실행 판 ⊕ 턴(idle) 기록을 연다 — `elanous pty state` 가 읽는다. 반환 = 정리. */
187
187
  startRunState?: (surfaceId: string) => (() => void);
188
+ /** 미룬 우편 깨움 폴러(TUI-H4)를 연다 — 반환 = 정리. 기본은 실 행 등록과 짝일 때만 늦게 불러온 `startPendingWakePoller`. */
189
+ startWakePoller?: (surfaceId: string) => (() => void);
188
190
  }
189
191
 
190
192
  export type TuiControlInitStage = 'create-target' | 'register-target' | 'start-poller' | 'publish-manifest';
@@ -263,6 +265,17 @@ export function startTuiSelfReport(deps: TuiSelfReportDeps = {}): () => void {
263
265
  // 행 등록을 갈아 끼운 호출자(시험)는 실 manifest 를 안 건드린다 — 기본 녹음기는 기본 행 등록과 짝일 때만.
264
266
  const startRunState = deps.startRunState ?? (deps.registerRow ? () => () => {} : startTuiRunStateRecorder);
265
267
  try { stopRunState = startRunState(surfaceId); } catch { /* fail-soft — recorder logs its own write failures */ }
268
+ // 미룬 우편 깨움(TUI-H4) — 이 TUI 가 턴 중·5분 창이라 못 받은 깨움을 idle 로 «기록»된 뒤 한 번 다시 두드린다.
269
+ // 실 행 등록과 짝일 때만(시험이 행 등록을 갈아 끼우면 0) · 무거운 모듈은 늦게 불러온다.
270
+ let stopWakePoller: () => void = () => {};
271
+ let wakePollerStopped = false;
272
+ if (deps.startWakePoller) {
273
+ try { stopWakePoller = deps.startWakePoller(surfaceId); } catch { /* fail-soft */ }
274
+ } else if (!deps.registerRow) {
275
+ void import('../loops/msg-wake.js').then(mod => {
276
+ if (!wakePollerStopped) stopWakePoller = mod.startPendingWakePoller(surfaceId);
277
+ }).catch(() => { /* fail-soft — the post-time wake still runs */ });
278
+ }
266
279
  const driveTicks = deps.driveTicks ?? ((tick, ms) => {
267
280
  const t = setInterval(tick, ms);
268
281
  (t as { unref?: () => void }).unref?.();
@@ -338,6 +351,8 @@ export function startTuiSelfReport(deps: TuiSelfReportDeps = {}): () => void {
338
351
  try { mirror?.stop(); } catch { /* fail-soft — restores stdout.write */ }
339
352
  clearInterval(hb);
340
353
  try { stopRunState(); } catch { /* fail-soft */ }
354
+ wakePollerStopped = true;
355
+ try { stopWakePoller(); } catch { /* fail-soft */ }
341
356
  try { markClosed(surfaceId, now()); } catch { /* fail-soft */ }
342
357
  try { activeControlTarget?.deactivate(); } catch { /* fail-soft */ }
343
358
  try { stopControlPoller(); } catch { /* fail-soft */ }
@@ -17,6 +17,10 @@ import type { DevChatOpts } from '../self-dev/dev-pipeline.js';
17
17
  export interface ChatCliOpts {
18
18
  session?: string;
19
19
  new?: boolean;
20
+ /** `--continue` — 활성 세션 이어하기(명시). 대표 #73: 기본은 새 세션. */
21
+ continue?: boolean;
22
+ /** `--resume [id]` — id 면 그 세션, 값 없이(true) 면 활성 세션. */
23
+ resume?: string | boolean;
20
24
  json?: boolean;
21
25
  tools?: boolean;
22
26
  goalLoop?: boolean;
@@ -29,13 +33,17 @@ export interface ChatCliDeps {
29
33
  runDevPipeline?: typeof runDevPipeline;
30
34
  }
31
35
 
32
- /** CLI 옵션 → DevChatOpts(--new→forceNew·나머지 boolean 정규화). reuseActive 는 dispatch 클로저에서 !forceNew 파생.
36
+ /** CLI 옵션 → DevChatOpts(--new→forceNew·--continue/--resume→continueActive·나머지 boolean 정규화).
37
+ * 대표 #73 — reuseActive 는 dispatch 클로저에서 continueActive 로만 켠다(인자 없음 = 새 세션).
33
38
  * session 은 `!== undefined` 로 통과(원 액션 explicitSessionId:opts.session 과 정확 등가 — 빈 문자열도 그대로,
34
39
  * runChatTurnCli 가 falsy 처리해 결과는 동일하나 중간값까지 무손실 유지). */
35
40
  export function toDevChatOpts(opts: ChatCliOpts): DevChatOpts {
36
41
  return {
37
- ...(opts.session !== undefined ? { session: opts.session } : {}),
42
+ ...(opts.session !== undefined
43
+ ? { session: opts.session }
44
+ : typeof opts.resume === 'string' ? { session: opts.resume } : {}),
38
45
  forceNew: opts.new === true,
46
+ continueActive: opts.continue === true || opts.resume === true,
39
47
  json: opts.json === true,
40
48
  enableTools: opts.tools === true,
41
49
  goalLoop: opts.goalLoop === true,
package/src/chat/index.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  // Integrates into the dashboard log pane as an inline chat
3
3
 
4
4
  import { getGrokApiKey, GROK_MODEL, GROK_API_URL } from '../config.js';
5
- import { C, ansi, KeyStreamParser, readKey, traceKey, traceKeyListener, termSize, pad, visibleWidth, stripAnsi, truncate, render, hLine, closeTui, resetRenderCache, invalidateRenderCacheFromRow, injectKey } from '../tui.js';
5
+ import { C, ansi, KeyStreamParser, readKey, traceKey, traceKeyListener, termSize, pad, visibleWidth, stripAnsi, truncate, render, hLine, closeTui, resetRenderCache, invalidateRenderCacheFromRow, injectKey, takeInjectedKeys, cancelPendingReadKey } from '../tui.js';
6
6
  import { paintCursorMove, paintCursorVisibility, type CursorState } from '../display/cursor-state.js';
7
7
  import { firstVisibleInputLineIdx, inputLineWindow } from '../display/prompt-frame.js';
8
8
  import { createChatPickerFamilySource, createChatPickerFamilySources } from './pickers/modals.js';
@@ -248,6 +248,8 @@ export interface TextInputRenderActions {
248
248
  repaintUserMutation: () => void;
249
249
  }
250
250
 
251
+ /** Prefix painted in place of the prompt on input continuation rows. */
252
+ const TEXT_INPUT_CONTINUATION_PREFIX = ' \u00B7 ';
251
253
  const TEXT_INPUT_CURSOR_PROTOCOL_ENABLE = '\x1b[>1u\x1b[>4;2m';
252
254
  const TEXT_INPUT_CURSOR_PROTOCOL_DISABLE = '\x1b[<u\x1b[>4;0m';
253
255
  const SYNCHRONIZED_OUTPUT_BEGIN = '\x1b[?2026h';
@@ -678,6 +680,20 @@ export interface InputResult {
678
680
  * similar. textInput itself doesn't act on the chord beyond
679
681
  * returning — the host decides. */
680
682
  saved?: boolean;
683
+ /** H2 내부 턴 문 — 입력칸이 «비켜 줬다»(버퍼가 비어 있었다). 텍스트 없음 · 제출 아님. 호스트는
684
+ * 내부 턴 문(`InternalTurnGate.takePending`)에서 실행할 턴을 꺼낸다. */
685
+ yieldedToInternalTurn?: true;
686
+ }
687
+
688
+ /** H2 내부 턴 문이 마운트된 textInput 에 «비켜 달라»를 청하는 자리.
689
+ * ⛔ 입력칸 버퍼·합성 키를 쓰지 않는다 — textInput 은 버퍼가 «비었을 때만» 스스로 물러난다. */
690
+ export interface TextInputInternalTurnYieldPort {
691
+ /** textInput 이 마운트되면 부른다. 넘긴 함수는 버퍼가 비었으면 true(물러남 예약), 아니면 false. */
692
+ attach(requestYield: () => boolean): void;
693
+ /** textInput 이 내려가면 부른다. `yielded` 가 아니면 열린 내부 턴은 거둬진다(사람이 먼저 끝냈다). */
694
+ detach(opts?: { yielded?: boolean }): void;
695
+ /** 물러남을 예약한 뒤 그 사이 사람이 글자를 넣어 «물러나지 않았다». */
696
+ declined?(detail: string): void;
681
697
  }
682
698
 
683
699
  export interface TextInputExternalSubmitRequest {
@@ -895,6 +911,8 @@ export async function textInput(opts: {
895
911
  * side-effect boundary instead of a flat callback bag. Legacy
896
912
  * fields above remain supported for compatibility/tests. */
897
913
  host?: TextInputHost;
914
+ /** H2 내부 턴 문 — 버퍼가 비었을 때 입력 루프가 물러나 호스트가 내부 턴을 실행하게 한다. */
915
+ internalTurnYield?: TextInputInternalTurnYieldPort;
898
916
  }): Promise<InputResult> {
899
917
  const { row: initialRow, col, width, maxLines = 5, prompt = '\u276f ', placeholder = '' } = opts;
900
918
  const getWidth = (): number => opts.getWidth?.() ?? width;
@@ -907,7 +925,8 @@ export async function textInput(opts: {
907
925
  setInputPromptStartRow(row);
908
926
  const commands = opts.commands ?? SLASH_COMMANDS;
909
927
  const history = opts.history ?? [];
910
- let lines: string[] = [opts.initialText ?? ''];
928
+ // 턴 중 typeahead 가 Shift+Enter 로 만든 여러 줄 prefill 은 줄 단위로 연다.
929
+ let lines: string[] = (opts.initialText ?? '').split('\n');
911
930
  // Line-count reporting: only fires when the visible count actually
912
931
  // changes, so hosts don't re-render on every keystroke.
913
932
  const resolvedHost = resolveTextInputHost(opts);
@@ -915,8 +934,8 @@ export async function textInput(opts: {
915
934
  const onLinesChangeHandler = resolvedHost.onLinesChange;
916
935
  const dispatchGlobalAction = resolvedHost.dispatchGlobalAction;
917
936
  let lastReportedLines = -1;
918
- let lineIdx = 0; // current line
919
- let colIdx = lines[0]!.length; // cursor at end of initial text
937
+ let lineIdx = lines.length - 1; // current line
938
+ let colIdx = lines[lineIdx]!.length; // cursor at end of initial text
920
939
  let ctrlCArmedAt: number | null = null;
921
940
  let ctrlCHintTimer: ReturnType<typeof setTimeout> | null = null;
922
941
  let ctrlCHint: string | null = null;
@@ -1134,7 +1153,12 @@ export async function textInput(opts: {
1134
1153
  setInputPromptStartRow(row);
1135
1154
  const promptStr = C.accent(prompt);
1136
1155
  const promptW = visibleWidth(prompt);
1137
- const textW = Math.max(0, getWidth() - promptW - 1);
1156
+ // Continuation rows carry a 4-cell ` · ` prefix instead of the prompt,
1157
+ // so each row gets its own text width — sharing the first row's width
1158
+ // let continuation rows overrun the terminal by `contPfxW - promptW` cells.
1159
+ const contPfxW = visibleWidth(TEXT_INPUT_CONTINUATION_PREFIX);
1160
+ const textWFor = (idx: number): number =>
1161
+ Math.max(0, getWidth() - (idx === 0 ? promptW : contPfxW) - 1);
1138
1162
  const numLines = lines.length;
1139
1163
  // Visible window: at most `maxLines` rows on screen, but the buffer
1140
1164
  // (`lines`) may exceed that. `firstVisibleIdx` keeps the cursor's
@@ -1177,16 +1201,17 @@ export async function textInput(opts: {
1177
1201
  if (i < visibleLines) {
1178
1202
  const lineIdxInArray = firstVisibleIdx + (visibleLines - 1 - i);
1179
1203
  const lineContent = lines[lineIdxInArray]!;
1180
- const pfx = lineIdxInArray === 0 ? promptStr : C.muted(' ' + '\u00B7' + ' ');
1204
+ const pfx = lineIdxInArray === 0 ? promptStr : C.muted(TEXT_INPUT_CONTINUATION_PREFIX);
1205
+ const rowTextW = textWFor(lineIdxInArray);
1181
1206
  const display = lineIdxInArray === 0 && numLines === 1 && !lineContent
1182
- ? truncate(C.muted(placeholder), Math.max(0, textW))
1207
+ ? truncate(C.muted(placeholder), Math.max(0, rowTextW))
1183
1208
  : inputLineWindow(
1184
1209
  lineContent,
1185
1210
  lineIdxInArray === lineIdx ? colIdx : lineContent.length,
1186
- textW,
1211
+ rowTextW,
1187
1212
  ).display;
1188
1213
 
1189
- const padded = display + ' '.repeat(Math.max(0, textW - visibleWidth(display)));
1214
+ const padded = display + ' '.repeat(Math.max(0, rowTextW - visibleWidth(display)));
1190
1215
  writeTerminal(ansi.moveTo(r, col) + '\x1b[2K' + pfx + padded);
1191
1216
  } else {
1192
1217
  // This row had content on the previous paint but doesn't anymore
@@ -1216,8 +1241,8 @@ export async function textInput(opts: {
1216
1241
  Math.min(lineIdx - firstVisibleIdx, visibleLines - 1),
1217
1242
  );
1218
1243
  const curR = row - (visibleLines - 1 - cursorScreenLine);
1219
- const pfxW = lineIdx === 0 ? visibleWidth(prompt) : 4;
1220
- const { cursorCol } = inputLineWindow(lines[lineIdx]!, colIdx, textW);
1244
+ const pfxW = lineIdx === 0 ? visibleWidth(prompt) : contPfxW;
1245
+ const { cursorCol } = inputLineWindow(lines[lineIdx]!, colIdx, textWFor(lineIdx));
1221
1246
  const curX = col + pfxW + cursorCol;
1222
1247
  // P2.2.c — coordinator owns the cursor emit when wired; falls
1223
1248
  // back to direct stdout for non-coordinator callers (tests, non-dashboard
@@ -1382,6 +1407,7 @@ export async function textInput(opts: {
1382
1407
  const finalizeInput = (result: InputResult): InputResult => {
1383
1408
  // 외부 주입 라우터가 «composer 가 안 떠 있다»를 알 수 있게 내린다.
1384
1409
  if (hostControl) hostControl.getBufferText = undefined;
1410
+ detachInternalTurnYield(result.yieldedToInternalTurn === true);
1385
1411
  clearPicker();
1386
1412
  writeTerminal(endTextInputCursor(opts.cursorSink));
1387
1413
  return result;
@@ -1454,9 +1480,34 @@ export async function textInput(opts: {
1454
1480
  };
1455
1481
  }
1456
1482
 
1483
+ // ⭐ H2 내부 턴 문 — 버퍼가 비었을 때만 물러남을 예약하고 걸린 readKey 를 «빈 키»로 깨운다.
1484
+ // ⛔ 버퍼·커서·키 큐는 건드리지 않는다(대표 비침투). 마운트가 끝나면(어느 반환 길이든) 무효다.
1485
+ let internalYieldRequested = false;
1486
+ let internalYieldMounted = true;
1487
+ function detachInternalTurnYield(yielded = false): void {
1488
+ if (!internalYieldMounted) return;
1489
+ internalYieldMounted = false;
1490
+ internalYieldRequested = false;
1491
+ opts.internalTurnYield?.detach({ yielded });
1492
+ }
1493
+ opts.internalTurnYield?.attach(() => {
1494
+ if (!internalYieldMounted || lines.join('\n').length > 0) return false;
1495
+ internalYieldRequested = true;
1496
+ cancelPendingReadKey();
1497
+ return true;
1498
+ });
1499
+
1457
1500
  drawAll();
1458
1501
 
1459
1502
  while (true) {
1503
+ if (internalYieldRequested) {
1504
+ internalYieldRequested = false;
1505
+ if (lines.join('\n').length === 0) {
1506
+ return finalizeInput({ text: '', submitted: false, yieldedToInternalTurn: true });
1507
+ }
1508
+ // 판정과 물러남 사이에 사람이 글자를 넣었다 — 사람이 먼저다.
1509
+ opts.internalTurnYield?.declined?.('buffer');
1510
+ }
1460
1511
  // IDX-F2.5 — picker.onKey may have set pendingSubmit on the
1461
1512
  // previous iteration (the closure can't return from textInput
1462
1513
  // itself). Consume the signal at the top of the loop, tear
@@ -1471,6 +1522,7 @@ export async function textInput(opts: {
1471
1522
  }
1472
1523
 
1473
1524
  const key = await (opts.readKey ?? (() => readKey('input')))();
1525
+ if (internalYieldRequested && !key.name) continue; // H2 — 내부 턴 문이 깨운 빈 키
1474
1526
  traceAfterSubmitKey(key);
1475
1527
 
1476
1528
  // Raw-key trace — diagnoses "modifier bit dropped before global-action
@@ -1671,6 +1723,7 @@ export async function textInput(opts: {
1671
1723
  // input loop exits cleanly and the dashboard's pane dispatcher
1672
1724
  // picks up the keys.
1673
1725
  if (hostControl) hostControl.getBufferText = undefined;
1726
+ detachInternalTurnYield();
1674
1727
  return { text: '', submitted: false, gotoPane: true };
1675
1728
  }
1676
1729
  drawAll();
@@ -2001,8 +2054,18 @@ export function attachStreamingKeys(
2001
2054
  // ⭐ 창 길이는 `readKey` 와 같은 25ms — 두 진입점이 같은 규칙을 쓴다.
2002
2055
  let escapeTimer: ReturnType<typeof setTimeout> | undefined;
2003
2056
  const clearEscapeTimer = () => { if (escapeTimer) { clearTimeout(escapeTimer); escapeTimer = undefined; } };
2057
+ // ⭐ TUI-ESC-ABORT-TOOLS (2026-10-15) — 바깥 키(`pty key` · 제어 IPC input-key)는 stdin 이
2058
+ // 아니라 `injectKey` 큐로 들어오고 빈 청크로 깨울 뿐이다. 이 리스너가 큐를 안 보면 턴 중
2059
+ // Esc 가 escGate 에 닿지 않고 다음 readKey(턴 끝)까지 잠든다. 주입이 먼저 왔으므로 먼저 배달한다.
2060
+ const deliverInjected = () => {
2061
+ const injected = takeInjectedKeys();
2062
+ if (injected.length === 0) return;
2063
+ for (const key of injected) debug.log('tui.input', 'injected-key-stream-delivered', { key: key.name });
2064
+ deliver(injected);
2065
+ };
2004
2066
  const listener = (data: string | Buffer) => {
2005
2067
  clearEscapeTimer();
2068
+ deliverInjected();
2006
2069
  const keys = parser.push(data);
2007
2070
  deliver(keys);
2008
2071
  // ⚠️ `unref()` — 이 타이머가 프로세스를 붙잡아 두면 안 된다(입력 대기는 stdin 의 몫).
@@ -2033,6 +2096,9 @@ export function attachStreamingKeys(
2033
2096
  // leaves streaming typeahead and lone Escape with no events at all.
2034
2097
  process.stdin.resume();
2035
2098
  traceKeyListener('attach', 'stream');
2099
+ // 턴 시작 «전»에 주입돼 큐에 남은 키도 배달한다 — 마이크로태스크로 미뤄 호출자가 cleanup 을
2100
+ // 손에 쥔 뒤에 handler 가 불리게 한다.
2101
+ queueMicrotask(() => { if (!cleanedUp) deliverInjected(); });
2036
2102
  return () => {
2037
2103
  if (cleanedUp) return;
2038
2104
  cleanedUp = true;
@@ -16,22 +16,24 @@ export interface TextInputControlState {
16
16
  }
17
17
 
18
18
  export function resolveTextInputControlAction(
19
- key: Pick<Key, 'name' | 'ctrl' | 'shift'>,
19
+ key: Pick<Key, 'name' | 'ctrl' | 'shift'> & { alt?: boolean },
20
20
  state: TextInputControlState,
21
21
  ): TextInputControlAction {
22
22
  const stripTrailingBackslash =
23
23
  key.name === 'enter'
24
24
  && state.cursor > 0
25
25
  && state.currentLine[state.cursor - 1] === '\\';
26
+ // ⭐ Alt+Enter 도 줄바꿈이다 — kitty 프로토콜을 켠 멀티플렉서(herdr)는 바깥의 `ESC CR` 을
27
+ // `CSI 13;3u`(alt) 로 바꿔 넘긴다. 종전엔 그 꼴이 «제출»로 떨어져 대체 키가 죽어 있었다.
26
28
  const isNewline =
27
- (key.name === 'enter' && key.shift)
29
+ (key.name === 'enter' && (key.shift || key.alt === true))
28
30
  || (key.name === 'j' && key.ctrl)
29
31
  || stripTrailingBackslash;
30
32
 
31
33
  if (isNewline) {
32
34
  return { kind: 'newline', stripTrailingBackslash };
33
35
  }
34
- if (key.name === 'enter' && !key.shift) {
36
+ if (key.name === 'enter' && !key.shift && !key.alt) {
35
37
  return { kind: 'submit' };
36
38
  }
37
39
  if (key.name === 'escape') {
@@ -0,0 +1,38 @@
1
+ // ── 도구별 «제출로 끊어도 되나» 선언 (10-14 · 대표 «지금 밀어 넣기») ─────────────────
2
+ //
3
+ // 턴 중에 사용자가 «지금 밀어 넣기»를 하면, 도는 도구가 «전부» `cancel` 일 때만 턴을 끊고 그 발화로
4
+ // 바로 이어 간다. 하나라도 `block` 이면 끊지 않고 다음 도구 경계에 최우선으로 넣는다.
5
+ // ⭐ 기본은 `block` 이다 — 모르는 도구(쓰기·실행·자식 띄우기)를 «끊어도 된다»로 읽지 않는다.
6
+ // ⭐ `cancel` 은 부작용 없는 읽기·대기 도구만 — 끊으면 결과를 버릴 뿐 바깥 상태가 안 바뀐다.
7
+ // (Claude Code `Tool.interruptBehavior()` 계약과 같은 축 · 기본 block)
8
+ // ⚠️ 이 표가 «도구 선언 칸»이다. TUI 는 도는 도구의 «이름»만 알아서 스펙 객체가 아니라 이름으로 선언한다.
9
+ // 새 읽기 전용 도구를 더하면 여기 한 줄을 더한다.
10
+
11
+ export type ToolInterruptBehavior = 'cancel' | 'block';
12
+
13
+ const DECLARED: ReadonlyMap<string, ToolInterruptBehavior> = new Map<string, ToolInterruptBehavior>([
14
+ ['Read', 'cancel'],
15
+ ['Grep', 'cancel'],
16
+ ['Glob', 'cancel'],
17
+ ['ListDir', 'cancel'],
18
+ ['WebSearch', 'cancel'],
19
+ ['WebFetch', 'cancel'],
20
+ // 대기·조회 — 끊어도 자식은 산다(턴만 끊는다).
21
+ ['AgentOutput', 'cancel'],
22
+ ['AgentList', 'cancel'],
23
+ ['TaskGet', 'cancel'],
24
+ ['TaskList', 'cancel'],
25
+ ]);
26
+
27
+ export function toolInterruptBehavior(name: string): ToolInterruptBehavior {
28
+ return DECLARED.get(name) ?? 'block';
29
+ }
30
+
31
+ /**
32
+ * 도는 도구가 «전부» 끊어도 되는가. 도는 도구가 없으면(모델이 글을 쓰는 중) 참이다.
33
+ * 막는 도구 이름을 함께 낸다(안내 줄용).
34
+ */
35
+ export function canInterruptRunningTools(names: readonly string[]): { ok: boolean; blocking: string[] } {
36
+ const blocking = [...new Set(names.filter(name => toolInterruptBehavior(name) === 'block'))].sort();
37
+ return { ok: blocking.length === 0, blocking };
38
+ }
@@ -361,7 +361,11 @@ function extractSyntheticGuardSummary(result: unknown): string | null {
361
361
  return 'inspect budget exhausted — summarize inspected files';
362
362
  }
363
363
  if (text.includes('TOOL CALL REJECTED')) {
364
- return 'tool budget exhausted — final answer required';
364
+ // Only the turn-budget stub is a budget; phase guards (VERIFY/REPAIR/INSPECT ACTION
365
+ // REQUIRED …) reject a tool for the current phase and must not read as «budget» (#67).
366
+ if (text.includes('tool-loop budget exhausted')) return 'tool budget exhausted — final answer required';
367
+ const reason = /\b([A-Z][A-Z]+(?: [A-Z]+)* (?:REQUIRED|EXHAUSTED))\b/.exec(text)?.[1];
368
+ return reason ? `tool call rejected — ${reason.toLowerCase()}` : 'tool call rejected';
365
369
  }
366
370
  if (text.includes('RUNTIME BLOCKED')) {
367
371
  return 'reuse current candidates';