elanous 0.2.27 → 0.2.29

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 (700) 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/{Ev2jivDMTSoEc-5rIXdcy → cIpv5nU9AycwYWZI9H589}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{ab4d57c2.e90bc2cb31949045.js → 058a98ba.7eb28d5e6dc03565.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{4565-67e4c620597965c8.js → 1015-9cba22a5a4554797.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +8 -0
  9. package/apps/pwa/out/_next/static/chunks/{1516.83dd2c1b86b4e507.js → 1142.65d002789ab3af7d.js} +2 -2
  10. package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +34 -0
  12. package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1516.dfaceff3fd2d0e0d.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +286 -0
  16. package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +24 -0
  17. package/apps/pwa/out/_next/static/chunks/1782-59db1b5aa06df38a.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{1743.563d3168e95825ef.js → 1852.7f7b53991fcb99ef.js} +2 -2
  19. package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +36 -0
  22. package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +64 -0
  24. package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{65ebff95.081daeff622d238e.js → 285adb1a.5654e605dddf86d2.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +115 -0
  31. package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/3160-95c96f4d2a21dd26.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +90 -0
  36. package/apps/pwa/out/_next/static/chunks/328bb3ab-6628a1114fe3fb3b.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{9917-9e26abc5f7772735.js → 3396-97b97928c49190c9.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/{6196.34d6b229079e9e28.js → 3403.7199205e65124486.js} +1 -1
  40. package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/419.736c0d6f426249a7.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{6def8a8e.c81f9ca41028eccf.js → 425cfc4d.fb91158e3971c39f.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/{16e57f67.3ea19e893461e611.js → 46bd8bea.2f4b4099172fcdb7.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/{5081.a240b63fad28663a.js → 4759.1f76713aefb87db5.js} +1 -1
  51. package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +94 -0
  54. package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +62 -0
  60. package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +27 -0
  63. package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +104 -0
  64. package/apps/pwa/out/_next/static/chunks/{9974.e77b4ff4884557b3.js → 5591.a35e7a217734a8b9.js} +2 -2
  65. package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +93 -0
  66. package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/{5492-e05e26a033ba80d2.js → 6013-2f769370d8b4c2c6.js} +3 -3
  69. package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +24 -0
  70. package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +2 -0
  72. package/apps/pwa/out/_next/static/chunks/{5408.377c8c543635b81f.js → 6534.1ab00f370db7b105.js} +1 -1
  73. package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +148 -0
  74. package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +149 -0
  75. package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +79 -0
  77. package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/{8578.dff22d988cc2b106.js → 6767.1fcfc9b8be83975f.js} +16 -16
  79. package/apps/pwa/out/_next/static/chunks/6776.06ff1e3b464cc607.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/{9311.24c8f5ea793253dd.js → 6853.cc5174a9dee59593.js} +1 -1
  81. package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +287 -0
  86. package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/{94.4cfed21c0b781a06.js → 7375.050ea0d72968e49f.js} +16 -16
  92. package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +77 -0
  94. package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +74 -0
  97. package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7725-4f83d5541fbdb81b.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8332.6f0f49df772e163b.js +23 -0
  102. package/apps/pwa/out/_next/static/chunks/{7483.ba01c6c209b81bba.js → 8398.73a19b39715eda04.js} +1 -1
  103. package/apps/pwa/out/_next/static/chunks/{2846.d6a433b8663819a5.js → 8471.8d2a8c74f09c36ff.js} +3 -3
  104. package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +226 -0
  106. package/apps/pwa/out/_next/static/chunks/{5785-ea8d2c633b6688e3.js → 8767-2f6a634f5abeaa01.js} +1 -1
  107. package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +32 -0
  109. package/apps/pwa/out/_next/static/chunks/8795.32573a185af18c7b.js +41 -0
  110. package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{4593.10f5b9bd702d4a6c.js → 9143.ff14585db1d275ff.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{4204.a409ab6250c0f6a8.js → 9907.49be0fcadaf214b5.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{973cbf1b.3bbcf2b41548eca7.js → a435ad95.577add051b4facb2.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-a5635eba0d73b84e.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/{page-ff27902d0b11ef4f.js → page-8aaa6dedc4c10dfb.js} +1 -1
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/{page-25a302273b054fd7.js → page-33bf667a5fb297bf.js} +1 -1
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-29900ed0011b2c83.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/{page-87b88f551f421d8b.js → page-9eb56166774eb256.js} +1 -1
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9f92737b8766009a.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{f4dfbfc0.a69fb12f854882aa.js → bc324b7c.02a09dd93f6a399b.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +122 -0
  177. package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +1 -0
  183. package/apps/pwa/out/approvals/index.html +1 -1
  184. package/apps/pwa/out/approvals/index.txt +22 -22
  185. package/apps/pwa/out/autopilot/index.html +1 -1
  186. package/apps/pwa/out/autopilot/index.txt +22 -22
  187. package/apps/pwa/out/board/index.html +1 -1
  188. package/apps/pwa/out/board/index.txt +22 -22
  189. package/apps/pwa/out/botlab/index.html +1 -1
  190. package/apps/pwa/out/botlab/index.txt +21 -21
  191. package/apps/pwa/out/bots/index.html +1 -1
  192. package/apps/pwa/out/bots/index.txt +21 -21
  193. package/apps/pwa/out/ceo/index.html +1 -1
  194. package/apps/pwa/out/ceo/index.txt +22 -22
  195. package/apps/pwa/out/chat/index.html +1 -1
  196. package/apps/pwa/out/chat/index.txt +21 -21
  197. package/apps/pwa/out/consult/index.html +1 -1
  198. package/apps/pwa/out/consult/index.txt +22 -22
  199. package/apps/pwa/out/control/index.html +1 -1
  200. package/apps/pwa/out/control/index.txt +22 -22
  201. package/apps/pwa/out/decisions/index.html +1 -1
  202. package/apps/pwa/out/decisions/index.txt +21 -21
  203. package/apps/pwa/out/design-check/index.html +1 -1
  204. package/apps/pwa/out/design-check/index.txt +22 -22
  205. package/apps/pwa/out/editor/index.html +1 -1
  206. package/apps/pwa/out/editor/index.txt +22 -22
  207. package/apps/pwa/out/exec/index.html +1 -1
  208. package/apps/pwa/out/exec/index.txt +22 -22
  209. package/apps/pwa/out/field/index.html +1 -1
  210. package/apps/pwa/out/field/index.txt +22 -22
  211. package/apps/pwa/out/healthz +1 -1
  212. package/apps/pwa/out/index.html +1 -1
  213. package/apps/pwa/out/index.txt +21 -21
  214. package/apps/pwa/out/inside/index.html +1 -1
  215. package/apps/pwa/out/inside/index.txt +21 -21
  216. package/apps/pwa/out/intake/index.html +1 -1
  217. package/apps/pwa/out/intake/index.txt +22 -22
  218. package/apps/pwa/out/live/index.html +1 -1
  219. package/apps/pwa/out/live/index.txt +22 -22
  220. package/apps/pwa/out/live-run/index.html +1 -1
  221. package/apps/pwa/out/live-run/index.txt +22 -22
  222. package/apps/pwa/out/loops/index.html +1 -1
  223. package/apps/pwa/out/loops/index.txt +21 -21
  224. package/apps/pwa/out/market/index.html +1 -1
  225. package/apps/pwa/out/market/index.txt +21 -21
  226. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  227. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  228. package/apps/pwa/out/morning/index.html +1 -1
  229. package/apps/pwa/out/morning/index.txt +22 -22
  230. package/apps/pwa/out/observatory/index.html +1 -1
  231. package/apps/pwa/out/observatory/index.txt +22 -22
  232. package/apps/pwa/out/ops/checklist/index.html +1 -1
  233. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  234. package/apps/pwa/out/ops/release/index.html +1 -1
  235. package/apps/pwa/out/ops/release/index.txt +21 -21
  236. package/apps/pwa/out/ops/seats/index.html +1 -1
  237. package/apps/pwa/out/ops/seats/index.txt +21 -21
  238. package/apps/pwa/out/outputs/index.html +1 -1
  239. package/apps/pwa/out/outputs/index.txt +21 -21
  240. package/apps/pwa/out/reflection/index.html +1 -1
  241. package/apps/pwa/out/reflection/index.txt +22 -22
  242. package/apps/pwa/out/scheduler/index.html +1 -1
  243. package/apps/pwa/out/scheduler/index.txt +22 -22
  244. package/apps/pwa/out/sessions/index.html +1 -1
  245. package/apps/pwa/out/sessions/index.txt +21 -21
  246. package/apps/pwa/out/settings/devices/index.html +1 -1
  247. package/apps/pwa/out/settings/devices/index.txt +22 -22
  248. package/apps/pwa/out/settings/index.html +1 -1
  249. package/apps/pwa/out/settings/index.txt +22 -22
  250. package/apps/pwa/out/setup/done/index.html +1 -1
  251. package/apps/pwa/out/setup/done/index.txt +22 -22
  252. package/apps/pwa/out/setup/index.html +1 -1
  253. package/apps/pwa/out/setup/index.txt +22 -22
  254. package/apps/pwa/out/share/index.html +1 -1
  255. package/apps/pwa/out/share/index.txt +22 -22
  256. package/apps/pwa/out/showroom/index.html +1 -1
  257. package/apps/pwa/out/showroom/index.txt +21 -21
  258. package/apps/pwa/out/tasks/index.html +1 -1
  259. package/apps/pwa/out/tasks/index.txt +22 -22
  260. package/apps/pwa/out/term/index.html +1 -1
  261. package/apps/pwa/out/term/index.txt +22 -22
  262. package/apps/pwa/out/today/index.html +1 -1
  263. package/apps/pwa/out/today/index.txt +22 -22
  264. package/apps/pwa/out/trace/index.html +1 -1
  265. package/apps/pwa/out/trace/index.txt +22 -22
  266. package/apps/pwa/out/vault/index.html +1 -1
  267. package/apps/pwa/out/vault/index.txt +22 -22
  268. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  269. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  270. package/apps/pwa/out/workflows/index.html +1 -1
  271. package/apps/pwa/out/workflows/index.txt +22 -22
  272. package/apps/pwa/out/workspace/index.html +1 -1
  273. package/apps/pwa/out/workspace/index.txt +22 -22
  274. package/apps/pwa/out/worktrees/index.html +1 -1
  275. package/apps/pwa/out/worktrees/index.txt +22 -22
  276. package/graphs/implement-loop.yaml +38 -1
  277. package/graphs/release/release-loop.yaml +6 -2
  278. package/graphs/steward/recipes.yaml +6 -0
  279. package/graphs/steward/release-day.yaml +23 -0
  280. package/graphs/steward/steward.yaml +9 -1
  281. package/graphs/work/code-pr.yaml +23 -0
  282. package/package.json +1 -1
  283. package/plugins/agent-team/agents/research.md +1 -0
  284. package/scripts/browser-observe-cycle.ts +76 -2
  285. package/scripts/ci-typecheck-changed.ts +53 -19
  286. package/scripts/coord-channel-watch.sh +26 -6
  287. package/scripts/coord-role-pack.ts +143 -0
  288. package/scripts/detect-test-interference.ts +31 -1
  289. package/scripts/lib/morning-report-options.ts +41 -0
  290. package/scripts/pr-land-extra-remote-gates.ts +49 -0
  291. package/scripts/release-loop/docs-node.ts +51 -22
  292. package/scripts/release-loop/gate-batch-safe.ts +23 -0
  293. package/scripts/release-loop/gate-history.ts +422 -0
  294. package/scripts/release-loop/gate-node.ts +336 -39
  295. package/scripts/release-loop/gate-triage-node.ts +190 -0
  296. package/scripts/release-loop/node-verdict.ts +3 -1
  297. package/scripts/release-loop/publish-node.ts +3 -0
  298. package/scripts/release-loop/spawn-lane.ts +68 -0
  299. package/scripts/release-loop/tui-node-checks.ts +28 -2
  300. package/scripts/release-loop/version-node.ts +62 -4
  301. package/scripts/skills/public-check.ts +5 -2
  302. package/scripts/test-deterministic.ts +549 -37
  303. package/scripts/usage-rollup.ts +11 -3
  304. package/scripts/ux-sim.ts +7 -1
  305. package/scripts/verify-kpack6-live.ts +230 -0
  306. package/src/acp/codex-plugins.ts +17 -0
  307. package/src/acp/core-turn-bridge.ts +98 -22
  308. package/src/acp/elanous-extensions.ts +2 -0
  309. package/src/acp/server.ts +2 -0
  310. package/src/agent/ref-grounding.ts +18 -0
  311. package/src/agent/task-notification.ts +2 -1
  312. package/src/agent-mission/in-agent-plugin.ts +8 -3
  313. package/src/agent-substrate/pr-reviewer.ts +29 -21
  314. package/src/agent-substrate/self-review-cli.ts +34 -10
  315. package/src/briefing/brief-items.ts +151 -35
  316. package/src/budget/llm-cost.ts +25 -2
  317. package/src/budget/pty-usage-reemit.ts +7 -0
  318. package/src/budget/run-usage-rollup.ts +9 -0
  319. package/src/budget/usage-daily-store.ts +98 -0
  320. package/src/budget/usage-outcomes.ts +32 -0
  321. package/src/capture/tui-self-report.ts +22 -4
  322. package/src/chat/index.ts +31 -10
  323. package/src/chat/pickers/modal-runtime.ts +1 -0
  324. package/src/chat/pickers/modals.ts +3 -1
  325. package/src/chat/turn-typeahead.ts +123 -16
  326. package/src/claims/claims-ledger.ts +23 -0
  327. package/src/claims/claims-render.ts +22 -2
  328. package/src/cli/brief-cli.ts +131 -10
  329. package/src/cli/claims-cli.ts +24 -4
  330. package/src/cli/dashboard-name-flag.ts +48 -0
  331. package/src/cli/doctor-cli.ts +80 -0
  332. package/src/cli/log-event-names.ts +12 -0
  333. package/src/cli/msg-cli.ts +210 -11
  334. package/src/cli/plugin-cli.ts +11 -3
  335. package/src/cli/pr-cli.ts +443 -104
  336. package/src/cli/pr-land-heavy-remote.ts +233 -0
  337. package/src/cli/pr-land-overlap-evidence.ts +104 -5
  338. package/src/cli/pr-land-refusal.ts +20 -0
  339. package/src/cli/pty-takeover-cli.ts +125 -16
  340. package/src/cli/release-cli.ts +46 -2
  341. package/src/cli/remote-resolve.ts +2 -1
  342. package/src/cli/rfc-cli.ts +24 -0
  343. package/src/cli/seat-cli.ts +26 -16
  344. package/src/cli/tailscale-serve.ts +5 -8
  345. package/src/cli/tasks-cli.ts +400 -27
  346. package/src/cli/usage-cli.ts +155 -16
  347. package/src/cli/usage-daily-cli.ts +84 -0
  348. package/src/context-bus/context-now.ts +82 -5
  349. package/src/core-turn/auth-rejected-notice.ts +41 -0
  350. package/src/core-turn/run-core-turn.ts +13 -2
  351. package/src/core-turn/run-goal-loop.ts +17 -1
  352. package/src/core-turn/short-question.ts +45 -12
  353. package/src/core-turn/types.ts +7 -0
  354. package/src/dashboard/acp-active-model.ts +40 -0
  355. package/src/dashboard/auto-compact-runtime.ts +2 -0
  356. package/src/dashboard/boot-banner.ts +80 -0
  357. package/src/dashboard/dashboard-status-lines.ts +11 -0
  358. package/src/dashboard/detail-viewer-runtime.ts +15 -2
  359. package/src/dashboard/event-loop-stall-monitor.ts +4 -0
  360. package/src/dashboard/first-screen-band.ts +63 -13
  361. package/src/dashboard/goal-loop-thinking.ts +16 -0
  362. package/src/dashboard/hitl-boot.ts +9 -4
  363. package/src/dashboard/index.ts +235 -389
  364. package/src/dashboard/input/chat-main-entry-runtime.ts +2 -0
  365. package/src/dashboard/input/chat-main-log-actions.ts +4 -0
  366. package/src/dashboard/input/chat-main-log-command.ts +12 -1
  367. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +172 -3
  368. package/src/dashboard/input/chat-main-session.ts +6 -2
  369. package/src/dashboard/input/chat-main-slash-command.ts +7 -0
  370. package/src/dashboard/input/chat-main-turn.ts +2 -1
  371. package/src/dashboard/input/compact-prepass-recovery.ts +97 -0
  372. package/src/dashboard/input/dashboard-chord-actions.ts +10 -1
  373. package/src/dashboard/input/dashboard-chord-runtime.ts +2 -0
  374. package/src/dashboard/input/external-input-host.ts +45 -0
  375. package/src/dashboard/input/log-fold-binding.ts +18 -0
  376. package/src/dashboard/input/mouse-wiring.ts +17 -4
  377. package/src/dashboard/input/turn-steer-bridge.ts +94 -0
  378. package/src/dashboard/log-click-runtime.ts +5 -3
  379. package/src/dashboard/running-build-status.ts +74 -0
  380. package/src/dashboard/seat-boot-preamble.ts +113 -0
  381. package/src/dashboard/seat-local-instructions.ts +305 -0
  382. package/src/dashboard/skill-detection-runtime.ts +24 -4
  383. package/src/dashboard/slash-runtime/dashboard-handlers.ts +100 -28
  384. package/src/dashboard/slash-runtime/model-choices.ts +35 -0
  385. package/src/dashboard/term-slash-runtime.ts +15 -0
  386. package/src/dashboard/turn-preamble.ts +30 -2
  387. package/src/dashboard/turn-session-layers.ts +176 -0
  388. package/src/dashboard/turn-stream-formatter.ts +14 -6
  389. package/src/dashboard/turn-stream-presentation-applier.ts +8 -0
  390. package/src/domains/morning-report.ts +3 -1
  391. package/src/domains/release-tool.ts +8 -9
  392. package/src/domains/surface-events.ts +4 -1
  393. package/src/domains/watch-default-scheduler.ts +8 -9
  394. package/src/fold-stack.ts +24 -1
  395. package/src/git-fs/dirty.ts +32 -4
  396. package/src/git-fs/index.ts +43 -1
  397. package/src/github/pr-labels.ts +10 -4
  398. package/src/graph-runner/runner.ts +102 -14
  399. package/src/harness/harness-clean.ts +21 -3
  400. package/src/harness/harness-cli-command.ts +22 -6
  401. package/src/harness/harness-gc.ts +32 -5
  402. package/src/harness/harness-pod-dispatch.ts +11 -4
  403. package/src/hq/seats.ts +17 -3
  404. package/src/index.ts +48 -6
  405. package/src/input/external-input-queue.ts +219 -0
  406. package/src/intelligence-map/model-bench-scores.ts +102 -0
  407. package/src/interactive-terminal-modal.ts +13 -0
  408. package/src/llm/route-decision.ts +25 -0
  409. package/src/llm-stream-retry-display.ts +59 -0
  410. package/src/llm.ts +253 -55
  411. package/src/log-entry.ts +3 -3
  412. package/src/log-pane/search.ts +29 -4
  413. package/src/loops/agent-reply.ts +256 -0
  414. package/src/loops/budget.ts +37 -7
  415. package/src/loops/loop-cli.ts +3 -2
  416. package/src/loops/msg-address.ts +57 -0
  417. package/src/loops/msg-wake.ts +282 -0
  418. package/src/loops/orchestrator/inbox.ts +130 -0
  419. package/src/loops/orchestrator/resync-shadow.ts +100 -12
  420. package/src/loops/orchestrator/tick.ts +94 -3
  421. package/src/loops/registry.ts +42 -4
  422. package/src/maturity/feature-maturity.ts +1 -1
  423. package/src/memory.ts +20 -5
  424. package/src/msg/msg-sse-server.ts +141 -0
  425. package/src/msg/msg-store.ts +84 -14
  426. package/src/native-tool-catalog.ts +125 -0
  427. package/src/nexus/api/http-server.ts +5 -0
  428. package/src/nexus/api/ops-api.ts +2 -0
  429. package/src/nexus/api/project-autopsy.ts +127 -0
  430. package/src/nexus/api/terminals.ts +3 -0
  431. package/src/nexus/api/workflow-approvals.ts +2 -0
  432. package/src/nexus/onboarding/first-boot-wizard.ts +56 -2
  433. package/src/oauth/codex-account-store.ts +15 -3
  434. package/src/oauth/codex-billing-route.ts +31 -0
  435. package/src/ops/overview-collect.ts +19 -2
  436. package/src/panes/log-pane.ts +67 -8
  437. package/src/patents/ledger.ts +128 -0
  438. package/src/persona/presets.ts +44 -0
  439. package/src/plugins/install/market-fetch.ts +32 -1
  440. package/src/plugins/maker/wizard-generate.ts +6 -4
  441. package/src/pod-lease/admission.ts +116 -41
  442. package/src/preview/terminal.ts +14 -1
  443. package/src/prompt-cache/types.ts +2 -0
  444. package/src/prompt-enhance/enhance.ts +24 -8
  445. package/src/prompt-library/universal-preamble.ts +273 -56
  446. package/src/pty-shell/pty-control-ipc.ts +4 -1
  447. package/src/pty-shell/pty-manifest.ts +77 -5
  448. package/src/pty-shell/registry.ts +19 -2
  449. package/src/pty-shell/tui-run-state.ts +253 -0
  450. package/src/release-loop/checklist.ts +11 -0
  451. package/src/release-loop/light-rc.ts +28 -3
  452. package/src/release-loop/merged-pr-checklist.ts +24 -5
  453. package/src/release-loop/rehearsal.ts +1 -1
  454. package/src/release-loop/rubric.ts +70 -0
  455. package/src/render.ts +5 -1
  456. package/src/rfc-registry/registry.ts +88 -0
  457. package/src/seat-dispatch/seat-request-ledger.ts +4 -0
  458. package/src/seat-loop/knowhow-lint.ts +233 -0
  459. package/src/seat-loop/seat-pack.ts +16 -4
  460. package/src/seat-loop/seat-report.ts +42 -2
  461. package/src/seat-loop/traffic-signal.ts +7 -0
  462. package/src/self-dev/ask-launch-flow.ts +48 -8
  463. package/src/self-dev/ask-path-candidates.ts +69 -14
  464. package/src/self-dev/decompose-proposal.ts +43 -1
  465. package/src/self-dev/graph-journey-nodes.ts +2 -0
  466. package/src/self-dev/launch-preflight-text.ts +5 -1
  467. package/src/self-dev/launch-preflight.ts +143 -10
  468. package/src/self-dev/run-supervisor.ts +71 -5
  469. package/src/self-dev/shard-aggregate.ts +2 -0
  470. package/src/self-dev/shard-run.ts +23 -2
  471. package/src/self-health/signatures.ts +132 -0
  472. package/src/self-implement/doctor-visit.ts +118 -0
  473. package/src/self-implement/gate-cli.ts +17 -4
  474. package/src/self-implement/goal-author-decompose.ts +80 -16
  475. package/src/self-implement/goal-author.ts +116 -73
  476. package/src/self-implement/goal-authoring-grounding.ts +1 -1
  477. package/src/self-implement/goal-file-name.ts +65 -0
  478. package/src/self-implement/goal-new-paths.ts +4 -5
  479. package/src/self-implement/graph-authority.ts +17 -3
  480. package/src/self-implement/graph-yaml.ts +15 -7
  481. package/src/self-implement/ground-goal.ts +2 -1
  482. package/src/self-implement/headless-elanous-driver.ts +16 -1
  483. package/src/self-implement/host-regate.ts +58 -9
  484. package/src/self-implement/orchestrator.ts +3 -10
  485. package/src/self-implement/review-mustfix-class.ts +115 -0
  486. package/src/self-implement/rework-policy.ts +80 -2
  487. package/src/self-implement/run-ledger.ts +111 -7
  488. package/src/self-implement/running-runs.ts +10 -6
  489. package/src/self-implement/self-implement-runtime.ts +32 -0
  490. package/src/self-implement/speed-claims.ts +145 -6
  491. package/src/session/pending-input.ts +62 -11
  492. package/src/session-runtime/index.ts +7 -1
  493. package/src/skills/tools/ops-ledger.ts +707 -0
  494. package/src/skills/tools/persistent-grounding.ts +103 -8
  495. package/src/skills/tools/shell.ts +196 -2
  496. package/src/status/bar.ts +32 -2
  497. package/src/status/status-provider-info.ts +58 -0
  498. package/src/steward/rejudge-tick.ts +12 -1
  499. package/src/steward/release-day.ts +158 -0
  500. package/src/steward/resync-tick.ts +123 -0
  501. package/src/task-agent/actions.ts +1 -0
  502. package/src/task-agent/adopt-pr.ts +140 -0
  503. package/src/task-agent/board.ts +11 -1
  504. package/src/task-agent/card-evidence.ts +37 -5
  505. package/src/task-agent/cover.ts +84 -17
  506. package/src/task-agent/failure-notify.ts +61 -0
  507. package/src/task-agent/green-sweep.ts +170 -0
  508. package/src/task-agent/land-worktree.ts +52 -5
  509. package/src/task-agent/live-move-history.ts +1 -0
  510. package/src/task-agent/live-moves.ts +43 -12
  511. package/src/task-agent/parent-host.ts +1 -1
  512. package/src/task-agent/postland-card.ts +139 -0
  513. package/src/task-agent/rejudge-on-head.ts +109 -7
  514. package/src/task-agent/remote-rejudge-bind.ts +91 -0
  515. package/src/task-agent/repair-branch-cas.ts +182 -0
  516. package/src/task-agent/repair-cycle.ts +288 -0
  517. package/src/task-agent/repair-next-move.ts +31 -0
  518. package/src/task-agent/repair-review.ts +24 -0
  519. package/src/task-agent/repair-worker.ts +87 -0
  520. package/src/task-agent/review-result-capture.ts +2 -1
  521. package/src/task-agent/shadow.ts +13 -7
  522. package/src/task-agent/task-hand.ts +115 -6
  523. package/src/task-orchestrator/surfaces/kubectl-transient-retry.ts +51 -0
  524. package/src/task-orchestrator/surfaces/pod-command-job.ts +63 -7
  525. package/src/task-orchestrator/surfaces/pod-install-slots.ts +6 -11
  526. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +76 -0
  527. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +96 -0
  528. package/src/task-orchestrator/surfaces/self-implement-pod.ts +175 -43
  529. package/src/telegram.ts +30 -1
  530. package/src/terminal/session-registry.ts +6 -0
  531. package/src/thinking-line.ts +12 -3
  532. package/src/tool-runtime/index.ts +4 -0
  533. package/src/tool-runtime/ops-ledger-runtimes.ts +84 -0
  534. package/src/tool-runtime/ref-consult-runtime.ts +17 -2
  535. package/src/tool-runtime/run-shell-runtime.ts +4 -1
  536. package/src/tool-runtime/self-cognition-runtimes.ts +5 -1
  537. package/src/tui.ts +5 -0
  538. package/src/user-config.ts +62 -7
  539. package/src/ux-sim/fake-llm.ts +29 -0
  540. package/src/ux-sim/fault-sqlite-busy.ts +50 -0
  541. package/src/ux-sim/in-process-cli.ts +175 -0
  542. package/src/version/packed-revision.json +1 -1
  543. package/apps/pwa/out/_next/static/chunks/1027.a0f04663d24c2779.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/1038.676007ae505822e7.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/1113.a37eadf7f740d955.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/112-fa7c526c20ce1405.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/1144.5fa1fa1d48dbcd12.js +0 -36
  548. package/apps/pwa/out/_next/static/chunks/1146.80d15ea7c6e6ee95.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/1157.f08bf2b70915e176.js +0 -148
  550. package/apps/pwa/out/_next/static/chunks/119b405e.8fdd0e44d1ff37aa.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/1296.04560d98e73fbf51.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/1314-f604ba013ec535b0.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/1454-a9c338f5bb556f42.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/1464.f3209af0d8ae4ff2.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/1729-d73dd25e564679d4.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/1843.5924c24295243261.js +0 -27
  557. package/apps/pwa/out/_next/static/chunks/1987.e28149724b92918b.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/2066-5ca18ffa5a4be68b.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/2240.d10a66695155fd93.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/2391.e2cbc98d4abbb41a.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/2528.3868070ef1be69f9.js +0 -24
  562. package/apps/pwa/out/_next/static/chunks/2566-734cb83bbd405886.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/2697.76ca2ac3efef6f3b.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/275.0e6bad414729bfa0.js +0 -32
  565. package/apps/pwa/out/_next/static/chunks/2803-33bdae771855a8d1.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/3143.257997a5f1ed79df.js +0 -34
  567. package/apps/pwa/out/_next/static/chunks/3259-86f3be56e43eaf6a.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/3280-e177c33bfbdcfb0a.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/3294-2b6a6d45a46a6c1c.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/3309.364573ceedbdfd5f.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/3522.758840fc5e7fe630.js +0 -287
  572. package/apps/pwa/out/_next/static/chunks/3525-a7c989c1a661e880.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/3694.b1a66387756458c0.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/370.124f9e678a76fc01.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/3797-9643105335e660fe.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/4084.15ecaf4240bd9e77.js +0 -286
  577. package/apps/pwa/out/_next/static/chunks/4089-b3382b8843114eee.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/4293.928a8d573c16aab7.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/4402.f9238a3b18a7bd43.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/4490-9b090b0f9427f902.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/4548.13502d0ca3b4f862.js +0 -8
  582. package/apps/pwa/out/_next/static/chunks/4599-548bc96cda44a5a7.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/4625.206574e33a9e7ae8.js +0 -104
  584. package/apps/pwa/out/_next/static/chunks/4862-392c9a71f0d8dfb4.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/5054.2906d1b02542edc5.js +0 -149
  586. package/apps/pwa/out/_next/static/chunks/5102-c822bbbee5a022a4.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/5194-8c93f2e7e4b6f717.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/5305-bacd7eca0b9a5848.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/5311.9071ee3f44fd7ff5.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/5369.9f34353442daa421.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/589-49d730cb8138b397.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/5904-264a6412ae3c9028.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/5980.728531d5c566535c.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/599-a914cc0468f56143.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/6011.f525002e21bef0ac.js +0 -23
  596. package/apps/pwa/out/_next/static/chunks/6132.4381ab93683f1acf.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/6149.2e698635e454d8f6.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/6356-0afafc4230cf9767.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/6406.64756073f7df35b8.js +0 -77
  600. package/apps/pwa/out/_next/static/chunks/6479-16e62aedafa0e310.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/6599.b5246b46a2453329.js +0 -64
  602. package/apps/pwa/out/_next/static/chunks/6610.5c26eec011565acb.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/666.37d18474edc1c552.js +0 -2
  604. package/apps/pwa/out/_next/static/chunks/6904.a0b5b1ed4f2d2c20.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/7247-1f4aba94aba50d9f.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/7274-e71a7c5b7760cd02.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/7290.1fcaeef3adb5d0d4.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/7477-2c64e42760f82f33.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/7505-47002b76ff1aef6c.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/7600-11884ca4da68e5d9.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/7607.40d8bb3689697ccb.js +0 -62
  612. package/apps/pwa/out/_next/static/chunks/7752.5cbdd0b433c54af9.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/7763.f51fcc19ca1414ec.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/7785.846140c859b1adf6.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/7807-a0fdac6393e0bf36.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/7837-20a63b4b7e9342b1.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/800.7815414cf280545d.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/8085-1e5fce59500a2cc2.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/8100.415f2105faa63e97.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/8290.701aa42ed13aa767.js +0 -226
  621. package/apps/pwa/out/_next/static/chunks/83a80514-b897b64df43ce108.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/8444.d9c74214a3145a43.js +0 -93
  623. package/apps/pwa/out/_next/static/chunks/8569.98c915534928c7f9.js +0 -24
  624. package/apps/pwa/out/_next/static/chunks/8591.b1c7f876e5ec7cfb.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/8715-f63756021d3ab989.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/8879.776c2ec7732aa114.js +0 -115
  627. package/apps/pwa/out/_next/static/chunks/8881.ddca15b3c82c490c.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/8946.5da5c87f32a2e1a8.js +0 -41
  629. package/apps/pwa/out/_next/static/chunks/9117.080b9b75be90e14d.js +0 -74
  630. package/apps/pwa/out/_next/static/chunks/9167.f3ecb28f367d6e69.js +0 -94
  631. package/apps/pwa/out/_next/static/chunks/9224.66095370ee28c93b.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/9238-0682b013c83d6449.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/9449.d3ed795da4befb1c.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/949.1e7d45ccb71580aa.js +0 -90
  635. package/apps/pwa/out/_next/static/chunks/9638-d268329f2c6f4f8d.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/9842-d6644eb53d3dc6bf.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/9863.94ca3263e760696e.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/9938.b23e4d4dfa0114cd.js +0 -79
  639. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d9babd8795f396a5.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/app/approvals/page-a1ce306364f08da9.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-07110da72c45e68f.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/app/board/page-d2d76d4a7eae91bd.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/app/botlab/page-30007380f2e2a3c1.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/app/bots/page-e5a9302c105725a3.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/app/ceo/page-b93c04b5311c97ec.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/app/chat/page-718a49e86bf25f9c.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/app/consult/page-20662900d6b4b455.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/app/control/page-f707a509515ac50c.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/decisions/page-6a16a48d1aa6e91f.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/design-check/page-fcb06e305f515527.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/editor/page-6acf5ec4e6c6d1af.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/exec/page-39f82acf619cca23.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/field/page-7c2c8f81b185f9c0.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/healthz/route-d9babd8795f396a5.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/inside/page-ae7aff07e32676bb.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/intake/page-482c60c1bc540d0a.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/layout-7cb996c1aa08b6f5.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/live/page-623e08fe4477d606.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/live-run/page-db460cd8aecb8490.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/market/page-8397a5c6ca569bf4.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1917ea87ea71ab6b.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/not-found-670510eda8b9443f.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/observatory/page-d73c3f1e00d93986.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-65caacf54389081e.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-4bb7556e2e97a750.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-77e04b4f8762c666.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/outputs/page-15c0a4095baddfba.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/page-4eb96fc7241c2456.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/reflection/page-63e272a4cd3b6634.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-0d64ff212dc55d03.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/sessions/page-7f096248993fc2d4.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-e47fc72049149a38.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/settings/page-f7d808e31e005895.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-5c2b24b5496dad73.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/setup/layout-d9babd8795f396a5.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/setup/page-76cdb531668b5191.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/share/page-e2b63345bba1a11f.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/showroom/page-d376e0c83edc041a.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d6db55fe2c04d128.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/today/page-dab163b338e3b966.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/trace/page-08019efef111ed2e.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/vault/page-0260ffc7eda50db1.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-980ce6fe36ad95eb.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/workflows/page-99c4e6c7345a9156.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/workspace/page-0ab42e0f05823013.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-ad9220422d20ba33.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/dcf24383-2f82e35f2d827393.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/e117f801.e92bf10242653497.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/e87d89b9.2e71c0ae475d28a1.js +0 -122
  690. package/apps/pwa/out/_next/static/chunks/framework-bf135b997155e90e.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/main-5571537543bea91c.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/main-app-25c51c7df7f3a442.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/pages/_app-e3b2c1f5d82abd65.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/pages/_error-083f2e23e9bc3641.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/webpack-e94d22b7a028217b.js +0 -1
  696. package/src/dashboard/bench-slash-runtime.ts +0 -40
  697. package/src/dashboard/input/search-modal-router.ts +0 -9
  698. package/src/dashboard/modals/pane-key-router.ts +0 -27
  699. package/src/dashboard/view-slash-runtime.ts +0 -48
  700. /package/apps/pwa/out/_next/static/{Ev2jivDMTSoEc-5rIXdcy → cIpv5nU9AycwYWZI9H589}/_ssgManifest.js +0 -0
@@ -6,10 +6,12 @@
6
6
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
7
7
  import { join } from 'path';
8
8
  import { fileURLToPath } from 'node:url';
9
+ import { createRunningBuildStatus } from './running-build-status.js';
10
+ import { reportTuiTurn } from '../pty-shell/tui-run-state.js';
9
11
  import { createStaleInstallCheck, formatStaleInstallNotice, readCurrentInstalledCommit, readDashboardBootCommit, STALE_INSTALL_CHECK_INTERVAL_MS, versionedDashboardInstallDir } from './stale-install-check.js';
10
12
  import { spawn, spawnSync } from 'node:child_process';
11
13
  import { $ } from 'bun';
12
- import { LOCAL_SKILLS_DIR, SERVICE_NAMES, DATA_DIR, OBSIDIAN_VAULT } from '../config.js';
14
+ import { LOCAL_SKILLS_DIR, DATA_DIR, OBSIDIAN_VAULT } from '../config.js';
13
15
  import { dispatchDashboardSessionRuntimeTool } from './session-runtime-dispatch.js';
14
16
  import { nextChatScrollOffset } from '../chat/log-scroll-key.js';
15
17
  import { suggestProjectForFolder } from '../project/project-store.js';
@@ -160,8 +162,8 @@ function loadLastSelection(): LastSelection | null {
160
162
  }
161
163
  import { getLocalSkills, executeSync } from '../sync.js';
162
164
  import { computeDiff } from '../smart.js';
163
- import { analyzeDiff, summarizeDiff, isAnalyzerAvailable } from '../grok.js';
164
- import { C, ICONS, ansi, initTui, closeTui, setExitNotice, readKey, setKeyTracer, render, resetRenderCache, termSize, pad, stripAnsi, timeSince, hLine, showHelp, invalidateRenderCacheRow, wrapAnsiByWidth, injectKey } from '../tui.js';
165
+ import { summarizeDiff, isAnalyzerAvailable } from '../grok.js';
166
+ import { C, ICONS, ansi, initTui, closeTui, setExitNotice, readKey, setKeyTracer, render, termSize, pad, stripAnsi, hLine, showHelp, invalidateRenderCacheRow, wrapAnsiByWidth, injectKey } from '../tui.js';
165
167
  import { paintCursor, type CursorState } from '../display/cursor-state.js';
166
168
  import type { CursorDecision } from '../display/cursor-owner.js';
167
169
  import type { Key, RenderOptions } from '../tui.js';
@@ -169,7 +171,6 @@ import {
169
171
  createTurnTypeaheadState,
170
172
  applyTurnTypeaheadKey,
171
173
  renderTurnTypeaheadQueueRow,
172
- drainTurnTypeaheadOnce,
173
174
  renderTurnTypeaheadEcho,
174
175
  } from '../chat/turn-typeahead.js';
175
176
  import { dispatchStreamingTurnTypeaheadSubmission } from './input/streaming-turn-typeahead.js';
@@ -180,13 +181,11 @@ import type { CoreTurnDispatchTool } from '../core-turn/index.js';
180
181
  // ACP pair (see `bootDashboardAcpSession`), which internally routes
181
182
  // to streamLLMWithTools via runCoreTurn.
182
183
  import {
183
- startSpinner,
184
184
  createChatState,
185
185
  buildContext,
186
186
  formatResponse,
187
187
  onEscAbort,
188
188
  attachStreamingKeys,
189
- SLASH_COMMANDS,
190
189
  type InputResult,
191
190
  type TextInputExternalSubmitRequest,
192
191
  } from '../chat/index.js';
@@ -198,6 +197,7 @@ import {
198
197
  } from '../chat/hud-segments-wire.js';
199
198
  import { PreviewTerminal } from '../preview/terminal.js';
200
199
  import { startThinking, startPinnedThinking, type ThinkingHandle } from '../thinking-line.js';
200
+ import { goalLoopIterationThinking } from './goal-loop-thinking.js';
201
201
  import { debug, getAmbientSessionId } from '../debug/log.js';
202
202
  import { startEventLoopStallMonitor, thinkingVerbFromFooter } from './event-loop-stall-monitor.js';
203
203
  import { getPushcutClient } from '../pushcut/client.js';
@@ -220,11 +220,6 @@ import {
220
220
  registerAction as inputCoreRegisterAction,
221
221
  addDefaultBinding as inputCoreAddDefaultBinding,
222
222
  initUserBindings as initInputCoreUserBindings,
223
- readAuditTail,
224
- isInputAuditEntry,
225
- formatAuditEntry,
226
- parseDuration as parseAuditDuration,
227
- runRebindCommand,
228
223
  type DispatchContext as InputCoreDispatchContext,
229
224
  type MouseInputEvent as InputCoreMouseInputEvent,
230
225
  type RouteCallbacks as InputCoreRouteCallbacks,
@@ -255,7 +250,6 @@ import { wireInputModeContextBridge } from '../input-core/mode-context-bridge.js
255
250
  import { getDashboardContextKeyService } from './context/keys.js';
256
251
  import {
257
252
  getDashboardContextMenuRegistry,
258
- handleForPill,
259
253
  } from './context-menu/registry.js';
260
254
  import { createTransientOverlayHost } from '../display/transient-overlay-host.js';
261
255
  import { configureThemeIconsGetter } from '../theme/icons.js';
@@ -267,7 +261,6 @@ import {
267
261
  } from '../log-pane/buffer-policy.js';
268
262
  import { publishFocusContextKeysFromService } from './context/focus-bridge.js';
269
263
  import {
270
- modalBlocksBackground,
271
264
  modalParticipatesInViewMode,
272
265
  renderModalStack,
273
266
  topBlockingForegroundModalSurface,
@@ -285,7 +278,6 @@ import {
285
278
  debugWorkbenchIndexForTarget,
286
279
  getDebugCompanionSpec,
287
280
  listDebugCompanionKeys,
288
- resolveDebugCompanionTargets,
289
281
  type DebugWorkbenchPane,
290
282
  } from '../window/debug-window-consumers.js';
291
283
  import {
@@ -295,7 +287,6 @@ import {
295
287
  } from '../window/tablet-workspace-policy.js';
296
288
  import {
297
289
  type PromptFrame,
298
- bottomFixedRowsForPromptFrame,
299
290
  resolvePromptFrame,
300
291
  } from '../display/prompt-frame.js';
301
292
  import { resolveBottomSlotBounds } from '../display/bottom-slot.js';
@@ -341,27 +332,8 @@ import { attachDashboardQuickPassConsumers } from './input/control-signal-consum
341
332
  import { resolveDashboardChatMainSlashCommand } from './input/chat-main-slash-command.js';
342
333
  import { TuiChatPersonaSelection, tuiChatPersonaMessages } from './slash-runtime/chat-persona.js';
343
334
  import { awaitGlobalPersonaLoad } from '../persona/global-registry.js';
344
- import { resolveDashboardChatMainCacheCommand } from './input/chat-main-cache-command.js';
345
- import {
346
- dashboardDeltaHelpLines,
347
- resolveDashboardChatMainDeltaCommand,
348
- } from './input/chat-main-delta-command.js';
349
- import {
350
- DASHBOARD_SETUP_STEPS,
351
- dashboardSetupHelpLines,
352
- resolveDashboardChatMainSetupCommand,
353
- } from './input/chat-main-setup-command.js';
354
335
  import { createDashboardInlineSetupFlow } from './setup-inline.js';
355
- import { resolveDashboardChatMainThemeCommand } from './input/chat-main-theme-command.js';
356
- import { resolveDashboardChatMainLogCommand } from './input/chat-main-log-command.js';
357
336
  import { noProviderReply } from './input/no-provider-reply.js';
358
- import {
359
- dashboardLogHelpLines,
360
- resolveDashboardLogFilterAction,
361
- resolveDashboardLogSearchAction,
362
- resolveDashboardLogSizeAction,
363
- resolveDashboardLogTurnAction,
364
- } from './input/chat-main-log-actions.js';
365
337
  import type { LogTurnSeparatorMode } from './log-turn-separator-mode.js';
366
338
  import { createDashboardChatMainInteractionOpts } from './input/chat-main-interaction-opts.js';
367
339
  import { createDashboardChatMainCompletionOpts } from './input/chat-main-completion-opts.js';
@@ -379,6 +351,7 @@ import {
379
351
  matchDashboardChordAction,
380
352
  } from './input/dashboard-chord-actions.js';
381
353
  import { createDashboardChordRuntime } from './input/dashboard-chord-runtime.js';
354
+ import { registerLogFoldInputBinding } from './input/log-fold-binding.js';
382
355
  import { handleDashboardDisplayKeyRoute } from './input/dashboard-display-key-route.js';
383
356
  import { routeDashboardPriorityKey } from './input/dashboard-priority-key-route.js';
384
357
  import { shouldPassthroughDashboardHostOwnedInputCoreAction } from './input/input-core-host-action.js';
@@ -425,7 +398,6 @@ import {
425
398
  } from './voice-host-boot.js';
426
399
  import {
427
400
  bootDashboardAutoTts,
428
- handleAutoTtsSlash,
429
401
  } from './auto-tts/auto-tts-host-boot.js';
430
402
  import {
431
403
  bootDashboardVoiceChat,
@@ -443,7 +415,6 @@ import {
443
415
  import {
444
416
  resolveLegacyForegroundModalFocusPlan,
445
417
  resolveLegacyForegroundModalDemotionTransition,
446
- resolveLegacyForegroundModalFallbackPane,
447
418
  } from './input/foreground-modal-focus.js';
448
419
  import {
449
420
  resolveDashboardInitialWorkingFocus,
@@ -460,18 +431,10 @@ import { addHint, listHints, removeHint, resetScope } from '../tool-hints/regist
460
431
  import { resetGateCache } from '../tool-hints/gate.js';
461
432
  import { collectSignals, signalsSummary } from '../tool-hints/signals.js';
462
433
  import { resetProbes } from '../tool-hints/probe.js';
463
- import {
464
- addAllowed,
465
- hostOf,
466
- listAllowed,
467
- rateLimitStatus,
468
- removeAllowed,
469
- } from '../tool-hints/api-allowlist.js';
470
434
  import type { HintScope } from '../tool-hints/types.js';
471
- import { listSkillNames, describeSkill } from '../skills/runner.js';
472
435
  import { globalAgentRegistry, type AgentToolCallEvent } from '../agent/registry.js';
473
436
  import { SELF_IMPLEMENT_TOOL_NAMES } from '../boot/daemon-tools/self-implement-names.js';
474
- import { FOLD_LIMITS, type FoldMode } from '../log-entry.js';
437
+ import { type FoldMode } from '../log-entry.js';
475
438
  import { renderToolCallEvent, renderToolResultVariants } from '../chat/tool-render/index.js';
476
439
  import { FoldStack } from '../fold-stack.js';
477
440
  import { getSkillIndex, reloadSkillIndex, applySkillFilter, skillIndexProblems } from '../skills/index.js';
@@ -546,7 +509,11 @@ export function formatEscAbortWaitingTargets(targets: readonly string[]): string
546
509
  export function settleEscAbortPendingLines(lines: string[], fromIndex: number): void {
547
510
  let settled = false;
548
511
  for (let index = fromIndex; index < lines.length;) {
549
- const line = lines[index]!;
512
+ const line = lines[index];
513
+ if (typeof line !== 'string') {
514
+ index += 1;
515
+ continue;
516
+ }
550
517
  const isAbortPending = line.startsWith(' ⏳ 중단 요청됨 — ');
551
518
  const isAbortRepeat = /^ ⏳ ESC 재시도 \d+회 — /.test(line);
552
519
  if (!isAbortPending && !isAbortRepeat) {
@@ -625,37 +592,33 @@ export function getEscAbortRunningCount(
625
592
  return Math.max(1, registeredRunning);
626
593
  }
627
594
  }
628
- import { resetOnboardingMarker } from '../onboarding.js';
595
+ import { needsOnboarding, resetOnboardingMarker } from '../onboarding.js';
629
596
  import {
630
597
  getUserConfig, reloadUserConfig, saveUserConfig,
631
598
  rotateNextProvider, jumpToRotationEntry, rotationEntryLabel, applyRotationEntry,
632
- currentRotationIndex, resolveAcpHopCapFromConfig,
599
+ resolveAcpHopCapFromConfig,
633
600
  VOICE_HARDCODED_DEFAULTS,
634
601
  } from '../user-config.js';
635
- import { listProviders, streamLLM, anyProviderAvailable, getProviderForConfig, REASONING_CYCLE, nextReasoningLevel, reasoningLevelLabel, effectiveReasoningLevel, modelSupportsReasoning, type LLMMessage, type LLMToolSpec } from '../llm.js';
636
- import { resolveRouteDecision, recordCurrentRouteDecision, currentRouteDecision, formatRouteDecisionSummary } from '../llm/route-decision.js';
637
- import type { ReasoningLevel } from '../user-config.js';
602
+ import { streamLLM, anyProviderAvailable, getProviderForConfig, nextReasoningLevel, reasoningLevelLabel, effectiveReasoningLevel, modelSupportsReasoning, type LLMMessage, type LLMToolSpec } from '../llm.js';
603
+ import { currentRouteDecision, formatRouteDecisionSummary } from '../llm/route-decision.js';
604
+ import { resolveDashboardActiveModel } from './acp-active-model.js';
638
605
  import { getModelFamily, getModelTier } from '../models/prompts.js';
639
606
  import { buildPromptInjection, getPromptBankStore } from '../prompt-bank/index.js';
640
- import { getInputHistoryStore, inputHistoryDbPath, inputHistoryJsonPath } from '../input-history.js';
607
+ import { getInputHistoryStore } from '../input-history.js';
641
608
  import { inspectActiveProvider } from '../provider-summary.js';
609
+ import { createStatusProviderInfoReader } from '../status/status-provider-info.js';
642
610
  import { activeCodexAccountView } from '../oauth/codex-account-store.js';
643
- import { buildDashboardStatusLines } from './dashboard-status-lines.js';
644
- import { readSlashContextNow, seatsNowLine } from '../context-bus/context-now-surfaces.js';
611
+ import { buildDashboardStatusLines, readDashboardSeatsNow, type DashboardStatusLinesInput } from './dashboard-status-lines.js';
645
612
  import { buildFirstScreenBand, resolveTuiDaemonLink, type TuiDaemonLink } from './first-screen-band.js';
613
+ import { detectLocale } from '../expression/locale.js';
646
614
  import { runNexusShow, type NexusShowResult } from '../cli/nexus-show.js';
647
615
  import {
648
- workingDirSegment, sessionCwdSegment, modelSegment, gitSegment,
649
- ctxBarSegment, costSegment, speedSegment, elapsedSegment, cacheSegment,
650
- ptyShellCountSegment,
651
- voiceCostSegment,
652
616
  type GitSegmentState,
653
617
  } from '../status/bar.js';
654
618
  // PR-S1V.5 — voice month-to-date USD pill on the secondary status row.
655
619
  // The tracker is process-wide so the same singleton is read here and
656
620
  // updated by `voice-input-bridge.transcribe` (TUI path) + daemon REST
657
621
  // handler (PWA path).
658
- import { globalVoiceCostTracker } from '../voice/cost-tracker.js';
659
622
  import { createDashboardMouseWiring } from './input/mouse-wiring.js';
660
623
  import { createMouseConversationPopupRuntime } from './input/mouse-conversation-popup-runtime.js';
661
624
  import { createMouseModalHitRuntime } from './input/mouse-modal-hit-runtime.js';
@@ -739,7 +702,7 @@ import { createDashboardContextMenuFeedbackRuntime } from './context-menu-feedba
739
702
  import { createDashboardStatusFeedbackRuntime } from './status-feedback-runtime.js';
740
703
  import { createDashboardTransferFeedbackRuntime } from './transfer-feedback-runtime.js';
741
704
  import { createDashboardFinderFeedbackRuntime } from './finder-feedback-runtime.js';
742
- import { createDashboardTermSlashRuntime } from './term-slash-runtime.js';
705
+ import { createDashboardTermSlashRuntime, resolveTuiShellSeat } from './term-slash-runtime.js';
743
706
  import { createDashboardShellSlashRuntime } from './shell-slash-runtime.js';
744
707
  import { createDashboardRunSkillSlashRuntime } from './run-skill-slash-runtime.js';
745
708
  import { createDashboardSkillTriggersSlashRuntime } from './skill-triggers-slash-runtime.js';
@@ -789,7 +752,6 @@ import { createPfcScreenshotAttacher, type PfcScreenshotAttacher } from '../cond
789
752
  import { createStatusShellPostureRuntime } from './status-shell-posture-runtime.js';
790
753
  import { createTerminalHostFacade } from '../shell-runner/terminal-host-facade.js';
791
754
  import {
792
- buildTerminalMouseIntentEvent,
793
755
  interpretTerminalSurfaceIntent,
794
756
  } from './terminal-surface-intent.js';
795
757
  import {
@@ -820,15 +782,12 @@ import { bootDashboardApproverRuntimes } from './approver-runtime-boot.js';
820
782
  import { bootDashboardCaptureSourceProviders } from './capture-source-provider-boot.js';
821
783
  import { bootDashboardContextMenuProviders } from './context-menu-provider-boot.js';
822
784
  import { bootDashboardContextMenuRegistry } from './context-menu-registry-boot.js';
823
- import { buildPillMenu } from '../ui/context-menu-registry.js';
824
- import { createActionPickerRecipe } from '../mouse-action-recipes.js';
825
- import type { PopupPlacement } from '../ui/chrome/picker-popup-placement.js';
826
- import { deriveSubmenuPopupRoleTheme } from '../ui/submenu-popup-theme.js';
827
785
  import { bootDashboardContextRuntime } from './context-runtime-boot.js';
828
786
  import { bootDashboardContextWindowRuntime } from './context-window-runtime-boot.js';
829
787
  import { bootDashboardEagerTools } from './eager-tool-boot.js';
830
788
  import { bootDashboardEmbodiedTools } from './embodied-tools-boot.js';
831
789
  import { bootDashboardHitl } from './hitl-boot.js';
790
+ import { bootBannerStatusLines, normalizeBootBannerMode, renderMinimalBootBand, type BootBannerHeld } from './boot-banner.js';
832
791
  import { attachDashboardFilePathToken } from './file-path-attachment.js';
833
792
  import { bootDashboardSlashExecutor } from './slash-executor-boot.js';
834
793
  import { buildDashboardSlashRegistry, type DashboardSlashContext } from './slash-runtime/index.js';
@@ -879,14 +838,14 @@ import {
879
838
  } from '../dashboard-pane-context-menu.js';
880
839
  // writeClipboard imported below with other clipboard helpers (line ~185).
881
840
  import {
882
- renderPaneNav, paneAtColumn, paneNavLabel,
841
+ paneAtColumn, paneNavLabel,
883
842
  type PaneNavHitArea,
884
843
  } from './panes/nav.js';
885
844
  import { getSessionCwd, setSessionCwd, subscribeSessionCwd, pickSwdTargetFromBrowser } from '../session/working-dir.js';
886
845
  import {
887
846
  getGitStatusView,
888
847
  subscribeGitChanges,
889
- refreshDirty as refreshGitDirty,
848
+ refreshDirtyAsync as refreshGitDirtyAsync,
890
849
  } from '../git-fs/index.js';
891
850
  import { getPty, listPty, requestPtyTakeover } from '../pty-shell/registry.js';
892
851
  import { listPtyManifestRowsAt } from '../pty-shell/pty-manifest.js';
@@ -898,16 +857,13 @@ import { formatPtyCallLine, formatPtyResultLine } from '../pty-activity-log.js';
898
857
  import { getSessionMetrics } from '../status/metrics.js';
899
858
  import {
900
859
  createContextRegistry, tokenizeInput, pruneUnreferenced,
901
- addAttachment as ctxAdd,
902
860
  addAttachmentEx as ctxAddEx,
903
- clearAll as ctxClearAll, clearLarge as ctxClearLarge,
904
861
  dropAttachment as ctxDrop, listAttachments as ctxList,
905
862
  totalContextBytes as ctxTotalBytes,
906
- DEFAULT_LARGE_THRESHOLD_BYTES,
907
863
  type Attachment,
908
864
  } from '../context.js';
909
865
  import { loadAllAttachments } from '../extractors.js';
910
- import { grabClipboardImage, pruneOldPastes, isClipboardSupported, writeClipboard, writeClipboardDetailed, hasClipboardImage } from '../clipboard/index.js';
866
+ import { grabClipboardImage, pruneOldPastes, isClipboardSupported, writeClipboard, writeClipboardDetailed } from '../clipboard/index.js';
911
867
  import { startClipboardHistory, type ClipboardHistory } from '../clipboard/history.js';
912
868
  import { renderImagePreview } from '../image/preview.js';
913
869
  import { isKgpTerminal } from '../kgp/capabilities.js';
@@ -916,23 +872,19 @@ import { _internal as previewRouterInternal } from '../preview/router.js';
916
872
  import { showPreviewModal } from './modals/preview.js';
917
873
  import { terminalModalRouter } from './input/terminal-modal-router.js';
918
874
  import {
919
- computeDashboardViewMode,
920
875
  syncDashboardViewModeToContextKeys,
921
876
  type DashboardViewModeSignals,
922
877
  } from './runtime/view-mode.js';
923
878
  import { IDLE_VIEW_MODE, type ViewMode } from '../input-core/view-mode.js';
924
- import { createInteractiveTerminalModal } from '../interactive-terminal-modal.js';
925
879
  import { showToast } from './render/toast.js';
926
880
  import {
927
881
  browserWidgetInstanceIdForView,
928
- shortcutFor,
929
882
  } from './modals/pane.js';
930
883
  import { showTransientTerminalModal, currentTransientTerminalModal } from './modals/transient.js';
931
- import { showPaneMultiModal, showLivePaneMultiModal, currentPaneMultiModal, type PaneMultiModalHandle } from './modals/pane-multi.js';
884
+ import { showLivePaneMultiModal, type PaneMultiModalHandle } from './modals/pane-multi.js';
932
885
  import {
933
886
  resolveCompanionPopupChrome,
934
887
  resolveCompanionPopupTitleControls,
935
- resolveWindowScopedCompanionPopupChrome,
936
888
  } from './modals/companion-popup-chrome.js';
937
889
  import {
938
890
  resolveDebugPaneMultiChrome,
@@ -950,30 +902,22 @@ import {
950
902
  BroadcastBus,
951
903
  PreviewSlotAdapter,
952
904
  getChannelBus,
953
- type TerminalPlacement,
954
905
  } from '../terminal-matrix/index.js';
955
- import { resolveTerminalMoveDestination } from '../terminal-matrix/mobility.js';
956
906
  import { initElementObservability } from '../element-registry/index.js';
957
907
  import {
958
- armSessionQuickControl,
959
908
  createSearchPlannerState,
960
909
  buildSessionRuntimeToolSpecs,
961
910
  buildSessionDashboardStatusLines,
962
- buildSessionSurfaceStatusLines,
963
911
  consumeSessionQuickControl,
964
912
  createSessionPostureState,
965
913
  enterSessionControlMode,
966
914
  exitSessionControlMode,
967
915
  isSessionControlActive,
968
916
  routeDevHarnessSubmitIntent,
969
- parseSessionControlSlash,
970
- parseSessionSurfaceSlash,
971
917
  resolveSessionInputModeFromChatMode,
972
918
  resolveSessionModeSnapshot,
973
919
  resolveSessionSurfaceStatus,
974
- setSessionPreferredSurface,
975
920
  toggleSessionControlMode,
976
- type SearchPlannerState,
977
921
  } from '../session-runtime/index.js';
978
922
  import {
979
923
  initDashboardApprovers,
@@ -986,12 +930,13 @@ import {
986
930
  bootDashboardAcpSession,
987
931
  deriveDaemonHttpBase,
988
932
  fetchDaemonSessionHistory,
989
- fetchDaemonSessionList,
990
933
  } from './acp-boot.js';
991
934
  import { renderReplayPreviewLines } from './replay-preview.js';
992
935
  import {
993
936
  buildDashboardTurnPreamble,
994
937
  } from './turn-preamble.js';
938
+ import { describeSeatBoot, startSeatBootConversation } from './seat-boot-preamble.js';
939
+ import { ensureSeatLocalInstructions, installSeatSessionRecorder } from './seat-local-instructions.js';
995
940
  import type { DashboardSession } from '../tui-client/dashboard-session.js';
996
941
  import type { SessionTurnProfile } from '../session-runtime/index.js';
997
942
  import { createCompanionSurfaceHostRegistry } from './companion-surface-host-registry.js';
@@ -1020,7 +965,6 @@ import {
1020
965
  } from '../display/workspace-affinity.js';
1021
966
  import { initDashboardHitl, stopDashboardHitl } from './runtime/hitl.js';
1022
967
  import { openDashboardShellRollupPopup } from './shell-rollup-popup.js';
1023
- import { expandPromptReferences } from '../prompt/references.js';
1024
968
  import { spawnCodingAgent, CodingAgentBinaryMissing } from '../terminal/coding-agent.js';
1025
969
  import type { TerminalSession } from '../terminal/session-registry.js';
1026
970
  import { createSessionPickerModal } from '../session/picker-modal.js';
@@ -1030,15 +974,13 @@ import { listSessions as listChatSessionsForResume, adoptSession as adoptChatSes
1030
974
  // 영속은 세션 스토어(forkSessionFromHistory)가 담당한다.
1031
975
  import { userMessagePositions, truncateBeforeNthUser } from '../acp/session-fork.js';
1032
976
  import { resolveEscEscRewind } from '../chat/esc-esc-rewind.js';
1033
- import { wirePersistence, loadPersistedSessions } from '../terminal/session-persistence.js';
977
+ import { wirePersistence } from '../terminal/session-persistence.js';
1034
978
  import { renderMarkdown as renderMarkdownGlow } from '../markdown-preview.js';
1035
979
  import { basename, dirname } from 'path';
1036
980
  import { statSync } from 'fs';
1037
981
  import {
1038
- FIGURES, applyColor, toolHeader, toolResult, toolBlock,
1039
- renderTable, renderMarkdown, successLine, errorLine, warningLine,
1040
- sectionHeader, progressIndicator, renderTaskStatus,
1041
- type StatusColor, type TaskStatus,
982
+ FIGURES, toolHeader, toolResult,
983
+ renderMarkdown, successLine, errorLine, warningLine,
1042
984
  } from '../render.js';
1043
985
  import type { SyncMode } from '../types.js';
1044
986
  import type { ChatMessage } from '../chat/index.js';
@@ -1046,12 +988,12 @@ import type { PlainTurnSubmit } from '../input/turn-submit.js';
1046
988
  // U-4.2 · `renderLogPane` no longer called from dashboard directly —
1047
989
  // wd-log widget owns log rendering via renderLogViaWidget. Only
1048
990
  // `findBlock` still used here (chat-input block navigation).
1049
- import { findBlock } from '../panes/log-pane.js';
991
+ import { findBlock, logPaneContentHeight, maxLogPaneScroll, visibleSearchRowOffset } from '../panes/log-pane.js';
1050
992
  import { createQuitConfirmationState, gracefulQuit, type QuitConfirmationState } from './graceful-quit.js';
1051
- import { enqueuePendingUserInput } from '../session/pending-input.js';
993
+ import { handoffTurnTypeaheadAtTurnEnd, releaseTurnTypeaheadPending, steerLastTurnTypeaheadSubmission } from './input/turn-steer-bridge.js';
1052
994
  import { createAttachmentRowMap } from '../log-pane/attachment-row-map.js';
1053
995
  import { createAttachmentPopup, type AttachmentPopupAction } from '../log-pane/attachment-popup.js';
1054
- import { findLogMatches, type LogSearchResult } from '../log-pane/search.js';
996
+ import { findLogMatches, findVisibleLogMatches, type LogSearchResult } from '../log-pane/search.js';
1055
997
  import { createLogSearchModal, type LogSearchModalOpts } from '../log-pane/search-modal.js';
1056
998
  // U-4.3 · direct imports of tryAttachmentHitAtBodyRow /
1057
999
  // tryHandleLogAreaClick are gone · wd-log.onMouse owns the hit-test.
@@ -1110,7 +1052,6 @@ import {
1110
1052
  } from '../skills/tools/dashboard-config.js';
1111
1053
  import {
1112
1054
  initDashboardWidgetTools,
1113
- type WidgetInfo,
1114
1055
  } from '../skills/tools/dashboard-widget.js';
1115
1056
  import { initWidgetInspectorTools } from '../skills/tools/widget-inspector.js';
1116
1057
  import {
@@ -1123,7 +1064,6 @@ import {
1123
1064
  } from '../agent/spawn-embodied-agent-in-vw.js';
1124
1065
  import { findSessionObserver } from '../agent/observer-registry.js';
1125
1066
  import {
1126
- conversationHoverHudLabel,
1127
1067
  conversationModalTitle,
1128
1068
  conversationModalWidgetId,
1129
1069
  findConversationSessionEntry,
@@ -1169,10 +1109,10 @@ import {
1169
1109
  import { computeWorkingFocusSync } from '../display/working-focus-sync.js';
1170
1110
  import { dispatchPaneClick } from '../display/pane-click-dispatch.js';
1171
1111
  import { installResizeListener } from '../display/resize-listener.js';
1172
- import { isPtyForwardMouseEventType, type KeyEvent as DisplayKeyEvent } from '../display/types.js';
1112
+ import { isPtyForwardMouseEventType } from '../display/types.js';
1173
1113
  import { createDisplayEventBus } from '../display/events.js';
1174
1114
  import { agentBatchScratchTitle, renderAgentBatchScratch } from '../display/agent-batch.js';
1175
- import { createExecutionSurface, type ExecutionSurfaceHandle } from '../display/index.js';
1115
+ import { type ExecutionSurfaceHandle } from '../display/index.js';
1176
1116
  import { AgentSurfaceStore, renderAgentDetail, renderAgentRoster, type AgentSurfaceState } from '../display/agent-surface.js';
1177
1117
  import { globalAgentFlash } from '../display/agent-flash.js';
1178
1118
  import { renderDebugEventDetail, renderDebugEventRows, renderDebugStack, renderPromptInjectionDebug } from '../display/debug-surface.js';
@@ -1195,9 +1135,9 @@ export function registerDashboardCoreHostTools(host: Pick<PluginHost, 'registerH
1195
1135
  }
1196
1136
  }
1197
1137
  import { registerDashboardPaneHostTools } from './panes/host-tools.js';
1198
- import { DEFAULT_THEME_TOKENS, mergeThemeTokens, resolveThemeTokens, type ThemeTokenInput, type ThemeTokens } from '../theme/tokens.js';
1199
- import { resolveActiveTheme, setActivePresetInConfig } from './render/theme-resolver.js';
1200
- import { getTheme, listThemes } from '../themes/index.js';
1138
+ import { type ThemeTokens } from '../theme/tokens.js';
1139
+ import { resolveActiveTheme } from './render/theme-resolver.js';
1140
+ import { getTheme } from '../themes/index.js';
1201
1141
  import type { PaneFocus, PreviewSource, WorkingDirView } from '../workspace-types.js';
1202
1142
  import type { DisplayMouseEvent } from '../display/types.js';
1203
1143
  import type { Key as TuiKey } from '../tui.js';
@@ -1214,7 +1154,6 @@ import {
1214
1154
  readDirEntries,
1215
1155
  sortEntries,
1216
1156
  splitAtPrefix,
1217
- dirname as wdDirname,
1218
1157
  type WorkingDirState,
1219
1158
  type FsEntry,
1220
1159
  } from '../working-dir/index.js';
@@ -1224,8 +1163,6 @@ import {
1224
1163
  resolveBrowserActionContextFromHit,
1225
1164
  } from '../browser-pane/actions.js';
1226
1165
  import { resolveBrowserTransferCapability } from '../browser-pane/capabilities.js';
1227
- import { openBrowserPaneModal } from '../browser-pane/mount.js';
1228
- import { openPreviewPaneModal } from '../preview-pane/mount.js';
1229
1166
  import {
1230
1167
  cyclePreviewSourceForView,
1231
1168
  formatPreviewSourceLabel,
@@ -1238,7 +1175,7 @@ import {
1238
1175
  } from '../preview-pane/model.js';
1239
1176
  import { PreviewPaneRegistry } from '../preview-pane/registry.js';
1240
1177
  import { FileIndexCache, absolutize } from '../file-index.js';
1241
- import { firstPaneOfView, paneSetForView } from '../working-dir/focus.js';
1178
+ import { firstPaneOfView } from '../working-dir/focus.js';
1242
1179
  import { applyVisibleFocusRepair } from './focus-repair.js';
1243
1180
  import {
1244
1181
  nextVisiblePaneFocus,
@@ -1249,11 +1186,7 @@ import {
1249
1186
  } from '../views/pane-policy.js';
1250
1187
  import {
1251
1188
  autoTabletModeForViewport,
1252
- orderDashboardViewsForCompactMode,
1253
1189
  effectiveChatOnlyModeForViewport,
1254
- orderSurfaceCatalogForCompactMode,
1255
- pruneDashboardViewsForCompactMode,
1256
- pruneSurfaceCatalogForCompactMode,
1257
1190
  productCompactModeForViewport,
1258
1191
  } from '../views/product-compact-mode.js';
1259
1192
  import { readScopedRenderLogs, resolveRenderSuppressed, readScopedDebugLevel, resolveStartupDebugLevel, hotPathGateOpen } from '../mss/logging/scoped-level.js';
@@ -1264,7 +1197,6 @@ import {
1264
1197
  compileDashboardViewLayout,
1265
1198
  describeDashboardViewsForPrompt,
1266
1199
  findDashboardView,
1267
- nextDashboardView,
1268
1200
  panesForDashboardView,
1269
1201
  serializeDashboardViewsConfig,
1270
1202
  validateDashboardViewsConfig,
@@ -1344,6 +1276,8 @@ import {
1344
1276
  type SpaceLongPressDetector,
1345
1277
  } from './input/space-longpress-detector.js';
1346
1278
  import { isAllowlistedDictationSurface } from './input/dictation-surface-allowlist.js';
1279
+ import { createDashboardExternalInputHost } from './input/external-input-host.js';
1280
+ import { registerExternalInputHost } from '../input/external-input-queue.js';
1347
1281
  // H3 #6 follow-up #3 — background sessions render as a distinct sidebar
1348
1282
  // kind with live state badge + tap-to-Join. Dashboard pulls BG records
1349
1283
  // through backgroundToStub + maps state via bgStateToSessionStatus,
@@ -1896,18 +1830,20 @@ export function renderDashboardFirstScreenBand(input: {
1896
1830
  readonly history: ReadonlyArray<{ role: string }>;
1897
1831
  readonly lines: string[];
1898
1832
  readonly width: number;
1833
+ /** Renders the localized guidance rows; `undefined` keeps the historical mixed band. */
1834
+ readonly locale?: 'ko' | 'en';
1899
1835
  readonly draw: () => void;
1900
1836
  readonly observe: (data: { daemon: boolean; hasPwa: boolean; hasTailnet: boolean }) => void;
1901
1837
  readonly show?: () => Promise<Pick<NexusShowResult, 'status' | 'urls'>>;
1902
1838
  readonly daemonLink?: () => Promise<TuiDaemonLink>;
1903
1839
  }): Promise<void> {
1904
1840
  if (input.history.some((message) => message.role !== 'system')) return Promise.resolve();
1905
- const band = buildFirstScreenBand({ width: input.width, daemon: false, link: { status: 'checking' } });
1841
+ const band = buildFirstScreenBand({ width: input.width, daemon: false, link: { status: 'checking' }, locale: input.locale });
1906
1842
  input.lines.unshift(...band);
1907
1843
  const daemonLink = input.daemonLink ?? resolveTuiDaemonLink;
1908
1844
  const linkPending = Promise.resolve().then(() => daemonLink()).catch((): TuiDaemonLink => ({ status: 'error', stage: 'health' })).then((link) => {
1909
1845
  if (input.lines[0] !== band[0]) return;
1910
- input.lines[0] = buildFirstScreenBand({ width: input.width, daemon: false, link })[0]!;
1846
+ input.lines[0] = buildFirstScreenBand({ width: input.width, daemon: false, link, locale: input.locale })[0]!;
1911
1847
  try { input.draw(); } catch { /* screen may have closed */ }
1912
1848
  });
1913
1849
  const show = input.show ?? (() => runNexusShow({ format: 'json', out: { log: () => {}, error: () => {} } }));
@@ -1921,7 +1857,7 @@ export function renderDashboardFirstScreenBand(input: {
1921
1857
  const hasTailnet = !!pwa?.tailnet;
1922
1858
  observe({ daemon, hasPwa, hasTailnet });
1923
1859
  if (input.lines[1] !== band[1]) return;
1924
- input.lines[1] = buildFirstScreenBand({ width: input.width, daemon, pwa })[1]!;
1860
+ input.lines[1] = buildFirstScreenBand({ width: input.width, daemon, pwa, locale: input.locale })[1]!;
1925
1861
  try { input.draw(); } catch { /* screen may have closed */ }
1926
1862
  }).catch(() => {
1927
1863
  observe({ daemon: false, hasPwa: false, hasTailnet: false });
@@ -1929,6 +1865,17 @@ export function renderDashboardFirstScreenBand(input: {
1929
1865
  return Promise.all([linkPending, pwaPending]).then(() => {});
1930
1866
  }
1931
1867
 
1868
+ /** The /status reader used by the live dashboard slash callback. */
1869
+ export function renderDashboardStatusLines(input: Omit<DashboardStatusLinesInput, 'seatsNow'>, now = Date.now()): string[] {
1870
+ let seatsNow: string | null = null;
1871
+ try {
1872
+ seatsNow = readDashboardSeatsNow(now);
1873
+ } catch (error) {
1874
+ debug.log('dashboard.status', 'seats-unreadable', { error: String(error) });
1875
+ }
1876
+ return buildDashboardStatusLines({ ...input, seatsNow });
1877
+ }
1878
+
1932
1879
  export async function showDashboard(opts: ShowDashboardOptions = {}): Promise<DashboardAction> {
1933
1880
  let firstDashboardFrameRendered = false;
1934
1881
  await awaitGlobalPersonaLoad().catch(() => {});
@@ -2591,9 +2538,17 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
2591
2538
  };
2592
2539
  const clearLogFilter = (): void => {
2593
2540
  logFilterQuery = '';
2541
+ if (logSearchQuery) {
2542
+ logSearchResults = findLogMatches(chatLines, logSearchQuery);
2543
+ logSearchCursor = Math.min(logSearchCursor, Math.max(0, logSearchResults.length - 1));
2544
+ }
2594
2545
  };
2595
2546
  const applyLogFilter = (query: string): void => {
2596
2547
  logFilterQuery = query.trim();
2548
+ if (logSearchQuery) {
2549
+ logSearchResults = findVisibleLogMatches(chatLines, logSearchQuery, logFilterQuery);
2550
+ logSearchCursor = Math.min(logSearchCursor, Math.max(0, logSearchResults.length - 1));
2551
+ }
2597
2552
  if (debug.enabled) {
2598
2553
  debug.log('log-pane.filter.apply', `q="${logFilterQuery}"`, {
2599
2554
  active: logFilterQuery.length > 0,
@@ -2603,7 +2558,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
2603
2558
  const applyLogSearch = (query: string): void => {
2604
2559
  logSearchQuery = query.trim();
2605
2560
  logSearchResults = logSearchQuery
2606
- ? findLogMatches(chatLines, logSearchQuery)
2561
+ ? findVisibleLogMatches(chatLines, logSearchQuery, logFilterQuery)
2607
2562
  : [];
2608
2563
  logSearchCursor = 0;
2609
2564
  if (debug.enabled) {
@@ -2615,13 +2570,18 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
2615
2570
  /** Center the viewport on a search-result line. Sets chatScrollOffset
2616
2571
  * so the match row lands mid-pane when possible; clamps at bounds. */
2617
2572
  const scrollToSearchResult = (result: LogSearchResult): void => {
2573
+ // An explicit search may jump to output that arrived while the pane
2574
+ // was frozen. Release that snapshot before computing the row bound.
2575
+ if (logFrozenTailIndex !== null && result.lineIdx >= logFrozenTailIndex) {
2576
+ logFrozenTailIndex = null;
2577
+ }
2618
2578
  const { rows: tr } = termSize();
2619
2579
  const sH = computeLogH(tr);
2620
- const bodyH = Math.max(0, sH - 1);
2621
2580
  const hasFooter = chatFooterLine.current != null && chatFooterLine.current !== '';
2622
- const contentH = Math.max(0, bodyH - (hasFooter ? 2 : 0));
2623
- const target = Math.max(0, result.lineIdx - Math.floor(contentH / 2));
2624
- const maxScroll = Math.max(0, chatLines.length - contentH);
2581
+ const hasQueueRow = hasFooter && !!renderTurnTypeaheadQueueRow(turnTypeaheadRef.state, Math.max(20, termSize().cols - 6));
2582
+ const contentH = logPaneContentHeight(sH, hasFooter, hasQueueRow);
2583
+ const target = Math.max(0, visibleSearchRowOffset(chatLines, result, logFilterQuery) - Math.floor(contentH / 2));
2584
+ const maxScroll = logScrollMax(sH);
2625
2585
  chatScrollOffset = target >= maxScroll ? -1 : target;
2626
2586
  // Entering a scrolled state may set the freeze — the
2627
2587
  // handleLogPaneKey transition only fires for user keystrokes, so
@@ -3413,6 +3373,16 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
3413
3373
  // indicator below the scrolling log body. Mutated by startPinnedThinking
3414
3374
  // via this ref. `null` = no footer, body uses full log height.
3415
3375
  const chatFooterLine: { current: string | null } = { current: null };
3376
+ const logScrollMax = (height: number): number => {
3377
+ const hasFooter = chatFooterLine.current != null && chatFooterLine.current !== '';
3378
+ const hasQueueRow = hasFooter && !!renderTurnTypeaheadQueueRow(turnTypeaheadRef.state, Math.max(20, termSize().cols - 6));
3379
+ return maxLogPaneScroll(chatLines, height, {
3380
+ filterQuery: logFilterQuery,
3381
+ frozenTailIndex: logFrozenTailIndex,
3382
+ hasFooter,
3383
+ hasQueueRow,
3384
+ });
3385
+ };
3416
3386
  const disposeEventLoopStallMonitor = startEventLoopStallMonitor({
3417
3387
  getContext: () => ({
3418
3388
  streamingInFlight,
@@ -3535,21 +3505,11 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
3535
3505
  * actual view model instead of drifting toward an old 60/40 guess.
3536
3506
  */
3537
3507
  const dashboardState = new DashboardStateStore();
3538
- const getFallbackPromptFrame = (termRows: number) =>
3539
- dashboardState.getFallbackPromptFrame(termRows);
3540
3508
  const getLayoutPromptFrame = (termRows: number): PromptFrame =>
3541
3509
  dashboardState.getLayoutPromptFrame(termRows);
3542
3510
  const currentPromptFrame = (termRows = termSize().rows): PromptFrame =>
3543
3511
  dashboardState.getCurrentPromptFrame(termRows);
3544
3512
 
3545
- /** Rows taken up by everything BELOW the log zone (hud excluded — it
3546
- * sits between grid and log, and is reserved separately when the
3547
- * grid is present). Used to compute paneH below and to size the
3548
- * embedded grid when logEmbedded=true. Must match the number of
3549
- * rows pushed by zones 'input-divider-upper' through 'dock'. */
3550
- const bottomFixedRows = (inputHeight: number) =>
3551
- bottomFixedRowsForPromptFrame(inputHeight);
3552
-
3553
3513
  /** Compute paneH (height reserved for the top pane/grid in
3554
3514
  * non-chat-only, non-embedded modes) given termRows. Factored out
3555
3515
  * so layoutTools.getCurrentLayout can reuse the same math. */
@@ -3684,6 +3644,9 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
3684
3644
  // The ACP bridge is created later during dashboard boot. Keep status renders
3685
3645
  // safe before then, and bind this reader once the bridge exists.
3686
3646
  let activeAcpRuntimeModel = (): string | undefined => undefined;
3647
+ // 상태줄은 provider·model 만 쓴다 — 렌더마다 inspectActiveProvider(자격·authDetail 동기 읽기)를 안 부른다.
3648
+ const readStatusProviderInfo = createStatusProviderInfoReader();
3649
+ const runningBuildStatus = createRunningBuildStatus();
3687
3650
  /** Primary pill row — wd · git · provider/model · elapsed.
3688
3651
  * MX11b — delegates to mouseWiring.buildStatusLine so pill column
3689
3652
  * bounds are captured as a side effect; the return string is
@@ -3711,7 +3674,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
3711
3674
  return mouseWiring.buildStatusLine({
3712
3675
  swd,
3713
3676
  gitState,
3714
- providerInfo: inspectActiveProvider(undefined, activeAcpRuntimeModel()),
3677
+ providerInfo: readStatusProviderInfo(activeAcpRuntimeModel()),
3715
3678
  contextUsedTokens: metrics.lastContextUsed,
3716
3679
  tmuxLabel: tmuxStatusLabel,
3717
3680
  sshLabel: sshStatusLabel,
@@ -3733,44 +3696,12 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
3733
3696
  // dashboardVoiceChat.onPhaseChange). The status-bar pill is
3734
3697
  // intentionally null so we don't render the same state twice.
3735
3698
  voiceLabel: null,
3699
+ runningBuild: runningBuildStatus(),
3736
3700
  theme,
3737
3701
  });
3738
3702
  } catch { return ''; }
3739
3703
  };
3740
3704
 
3741
- /** Secondary metrics row — CTX bar · total cost · t/s · cache hit %.
3742
- * Reads from the session-metrics singleton populated by runTurn +
3743
- * dashboard streaming paths, plus the prompt-cache metrics
3744
- * singleton populated by onUsage. Renders an all-zero row when no
3745
- * turns have completed yet (matches Claude Code's "0k/N.Nk"
3746
- * placeholder). */
3747
- const buildSecondaryStatusLine = (): string => {
3748
- try {
3749
- const m = getSessionMetrics();
3750
- const theme = currentThemeTokens();
3751
- // Prompt-cache summary is ambient — import synchronously from a
3752
- // side-effect-free module; no fetch, no state beyond the session
3753
- // singleton that was already populated by onUsage events.
3754
- const { getSessionSummary } = require('../prompt-cache/metrics.js') as
3755
- typeof import('../prompt-cache/metrics.js');
3756
- const cachePct = getSessionSummary().hitRatePct;
3757
- // PR-S1V.5 — voice cost month-to-date pill. Reads the
3758
- // process-wide tracker that voice-input-bridge.transcribe and
3759
- // the daemon's /v1/voice/transcribe REST handler both write to,
3760
- // so the pill is the canonical view across surfaces. Empty
3761
- // string when nothing was spent this month.
3762
- const voiceMonthly = globalVoiceCostTracker().getMonthSummary().totalUsd;
3763
- const parts = [
3764
- ctxBarSegment(m.lastContextUsed, m.lastContextMax, 24),
3765
- costSegment(m.totalCostUsd, { theme }, m.unpricedTurns),
3766
- voiceCostSegment(voiceMonthly, { theme }),
3767
- speedSegment(m.lastTokensPerSec, { theme }),
3768
- cacheSegment(cachePct, { theme }),
3769
- ];
3770
- return parts.filter(Boolean).join(' ');
3771
- } catch { return ''; }
3772
- };
3773
-
3774
3705
  let draw: (opts?: { force?: boolean }) => void = () => {};
3775
3706
  let drawNow: (opts?: { force?: boolean }) => void = () => {};
3776
3707
  let drawQueued = false;
@@ -3927,9 +3858,6 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
3927
3858
  if (debug.enabled) {
3928
3859
  debug.log('status.shell-posture.boot', 'ready', statusShellPostureRuntime.current());
3929
3860
  }
3930
- const blankRows = (height: number, width: number): string[] => (
3931
- Array.from({ length: Math.max(0, height) }, () => ' '.repeat(Math.max(0, width)))
3932
- );
3933
3861
  // IUL Phase M (Bundle 1) → Phase S·a (Bundle 2) → Bundle 3 wiring.
3934
3862
  // Wraps the existing afterRender hook with composeIdentityHooks so
3935
3863
  // every modal-kind surface mount/dispose gets a stable ModalIdentity
@@ -4061,9 +3989,9 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
4061
3989
  // The 5s poll would eventually catch the change; forcing here
4062
3990
  // makes the "*N" suffix tick up within the same frame so the
4063
3991
  // user sees feedback for their own action immediately.
4064
- try {
4065
- refreshGitDirty(getSessionCwd(), { force: true });
4066
- } catch { /* noop */ }
3992
+ // TUI-TYPING-LAG — async probe: `git status` must not block key input.
3993
+ void refreshGitDirtyAsync(getSessionCwd(), { force: true })
3994
+ .then(() => { try { draw(); } catch { /* TUI torn down */ } }, () => { /* noop */ });
4067
3995
  });
4068
3996
  }
4069
3997
  // WD2 — session working directory subscription. Status bar pills
@@ -4095,10 +4023,8 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
4095
4023
  // Kick off the first dirty probe in the background so the
4096
4024
  // "*N" suffix appears on the first meaningful redraw. Throttle
4097
4025
  // handles repeated calls; we just fire-and-forget.
4098
- try {
4099
- refreshGitDirty(swd, { force: true });
4100
- try { draw(); } catch { /* noop */ }
4101
- } catch { /* noop */ }
4026
+ void refreshGitDirtyAsync(swd, { force: true })
4027
+ .then(() => { try { draw(); } catch { /* noop */ } }, () => { /* noop */ });
4102
4028
  };
4103
4029
  wireGitForSwd();
4104
4030
 
@@ -4127,14 +4053,15 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
4127
4053
  const gitDirtyTimer: ReturnType<typeof setInterval> = setInterval(() => {
4128
4054
  try {
4129
4055
  const before = getGitStatusView(getSessionCwd());
4130
- refreshGitDirty(getSessionCwd(), { minIntervalMs: 4_000 });
4131
- const after = getGitStatusView(getSessionCwd());
4132
- if (
4133
- (before.dirty?.total ?? -1) !== (after.dirty?.total ?? -1) ||
4134
- (before.aheadBehind?.ahead ?? -1) !== (after.aheadBehind?.ahead ?? -1)
4135
- ) {
4136
- try { draw(); } catch { /* noop */ }
4137
- }
4056
+ // TUI-TYPING-LAG — the 5s probe ran `git status` synchronously (130ms+, hundreds under load).
4057
+ void refreshGitDirtyAsync(getSessionCwd(), { minIntervalMs: 4_000 }).then((after) => {
4058
+ if (
4059
+ (before.dirty?.total ?? -1) !== (after.dirty?.total ?? -1) ||
4060
+ (before.aheadBehind?.ahead ?? -1) !== (after.aheadBehind?.ahead ?? -1)
4061
+ ) {
4062
+ try { draw(); } catch { /* noop */ }
4063
+ }
4064
+ }, () => { /* noop */ });
4138
4065
  } catch { /* noop */ }
4139
4066
  }, 5_000);
4140
4067
  (gitDirtyTimer as unknown as { unref?: () => void }).unref?.();
@@ -4395,6 +4322,9 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
4395
4322
  // requestConfirmation() / HitlConfirm tool reaches the iPhone.
4396
4323
  // Fire-and-forget: a listener start failure warns but doesn't
4397
4324
  // block dashboard init (HITL degrades to terminal-only / no-op).
4325
+ // #28 — the minimal boot banner holds healthy-boot rows for /status instead of the transcript.
4326
+ const bootBannerMode = normalizeBootBannerMode(getUserConfig().dashboard.bootBanner);
4327
+ const bootBannerHeld: BootBannerHeld = {};
4398
4328
  bootDashboardHitl({
4399
4329
  enabled: process.env['ELANOUS_HITL_DISABLE'] !== '1',
4400
4330
  initDashboardHitl,
@@ -4404,6 +4334,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
4404
4334
  try { return getPushcutClient().configured; } catch { return false; }
4405
4335
  },
4406
4336
  pushWarningLine: (message) => { chatLines.push(C.warning(message)); },
4337
+ holdWarningLine: bootBannerMode === 'minimal' ? (message) => { bootBannerHeld.hitl = message; } : undefined,
4407
4338
  draw: () => { draw(); },
4408
4339
  registerBeforeExit: (cb) => { process.once('beforeExit', cb); },
4409
4340
  warnConsole: (message) => { console.warn(message); },
@@ -4897,6 +4828,15 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
4897
4828
  inputCoreAddDefaultBinding({ matcher: 'ctrl+x s', actionId: 'mode.enter.sync' });
4898
4829
  inputCoreAddDefaultBinding({ matcher: 'ctrl+x c', actionId: 'mode.enter.control' });
4899
4830
  inputCoreAddDefaultBinding({ matcher: 'ctrl+x g', actionId: 'mode.enter.general' });
4831
+ // #19 — the log-pane `F` bulk fold toggle, shared by the input (`ctrl+x f`) and pane chords.
4832
+ const toggleAllLogFolds = (): void => {
4833
+ const changed = foldStack.toggleAll();
4834
+ debug.log('log.fold', 'toggle-all', { via: 'ctrl+x f', changed });
4835
+ if (changed === 0) pushDebugLine(C.muted('(nothing to fold/unfold)'));
4836
+ chatScrollOffset = -1;
4837
+ draw();
4838
+ };
4839
+ registerLogFoldInputBinding(toggleAllLogFolds);
4900
4840
 
4901
4841
  initTui(true);
4902
4842
 
@@ -6243,14 +6183,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6243
6183
  const active = inspectActiveProvider(cfg);
6244
6184
  const reasoningProvider = (['openai-codex', 'openai', 'anthropic', 'gemini', 'grok', 'local', 'openrouter'] as const)
6245
6185
  .find(provider => active.provider === provider || active.provider === `auto:${provider}`);
6246
- let seatsNow: string | null = null;
6247
- try {
6248
- seatsNow = seatsNowLine(readSlashContextNow([]), Date.now());
6249
- } catch (error) {
6250
- debug.log('dashboard.status', 'seats-unreadable', { error: String(error) });
6251
- }
6252
- return buildDashboardStatusLines({
6253
- seatsNow,
6186
+ return renderDashboardStatusLines({
6254
6187
  provider: active.provider,
6255
6188
  model: active.model,
6256
6189
  reasoning: reasoningProvider
@@ -6260,6 +6193,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6260
6193
  : undefined,
6261
6194
  daemonAddress: opts.remote?.url,
6262
6195
  daemonConnected: daemonAttached,
6196
+ bootHeld: bootBannerStatusLines(bootBannerHeld),
6263
6197
  accountName: active.provider === 'openai-codex' || active.provider === 'auto:openai-codex'
6264
6198
  ? activeCodexAccountView().name : undefined,
6265
6199
  sessionSurfaceLines: buildSessionDashboardStatusLines(resolveSessionSurfaceStatus({ chatModeState })),
@@ -6334,7 +6268,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6334
6268
  const { rows: tr } = termSize();
6335
6269
  const sH = computeLogH(tr);
6336
6270
  const halfSH = Math.max(1, Math.floor(sH / 2));
6337
- const maxScr = Math.max(0, chatLines.length - sH);
6271
+ const maxScr = logScrollMax(sH);
6338
6272
  // Scroll keys → Scrollable behavior on wd-log. Sync pre/post.
6339
6273
  const SCROLL_KEYS = new Set([
6340
6274
  'j', 'k', 'down', 'up',
@@ -6525,6 +6459,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6525
6459
  const chatLinesStartIndex = chatLines.length;
6526
6460
  userScrolledDuringStream = false;
6527
6461
  streamingInFlight = true;
6462
+ reportTuiTurn('busy');
6528
6463
  const SCROLL_KEYS = new Set(['j', 'k', 'down', 'up', 'pageup', 'pagedown', 'home', 'end', 'g', 'G']);
6529
6464
  // T3-B2: ESC abort gate. When the user hits Esc AND sub-agent
6530
6465
  // work is running, pop a confirmation modal before tearing down
@@ -6594,7 +6529,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6594
6529
  const scrollLogBy = (delta: number): void => {
6595
6530
  const { rows: tr } = termSize();
6596
6531
  const sH = computeLogH(tr);
6597
- const maxScr = Math.max(0, chatLines.length - sH);
6532
+ const maxScr = logScrollMax(sH);
6598
6533
  const cur = chatScrollOffset < 0 ? maxScr : chatScrollOffset;
6599
6534
  let next = Math.max(0, Math.min(cur + delta, maxScr));
6600
6535
  if (delta > 0 && next >= maxScr) next = -1; // re-pin tail
@@ -6839,22 +6774,22 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6839
6774
  },
6840
6775
  });
6841
6776
  if (queuedHistoryEntry) refreshInputHistory();
6842
- enqueuePendingUserInput(sid, queuedText, (drained) => {
6843
- // 배수된 만큼을 앞에서부터 떨어낸다(FIFO · 순서 보존).
6844
- const remaining = turnTypeaheadRef.state.queuedSubmissions.slice(drained.length);
6845
- turnTypeaheadRef.state = { ...turnTypeaheadRef.state, queuedSubmissions: remaining };
6846
- for (const text of drained) {
6777
+ // ⭐ 레지스트리 id 로 짝짓는다 — 배수·되꺼내기·턴 종료 승격이 같은 항목을 «한 번만» 보낸다.
6778
+ // ⛔ 슬래시는 안 넣는다(턴 종료 FIFO 로만 실행).
6779
+ steerLastTurnTypeaheadSubmission(turnTypeaheadRef, sid, ({ texts, remaining }) => {
6780
+ for (const text of texts) {
6847
6781
  echoSubmittedUserText(text, { live: true });
6848
6782
  debug.log('dashboard.turn-typeahead', 'echoed', { path: 'live', length: text.length });
6849
6783
  }
6850
- if (drained.length > 0) draw();
6784
+ if (texts.length > 0) draw();
6851
6785
  debug.log('dashboard.turn-typeahead', 'drained-into-live-turn', {
6852
- drained: drained.length, remaining: remaining.length,
6786
+ drained: texts.length, remaining,
6853
6787
  });
6854
6788
  });
6855
6789
  }
6856
6790
  }
6857
6791
  }
6792
+ if (r.releasedPendingIds) releaseTurnTypeaheadPending(r.releasedPendingIds, 'recalled');
6858
6793
  if (r.immediateSubmission) {
6859
6794
  turnTypeaheadRef.state = await dispatchStreamingTurnTypeaheadSubmission(
6860
6795
  turnTypeaheadRef.state,
@@ -7083,9 +7018,17 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
7083
7018
  return () => {
7084
7019
  cleanup();
7085
7020
  escGate.dispose();
7086
- if (!stoppedHarnessSpace) settleEscAbortPendingLines(chatLines, chatLinesStartIndex);
7087
- userScrolledDuringStream = false;
7088
- streamingInFlight = false;
7021
+ try {
7022
+ if (!stoppedHarnessSpace) settleEscAbortPendingLines(chatLines, chatLinesStartIndex);
7023
+ } catch (err) {
7024
+ const message = err instanceof Error ? err.message : String(err);
7025
+ const stackHead = err instanceof Error ? err.stack?.split('\n')[1]?.trim() : undefined;
7026
+ debug.log('dashboard.turn', 'settle-failed', { message, stackHead });
7027
+ } finally {
7028
+ userScrolledDuringStream = false;
7029
+ streamingInFlight = false;
7030
+ reportTuiTurn('idle');
7031
+ }
7089
7032
  };
7090
7033
  };
7091
7034
 
@@ -7329,9 +7272,6 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
7329
7272
  ?? viewRegistry.views[0]!;
7330
7273
  setActiveDashboardView(def);
7331
7274
  };
7332
- const reloadDashboardViews = (): void => {
7333
- applyDashboardViewsRuntime(getUserConfig().dashboard.views as any);
7334
- };
7335
7275
  const userClosedPanes = new Set<PaneFocus>();
7336
7276
  const closedPaneSet = (): ReadonlySet<PaneFocus> => {
7337
7277
  const closed = new Set(userClosedPanes);
@@ -8295,7 +8235,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
8295
8235
  }
8296
8236
  return;
8297
8237
  }
8298
- const maxScr = Math.max(0, chatLines.length - logViewport.height);
8238
+ const maxScr = logScrollMax(logViewport.height);
8299
8239
  const delta = m.type === 'scroll-up' ? -3 : 3;
8300
8240
  const before = chatScrollOffset;
8301
8241
  chatScrollOffset = Math.max(0, Math.min(
@@ -9364,24 +9304,6 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
9364
9304
  limit,
9365
9305
  });
9366
9306
  };
9367
- const describePaneStateForPrompt = (): string => {
9368
- const state = paneStateSnapshot();
9369
- const rows = state.panes.map(p => {
9370
- const bits = [
9371
- p.visible ? 'visible' : 'hidden',
9372
- p.closed ? 'closed' : '',
9373
- p.closeable ? 'closeable' : 'primary',
9374
- p.omittedReason ? `omitted=${p.omittedReason}` : '',
9375
- ].filter(Boolean).join(', ');
9376
- return `- ${p.pane}: ${bits}`;
9377
- });
9378
- return [
9379
- '## Dashboard Pane State',
9380
- '',
9381
- `Active view: ${state.activeViewId} "${state.viewLabel}" (baseView=${state.baseView}, compact=${state.compactLevel}, focus=${state.focused})`,
9382
- ...rows,
9383
- ].join('\n');
9384
- };
9385
9307
  // Surface-unification v2.2 V2.2-5 Part 2 (2026-05-11) — schedulerView
9386
9308
  // state · openSchedulerForm · activeSchedulerFormValue /
9387
9309
  // setActiveSchedulerFormValue · submitSchedulerForm 모두 폐기.
@@ -9443,11 +9365,6 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
9443
9365
  );
9444
9366
  };
9445
9367
 
9446
- // Plain row label used as the list widget's identity (selection
9447
- // matching, cursor display string). Kept ANSI-free so visibleWidth
9448
- // and the selected-set string lookup work correctly.
9449
- const fmtEntry = (e: FsEntry): string => e.isDir ? `${e.name}/` : e.name;
9450
-
9451
9368
  // Colored variant for the list widget's `items` array — yazi-style
9452
9369
  // accent for folders, per-extension fileColor for files. The list
9453
9370
  // widget renders these straight through when preserveAnsi is true.
@@ -9884,92 +9801,6 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
9884
9801
  );
9885
9802
  };
9886
9803
 
9887
- // ── Workspace context builder ──
9888
- // Emitted once per chat turn (prepended to the user message) so the
9889
- // LLM knows what widgets are currently on screen and how to write
9890
- // to them via layout_setWidgetState / layout_addWidget without
9891
- // having to probe layout_getState first. Kept compact — iteration
9892
- // order matches visual layout (top-to-bottom, left-to-right).
9893
- //
9894
- // Writable surfaces:
9895
- // wd-scratch — primary canvas for notes / reports. Persists
9896
- // until the user clears or switches to memo mode.
9897
- // wd-preview — secondary canvas. Persists until the user
9898
- // navigates to a different file in the browser
9899
- // (file nav overwrites, which is by design).
9900
- //
9901
- // Reserved (LLM writes rejected with a helpful error):
9902
- // wd-browser, wd-log — dashboard re-renders these every frame
9903
- // from its own buffers (file list, chat
9904
- // transcript). Use layout_addWidget to
9905
- // spawn a fresh widget the dashboard will
9906
- // NOT touch.
9907
- const buildWorkspaceContext = (): string => {
9908
- try {
9909
- const pluginLayout = pluginHost.activeLayout();
9910
- let layoutForCtx: Layout;
9911
- if (pluginLayout) {
9912
- layoutForCtx = pluginLayout;
9913
- } else {
9914
- const { cols, rows: tr } = termSize();
9915
- const promptFrame = getLayoutPromptFrame(tr);
9916
- const topHeight = computePromptFrameGridHeight(tr, promptFrame);
9917
- layoutForCtx = workingDirLayoutForView(cols - 1, topHeight);
9918
- }
9919
- const visibleWidgets: Array<{ id: string; type: string; title?: string }> = [];
9920
- for (const row of layoutForCtx.rows) {
9921
- for (const cell of row.cells) {
9922
- if (!cell.widgetInstanceId) continue;
9923
- const inst = widgetHost.get(cell.widgetInstanceId);
9924
- if (!inst) continue;
9925
- visibleWidgets.push({
9926
- id: inst.id,
9927
- type: inst.type,
9928
- title: inst.character || undefined,
9929
- });
9930
- }
9931
- }
9932
- if (visibleWidgets.length === 0) return '';
9933
- const rows = visibleWidgets.map(w => {
9934
- const tag =
9935
- w.id === 'wd-scratch' ? ' ← writable canvas; persistent'
9936
- : w.id === 'wd-preview' ? ' ← writable canvas; overwritten on file-nav'
9937
- : w.id === 'wd-browser' ? ' ← READ-ONLY (dashboard-managed file list)'
9938
- : w.id === 'wd-log' ? ' ← READ-ONLY (chat transcript)'
9939
- : w.id.startsWith('wd-debug-') ? ' ← READ-ONLY (debug event surface; use debug_* tools)'
9940
- : ' ← persistent (spawned by LLM)';
9941
- const label = w.title ? ` "${w.title}"` : '';
9942
- return `- ${w.id} (${w.type})${label}${tag}`;
9943
- }).join('\n');
9944
- return [
9945
- '## Current dashboard workspace',
9946
- '',
9947
- 'The following widgets are visible right now. You have three host-level tools to mutate the layout:',
9948
- '- `layout_getState` — refresh view of the grid.',
9949
- '- `layout_setWidgetState({id, patch})` — merge a patch into a widget\'s state. For markdown widgets patch `{text: "..."}`.',
9950
- '- `layout_addWidget({type, row, col, character, config})` — spawn a new widget; dashboard will NOT re-render its state.',
9951
- '',
9952
- rows,
9953
- '',
9954
- 'Writing rules:',
9955
- '- To SHOW the user multi-line output (notes, analyses, lists, reports), write to `wd-scratch` via `layout_setWidgetState({id:"wd-scratch", patch:{text:"<content>"}})`. The dashboard auto-reopens that pane if the user had it closed.',
9956
- '- For a secondary canvas (e.g. side-by-side comparison), write to `wd-preview` the same way.',
9957
- '- DO NOT write to `wd-browser` or `wd-log` — the dashboard rejects those patches with an error.',
9958
- '- DO NOT write to `wd-debug-*`; use `debug_getState`, `debug_getCallStack`, `debug_setLevel`, `debug_openView`, and `debug_selectEvent`.',
9959
- '- For your own persistent widget (won\'t be overwritten by anything), spawn with `layout_addWidget` and pick your own id.',
9960
- '',
9961
- describeDashboardViewsForPrompt(viewRegistry),
9962
- '',
9963
- describePaneStateForPrompt(),
9964
- ].join('\n');
9965
- } catch {
9966
- // Workspace snapshot is best-effort — a failure here must not
9967
- // break the chat turn. Return empty so the user message flows
9968
- // through unchanged.
9969
- return '';
9970
- }
9971
- };
9972
-
9973
9804
  // ── LLM layout tools (W5) ──
9974
9805
  // Host-level tools that let the chat LLM reshape the dashboard.
9975
9806
  // When a plugin is active the tools edit its layout directly; when
@@ -12808,43 +12639,6 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
12808
12639
  onContextMenuMouse: (ev) => ctxMenuWire.onMouse(ev),
12809
12640
  });
12810
12641
  };
12811
- const openBrowserOnlyModal = (): void => {
12812
- const { cols: tc, rows: tr } = termSize();
12813
- const liveMode = resolveBrowserPreviewModalLiveMode(process.env.ELANOUS_PANE_MODAL_LIVE);
12814
- void openBrowserPaneModal({
12815
- browserWidgetInstanceId: browserWidgetInstanceIdForView(workingDir.view),
12816
- liveMode,
12817
- browserPaneRegistry,
12818
- widgetHost,
12819
- coordinator: display,
12820
- termCols: tc,
12821
- termRows: tr,
12822
- captureSnapshot: () => captureDeferredPane('browser'),
12823
- theme: currentThemeTokens(),
12824
- fmtEntryColored,
12825
- iconForEntry,
12826
- onSubmit: dispatchSidebarSubmit,
12827
- onDispose: () => { draw(); },
12828
- onCancel: () => { draw(); },
12829
- });
12830
- };
12831
- const openPreviewOnlyModal = (): void => {
12832
- const { cols: tc, rows: tr } = termSize();
12833
- const liveMode = (process.env.ELANOUS_PANE_MODAL_LIVE ?? 'on').toLowerCase() !== 'off';
12834
- void openPreviewPaneModal({
12835
- preview: dockedPreview,
12836
- previewWidgetInstanceId: 'wd-preview',
12837
- liveMode,
12838
- widgetHost,
12839
- coordinator: display,
12840
- termCols: tc,
12841
- termRows: tr,
12842
- captureSnapshot: () => captureDeferredPane('preview'),
12843
- theme: currentThemeTokens(),
12844
- onDispose: () => { draw(); },
12845
- onCancel: () => { draw(); },
12846
- });
12847
- };
12848
12642
  registerDashboardGlobalKeys({
12849
12643
  enableSupplementalGlobalKeys: getUserConfig().dashboard.enableSupplementalGlobalKeys,
12850
12644
  register: (binding) => { display.registerKeyBinding(binding); },
@@ -13068,6 +12862,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
13068
12862
  repaint: () => void;
13069
12863
  insertAtCursor?: (text: string) => void;
13070
12864
  submit?: (request?: string | TextInputExternalSubmitRequest) => void;
12865
+ getBufferText?: () => string;
13071
12866
  } = { repaint: () => {} };
13072
12867
  repaintPromptAfterRender = () => {
13073
12868
  if (shouldSuppressDashboardBottomArea()) {
@@ -13091,6 +12886,13 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
13091
12886
  // safe. Dispose on process exit to keep the listener set clean.
13092
12887
  const disposeResizeListener = installResizeListener({ draw: (opts) => draw(opts), promptCtl });
13093
12888
  process.on('exit', disposeResizeListener);
12889
+ // 외부 주입(`pty text`)을 사용자 타이핑과 섞지 않고 별도 대기열로 — 결함 #6(10-14).
12890
+ const disposeExternalInputHost = registerExternalInputHost(createDashboardExternalInputHost({
12891
+ isTurnActive: () => streamingInFlight,
12892
+ promptCtl,
12893
+ pushNotice: (line) => { chatLines.push(C.muted(` ${line}`)); chatScrollOffset = -1; draw(); },
12894
+ }));
12895
+ process.on('exit', disposeExternalInputHost);
13094
12896
 
13095
12897
  const publishScratchSurface = (
13096
12898
  source: string,
@@ -13109,6 +12911,13 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
13109
12911
  const detailViewerRuntime = createDashboardDetailViewerRuntime({
13110
12912
  setOpen: (open) => { setCompanionPopupOpen('detail', open); },
13111
12913
  requestRender: () => { requestDashboardRender('detail'); },
12914
+ // 채팅 단독 화면에선 그리드 투영이 안 돌아 팝업이 «(no preview content)» 였다 — 그리기 전에 싣는다.
12915
+ project: (snapshot) => {
12916
+ const detailWidget = widgetHost.get('wd-detail') as WidgetInstance<Record<string, unknown>> | null;
12917
+ if (detailWidget?.state && typeof detailWidget.state === 'object') {
12918
+ companionWidgetRuntime.projectDetailWidget(detailWidget, snapshot);
12919
+ }
12920
+ },
13112
12921
  });
13113
12922
  const companionWidgetRuntime = createDashboardCompanionWidgetRuntime();
13114
12923
  const clipboardHistoryRuntime = createDashboardClipboardHistoryRuntime();
@@ -13798,6 +13607,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
13798
13607
  let session: TerminalSession;
13799
13608
  try {
13800
13609
  if (req.kind === 'shell') {
13610
+ const shellSeat = resolveTuiShellSeat(req.cwd, process.env.COORD_ID);
13801
13611
  session = sessionRegistry.spawn(
13802
13612
  {
13803
13613
  title: 'terminal',
@@ -13805,6 +13615,12 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
13805
13615
  command: req.command,
13806
13616
  env: req.env,
13807
13617
  kind: 'shell',
13618
+ useRegistry: true,
13619
+ registryKind: 'shell',
13620
+ registryNickname: `tui-shell:${req.cwd}`,
13621
+ registryOrigin: { originRoot: 'elanous-internal', controller: 'tui-shell' },
13622
+ registryPurpose: `tui-shell:${shellSeat}`,
13623
+ registrySeat: shellSeat,
13808
13624
  onExit: handleExit,
13809
13625
  onTitleAction: handleTitleAction,
13810
13626
  },
@@ -13896,8 +13712,8 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
13896
13712
  openInteractiveTerminalPopup,
13897
13713
  });
13898
13714
  const TerminalPopup = terminalPopupRuntime;
13899
- const spawnGlobalTerminalModal = (): void => {
13900
- terminalPopupRuntime.spawnGlobalTerminalModal(workingDir.cwd);
13715
+ const spawnGlobalTerminalModal = (command?: string): void => {
13716
+ openInteractiveTerminalPopup({ kind: 'shell', cwd: workingDir.cwd, command });
13901
13717
  };
13902
13718
 
13903
13719
  // E3 (2026-05-17) — copyLastAssistantTurnToClipboard /
@@ -14019,7 +13835,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
14019
13835
  },
14020
13836
  toggleLogZoom: () => { toggleChatOnlyLayout(); },
14021
13837
  copyLastBlock: copyLastAssistantTurnToClipboard,
14022
- spawnTerminalModal: spawnGlobalTerminalModal,
13838
+ spawnTerminalModal: () => spawnGlobalTerminalModal(),
14023
13839
  copyLogPane: copyLogPaneToClipboard,
14024
13840
  // Ctrl+L — 터미널 클리어 후 전체 강제 리페인트(resize 리스너와 동일 레시피).
14025
13841
  // 외부 출력/아티팩트로 더러워진 화면 복구용 · 대화(chatLines)는 보존.
@@ -14088,6 +13904,8 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
14088
13904
  },
14089
13905
  onPreviewTerminalExpandChanged: chordFeedbackRuntime.onPreviewTerminalExpandChanged,
14090
13906
  onMissingPreviewTerminal: chordFeedbackRuntime.onMissingPreviewTerminal,
13907
+ // #19 — Ctrl+X f from a pane; the input path is the `ctrl+x f` input-core binding.
13908
+ toggleAllFolds: toggleAllLogFolds,
14091
13909
  });
14092
13910
 
14093
13911
  // ══════════════════════════════════════════════════════════════
@@ -15366,6 +15184,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
15366
15184
  // adds turn concurrency must key this by turn (or session+turn) first.
15367
15185
  let acpTurnToolSpecs: LLMToolSpec[] = [];
15368
15186
  let acpDispatchToolSelf: CoreTurnDispatchTool | null = null;
15187
+ let acpToolDispatchCount = 0;
15369
15188
  const trMod = await import('../tool-runtime/index.js');
15370
15189
  trMod.registerAllDefaultToolRuntimes();
15371
15190
  acpToolRuntime = trMod;
@@ -15420,6 +15239,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
15420
15239
  modelFamily: getModelFamily(inspectActiveProvider().model),
15421
15240
  rich: false,
15422
15241
  enabledTools: tools.map(t => t.name),
15242
+ seatBoot: true,
15423
15243
  }),
15424
15244
  ];
15425
15245
  },
@@ -15449,35 +15269,16 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
15449
15269
  // Codex-first decision as every other surface. The core bridge now
15450
15270
  // supplies userText to resolveModel, preserving explicit pins and
15451
15271
  // making this the actual model override rather than a display hint.
15452
- getActiveModel: ({ userText }) => {
15453
- const cfg = getUserConfig();
15454
- const decision = resolveRouteDecision({
15455
- provider: cfg.llm.provider,
15456
- configuredModel: inspectActiveProvider().model,
15457
- text: userText,
15458
- routePolicy: cfg.llm.routePolicy,
15459
- });
15460
- // Badge truthfulness(2026-07-19 goal-exec) — resolveRouteDecision 의 codex
15461
- // tier-policy 브랜치는 curated effort(예: balanced=low)를 찍지만, codex provider 는
15462
- // 그 값을 wire 로 보내지 않는다: 실제 effort 는 effectiveReasoningLevel(cfg)(config
15463
- // 주도, reasoningLevel 미설정 시 model-default high). 그대로 두면 완료 뱃지가
15464
- // "terra(low)" 로 떠 사용자가 모델이 약하게 돈다고 오해한다(실제 high). 실제 wire
15465
- // effort 로 덮어써 뱃지를 진실하게. decision.effort 는 표시 전용이라 라우팅 무영향.
15466
- const trueEffort = effectiveReasoningLevel(cfg.llm, decision.provider, decision.model);
15467
- const badgedDecision = trueEffort && trueEffort !== 'off'
15468
- ? { ...decision, effort: trueEffort }
15469
- : decision;
15470
- recordCurrentRouteDecision('dashboard', badgedDecision);
15471
- if (debug.enabled) debug.log('llm.route-decision', 'dashboard-acp', {
15472
- provider: decision.provider, model: decision.model, mission: decision.mission, source: decision.source,
15473
- });
15474
- return decision.model || null;
15475
- },
15272
+ // 본체 = acp-active-model.ts(실물 경로를 시험이 그대로 부르도록 뺐다 · TUI-MODEL-SESSION-SCOPE).
15273
+ getActiveModel: ({ userText }) => resolveDashboardActiveModel(userText),
15476
15274
  // ⭐ The assignment is deliberate, not a typo: it captures a reference to
15477
15275
  // this very dispatcher so `agentDispatchTool` below can route a
15478
15276
  // sub-agent's tool calls back through it. A plain named const would need
15479
15277
  // the closure hoisted out of this literal; this keeps the diff local.
15480
15278
  dispatchTool: acpDispatchToolSelf = async (name, args, ctx) => {
15279
+ // Count at the server-side boundary, before any tool effect and
15280
+ // before the ACP notification can reach the TUI client.
15281
+ acpToolDispatchCount++;
15481
15282
  const runtime = acpToolRuntime;
15482
15283
  const persist = acpPersistToolOutputPreview;
15483
15284
  if (!runtime || !persist) {
@@ -15699,14 +15500,36 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
15699
15500
  }
15700
15501
  subscribeSessionCwd((state) => { pushProjectSuggestion(state.cwd); });
15701
15502
  chatScrollOffset = -1;
15702
- void renderDashboardFirstScreenBand({
15503
+ const firstScreenBandInput = {
15703
15504
  history: chat.history,
15704
15505
  lines: chatLines,
15705
15506
  width: Math.max(0, termSize().cols - 4),
15507
+ // The band ships ko/en only; any other detected locale keeps the English rows.
15508
+ locale: detectLocale() === 'ko' ? 'ko' as const : 'en' as const,
15706
15509
  draw: () => draw(),
15707
- observe: (data) => { try { debug.log('dashboard.first-screen-band', 'resolved', data); } catch { /* observation is best-effort */ } },
15708
- });
15510
+ observe: (data: { daemon: boolean; hasPwa: boolean; hasTailnet: boolean }) => { try { debug.log('dashboard.first-screen-band', 'resolved', data); } catch { /* observation is best-effort */ } },
15511
+ };
15512
+ void (bootBannerMode === 'full'
15513
+ ? renderDashboardFirstScreenBand(firstScreenBandInput)
15514
+ : renderMinimalBootBand({
15515
+ ...firstScreenBandInput,
15516
+ guidance: needsOnboarding(getUserConfig()),
15517
+ held: bootBannerHeld,
15518
+ show: () => runNexusShow({ format: 'json', out: { log: () => {}, error: () => {} } }),
15519
+ daemonLink: resolveTuiDaemonLink,
15520
+ styleFailure: (line) => C.warning(line),
15521
+ observeHeld: (data) => { try { debug.log('dashboard.first-screen-band', 'held', data); } catch { /* observation is best-effort */ } },
15522
+ }));
15709
15523
 
15524
+ // 🪪 L1 — 자리 부트(seat-boot-preamble.ts): 자리면 첫 화면에 한 줄.
15525
+ // 🪪 L2-lite(seat-local-instructions.ts): 자리 로컬 지시가 없으면 템플릿 생성(덮어쓰기 0) ⊕ 대화 끝 «지난 세션» 기록.
15526
+ const seatLocal = ensureSeatLocalInstructions(getSessionCwd());
15527
+ if (seatLocal.status === 'created') chatLines.push(C.muted(` 📝 자리 로컬 지시를 만들었다 — ${seatLocal.path} (사람이 고쳐도 된다)`));
15528
+ else if (seatLocal.status === 'exists' && seatLocal.missingPrinciple) chatLines.push(C.muted(` 💡 ${seatLocal.path} 에 제1원칙 절이 없다 — 넣을지 사람이 정한다(덮어쓰지 않음)`));
15529
+ installSeatSessionRecorder({ getCwd: () => getSessionCwd(), getHistory: () => chat.history });
15530
+ const seatBoot = describeSeatBoot(getSessionCwd());
15531
+ if (seatBoot) chatLines.push(C.muted(` 🪪 ${seatBoot.seat} 자리 · 안 읽은 우편 ${seatBoot.unread ?? '미관측'} — 부트 카드를 턴마다 싣는다`));
15532
+ if (dashboardAcpBootResult.mode !== 'resumed' && !opts.resumeSessionId) startSeatBootConversation({ reason: 'boot' });
15710
15533
  tuiSeatAskTimer = setInterval(pollTuiSeatAnswers, 10_000);
15711
15534
  tuiSeatAskTimer.unref();
15712
15535
  pollTuiSeatAnswers();
@@ -16691,7 +16514,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
16691
16514
  sync.cursors[sync.focus] = Math.max(0, Math.min(sync.cursors[sync.focus]! + delta, sync.lists[sync.focus]!.length - 1));
16692
16515
  } else if (mr > logViewport.startRow && mr <= logViewport.endRow) {
16693
16516
  // Scroll the log pane
16694
- const maxScr = Math.max(0, chatLines.length - logViewport.height);
16517
+ const maxScr = logScrollMax(logViewport.height);
16695
16518
  chatScrollOffset = Math.max(0, Math.min((chatScrollOffset < 0 ? maxScr : chatScrollOffset) + delta, maxScr));
16696
16519
  if (delta > 0 && chatScrollOffset >= maxScr) chatScrollOffset = -1;
16697
16520
  }
@@ -16766,17 +16589,19 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
16766
16589
  // 테스트가 그 순서를 다시 베껴야 하고, 베낀 테스트는 배선 회귀를 못 잡는다.
16767
16590
  const interrupted = lastTurnFinalStatus === 'interrupted';
16768
16591
  const queuedBeforeDrain = turnTypeaheadRef.state.queuedSubmissions.length;
16769
- const drained = drainTurnTypeaheadOnce(turnTypeaheadRef.state, nextInitial, { interrupted });
16592
+ // ⭐ 드레인 → 레지스트리 해제 → Enter 주입은 다리 모듈이 한 함수로 한다(시험이 같은 함수를 문다).
16593
+ const drained = handoffTurnTypeaheadAtTurnEnd(turnTypeaheadRef, nextInitial, { interrupted }, () => {
16594
+ injectKey({ name: 'enter', ctrl: false, shift: false });
16595
+ });
16770
16596
  lastTurnFinalStatus = undefined;
16771
- turnTypeaheadRef.state = drained.state;
16772
16597
  nextInitial = drained.nextInitial;
16773
16598
  const queuedTurnEndText = drained.injectEnter ? drained.nextInitial : undefined;
16774
16599
  if (interrupted && queuedBeforeDrain > 0) {
16775
16600
  debug.log('dashboard.turn-typeahead', 'restored-after-interrupt', { count: queuedBeforeDrain });
16776
16601
  }
16777
- if (drained.injectEnter) injectKey({ name: 'enter', ctrl: false, shift: false });
16778
16602
  draw();
16779
- const { cols: inputCols } = termSize();
16603
+ const getInputCols = () => termSize().cols;
16604
+ const inputCols = getInputCols();
16780
16605
  // Row is published by draw() via the `input-prompt` zone's
16781
16606
  // resolved geometry — no `termRows - N` math here anymore.
16782
16607
  // The composer is the single source of truth; if the layout
@@ -16787,6 +16612,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
16787
16612
  promptFrame: currentPromptFrame(termSize().rows),
16788
16613
  getPromptFrame: () => currentPromptFrame(termSize().rows),
16789
16614
  inputCols,
16615
+ getInputCols,
16790
16616
  surfaceRegistry: getSurfaceRegistry(),
16791
16617
  invalidateRenderCacheRow,
16792
16618
  buildPromptFrameDividerRows,
@@ -16800,8 +16626,9 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
16800
16626
  paintFrameNow: () => drawNow(),
16801
16627
  preferHistoryArrowKeys: slashQuickMode,
16802
16628
  history: inputHistory,
16629
+ // TUI-INPUT-PLACEHOLDER-OFF — provider 가 있으면 빈 입력창은 비워 둔다(대표 «불필요한 가이드 없애라»).
16803
16630
  placeholder: anyProviderAvailable()
16804
- ? '말 한 줄로 시작 — 질문하거나 «하니스로 구현 …» · /command · /path/to.pdf 첨부'
16631
+ ? ''
16805
16632
  : '/quit /clear (run `elanous setup` — no LLM provider available)',
16806
16633
  debugLog: debug.enabled ? (event, label, payload) => debug.log(event, label, payload) : undefined,
16807
16634
  textInputOpts: {
@@ -17657,7 +17484,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
17657
17484
  openDetailViewer: (title, lines) => { setDetailViewer(title, lines); },
17658
17485
  },
17659
17486
  undo: {
17660
- refreshGitDirty: () => { refreshGitDirty(getSessionCwd(), { force: true }); },
17487
+ refreshGitDirty: () => { void refreshGitDirtyAsync(getSessionCwd(), { force: true }).then(() => { try { draw(); } catch { /* noop */ } }, () => { /* noop */ }); },
17661
17488
  bold: C.bold,
17662
17489
  },
17663
17490
  delta: {
@@ -18043,6 +17870,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
18043
17870
  pushTurnSeparator: () => { pushTurnSeparator(); },
18044
17871
  getLogFoldMode: () => logFoldMode,
18045
17872
  setLogFoldMode: (mode) => { logFoldMode = mode; },
17873
+ setAllFolds: (expanded) => foldStack.setAll(expanded),
18046
17874
  copyEntireLog: async () => { await copyLogBlock(-1, 'all'); },
18047
17875
  returnFocusToInput: () => {
18048
17876
  const sourceFocus = workingDir.focus;
@@ -18140,6 +17968,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
18140
17968
  },
18141
17969
  termSlash: {
18142
17970
  slashRuntime: termSlashRuntime,
17971
+ openNewTerminal: spawnGlobalTerminalModal,
18143
17972
  sessionRegistry: sessionRegistry as unknown as DashboardSlashContext['termSlash']['sessionRegistry'],
18144
17973
  terminalMatrix: terminalMatrix as unknown as DashboardSlashContext['termSlash']['terminalMatrix'],
18145
17974
  vwRegistry: {
@@ -18945,10 +18774,11 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
18945
18774
  userConfig: args.userConfig,
18946
18775
  rich: false,
18947
18776
  enabledTools: tools.map(t => t.name),
18777
+ seatBoot: true,
18948
18778
  }),
18949
18779
  ];
18950
18780
  },
18951
- runAutoCompact: async ({ preamble, chatHistory, userMsg }) => {
18781
+ runAutoCompact: async ({ preamble, chatHistory, userMsg, onPrePassApplied }) => {
18952
18782
  const compactMod = await import('../compact/index.js');
18953
18783
  const { shouldAutoCompact, compactConversationPartial, compactConversation, runCompactPipeline, setVerifyProbeEnabled } = compactMod;
18954
18784
  const { renderCompactBoundary } = await import('../chat/compact-boundary.js');
@@ -18987,8 +18817,10 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
18987
18817
  getCompactProvider: () => getDefaultCompactProvider(),
18988
18818
  setVerifyProbeEnabled,
18989
18819
  sessionId: attachedSessionId ?? undefined,
18820
+ onPrePassApplied,
18990
18821
  });
18991
18822
  },
18823
+ readToolDispatchCount: () => opts.remote ? null : acpToolDispatchCount,
18992
18824
  attachChatStreamingKeys,
18993
18825
  createOptionalSpecs: async () => {
18994
18826
  const uc = (await import('../user-config.js')).getUserConfig();
@@ -19112,7 +18944,9 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
19112
18944
  recordTurnMetrics: async (fullResponse) => {
19113
18945
  await recordDashboardTurnMetrics({
19114
18946
  chatHistory: chat.history as ChatMessage[],
19115
- model: inspectActiveProvider().model,
18947
+ // 실제 턴 모델로 기록한다 — 설정 모델이면 ctx 최대치·단가가 다른 모델 것이 된다.
18948
+ // ACP 서버가 사용량에 실어 보낸 턴 모델 → 없으면 백엔드가 확인한 runtime 모델 → 설정.
18949
+ model: latestTurnUsage?.model ?? inspectActiveProvider(undefined, activeAcpRuntimeModel()).model,
19116
18950
  fullResponse,
19117
18951
  turnStartedAt,
19118
18952
  usage: latestTurnUsage,
@@ -19175,6 +19009,10 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
19175
19009
  },
19176
19010
  warningLine: (message) => C.warning(`${ICONS.warning} ${message}`),
19177
19011
  pushErrorLine: (message) => { chatLines.push(C.error(`Error: ${message}`)); },
19012
+ pushFailureNotice: (notice, raw) => {
19013
+ chatLines.push(C.warning(notice));
19014
+ detailViewerRuntime.stage('turn error', raw.split(/\r?\n/));
19015
+ },
19178
19016
  finalizeTurn: (finalStatus, finalError) => {
19179
19017
  lastTurnFinalStatus = finalStatus;
19180
19018
  clearEscAbortToolState(escAbortToolState);
@@ -19219,7 +19057,15 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
19219
19057
  }
19220
19058
  let goalLoopBudget = 100; // hard safety cap independent of /goal budget
19221
19059
  let lastTurnAborted = false;
19060
+ let goalLoopIteration = 0;
19222
19061
  do {
19062
+ // 앞 반복의 finalizeTurn 이 손잡이를 멈췄다 — 반복이 «실제로 시작될 때만» 새 표시를 단다(#5).
19063
+ thinking = goalLoopIterationThinking(goalLoopIteration++, thinking, () => startPinnedThinking({
19064
+ target: chatFooterLine,
19065
+ onFrame: () => { pinChatTail(); draw(); },
19066
+ message: 'Thinking',
19067
+ metrics: { startedAt: Date.now(), hint: 'esc 중단' },
19068
+ }));
19223
19069
  const turnText = goalLoopUserText ?? tok.text;
19224
19070
  await runDashboardChatMainSubmitIntent({
19225
19071
  submit: createDashboardChatMainTurnSubmit({