elanous 0.2.38 → 0.2.40

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 (615) 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/{RrjXTwz-urRAbChP1bX02 → HjeK7zONHfR7op1hKXp4k}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{7954.4f7a8832663ee979.js → 1060.014f1f01a17aec26.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{8911.bf5e712acb25fb6c.js → 1281.d81877e35b9068f4.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/{2104.70e086d5174a4736.js → 1350.59f40e39e02d91b1.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/1415.79821ec7ae99acdb.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1452.162bb2d9d699e82a.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/147.f92f63bbc5e85fa5.js +286 -0
  10. package/apps/pwa/out/_next/static/chunks/1537-6bb97b5214928ea9.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1661.fb425a1d8a065b72.js +149 -0
  12. package/apps/pwa/out/_next/static/chunks/1671-1c22b40b50b208f2.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1758.0204d3f48783c49d.js +90 -0
  14. package/apps/pwa/out/_next/static/chunks/1806.027bf78b6a94d340.js +104 -0
  15. package/apps/pwa/out/_next/static/chunks/2047.8f23e210995d4548.js +2 -0
  16. package/apps/pwa/out/_next/static/chunks/2061-7f2bbc53ae96c88b.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/{1632.7d87f998e714bede.js → 2066.a77257c8c350770a.js} +1 -1
  18. package/apps/pwa/out/_next/static/chunks/2096-a938496bc996dcbd.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/{8019.21ca554a821dad01.js → 2177.df8547f9d7215c4e.js} +3 -3
  20. package/apps/pwa/out/_next/static/chunks/2200-9a453b8f99687d49.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/{3528.e4b8ab70d339f965.js → 2226.2cf61ec781827219.js} +2 -2
  22. package/apps/pwa/out/_next/static/chunks/2281-b8cede695c6c650e.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{6493.27ad77de7aac7966.js → 2499.02fbfd18126c10c0.js} +1 -1
  24. package/apps/pwa/out/_next/static/chunks/{7628.6b16863ac3972333.js → 2522.f2766b76d22c8bdf.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/{3086.fb14b60ce98b53d3.js → 2566.beaffc3a5e1fcd2e.js} +1 -1
  26. package/apps/pwa/out/_next/static/chunks/{9299.24e2a7d9b6d1f91b.js → 261.0d471e8aded799f3.js} +3 -3
  27. package/apps/pwa/out/_next/static/chunks/2615.3c9738153de3ef3f.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2727.e703d99ac414916d.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2752.7904b8df0254d0ae.js +27 -0
  30. package/apps/pwa/out/_next/static/chunks/2762-5051a862dfa40e99.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/2767-31784bfedf8e245d.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/2774-719820e3f5b2a3eb.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/2812-f016aa0dda149287.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/2829-734fe8bf2eee7347.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/311-32dcac79970985e8.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3175-f93f7495cd28253c.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3184.8da993f5502d2140.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3231-d7c981db0ff8bdcc.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3250.151309c5176d6b4b.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/{7524.ce973525d30b3d52.js → 3330.7443183b7e6fdbdf.js} +1 -1
  41. package/apps/pwa/out/_next/static/chunks/3517.a5aa1797a9dbf2ee.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3567-45f676877ed9e8a5.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/{3124-561f7f037943cde2.js → 3746-f80a78f220bf37b5.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/3819.8a1de79b2e8c7298.js +24 -0
  45. package/apps/pwa/out/_next/static/chunks/39.9b37b0be4c128a83.js +77 -0
  46. package/apps/pwa/out/_next/static/chunks/{bb6987f9.3647e1a23b0e3217.js → 3b355b3d.6f73c98bf6f9c749.js} +1 -1
  47. package/apps/pwa/out/_next/static/chunks/4023.a19045970a9ce16a.js +36 -0
  48. package/apps/pwa/out/_next/static/chunks/{8994d93e.33ba491f95345fc2.js → 409c787b.e48c5bec8ec10456.js} +1 -1
  49. package/apps/pwa/out/_next/static/chunks/{5041-5aada92ca215ffdd.js → 413-24c8284bda08241d.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/4135.e45d6ebc29e20647.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4283.65502f5d0e6ff6c0.js +287 -0
  52. package/apps/pwa/out/_next/static/chunks/4305-4e28fa92a7b34a5b.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4335-50efa61fd7613142.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4351.0f37a6db2b34d50b.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{5638.107314dc479e2f37.js → 470.51a72a2348306455.js} +2 -2
  56. package/apps/pwa/out/_next/static/chunks/4720.ecbd1693fa151068.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/{8487.291666583bebe640.js → 4769.9fd582071301f382.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/{8509.3a54d4e61893d7cb.js → 483.725e4a61be922788.js} +1 -1
  59. package/apps/pwa/out/_next/static/chunks/{9fe1b809.738da85c8b17e3fb.js → 4864a2ca.1c1c280a7772c5e5.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/4969-4b209d7307410c00.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5068-c7f53862f83c0917.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5315.bc96711c24dfefe2.js +74 -0
  63. package/apps/pwa/out/_next/static/chunks/{8879.ac06755bcf3e44a1.js → 5383.bdfa5d886e39a826.js} +1 -1
  64. package/apps/pwa/out/_next/static/chunks/{6142.913b44e260a3f925.js → 5436.fdf6fa8ae3e9588d.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/5542.efbf14f16baed4dd.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5622.94893f5aea7185d0.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5644.8f401a25601d05fc.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5658.35f70eb9871a54bf.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/5721.7bdc0e904c76ab51.js +8 -0
  70. package/apps/pwa/out/_next/static/chunks/5790-eef0ca20884a6bdf.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/5802.ef0d8598ca68fe84.js +62 -0
  72. package/apps/pwa/out/_next/static/chunks/5890.fb974729788dcb71.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/5924.5ef25cddd36d5dbf.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/5979-e59c099ebf8d1f35.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/6020.714cfeada2315e2e.js +94 -0
  76. package/apps/pwa/out/_next/static/chunks/6027-dfe0349d8c50f698.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/{7161-8f22db3ec5ed005e.js → 6051-0ae955eedb10adb9.js} +3 -3
  78. package/apps/pwa/out/_next/static/chunks/6178.bc4730c86cf74536.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/{3291.f6c1005387d514bd.js → 6257.c0037b8949239f5e.js} +2 -2
  80. package/apps/pwa/out/_next/static/chunks/6273.d808b0dcb3c2b155.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6292.6ef1df64fa6a4c8a.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/647-af8dd920ba46533c.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6541-170dc5c59e135c0c.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/6624.981ef7caeb680560.js +32 -0
  85. package/apps/pwa/out/_next/static/chunks/6742-a1ad4a94ba7bc37a.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/{5203.51e5d8b5f1dcfe53.js → 6749.0744ce6eb08d40e9.js} +3 -3
  87. package/apps/pwa/out/_next/static/chunks/6836-493dc55c39187949.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/6856-53ac421c06039a18.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/{1938.0e6c60ee91c4d7f5.js → 6908.06008c67f6380ea9.js} +2 -2
  90. package/apps/pwa/out/_next/static/chunks/6915.096931864206f522.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/6925.5e181fb7dcf90193.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{de8b930d.d94c0f42acf807fc.js → 6cc1d1d6.9a98dd4622f1afc6.js} +1 -1
  93. package/apps/pwa/out/_next/static/chunks/7203-800e11037adc41eb.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7219-15bdd9a80661af8e.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7279.6170f591105936bb.js +93 -0
  96. package/apps/pwa/out/_next/static/chunks/7349-373165c7fbdcc3df.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7514-a533ba0ca1cae4f4.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7515.1ad6efe157fa4448.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/7521.d919cc1fab80c1d9.js +24 -0
  100. package/apps/pwa/out/_next/static/chunks/7538.90e97bbdf9178cff.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/7611.85f045bf232053ac.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/7825-39203196a12579b2.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/7869.5e1a9a12fd70d6c7.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8086.1ab9103c41be884f.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8099.1cccf31c1baa7e1c.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8179-e61fffbdb70f1152.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8265.bdeb991b34db6a06.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/{1026-44010f405704050c.js → 8272-025653884f9645d2.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/{5307.d7328020227880c2.js → 8357.1aaa713b052a78b1.js} +4 -4
  110. package/apps/pwa/out/_next/static/chunks/8638-e42615f2166165b5.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/{4199-f7c6eb40cd0322f8.js → 8639-92c11d069792429e.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/8691.54e22831d5e8ccf8.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/8d173e38.18a2f7b4e1848bdb.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9069.657590a84afb8fac.js +41 -0
  115. package/apps/pwa/out/_next/static/chunks/9125-ae588d88a0293b93.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9175.2de5209a5ce6f68a.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9184.45afbf44fec87574.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{eaad0cba.771200940c529df7.js → 9189505a.980427ac048c8c60.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/9311.f9f641a46a508611.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9371-a6fee8378ebfa3ee.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9421-3aa9ff4fa7f63d8a.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9992.07ce73c10bd5e6a1.js +79 -0
  123. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76394dc618d322c8.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/approvals/page-1b948637c37b3abd.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-c63400f1bcf3e47c.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/board/page-95d0957267819586.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-866aac5ff226a7f3.js → page-ba957ff875a026a0.js} +1 -1
  128. package/apps/pwa/out/_next/static/chunks/app/bots/page-bb6fd0714879cb87.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/ceo/page-8f9038520d2acbef.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/chat/page-d4b48397e05fce2c.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/consult/page-72d5744245dc0c27.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/control/page-37625dc8300fa43a.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/decisions/page-fbef9d160272dbc1.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/design-check/page-58424168df84928e.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/editor/page-72c12ba430ac57c0.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/exec/page-d53f3e9ed806d7e0.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/field/page-4d2fbd45feee0829.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76394dc618d322c8.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/inside/page-8783dc0ed7590a2c.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/intake/page-3706cb390606e930.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/layout-9b0a86598e0111fd.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live/page-4edb8df90f4537ce.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live-run/page-83d27757e2b8060a.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/loops/page-47398b9ba1cc5e1b.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/market/page-fb86f55cfe2e681d.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e22345fc8fd47b1b.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/morning/page-fca2e59a81744d9e.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/not-found-6e96bda63100b31e.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/observatory/page-4d17ad8e0db8cea4.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-121f92766c33beaa.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-43f14212c545f92d.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ccec2023e7a974ec.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/outputs/page-b04f33f548b89a94.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/page-c8792823c0917021.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/reflection/page-8c0e32782ceef4cb.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-94bd3922eb230ce8.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bca565887bafa03c.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ac1dffafe649fc6c.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/page-52374edb5e23e455.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ad4ebca120d43ca7.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76394dc618d322c8.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/page-718b89ce4b4ae4e4.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/share/page-204eca33eeeaddec.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/showroom/page-e58ba9bcdb9ac0f9.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/tasks/page-98f6dd50bafd7734.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/term/page-139d722de1dcd6c1.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/today/page-5a4bdd72bff27057.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/trace/page-6f6ab17d44f984ce.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/vault/page-aabb7bd15fb72da9.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-e4322319164a4436.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/page-e9efc0c8f32e2371.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workspace/page-ccde99f07aaf71f7.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-80464aced9614390.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/{b7478fef.5917716286213fcc.js → b84cad00.594027ebe0531fe2.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/c696986b.5dc8bb1143af16d1.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/{b7459770.6539b11860eb8a9c.js → ca3702f8.2913182e73889fa2.js} +7 -7
  177. package/apps/pwa/out/_next/static/chunks/{3f0de3de-2340c532c00395db.js → d5d3cefc-373c4eb722ed848b.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/{89d6c04f-6b8ab341748e468a.js → d8de0de2-dd0f4ac8e5ab1832.js} +1 -1
  179. package/apps/pwa/out/_next/static/chunks/{framework-4b12a946f352cee2.js → framework-002b472a66935d31.js} +1 -1
  180. package/apps/pwa/out/_next/static/chunks/main-49b88d47292c0476.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/main-app-fff2549cb10a133f.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_app-32abbbba3f3b76b7.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/pages/_error-9d9cfef60c60dd7a.js +1 -0
  184. package/apps/pwa/out/_next/static/chunks/webpack-cc7f483fa294034a.js +1 -0
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +22 -22
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +22 -22
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +22 -22
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +21 -21
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +21 -21
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +22 -22
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +21 -21
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +22 -22
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +22 -22
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +21 -21
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +22 -22
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +22 -22
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +22 -22
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +22 -22
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +21 -21
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +21 -21
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +22 -22
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +22 -22
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +22 -22
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +21 -21
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +21 -21
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +22 -22
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +22 -22
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +21 -21
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +21 -21
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +21 -21
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +22 -22
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +22 -22
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +21 -21
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +22 -22
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +22 -22
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +22 -22
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +22 -22
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +22 -22
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +21 -21
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +22 -22
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +22 -22
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +22 -22
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +22 -22
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +22 -22
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +22 -22
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +22 -22
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +22 -22
  278. package/graphs/demo/persona-marketer/fixtures/marketer-scenario.yaml +10 -0
  279. package/graphs/demo/persona-marketer/persona-marketer.yaml +25 -0
  280. package/graphs/demo/persona-marketer/recipes.yaml +19 -0
  281. package/graphs/video/explainer-line.yaml +4 -1
  282. package/package.json +1 -1
  283. package/scripts/dead-code/report.ts +169 -0
  284. package/scripts/lib/morning-report-options.ts +3 -4
  285. package/scripts/lib/tui-regress-evidence.ts +56 -0
  286. package/scripts/morning-report.ts +5 -1
  287. package/scripts/public-export.ts +15 -7
  288. package/scripts/release-loop/export-check-node.ts +21 -3
  289. package/scripts/release-loop/gate-node.ts +379 -48
  290. package/scripts/release-loop/gate-shard-dispatch.ts +128 -0
  291. package/scripts/release-loop/gate-shard-receipts.ts +89 -0
  292. package/scripts/release-loop/gate-wall.ts +5 -5
  293. package/scripts/release-loop/preflight.ts +6 -2
  294. package/scripts/release-loop/resume-release.ts +20 -5
  295. package/scripts/release-loop/resume.ts +48 -0
  296. package/scripts/release-loop/version-node.ts +7 -2
  297. package/scripts/release-story/draft.ts +1 -1
  298. package/scripts/research-bench/README.md +53 -0
  299. package/scripts/research-bench/questions.json +66 -0
  300. package/scripts/research-bench/rubric.md +33 -0
  301. package/scripts/research-bench/run.ts +523 -0
  302. package/scripts/tui-regress.ts +85 -10
  303. package/src/acp/core-turn-bridge.ts +8 -0
  304. package/src/agent/autonomous-tools.ts +10 -3
  305. package/src/agent/monad-agent-turn.ts +4 -1
  306. package/src/agent/registry.ts +26 -2
  307. package/src/agent/shared-app-tools.ts +1 -1
  308. package/src/agent/surface-ux/build.ts +12 -3
  309. package/src/agent/surface-ux/types.ts +1 -1
  310. package/src/agent/task-notification.ts +75 -6
  311. package/src/agent/types.ts +3 -0
  312. package/src/agent-mission/driver.ts +29 -3
  313. package/src/agent-mission/mission-cli.ts +2 -1
  314. package/src/agent-substrate/review-context-pack.ts +365 -0
  315. package/src/agent-substrate/self-review-cli.ts +226 -17
  316. package/src/ask-user-question/index.ts +6 -0
  317. package/src/ask-user-question/inline-resolver.ts +49 -0
  318. package/src/auto-research/question-ladder-contract.ts +22 -3
  319. package/src/auto-research/research-turn.ts +350 -17
  320. package/src/autopilot/agent-loop.ts +1 -1
  321. package/src/autopilot/pty-control-loop.ts +8 -1
  322. package/src/boot/daemon-tools/index.ts +4 -3
  323. package/src/boot/daemon-tools/self-implement.ts +270 -2
  324. package/src/boot/daemon-tools/types.ts +2 -0
  325. package/src/budget/llm-cost.ts +44 -5
  326. package/src/budget/unified-usage.ts +17 -1
  327. package/src/capture/tui-self-report.ts +14 -0
  328. package/src/chat/index.ts +33 -7
  329. package/src/cli/agent-cli.ts +43 -8
  330. package/src/cli/intake-cli.ts +22 -1
  331. package/src/cli/lesson-cli.ts +19 -3
  332. package/src/cli/log-event-names.ts +1 -0
  333. package/src/cli/pod-cli.ts +17 -2
  334. package/src/cli/pty-takeover-cli.ts +67 -7
  335. package/src/cli/release-cli.ts +52 -6
  336. package/src/cli/repo-cli.ts +2 -1
  337. package/src/cli/tasks-cli.ts +36 -9
  338. package/src/control-plane/ledger.ts +21 -4
  339. package/src/core-turn/run-core-turn.ts +44 -3
  340. package/src/core-turn/run-goal-loop.ts +152 -8
  341. package/src/core-turn/types.ts +9 -0
  342. package/src/dashboard/chat/acp-chat.ts +2 -2
  343. package/src/dashboard/classic-sigquit.ts +16 -0
  344. package/src/dashboard/index.ts +321 -27
  345. package/src/dashboard/input/chat-main-interaction-opts.ts +3 -0
  346. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +7 -2
  347. package/src/dashboard/input/chat-main-slash-command.ts +7 -0
  348. package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
  349. package/src/dashboard/input/dashboard-priority-key-route.ts +21 -5
  350. package/src/dashboard/input/external-input-host.ts +2 -0
  351. package/src/dashboard/sidetab-runtime.ts +228 -0
  352. package/src/dashboard/slash-runtime/ask-clarification.ts +7 -1
  353. package/src/dashboard/slash-runtime/dashboard-handlers.ts +20 -8
  354. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -2
  355. package/src/dashboard/term-slash-runtime.ts +16 -18
  356. package/src/dashboard/turn-preamble.ts +2 -0
  357. package/src/domains/knowledge.ts +1 -1
  358. package/src/esc-abort-gate.ts +33 -1
  359. package/src/execution-loop/launch-gate.ts +206 -1
  360. package/src/graph-runner/graph-cli.ts +6 -4
  361. package/src/graph-runner/runner.ts +31 -9
  362. package/src/graph-wizard/generate.ts +16 -7
  363. package/src/graph-wizard/mission-compose.ts +201 -0
  364. package/src/grok/agent-search.ts +8 -2
  365. package/src/grok/credential.ts +5 -0
  366. package/src/grounding/ref-index.ts +11 -0
  367. package/src/grounding/ref-vector.ts +61 -0
  368. package/src/grounding/sources-cli.ts +2 -2
  369. package/src/grounding/sources.ts +15 -1
  370. package/src/harness/harness-cli-command.ts +38 -9
  371. package/src/harness/harness-pod-dispatch.ts +7 -1
  372. package/src/index.ts +18 -4
  373. package/src/input/external-input-queue.ts +10 -0
  374. package/src/intake-plane/collect-telegram-saved.ts +36 -1
  375. package/src/intake-plane/intake-to-tasks.ts +246 -3
  376. package/src/lessons/friction-ledger.ts +154 -0
  377. package/src/live-supply/collector.ts +149 -0
  378. package/src/live-supply/probes.ts +52 -0
  379. package/src/live-supply/snapshot.ts +40 -0
  380. package/src/llm.ts +431 -76
  381. package/src/loops/orchestrator/tick.ts +8 -0
  382. package/src/nexus/api/harness-api.ts +2 -1
  383. package/src/pty/snapshot.py +132 -0
  384. package/src/pty-shell/pty-control-ipc.ts +29 -2
  385. package/src/pty-shell/pty-manifest.ts +59 -3
  386. package/src/pty-shell/registry.ts +2 -0
  387. package/src/pty-shell/tui-run-state.ts +80 -3
  388. package/src/release-loop/gate-host-reservation.ts +13 -4
  389. package/src/release-loop/gate-shard-ledger.ts +68 -0
  390. package/src/release-loop/merged-pr-checklist.ts +25 -2
  391. package/src/release-loop/rehearsal-shard-plan.ts +6 -1
  392. package/src/release-loop/rehearsal.ts +27 -0
  393. package/src/research/edge-decision.ts +124 -15
  394. package/src/research/gap-followup.ts +249 -0
  395. package/src/research/lenses/counter-evidence.ts +100 -0
  396. package/src/research/lenses/working-backwards.ts +89 -0
  397. package/src/research/plugin-discovery.ts +242 -0
  398. package/src/research-bridge/invoke.ts +4 -2
  399. package/src/research-bridge/types.ts +2 -0
  400. package/src/self-dev/ask-launch-flow.ts +34 -106
  401. package/src/self-dev/dev-cli.ts +2 -0
  402. package/src/self-dev/dev-pipeline.ts +8 -4
  403. package/src/self-dev/graph-journey-route.ts +10 -2
  404. package/src/self-dev/launch-preflight-text.ts +2 -2
  405. package/src/self-dev/launch-preflight.ts +38 -7
  406. package/src/self-dev/orchestrate-cli.ts +1 -0
  407. package/src/self-dev/run-supervisor.ts +19 -0
  408. package/src/self-implement/device-first.ts +8 -2
  409. package/src/self-implement/doctor-visit.ts +76 -58
  410. package/src/self-implement/gate-artifacts.ts +3 -0
  411. package/src/self-implement/gate-baseline.ts +75 -4
  412. package/src/self-implement/gate-cli.ts +317 -9
  413. package/src/self-implement/gate-receipt-registry.ts +180 -0
  414. package/src/self-implement/gate-remote.ts +145 -22
  415. package/src/self-implement/goal-author-clarification.ts +178 -24
  416. package/src/self-implement/goal-author-decompose.ts +24 -15
  417. package/src/self-implement/goal-author.ts +9 -5
  418. package/src/self-implement/host-regate.ts +120 -45
  419. package/src/self-implement/impl-findings-feedback.ts +188 -0
  420. package/src/self-implement/knowhow-pack.ts +189 -10
  421. package/src/self-implement/off-diff-evidence.ts +124 -0
  422. package/src/self-implement/orchestrator.ts +85 -7
  423. package/src/self-implement/run-ledger.ts +46 -8
  424. package/src/self-implement/run-stop.ts +12 -0
  425. package/src/self-implement/seams.ts +6 -3
  426. package/src/self-implement/self-implement-cli.ts +4 -2
  427. package/src/session/chat.ts +89 -15
  428. package/src/session-runtime/provider-circuit.ts +140 -0
  429. package/src/shell-runner/file-engine.ts +1 -0
  430. package/src/shell-runner/types.ts +4 -0
  431. package/src/sidetab-core/model.ts +176 -0
  432. package/src/skills/tools/schedule-wakeup.ts +23 -1
  433. package/src/skills/tools/shell.ts +51 -5
  434. package/src/steward/directive-audit.ts +354 -0
  435. package/src/surface/child-process.ts +31 -0
  436. package/src/surface/tui-stderr-owner.ts +48 -0
  437. package/src/task-agent/cover.ts +30 -12
  438. package/src/task-agent/judge.ts +56 -0
  439. package/src/task-agent/postland-card.ts +35 -2
  440. package/src/task-agent/rejudge-on-head.ts +46 -2
  441. package/src/task-agent/repair-cycle.ts +1 -1
  442. package/src/task-agent/task-hand.ts +129 -24
  443. package/src/task-agent/tier-split.ts +105 -21
  444. package/src/task-orchestrator/surfaces/pod-command-job.ts +330 -2
  445. package/src/task-orchestrator/surfaces/pod-config-snapshot.ts +123 -0
  446. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +27 -2
  447. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +11 -8
  448. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +1 -1
  449. package/src/task-orchestrator/surfaces/pod-source-receive.ts +74 -6
  450. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +2 -1
  451. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +56 -15
  452. package/src/task-orchestrator/surfaces/self-implement-pod.ts +186 -33
  453. package/src/tool-runtime/skill-exec-runtime.ts +95 -5
  454. package/src/tui/entry.ts +15 -2
  455. package/src/tui/inline-choice.ts +188 -0
  456. package/src/tui/sidetab/list.ts +2 -176
  457. package/src/tui/slash/term.ts +12 -1
  458. package/src/tui-client/dashboard-session.ts +7 -1
  459. package/src/user-config.ts +34 -4
  460. package/src/ux-sim/classic-tui-seat-scenarios.ts +1 -7
  461. package/src/ux-sim/fake-land-queue.ts +88 -0
  462. package/src/ux-sim/gate-shard-host-reroute.ts +82 -0
  463. package/src/ux-sim/goal-interim-trace.ts +24 -0
  464. package/src/ux-sim/next-tui-seat-scenarios.ts +8 -13
  465. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +4 -1
  466. package/src/version/packed-revision.json +1 -1
  467. package/src/video-pipeline/recipes/explainer.ts +54 -2
  468. package/src/web-search/grok.ts +32 -6
  469. package/src/web-search/index.ts +8 -7
  470. package/src/workflow-runtime/node-catalog.ts +53 -4
  471. package/apps/pwa/out/_next/static/chunks/1118.a8a74ea29aac3e46.js +0 -27
  472. package/apps/pwa/out/_next/static/chunks/1204-2aa830479adf80f4.js +0 -1
  473. package/apps/pwa/out/_next/static/chunks/1341-43b7d2dc77d45c9d.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/1440-c3ea8882badfd9bf.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/1698-9c11cbf97f13717e.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/1770-3b1fc92253ef9f2f.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/1923-5c1695332240246a.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/213-20675f20673ba22a.js +0 -1
  479. package/apps/pwa/out/_next/static/chunks/214.186a430da28338f1.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/2277.3bd4c0ac7f1b5996.js +0 -93
  481. package/apps/pwa/out/_next/static/chunks/240.e09f433f71c78ff4.js +0 -104
  482. package/apps/pwa/out/_next/static/chunks/2415.738b777642a02233.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/2417.02151393605a7cd0.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/2463.cd2641a76daaa9ff.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/2576.b9e9c629c4b84c52.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/265-c021de53f0865bd9.js +0 -1
  487. package/apps/pwa/out/_next/static/chunks/2998-b1cc13956cd6a6e7.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/2e4782d3.ba2f0ab2b63a53e7.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/3130.626b54382b4dc379.js +0 -1
  490. package/apps/pwa/out/_next/static/chunks/3221-1bb3f99a55088613.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/3280.24edb1ffd03a7f3f.js +0 -24
  492. package/apps/pwa/out/_next/static/chunks/3288-eb3c22a1cbf2ae68.js +0 -1
  493. package/apps/pwa/out/_next/static/chunks/33.ef99e8374f96c6c4.js +0 -36
  494. package/apps/pwa/out/_next/static/chunks/3341-f09b9efbd7a82f70.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/3389.012c70767a872f9b.js +0 -1
  496. package/apps/pwa/out/_next/static/chunks/3410-d7c0f14b329d6fda.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/3421.c87d6313a7d670f7.js +0 -287
  498. package/apps/pwa/out/_next/static/chunks/3422-83a3953f9bd67e26.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/3587-002e24e368c515a9.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/3644.f12a7d821ab940af.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/3660.d7516588e2d875c3.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/3695.b82e2610f4cd4ea9.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/3858.ca1f5bc0f577eac9.js +0 -94
  504. package/apps/pwa/out/_next/static/chunks/3959-e6ac4a139d9d4bcc.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/4032.53f62176514ec0ea.js +0 -1
  506. package/apps/pwa/out/_next/static/chunks/4204-ef8484cbecd5d62f.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/4259-163129ca79913c4b.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/428-eaa77df3d0c85969.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/4432-97e400ffa1e161f5.js +0 -1
  510. package/apps/pwa/out/_next/static/chunks/449-aa427cf2cbb75f50.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/4491-39a0fd32bbaf3840.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/4588.b7cf06d382953979.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/4690.70ec8060825366ab.js +0 -32
  514. package/apps/pwa/out/_next/static/chunks/4804.6012b5cd33c22792.js +0 -90
  515. package/apps/pwa/out/_next/static/chunks/4881.e4d22d730e3b9df5.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/4937.ce2e340dc29cad3e.js +0 -79
  517. package/apps/pwa/out/_next/static/chunks/5-bb1c08d84bd71df3.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/5005.de98df23b37cdf3c.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/5035.dc64a89cad5573cc.js +0 -74
  520. package/apps/pwa/out/_next/static/chunks/5207.1a224035455790fd.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/5255-1b60d50eabe9f057.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/5269.d0436ee6d773382a.js +0 -286
  523. package/apps/pwa/out/_next/static/chunks/5300.677c97e0393742e6.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/5309.3367c4d50f52b489.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/552-689827d49780fa00.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/5539.34cc9d60622cb69b.js +0 -8
  527. package/apps/pwa/out/_next/static/chunks/5568.218dea0c00ca2ec7.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/5645.b7e3b055455a04ea.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/5662.18cc0f30353cbd96.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/5671.da24fc9dc5e98325.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/5b141171.324c40fd49cb6821.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/6175-d4621f6a10b0cfab.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/6290.3eb53a20746b72ce.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/6415-9307f3eafa90837f.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/6579-3de35d00aacd71b5.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/680-2f324c4e039a5b67.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/6845-331b3c7481da3ba3.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/7000.28157393caaf5343.js +0 -62
  539. package/apps/pwa/out/_next/static/chunks/7311-60a7ea80d23c7521.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/7401.525d0a12f7d02c06.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/7438.c2cf72b66dca6aa4.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/7488.966b116789f3d41a.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/7573.2376e13c9c21f1f8.js +0 -77
  544. package/apps/pwa/out/_next/static/chunks/7577.ea6e9ac72e035520.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/7657.8d1fb3d2f7ebe273.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/7903-1435d5d2f0dd7807.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/7978-30a91192c5dbe3c2.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/8025-8795821525cf1a07.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/8191.3674a00f0b565c23.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/8217-604955d8885c5ef2.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/8298-eed6f5f2585a63f4.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/8758.ac421f726a189125.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/891.d6c723a51a067b36.js +0 -149
  554. package/apps/pwa/out/_next/static/chunks/9223.cbcc88e0e9950426.js +0 -41
  555. package/apps/pwa/out/_next/static/chunks/9317.6a9869039c231bb3.js +0 -24
  556. package/apps/pwa/out/_next/static/chunks/9383.e4755f275b3c11ff.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/9581.da63ddf41acfad46.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/9715.8c5529a0a5c41a36.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/9817.3009d65f0889ef1f.js +0 -2
  560. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76873dd80da4f715.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed32b6ec5dea8f23.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-fdd40e15babf3d25.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/app/board/page-384efc78e85e400b.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/app/bots/page-d91809c5aeed319a.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/app/ceo/page-128f3522f89a81ab.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/app/chat/page-595961abf3b43ad1.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/app/consult/page-f41dccb76d8c0263.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/app/control/page-a3205c2e28b7d0d9.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/app/decisions/page-c39a80277814a3f4.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/app/design-check/page-1ab3f98194513195.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/app/editor/page-a5246f7e254d77d0.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/app/exec/page-0f92287bdb81217d.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/app/field/page-5a37131ff63793ef.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76873dd80da4f715.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/inside/page-ac4bd14bb2348bfd.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/intake/page-c348a3959c5b5fc6.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/layout-2addd81c0d3e2906.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/live/page-da6b765f58a3eefb.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0661e40f8780c32c.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/app/loops/page-b89af1b1c8e4875b.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/app/market/page-da8aeb82ba751cdb.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-cc71317b239439db.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/app/morning/page-bde7fc1d64ffe369.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/app/not-found-e2797214f713fa58.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/app/observatory/page-2a35bcda70defaf6.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3af03deedde45032.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-d1d1210f99f620ae.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-46d1b5500885861d.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/app/outputs/page-291ab19fe2acb173.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/app/page-7f569e533ddeecba.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/app/reflection/page-990129c9fee46d8f.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-7737f785ebb1cdaf.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9f3c73a4f7ffd2f8.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-03be7fb347f01058.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/app/settings/page-96b0280625e4df2b.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-56855545049eb56d.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76873dd80da4f715.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/app/setup/page-79a909c9981f0338.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/app/share/page-a9d9a3e66459c1e0.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c383cbf2013f7069.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f57c6a2e54dbdca4.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/app/term/page-6b140f77593576eb.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/app/today/page-6b767ae2d9d0adfc.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/app/trace/page-116d6198d5da0e3d.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/app/vault/page-b9c9b778c7501370.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-a6c78392ab8f6335.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/app/workflows/page-455183deb4ed0cfe.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6a63e99526bd63d0.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-31c22caafe788c08.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/main-941155250ed2644b.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/main-app-f8b6765abed6d149.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/pages/_app-78432194c85388f9.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/pages/_error-cdf7390829512b1b.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/webpack-d5f0964a9c2e92d2.js +0 -1
  615. /package/apps/pwa/out/_next/static/{RrjXTwz-urRAbChP1bX02 → HjeK7zONHfR7op1hKXp4k}/_ssgManifest.js +0 -0
@@ -7,7 +7,8 @@ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
7
7
  import { join } from 'path';
8
8
  import { fileURLToPath } from 'node:url';
9
9
  import { createRunningBuildStatus } from './running-build-status.js';
10
- import { reportTuiTurn } from '../pty-shell/tui-run-state.js';
10
+ import { reportTuiAbortRequested, reportTuiProgress, reportTuiTurn } from '../pty-shell/tui-run-state.js';
11
+ import { installTuiStderrOwner } from '../surface/tui-stderr-owner.js';
11
12
  import { logTurnThrew, runTurnTeardownStep } from './turn-busy-teardown.js';
12
13
  import { createStaleInstallCheck, formatStaleInstallNotice, readCurrentInstalledCommit, readDashboardBootCommit, STALE_INSTALL_CHECK_INTERVAL_MS, versionedDashboardInstallDir } from './stale-install-check.js';
13
14
  import { spawn, spawnSync } from 'node:child_process';
@@ -188,6 +189,7 @@ import {
188
189
  formatResponse,
189
190
  onEscAbort,
190
191
  attachStreamingKeys,
192
+ SLASH_COMMANDS,
191
193
  type InputResult,
192
194
  type TextInputExternalSubmitRequest,
193
195
  } from '../chat/index.js';
@@ -397,6 +399,7 @@ import { resolveDashboardChatMainSubmitIntent } from './input/chat-main-submit-r
397
399
  import { maybeEmitDashboardSubmitQuickPass } from './input/chat-main-submit-control.js';
398
400
  import { attachDashboardQuickPassConsumers } from './input/control-signal-consumers.js';
399
401
  import { resolveDashboardChatMainSlashCommand } from './input/chat-main-slash-command.js';
402
+ import { isClassicSigquitChord, registerClassicSigquitHandler } from './classic-sigquit.js';
400
403
  import { TuiChatPersonaSelection, tuiChatPersonaMessages } from './slash-runtime/chat-persona.js';
401
404
  import { awaitGlobalPersonaLoad } from '../persona/global-registry.js';
402
405
  import { createDashboardInlineSetupFlow } from './setup-inline.js';
@@ -526,6 +529,41 @@ export function observeDashboardDevRequestRoute(
526
529
  observeDevRequestRouteFailSoft(text, cfg, { surface: 'dashboard' });
527
530
  }
528
531
 
532
+ export async function cancelDelegatedToolOnEscape(deps: {
533
+ abortCtrl: AbortController;
534
+ child: { pid: number; isAlive(): boolean; kill(signal?: NodeJS.Signals): void };
535
+ waitForExit(): Promise<void>;
536
+ pushChatLine(line: string): void;
537
+ }): Promise<boolean> {
538
+ abortTurnOnly(deps.abortCtrl);
539
+ try {
540
+ if (deps.child.isAlive()) deps.child.kill();
541
+ await deps.waitForExit();
542
+ if (deps.child.isAlive()) throw new Error('child still alive after exit acknowledgement');
543
+ debug.log('dashboard.esc-child', 'termination-confirmed', { pid: deps.child.pid });
544
+ deps.pushChatLine(' ⏹ 중단됨');
545
+ return true;
546
+ } catch (error) {
547
+ const reason = error instanceof Error ? error.message : String(error);
548
+ debug.log('dashboard.esc-child', 'termination-failed', { pid: deps.child.pid, reason });
549
+ deps.pushChatLine(` ✘ 종료 실패 — ${reason}`);
550
+ return false;
551
+ }
552
+ }
553
+
554
+ export function activeEscDelegatedPty(
555
+ toolState: EscAbortToolState,
556
+ ptyIdsByCallId: ReadonlyMap<string, string>,
557
+ getPtyById: (id: string) => { pid: number; isAlive(): boolean; kill(signal?: NodeJS.Signals): void } | undefined,
558
+ ): { pid: number; isAlive(): boolean; kill(signal?: NodeJS.Signals): void } | null {
559
+ const active = [...toolState.activeToolNamesByCallId];
560
+ if (active.length !== 1) return null;
561
+ const [callId, name] = active[0]!;
562
+ if (name !== 'PtyShellPoll' && name !== 'PtyShellSnapshot' && name !== 'PtyShellSend') return null;
563
+ const ptyId = ptyIdsByCallId.get(callId);
564
+ return ptyId ? getPtyById(ptyId) ?? null : null;
565
+ }
566
+
529
567
  export interface EscAbortToolState {
530
568
  activeToolNamesByCallId: Map<string, string>;
531
569
  }
@@ -741,7 +779,7 @@ import { needsOnboarding, resetOnboardingMarker } from '../onboarding.js';
741
779
  import {
742
780
  getUserConfig, reloadUserConfig, saveUserConfig,
743
781
  rotateNextProvider, jumpToRotationEntry, rotationEntryLabel, applyRotationEntry,
744
- resolveAcpHopCapFromConfig,
782
+ resolveAcpHopCapFromConfig, resolveTuiUnattended,
745
783
  VOICE_HARDCODED_DEFAULTS,
746
784
  } from '../user-config.js';
747
785
  import { streamLLM, anyProviderAvailable, getProviderForConfig, nextReasoningLevel, reasoningLevelLabel, effectiveReasoningLevel, modelSupportsReasoning, type LLMMessage, type LLMToolSpec } from '../llm.js';
@@ -917,6 +955,7 @@ import {
917
955
  runDashboardScratchExportAction,
918
956
  } from './context-menu-action-runtime.js';
919
957
  import { createDashboardTerminalPopupRuntime } from './terminal-popup-runtime.js';
958
+ import { createDashboardSidetabRuntime } from './sidetab-runtime.js';
920
959
  import { toggleDashboardAssistantRenderState } from './assistant-render-state-runtime.js';
921
960
  import { bootDashboardAcpBgSweep } from './acp-bg-sweep-boot.js';
922
961
  import { bootDashboardConfigTools } from './config-tools-boot.js';
@@ -1143,7 +1182,7 @@ import type { PlainTurnSubmit } from '../input/turn-submit.js';
1143
1182
  import { findBlock, logPaneContentHeight, maxLogPaneScroll, visibleSearchRowOffset } from '../panes/log-pane.js';
1144
1183
  import { createQuitConfirmationState, gracefulQuit, type QuitConfirmationState } from './graceful-quit.js';
1145
1184
  import { consumeTurnEndInterrupted, handoffTurnTypeaheadAtTurnEnd, releaseTurnTypeaheadPending, runTurnTypeaheadPushNow, steerLastTurnTypeaheadSubmission } from './input/turn-steer-bridge.js';
1146
- import { abortTurnOnly } from '../turn-abort-scope.js';
1185
+ import { abortAndKillChildren, abortTurnOnly } from '../turn-abort-scope.js';
1147
1186
  import { consumeInternalTurnYield, createInternalTurnGate, formatInternalTurnBanner, resolveInternalTurnSubmitIntent, type InternalTurnRequest } from './input/internal-turn.js';
1148
1187
  import { createClassicInterimFold } from './input/goal-interim.js';
1149
1188
  import { createSeatAutowake } from './input/seat-autowake.js';
@@ -1293,6 +1332,7 @@ export function subscribeDashboardAgentResults(
1293
1332
  }
1294
1333
  }
1295
1334
  });
1335
+ queue.replayPendingWakes(listener);
1296
1336
  return () => { offWake(); offDrain(); };
1297
1337
  }
1298
1338
 
@@ -1451,6 +1491,9 @@ import {
1451
1491
  } from './input/space-longpress-detector.js';
1452
1492
  import { isAllowlistedDictationSurface } from './input/dictation-surface-allowlist.js';
1453
1493
  import { createDashboardExternalInputHost, stopTurnViaEscGate, updateDashboardExternalInputQueueNotice } from './input/external-input-host.js';
1494
+ import { registerTuiForceStopHandler } from '../capture/tui-self-report.js';
1495
+ import { createInlineAskUserQuestionResolver, resolveUnattendedInlineChoiceTimeoutMs, UNATTENDED_INLINE_CHOICE_TIMEOUT_MS } from '../ask-user-question/index.js';
1496
+ import { createInlineChoiceTurnEndCleanup, InlineChoiceBroker } from '../tui/inline-choice.js';
1454
1497
  import { registerExternalInputHost } from '../input/external-input-queue.js';
1455
1498
  // H3 #6 follow-up #3 — background sessions render as a distinct sidebar
1456
1499
  // kind with live state badge + tap-to-Join. Dashboard pulls BG records
@@ -2043,9 +2086,18 @@ export async function showDashboard(opts: ShowDashboardOptions = {}): Promise<Da
2043
2086
  let disposeDashboardEventLoopMonitor = (): void => {};
2044
2087
  // TUI-AGENT-IDLE-WAKE — 이 대시보드 «자기» 완료 알림 구독만 푼다(배선 지점에서 채운다).
2045
2088
  let disposeDashboardAgentWake = (): void => {};
2089
+ let disposeClassicSigquit = (): void => {};
2090
+ let closeClassicSidetabRuntime = (): void => {};
2091
+ let restoreTuiStderrOwner = (): void => {};
2046
2092
  const closeDashboardTui = (): void => {
2047
2093
  disposeDashboardEventLoopMonitor();
2048
2094
  try { disposeDashboardAgentWake(); } catch { /* never block exit */ }
2095
+ disposeClassicSigquit();
2096
+ disposeClassicSigquit = (): void => {};
2097
+ try { closeClassicSidetabRuntime(); } catch { /* never block exit */ }
2098
+ closeClassicSidetabRuntime = (): void => {};
2099
+ try { restoreTuiStderrOwner(); } catch { /* never block screen cleanup */ }
2100
+ restoreTuiStderrOwner = (): void => {};
2049
2101
  closeTui();
2050
2102
  };
2051
2103
  const exitDashboardTui = (): void => {
@@ -2582,6 +2634,15 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
2582
2634
  }
2583
2635
  chatScrollOffset = -1;
2584
2636
  };
2637
+ const inlineChoiceBroker = new InlineChoiceBroker({
2638
+ appendLines: (lines) => {
2639
+ for (const line of lines) pushChatLine(C.info(line));
2640
+ draw();
2641
+ },
2642
+ });
2643
+ const resolveInlineAskUserQuestion = createInlineAskUserQuestionResolver(inlineChoiceBroker, {
2644
+ timeoutMs: () => resolveUnattendedInlineChoiceTimeoutMs(getUserConfig()),
2645
+ });
2585
2646
  const liveTypeaheadEchoes: { at: number; lines: string[] }[] = [];
2586
2647
  const restoreLiveTypeaheadEchoes = (): void => {
2587
2648
  let after = 0;
@@ -3076,6 +3137,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
3076
3137
  let attachedSessionId: string | null = null;
3077
3138
  const chatPersonaSelection = new TuiChatPersonaSelection();
3078
3139
  let chatPersonaConversationId = crypto.randomUUID();
3140
+ const slashUsageRunId = crypto.randomUUID();
3079
3141
  const currentChatPersonaSessionId = () => attachedSessionId ?? chatPersonaConversationId;
3080
3142
  let attachedChatId: number | null = null;
3081
3143
  const forkableSessionHistory = (source: ChatMessage[] = chat.history): ForkableSessionTurn[] =>
@@ -5138,6 +5200,17 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
5138
5200
  };
5139
5201
  registerLogFoldInputBinding(toggleAllLogFolds);
5140
5202
 
5203
+ const showClassicSigquitGuidance = (): void => {
5204
+ debug.log('dashboard.signal', 'sigquit-guidance', { surface: 'classic', source: 'ctrl-backslash' });
5205
+ chatLines.push(C.warning(' classic 사이드탭: /side · /side new · /side attach <번호>'));
5206
+ chatScrollOffset = -1;
5207
+ draw({ force: true });
5208
+ };
5209
+
5210
+ restoreTuiStderrOwner = installTuiStderrOwner((line) => {
5211
+ chatLines.push(C.warning(`[stderr] ${line}`));
5212
+ draw({ force: true });
5213
+ });
5141
5214
  initTui(true);
5142
5215
 
5143
5216
  // ── Working-dir browser glyphs (shared between the list widget and
@@ -6748,6 +6821,11 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6748
6821
  * this function is invoked.
6749
6822
  */
6750
6823
  const escAbortToolState = createEscAbortToolState();
6824
+ let escDelegatedTermination: Promise<boolean> | null = null;
6825
+ let delegatedTerminationPending = false;
6826
+ let delegatedTerminationFailed = false;
6827
+ const escDelegatedPtyIdsByCallId = new Map<string, string>();
6828
+ const escDelegatedShellResultsByCallId = new Map<string, Promise<unknown>>();
6751
6829
  const escHarnessSpacesByCallId = new Map<string, string>();
6752
6830
  setSelfImplementSoftStopSpaceObserver((callId, spaceId) => {
6753
6831
  const toolName = escAbortToolState.activeToolNamesByCallId.get(callId);
@@ -6768,6 +6846,12 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6768
6846
  // the stream — the running count is visible in the HUD (T3-B1)
6769
6847
  // so the user can make an informed call.
6770
6848
  let abortGateModalId: string | null = null;
6849
+ const getDelegatedPty = () => activeEscDelegatedPty(escAbortToolState, escDelegatedPtyIdsByCallId, getPty);
6850
+ const getDelegatedShell = () => {
6851
+ const active = [...escAbortToolState.activeToolNamesByCallId];
6852
+ if (active.length !== 1 || (active[0]![1] !== 'Bash' && active[0]![1] !== 'RunShell')) return null;
6853
+ return escDelegatedShellResultsByCallId.get(active[0]![0]) ?? null;
6854
+ };
6771
6855
  const showHarnessEscHint = createHarnessEscHint((line) => pushChatLine(line));
6772
6856
  const activeHarnessSpace = (): string | null => activeEscHarnessSpace(escAbortToolState, escHarnessSpacesByCallId);
6773
6857
  // ⭐ TUI-ESC-EXIT — `createEscAbortPendingGate` is the production
@@ -6779,7 +6863,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6779
6863
  runSoftStop: runEscAbortPendingSoftStop,
6780
6864
  formatWaitingTargets: formatEscAbortWaitingTargets,
6781
6865
  getActiveHarnessSpace: activeHarnessSpace,
6782
- pushChatLine: (line) => pushChatLine(line),
6866
+ pushChatLine: (line) => { if (!getDelegatedPty() && !getDelegatedShell() && !delegatedTerminationPending && !delegatedTerminationFailed) pushChatLine(line); },
6783
6867
  showHarnessEscHint,
6784
6868
  afterAbortEvent: () => { chatScrollOffset = -1; },
6785
6869
  });
@@ -6796,11 +6880,77 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6796
6880
  requestRedraw: () => draw(),
6797
6881
  getTheme: () => currentThemeTokens(),
6798
6882
  getWaitingTargetNames: () => getEscAbortWaitingToolNames(escAbortToolState),
6799
- shouldAbortImmediately: () => activeHarnessSpace() !== null,
6883
+ shouldAbortImmediately: () => activeHarnessSpace() !== null || getDelegatedPty() !== null || getDelegatedShell() !== null,
6884
+ forceStopWithoutModal: () => resolveTuiUnattended(getUserConfig()),
6885
+ confirmStopInline: async () => {
6886
+ const result = await inlineChoiceBroker.ask({
6887
+ id: `stop-turn:${Date.now().toString(36)}`,
6888
+ question: '도는 작업과 하위 에이전트를 함께 중단할까요?',
6889
+ options: [
6890
+ { value: 'stop', label: '중단', description: '현재 턴과 자식 작업을 종료합니다.' },
6891
+ { value: 'continue', label: '계속', description: '현재 작업을 계속 실행합니다.' },
6892
+ ],
6893
+ includeOther: false,
6894
+ timeoutMs: UNATTENDED_INLINE_CHOICE_TIMEOUT_MS,
6895
+ });
6896
+ return !('cancelled' in result) && result.selected[0] === 'stop';
6897
+ },
6800
6898
  // ⭐ TUI-ESC-EXIT — `runEscAbortPendingSoftStop` is the production
6801
6899
  // soft-stop callback seam; the incident test in
6802
6900
  // test/esc-harness-stop.test.ts exercises this same function.
6803
- onAbortPending: escAbortPendingGate.onAbortPending,
6901
+ onAbortPending: (event) => {
6902
+ const child = getDelegatedPty();
6903
+ const shell = getDelegatedShell();
6904
+ if (!child && !shell) { escAbortPendingGate.onAbortPending(event); return; }
6905
+ if (shell && !child) {
6906
+ delegatedTerminationPending = true;
6907
+ pushChatLine(' ⏳ 중단 요청됨 — 위임 자식 종료를 확인하는 중입니다.');
6908
+ escDelegatedTermination = (async () => {
6909
+ abortTurnOnly(abortCtrl);
6910
+ try {
6911
+ const result = await Promise.race([shell, Bun.sleep(4_000).then(() => { throw new Error('shell child termination timeout'); })]);
6912
+ const status = result as { aborted?: boolean; outcome?: string; output?: string } | null;
6913
+ if (!status?.aborted && status?.outcome !== 'aborted'
6914
+ && !status?.output?.includes('[aborted]')) throw new Error('shell child exit not confirmed as aborted');
6915
+ debug.log('dashboard.esc-child', 'termination-confirmed', { tool: event.targets });
6916
+ const pendingIndex = chatLines.lastIndexOf(' ⏳ 중단 요청됨 — 위임 자식 종료를 확인하는 중입니다.');
6917
+ if (pendingIndex >= 0) chatLines.splice(pendingIndex, 1);
6918
+ pushChatLine(' ⏹ 중단됨');
6919
+ draw();
6920
+ return true;
6921
+ } catch (error) {
6922
+ delegatedTerminationFailed = true;
6923
+ const reason = error instanceof Error ? error.message : String(error);
6924
+ debug.log('dashboard.esc-child', 'termination-failed', { tool: event.targets, reason });
6925
+ const pendingIndex = chatLines.lastIndexOf(' ⏳ 중단 요청됨 — 위임 자식 종료를 확인하는 중입니다.');
6926
+ if (pendingIndex >= 0) chatLines.splice(pendingIndex, 1);
6927
+ pushChatLine(` ✘ 종료 실패 — ${reason}`);
6928
+ draw();
6929
+ return false;
6930
+ }
6931
+ })().finally(() => { delegatedTerminationPending = false; });
6932
+ return;
6933
+ }
6934
+ if (!child) return;
6935
+ delegatedTerminationPending = true;
6936
+ pushChatLine(' ⏳ 중단 요청됨 — 위임 자식 종료를 확인하는 중입니다.');
6937
+ escDelegatedTermination = cancelDelegatedToolOnEscape({
6938
+ abortCtrl,
6939
+ child,
6940
+ waitForExit: async () => {
6941
+ const deadline = Date.now() + 3_000;
6942
+ while (child.isAlive() && Date.now() < deadline) await Bun.sleep(50);
6943
+ if (child.isAlive()) throw new Error('PTY child termination timeout');
6944
+ },
6945
+ pushChatLine: (line) => {
6946
+ delegatedTerminationFailed = line.includes('종료 실패');
6947
+ const pendingIndex = chatLines.lastIndexOf(' ⏳ 중단 요청됨 — 위임 자식 종료를 확인하는 중입니다.');
6948
+ if (pendingIndex >= 0) chatLines.splice(pendingIndex, 1);
6949
+ pushChatLine(line);
6950
+ draw();
6951
+ },
6952
+ }).finally(() => { delegatedTerminationPending = false; });
6953
+ },
6804
6954
  onAbortRepeat: escAbortPendingGate.onAbortRepeat,
6805
6955
  // ⭐⭐⭐ 턴을 멈추기 «전»에 살아남을 자식을 백그라운드 라우팅으로 넘긴다(`R4a` · 2026-08-19).
6806
6956
  // ⛔ 없으면 `R1` 이후 자식이 «고아»가 된다 — 살아 있는데 완료를 실어 나를 채널이 없다
@@ -6818,6 +6968,15 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6818
6968
  } catch { /* 관측·핸드오프가 중단을 막지 않는다 */ }
6819
6969
  },
6820
6970
  });
6971
+ const unregisterTuiForceStop = registerTuiForceStopHandler(() => {
6972
+ if (abortCtrl.signal.aborted) return false;
6973
+ debug.log('pty.stop-turn', 'force-requested', { targets: getEscAbortWaitingToolNames(escAbortToolState) });
6974
+ abortAndKillChildren(abortCtrl);
6975
+ pushChatLine(' ⏹ 강제 중단을 요청했습니다. 현재 턴과 자식 작업이 정리되면 유휴 상태로 돌아갑니다.');
6976
+ draw();
6977
+ return true;
6978
+ });
6979
+ const cancelInlineChoiceAtTurnEnd = createInlineChoiceTurnEndCleanup(inlineChoiceBroker);
6821
6980
 
6822
6981
  // Scroll the log pane by ±N rows from whatever the current tail-
6823
6982
  // relative offset resolves to. Shared by keyboard and mouse-wheel
@@ -7337,15 +7496,21 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
7337
7496
  streamingInFlight = true;
7338
7497
  noteClipboardBusyChange();
7339
7498
  reportTuiTurn('busy');
7340
- const externalStop = (): void => { stopTurnViaEscGate(escGate); };
7499
+ const externalStop = (): void => {
7500
+ // Esc 게이트가 턴 중단을 청하는 순간 — busy 가 이 뒤로 지속되면 abort-ignored 판정 재료가 된다.
7501
+ reportTuiAbortRequested();
7502
+ stopTurnViaEscGate(escGate);
7503
+ };
7341
7504
  currentTurnExternalStop = externalStop;
7342
7505
  return () => {
7343
7506
  if (currentTurnExternalStop === externalStop) currentTurnExternalStop = null;
7344
7507
  // 단계마다 격리 — 앞 단계가 던져도 settle·idle 전이에 닿는다(키 층 유휴 ∧ 턴 층 busy 이원 판정 #55 차단).
7345
7508
  runTurnTeardownStep('stream-keys-detach', cleanup);
7509
+ runTurnTeardownStep('inline-choice-cancel', cancelInlineChoiceAtTurnEnd);
7510
+ runTurnTeardownStep('tui-force-stop-detach', unregisterTuiForceStop);
7346
7511
  runTurnTeardownStep('esc-gate-dispose', () => { escGate.dispose(); });
7347
7512
  try {
7348
- if (!escAbortPendingGate.getStoppedHarnessSpace()) settleEscAbortPendingLines(chatLines, chatLinesStartIndex);
7513
+ if (!escAbortPendingGate.getStoppedHarnessSpace() && !delegatedTerminationPending && !delegatedTerminationFailed) settleEscAbortPendingLines(chatLines, chatLinesStartIndex);
7349
7514
  } catch (err) {
7350
7515
  const message = err instanceof Error ? err.message : String(err);
7351
7516
  const stackHead = err instanceof Error ? err.stack?.split('\n')[1]?.trim() : undefined;
@@ -12734,6 +12899,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
12734
12899
  const disposeExternalInputHost = registerExternalInputHost(createDashboardExternalInputHost({
12735
12900
  isTurnActive: () => streamingInFlight,
12736
12901
  getTurnStop: () => currentTurnExternalStop,
12902
+ handleInlineChoice: (text) => inlineChoiceBroker.handleInput(text),
12737
12903
  promptCtl,
12738
12904
  pushNotice: (line) => { chatLines.push(C.muted(` ${line}`)); chatScrollOffset = -1; draw(); },
12739
12905
  setQueueNotice: setExternalInputQueueNotice,
@@ -13578,6 +13744,87 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
13578
13744
  const spawnGlobalTerminalModal = (command?: string): void => {
13579
13745
  openInteractiveTerminalPopup({ kind: 'shell', cwd: workingDir.cwd, command });
13580
13746
  };
13747
+ const classicSidetabRuntime = createDashboardSidetabRuntime({
13748
+ currentSessionId: () => currentChatPersonaSessionId(),
13749
+ termSize,
13750
+ pushModal: (surface) => {
13751
+ attachSurfaceToWorkspace(surface, currentWorkspaceOwnerId());
13752
+ const handle = display.pushModal(surface);
13753
+ draw();
13754
+ return { dispose: () => { handle.dispose(); draw(); } };
13755
+ },
13756
+ attach: (row) => {
13757
+ if (row.sessionId && sessionRegistry.get(row.sessionId)) {
13758
+ const { cols, rows } = termSize();
13759
+ const attached = sessionRegistry.attach(row.sessionId, { termCols: cols, termRows: rows });
13760
+ if (attached?.modal) {
13761
+ terminalModalRouter.set(attached.modal, {
13762
+ onClose: () => { sessionRegistry.detach(attached.id); draw(); },
13763
+ });
13764
+ draw();
13765
+ }
13766
+ return;
13767
+ }
13768
+ if (!row.ptyId) return;
13769
+ void requestRemotePtyControl(row.ptyId, 'snapshot', { ansi: false }, { timeoutMs: 450 })
13770
+ .then((result) => {
13771
+ if (result.status === 'success' && result.screen?.trim()) {
13772
+ chatLines.push(C.muted(` ${row.label} · 읽기 전용 snapshot (입력은 전달되지 않습니다)`));
13773
+ chatLines.push(...stripAnsi(result.screen).split('\n'));
13774
+ } else chatLines.push(C.warning(` PTY 화면 읽기 실패 · ${result.status}`));
13775
+ chatScrollOffset = -1;
13776
+ draw();
13777
+ })
13778
+ .catch((error) => {
13779
+ chatLines.push(C.warning(` PTY 화면 읽기 오류 · ${error instanceof Error ? error.message : String(error)}`));
13780
+ chatScrollOffset = -1;
13781
+ draw();
13782
+ });
13783
+ },
13784
+ spawnShell: () => { spawnGlobalTerminalModal(); },
13785
+ detach: (row) => {
13786
+ if (row?.currentProcess) {
13787
+ chatLines.push(C.muted(' 현재 classic TUI는 분리할 수 없습니다'));
13788
+ } else {
13789
+ const id = row?.sessionId ?? terminalModalRouter.current()?.id ?? sessionRegistry.foreground()?.id;
13790
+ if (!id) chatLines.push(C.muted(' 분리할 셸 세션이 없습니다'));
13791
+ else if (terminalModalRouter.current()?.id === id) terminalModalRouter.close();
13792
+ else sessionRegistry.detach(id);
13793
+ }
13794
+ chatScrollOffset = -1;
13795
+ draw();
13796
+ },
13797
+ kill: (row) => {
13798
+ if (row.sessionId && sessionRegistry.get(row.sessionId)) {
13799
+ if (terminalModalRouter.current()?.id === row.sessionId) terminalModalRouter.close();
13800
+ sessionRegistry.kill(row.sessionId);
13801
+ chatLines.push(C.muted(` ${row.label} 종료 요청 완료`));
13802
+ } else if (row.ptyId) {
13803
+ void requestRemotePtyControl(row.ptyId, 'terminate', undefined, { timeoutMs: 1_000 })
13804
+ .then((result) => chatLines.push(result.status === 'success'
13805
+ ? C.muted(` ${row.label} 종료 요청 완료`)
13806
+ : C.warning(` PTY 종료 거부 · ${result.status}`)))
13807
+ .catch((error) => chatLines.push(C.warning(` PTY 종료 오류 · ${error instanceof Error ? error.message : String(error)}`)))
13808
+ .finally(() => { chatScrollOffset = -1; draw(); });
13809
+ }
13810
+ chatScrollOffset = -1;
13811
+ draw();
13812
+ },
13813
+ returnToParent: () => {
13814
+ if (terminalModalRouter.current()) terminalModalRouter.close();
13815
+ setWorkingFocus('input', 'classic-sidetab-parent');
13816
+ draw();
13817
+ },
13818
+ status: (message) => {
13819
+ chatLines.push(C.muted(` ${message}`));
13820
+ chatScrollOffset = -1;
13821
+ draw();
13822
+ },
13823
+ });
13824
+ closeClassicSidetabRuntime = () => classicSidetabRuntime.close();
13825
+ disposeClassicSigquit = registerClassicSigquitHandler(() => {
13826
+ classicSidetabRuntime.beginPrefix();
13827
+ });
13581
13828
 
13582
13829
  // E3 (2026-05-17) — copyLastAssistantTurnToClipboard /
13583
13830
  // copyLastAssistantCodeToClipboard land into the outer-scoped
@@ -15147,20 +15394,21 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
15147
15394
  const contextUserText = ctx?.userText;
15148
15395
  const turnRefUserText = acpTurnRef.userText;
15149
15396
  const hasParentTurnAbortSignal = acpTurnRef.abortCtrl?.signal !== undefined;
15397
+ const turnSignal = acpTurnRef.abortCtrl?.signal ?? new AbortController().signal;
15150
15398
  observeDashboardToolDispatchSignal({
15151
15399
  toolName: name,
15152
15400
  turnIndex: ctx?.turnIndex ?? null,
15153
15401
  signalSource: hasParentTurnAbortSignal ? 'parent-turn' : 'fallback',
15154
15402
  hasParentTurnAbortSignal,
15155
- signalAlreadyAborted: (acpTurnRef.abortCtrl?.signal ?? new AbortController().signal).aborted,
15403
+ signalAlreadyAborted: turnSignal.aborted,
15156
15404
  });
15157
- const result = await dispatchDashboardSessionRuntimeTool(name, args, {
15405
+ const dispatchPromise = dispatchDashboardSessionRuntimeTool(name, args, {
15158
15406
  contextUserText,
15159
15407
  turnRefUserText,
15160
15408
  muted: C.muted,
15161
15409
  pushChatLine,
15162
15410
  draw,
15163
- signal: acpTurnRef.abortCtrl?.signal ?? new AbortController().signal,
15411
+ signal: turnSignal,
15164
15412
  toolCallId: ctx?.callId,
15165
15413
  // ⛔⭐ 폴백은 `''` 가 아니라 `undefined` 다 — 「안 넘김」과 「말했는데 어휘가 없음」은 «다른 값»이다.
15166
15414
  // harnessMentionState(session-runtime 소비처)는 `undefined → 'absent'` · `'' → 'not-matched'` 로
@@ -15187,7 +15435,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
15187
15435
  runtime.dispatchToolByName(toolName, input, {
15188
15436
  surface: 'tui',
15189
15437
  toolCallId,
15190
- signal: acpTurnRef.abortCtrl?.signal,
15438
+ signal: hasParentTurnAbortSignal ? turnSignal : undefined,
15191
15439
  // ⭐ Agent-family context. Without these two the sub-agent runs
15192
15440
  // text-only (see getTools above). `agentDispatchTool` routes the
15193
15441
  // child's calls back through THIS dispatcher so the child gets the
@@ -15206,6 +15454,10 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
15206
15454
  dispatchPluginTool: (toolName, input) =>
15207
15455
  pluginHost.dispatchTool(toolName, input),
15208
15456
  });
15457
+ if (ctx?.callId && (name === 'Bash' || name === 'RunShell')) {
15458
+ escDelegatedShellResultsByCallId.set(ctx.callId, dispatchPromise);
15459
+ }
15460
+ const result = await dispatchPromise;
15209
15461
  // Mirror the direct-path truncation wrapper at
15210
15462
  // dashboard/index.ts L19917-19932 so large tool outputs
15211
15463
  // land in the preview store + the LLM sees the short
@@ -15655,6 +15907,12 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
15655
15907
 
15656
15908
  const priorityRoute = await routeDashboardPriorityKey(key, {
15657
15909
  inputOwner: chatMainVisibility.inputOwnership?.owner,
15910
+ routeClassicSigquitChord: (routeKey) => {
15911
+ if (classicSidetabRuntime.routeKey(routeKey)) return true;
15912
+ if (!isClassicSigquitChord(routeKey)) return false;
15913
+ showClassicSigquitGuidance();
15914
+ return true;
15915
+ },
15658
15916
  routeBellKey: async (routeKey) => {
15659
15917
  if (!bellOpen || routeKey.mouse) return false;
15660
15918
  const inst = widgetHost.get('wd-notification-bell');
@@ -15701,6 +15959,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
15701
15959
  draw();
15702
15960
  return true;
15703
15961
  },
15962
+ routeSidetabKey: (routeKey) => classicSidetabRuntime.routeKey(routeKey),
15704
15963
  dispatchPreKey: (routeKey, targetHandlerName) => {
15705
15964
  const questionViewHandler = {
15706
15965
  name: 'question-view',
@@ -15789,13 +16048,9 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
15789
16048
  return true;
15790
16049
  },
15791
16050
  // Step 0 force-quit — fires from anywhere (bell modal, popup
15792
- // terminal, drag, dashboard). Escape-hatch aliases:
15793
- // - Ctrl+Shift+Q
15794
- // - Ctrl+\
15795
- // The second alias is for terminal/VW-heavy contexts where
15796
- // Shift-modified control chords may get normalized away by the
15797
- // terminal emulator. Plain Ctrl+Q is still *not* the true
15798
- // force-quit because terminal-resident apps use it.
16051
+ // terminal, drag, dashboard). Ctrl+Shift+Q is the escape chord;
16052
+ // Ctrl+\ is reserved for classic side-tab guidance. Plain Ctrl+Q
16053
+ // remains available to terminal-resident apps.
15799
16054
  // Korean shifted ㅃ (Shift+ㅂ on 2-bul) accepts ctrl-only
15800
16055
  // because the shift bit may be implicit in the codepoint.
15801
16056
  isForceQuitChord: (routeKey) => {
@@ -15812,7 +16067,6 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
15812
16067
  });
15813
16068
  }
15814
16069
  if (!routeKey.ctrl) return false;
15815
- if (routeKey.name === '\\' || routeKey.name === 'backslash') return true;
15816
16070
  if (routeKey.shift && (routeKey.name === 'q' || routeKey.name === 'Q' || routeKey.name === 'ㅂ')) return true;
15817
16071
  if (routeKey.name === 'ㅃ') return true;
15818
16072
  return false;
@@ -16573,6 +16827,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
16573
16827
  chatMainInputVisibilityState().inputOwnership?.owner === 'chat-main',
16574
16828
  onPasteImage: attachClipboardImage,
16575
16829
  routeVoiceKey: async (routeKey) => {
16830
+ if (classicSidetabRuntime.routeKey(routeKey)) return 'consumed';
16576
16831
  // 2026-04-30 — voice-chat ESC: when the controller is
16577
16832
  // active and the user hits ESC inside chat-main, take
16578
16833
  // it as a "exit voice mode" gesture and DO NOT let
@@ -16825,6 +17080,12 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
16825
17080
  const outcome = await inputCoreRouteInputEventAsync(ev, ctx);
16826
17081
  return outcome === 'consumed' ? 'consumed' : 'passthrough';
16827
17082
  },
17083
+ routeQuitChord: (key) => {
17084
+ if (classicSidetabRuntime.routeKey(key)) return 'consumed';
17085
+ if (!isClassicSigquitChord(key)) return 'passthrough';
17086
+ showClassicSigquitGuidance();
17087
+ return 'consumed';
17088
+ },
16828
17089
  shouldRouteInputDispatcherKey: (key) => {
16829
17090
  const topModalId = display.modalStack().at(-1) ?? null;
16830
17091
  const topModal = topModalId ? display.surface(topModalId) : null;
@@ -17249,9 +17510,11 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
17249
17510
  // { return: DashboardAction }.
17250
17511
  const dashboardSlashSurfaceUx = resolveDashboardSlashSurfaceUx();
17251
17512
  const clarificationSurfaceUx = dashboardSlashSurfaceUx ? {
17252
- question: (request: Parameters<typeof dashboardSlashSurfaceUx.question>[0]) => {
17253
- const pending = dashboardSlashSurfaceUx.question(request);
17254
- if ((request as typeof request & { [DASHBOARD_CLARIFICATION_REQUEST]?: boolean })[DASHBOARD_CLARIFICATION_REQUEST]) {
17513
+ question: (request: Parameters<typeof dashboardSlashSurfaceUx.question>[0], options?: Parameters<typeof dashboardSlashSurfaceUx.question>[1]) => {
17514
+ const clarification = (request as typeof request & { [DASHBOARD_CLARIFICATION_REQUEST]?: boolean })[DASHBOARD_CLARIFICATION_REQUEST] === true;
17515
+ if (clarification && resolveTuiUnattended(getUserConfig())) return resolveInlineAskUserQuestion(request);
17516
+ const pending = dashboardSlashSurfaceUx.question(request, options);
17517
+ if (clarification) {
17255
17518
  const handle = approvalModalRouter.current();
17256
17519
  if (approvalModalRouter.currentKind() === 'askUser' && handle) {
17257
17520
  clarificationModalId = handle.surface.id;
@@ -17603,6 +17866,8 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
17603
17866
  pushModalSurface: (surface: import('../display/modal-stack.js').ModalSurface) => display.pushModal(surface),
17604
17867
  redraw: draw,
17605
17868
  onStatus: (line: string) => {
17869
+ // 상태 줄 = 진전 신호(SURVIVAL-PROGRESS-CLOCK) — 마지막 진전 시각을 올린다.
17870
+ reportTuiProgress();
17606
17871
  chatLines.push(C.muted(` ${line}`));
17607
17872
  chatScrollOffset = -1;
17608
17873
  },
@@ -17947,10 +18212,16 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
17947
18212
  schedulerRef: dashboardLoopSchedulerRef,
17948
18213
  },
17949
18214
  };
17950
- const slashOutcome = await dashboardSlashRegistry.dispatch(cmdLower, args, slashCtx);
17951
- if (cmdLower === 'mission') {
17952
- debug.log('tui.legacy-slash-use', 'mission', { surface: 'classic', tuiSession: null });
18215
+ const slashCommand = SLASH_COMMANDS.find((entry) => entry.name === cmdLower || entry.aliases?.includes(cmdLower));
18216
+ if (slashCommand) {
18217
+ debug.log('tui.slash-use', 'dispatch', {
18218
+ command: slashCommand.name,
18219
+ alias: cmdLower === slashCommand.name ? null : cmdLower,
18220
+ surface: 'classic',
18221
+ runId: slashUsageRunId,
18222
+ });
17953
18223
  }
18224
+ const slashOutcome = await dashboardSlashRegistry.dispatch(cmdLower, args, slashCtx);
17954
18225
  if (debug.enabled) {
17955
18226
  debug.log('dashboard.slash.dispatch', cmdLower, {
17956
18227
  argsCount: args.length,
@@ -17963,6 +18234,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
17963
18234
  if (slashOutcome.kind === 'return') return slashOutcome.value;
17964
18235
  if (slashOutcome.kind === 'continue') {
17965
18236
  if (exitInputLoop) break;
18237
+ draw();
17966
18238
  continue;
17967
18239
  }
17968
18240
  switch (cmdLower) {
@@ -18771,7 +19043,11 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
18771
19043
  createTurnStreamRuntime: (initialAssistantStart) => {
18772
19044
  latestTurnUsage = undefined;
18773
19045
  createDashboardTurnStreamRuntimeEscBoundary(escAbortToolState);
19046
+ delegatedTerminationPending = false;
19047
+ delegatedTerminationFailed = false;
18774
19048
  escHarnessSpacesByCallId.clear();
19049
+ escDelegatedPtyIdsByCallId.clear();
19050
+ escDelegatedShellResultsByCallId.clear();
18775
19051
  liveTypeaheadEchoes.length = 0;
18776
19052
  const toolRendering = {
18777
19053
  ...getUserConfig().chat.rendering.tool,
@@ -18814,19 +19090,31 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
18814
19090
  return {
18815
19091
  ...turnStreamRuntime,
18816
19092
  onText: (chunk, accumulated) => {
19093
+ // 스트림 텍스트 = 진전 신호(SURVIVAL-PROGRESS-CLOCK) — 마지막 진전 시각을 올린다.
19094
+ reportTuiProgress();
18817
19095
  turnStreamRuntime.onText(chunk, accumulated);
18818
19096
  restoreLiveTypeaheadEchoes();
18819
19097
  draw();
18820
19098
  },
18821
19099
  onToolCall: (call) => {
18822
19100
  const toolCall = call as DashboardTurnStreamCall;
19101
+ // 도구 시작 = 진전 신호 — 녹음기가 없으면(reportTuiProgress 계약) 아무 일도 안 한다.
19102
+ reportTuiProgress();
18823
19103
  trackEscAbortToolCall(escAbortToolState, toolCall);
19104
+ if ((toolCall.name === 'PtyShellPoll' || toolCall.name === 'PtyShellSnapshot' || toolCall.name === 'PtyShellSend')
19105
+ && typeof toolCall.args.process_id === 'string') {
19106
+ escDelegatedPtyIdsByCallId.set(toolCall.id, toolCall.args.process_id);
19107
+ }
18824
19108
  turnStreamRuntime.onToolCall(toolCall);
18825
19109
  },
18826
19110
  onToolResult: (call) => {
18827
19111
  const toolCall = call as DashboardTurnStreamCall;
19112
+ // 도구 끝 = 진전 신호 — 마지막 진전 시각을 올린다.
19113
+ reportTuiProgress();
18828
19114
  turnStreamRuntime.onToolResult(toolCall);
18829
19115
  settleEscAbortToolCall(escAbortToolState, toolCall);
19116
+ escDelegatedPtyIdsByCallId.delete(toolCall.id);
19117
+ escDelegatedShellResultsByCallId.delete(toolCall.id);
18830
19118
  escHarnessSpacesByCallId.delete(toolCall.id);
18831
19119
  },
18832
19120
  onThought: (text) => {
@@ -18968,7 +19256,13 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
18968
19256
  chatLines.push(C.warning(notice));
18969
19257
  detailViewerRuntime.stage('turn error', raw.split(/\r?\n/));
18970
19258
  },
18971
- finalizeTurn: (finalStatus, finalError) => {
19259
+ finalizeTurn: async (finalStatus, finalError) => {
19260
+ if (escDelegatedTermination) {
19261
+ const terminated = await escDelegatedTermination;
19262
+ finalStatus = terminated ? 'interrupted' : 'failed';
19263
+ if (!terminated) finalError = 'delegated PTY termination failed';
19264
+ escDelegatedTermination = null;
19265
+ }
18972
19266
  lastTurnFinalStatus = finalStatus;
18973
19267
  clearEscAbortToolState(escAbortToolState);
18974
19268
  finalizeDashboardTurn({
@@ -18,6 +18,7 @@ export type DashboardChatMainInteractionOpts = Pick<
18
18
  | 'onPasteImage'
19
19
  | 'onKey'
20
20
  | 'onPreKey'
21
+ | 'onQuitChord'
21
22
  | 'onMouse'
22
23
  >;
23
24
 
@@ -46,6 +47,7 @@ export interface CreateDashboardChatMainInteractionOptsDeps {
46
47
  * instead of "<transcript>a" (PR #1109 review fix). */
47
48
  routeLongPressDictation?: (key: Key) => 'consumed' | 'passthrough' | Promise<'consumed' | 'passthrough'>;
48
49
  routeInputKey: NonNullable<DashboardChatMainInteractionOpts['onKey']>;
50
+ routeQuitChord?: NonNullable<DashboardChatMainInteractionOpts['onQuitChord']>;
49
51
  shouldRouteInputDispatcherKey?: (key: Key) => boolean;
50
52
  hasActiveStatusPopup: () => boolean;
51
53
  hasTerminalModal: () => boolean;
@@ -73,6 +75,7 @@ export function createDashboardChatMainInteractionOpts(
73
75
  }
74
76
  return await deps.routeInputKey(key);
75
77
  },
78
+ onQuitChord: deps.routeQuitChord,
76
79
  onPreKey: async (key) => {
77
80
  if (deps.routeVoiceKey) {
78
81
  const voiceRoute = await deps.routeVoiceKey(key);