elanous 0.2.35 → 0.2.37

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 (827) 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/{T1mBQqmkwKDLGtyisDCOd → 8kITumG9GAZ1LwT9POrAR}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/1041-5841aae848fb6403.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/1087.3177e54f672dc526.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1105.efe1e13503ac7a33.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1224.2ceca6c180d5130b.js +62 -0
  8. package/apps/pwa/out/_next/static/chunks/{9952.5daf5f94063a2b3e.js → 1262.a89bb27a5b2f844e.js} +1 -1
  9. package/apps/pwa/out/_next/static/chunks/1417-1768233ac92f8a5d.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1612.81bbc19af06af16c.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1746.3563617ea64023a3.js +115 -0
  12. package/apps/pwa/out/_next/static/chunks/1766.728d42053070bb2d.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1773.d38e945481e04125.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1974-c12f9600da3d3c26.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/{1dc5a567.9b092bfae3d7099b.js → 1ed5e8af.cf424815c7c0efad.js} +1 -1
  16. package/apps/pwa/out/_next/static/chunks/{4705-194e64e47ca0fbdb.js → 2002-a43a3f380df873ec.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/2061.7232dc9dc058417f.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{13.02a07436dec15f89.js → 210.90b2cbd64926cf34.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/{9512.5a76207a730e0491.js → 2283.edd9627b7bdfb546.js} +2 -2
  20. package/apps/pwa/out/_next/static/chunks/{6866-79aa5b4e47cac6aa.js → 2318-450e75d07605b8fe.js} +1 -1
  21. package/apps/pwa/out/_next/static/chunks/{938.66ad1ef0e5abae1c.js → 2375.bf364c85dbb6f085.js} +1 -1
  22. package/apps/pwa/out/_next/static/chunks/244-a810d282a20f1783.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2479-fe7e188bd9402d14.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2514.03b60f266531a015.js +148 -0
  25. package/apps/pwa/out/_next/static/chunks/2526-a657538869888604.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2533-6f0341ff075809e9.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2676.e7994c695ef0f30d.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2734.3ffdf54254fb6f99.js +27 -0
  29. package/apps/pwa/out/_next/static/chunks/2770-23252bf3a37880b9.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/2969.66b8b545139d1544.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/3128.a9210d08800ea6a8.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/3199.6a1a9b0e6cd01dc6.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/3212.12179fd3eee8cef1.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/{9214.63a510d39178e997.js → 3578.4e9f9948a9a6f2f4.js} +2 -2
  35. package/apps/pwa/out/_next/static/chunks/3760-2909ddb9279281cd.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3825.1921b5901bf33dce.js +36 -0
  37. package/apps/pwa/out/_next/static/chunks/3994-63eb884ed0547011.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/4036.d54e55e1ebf5acdc.js +90 -0
  39. package/apps/pwa/out/_next/static/chunks/4115.5b438b99f0ae729f.js +226 -0
  40. package/apps/pwa/out/_next/static/chunks/4269.d8f9f34bb0fc6c43.js +287 -0
  41. package/apps/pwa/out/_next/static/chunks/431-4eed5bd2c5fe1719.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/{2018.a741297bce759490.js → 4313.76f232c304a15bde.js} +1 -1
  43. package/apps/pwa/out/_next/static/chunks/{1165.bad13fc9151a7288.js → 4324.c99ba3e83eb1b691.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/{3f7c4ee5.3dde54f01a816613.js → 4337e36d.f42c3b391b3d8f20.js} +1 -1
  45. package/apps/pwa/out/_next/static/chunks/{7385.50a308a477bdfc21.js → 4383.18e5c54db3a22c88.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4599-96eff3f2a9c242c1.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{8557-e7898769499cd56f.js → 4725-34bed25720cc326b.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/4825-a9d9d4e9f5892309.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/{5483-dd5d7697f6bdb106.js → 4833-7934c592c5569f00.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/4879-68518f547a207aff.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4896.f9b70285363b27b2.js +24 -0
  52. package/apps/pwa/out/_next/static/chunks/{8444.4c26b379ca2b9596.js → 4931.95cc6dbd230774ca.js} +17 -17
  53. package/apps/pwa/out/_next/static/chunks/4937-28d437999b77c9dd.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/49aa54ab.80f39398e0ed0f30.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{3408.21d1570602f4b6c0.js → 5046.7fd5cbd859299448.js} +1 -1
  56. package/apps/pwa/out/_next/static/chunks/5056.482687319b82638e.js +104 -0
  57. package/apps/pwa/out/_next/static/chunks/506.16b83d56a437a9ee.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5260-20593b0a25d0afbc.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5404.cc4e9fec26fd5925.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/576.485e83e3f3dec19a.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5832-a6be14e663f65726.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5854-56648a9fe646b9a0.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/58edce7d.f1b0c72acf13b123.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5925.3b1f8b135710249b.js +93 -0
  65. package/apps/pwa/out/_next/static/chunks/5952.294fc574a8625184.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/{b6705a4f-b9a9047de9eecfd0.js → 5f6af561-f90b7a67f4f75d13.js} +1 -1
  67. package/apps/pwa/out/_next/static/chunks/6168.17749aa3905fa073.js +74 -0
  68. package/apps/pwa/out/_next/static/chunks/6252.240578f10952e091.js +34 -0
  69. package/apps/pwa/out/_next/static/chunks/6416.5d50b8ec9986ca98.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/{5101.e32282718f99ed6f.js → 6680.6a693c28aae4cd19.js} +1 -1
  71. package/apps/pwa/out/_next/static/chunks/{4718-17d2af636796a330.js → 6745-5a63492933959dd9.js} +3 -3
  72. package/apps/pwa/out/_next/static/chunks/6758.e7fbf532953c0783.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6795.0cb8a59730d99703.js +149 -0
  74. package/apps/pwa/out/_next/static/chunks/{6236.e18cced2d5ba6afb.js → 6819.be5c9c4d67f22922.js} +16 -16
  75. package/apps/pwa/out/_next/static/chunks/6877-84d47b7e85d0c41e.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/{2833-0fe47af99ed13c29.js → 6971-fb5f9dc0a2cb5d2d.js} +1 -1
  77. package/apps/pwa/out/_next/static/chunks/{da5176c6.6773b6c5994e1d99.js → 709a918c.4fd3b4e2a32cb4e3.js} +1 -1
  78. package/apps/pwa/out/_next/static/chunks/717.522b08685979b814.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/7191.e41eb8f455c7f089.js +41 -0
  80. package/apps/pwa/out/_next/static/chunks/7233.8e744b7513119409.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7238-97c2226f80504bd8.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7285.307963afcf7e7660.js +24 -0
  83. package/apps/pwa/out/_next/static/chunks/7299-fbe4b8c47a87614a.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7314.df0d95930b0c3f50.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7406.c0589fdf2ee66629.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7424.c0fe2a595d4232b5.js +23 -0
  87. package/apps/pwa/out/_next/static/chunks/752-90e3e7daad3d8e39.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7524-bcd3d9928c6842d9.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7549.9a4de3bf231cfc52.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/757-4fbaf50942b8c424.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/765.76ae970ceb597b5b.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{7644.17e37ba6f1d4226e.js → 7867.e8725745ddd1d940.js} +4 -4
  93. package/apps/pwa/out/_next/static/chunks/7893-e444a1b0809cd1e4.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7956-33748cabb3a05562.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{0368f25d-ad84af92fefee68f.js → 7c5ed21f-f286708e57cf88f7.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/8030-aa66b478b53dbfca.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8051.c88c07dacbbc5f21.js +8 -0
  98. package/apps/pwa/out/_next/static/chunks/{359-2250789a2d3499e7.js → 8080-40d781e7704d3671.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/8149.80e402d4345e8dae.js +77 -0
  100. package/apps/pwa/out/_next/static/chunks/8205.50a5268f4e12ba0b.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8231.a128feaa6f8b6079.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/85.4ddb1dda2ea3ffa2.js +286 -0
  103. package/apps/pwa/out/_next/static/chunks/8537.26517a09e8247beb.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8595-e9b7081ab773a61f.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8821-30cc65a61a60951f.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8905.b3385aadb7b133e6.js +79 -0
  107. package/apps/pwa/out/_next/static/chunks/8983.246bb3a1ac38f50f.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/{b2f6ba4d.fb56fdbbf798df33.js → 8c58d09b.e8724a299658d86f.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/9072.18342f5941a1f3ec.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/9123.9df04866b2d6e00f.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/{1530.0e612369b6fd7ea0.js → 9151.a2c51e93f9156dae.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/{4441-875b97f5821ed58a.js → 9175-7d383df15a82e2be.js} +1 -1
  113. package/apps/pwa/out/_next/static/chunks/9181-bf89c07ce5b8f599.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/920-429bbc4504b45f71.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9207.625edf45d656151c.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9378.d2575c6ffd6dd756.js +94 -0
  117. package/apps/pwa/out/_next/static/chunks/957.db5b5c4d32a35240.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/958.53a8dcf4729e6997.js +64 -0
  119. package/apps/pwa/out/_next/static/chunks/9647.8f0cd0898c592a29.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9665-26abb02665704c2c.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9703.e7d81b6faef1050a.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9882-7a9164b3c2dacbe5.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/9998.b74e033efadecd10.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c604fb980a634d88.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ec2d8a4979ca9075.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cb6add08ad3c7660.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/board/page-e2eaa321ec223fe6.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/botlab/page-5b8a09c475b5f844.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/bots/page-91a77daedfbac191.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/ceo/page-f37fc5e974bda39b.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/chat/page-91429a0b78415a94.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/consult/page-b95798b58263b910.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/control/page-763d53e175e17aa1.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/decisions/page-d55023204055b12f.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/design-check/page-89d2140d78abc810.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/editor/page-82dc069abfe27f55.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/exec/page-25d9eee7beb552c0.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/field/page-770b4594c713ee97.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c604fb980a634d88.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/inside/page-ba8e0dcae4f83985.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/intake/page-5c112c6d7c33656e.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/layout-09788e1aa9a87db6.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live/page-3337c6a1328c2674.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live-run/page-89acd5d68c0bc560.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/loops/page-5c13e2c76371d797.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/market/page-653a9f18642825c6.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-fe986fe79b107546.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/morning/{page-47c5d4db587266bd.js → page-1e5da297557d2354.js} +1 -1
  149. package/apps/pwa/out/_next/static/chunks/app/not-found-91ea9f5869a40943.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/observatory/page-7824e21b999962e2.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-53d00a60cc75a922.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-1f5a60f70cb4dd0c.js → page-88a1edbff62eaf1d.js} +1 -1
  153. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e931248b3f9574b.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/outputs/{page-bac7dee94e5eae4a.js → page-443364c9e4a23b31.js} +1 -1
  155. package/apps/pwa/out/_next/static/chunks/app/page-b9af2ac1c4737ce8.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/reflection/page-25ab9c614c14129b.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-dbcdcfac0a395a8a.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bf1de6645089ec58.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c4201761a5e839c9.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/page-c304f469ea5d70e4.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8e5a238cf5e50c9c.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c604fb980a634d88.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/page-32b526069ee50b3c.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/share/page-fb9e639c107f5f72.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/showroom/page-84220c776608cedc.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/tasks/page-e475618cbfd5ca2b.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/term/{page-dc0a532f5b9196ec.js → page-ac2c1e6169cfce57.js} +1 -1
  168. package/apps/pwa/out/_next/static/chunks/app/today/page-fccd3020af2f8806.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/trace/page-9c0d7198ff7b5a91.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/vault/page-d54b1ec9b9c6430d.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8c4bef1791d732ca.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/page-46fcc0b0bbc6fbfe.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workspace/page-c1c80e345fa9d6f5.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7dfda00afd172f5b.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/{d06f9160.a3d9062f95de8ad7.js → d9815f84.4918f682a45a8502.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{cbe38a15.5a032598e39970c6.js → de8446d3.31b73eb239fecd7b.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/f21fd540.63ac75328926ed30.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/framework-77fdcc873519a6cd.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-app-d0d620d2ce235713.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-e0ef79c79337ba90.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-84b1bc71e3f9ce6a.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-2acb61f1363128cb.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-462ff5727ceb7824.js +1 -0
  184. package/apps/pwa/out/_next/static/css/{b5d88eba78a3d7bf.css → be9019f696217521.css} +1 -1
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +23 -23
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +23 -23
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +23 -23
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +22 -22
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +22 -22
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +23 -23
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +22 -22
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +23 -23
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +23 -23
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +22 -22
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +23 -23
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -23
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +23 -23
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +23 -23
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +22 -22
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +23 -23
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +23 -23
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -23
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +22 -22
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +22 -22
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +23 -23
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +23 -23
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +22 -22
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +22 -22
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +22 -22
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +23 -23
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +23 -23
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +22 -22
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +23 -23
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +23 -23
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +23 -23
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +23 -23
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +23 -23
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +22 -22
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +23 -23
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +23 -23
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +23 -23
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +23 -23
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +23 -23
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +23 -23
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +23 -23
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +23 -23
  278. package/docs/goal-context/05-authoring-lessons.jsonl +47 -0
  279. package/docs/goal-context/README.md +3 -0
  280. package/graphs/default-loop.yaml +6 -1
  281. package/graphs/drafts/recipes.yaml +27 -7
  282. package/graphs/implement-loop.yaml +24 -0
  283. package/graphs/release/recipes.yaml +6 -0
  284. package/graphs/release/release-loop.yaml +17 -4
  285. package/graphs/wizard/recipes.yaml +44 -0
  286. package/graphs/wizard/wizard-loop.yaml +44 -0
  287. package/graphs/work/draft-close.yaml +54 -0
  288. package/graphs/work/green-close.yaml +37 -0
  289. package/graphs/work/recipes.yaml +46 -1
  290. package/graphs/work/research-report.yaml +2 -0
  291. package/graphs/work/run-research.yaml +35 -0
  292. package/package.json +1 -1
  293. package/scripts/__fixtures__/authoring-paths-10x3.json +32 -0
  294. package/scripts/boundary-proof-mapping-audit.ts +88 -0
  295. package/scripts/ci-typecheck-changed.ts +139 -5
  296. package/scripts/codex-fallback-live-probe.ts +17 -15
  297. package/scripts/coord-role-pack.ts +1 -1
  298. package/scripts/first10-gate.ts +416 -0
  299. package/scripts/fleet/node-setup.sh +32 -2
  300. package/scripts/fleet/run-light-worker.sh +9 -0
  301. package/scripts/fleet/wsl-node-setup.sh +432 -0
  302. package/scripts/gate-0226-failure-census.ts +507 -0
  303. package/scripts/goals/authoring-metrics.ts +258 -0
  304. package/scripts/graph-units/draft-close-node.ts +222 -0
  305. package/scripts/hook-order-sweep.ts +7 -4
  306. package/scripts/land-global-checks.ts +69 -1
  307. package/scripts/measure-nl-routing-corpus.ts +207 -2
  308. package/scripts/release-loop/docs-node.ts +344 -8
  309. package/scripts/release-loop/gate-closure.ts +48 -0
  310. package/scripts/release-loop/gate-diff.ts +2 -1
  311. package/scripts/release-loop/gate-node.ts +249 -53
  312. package/scripts/release-loop/known-issues-node.ts +6 -4
  313. package/scripts/release-loop/node-verdict.ts +2 -0
  314. package/scripts/release-loop/notes-repair.ts +216 -0
  315. package/scripts/release-loop/prepare-node.ts +61 -5
  316. package/scripts/release-loop/resume-cap.ts +14 -34
  317. package/scripts/release-loop/resume-release.ts +151 -15
  318. package/scripts/release-loop/resume-test-traffic.ts +10 -0
  319. package/scripts/release-loop/traffic-node.ts +59 -0
  320. package/scripts/release-loop/traffic-transition.ts +159 -0
  321. package/scripts/release-loop/version-node.ts +81 -12
  322. package/scripts/rhythm/daily.ts +137 -3
  323. package/scripts/train/green-leg.ts +176 -0
  324. package/scripts/tui-continue-real-evidence.ts +47 -0
  325. package/scripts/ux-sim.ts +53 -0
  326. package/skills/README.md +1 -0
  327. package/src/acp/client.ts +31 -5
  328. package/src/acp/core-turn-bridge.ts +54 -6
  329. package/src/acp/stderr-summary.ts +49 -0
  330. package/src/agent/delegate-hint.ts +16 -0
  331. package/src/agent/monad-agent-turn.ts +1 -0
  332. package/src/agent/runner.ts +82 -2
  333. package/src/agent/task-notification.ts +56 -10
  334. package/src/agent/terminal-surface.ts +217 -0
  335. package/src/agent/types.ts +4 -0
  336. package/src/agent-substrate/pr-reviewer.ts +64 -4
  337. package/src/agent-substrate/review-intent.ts +29 -2
  338. package/src/agent-substrate/review-observation.ts +3 -0
  339. package/src/agent-substrate/self-review-cli.ts +490 -26
  340. package/src/autopilot/lineage/sources.ts +1 -1
  341. package/src/autopilot/mission-codebase-gate.ts +141 -12
  342. package/src/autopilot/pr-manager.ts +89 -18
  343. package/src/boot/daemon-runtime.ts +35 -3
  344. package/src/boot/daemon-tools/pty-shell.ts +2 -1
  345. package/src/boot/daemon-tools/self-implement.ts +1 -0
  346. package/src/budget/run-usage-rollup.ts +12 -7
  347. package/src/budget/unified-usage.ts +20 -0
  348. package/src/budget/usage-outcomes.ts +8 -4
  349. package/src/capture/tui-self-report.ts +132 -1
  350. package/src/chat/goal-continue-verdict.ts +41 -0
  351. package/src/chat/index.ts +30 -4
  352. package/src/chat/internal-turn-origin.ts +1 -0
  353. package/src/chat/paste-fold.ts +86 -0
  354. package/src/chat/tool-render/block.ts +32 -0
  355. package/src/chat/tool-render/dispatch.ts +2 -20
  356. package/src/chat/tool-render/result-text.ts +98 -0
  357. package/src/chat/turn-typeahead.ts +70 -7
  358. package/src/cli/autopilot-cli.ts +24 -9
  359. package/src/cli/config-audit.ts +119 -0
  360. package/src/cli/decisions-cli.ts +7 -4
  361. package/src/cli/doctor-cli.ts +137 -6
  362. package/src/cli/guardian-cli.ts +10 -0
  363. package/src/cli/herdr-cli.ts +34 -0
  364. package/src/cli/light-entry-route.ts +6 -3
  365. package/src/cli/log-event-names.ts +2 -0
  366. package/src/cli/logs-cli.ts +357 -2
  367. package/src/cli/make-cli.ts +247 -11
  368. package/src/cli/memory-cli.ts +30 -1
  369. package/src/cli/msg-cli.ts +132 -14
  370. package/src/cli/pr-cli.ts +29 -16
  371. package/src/cli/pr-granularity.ts +5 -3
  372. package/src/cli/pr-land-base-read.ts +11 -2
  373. package/src/cli/pr-land-heavy-remote.ts +6 -3
  374. package/src/cli/pr-land-overlap-evidence.ts +23 -4
  375. package/src/cli/pr-land-recovery.ts +117 -1
  376. package/src/cli/pty-takeover-cli.ts +8 -7
  377. package/src/cli/release-checklist-read-cli.ts +109 -4
  378. package/src/cli/release-cli.ts +64 -15
  379. package/src/cli/release-single-flight.ts +1 -1
  380. package/src/cli/self-update.ts +23 -5
  381. package/src/cli/self-utterances-cli.ts +13 -16
  382. package/src/cli/tasks-card-show.ts +162 -0
  383. package/src/cli/tasks-cli.ts +868 -352
  384. package/src/cli/tasks-read-cli.ts +197 -0
  385. package/src/cli/usage-cli.ts +12 -10
  386. package/src/context-bus/claude-memory-import.ts +99 -0
  387. package/src/context-bus/long-term-memory.ts +125 -0
  388. package/src/core-turn/run-core-turn.ts +4 -2
  389. package/src/core-turn/run-goal-loop.ts +76 -16
  390. package/src/core-turn/types.ts +8 -1
  391. package/src/dashboard/chat/acp-chat.ts +9 -0
  392. package/src/dashboard/context/keys.ts +8 -31
  393. package/src/dashboard/index.ts +299 -62
  394. package/src/dashboard/input/agent-wake.ts +50 -1
  395. package/src/dashboard/input/chat-main-acp-dispatch.ts +21 -1
  396. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +146 -3
  397. package/src/dashboard/input/chat-main-slash-command.ts +4 -2
  398. package/src/dashboard/input/goal-continue.ts +210 -0
  399. package/src/dashboard/input/goal-interim.ts +2 -0
  400. package/src/dashboard/input/internal-turn.ts +2 -8
  401. package/src/dashboard/input/seat-autowake.ts +9 -7
  402. package/src/dashboard/input/turn-autoheal.ts +52 -0
  403. package/src/dashboard/replay-preview.ts +25 -0
  404. package/src/dashboard/seat-boot-preamble.ts +132 -5
  405. package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
  406. package/src/dashboard/slash-runtime/dashboard-handlers.ts +20 -10
  407. package/src/dashboard/slash-runtime/model-choices.ts +15 -0
  408. package/src/dashboard/stale-install-check.ts +3 -99
  409. package/src/dashboard/synchronized-frame-output.ts +74 -0
  410. package/src/debug/batch-queue.ts +119 -0
  411. package/src/debug/tui-log-tag.ts +67 -0
  412. package/src/display/agent-surface.ts +7 -0
  413. package/src/display/coordinator.ts +45 -12
  414. package/src/display/resize-listener.ts +41 -20
  415. package/src/display/synchronized-output-region.ts +60 -0
  416. package/src/domains/standalone-log-sink.ts +15 -2
  417. package/src/domains/surface-events.ts +80 -1
  418. package/src/esc-abort-gate.ts +69 -0
  419. package/src/exec-requests/planner.ts +37 -2
  420. package/src/execution-loop/launch-gate.ts +4 -3
  421. package/src/git-fs/cli-stderr.ts +45 -0
  422. package/src/git-fs/gh-cli.ts +6 -3
  423. package/src/git-fs/git-cli.ts +11 -5
  424. package/src/git-fs/worktree.ts +95 -1
  425. package/src/graph-runner/graph-cli.ts +44 -2
  426. package/src/graph-runner/graph-run-api.ts +3 -2
  427. package/src/graph-runner/runner.ts +37 -16
  428. package/src/graph-wizard/generate.ts +131 -4
  429. package/src/graph-wizard/steps.ts +15 -0
  430. package/src/grounding/proactive-ground.ts +86 -0
  431. package/src/harness/control-inbox.ts +49 -1
  432. package/src/harness/harness-cli-command.ts +230 -40
  433. package/src/harness/harness-incidents.ts +52 -1
  434. package/src/harness/pod-control-send.ts +33 -5
  435. package/src/harness/review-adapter.ts +26 -6
  436. package/src/harness/self-send-remote.ts +69 -0
  437. package/src/harness/self-send-routing-guard.ts +6 -0
  438. package/src/harness/self-send-target.ts +4 -3
  439. package/src/index.ts +443 -25
  440. package/src/input-core/context-key-runtime.ts +21 -0
  441. package/src/instance/test-write-guard-real-transport.fixture.ts +52 -0
  442. package/src/light-cli.ts +6 -1
  443. package/src/llm/route-decision.ts +13 -0
  444. package/src/llm-tool-name.ts +37 -0
  445. package/src/llm-tool-schema.ts +35 -0
  446. package/src/llm-wellformed.ts +70 -0
  447. package/src/llm.ts +158 -15
  448. package/src/loops/checker.ts +100 -0
  449. package/src/loops/consensus.ts +26 -2
  450. package/src/loops/loop-cli.ts +9 -4
  451. package/src/loops/msg-wake.ts +35 -39
  452. package/src/loops/orchestrator/anomaly-cluster.ts +243 -0
  453. package/src/loops/orchestrator/inbox.ts +59 -11
  454. package/src/loops/orchestrator/knowhow-pack.ts +364 -0
  455. package/src/loops/orchestrator/tick.ts +54 -5
  456. package/src/maturity/feature-maturity.ts +1 -1
  457. package/src/model-tier/llm-tier-map.ts +12 -17
  458. package/src/models/prompts.ts +17 -2
  459. package/src/msg/msg-post-office.ts +116 -0
  460. package/src/msg/msg-store.ts +17 -0
  461. package/src/mss/logging/log-store.ts +79 -22
  462. package/src/native-tool-catalog.ts +1 -1
  463. package/src/nexus/api/decisions-route.ts +38 -18
  464. package/src/nexus/api/graph-wizard-api.ts +46 -3
  465. package/src/nexus/api/grid.ts +24 -4
  466. package/src/nexus/api/http-server.ts +1 -1
  467. package/src/nexus/api/ops-api.ts +14 -6
  468. package/src/nexus/boot/register-mcp-clients.ts +263 -38
  469. package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
  470. package/src/nexus/state/state.ts +7 -1
  471. package/src/oauth/codex-account-store.ts +34 -1
  472. package/src/onboarding/first-run.ts +37 -6
  473. package/src/onboarding/web-first.ts +43 -11
  474. package/src/ops/loops-map.ts +46 -0
  475. package/src/ops/overview-cache.ts +22 -4
  476. package/src/ops/overview-collect.ts +12 -6
  477. package/src/ops/overview.ts +44 -8
  478. package/src/persona/loader.ts +11 -0
  479. package/src/persona/types.ts +8 -0
  480. package/src/policy/llm-policy.ts +3 -1
  481. package/src/prompt-enhance/enhance.ts +4 -4
  482. package/src/prompt-library/session-guidance.ts +14 -0
  483. package/src/provider-summary.ts +8 -0
  484. package/src/pty-shell/availability.ts +7 -0
  485. package/src/pty-shell/herdr-agent-report.ts +155 -37
  486. package/src/pty-shell/herdr-prompt.ts +266 -0
  487. package/src/pty-shell/herdr-prune-stale.ts +17 -0
  488. package/src/pty-shell/herdr-sequence-lease.ts +60 -0
  489. package/src/pty-shell/pty-control-ipc.ts +327 -15
  490. package/src/pty-shell/pty-special-keys.ts +42 -2
  491. package/src/pty-shell/registry.ts +25 -15
  492. package/src/pty-shell/stale-install-check.ts +99 -0
  493. package/src/pty-shell/tui-run-state.ts +249 -3
  494. package/src/release-loop/auto-start.ts +20 -2
  495. package/src/release-loop/checklist.ts +126 -9
  496. package/src/release-loop/feature-store.ts +9 -9
  497. package/src/release-loop/landed-but-yellow.ts +93 -12
  498. package/src/release-loop/rehearsal.ts +36 -20
  499. package/src/repl/index.ts +27 -1
  500. package/src/seat-loop/knowhow-lint.ts +1 -1
  501. package/src/seat-loop/seat-report.ts +1 -0
  502. package/src/self-dev/ask-launch-flow.ts +86 -10
  503. package/src/self-dev/decompose-proposal.ts +183 -20
  504. package/src/self-dev/decompose.ts +61 -0
  505. package/src/self-dev/dev-cli.ts +37 -3
  506. package/src/self-dev/dev-pipeline.ts +37 -9
  507. package/src/self-dev/draft-sweep.ts +241 -16
  508. package/src/self-dev/draft-triage-rules.ts +50 -5
  509. package/src/self-dev/glm-credential-guard.ts +77 -0
  510. package/src/self-dev/graph-journey-nodes.ts +1 -0
  511. package/src/self-dev/graph-journey-route.ts +12 -2
  512. package/src/self-dev/orchestrate-cli.ts +68 -3
  513. package/src/self-dev/orchestrate.ts +116 -17
  514. package/src/self-dev/review-provider-fallback.ts +45 -7
  515. package/src/self-dev/run-supervisor.ts +55 -2
  516. package/src/self-dev/run-types.ts +1 -1
  517. package/src/self-dev/shard-plan.ts +48 -0
  518. package/src/self-dev/shard-run.ts +50 -3
  519. package/src/self-health/autoheal.ts +153 -0
  520. package/src/self-health/signatures.ts +6 -0
  521. package/src/self-implement/device-first.ts +116 -0
  522. package/src/self-implement/doctor-visit.ts +322 -1
  523. package/src/self-implement/evidence-command-budget.ts +80 -0
  524. package/src/self-implement/gate-artifacts.ts +6 -2
  525. package/src/self-implement/gate-baseline.ts +64 -1
  526. package/src/self-implement/gate-cli.ts +93 -9
  527. package/src/self-implement/gate-remote.ts +28 -4
  528. package/src/self-implement/gate-scope.ts +13 -1
  529. package/src/self-implement/goal-author-cli.ts +1 -0
  530. package/src/self-implement/goal-author-decompose.ts +265 -4
  531. package/src/self-implement/goal-author.ts +366 -26
  532. package/src/self-implement/goal-elaborate.ts +176 -22
  533. package/src/self-implement/goal-refine.ts +3 -0
  534. package/src/self-implement/goal-supervisor-fill.ts +75 -26
  535. package/src/self-implement/graph-variant.ts +40 -6
  536. package/src/self-implement/headless-elanous-driver.ts +19 -3
  537. package/src/self-implement/importer-test-index.ts +215 -2
  538. package/src/self-implement/knowhow-pack.ts +5 -5
  539. package/src/self-implement/off-diff-evidence.ts +58 -6
  540. package/src/self-implement/orchestrator.ts +536 -42
  541. package/src/self-implement/pod-warm-pool-profile.ts +1 -0
  542. package/src/self-implement/pwa-import-graph.ts +1 -1
  543. package/src/self-implement/review-round-brief.ts +300 -0
  544. package/src/self-implement/rework-policy.ts +44 -0
  545. package/src/self-implement/run-ledger.ts +278 -6
  546. package/src/self-implement/run-stop.ts +1 -1
  547. package/src/self-implement/run-ttl.ts +38 -24
  548. package/src/self-implement/running-runs.ts +17 -3
  549. package/src/self-implement/scope-adjacency.ts +3 -1
  550. package/src/self-implement/seams.ts +72 -10
  551. package/src/self-implement/stop-autoheal.ts +1 -0
  552. package/src/self-implement/test-seams.ts +13 -1
  553. package/src/self-implement/train-reach-grouping.ts +8 -2
  554. package/src/self-implement/wiring-check.ts +358 -0
  555. package/src/session/chat.ts +7 -1
  556. package/src/session/id-prefix.ts +60 -0
  557. package/src/session/index.ts +4 -0
  558. package/src/session-runtime/index.ts +9 -1
  559. package/src/shell-env-bootstrap.ts +11 -4
  560. package/src/skills/runner.ts +4 -2
  561. package/src/skills/tools/agent.ts +290 -48
  562. package/src/skills/tools/pty.ts +5 -0
  563. package/src/skills/tools/schedule-wakeup.ts +23 -4
  564. package/src/skills/tools/shell.ts +61 -6
  565. package/src/skills/tools/terminal-modal-inject.ts +1 -2
  566. package/src/skills/tools/terminal-modal.ts +10 -8
  567. package/src/skills/url-router.ts +41 -1
  568. package/src/smart-wizard/run.ts +66 -0
  569. package/src/status/bar.ts +34 -6
  570. package/src/status/metrics.ts +12 -1
  571. package/src/status/status-provider-info.ts +37 -6
  572. package/src/steward/rejudge-tick.ts +22 -7
  573. package/src/steward/resync-tick.ts +31 -4
  574. package/src/steward/ta-repair-event-collect.ts +17 -6
  575. package/src/task-agent/actions.ts +202 -5
  576. package/src/task-agent/boundary-proof-mapping.ts +12 -0
  577. package/src/task-agent/boundary-proof-producer.ts +147 -0
  578. package/src/task-agent/completion-evidence.ts +2 -1
  579. package/src/task-agent/green-close-recipe.ts +239 -0
  580. package/src/task-agent/green-sweep.ts +64 -10
  581. package/src/task-agent/land-queue.ts +21 -8
  582. package/src/task-agent/live-moves.ts +70 -9
  583. package/src/task-agent/map-host-adapter.ts +134 -0
  584. package/src/task-agent/map-reduce.ts +158 -0
  585. package/src/task-agent/map-run-ledger.ts +226 -0
  586. package/src/task-agent/mission.ts +30 -0
  587. package/src/task-agent/parent-host.ts +21 -11
  588. package/src/task-agent/rejudge-on-head.ts +87 -5
  589. package/src/task-agent/repair-cycle.ts +179 -32
  590. package/src/task-agent/repair-next-move.ts +42 -4
  591. package/src/task-agent/repair-outcomes.ts +29 -0
  592. package/src/task-agent/repair-worker.ts +14 -4
  593. package/src/task-agent/review-prior-fix.ts +12 -2
  594. package/src/task-agent/shadow.ts +229 -8
  595. package/src/task-agent/task-card-prefix.ts +2 -0
  596. package/src/task-agent/task-hand.ts +630 -30
  597. package/src/task-agent/task-parent-role-llm.ts +45 -0
  598. package/src/task-agent/tier-split.ts +80 -10
  599. package/src/task-agent/work-order.ts +53 -2
  600. package/src/task-orchestrator/dispatcher.ts +46 -1
  601. package/src/task-orchestrator/generator-prompt.ts +6 -0
  602. package/src/task-orchestrator/surfaces/pod-account-broker.ts +9 -0
  603. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +16 -6
  604. package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
  605. package/src/task-orchestrator/surfaces/pod-command-job.ts +86 -5
  606. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
  607. package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
  608. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +8 -6
  609. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +97 -0
  610. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +11 -0
  611. package/src/task-orchestrator/surfaces/pod-pool.ts +126 -8
  612. package/src/task-orchestrator/surfaces/pod-provenance.ts +8 -2
  613. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +18 -3
  614. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +16 -0
  615. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +224 -0
  616. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +201 -0
  617. package/src/task-orchestrator/surfaces/pod-si-warm-provider.ts +444 -0
  618. package/src/task-orchestrator/surfaces/pod-si-warm-runner.ts +387 -0
  619. package/src/task-orchestrator/surfaces/pod-si-warm-transport.ts +157 -0
  620. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +4 -0
  621. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +491 -36
  622. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
  623. package/src/task-orchestrator/surfaces/self-implement-pod.ts +612 -54
  624. package/src/task-orchestrator/surfaces/self-implement.ts +46 -2
  625. package/src/testing/linux-env.ts +177 -0
  626. package/src/tool-runtime/index.ts +15 -2
  627. package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
  628. package/src/tty-foreground.ts +155 -0
  629. package/src/tui/chat/goal-interim.ts +177 -0
  630. package/src/tui/chat/log-view.ts +205 -18
  631. package/src/tui/chat/self-health-status.ts +232 -0
  632. package/src/tui/entry.ts +623 -80
  633. package/src/tui/input/at-picker.ts +55 -0
  634. package/src/tui/input/composer.ts +8 -1
  635. package/src/tui/slash/compact-command.ts +7 -0
  636. package/src/tui/slash/compact.ts +1 -7
  637. package/src/tui/slash/resume.ts +98 -0
  638. package/src/tui/slash/signals.ts +114 -0
  639. package/src/tui/slash/term-next.ts +71 -0
  640. package/src/tui-client/local-chat-turn.ts +49 -5
  641. package/src/tui-client/next-dashboard-runtime.ts +8 -0
  642. package/src/tui-client/next-loop-command.ts +70 -0
  643. package/src/tui-client/next-wakeup.ts +191 -0
  644. package/src/tui.ts +37 -0
  645. package/src/ui/modal-adapter.ts +2 -2
  646. package/src/user-config.ts +19 -1
  647. package/src/ux-sim/boot-daemon-tools-pty-shell-device.ts +136 -0
  648. package/src/ux-sim/classic-tui-seat-scenarios.ts +670 -0
  649. package/src/ux-sim/cli-config-audit-device.ts +121 -0
  650. package/src/ux-sim/dashboard-event-loop-stall-monitor-device.ts +238 -0
  651. package/src/ux-sim/event-monkey.ts +3 -2
  652. package/src/ux-sim/fake-bin.ts +45 -0
  653. package/src/ux-sim/fake-gh.ts +174 -0
  654. package/src/ux-sim/fake-herdr.ts +238 -0
  655. package/src/ux-sim/fake-kubectl.ts +142 -0
  656. package/src/ux-sim/fake-llm.ts +116 -6
  657. package/src/ux-sim/fault-glm-no-credential.ts +116 -0
  658. package/src/ux-sim/fault-nextmove-dispatch.ts +102 -1
  659. package/src/ux-sim/fault-scope-escape-lift.ts +33 -6
  660. package/src/ux-sim/fault-tui-400-autoheal.ts +297 -0
  661. package/src/ux-sim/goal-device.ts +619 -0
  662. package/src/ux-sim/in-process-cli.ts +22 -5
  663. package/src/ux-sim/mock-authoring-first-run-child.ts +35 -0
  664. package/src/ux-sim/mock-authoring-first-run.ts +97 -0
  665. package/src/ux-sim/mock-seat-pty-frame-child.ts +29 -0
  666. package/src/ux-sim/mock-seat-pty-frame.ts +297 -0
  667. package/src/ux-sim/mock-seat-pty-sequence-child.ts +21 -0
  668. package/src/ux-sim/mock-seat-pty-sequence.ts +206 -0
  669. package/src/ux-sim/next-tui-seat-scenarios.ts +749 -0
  670. package/src/ux-sim/onboarding-first-run-device.ts +269 -0
  671. package/src/ux-sim/pty-key-modifiers-device.ts +85 -0
  672. package/src/ux-sim/resume-picker-device.ts +173 -0
  673. package/src/ux-sim/session-id-seed.ts +60 -0
  674. package/src/ux-sim/skills-tools-shell-device.ts +156 -0
  675. package/src/ux-sim/subagent-tools-device.ts +81 -0
  676. package/src/ux-sim/task-agent-parent-host-device.ts +264 -0
  677. package/src/ux-sim/task-agent-rejudge-on-head-device.ts +114 -0
  678. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +250 -0
  679. package/src/ux-sim/tty-foreground-steal-child.ts +21 -0
  680. package/src/version/packed-revision.json +1 -1
  681. package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +0 -41
  682. package/apps/pwa/out/_next/static/chunks/1674.2a65fd5668e1cc5f.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +0 -24
  684. package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +0 -74
  685. package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/1993-c0007b7ad0c0ef41.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +0 -148
  694. package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/2625.5d870aa999f33db1.js +0 -34
  696. package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +0 -77
  697. package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +0 -62
  699. package/apps/pwa/out/_next/static/chunks/3103.0df8da390948bb84.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +0 -90
  701. package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/3589.5444a06bcf6e775c.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +0 -36
  705. package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/3677-4215f826f6aa68e5.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +0 -79
  708. package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/4346.8601952e73bf5803.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +0 -286
  712. package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +0 -24
  715. package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +0 -23
  724. package/apps/pwa/out/_next/static/chunks/5637.281e5dec4ea6ecf1.js +0 -94
  725. package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/56d372f2.681ab4ec4c998fae.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +0 -287
  729. package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +0 -8
  736. package/apps/pwa/out/_next/static/chunks/630.fe5a46428d63b013.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +0 -27
  739. package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +0 -93
  741. package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/6b89c8bd.24df687a820500b3.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +0 -149
  747. package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +0 -104
  748. package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/8219.baa715d1deee80e2.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +0 -226
  758. package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +0 -64
  760. package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/8637.47f5b35afcae5e6b.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/8714.ff0b7ce3ec3e3ae2.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +0 -115
  767. package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/967-2aa39b2d04b4c690.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/control/page-406b47745b53f269.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +0 -1
  794. package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +0 -1
  795. package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +0 -1
  796. package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +0 -1
  797. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +0 -1
  798. package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +0 -1
  799. package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +0 -1
  800. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +0 -1
  801. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +0 -1
  802. package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +0 -1
  803. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +0 -1
  804. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +0 -1
  805. package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +0 -1
  806. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +0 -1
  807. package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +0 -1
  808. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +0 -1
  809. package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +0 -1
  810. package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +0 -1
  811. package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +0 -1
  812. package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +0 -1
  813. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +0 -1
  814. package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +0 -1
  815. package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +0 -1
  816. package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +0 -1
  817. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +0 -1
  818. package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +0 -1
  819. package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +0 -1
  820. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +0 -1
  821. package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +0 -1
  822. package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +0 -1
  823. package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +0 -1
  824. package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +0 -1
  825. package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +0 -1
  826. package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +0 -1
  827. /package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → 8kITumG9GAZ1LwT9POrAR}/_ssgManifest.js +0 -0
package/src/tui/entry.ts CHANGED
@@ -1,14 +1,57 @@
1
1
  import { initTui, closeTui, injectKey, readKey, type Key } from '../tui.js';
2
2
  import { createSession, getActiveSessionId, loadSession, resolveSessionId, setActiveSessionId } from '../session/index.js';
3
- import { fitLogLine, logViewLines, safeLogText, safeStatusText, streamReplyLines, wheelScroll } from './chat/log-view.js';
3
+ import { fitLogLine, isToolFoldToggleKey, logViewLines, safeLogText, safeStatusText, streamReplyLines, toggleVisibleToolFold, toolFoldBlockStarts, wheelScroll } from './chat/log-view.js';
4
4
  import { BackgroundJobStatus } from './chat/background-job-status.js';
5
5
  import { MOUSE_RESIDUE_WINDOW_MS, MouseResidueGuard, applyComposerKey, composerViewport, emptyComposer, wheelDirection } from './input/composer.js';
6
6
  import { createInlineEditorState, type InlineEditorState } from '../input-core/inline-editor.js';
7
7
  import { isNewSessionCommand, nextTuiTitle, requestNewTuiSession } from './slash/new-session.js';
8
- import { COMPACT_BUSY_STATUS, COMPACT_NO_SESSION_STATUS, isCompactCommand } from './slash/compact.js';
8
+ import { COMPACT_BUSY_STATUS, COMPACT_NO_SESSION_STATUS, isCompactCommand } from './slash/compact-command.js';
9
+ import { RESUME_BUSY_STATUS, parseResumeCommand, requestResumeTuiSession, resumeCandidates, resumeListLines } from './slash/resume.js';
10
+ import { reportTuiTurn } from '../pty-shell/tui-run-state.js';
11
+ import { createPasteFold } from '../chat/paste-fold.js';
12
+ import { createTurnTypeaheadState, dequeueTurnTypeaheadHandoff, drainTurnTypeaheadOnce, restoreTurnTypeaheadSubmission } from '../chat/turn-typeahead.js';
13
+ import { debug } from '../debug/log.js';
14
+ import { setCliStderrSink } from '../git-fs/cli-stderr.js';
15
+ import { createInputLagProbe } from './input-lag-probe.js';
16
+ import type { NextTuiWakeup } from '../tui-client/next-wakeup.js';
17
+ import { countInterimDisplay, internalTurnOriginOfText, planInterimDisplay } from './chat/goal-interim.js';
18
+ import type { NextTuiSelfHealthSnapshot } from './chat/self-health-status.js';
19
+ import { createNextLoopCommand, type NextLoopCommand } from '../tui-client/next-loop-command.js';
20
+ import { handleMissionSlash, type MissionSlashContext } from './slash/mission.js';
21
+ import { handleSignalsSlash } from './slash/signals.js';
22
+
23
+ /** Status-line count of what waits for the running turn — empty when nothing waits. */
24
+ export function nextTuiQueueSuffix(count: number): string {
25
+ return count > 0 ? ` · 대기 ${count}` : '';
26
+ }
27
+
28
+ type NextTuiTermSession = {
29
+ id: string;
30
+ title: string;
31
+ kind: string;
32
+ status: 'running' | 'backgrounded' | 'completed' | 'killed' | 'exited';
33
+ cwd?: string;
34
+ exitCode?: number | null;
35
+ };
9
36
 
10
37
  export interface NextTuiOptions {
11
38
  readonly resumeSessionId?: string;
39
+ /** Read-only terminal session source; injectable so the Next slash stays testable without PTYs. */
40
+ readonly termSessions?: {
41
+ list(): readonly NextTuiTermSession[] | Promise<readonly NextTuiTermSession[]>;
42
+ };
43
+ }
44
+
45
+ interface AtPickerCandidate {
46
+ readonly label: string;
47
+ readonly absPath: string;
48
+ readonly isDir: false;
49
+ }
50
+
51
+ interface AtPickerQuery {
52
+ readonly prefix: string;
53
+ readonly start: number;
54
+ readonly end: number;
12
55
  }
13
56
 
14
57
  /** Local chat entry: history and input are TUI-owned; turn execution stays shared. */
@@ -17,13 +60,15 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
17
60
  if ((process.stdout.columns || 0) < 20 || (process.stdout.rows || 0) < 6) {
18
61
  throw new Error('elanous --tui next requires at least 20 columns and 6 rows');
19
62
  }
63
+ const dashboardRuntime = await (await import('../tui-client/next-dashboard-runtime.js')).loadNextTuiDashboardRuntime();
20
64
  const requested = options.resumeSessionId ?? getActiveSessionId();
21
65
  let id = requested ? resolveSessionId(requested) : null;
22
66
  if (requested && !id) throw new Error(`session not found: ${requested}`);
23
67
  let session = id ? loadSession(id) : null;
24
68
  let messages = session?.messages ?? [];
25
69
  // The seat ledger is touched only on next-TUI boot, and only when the
26
- // optional seat directory exists. No dashboard modules enter this path.
70
+ // optional seat directory exists. The one dashboard module below is the
71
+ // turn-start segments recorder wired over the shared turn delegation.
27
72
  const { readSeatMailSnapshot, seatMailLine } = await import('./seat-mail-boot.js');
28
73
  const mailLine = seatMailLine(readSeatMailSnapshot(process.cwd()));
29
74
  let editor = emptyComposer();
@@ -43,11 +88,155 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
43
88
  let historyIndex = 0;
44
89
  let draft = '';
45
90
  let activity: string[] = [];
91
+ /** Rows of the last `/resume` list — `/resume <n>` picks from what the user saw. */
92
+ let lastResumeRows: ReturnType<typeof resumeCandidates> | null = null;
93
+ let atPicker: { query: AtPickerQuery; candidates: AtPickerCandidate[]; selected: number } | null = null;
94
+ let atPickerApi: typeof import('./input/at-picker.js') | null = null;
95
+ let dismissedAtQuery = '';
96
+ const atAttachmentTokens = new Map<string, string>();
97
+ let atAttachmentOrdinal = 0;
98
+ // Tool-output fold state, keyed by message index; long tool output renders
99
+ // collapsed and Enter/Tab/F in the log toggles the foldable block on screen nearest the
100
+ // bottom of the last rendered scroll window.
101
+ const expandedToolBlocks = new Set<number>();
102
+ let logWindow = { start: 0, rows: 0, columns: 80 };
46
103
  let streamingReply = '';
47
104
  let streamRenderAt = 0;
48
105
  let streamRenderTimer: ReturnType<typeof setTimeout> | null = null;
49
106
  const backgroundJobs = new BackgroundJobStatus(id);
50
107
  const backgroundSubscription: { stop?: () => void } = {};
108
+ const selfHealthSubscription: { stop?: () => void } = {};
109
+ let selfHealthLine: string | null = null;
110
+ // TUI-NEXT-QUEUE-AND-WAKE — what is submitted while busy waits here (the classic FIFO state) and
111
+ // leaves one item per settle; Esc returns it all to the prompt (classic «interrupted» drain).
112
+ let queue = createTurnTypeaheadState();
113
+ let interrupted = false;
114
+ /** The prompt text a queued submission displaced; it comes back once that submission is sent. */
115
+ let restoreDraft: string | null = null;
116
+ /** ⏰/↻ lines from the wakeup scheduler and the internal-turn door (newest last, at most three). */
117
+ let notices: string[] = [];
118
+ // Distinct sentinels: the loop owns them, nothing else reads them as keys.
119
+ const queueWake: Key = { name: '', ctrl: false, shift: false, raw: '' };
120
+ const internalWake: Key = { name: '', ctrl: false, shift: false, raw: '' };
121
+ let wakeup: NextTuiWakeup | null = null;
122
+ let loopCommand: NextLoopCommand | null = null;
123
+ const pasteFold = createPasteFold();
124
+ // TURN-END-BEFORE-GOAL — 답이 약속만 하고 끝나면 깨움 문으로 한 턴 더(classic 과 같은 모듈 · 동적 로드).
125
+ let goalContinue: ReturnType<(typeof dashboardRuntime)['createGoalContinue']> | null = null;
126
+ /** 이번 턴이 실패·취소로 끝났나 — 그런 턴은 이어가지 않는다. */
127
+ let turnFailed = false;
128
+ /** 마지막으로 관측에 남긴 접힌 중간 답 수(next · 바뀔 때만 'folded' 한 줄). */
129
+ let interimFoldedShown = 0;
130
+ const pushNotice = (line: string): void => {
131
+ notices = [...notices, safeStatusText(line)].slice(-3);
132
+ };
133
+ const slashHandlers = new Map<string, (args: string[], context: MissionSlashContext) => Promise<void>>();
134
+ slashHandlers.set('mission', handleMissionSlash);
135
+ slashHandlers.set('signals', handleSignalsSlash);
136
+ const dispatchSlash = async (name: string, args: string[], context: MissionSlashContext): Promise<boolean> => {
137
+ const handler = slashHandlers.get(name);
138
+ if (!handler) return false;
139
+ await handler(args, context);
140
+ return true;
141
+ };
142
+ const missionWatchTimers = new Set<ReturnType<typeof setInterval>>();
143
+ let missionWatchesClosed = false;
144
+ const readyWatchIds = new Set<string>();
145
+ const runWatchIds = new Set<string>();
146
+ const startMissionReadyWatch = (missionId: string): void => {
147
+ if (readyWatchIds.has(missionId)) return;
148
+ readyWatchIds.add(missionId);
149
+ pushNotice(`미션 준비 관찰 시작: ${missionId}`);
150
+ void import('../autopilot/mission-tui-watch.js').then((watch) => {
151
+ if (missionWatchesClosed) { readyWatchIds.delete(missionId); return; }
152
+ const baseline = watch.takeMissionReadySnapshot(missionId);
153
+ let state = watch.createMissionWatchState(baseline, Date.now());
154
+ const timer = setInterval(() => {
155
+ const current = watch.takeMissionReadySnapshot(missionId);
156
+ const result = watch.advanceMissionWatch(state, current, Date.now());
157
+ state = result.state;
158
+ for (const event of result.events) {
159
+ if (event.kind === 'phases') activity.push(`미션 분해 진행 — ${event.count} 페이즈 (${missionId})`);
160
+ else if (event.kind === 'ready') {
161
+ activity.push(`미션 준비 완료 — ${event.snapshot.goal}`);
162
+ activity.push(...watch.missionDescriptionDigest(event.snapshot.description));
163
+ activity.push(...watch.renderMissionPhaseBoardLines(event.snapshot.phases, { goal: event.snapshot.goal }));
164
+ activity.push(`검토 후 /mission approve|hold ${missionId}`);
165
+ } else if (event.kind === 'resolved-elsewhere') activity.push(`미션 ${missionId} 은 다른 서피스에서 해소됨 (status=${event.status})`);
166
+ else if (event.kind === 'gone') activity.push(`미션 ${missionId} 삭제됨 · 준비 관찰 종료`);
167
+ else if (event.kind === 'timeout') activity.push(`미션 준비 관찰 타임아웃 · /mission trace ${missionId}`);
168
+ }
169
+ if (result.events.length > 0) { activity = activity.slice(-80); render(); }
170
+ if (result.done) { clearInterval(timer); missionWatchTimers.delete(timer); readyWatchIds.delete(missionId); }
171
+ }, watch.MISSION_WATCH_INTERVAL_MS);
172
+ missionWatchTimers.add(timer);
173
+ }).catch((error: unknown) => {
174
+ readyWatchIds.delete(missionId);
175
+ pushNotice(`미션 준비 관찰 실패: ${safeStatusText(error instanceof Error ? error.message : String(error))}`);
176
+ render();
177
+ });
178
+ render();
179
+ };
180
+ const startMissionRunWatch = (missionId: string): void => {
181
+ if (runWatchIds.has(missionId)) return;
182
+ runWatchIds.add(missionId);
183
+ pushNotice(`미션 실행 관찰 시작: ${missionId}`);
184
+ void import('../autopilot/mission-tui-watch.js').then((watch) => {
185
+ if (missionWatchesClosed) { runWatchIds.delete(missionId); return; }
186
+ const baseline = watch.takeMissionRunSnapshot(missionId);
187
+ let state = watch.createMissionRunWatchState(baseline, Date.now());
188
+ const timer = setInterval(() => {
189
+ const current = watch.takeMissionRunSnapshot(missionId);
190
+ const result = watch.advanceMissionRunWatch(state, current, Date.now());
191
+ state = result.state;
192
+ for (const event of result.events) {
193
+ if (event.kind === 'phase') activity.push(watch.renderMissionRunPhaseLine(event));
194
+ else if (event.kind === 'progress') activity.push(`미션 진행 ${event.phase.index + 1}/${event.total}: ${event.note}`);
195
+ else if (event.kind === 'finished') activity.push('미션 종결', ...watch.renderMissionRunReportLines(event.snapshot));
196
+ else if (event.kind === 'gone') activity.push(`미션 ${missionId} 삭제됨 · 실행 관찰 종료`);
197
+ else if (event.kind === 'timeout') activity.push(`미션 실행 관찰 타임아웃 · /mission trace ${missionId}`);
198
+ }
199
+ if (result.events.length > 0) { activity = activity.slice(-80); render(); }
200
+ if (result.done) { clearInterval(timer); missionWatchTimers.delete(timer); runWatchIds.delete(missionId); }
201
+ }, watch.MISSION_RUN_WATCH_INTERVAL_MS);
202
+ missionWatchTimers.add(timer);
203
+ if (baseline) { activity.push(watch.renderMissionRunFooter(baseline)); render(); }
204
+ }).catch((error: unknown) => {
205
+ runWatchIds.delete(missionId);
206
+ pushNotice(`미션 실행 관찰 실패: ${safeStatusText(error instanceof Error ? error.message : String(error))}`);
207
+ render();
208
+ });
209
+ render();
210
+ };
211
+ const missionContext: MissionSlashContext = {
212
+ chatLines: activity,
213
+ setChatScrollOffset: (value) => { scroll = Math.max(0, Math.min(value, maxScroll)); },
214
+ muted: (text) => text,
215
+ accent: (text) => text,
216
+ text: (text) => text,
217
+ error: (text) => text,
218
+ success: (text) => text,
219
+ warning: (text) => text,
220
+ info: (text) => text,
221
+ subtext: (text) => text,
222
+ missionTui: {
223
+ startReadyWatch: startMissionReadyWatch,
224
+ startRunWatch: startMissionRunWatch,
225
+ },
226
+ };
227
+
228
+ // TURN-START-BLOCK-REST — 턴 경계 recorder: showNextTui → runLocalChatTurn 위임 턴의
229
+ // 시작 경계(begin)와 첫 응답 경계(end · stream-open)를 세션 키로 열고 닫아
230
+ // debug.log('tui.turn-start', 'segments', …) 줄 한 개로 남긴다. 박동은 전용 input-lag
231
+ // 프로브(20ms·unref)의 것만 읽는다 — 키 지연 계측(noteKey/notePaint) 등록은 이 몫 범위 밖.
232
+ // recorder·프로브 타이머는 모두 unref 라 teardown 이 기다리는 대상에 들지 않고, dispose 는
233
+ // 부르지 않는다 — 닫힌 턴의 줄은 박동 두 번 뒤 지연 emit 되므로 dispose 가 그 줄을 끊는다.
234
+ const turnStartBeats = createInputLagProbe({ log: () => {}, isBusy: () => busy });
235
+ dashboardRuntime.setTurnStartSegments(dashboardRuntime.createTurnStartSegments({
236
+ beats: turnStartBeats.beats,
237
+ log: (category, event, data) => { debug.log(category, event, data); },
238
+ isBusy: () => busy,
239
+ }));
51
240
 
52
241
  const render = (): void => {
53
242
  const columns = process.stdout.columns || 0;
@@ -58,30 +247,284 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
58
247
  }
59
248
  const backgroundLine = backgroundJobs.line();
60
249
  const footerRows = backgroundLine ? 2 : 1;
61
- const history = [...logViewLines(messages, columns), ...activity.map((line) => fitLogLine(line, columns))];
250
+ const history = [
251
+ ...logViewLines(messages, columns, expandedToolBlocks),
252
+ ...notices.map((line) => fitLogLine(line, columns)),
253
+ ...activity.map((line) => fitLogLine(line, columns)),
254
+ ];
62
255
  const bodyRows = rows - 3 - footerRows;
63
256
  maxScroll = Math.max(0, history.length - bodyRows);
64
257
  scroll = Math.min(scroll, maxScroll);
65
258
  const start = Math.max(0, history.length - bodyRows - scroll);
66
259
  const body = history.slice(start, start + bodyRows);
260
+ logWindow = { start, rows: bodyRows, columns };
67
261
  const title = fitLogLine(`elanous next · ${safeLogText(nextTuiTitle(session?.meta)).split('\n')[0]}`, columns);
68
- const turnStatus = !busy && focus === 'log' ? '로그 탐색 · ↑↓ 스크롤 · Esc 입력' : status;
262
+ const turnStatus = (!busy && focus === 'log'
263
+ ? `로그 탐색 · ↑↓ 스크롤${toolFoldBlockStarts(messages, columns).length > 0 ? ' · Enter 접기/펼치기' : ''} · Esc 입력`
264
+ : status) + nextTuiQueueSuffix(queue.queuedSubmissions.length);
69
265
  const footer = backgroundLine
70
266
  ? [fitLogLine(backgroundLine, columns), fitLogLine(turnStatus, columns)]
71
267
  : [fitLogLine(turnStatus, columns)];
72
268
  const prompt = composerViewport(editor, columns);
73
- const lines = [title, mailLine ? fitLogLine(mailLine, columns) : '─'.repeat(Math.min(columns, 80)), ...body, ...footer, prompt.line];
269
+ const header = [title, mailLine ? fitLogLine(mailLine, columns) : '─'.repeat(Math.min(columns, 80))];
270
+ if (selfHealthLine) header.push(fitLogLine(selfHealthLine, columns));
271
+ if (atPicker) {
272
+ const limit = Math.max(1, Math.min(6, rows - 8));
273
+ const start = Math.max(0, Math.min(atPicker.selected - limit + 1, atPicker.candidates.length - limit));
274
+ const visible = atPicker.candidates.slice(start, start + limit);
275
+ header.push(fitLogLine(visible.length ? '@ 파일 첨부 · ↑↓ 선택 · Enter 추가 · Esc 닫기' : '@ 파일 후보 없음', columns));
276
+ for (const [offset, candidate] of visible.entries()) {
277
+ header.push(fitLogLine((start + offset === atPicker.selected ? '▸' : ' ') + ' ' + candidate.label, columns));
278
+ }
279
+ }
280
+ const lines = [...header, ...body, ...footer, prompt.line];
74
281
  const promptRow = lines.length;
75
282
  process.stdout.write(`\x1b[H\x1b[2J${lines.join('\n')}\x1b[${promptRow};${prompt.cursorCol}H\x1b[?25h`);
76
283
  };
77
284
 
285
+ let restoreCliStderrSink: (() => void) | null = null;
286
+
287
+ const refreshAtPicker = async (): Promise<void> => {
288
+ const query = editor.text.slice(0, editor.cursor).match(/(?:^|\s)@([\p{L}\p{N}_./~\\-]*)$/u);
289
+ if (!query) {
290
+ atPicker = null;
291
+ dismissedAtQuery = '';
292
+ if (status.startsWith('@ 파일')) status = 'Enter 전송 · Esc 취소 · Ctrl+Q 종료';
293
+ return;
294
+ }
295
+ const prefix = query[1] ?? '';
296
+ const start = editor.cursor - prefix.length - 1;
297
+ const key = start + ':' + prefix;
298
+ if (dismissedAtQuery === key) { atPicker = null; return; }
299
+ if (!atPickerApi) {
300
+ atPickerApi = await import('./input/at-picker.js');
301
+ debug.log('tui.next', 'at-picker-module-loaded', { onDemand: true });
302
+ }
303
+ const candidates = await atPickerApi.listAtFiles(prefix, process.cwd());
304
+ atPicker = { query: { prefix, start, end: editor.cursor }, candidates, selected: 0 };
305
+ status = candidates.length ? '@ 파일 첨부 후보 · ↑↓ 선택 · Enter 추가' : '@ 파일 후보 없음 · 계속 입력';
306
+ };
307
+
308
+ /** Every busy path ends here: the door learns the turn is over, then the queue moves or returns to the prompt. */
309
+ const settle = (): void => {
310
+ wakeup?.gate.noteTurnSettled();
311
+ const count = queue.queuedSubmissions.length;
312
+ if (interrupted) {
313
+ interrupted = false;
314
+ if (count === 0) return;
315
+ const drained = drainTurnTypeaheadOnce(queue, editor.text || null, { interrupted: true });
316
+ queue = drained.state;
317
+ editor = createInlineEditorState(drained.nextInitial ?? '');
318
+ status = `응답 취소됨 · 대기 ${count}건을 입력칸으로 · Enter 전송`;
319
+ debug.log('tui.next', 'queue-restored', { count });
320
+ return;
321
+ }
322
+ if (count > 0) injectKey(queueWake);
323
+ };
324
+
325
+ /** Sends the head of the queue through the ordinary idle submit path (slash commands included). */
326
+ const dispatchQueued = (): void => {
327
+ const { handoff, state } = dequeueTurnTypeaheadHandoff(queue);
328
+ if (handoff.kind !== 'submit') return;
329
+ queue = state;
330
+ // 대기열에서 나가는 것도 사람이 쳐 둔 턴이다 — 골 이어가기의 연속·지문을 비운다(r3 must-fix).
331
+ goalContinue?.noteHumanTurn();
332
+ restoreDraft = editor.text;
333
+ editor = createInlineEditorState(handoff.text);
334
+ focus = 'input';
335
+ historyIndex = 0;
336
+ debug.log('tui.next', 'queue-dispatched', { length: handoff.text.length, remaining: queue.queuedSubmissions.length });
337
+ replay.push({ name: 'enter', ctrl: false, shift: false, raw: '\r' });
338
+ };
339
+
340
+ /** One chat turn on the shared REPL child — a person's submit, or an internal turn the door opened (banner). */
341
+ const startChatTurn = (turnText: string, banner?: string): void => {
342
+ activity = [];
343
+ streamingReply = '';
344
+ streamRenderAt = 0;
345
+ const attachments = [...atAttachmentTokens].filter(([token]) => turnText.includes(token)).map(([, path]) => path);
346
+ if (!id) {
347
+ id = createSession({ source: 'tui' }).id;
348
+ setActiveSessionId(id);
349
+ session = loadSession(id);
350
+ backgroundJobs.setSessionId(id);
351
+ }
352
+ const turnSessionId = id;
353
+ busy = true;
354
+ // herdr pane 이면 턴 시작·끝을 working → idle 로 신고한다(`eln herdr prompt --wait` 가 이것을 기다린다).
355
+ // 녹음기는 startTuiSelfReport 가 이미 열었다 — 없으면 아무것도 안 한다.
356
+ reportTuiTurn('busy');
357
+ // An internal turn says where it came from (classic «↻ 자동 재개(<origin>): <이유>») instead of looking typed.
358
+ // TUI-GOAL-INTERIM-QUIET — the log draws a recognized internal input in place («↻ 자동 재개(<origin>)»), so the
359
+ // notice list would only repeat it under the last reply; the status line still names it while the turn runs.
360
+ if (banner && !internalTurnOriginOfText(turnText)) pushNotice(banner);
361
+ status = banner ? `${safeStatusText(banner)} · 응답 중 · Esc 취소` : '응답 중 · Esc 취소';
362
+ dashboardRuntime.beginTurnStartSegments(turnSessionId);
363
+ // «압축 N→M 메시지» stays on the status line through the reply when this turn compacted first.
364
+ let compactNote = '';
365
+ turnFailed = false;
366
+ // 이번 턴이 만든 답만 골 이어가기 판정에 쓴다 — 시작 때 세션 길이를 잡아 둔다.
367
+ const messagesAtTurnStart = messages.length;
368
+ // 이번 턴에 자동 압축이 있었나 — 있으면 길이 기준이 깨지므로 «마지막 사람 글 뒤» 로 판정한다.
369
+ let turnCompacted = false;
370
+ const abort = new AbortController();
371
+ turnAbort = abort;
372
+ turnDone = import('../tui-client/local-chat-turn.js')
373
+ .then(({ runLocalChatTurn, onLocalChatBackgroundStatus, onLocalChatSelfHealthStatus }) => {
374
+ backgroundSubscription.stop ??= onLocalChatBackgroundStatus(turnSessionId, (frame) => {
375
+ if (frame === null) {
376
+ backgroundJobs.clear();
377
+ render();
378
+ } else if (backgroundJobs.accept(frame)) render();
379
+ });
380
+ selfHealthSubscription.stop ??= onLocalChatSelfHealthStatus(turnSessionId, (snapshot: NextTuiSelfHealthSnapshot | null) => {
381
+ selfHealthLine = snapshot?.line ?? null;
382
+ render();
383
+ });
384
+ let firstResponseSeen = false;
385
+ return runLocalChatTurn(turnSessionId, turnText, abort.signal, undefined, undefined, (delta) => {
386
+ // 첫 응답 경계: 첫 스트림 델타에서 턴 시작 트레이스를 닫는다(endedBy=stream-open).
387
+ if (!firstResponseSeen) {
388
+ firstResponseSeen = true;
389
+ dashboardRuntime.endTurnStartSegments(turnSessionId, 'stream-open');
390
+ }
391
+ // The first model token is visible before the final JSONL frame. Keep only
392
+ // a bounded tail until session history becomes the canonical display.
393
+ streamingReply = (streamingReply + delta).slice(-32_768);
394
+ activity = streamReplyLines(streamingReply, process.stdout.columns || 80);
395
+ const now = performance.now();
396
+ if (streamRenderAt === 0 || now - streamRenderAt >= 33) {
397
+ streamRenderAt = now;
398
+ render();
399
+ } else if (streamRenderTimer === null) {
400
+ streamRenderTimer = setTimeout(() => {
401
+ streamRenderTimer = null;
402
+ streamRenderAt = performance.now();
403
+ render();
404
+ }, 33 - (now - streamRenderAt));
405
+ }
406
+ }, {
407
+ onCompact: (outcome) => {
408
+ compactNote = outcome.status ? `${outcome.status} · ` : '';
409
+ turnCompacted = true;
410
+ status = `${compactNote}응답 중 · Esc 취소`;
411
+ session = loadSession(turnSessionId);
412
+ messages = session?.messages ?? [];
413
+ expandedToolBlocks.clear();
414
+ render();
415
+ },
416
+ }, attachments);
417
+ })
418
+ .then(() => { status = `${compactNote}응답 완료 · Enter 전송 · Ctrl+Q 종료`; })
419
+ .catch((error: unknown) => {
420
+ const message = error instanceof Error ? error.message : String(error);
421
+ turnFailed = true;
422
+ status = compactNote + (message === '응답을 취소했습니다'
423
+ ? '응답 취소됨 · Enter 전송'
424
+ : `응답 실패: ${safeStatusText(message)}`);
425
+ })
426
+ .finally(() => {
427
+ if (streamRenderTimer !== null) clearTimeout(streamRenderTimer);
428
+ streamRenderTimer = null;
429
+ session = loadSession(turnSessionId);
430
+ messages = session?.messages ?? [];
431
+ activity = [];
432
+ streamingReply = '';
433
+ busy = false;
434
+ reportTuiTurn('idle');
435
+ turnAbort = null;
436
+ scroll = 0;
437
+ settle();
438
+ // TUI-GOAL-INTERIM-QUIET 관측 — 그리기 계획(log-view 와 같은 함수)의 접힘 수가 바뀐 턴 끝에 한 줄.
439
+ try {
440
+ const shown = countInterimDisplay(planInterimDisplay(messages));
441
+ if (shown.folded !== interimFoldedShown) {
442
+ interimFoldedShown = shown.folded;
443
+ debug.log('tui.goal-interim', 'folded', { surface: 'next', ...shown });
444
+ }
445
+ } catch { /* fail-soft: 관측은 턴 정리를 막지 않는다 */ }
446
+ // 사람이 쌓아 둔 다음 입력이 먼저다 — 대기열이 비었을 때만 골 이어가기를 잰다.
447
+ if (goalContinue && queue.queuedSubmissions.length === 0 && editor.text.length === 0) {
448
+ try {
449
+ goalContinue.noteTurnEnded({ lines: dashboardRuntime.replyLinesOfThisTurn(messages, turnCompacted ? 'after-last-user' : messagesAtTurnStart), failed: turnFailed || interrupted });
450
+ goalContinue.check();
451
+ } catch { /* fail-soft: 골 이어가기는 턴 정리를 막지 않는다 */ }
452
+ } else if (goalContinue && (queue.queuedSubmissions.length > 0 || editor.text.length > 0)) {
453
+ debug.log('tui.proactive', 'yield-user-input', { queued: queue.queuedSubmissions.length, bufferedChars: editor.text.length });
454
+ }
455
+ render();
456
+ });
457
+ };
458
+
78
459
  initTui();
460
+ restoreCliStderrSink = setCliStderrSink(({ source, exitCode, raw }) => {
461
+ // Keep the exact bytes in the normal debug log while rendering only failures through the
462
+ // TUI-owned notice area. Writing the CLI stream to process.stderr would overwrite the prompt.
463
+ debug.log('tui.cli-stderr', 'captured', {
464
+ source,
465
+ exitCode,
466
+ text: raw.toString('utf8'),
467
+ rawBase64: raw.toString('base64'),
468
+ byteLength: raw.length,
469
+ });
470
+ if (exitCode !== 0) {
471
+ const text = raw.toString('utf8').trim() || `${source} exited with rc=${exitCode}`;
472
+ pushNotice(`[${source} stderr · rc=${exitCode}] ${text}`);
473
+ render();
474
+ }
475
+ });
79
476
  process.stdout.on('resize', render);
80
477
  try {
478
+ {
479
+ const { createNextTuiWakeup, setNextTuiWakeupTool } = await import('../tui-client/next-wakeup.js');
480
+ wakeup = createNextTuiWakeup({
481
+ isTurnRunning: () => busy,
482
+ getBufferText: () => editor.text,
483
+ getQueuedCount: () => queue.queuedSubmissions.length,
484
+ requestYield: () => injectKey(internalWake),
485
+ notify: (line) => { pushNotice(line); render(); },
486
+ });
487
+ setNextTuiWakeupTool(wakeup.tool);
488
+ const gate = wakeup.gate;
489
+ loopCommand = createNextLoopCommand(gate, (event, data) => debug.log('dashboard.loop', event, data));
490
+ goalContinue = dashboardRuntime.createGoalContinue({
491
+ startTurnIfIdle: (text, opts) => gate.startTurnIfIdle(text, opts),
492
+ notify: (line) => { pushNotice(line); render(); },
493
+ });
494
+ }
81
495
  render();
82
496
  while (true) {
83
497
  const replayed = replay.shift();
84
- const key = replayed ?? await readKey();
498
+ const rawKey = replayed ?? await readKey();
499
+ // TUI-PASTE-ECHO — 긴 붙여넣기는 입력창에 자리표시 한 덩어리로(제출 때 원문으로 되돌린다).
500
+ let key: Key = rawKey.name === 'paste' && typeof rawKey.paste === 'string' ? { ...rawKey, paste: pasteFold.fold(rawKey.paste) } : rawKey;
501
+ // Ctrl+V — 클립보드 글을 같은 붙여넣기 규칙으로(예전엔 next 가 Ctrl 글자를 버려 아무 일도 없었다).
502
+ if (key.ctrl && (key.name === 'v' || key.name === 'V' || key.name === 'ㅍ') && focus === 'input') {
503
+ const { readClipboardText } = await import('../clipboard/index.js');
504
+ const clip = await readClipboardText().catch(() => null);
505
+ debug.log('tui.paste', 'clipboard-read', { surface: 'next', chars: clip?.length ?? 0 });
506
+ if (!clip) {
507
+ status = '클립보드에 붙여넣을 글이 없습니다 · Enter 전송';
508
+ render();
509
+ continue;
510
+ }
511
+ key = { name: 'paste', ctrl: false, shift: false, raw: '', paste: pasteFold.fold(clip) };
512
+ }
513
+ if (key === queueWake) {
514
+ if (!busy) dispatchQueued();
515
+ render();
516
+ continue;
517
+ }
518
+ if (key === internalWake) {
519
+ // The door opened while idle; a person who got here first (a turn, a typed prompt) withdraws it.
520
+ if (busy || editor.text.length > 0) wakeup?.gate.port.declined?.(busy ? 'turn-running' : 'buffer');
521
+ else {
522
+ const request = wakeup?.gate.takePending();
523
+ if (request) startChatTurn(request.input, wakeup!.banner(request));
524
+ }
525
+ render();
526
+ continue;
527
+ }
85
528
  if (!replayed) {
86
529
  const step = mouseResidue.accept(key, Date.now());
87
530
  if (step.kind === 'hold') {
@@ -130,6 +573,7 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
130
573
  }
131
574
  if (busy && (key.name === 'escape' || (key.ctrl && key.name === 'c'))) {
132
575
  turnAbort?.abort();
576
+ interrupted = true;
133
577
  status = '응답 취소 중';
134
578
  render();
135
579
  continue;
@@ -145,6 +589,12 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
145
589
  render();
146
590
  continue;
147
591
  }
592
+ // TUI-NEXT-FOLD — Enter/Tab (or F) in the log expands/folds the long tool block visible in the
593
+ // current scroll window (nearest the bottom). With none on screen the key keeps its ordinary meaning.
594
+ if (focus === 'log' && isToolFoldToggleKey(key.name) && toggleVisibleToolFold(expandedToolBlocks, messages, logWindow.columns, logWindow)) {
595
+ render();
596
+ continue;
597
+ }
148
598
  if (focus === 'log' && (key.name === 'up' || key.name === 'down')) {
149
599
  scroll = Math.max(0, scroll + (key.name === 'up' ? 1 : -1));
150
600
  render();
@@ -155,6 +605,33 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
155
605
  render();
156
606
  continue;
157
607
  }
608
+ const activeAtPicker = atPicker as { query: AtPickerQuery; candidates: AtPickerCandidate[]; selected: number } | null;
609
+ if (!busy && focus === 'input' && activeAtPicker) {
610
+ if (key.name === 'escape') {
611
+ dismissedAtQuery = activeAtPicker.query.start + ':' + activeAtPicker.query.prefix;
612
+ atPicker = null;
613
+ status = '파일 선택 닫힘 · Enter 전송';
614
+ render();
615
+ continue;
616
+ }
617
+ if ((key.name === 'up' || key.name === 'down') && activeAtPicker.candidates.length > 0) {
618
+ activeAtPicker.selected = (activeAtPicker.selected + (key.name === 'up' ? -1 : 1) + activeAtPicker.candidates.length) % activeAtPicker.candidates.length;
619
+ render();
620
+ continue;
621
+ }
622
+ if ((key.name === 'enter' || key.name === 'return') && !key.shift && activeAtPicker.candidates[activeAtPicker.selected]) {
623
+ const candidate = activeAtPicker.candidates[activeAtPicker.selected]!;
624
+ const picked = atPickerApi!.acceptAtFile(editor.text, activeAtPicker.query, candidate, ++atAttachmentOrdinal);
625
+ editor = { text: picked.text, cursor: picked.cursor };
626
+ atAttachmentTokens.set(picked.token, candidate.absPath);
627
+ atPicker = null;
628
+ dismissedAtQuery = '';
629
+ status = '파일 첨부 추가됨 · Enter 전송';
630
+ debug.log('tui.next', 'at-picker-selected', { path: candidate.absPath });
631
+ render();
632
+ continue;
633
+ }
634
+ }
158
635
  if (busy) {
159
636
  const pending = applyComposerKey(editor, key);
160
637
  editor = pending.state;
@@ -176,8 +653,17 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
176
653
  render();
177
654
  continue;
178
655
  }
179
- editor = createInlineEditorState(pending.submitted);
180
- status = '응답 중 · 완료 뒤 Enter 전송';
656
+ if (parseResumeCommand(pending.submitted)) {
657
+ // Same reason as /new: the running turn still writes to the current session.
658
+ status = RESUME_BUSY_STATUS;
659
+ render();
660
+ continue;
661
+ }
662
+ // Queued, not put back: it leaves on its own after this turn settles (herdr `pane run` and msg-wake
663
+ // pastes arrive here too, so an outside prompt during a turn is kept, not lost).
664
+ queue = restoreTurnTypeaheadSubmission(queue, pending.submitted);
665
+ status = '응답 중 · 완료 뒤 순서대로 전송 · Esc 취소';
666
+ debug.log('tui.next', 'queue-enqueued', { length: pending.submitted.length, count: queue.queuedSubmissions.length });
181
667
  }
182
668
  render();
183
669
  continue;
@@ -197,25 +683,44 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
197
683
  focus = 'input';
198
684
  const result = applyComposerKey(editor, key);
199
685
  editor = result.state;
686
+ if (result.action === 'edit') await refreshAtPicker();
687
+ else if (result.action === 'submit' || result.action === 'cancel' || result.action === 'quit') atPicker = null;
688
+ if (restoreDraft !== null) {
689
+ // A queued submission just left through this Enter; what the person was typing comes back.
690
+ if (result.action === 'submit') editor = createInlineEditorState(restoreDraft);
691
+ restoreDraft = null;
692
+ }
200
693
  if (result.action === 'edit' || result.action === 'cancel' || result.action === 'submit') historyIndex = 0;
201
694
  if (result.action === 'quit') break;
202
- if (result.action === 'cancel') status = '입력 취소됨 · Enter 전송 · Ctrl+Q 종료';
695
+ if (result.action === 'cancel') {
696
+ status = '입력 취소됨 · Enter 전송 · Ctrl+Q 종료';
697
+ pasteFold.retainOnly([editor.text, ...queue.queuedSubmissions.map(String)]);
698
+ }
203
699
  if (result.action === 'submit' && result.submitted) {
204
- const submitted = result.submitted.trim();
700
+ const submittedFull = pasteFold.expand(result.submitted);
701
+ // 지운 붙여넣기의 원문은 놓는다 — 입력칸·대기열에 남은 토큰만 쥔다(r3 must-fix).
702
+ pasteFold.retainOnly([editor.text, ...queue.queuedSubmissions.map(String)]);
703
+ const submitted = submittedFull.trim();
205
704
  if (submitted === '/quit') break;
206
705
  if (isNewSessionCommand(submitted)) {
207
706
  const next = requestNewTuiSession({ busy, from: id });
208
707
  if (next.kind === 'started') {
708
+ loopCommand?.run('stop');
209
709
  const previous = id;
210
710
  backgroundSubscription.stop?.();
211
711
  backgroundSubscription.stop = undefined;
712
+ selfHealthSubscription.stop?.();
713
+ selfHealthSubscription.stop = undefined;
714
+ selfHealthLine = null;
212
715
  if (previous) {
213
716
  const { closeLocalChatSession } = await import('../tui-client/local-chat-turn.js');
214
717
  await closeLocalChatSession(previous);
215
718
  }
216
719
  id = next.id;
720
+ lastResumeRows = null;
217
721
  session = loadSession(id);
218
722
  messages = [];
723
+ expandedToolBlocks.clear();
219
724
  backgroundJobs.setSessionId(id);
220
725
  backgroundJobs.clear();
221
726
  activity = [];
@@ -248,13 +753,62 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
248
753
  .finally(() => {
249
754
  session = loadSession(compactSessionId);
250
755
  messages = session?.messages ?? [];
756
+ expandedToolBlocks.clear();
251
757
  busy = false;
252
758
  scroll = 0;
759
+ settle();
253
760
  render();
254
761
  });
255
762
  render();
256
763
  continue;
257
764
  }
765
+ const resumeCommand = parseResumeCommand(submitted);
766
+ if (resumeCommand?.kind === 'list') {
767
+ lastResumeRows = resumeCandidates(id);
768
+ activity = resumeListLines(lastResumeRows, id).map(safeStatusText);
769
+ status = '/resume <번호|id 앞자리> 로 이어 가기 · Enter 전송';
770
+ debug.log('tui.next', 'session-resume-list', { from: id, rows: activity.length });
771
+ render();
772
+ continue;
773
+ }
774
+ if (resumeCommand?.kind === 'load') {
775
+ const next = requestResumeTuiSession({ busy, from: id, prefix: resumeCommand.prefix, rows: lastResumeRows ?? resumeCandidates(id) });
776
+ if (next.kind === 'started') {
777
+ loopCommand?.run('stop');
778
+ const previous = id;
779
+ backgroundSubscription.stop?.();
780
+ backgroundSubscription.stop = undefined;
781
+ selfHealthSubscription.stop?.();
782
+ selfHealthSubscription.stop = undefined;
783
+ selfHealthLine = null;
784
+ if (previous) {
785
+ const { closeLocalChatSession } = await import('../tui-client/local-chat-turn.js');
786
+ await closeLocalChatSession(previous);
787
+ }
788
+ id = next.id;
789
+ lastResumeRows = null;
790
+ session = loadSession(id);
791
+ messages = session?.messages ?? [];
792
+ expandedToolBlocks.clear();
793
+ backgroundJobs.setSessionId(id);
794
+ backgroundJobs.clear();
795
+ activity = [];
796
+ streamingReply = '';
797
+ scroll = 0;
798
+ focus = 'input';
799
+ draft = '';
800
+ historyIndex = 0;
801
+ }
802
+ status = safeStatusText(next.status);
803
+ render();
804
+ continue;
805
+ }
806
+ if (submitted === '/loop' || submitted.startsWith('/loop ')) {
807
+ activity = loopCommand?.run(submitted.slice('/loop'.length)) ?? ['사용법: /loop <간격> <프롬프트> · /loop stop'];
808
+ status = 'Enter 전송';
809
+ render();
810
+ continue;
811
+ }
258
812
  if (submitted === '/provider' || submitted.startsWith('/provider ')) {
259
813
  const command = submitted.slice('/provider'.length).trim();
260
814
  activity = ['provider 목록 조회 중'];
@@ -278,6 +832,7 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
278
832
  .finally(() => {
279
833
  busy = false;
280
834
  turnAbort = null;
835
+ settle();
281
836
  render();
282
837
  });
283
838
  render();
@@ -313,89 +868,77 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
313
868
  .finally(() => {
314
869
  busy = false;
315
870
  turnAbort = null;
871
+ settle();
316
872
  render();
317
873
  });
318
874
  render();
319
875
  continue;
320
876
  }
321
- activity = [];
322
- streamingReply = '';
323
- streamRenderAt = 0;
324
- if (!id) {
325
- id = createSession({ source: 'tui' }).id;
326
- setActiveSessionId(id);
327
- session = loadSession(id);
328
- backgroundJobs.setSessionId(id);
329
- }
330
- const turnSessionId = id;
331
- const turnText = result.submitted;
332
- busy = true;
333
- status = '응답 중 · Esc 취소';
334
- // «압축 N→M 메시지» stays on the status line through the reply when this turn compacted first.
335
- let compactNote = '';
336
- const abort = new AbortController();
337
- turnAbort = abort;
338
- turnDone = import('../tui-client/local-chat-turn.js')
339
- .then(({ runLocalChatTurn, onLocalChatBackgroundStatus }) => {
340
- backgroundSubscription.stop ??= onLocalChatBackgroundStatus(turnSessionId, (frame) => {
341
- if (frame === null) {
342
- backgroundJobs.clear();
343
- render();
344
- } else if (backgroundJobs.accept(frame)) render();
345
- });
346
- return runLocalChatTurn(turnSessionId, turnText, abort.signal, undefined, undefined, (delta) => {
347
- // The first model token is visible before the final JSONL frame. Keep only
348
- // a bounded tail until session history becomes the canonical display.
349
- streamingReply = (streamingReply + delta).slice(-32_768);
350
- activity = streamReplyLines(streamingReply, process.stdout.columns || 80);
351
- const now = performance.now();
352
- if (streamRenderAt === 0 || now - streamRenderAt >= 33) {
353
- streamRenderAt = now;
354
- render();
355
- } else if (streamRenderTimer === null) {
356
- streamRenderTimer = setTimeout(() => {
357
- streamRenderTimer = null;
358
- streamRenderAt = performance.now();
359
- render();
360
- }, 33 - (now - streamRenderAt));
361
- }
362
- }, {
363
- onCompact: (outcome) => {
364
- compactNote = outcome.status ? `${outcome.status} · ` : '';
365
- status = `${compactNote}응답 중 · Esc 취소`;
366
- session = loadSession(turnSessionId);
367
- messages = session?.messages ?? [];
368
- render();
369
- },
370
- });
371
- })
372
- .then(() => { status = `${compactNote}응답 완료 · Enter 전송 · Ctrl+Q 종료`; })
373
- .catch((error: unknown) => {
374
- const message = error instanceof Error ? error.message : String(error);
375
- status = compactNote + (message === '응답을 취소했습니다'
376
- ? '응답 취소됨 · Enter 전송'
377
- : `응답 실패: ${safeStatusText(message)}`);
378
- })
379
- .finally(() => {
380
- if (streamRenderTimer !== null) clearTimeout(streamRenderTimer);
381
- streamRenderTimer = null;
382
- session = loadSession(turnSessionId);
383
- messages = session?.messages ?? [];
384
- activity = [];
385
- streamingReply = '';
386
- busy = false;
387
- turnAbort = null;
388
- scroll = 0;
389
- render();
877
+ if (submitted === '/term' || submitted.startsWith('/term ') || submitted === '/terminal' || submitted.startsWith('/terminal ')) {
878
+ const { dispatchNextTermSlash } = await import('./slash/term-next.js');
879
+ const args = submitted.slice('/'.length).trim().split(/\s+/).slice(1);
880
+ const sessions = options.termSessions ?? {
881
+ list: async () => {
882
+ const { listPty } = await import('../pty-shell/registry.js');
883
+ return listPty().map((handle) => ({
884
+ id: handle.id,
885
+ title: handle.nickname ?? handle.cmd,
886
+ kind: handle.kind,
887
+ status: handle.isAlive() ? 'running' as const : 'exited' as const,
888
+ ...(handle.workdir === undefined ? {} : { cwd: handle.workdir }),
889
+ exitCode: handle.exitCode,
890
+ }));
891
+ },
892
+ };
893
+ await dispatchNextTermSlash(args, {
894
+ chatLines: activity,
895
+ setChatScrollOffset: (value) => { scroll = Math.max(0, Math.min(value, maxScroll)); },
896
+ sessions,
390
897
  });
898
+ status = 'Enter 전송';
899
+ render();
900
+ continue;
901
+ }
902
+ if (
903
+ submitted === '/mission' || submitted.startsWith('/mission ')
904
+ || submitted === '/signals' || submitted.startsWith('/signals ')
905
+ ) {
906
+ missionContext.chatLines = activity;
907
+ const [command = '', ...args] = submitted.slice('/'.length).trim().split(/\s+/);
908
+ const dispatched = await dispatchSlash(command, args, missionContext);
909
+ if (!dispatched) activity.push('알 수 없는 슬래시 명령');
910
+ status = 'Enter 전송';
911
+ render();
912
+ continue;
913
+ }
914
+ // A person's turn: an internal turn opened but not yet run gives way, and the door's «last turn» moves.
915
+ wakeup?.gate.port.declined?.('human-turn');
916
+ wakeup?.gate.noteHumanTurn();
917
+ goalContinue?.noteHumanTurn();
918
+ startChatTurn(submittedFull);
391
919
  }
392
920
  render();
393
921
  }
394
922
  } finally {
923
+ restoreCliStderrSink?.();
924
+ restoreCliStderrSink = null;
395
925
  if (residueTimer !== null) clearTimeout(residueTimer);
926
+ loopCommand?.dispose();
927
+ missionWatchesClosed = true;
928
+ for (const timer of missionWatchTimers) clearInterval(timer);
929
+ missionWatchTimers.clear();
930
+ readyWatchIds.clear();
931
+ runWatchIds.clear();
932
+ wakeup?.dispose();
933
+ if (wakeup) {
934
+ const { setNextTuiWakeupTool } = await import('../tui-client/next-wakeup.js');
935
+ setNextTuiWakeupTool(null);
936
+ }
396
937
  turnAbort?.abort();
397
938
  await turnDone;
398
939
  backgroundSubscription.stop?.();
940
+ selfHealthSubscription.stop?.();
941
+ selfHealthLine = null;
399
942
  if (id) {
400
943
  const { closeLocalChatSession } = await import('../tui-client/local-chat-turn.js');
401
944
  await closeLocalChatSession(id);