elanous 0.2.28 → 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 (818) 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/{y1ltt7oCZxVpC6zVPhZ2O → LSXfY0u9QtfDbejY0Ukf_}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{ab4d57c2.e90bc2cb31949045.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/{5492-e05e26a033ba80d2.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/1654.32de4b324981a188.js +23 -0
  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/1913.7cc6fb6055b1ed3f.js +41 -0
  18. package/apps/pwa/out/_next/static/chunks/2001.6c7e0fd02190886c.js +1 -0
  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/{8578.dff22d988cc2b106.js → 2213.2ccbada92c33ea0f.js} +3 -3
  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/{5081.a240b63fad28663a.js → 2871.0bca6137343b3f76.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/2898.fd781bc7cf01a7b7.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2940-619bfd8ef337c611.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/{2846.d6a433b8663819a5.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/{f4dfbfc0.a69fb12f854882aa.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/3541-ce3a5424ed5ad7f1.js +1 -0
  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/{3143.257997a5f1ed79df.js → 3902.e1e71aaac850a045.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/{16e57f67.3ea19e893461e611.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
  41. package/apps/pwa/out/_next/static/chunks/{1146.80d15ea7c6e6ee95.js → 4111.2bfedbb233ad206b.js} +1 -1
  42. package/apps/pwa/out/_next/static/chunks/{1516.83dd2c1b86b4e507.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/{9938.b23e4d4dfa0114cd.js → 4999.c064a4000c2a9e94.js} +2 -2
  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/{1157.f08bf2b70915e176.js → 5304.04d24756f242a094.js} +2 -2
  57. package/apps/pwa/out/_next/static/chunks/{7752.5cbdd0b433c54af9.js → 5307.60f2209e809bd627.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{9917-9e26abc5f7772735.js → 5458-16cd7a2b51b74c8c.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/{6196.34d6b229079e9e28.js → 5525.86debf231e181813.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{4593.10f5b9bd702d4a6c.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/{7483.ba01c6c209b81bba.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/{9974.e77b4ff4884557b3.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/{3309.364573ceedbdfd5f.js → 6323.8672b4817a306928.js} +1 -1
  74. package/apps/pwa/out/_next/static/chunks/{94.4cfed21c0b781a06.js → 6433.fc573af22bbc9ab7.js} +4 -4
  75. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/{949.1e7d45ccb71580aa.js → 6517.4147878ac06d584d.js} +2 -2
  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/{2528.3868070ef1be69f9.js → 6767.ea607cf0c20a25af.js} +2 -2
  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/{1743.563d3168e95825ef.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/{5408.377c8c543635b81f.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/{65ebff95.081daeff622d238e.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/{2697.76ca2ac3efef6f3b.js → 8018.a32663f04a6fc5f9.js} +1 -1
  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/9138.b6e80031afb1d973.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/{4204.a409ab6250c0f6a8.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/{5785-ea8d2c633b6688e3.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/9398-6aed28f0a96d0d6f.js +1 -0
  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/997ce8a5-2ad501927003b41b.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{9311.24c8f5ea793253dd.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-fa46d4588e8442c2.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-ced0bcfc6542b3fc.js → page-349f2752d8cd37ad.js} +1 -1
  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-cb249e81ed339318.js → page-0a07363b130182a1.js} +1 -1
  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-521ee23ac8c0abfa.js +1 -0
  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-149dc1caba411bb9.js +1 -0
  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/{6def8a8e.c81f9ca41028eccf.js → b313b242.cb1265eea908db61.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/{e87d89b9.2e71c0ae475d28a1.js → e5012ffe.f727e23c231f4342.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/{e117f801.e92bf10242653497.js → ebc7d829.264a0bcb6c750b50.js} +1 -1
  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 +15 -7
  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/plugins/agent-team/agents/research.md +1 -0
  289. package/scripts/check-native-tool-wiring.ts +3 -2
  290. package/scripts/ci-android-unit-tests.ts +16 -0
  291. package/scripts/ci-typecheck-changed.ts +40 -11
  292. package/scripts/coord-channel-watch.sh +45 -19
  293. package/scripts/coord-role-pack.ts +222 -0
  294. package/scripts/cron-run.ts +96 -3
  295. package/scripts/detect-test-interference.ts +38 -5
  296. package/scripts/gate-pr-cache.ts +65 -0
  297. package/scripts/gh-surface/capture.ts +126 -0
  298. package/scripts/gh-surface/gh +40 -0
  299. package/scripts/import-graph-scc.ts +38 -0
  300. package/scripts/install.ps1 +19 -0
  301. package/scripts/intake-social.ts +181 -0
  302. package/scripts/lecture-note/node.ts +71 -4
  303. package/scripts/lib/android-toolchain.ts +32 -0
  304. package/scripts/lib/deterministic-env.ts +62 -0
  305. package/scripts/lib/gate-test-env.ts +19 -0
  306. package/scripts/lib/morning-report-options.ts +41 -0
  307. package/scripts/measure-goal-grounding-corpus.ts +2 -1
  308. package/scripts/pr-land-extra-remote-gates.ts +49 -0
  309. package/scripts/ratchets/test-interference-patterns.allowlist.txt +257 -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-batch-safe.ts +23 -0
  317. package/scripts/release-loop/gate-closure.ts +12 -8
  318. package/scripts/release-loop/gate-diff.ts +1 -1
  319. package/scripts/release-loop/gate-history.ts +422 -0
  320. package/scripts/release-loop/gate-host-mirror.ts +66 -0
  321. package/scripts/release-loop/gate-node.ts +806 -94
  322. package/scripts/release-loop/gate-partial.ts +106 -9
  323. package/scripts/release-loop/gate-pr-cache.ts +66 -0
  324. package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
  325. package/scripts/release-loop/gate-r2-verdict.ts +189 -0
  326. package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
  327. package/scripts/release-loop/gate-triage-node.ts +190 -0
  328. package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
  329. package/scripts/release-loop/import-graph-scc-run.ts +54 -0
  330. package/scripts/release-loop/import-graph-scc.ts +215 -0
  331. package/scripts/release-loop/node-verdict.ts +2 -0
  332. package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
  333. package/scripts/release-loop/resume-release.ts +33 -4
  334. package/scripts/release-loop/resume.ts +13 -5
  335. package/scripts/release-loop/spawn-lane.ts +51 -0
  336. package/scripts/release-loop/tui-node-checks.ts +23 -0
  337. package/scripts/release-loop/tui-sim-node.ts +3 -2
  338. package/scripts/release-loop/unattended-release.ts +16 -0
  339. package/scripts/release-loop/version-node.ts +62 -4
  340. package/scripts/test-deterministic.ts +46 -73
  341. package/scripts/train-reach-grouping.ts +48 -0
  342. package/scripts/tsc-incremental-cache.ts +86 -0
  343. package/scripts/tsc-incremental-diagnostics.ts +76 -0
  344. package/scripts/tsc-main-safety-net.ts +2 -2
  345. package/scripts/usage-rollup.ts +11 -3
  346. package/src/acp/client.ts +4 -1
  347. package/src/acp/core-turn-bridge.ts +145 -24
  348. package/src/acp/elanous-extensions.ts +2 -0
  349. package/src/acp/server.ts +2 -0
  350. package/src/ad-pipeline/run.ts +4 -2
  351. package/src/agent/ref-grounding.ts +18 -0
  352. package/src/agent/runner.ts +169 -3
  353. package/src/agent/subagent-callable.ts +3 -2
  354. package/src/agent-mission/review-loop.ts +6 -3
  355. package/src/agent-substrate/acp-implementer.ts +14 -2
  356. package/src/agent-substrate/pr-reviewer.ts +41 -21
  357. package/src/agent-substrate/self-review-cli.ts +30 -4
  358. package/src/autopilot/pr-manager.ts +62 -7
  359. package/src/briefing/brief-items.ts +24 -22
  360. package/src/budget/pty-usage-reemit.ts +7 -0
  361. package/src/budget/run-usage-rollup.ts +9 -0
  362. package/src/budget/usage-daily-store.ts +98 -0
  363. package/src/capture/tui-self-report.ts +37 -4
  364. package/src/chat/chat-cli.ts +10 -2
  365. package/src/chat/index.ts +107 -20
  366. package/src/chat/input-control-key.ts +5 -3
  367. package/src/chat/pickers/modal-runtime.ts +1 -0
  368. package/src/chat/pickers/modals.ts +3 -1
  369. package/src/chat/tool-interrupt-behavior.ts +38 -0
  370. package/src/chat/tool-render/dispatch.ts +5 -1
  371. package/src/chat/turn-typeahead.ts +191 -29
  372. package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
  373. package/src/cli/agent-cli.ts +41 -13
  374. package/src/cli/config-audit.ts +123 -0
  375. package/src/cli/dashboard-name-flag.ts +48 -0
  376. package/src/cli/decisions-cli.ts +80 -6
  377. package/src/cli/doctor-cli.ts +80 -0
  378. package/src/cli/log-event-names.ts +19 -0
  379. package/src/cli/mcp-login.ts +21 -5
  380. package/src/cli/msg-cli.ts +133 -2
  381. package/src/cli/pr-cli.ts +546 -112
  382. package/src/cli/pr-land-heavy-remote.ts +233 -0
  383. package/src/cli/pr-land-overlap-evidence.ts +167 -14
  384. package/src/cli/pr-land-pod-shadow-job.ts +83 -0
  385. package/src/cli/pr-land-pod-shadow.ts +16 -3
  386. package/src/cli/pr-land-virtual-rebase.ts +108 -0
  387. package/src/cli/pty-takeover-cli.ts +125 -16
  388. package/src/cli/release-cli.ts +122 -14
  389. package/src/cli/remote-resolve.ts +2 -1
  390. package/src/cli/seat-cli.ts +164 -19
  391. package/src/cli/self-update.ts +5 -2
  392. package/src/cli/tasks-cli.ts +105 -21
  393. package/src/cli/usage-cli.ts +146 -12
  394. package/src/cli/usage-daily-cli.ts +84 -0
  395. package/src/context-bus/context-first.ts +13 -0
  396. package/src/context-bus/context-now.ts +95 -7
  397. package/src/context-bus/ops-events.ts +75 -0
  398. package/src/control-plane/lease-holder.ts +12 -8
  399. package/src/control-plane/ledger.ts +163 -4
  400. package/src/control-plane/server.ts +91 -11
  401. package/src/core-turn/auth-rejected-notice.ts +41 -0
  402. package/src/core-turn/run-core-turn.ts +14 -2
  403. package/src/core-turn/run-goal-loop.ts +239 -4
  404. package/src/core-turn/seat-turn-cap.ts +79 -0
  405. package/src/core-turn/short-question.ts +78 -13
  406. package/src/core-turn/types.ts +10 -0
  407. package/src/dashboard/acp-active-model.ts +40 -0
  408. package/src/dashboard/acp-boot.ts +3 -0
  409. package/src/dashboard/auto-compact-runtime.ts +2 -0
  410. package/src/dashboard/boot-banner.ts +80 -0
  411. package/src/dashboard/dashboard-status-lines.ts +11 -0
  412. package/src/dashboard/detail-viewer-runtime.ts +15 -2
  413. package/src/dashboard/event-loop-stall-monitor.ts +4 -0
  414. package/src/dashboard/goal-loop-thinking.ts +16 -0
  415. package/src/dashboard/hitl-boot.ts +9 -4
  416. package/src/dashboard/index.ts +448 -998
  417. package/src/dashboard/input/chat-main-entry-runtime.ts +2 -0
  418. package/src/dashboard/input/chat-main-log-actions.ts +4 -0
  419. package/src/dashboard/input/chat-main-log-command.ts +12 -1
  420. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +176 -4
  421. package/src/dashboard/input/chat-main-session.ts +14 -3
  422. package/src/dashboard/input/chat-main-slash-command.ts +7 -0
  423. package/src/dashboard/input/chat-main-turn.ts +14 -4
  424. package/src/dashboard/input/compact-prepass-recovery.ts +130 -0
  425. package/src/dashboard/input/dashboard-chord-actions.ts +10 -1
  426. package/src/dashboard/input/dashboard-chord-runtime.ts +2 -0
  427. package/src/dashboard/input/external-input-host.ts +71 -0
  428. package/src/dashboard/input/internal-turn.ts +261 -0
  429. package/src/dashboard/input/log-fold-binding.ts +18 -0
  430. package/src/dashboard/input/mouse-wiring.ts +17 -4
  431. package/src/dashboard/input/seat-autowake.ts +318 -0
  432. package/src/dashboard/input/turn-steer-bridge.ts +164 -0
  433. package/src/dashboard/log-click-runtime.ts +5 -3
  434. package/src/dashboard/loop-scheduler.ts +72 -0
  435. package/src/dashboard/running-build-status.ts +74 -0
  436. package/src/dashboard/seat-boot-preamble.ts +131 -0
  437. package/src/dashboard/seat-local-instructions.ts +305 -0
  438. package/src/dashboard/skill-runtime.ts +2 -0
  439. package/src/dashboard/slash-runtime/dashboard-handlers.ts +220 -1203
  440. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
  441. package/src/dashboard/slash-runtime/index.ts +13 -0
  442. package/src/dashboard/slash-runtime/model-choices.ts +35 -0
  443. package/src/dashboard/term-slash-runtime.ts +15 -0
  444. package/src/dashboard/turn-busy-teardown.ts +50 -0
  445. package/src/dashboard/turn-preamble.ts +30 -2
  446. package/src/dashboard/turn-session-layers.ts +176 -0
  447. package/src/dashboard/turn-stream-formatter.ts +14 -6
  448. package/src/dashboard/turn-stream-presentation-applier.ts +8 -0
  449. package/src/decisions/decision-ledger.ts +45 -4
  450. package/src/discord-self-message.ts +4 -4
  451. package/src/domains/release-tool.ts +26 -10
  452. package/src/domains/surface-events.ts +4 -1
  453. package/src/domains/watch-default-scheduler.ts +8 -9
  454. package/src/field-note/transcribe.ts +17 -0
  455. package/src/fold-stack.ts +24 -1
  456. package/src/git-fs/dirty.ts +32 -4
  457. package/src/git-fs/index.ts +43 -1
  458. package/src/github/remote-call.ts +81 -0
  459. package/src/goals/registry.ts +46 -6
  460. package/src/goals/types.ts +7 -1
  461. package/src/graph-runner/runner.ts +2 -0
  462. package/src/grok/credential.ts +26 -0
  463. package/src/harness/harness-clean.ts +2 -1
  464. package/src/harness/harness-cli-command.ts +52 -5
  465. package/src/harness/harness-gc.ts +34 -6
  466. package/src/harness/harness-incidents.ts +57 -20
  467. package/src/harness/harness-pod-dispatch.ts +87 -10
  468. package/src/harness/harness-queue.ts +53 -4
  469. package/src/harness/harness-stop.ts +4 -3
  470. package/src/harness/harness-substrate-default.ts +78 -7
  471. package/src/harness/harness-worktree-auto.ts +2 -1
  472. package/src/harness/harness-worktrees.ts +3 -2
  473. package/src/hooks/dispatch.ts +2 -1
  474. package/src/index.ts +166 -26
  475. package/src/input/external-input-queue.ts +251 -0
  476. package/src/intake-plane/slash.ts +14 -3
  477. package/src/interactive-terminal-modal.ts +13 -0
  478. package/src/keybindings.ts +4 -1
  479. package/src/llm/route-decision.ts +25 -0
  480. package/src/llm/tool-loop-steered-rejection.ts +33 -0
  481. package/src/llm-stream-retry-display.ts +59 -0
  482. package/src/llm.ts +391 -74
  483. package/src/log-entry.ts +3 -3
  484. package/src/log-pane/search.ts +29 -4
  485. package/src/loops/agent-reply.ts +256 -0
  486. package/src/loops/budget.ts +37 -7
  487. package/src/loops/consensus.ts +348 -0
  488. package/src/loops/loop-cli.ts +3 -2
  489. package/src/loops/msg-address.ts +57 -0
  490. package/src/loops/msg-wake.ts +484 -0
  491. package/src/loops/observe.ts +19 -3
  492. package/src/loops/orchestrator/inbox.ts +60 -3
  493. package/src/loops/orchestrator/tick.ts +80 -6
  494. package/src/loops/orchestrator/traffic.ts +64 -1
  495. package/src/loops/registry.ts +72 -4
  496. package/src/market/signed-index.ts +14 -0
  497. package/src/mcp/mcp-oauth.ts +54 -5
  498. package/src/memory.ts +20 -5
  499. package/src/models/prompts.ts +28 -0
  500. package/src/msg/msg-sse-client.ts +223 -0
  501. package/src/msg/msg-store.ts +86 -2
  502. package/src/mss/logging/log-store.ts +225 -1
  503. package/src/native-tool-catalog.ts +125 -0
  504. package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
  505. package/src/nexus/api/http-server.ts +59 -15
  506. package/src/nexus/api/loop-resources.ts +19 -3
  507. package/src/nexus/api/ops-api.ts +13 -0
  508. package/src/nexus/api/project-autopsy.ts +127 -0
  509. package/src/nexus/api/terminals.ts +3 -0
  510. package/src/nexus/api/workflow-approvals.ts +2 -0
  511. package/src/nexus/daemon-thin-inventory.md +37 -0
  512. package/src/nexus/index.ts +70 -0
  513. package/src/nexus/onboarding/first-boot-wizard.ts +56 -2
  514. package/src/nexus/state/state.ts +1 -0
  515. package/src/oauth/codex-account-store.ts +15 -3
  516. package/src/oauth/codex-billing-route.ts +31 -0
  517. package/src/oauth/store.ts +32 -7
  518. package/src/onboarding/first-run.ts +28 -3
  519. package/src/ops/overview-cache.ts +16 -4
  520. package/src/ops/overview-collect.ts +19 -2
  521. package/src/ops/resources.ts +82 -0
  522. package/src/panes/log-pane.ts +67 -8
  523. package/src/persona/presets.ts +44 -0
  524. package/src/plugins/maker/connector-maker.ts +41 -0
  525. package/src/plugins/maker/skill-maker.ts +42 -0
  526. package/src/plugins/maker/wizard-generate.ts +6 -4
  527. package/src/pr-tool/census.ts +288 -0
  528. package/src/preview/terminal.ts +14 -1
  529. package/src/prompt-cache/types.ts +2 -0
  530. package/src/prompt-enhance/enhance.ts +24 -8
  531. package/src/prompt-library/chat-conciseness.ts +13 -0
  532. package/src/prompt-library/universal-preamble.ts +283 -61
  533. package/src/pty-shell/pty-control-ipc.ts +4 -1
  534. package/src/pty-shell/pty-manifest.ts +77 -5
  535. package/src/pty-shell/registry.ts +19 -2
  536. package/src/pty-shell/tui-run-state.ts +253 -0
  537. package/src/release-loop/gate-host-reservation.ts +97 -0
  538. package/src/release-loop/landing-freeze.ts +5 -0
  539. package/src/release-loop/light-rc.ts +32 -4
  540. package/src/release-loop/placement.ts +92 -1
  541. package/src/release-loop/rehearsal-shard-plan.ts +149 -0
  542. package/src/release-loop/rehearsal.ts +73 -17
  543. package/src/render.ts +5 -1
  544. package/src/repl/index.ts +20 -2
  545. package/src/seat-loop/seat-knowhow.ts +282 -0
  546. package/src/seat-loop/seat-loop.ts +41 -2
  547. package/src/seat-loop/seat-report.ts +42 -2
  548. package/src/seat-loop/traffic-signal.ts +3 -0
  549. package/src/self-dev/ask-launch-flow.ts +24 -3
  550. package/src/self-dev/decompose-compose-graph.ts +28 -27
  551. package/src/self-dev/decompose-proposal.ts +53 -38
  552. package/src/self-dev/decompose.ts +17 -0
  553. package/src/self-dev/dev-pipeline.ts +31 -2
  554. package/src/self-dev/draft-residue.ts +24 -9
  555. package/src/self-dev/draft-sweep.ts +59 -4
  556. package/src/self-dev/external-call-zero.ts +77 -0
  557. package/src/self-dev/launch-preflight-text.ts +6 -0
  558. package/src/self-dev/launch-preflight.ts +25 -3
  559. package/src/self-dev/local-supervisor-judge.ts +185 -0
  560. package/src/self-dev/run-supervisor.ts +300 -24
  561. package/src/self-dev/run-types.ts +20 -0
  562. package/src/self-dev/shard-aggregate.ts +15 -2
  563. package/src/self-dev/shard-plan.ts +47 -0
  564. package/src/self-dev/shard-run.ts +135 -12
  565. package/src/self-dev/spawn-lane-files.ts +19 -0
  566. package/src/self-health/signatures.ts +132 -0
  567. package/src/self-implement/app-api-budget.ts +51 -11
  568. package/src/self-implement/config-gate.ts +2 -1
  569. package/src/self-implement/doctor-visit.ts +118 -0
  570. package/src/self-implement/expose-gate.ts +2 -1
  571. package/src/self-implement/gate-artifacts.ts +405 -0
  572. package/src/self-implement/gate-cli.ts +212 -18
  573. package/src/self-implement/gate-remote.ts +110 -25
  574. package/src/self-implement/gate-scenario.ts +85 -0
  575. package/src/self-implement/goal-author-decompose.ts +80 -16
  576. package/src/self-implement/goal-author.ts +270 -76
  577. package/src/self-implement/goal-authoring-grounding.ts +1 -1
  578. package/src/self-implement/goal-file-name.ts +65 -0
  579. package/src/self-implement/graph-authority.ts +38 -6
  580. package/src/self-implement/graph-overlay-condition.ts +92 -1
  581. package/src/self-implement/ground-goal.ts +2 -1
  582. package/src/self-implement/heal-triage.ts +79 -0
  583. package/src/self-implement/host-regate.ts +74 -2
  584. package/src/self-implement/orchestrator.ts +14 -123
  585. package/src/self-implement/pr-title.ts +123 -0
  586. package/src/self-implement/review-mustfix-class.ts +115 -0
  587. package/src/self-implement/run-checkpoint.ts +235 -0
  588. package/src/self-implement/run-ledger.ts +266 -17
  589. package/src/self-implement/run-stop.ts +4 -3
  590. package/src/self-implement/run-ttl.ts +28 -4
  591. package/src/self-implement/running-runs.ts +10 -6
  592. package/src/self-implement/seams.ts +2 -0
  593. package/src/self-implement/self-implement-runtime.ts +32 -0
  594. package/src/self-implement/shadow-stage.ts +7 -6
  595. package/src/self-implement/stop-autoheal.ts +2 -1
  596. package/src/self-implement/train-gate-remote.ts +37 -8
  597. package/src/self-implement/train-reach-grouping.ts +157 -0
  598. package/src/self-implement/train-scenario-layers.ts +133 -0
  599. package/src/self-implement/uncommitted-work.ts +2 -0
  600. package/src/session/pending-input.ts +81 -11
  601. package/src/session/session-start.ts +224 -0
  602. package/src/session-runtime/index.ts +7 -1
  603. package/src/session-runtime/parallel-dispatch.ts +22 -5
  604. package/src/skills/tools/dev-harness.ts +6 -4
  605. package/src/skills/tools/ops-ledger.ts +707 -0
  606. package/src/skills/tools/persistent-grounding.ts +47 -7
  607. package/src/skills/tools/shell.ts +117 -1
  608. package/src/status/bar.ts +32 -2
  609. package/src/status/status-provider-info.ts +58 -0
  610. package/src/steward/resync-tick.ts +114 -23
  611. package/src/steward/ta-repair-event-collect.ts +158 -0
  612. package/src/task-agent/card-evidence.ts +25 -1
  613. package/src/task-agent/green-sweep.ts +8 -3
  614. package/src/task-agent/judge.ts +76 -0
  615. package/src/task-agent/land-queue.ts +79 -0
  616. package/src/task-agent/live-moves.ts +30 -9
  617. package/src/task-agent/postland-card.ts +5 -0
  618. package/src/task-agent/prelaunch-already-done.ts +98 -0
  619. package/src/task-agent/real-launch-guard.ts +37 -0
  620. package/src/task-agent/rejudge-on-head.ts +93 -13
  621. package/src/task-agent/remote-rejudge-bind.ts +62 -13
  622. package/src/task-agent/repair-cycle.ts +58 -7
  623. package/src/task-agent/repair-worker.ts +7 -0
  624. package/src/task-agent/run-identity.ts +200 -0
  625. package/src/task-agent/shadow.ts +50 -3
  626. package/src/task-agent/task-hand.ts +158 -5
  627. package/src/task-agent/train-landing.ts +77 -0
  628. package/src/task-agent/work-order.ts +104 -0
  629. package/src/task-orchestrator/surfaces/kubectl-transient-retry.ts +51 -0
  630. package/src/task-orchestrator/surfaces/pod-command-job.ts +138 -22
  631. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
  632. package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
  633. package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
  634. package/src/task-orchestrator/surfaces/pod-install-slots.ts +122 -15
  635. package/src/task-orchestrator/surfaces/pod-lease.ts +20 -6
  636. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
  637. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +103 -0
  638. package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
  639. package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +63 -0
  640. package/src/task-orchestrator/surfaces/pod-source-receive.ts +19 -3
  641. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +141 -0
  642. package/src/task-orchestrator/surfaces/pod-warm-ta-shadow.ts +85 -0
  643. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
  644. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +208 -0
  645. package/src/task-orchestrator/surfaces/self-implement-pod.ts +237 -46
  646. package/src/telegram.ts +2 -4
  647. package/src/terminal/session-registry.ts +6 -0
  648. package/src/thinking-line.ts +12 -3
  649. package/src/tool-runtime/index.ts +4 -0
  650. package/src/tool-runtime/ops-ledger-runtimes.ts +84 -0
  651. package/src/tool-runtime/ref-consult-runtime.ts +17 -2
  652. package/src/tool-runtime/run-shell-runtime.ts +4 -1
  653. package/src/tool-runtime/self-cognition-runtimes.ts +5 -1
  654. package/src/tui/input/pickers.ts +732 -0
  655. package/src/tui/slash/mission.ts +492 -0
  656. package/src/tui/slash/term.ts +877 -0
  657. package/src/tui-client/dashboard-session.ts +9 -0
  658. package/src/tui.ts +53 -0
  659. package/src/user-config/gemini-server-tools.ts +9 -0
  660. package/src/user-config.ts +106 -21
  661. package/src/util/spawn-sync-output.ts +7 -0
  662. package/src/ux-sim/fake-bin.ts +154 -0
  663. package/src/ux-sim/fake-clock.ts +36 -0
  664. package/src/ux-sim/fake-llm.ts +29 -0
  665. package/src/ux-sim/headless-tui.ts +72 -0
  666. package/src/ux-sim/in-process-cli.ts +176 -0
  667. package/src/ux-sim/temp-git-remote.ts +82 -0
  668. package/src/version/packed-revision.json +1 -1
  669. package/src/video-pipeline/recipes/vlog.ts +25 -7
  670. package/apps/pwa/out/_next/static/chunks/1027.a0f04663d24c2779.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/1038.676007ae505822e7.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/1113.a37eadf7f740d955.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/112-fa7c526c20ce1405.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/1144.5fa1fa1d48dbcd12.js +0 -36
  675. package/apps/pwa/out/_next/static/chunks/119b405e.8fdd0e44d1ff37aa.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/1296.04560d98e73fbf51.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/1314-f604ba013ec535b0.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/1454-29d1d773d5996a49.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/1464.f3209af0d8ae4ff2.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/1729-d73dd25e564679d4.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/1843.5924c24295243261.js +0 -27
  682. package/apps/pwa/out/_next/static/chunks/1987.e28149724b92918b.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/2066-5ca18ffa5a4be68b.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/2240.d10a66695155fd93.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/2391.e2cbc98d4abbb41a.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/2566-734cb83bbd405886.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/275.0e6bad414729bfa0.js +0 -32
  688. package/apps/pwa/out/_next/static/chunks/2803-33bdae771855a8d1.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/3259-86f3be56e43eaf6a.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/3280-e177c33bfbdcfb0a.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/3294-2b6a6d45a46a6c1c.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/3522.758840fc5e7fe630.js +0 -287
  693. package/apps/pwa/out/_next/static/chunks/3525-a7c989c1a661e880.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/3694.b1a66387756458c0.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/370.124f9e678a76fc01.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/3797-9643105335e660fe.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/4084.15ecaf4240bd9e77.js +0 -286
  698. package/apps/pwa/out/_next/static/chunks/4089-b3382b8843114eee.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/4293.928a8d573c16aab7.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/4402.f9238a3b18a7bd43.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/4490-9b090b0f9427f902.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/4548.13502d0ca3b4f862.js +0 -8
  703. package/apps/pwa/out/_next/static/chunks/4565-67e4c620597965c8.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/4599-548bc96cda44a5a7.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/4625.206574e33a9e7ae8.js +0 -104
  706. package/apps/pwa/out/_next/static/chunks/4862-392c9a71f0d8dfb4.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/5054.2906d1b02542edc5.js +0 -149
  708. package/apps/pwa/out/_next/static/chunks/5102-c822bbbee5a022a4.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/5194-8c93f2e7e4b6f717.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/5305-bacd7eca0b9a5848.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/5311.9071ee3f44fd7ff5.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/5369.9f34353442daa421.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/589-49d730cb8138b397.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/5904-264a6412ae3c9028.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/5980.728531d5c566535c.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/599-56f2c0a5cc4a7295.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/6011.f525002e21bef0ac.js +0 -23
  718. package/apps/pwa/out/_next/static/chunks/6132.4381ab93683f1acf.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/6149.2e698635e454d8f6.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/6356-0afafc4230cf9767.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/6406.64756073f7df35b8.js +0 -77
  722. package/apps/pwa/out/_next/static/chunks/6479-16e62aedafa0e310.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/6599.b5246b46a2453329.js +0 -64
  724. package/apps/pwa/out/_next/static/chunks/6610.5c26eec011565acb.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/666.37d18474edc1c552.js +0 -2
  726. package/apps/pwa/out/_next/static/chunks/6904.a0b5b1ed4f2d2c20.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/7247-1f4aba94aba50d9f.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/7274-e71a7c5b7760cd02.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/7290.1fcaeef3adb5d0d4.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/7477-2c64e42760f82f33.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/7505-47002b76ff1aef6c.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/7600-11884ca4da68e5d9.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/7607.40d8bb3689697ccb.js +0 -62
  734. package/apps/pwa/out/_next/static/chunks/7763.f51fcc19ca1414ec.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/7785.846140c859b1adf6.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/7807-a0fdac6393e0bf36.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/7837-20a63b4b7e9342b1.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/800.7815414cf280545d.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/8085-1e5fce59500a2cc2.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/8100.415f2105faa63e97.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/8290.701aa42ed13aa767.js +0 -226
  742. package/apps/pwa/out/_next/static/chunks/83a80514-b897b64df43ce108.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/8444.d9c74214a3145a43.js +0 -93
  744. package/apps/pwa/out/_next/static/chunks/8569.98c915534928c7f9.js +0 -24
  745. package/apps/pwa/out/_next/static/chunks/8591.b1c7f876e5ec7cfb.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/8715-f63756021d3ab989.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/8879.776c2ec7732aa114.js +0 -115
  748. package/apps/pwa/out/_next/static/chunks/8881.ddca15b3c82c490c.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/8946.5da5c87f32a2e1a8.js +0 -41
  750. package/apps/pwa/out/_next/static/chunks/9117.080b9b75be90e14d.js +0 -74
  751. package/apps/pwa/out/_next/static/chunks/9167.f3ecb28f367d6e69.js +0 -94
  752. package/apps/pwa/out/_next/static/chunks/9224.66095370ee28c93b.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/9238-0682b013c83d6449.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/9449.d3ed795da4befb1c.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/9638-d268329f2c6f4f8d.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/973cbf1b.3bbcf2b41548eca7.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/9842-d6644eb53d3dc6bf.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/9863.94ca3263e760696e.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d9babd8795f396a5.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/approvals/page-5ab1e47978577c5e.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-24453f6a302816b4.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/board/page-6c131d30bb1cf871.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/bots/page-dc0772b11861af51.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/ceo/page-66ad46ed0279feb9.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/chat/page-5159dc8752c6cd29.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/consult/page-c5a2478861c08b87.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/control/page-f722a9dec084e08b.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/decisions/page-256ffd365d32e100.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e0de78ae7b99f01c.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/editor/page-cfbdc44b708d9801.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/exec/page-4c741eb760f2f77c.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/field/page-e9ba98f5f1440a21.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/app/healthz/route-d9babd8795f396a5.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/inside/page-dafc901bb1b72b5f.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/intake/page-2f6f303fa114ec24.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/layout-1634081c5272006c.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/live-run/page-bb1f05cd51c38944.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/loops/page-646b50f63b6fe732.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/market/page-db069b48a59c8c00.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-f736324afa2117c1.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/morning/page-6f131b51193a36f9.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/not-found-435f5e2faf02bc01.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/observatory/page-497e0eedf20e7890.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-a8d28fdf995e16ea.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-8966452228753c5e.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fd5d18656cb432b6.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/outputs/page-5663779cb1a37609.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/app/page-66a67eb19ebd976b.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/app/reflection/page-3b492aa78cf3c4a6.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c71267e7681da982.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/app/sessions/page-a21d1e1797172692.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/app/settings/page-781cfc5114e097da.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-478157214db6a023.js +0 -1
  794. package/apps/pwa/out/_next/static/chunks/app/setup/layout-d9babd8795f396a5.js +0 -1
  795. package/apps/pwa/out/_next/static/chunks/app/setup/page-86141f12cf090b7f.js +0 -1
  796. package/apps/pwa/out/_next/static/chunks/app/share/page-7256c73bb1c36751.js +0 -1
  797. package/apps/pwa/out/_next/static/chunks/app/showroom/page-5c738ca7adef3de5.js +0 -1
  798. package/apps/pwa/out/_next/static/chunks/app/tasks/page-0138c8091ec17224.js +0 -1
  799. package/apps/pwa/out/_next/static/chunks/app/term/page-cc2f24f16d85e735.js +0 -1
  800. package/apps/pwa/out/_next/static/chunks/app/today/page-979d318a534e92da.js +0 -1
  801. package/apps/pwa/out/_next/static/chunks/app/trace/page-182d394f7e6e096b.js +0 -1
  802. package/apps/pwa/out/_next/static/chunks/app/vault/page-21050928a697ed7a.js +0 -1
  803. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-44b9d807005a9030.js +0 -1
  804. package/apps/pwa/out/_next/static/chunks/app/workflows/page-601fb77340e63c9a.js +0 -1
  805. package/apps/pwa/out/_next/static/chunks/app/workspace/page-75d3fb5d47af0edf.js +0 -1
  806. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-11bf9e5725a72c22.js +0 -1
  807. package/apps/pwa/out/_next/static/chunks/dcf24383-2f82e35f2d827393.js +0 -1
  808. package/apps/pwa/out/_next/static/chunks/framework-bf135b997155e90e.js +0 -1
  809. package/apps/pwa/out/_next/static/chunks/main-5571537543bea91c.js +0 -1
  810. package/apps/pwa/out/_next/static/chunks/main-app-25c51c7df7f3a442.js +0 -1
  811. package/apps/pwa/out/_next/static/chunks/pages/_app-e3b2c1f5d82abd65.js +0 -1
  812. package/apps/pwa/out/_next/static/chunks/pages/_error-083f2e23e9bc3641.js +0 -1
  813. package/apps/pwa/out/_next/static/chunks/webpack-e94d22b7a028217b.js +0 -1
  814. package/src/dashboard/bench-slash-runtime.ts +0 -40
  815. package/src/dashboard/input/search-modal-router.ts +0 -9
  816. package/src/dashboard/modals/pane-key-router.ts +0 -27
  817. package/src/dashboard/view-slash-runtime.ts +0 -48
  818. /package/apps/pwa/out/_next/static/{y1ltt7oCZxVpC6zVPhZ2O → LSXfY0u9QtfDbejY0Ukf_}/_ssgManifest.js +0 -0
@@ -21,7 +21,7 @@ export const RELEASE_STATUS_SPEC: LLMToolSpec = {
21
21
  + 'topic=cell: id 칸 하나의 상태·근거와 살핀 판.\n'
22
22
  + 'topic=schedule: 발행 이후 판의 컷·착지·발행·동결 일정.\n'
23
23
  + 'topic=ops: 도는 런·발행·늦은 스케줄·자리·열린 결정의 출처 있는 개관.\n'
24
- + 'topic 과 action 을 동시에 쓰면 topic 을 우선하고 action 은 무시한다. topic 은 읽을 대상, action 은 단독 조회의 짧은 요약.\n'
24
+ + 'topic 과 action 을 동시에 쓰면 오류를 돌려받는다 — 둘 중 하나만 보낸다. topic 은 읽을 대상, action 은 단독 조회의 짧은 요약.\n'
25
25
  + 'topic=features 에서는 owner·status 로 칸을 필터링할 수 있다.\n'
26
26
  + '발행·버전·피처·체크리스트·칸·컷·일정·운영 상태 질문은 Grep·ListDir·파일 검색보다 이 도구를 먼저 부른다 — 그 답은 파일이 아니라 원장에 있다.',
27
27
  parameters: { type: 'object', properties: {
@@ -122,13 +122,29 @@ function cellView(item: ChecklistItem) {
122
122
  owner: item.owner ?? null, priority: item.priority ?? null, evidence: item.evidence ? firstLine(item.evidence) : null };
123
123
  }
124
124
 
125
- export function dispatchReleaseStatus(args: Record<string, unknown>, deps: ReleaseToolDeps = {}): { text: string; structured: Record<string, unknown> } {
125
+ export function dispatchReleaseStatus(rawArgs: Record<string, unknown>, deps: ReleaseToolDeps = {}): { text: string; structured: Record<string, unknown> } {
126
+ // A blank topic/action ("" · spaces) means «not sent» — models fill unused enum slots with "" and then hit the
127
+ // simultaneous-topic-and-action rejection over and over (TUI defect #70 · 10-15: 10+ identical retries, then gave up).
128
+ const args = { ...rawArgs };
129
+ for (const key of Object.keys(args)) if (typeof args[key] === 'string' && !(args[key] as string).trim()) delete args[key];
130
+ // topic=status is the default read — beside an action it adds nothing, so the action wins (#70 · 10-15 실측:
131
+ // models send {topic:"status", action:"landed"} and looped on the simultaneous-topic-and-action rejection).
132
+ if (args.topic === 'status' && args.action !== undefined) delete args.topic;
133
+ // Any other non-features topic beside an action: the action wins too, with one warning line in front (#70b · 10-15
134
+ // 실측: {topic:"ops", action:"schedule"} rejected over and over). topic=features ⊕ action stays rejected below —
135
+ // a feature list and a short summary are different answers.
136
+ if (args.action !== undefined && typeof args.topic === 'string'
137
+ && ['cell', 'schedule', 'ops'].includes(args.topic)) {
138
+ const { topic: ignoredTopic, ...rest } = args;
139
+ debug.log('release.tool', 'topic-ignored-for-action', { topic: ignoredTopic, action: args.action });
140
+ const result = dispatchReleaseStatus(rest, deps);
141
+ return { text: `topic(${ignoredTopic}) 은 무시하고 action 으로 답함\n${result.text}`, structured: { ...result.structured, ignoredTopic } };
142
+ }
126
143
  const topic = args.topic === undefined ? 'status' : args.topic;
127
144
  if (typeof topic !== 'string' || !['status', 'features', 'cell', 'schedule', 'ops'].includes(topic)) throw new Error('topic 은 status, features, cell, schedule, ops 중 하나');
128
- const ignoredAction = args.topic !== undefined && args.action !== undefined ? args.action : undefined;
129
- const withIgnoredAction = (result: { text: string; structured: Record<string, unknown> }) => ignoredAction === undefined
130
- ? result
131
- : { ...result, text: `action=${String(ignoredAction)} 은 무시됨 — topic 과 같이 못 쓴다\n${result.text}` };
145
+ if (args.topic !== undefined && args.action !== undefined) {
146
+ throw new Error('topic 과 action 을 동시에 쓸 수 없습니다 — 둘 중 하나만: topic=features 는 피처 목록 · action 은 짧은 요약');
147
+ }
132
148
  const requested = args.version;
133
149
  if (topic === 'features') {
134
150
  for (const key of ['owner', 'status'] as const) {
@@ -149,10 +165,10 @@ export function dispatchReleaseStatus(args: Record<string, unknown>, deps: Relea
149
165
  const kinds: ContextFact['kind'][] = ['run', 'release', 'schedule-late', 'seat', 'decision'];
150
166
  const facts = answer.facts.filter(fact => kinds.includes(fact.kind));
151
167
  debug.log('release.tool', 'status', { action: 'status', topic, version: requested ?? null });
152
- return withIgnoredAction({ text: facts.length ? facts.map(fact => JSON.stringify(fact)).join('\n') : '운영 개관: 관측된 사실 없음', structured: { facts } });
168
+ return { text: facts.length ? facts.map(fact => JSON.stringify(fact)).join('\n') : '운영 개관: 관측된 사실 없음', structured: { facts } };
153
169
  }
154
170
  const dev = checklistDevVersion(deps.devVersion?.() ?? devVersion());
155
- if (ignoredAction === undefined && args.action !== undefined) {
171
+ if (args.action !== undefined) {
156
172
  const action = args.action;
157
173
  if (typeof action !== 'string' || !['schedule', 'blocked', 'landed'].includes(action)) {
158
174
  throw new Error('action 은 schedule, blocked, landed 중 하나여야 합니다');
@@ -225,7 +241,7 @@ export function dispatchReleaseStatus(args: Record<string, unknown>, deps: Relea
225
241
  publishAt: row.publishAt ?? null, freezeFrom: row.freezeFrom ?? null, freezeUntil: row.freezeUntil ?? null })) } };
226
242
  }
227
243
  debug.log('release.tool', 'status', { action: 'status', topic, version: requested ?? dev });
228
- return withIgnoredAction(result);
244
+ return result;
229
245
  }
230
246
  const version = requested ? null : dev;
231
247
  const versions = requested ? [requested as string] : [version!, nextVersion(version!)];
@@ -270,7 +286,7 @@ export function dispatchReleaseStatus(args: Record<string, unknown>, deps: Relea
270
286
  : published.state === 'unreadable' ? `발행 판 ${published.version} · 발행 기록 못 읽음` : '발행 판 모름';
271
287
  const structured = { releases: entries, latestRun: latest, published };
272
288
  debug.log('release.tool', 'status', { action: 'status', topic, version: versions.join(',') });
273
- return withIgnoredAction({ text: `${lines.join('\n\n')}\n${cards.map(formatElanousCard).join('\n')}\n${publishedLine}`, structured });
289
+ return { text: `${lines.join('\n\n')}\n${cards.map(formatElanousCard).join('\n')}\n${publishedLine}`, structured };
274
290
  }
275
291
 
276
292
  function requiredString(args: Record<string, unknown>, key: string): string {
@@ -146,7 +146,10 @@ export function recordInboundTurn(
146
146
  ): string | null {
147
147
  const q = (opts.userText ?? '').trim();
148
148
  if (!q) return null;
149
- const db = opts.db ?? openSurfaceEventsDb();
149
+ // Test runners must never fall through to the user's production memory DB.
150
+ const testRunner = process.env.NODE_ENV === 'test' || process.env.BUN_TEST !== undefined;
151
+ const isolatedTestPath = process.env.ELANOUS_STATE_DIR?.trim() ? surfaceEventsDbPath() : ':memory:';
152
+ const db = opts.db ?? openSurfaceEventsDb(testRunner ? isolatedTestPath : surfaceEventsDbPath());
150
153
  const ownDb = !opts.db;
151
154
  try {
152
155
  const a = (opts.responseText ?? '').trim();
@@ -50,8 +50,13 @@ export function startWatchDefaultScheduler(opts: WatchDefaultSchedulerOpts = {})
50
50
  running = true;
51
51
  try {
52
52
  const active = enabled() && listSources({ seat: 'user' }, root).length > 0;
53
- const registryDay = now().toISOString().slice(0, 10);
54
- const inventoryKey = `${registryDay}:${active}`;
53
+ const parts = new Intl.DateTimeFormat('en-CA', {
54
+ timeZone, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hourCycle: 'h23',
55
+ }).formatToParts(now());
56
+ const part = (type: string) => parts.find((entry) => entry.type === type)?.value ?? '';
57
+ const day = `${part('year')}-${part('month')}-${part('day')}`;
58
+ const clock = `${part('hour')}:${part('minute')}`;
59
+ const inventoryKey = `${day}:${active}`;
55
60
  if (lastInventory !== inventoryKey) {
56
61
  // The registry row is a view; a registry failure must not skip the real collect/brief of this minute.
57
62
  try {
@@ -62,14 +67,8 @@ export function startWatchDefaultScheduler(opts: WatchDefaultSchedulerOpts = {})
62
67
  }
63
68
  lastFailure = undefined;
64
69
  if (!active) return;
65
- const parts = new Intl.DateTimeFormat('en-CA', {
66
- timeZone, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hourCycle: 'h23',
67
- }).formatToParts(now());
68
- const part = (type: string) => parts.find((entry) => entry.type === type)?.value ?? '';
69
- const day = `${part('year')}-${part('month')}-${part('day')}`;
70
- const clock = `${part('hour')}:${part('minute')}`;
71
70
  for (const [job, at, fire] of [['watch-collect', '07:00', collect], ['watch-brief', '08:30', brief]] as const) {
72
- if (clock !== at || lastRun.get(job) === day) continue;
71
+ if (clock < at || lastRun.get(job) === day) continue;
73
72
  try {
74
73
  const outcome = await fire();
75
74
  if (job === 'watch-brief' && (!outcome || (outcome as { sent?: boolean }).sent !== true)) continue;
@@ -1,4 +1,5 @@
1
1
  import type { TranscriptEntry } from './index';
2
+ import type { STTProvider } from '../voice/stt-provider.js';
2
3
 
3
4
  /** Mono, normalized PCM. The capture instant is required for NOTE1's absolute photo alignment. */
4
5
  export interface FieldAudio {
@@ -70,6 +71,22 @@ export function createCloudSttEngine(client: CloudSttClient): TranscriptionEngin
70
71
  };
71
72
  }
72
73
 
74
+ export function createBatchSttEngine(provider: STTProvider): TranscriptionEngine {
75
+ return {
76
+ async transcribe(chunk, request) {
77
+ if (chunk.sampleRate !== 16000) throw new RangeError('Batch STT requires 16 kHz mono PCM');
78
+ const pcm = Buffer.alloc(chunk.samples.length * 2);
79
+ for (let i = 0; i < chunk.samples.length; i++) {
80
+ const sample = chunk.samples[i]!;
81
+ if (!Number.isFinite(sample)) throw new RangeError('Audio samples must be finite');
82
+ pcm.writeInt16LE(Math.round(Math.max(-1, Math.min(1, sample)) * (sample < 0 ? 32768 : 32767)), i * 2);
83
+ }
84
+ const { text } = await provider.transcribeBatch(pcm, { language: request.language });
85
+ return text.trim() ? [{ startSeconds: 0, endSeconds: chunk.samples.length / chunk.sampleRate, text }] : [];
86
+ },
87
+ };
88
+ }
89
+
73
90
  export interface TranscriptionOptions {
74
91
  /** Default: ko. */
75
92
  language?: string;
package/src/fold-stack.ts CHANGED
@@ -70,6 +70,9 @@ export interface StaticFoldTarget {
70
70
  groupKey?: string;
71
71
  /** Fold mode shared with fold-applied. FoldStack does not invent this. */
72
72
  mode?: string;
73
+ /** Offset (from lineStart) of the click that expanded this target —
74
+ * clicking the same row again collapses it (#16 two-way click). */
75
+ expandedAtOffset?: number;
73
76
  }
74
77
 
75
78
  export type FoldTarget = LiveFoldTarget | StaticFoldTarget;
@@ -178,6 +181,7 @@ export class FoldStack {
178
181
 
179
182
  this.opts.chatLines.splice(t.lineStart, oldLen, ...newLines);
180
183
  t.expanded = nextExpanded;
184
+ t.expandedAtOffset = undefined;
181
185
  t.lineEnd = t.lineStart + newLines.length;
182
186
 
183
187
  // Any OTHER static target whose lineStart is ≥ the toggled
@@ -224,6 +228,7 @@ export class FoldStack {
224
228
  const lineStart = t.lineStart;
225
229
  const lineEnd = t.lineEnd;
226
230
  const toggled = this.toggleTarget(t);
231
+ if (toggled) t.expandedAtOffset = t.expanded ? lineIndex - lineStart : undefined;
227
232
  if (toggled) {
228
233
  debug.log('log.fold', t.expanded ? 'fold-expanded' : 'fold-recollapsed', {
229
234
  mode: t.mode ?? null,
@@ -259,6 +264,16 @@ export class FoldStack {
259
264
  return t != null && t.expanded && t.lineStart === lineIndex;
260
265
  }
261
266
 
267
+ /** Fact for callers: may a click on `lineIndex` collapse its expanded
268
+ * target? True on the first line, the last line, and the row whose
269
+ * click expanded it — the rest of the body stays a reading area. */
270
+ isExpandedCollapseLine(lineIndex: number): boolean {
271
+ const t = this.findLatestStaticContaining(lineIndex);
272
+ if (t == null || !t.expanded) return false;
273
+ const offset = lineIndex - t.lineStart;
274
+ return offset === 0 || lineIndex === t.lineEnd - 1 || offset === t.expandedAtOffset;
275
+ }
276
+
262
277
  /** Toggle every static target on the stack in the same direction.
263
278
  * If ≥ half are already expanded we collapse all; otherwise we
264
279
  * expand all. Returns the number of targets that actually changed
@@ -273,7 +288,14 @@ export class FoldStack {
273
288
  const statics = this.targets.filter((t): t is StaticFoldTarget => t.kind === 'static');
274
289
  if (statics.length === 0) return 0;
275
290
  const expandedCount = statics.filter(t => t.expanded).length;
276
- const targetExpanded = expandedCount * 2 < statics.length; // <50% → expand all
291
+ return this.setAll(expandedCount * 2 < statics.length); // <50% → expand all
292
+ }
293
+
294
+ /** Put every static target in one explicit state (`/log unfold all` ·
295
+ * `/log fold all`). Returns how many targets changed; live targets are
296
+ * skipped exactly as in toggleAll. */
297
+ setAll(targetExpanded: boolean): number {
298
+ const statics = this.targets.filter((t): t is StaticFoldTarget => t.kind === 'static');
277
299
  // Sort by lineStart ascending; toggling from the top of chatLines
278
300
  // down means later targets shift consistently as we go. Skip
279
301
  // targets already in the desired state.
@@ -287,6 +309,7 @@ export class FoldStack {
287
309
  const delta = newLines.length - oldLen;
288
310
  this.opts.chatLines.splice(t.lineStart, oldLen, ...newLines);
289
311
  t.expanded = targetExpanded;
312
+ t.expandedAtOffset = undefined;
290
313
  t.lineEnd = t.lineStart + newLines.length;
291
314
  if (delta !== 0) {
292
315
  for (const other of this.targets) {
@@ -5,10 +5,11 @@
5
5
  // kernel has to stat every tracked file vs its index entry.
6
6
  //
7
7
  // Throttle is enforced by the caller (the index.ts cache). This
8
- // module just does one probe, synchronously (spawnSync), and is
9
- // intentionally side-effect free.
8
+ // module just does one probe and is intentionally side-effect free.
9
+ // The sync probes serve one-shot callers; the TUI's periodic refresh
10
+ // uses the async twins so `git status` never blocks its event loop.
10
11
 
11
- import { spawnSync } from 'node:child_process';
12
+ import { execFile, spawnSync } from 'node:child_process';
12
13
  import type { DirtyCount, AheadBehind } from './types.js';
13
14
  import { CLEAN_DIRTY } from './types.js';
14
15
 
@@ -26,6 +27,23 @@ export function probeDirty(cwd: string, timeoutMs = 5_000): DirtyCount {
26
27
  return parsePorcelain(res.stdout);
27
28
  }
28
29
 
30
+ /** Run git without blocking the caller's event loop; null on failure. */
31
+ function execGit(cwd: string, args: string[], timeoutMs: number, maxBuffer: number): Promise<string | null> {
32
+ return new Promise((resolveOut) => {
33
+ try {
34
+ execFile('git', args, { cwd, encoding: 'utf8', timeout: timeoutMs, maxBuffer }, (error, stdout) => {
35
+ resolveOut(error ? null : String(stdout ?? ''));
36
+ });
37
+ } catch { resolveOut(null); }
38
+ });
39
+ }
40
+
41
+ /** Async twin of `probeDirty`. */
42
+ export async function probeDirtyAsync(cwd: string, timeoutMs = 5_000): Promise<DirtyCount> {
43
+ const out = await execGit(cwd, ['status', '--porcelain'], timeoutMs, 2 * 1024 * 1024);
44
+ return out === null ? CLEAN_DIRTY : parsePorcelain(out);
45
+ }
46
+
29
47
  /** Parse porcelain v1 output. Format per line:
30
48
  *
31
49
  * XY <path> — regular change
@@ -66,7 +84,17 @@ export function probeAheadBehind(cwd: string, timeoutMs = 5_000): AheadBehind |
66
84
  { cwd, encoding: 'utf8', timeout: timeoutMs, maxBuffer: 64 * 1024 },
67
85
  );
68
86
  if (res.status !== 0 || res.error) return null;
69
- const parts = res.stdout.trim().split(/\s+/);
87
+ return parseAheadBehind(res.stdout);
88
+ }
89
+
90
+ /** Async twin of `probeAheadBehind`. */
91
+ export async function probeAheadBehindAsync(cwd: string, timeoutMs = 5_000): Promise<AheadBehind | null> {
92
+ const out = await execGit(cwd, ['rev-list', '--left-right', '--count', '@{u}...HEAD'], timeoutMs, 64 * 1024);
93
+ return out === null ? null : parseAheadBehind(out);
94
+ }
95
+
96
+ function parseAheadBehind(out: string): AheadBehind | null {
97
+ const parts = out.trim().split(/\s+/);
70
98
  if (parts.length < 2) return null;
71
99
  const behind = Number.parseInt(parts[0]!, 10);
72
100
  const ahead = Number.parseInt(parts[1]!, 10);
@@ -13,7 +13,7 @@ import { spawnSync } from 'node:child_process';
13
13
  import { findGitDir, type LocatedGit } from './locate.js';
14
14
  import { readGitHead } from './read-head.js';
15
15
  import { GitFileWatcher } from './watcher.js';
16
- import { probeDirty, probeAheadBehind } from './dirty.js';
16
+ import { probeDirty, probeAheadBehind, probeDirtyAsync, probeAheadBehindAsync } from './dirty.js';
17
17
  import { debug } from '../debug/log.js';
18
18
  import type {
19
19
  GitHeadInfo,
@@ -170,6 +170,47 @@ export function refreshDirty(
170
170
  };
171
171
  }
172
172
 
173
+ const dirtyInFlight = new Map<CacheEntry, Promise<GitStatusView>>();
174
+
175
+ function viewOf(entry: CacheEntry): GitStatusView {
176
+ return { head: entry.head, dirty: entry.dirty, aheadBehind: entry.aheadBehind, lastDirtyProbeAt: entry.lastDirtyProbeAt };
177
+ }
178
+
179
+ /** Non-blocking twin of `refreshDirty` for the TUI: the probes run as
180
+ * async subprocesses so a slow `git status` (large worktree, loaded
181
+ * host) never stalls key input. Same throttle; concurrent calls share
182
+ * one probe, except that `force` (a known write just happened) never
183
+ * reuses a probe that started before it. */
184
+ export function refreshDirtyAsync(
185
+ cwd: string,
186
+ opts: { minIntervalMs?: number; force?: boolean } = {},
187
+ ): Promise<GitStatusView> {
188
+ let entry: CacheEntry | null;
189
+ try { entry = ensureEntry(cwd); } catch (error) { return Promise.reject(error); }
190
+ if (!entry) return Promise.resolve({ head: null, dirty: null, aheadBehind: null, lastDirtyProbeAt: 0 });
191
+ // An in-flight probe (possibly a forced, post-write one) is newer than the last stored view.
192
+ const running = dirtyInFlight.get(entry);
193
+ if (running && !opts.force) return running;
194
+ const min = opts.minIntervalMs ?? 2_000;
195
+ if (!opts.force && entry.lastDirtyProbeAt > 0 && Date.now() - entry.lastDirtyProbeAt < min) {
196
+ return Promise.resolve(viewOf(entry));
197
+ }
198
+ const target = entry;
199
+ const root = target.located.root;
200
+ const start = (): Promise<GitStatusView> => Promise.all([probeDirtyAsync(root), probeAheadBehindAsync(root)])
201
+ .then(([dirty, aheadBehind]) => {
202
+ target.dirty = dirty;
203
+ target.aheadBehind = aheadBehind;
204
+ target.lastDirtyProbeAt = Date.now();
205
+ return viewOf(target);
206
+ });
207
+ // A forced probe queues behind the running one so it reads the post-write tree.
208
+ const probe = (running ? running.then(start, start) : start())
209
+ .finally(() => { if (dirtyInFlight.get(target) === probe) dirtyInFlight.delete(target); });
210
+ dirtyInFlight.set(target, probe);
211
+ return probe;
212
+ }
213
+
173
214
  /** Claude Code-style git snapshot for LLM system context.
174
215
  * This is intentionally a point-in-time summary: good enough for
175
216
  * baseline repo awareness, but callers should still use tools for
@@ -256,4 +297,5 @@ export function __resetGitFsCache(): void {
256
297
  for (const [, entry] of cache) entry.watcher.dispose();
257
298
  cache.clear();
258
299
  clearGitSnapshotCache();
300
+ dirtyInFlight.clear();
259
301
  }
@@ -0,0 +1,81 @@
1
+ import { debug } from '../debug/log.js';
2
+
3
+ /** One measured execution at a GitHub boundary. Never put an URL, arguments, token, or body here. */
4
+ export interface GithubRemoteCall {
5
+ kind: 'rest' | 'graphql' | 'gh-command' | 'git-clone' | 'git-fetch' | 'git-push';
6
+ caller: string;
7
+ route: string;
8
+ method?: string;
9
+ host: string;
10
+ scopeId?: string;
11
+ runId?: string;
12
+ retry?: number;
13
+ }
14
+
15
+ export interface GithubRemoteOutcome<T> {
16
+ failed: boolean;
17
+ result?: T;
18
+ error?: unknown;
19
+ }
20
+
21
+ export interface GithubRemoteCallOptions<T> {
22
+ /** Return an observed HTTP status only; CLI success alone is not HTTP 200. */
23
+ status?: (outcome: GithubRemoteOutcome<T>) => number | undefined;
24
+ now?: () => number;
25
+ emit?: (category: string, event: string, data: Record<string, unknown>) => void;
26
+ }
27
+
28
+ /** Execute the real call and record exactly one completion, including failures. Observation cannot change the result. */
29
+ export async function runGithubRemoteCall<T>(
30
+ call: GithubRemoteCall,
31
+ execute: () => Promise<T>,
32
+ options: GithubRemoteCallOptions<T> = {},
33
+ ): Promise<T> {
34
+ const now = options.now ?? Date.now;
35
+ const safeNow = (): number | undefined => {
36
+ try { const value = now(); return Number.isFinite(value) ? value : undefined; } catch { return undefined; }
37
+ };
38
+ const started = safeNow();
39
+ let outcome: GithubRemoteOutcome<T> = { failed: false };
40
+ try {
41
+ const result = await execute();
42
+ outcome = { failed: false, result };
43
+ return result;
44
+ } catch (error) {
45
+ outcome = { failed: true, error };
46
+ throw error;
47
+ } finally {
48
+ let status: number | undefined;
49
+ try { status = options.status?.(outcome); } catch { /* telemetry must not alter the call */ }
50
+ const ended = safeNow();
51
+ const data: Record<string, unknown> = {
52
+ kind: call.kind,
53
+ caller: call.caller,
54
+ route: call.route,
55
+ method: call.method ?? 'unmeasured',
56
+ host: call.host,
57
+ scopeId: call.scopeId ?? 'unmeasured',
58
+ runId: call.runId ?? '',
59
+ retry: call.retry ?? 'unmeasured',
60
+ status: status ?? 'unmeasured',
61
+ ok: !outcome.failed,
62
+ durationMs: started === undefined || ended === undefined ? 'unmeasured' : Math.max(0, ended - started),
63
+ };
64
+ try { (options.emit ?? debug.log.bind(debug))('github.transport', 'complete', data); } catch { /* same rule */ }
65
+ }
66
+ }
67
+
68
+ /** Only a real GitHub remote belongs in the Git transport denominator. */
69
+ export function isGithubGitRemote(remote: string): boolean {
70
+ let host: string | undefined;
71
+ if (remote.includes('://')) {
72
+ try {
73
+ const url = new URL(remote);
74
+ if (!['http:', 'https:', 'ssh:', 'git:'].includes(url.protocol)) return false;
75
+ host = url.hostname;
76
+ } catch { return false; }
77
+ } else {
78
+ host = /^(?:[^@\s]+@)?([^:/\s]+):[^\s]+$/.exec(remote)?.[1];
79
+ }
80
+ return host === 'github.com' || host === 'ssh.github.com';
81
+ }
@@ -75,8 +75,18 @@ export function hydrateGoalFromSnapshot(): Goal | null {
75
75
  persistSnapshot(null);
76
76
  return null;
77
77
  }
78
- current = parsed;
79
- debug.log('goal', 'snapshot.hydrated', { id: current.id, status: current.status });
78
+ // TUI-GOAL-LOOP-FRICTION(#35) — 프로세스가 죽어 있던 시간은 이 목표가 «돈» 시간이 아니다.
79
+ // active 로 되살아나면 벽시계 기준을 지금으로 다시 잡는다(낡은 createdAt 기준 4.9억 ms 소진 오판 방지).
80
+ const now = Date.now();
81
+ const staleStart = goalWallClockStart(parsed);
82
+ current = parsed.status === 'active'
83
+ ? { ...parsed, activeSince: now, usage: { ...parsed.usage, elapsedMs: 0 } }
84
+ : parsed;
85
+ debug.log('goal', 'snapshot.hydrated', {
86
+ id: current.id, status: current.status,
87
+ wallClockRestarted: parsed.status === 'active',
88
+ staleElapsedMs: Math.max(0, now - staleStart),
89
+ });
80
90
  notify(current, null);
81
91
  return getCurrentGoal();
82
92
  } catch (error) {
@@ -100,12 +110,25 @@ export function generateGoalId(): string {
100
110
  return `g-${ts}-${rand}`;
101
111
  }
102
112
 
113
+ /** TUI-GOAL-LOOP-FRICTION(#35) — 벽시계 예산의 기준 시각 = 이번에 active 로 들어선 때.
114
+ * 옛 스냅숏(activeSince 없음)만 createdAt 으로 떨어진다. */
115
+ export function goalWallClockStart(goal: Goal): number {
116
+ return typeof goal.activeSince === 'number' && Number.isFinite(goal.activeSince)
117
+ ? goal.activeSince
118
+ : goal.createdAt;
119
+ }
120
+
121
+ /** 이번 활성화 기준 벽시계 경과(ms). 시계가 거꾸로 가도 음수는 내지 않는다. */
122
+ export function goalWallClockElapsedMs(goal: Goal, now: number): number {
123
+ return Math.max(0, now - goalWallClockStart(goal));
124
+ }
125
+
103
126
  export function getCurrentGoal(): Goal | null {
104
127
  if (!current) return null;
105
128
  // Refresh elapsed ms on read so callers don't see stale values.
106
129
  return {
107
130
  ...current,
108
- usage: { ...current.usage, elapsedMs: Date.now() - current.createdAt },
131
+ usage: { ...current.usage, elapsedMs: goalWallClockElapsedMs(current, Date.now()) },
109
132
  };
110
133
  }
111
134
 
@@ -155,6 +178,7 @@ export function startGoal(input: GoalCreateInput): { ok: true; goal: Goal } | {
155
178
  status: 'active',
156
179
  createdAt: now,
157
180
  updatedAt: now,
181
+ activeSince: now,
158
182
  budget,
159
183
  usage: { turnsUsed: 0, tokensUsed: 0, tokensMeasured: true, elapsedMs: 0 },
160
184
  linkedTaskId: input.linkedTaskId,
@@ -173,8 +197,22 @@ export function setStatus(next: GoalStatus, reason?: string): { ok: true; goal:
173
197
  return { ok: false, error: { code: 'GoalNotFound', message: 'No active goal.' } };
174
198
  }
175
199
  const prev = { ...current };
176
- current = { ...current, status: next, updatedAt: Date.now() };
200
+ const now = Date.now();
201
+ // TUI-GOAL-LOOP-FRICTION(#35) — paused·budget-limited·resume_required → active 는 «새 활성화»다.
202
+ // 벽시계는 여기서 다시 잰다 — 멈춰 있던 시간(며칠)을 이번 실행 예산에 싣지 않는다.
203
+ const reactivated = next === 'active' && prev.status !== 'active';
204
+ current = {
205
+ ...current,
206
+ status: next,
207
+ updatedAt: now,
208
+ ...(reactivated ? { activeSince: now, usage: { ...current.usage, elapsedMs: 0 } } : {}),
209
+ };
177
210
  debug.log('goal', 'status', { id: current.id, from: prev.status, to: next, reason: reason ?? '' });
211
+ if (reactivated) {
212
+ debug.log('goal', 'wall-clock-restart', {
213
+ id: current.id, from: prev.status, priorElapsedMs: goalWallClockElapsedMs(prev, now),
214
+ });
215
+ }
178
216
  try {
179
217
  writeGoalTransitionLedger({
180
218
  timestamp: new Date().toISOString(),
@@ -210,7 +248,7 @@ export function recordTurn(opts: { tokens?: number; verdict?: Goal['lastVerdict'
210
248
  turnsUsed: current.usage.turnsUsed + 1,
211
249
  tokensUsed: current.usage.tokensUsed + (opts.tokens ?? 0),
212
250
  tokensMeasured: current.usage.tokensMeasured && opts.tokens !== undefined,
213
- elapsedMs: Date.now() - current.createdAt,
251
+ elapsedMs: goalWallClockElapsedMs(current, Date.now()),
214
252
  },
215
253
  lastVerdict: opts.verdict ?? current.lastVerdict,
216
254
  lastSummary: opts.summary ?? current.lastSummary,
@@ -251,7 +289,9 @@ const NO_GOAL_BUDGET_DIAGNOSTICS: GoalBudgetDiagnostics = {
251
289
  export function evaluateGoalBudget(goal: Goal, now: number): GoalBudgetDiagnostics {
252
290
  const { turnsUsed, tokensUsed, elapsedMs, tokensMeasured } = goal.usage;
253
291
  const { maxTurns, tokenBudget, wallClockMaxMs } = goal.budget;
254
- const elapsedWallClockMs = Math.max(elapsedMs, now - goal.createdAt);
292
+ // TUI-GOAL-LOOP-FRICTION(#35) — 기준 = 이번 활성화 시작(activeSince · 옛 스냅숏만 createdAt).
293
+ // usage.elapsedMs 도 같은 기준으로만 쓰인다(재활성화·hydrate 때 0 으로 되돌린다).
294
+ const elapsedWallClockMs = Math.max(elapsedMs, goalWallClockElapsedMs(goal, now));
255
295
  const exceededAxes = [
256
296
  ...(turnsUsed >= maxTurns ? [{ axis: 'maxTurns' as const, used: turnsUsed, limit: maxTurns }] : []),
257
297
  ...(tokenBudget > 0 && tokensUsed >= tokenBudget
@@ -69,7 +69,8 @@ export interface GoalUsage {
69
69
  tokensUsed: number;
70
70
  /** Whether every recorded auto-turn supplied a token measurement. */
71
71
  tokensMeasured: boolean;
72
- /** Wall-clock since createdAt, refreshed on read. */
72
+ /** Wall-clock since this activation began (`activeSince`, falling back to
73
+ * `createdAt` for old snapshots), refreshed on read. */
73
74
  elapsedMs: number;
74
75
  }
75
76
 
@@ -97,6 +98,11 @@ export interface Goal {
97
98
  status: GoalStatus;
98
99
  /** Epoch ms. */
99
100
  createdAt: number;
101
+ /** TUI-GOAL-LOOP-FRICTION(#35) — epoch ms when the goal last entered `active`
102
+ * (start · resume · process restart hydrate). The wall-clock budget is measured
103
+ * from here, not from `createdAt`: a goal created days ago and resumed now must
104
+ * not report 4.9e8 ms elapsed. Optional so older snapshots still parse. */
105
+ activeSince?: number;
100
106
  /** Last time status transitioned. */
101
107
  updatedAt: number;
102
108
  budget: GoalBudget;
@@ -34,6 +34,7 @@ const RELEASE_NODE_COMMANDS: Readonly<Record<string, { recipe: string; command?:
34
34
  'checklist-gate': { recipe: 'cmd:checklist-gate', command: 'bun scripts/release-loop/checklist-gate-node.ts' },
35
35
  prefetch: { recipe: 'cmd:docs', command: 'bun scripts/release-loop/docs-node.ts --json' },
36
36
  gate: { recipe: 'cmd:gate', command: 'bun scripts/release-loop/gate-node.ts --json' },
37
+ 'gate-triage': { recipe: 'cmd:gate-triage', command: 'bun scripts/release-loop/gate-triage-node.ts' },
37
38
  'mac-smoke': { recipe: 'cmd:mac-smoke', command: 'bun scripts/release-loop/mac-smoke-node.ts' },
38
39
  'export-check': { recipe: 'cmd:export-check', command: 'bun scripts/release-loop/export-check-node.ts' },
39
40
  pwa: { recipe: 'cmd:pwa', command: 'bun scripts/release-loop/node-verdict.ts pwa' },
@@ -53,6 +54,7 @@ const RELEASE_NODE_COMMANDS: Readonly<Record<string, { recipe: string; command?:
53
54
  'release-story': { recipe: 'cmd:release-story', command: 'bun scripts/release-story/draft.ts --graph' },
54
55
  'ops-upgrade': { recipe: 'cmd:ops-upgrade', command: 'bun scripts/release-loop/ops-upgrade-node.ts' },
55
56
  'version-dev-bump': { recipe: 'cmd:version-dev-bump', command: 'bun scripts/release-loop/version-node.ts dev-bump --json' },
57
+ 'version-dev-bump-after-failure': { recipe: 'cmd:version-dev-bump', command: 'bun scripts/release-loop/version-node.ts dev-bump --json' },
56
58
  done: { recipe: 'none' },
57
59
  failed: { recipe: 'none' },
58
60
  };
@@ -478,6 +478,32 @@ export function isGrokSubscriptionExpiring(
478
478
  return (opts.now ?? Date.now)() + (opts.bufferMs ?? GROK_REFRESH_BUFFER_MS) >= ms;
479
479
  }
480
480
 
481
+ /** 구독 만료 상태 — 칸 CRED-EXPIRY-REFRESH 기준 창. 이 안에 만료가 오면 갱신 후보다. */
482
+ export const GROK_EXPIRY_SOON_WINDOW_MS = 2 * 60 * 60 * 1000;
483
+
484
+ /** 만료 상태 셋 — ⛔ boolean 으로 접으면 「모름」과 «여유»가 «같은 값»이 된다. */
485
+ export type GrokSubscriptionExpiryState = 'healthy' | 'expiring' | 'unknown';
486
+
487
+ /** 실제로 쓸 구독(key 를 가진 scope 중 가장 늦게 만료되는 것)의 expires_at 만으로 상태를 가른다.
488
+ *
489
+ * ⭐ 칸 CRED-EXPIRY-REFRESH 첫 조각 — «토큰 없이» 읽는다:
490
+ * · 선택 규칙은 `readSubscriptionToken` 과 «같다»(key 없는 항목의 만료에 속지 않는다).
491
+ * · 반환은 상태 «하나»뿐 — 토큰 값은 어떤 형태로도 나가지 않는다.
492
+ * · 기존 `isGrokSubscriptionExpiring`(boolean)은 모름을 false 로 접는다 — 이 함수는
493
+ * 모름을 'unknown' 으로 «별도의 값»으로 낸다. 갱신 유도·호스트 발사는 후속 조각.
494
+ * · 순수 판정 — 부수효과가 없고, 파일이 못 읽히면 죽이지 않고 'unknown' 을 낸다. */
495
+ export function grokSubscriptionExpiryState(
496
+ opts: { home?: string; bufferMs?: number; now?: () => number } = {},
497
+ ): GrokSubscriptionExpiryState {
498
+ const raw = readSubscriptionToken(grokAuthFilePath(opts.home))?.expiresAt ?? null;
499
+ if (raw === null) return 'unknown';
500
+ const ms = Date.parse(raw);
501
+ if (!Number.isFinite(ms)) return 'unknown';
502
+ return (opts.now ?? Date.now)() + (opts.bufferMs ?? GROK_EXPIRY_SOON_WINDOW_MS) >= ms
503
+ ? 'expiring'
504
+ : 'healthy';
505
+ }
506
+
481
507
  /** 갱신 경로의 관측 — ⛔ 토큰은 «절대» 싣지 않는다(판정·결과·출처만). */
482
508
  function observeGrokAuth(event: string, data: Record<string, unknown>): void {
483
509
  try {
@@ -5,6 +5,7 @@
5
5
  // planHarnessClean = 순수 분류(테스트). execHarnessClean = git/gh IO + 실제 제거.
6
6
 
7
7
  import { spawnSync } from 'node:child_process';
8
+ import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
8
9
  import { existsSync, readdirSync, statSync } from 'node:fs';
9
10
  import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
10
11
  import { listPtyManifest, type PtyManifestRow } from '../pty-shell/pty-manifest.js';
@@ -466,7 +467,7 @@ export type { GitRunner, GitRunResult } from '../git-fs/retry.js';
466
467
 
467
468
  const defaultGitRunner: GitRunner = (args) => {
468
469
  // git-spawn-allow: This is the injected low-level runner consumed by direct runGitWithRetry callers; routing it through runGitCommand would recurse through the retry seam.
469
- const r = spawnSync('git', args, { encoding: 'utf8', timeout: 20_000 });
470
+ const r = spawnSync('git', args, { encoding: 'utf8', timeout: 20_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
470
471
  return { status: r.status, stdout: r.stdout ?? '', stderr: r.stderr ?? '' };
471
472
  };
472
473