elanous 0.2.28 → 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 (609) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{y1ltt7oCZxVpC6zVPhZ2O → 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-fa46d4588e8442c2.js → page-a5635eba0d73b84e.js} +1 -1
  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-66ad46ed0279feb9.js → page-86feb08080261a2f.js} +1 -1
  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-646b50f63b6fe732.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-6f131b51193a36f9.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-9eb56166774eb256.js +1 -0
  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/release/release-loop.yaml +6 -2
  277. package/package.json +1 -1
  278. package/plugins/agent-team/agents/research.md +1 -0
  279. package/scripts/ci-typecheck-changed.ts +3 -2
  280. package/scripts/coord-channel-watch.sh +26 -6
  281. package/scripts/coord-role-pack.ts +143 -0
  282. package/scripts/lib/morning-report-options.ts +41 -0
  283. package/scripts/pr-land-extra-remote-gates.ts +49 -0
  284. package/scripts/release-loop/gate-batch-safe.ts +23 -0
  285. package/scripts/release-loop/gate-history.ts +422 -0
  286. package/scripts/release-loop/gate-node.ts +310 -46
  287. package/scripts/release-loop/gate-triage-node.ts +190 -0
  288. package/scripts/release-loop/spawn-lane.ts +68 -0
  289. package/scripts/release-loop/tui-node-checks.ts +23 -0
  290. package/scripts/release-loop/version-node.ts +62 -4
  291. package/scripts/test-deterministic.ts +41 -12
  292. package/scripts/usage-rollup.ts +11 -3
  293. package/src/acp/core-turn-bridge.ts +98 -22
  294. package/src/acp/elanous-extensions.ts +2 -0
  295. package/src/acp/server.ts +2 -0
  296. package/src/agent/ref-grounding.ts +18 -0
  297. package/src/agent-substrate/pr-reviewer.ts +29 -21
  298. package/src/budget/pty-usage-reemit.ts +7 -0
  299. package/src/budget/run-usage-rollup.ts +9 -0
  300. package/src/budget/usage-daily-store.ts +98 -0
  301. package/src/capture/tui-self-report.ts +22 -4
  302. package/src/chat/index.ts +31 -10
  303. package/src/chat/pickers/modal-runtime.ts +1 -0
  304. package/src/chat/pickers/modals.ts +3 -1
  305. package/src/chat/turn-typeahead.ts +123 -16
  306. package/src/cli/dashboard-name-flag.ts +48 -0
  307. package/src/cli/doctor-cli.ts +80 -0
  308. package/src/cli/log-event-names.ts +12 -0
  309. package/src/cli/msg-cli.ts +45 -2
  310. package/src/cli/pr-cli.ts +382 -105
  311. package/src/cli/pr-land-heavy-remote.ts +233 -0
  312. package/src/cli/pr-land-overlap-evidence.ts +104 -5
  313. package/src/cli/pty-takeover-cli.ts +125 -16
  314. package/src/cli/release-cli.ts +44 -2
  315. package/src/cli/remote-resolve.ts +2 -1
  316. package/src/cli/seat-cli.ts +26 -16
  317. package/src/cli/tasks-cli.ts +8 -2
  318. package/src/cli/usage-cli.ts +146 -12
  319. package/src/cli/usage-daily-cli.ts +84 -0
  320. package/src/context-bus/context-now.ts +82 -5
  321. package/src/core-turn/auth-rejected-notice.ts +41 -0
  322. package/src/core-turn/run-core-turn.ts +13 -2
  323. package/src/core-turn/run-goal-loop.ts +17 -1
  324. package/src/core-turn/short-question.ts +45 -12
  325. package/src/core-turn/types.ts +7 -0
  326. package/src/dashboard/acp-active-model.ts +40 -0
  327. package/src/dashboard/auto-compact-runtime.ts +2 -0
  328. package/src/dashboard/boot-banner.ts +80 -0
  329. package/src/dashboard/dashboard-status-lines.ts +11 -0
  330. package/src/dashboard/detail-viewer-runtime.ts +15 -2
  331. package/src/dashboard/event-loop-stall-monitor.ts +4 -0
  332. package/src/dashboard/goal-loop-thinking.ts +16 -0
  333. package/src/dashboard/hitl-boot.ts +9 -4
  334. package/src/dashboard/index.ts +228 -387
  335. package/src/dashboard/input/chat-main-entry-runtime.ts +2 -0
  336. package/src/dashboard/input/chat-main-log-actions.ts +4 -0
  337. package/src/dashboard/input/chat-main-log-command.ts +12 -1
  338. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +172 -3
  339. package/src/dashboard/input/chat-main-session.ts +6 -2
  340. package/src/dashboard/input/chat-main-slash-command.ts +7 -0
  341. package/src/dashboard/input/chat-main-turn.ts +2 -1
  342. package/src/dashboard/input/compact-prepass-recovery.ts +97 -0
  343. package/src/dashboard/input/dashboard-chord-actions.ts +10 -1
  344. package/src/dashboard/input/dashboard-chord-runtime.ts +2 -0
  345. package/src/dashboard/input/external-input-host.ts +45 -0
  346. package/src/dashboard/input/log-fold-binding.ts +18 -0
  347. package/src/dashboard/input/mouse-wiring.ts +17 -4
  348. package/src/dashboard/input/turn-steer-bridge.ts +94 -0
  349. package/src/dashboard/log-click-runtime.ts +5 -3
  350. package/src/dashboard/running-build-status.ts +74 -0
  351. package/src/dashboard/seat-boot-preamble.ts +113 -0
  352. package/src/dashboard/seat-local-instructions.ts +305 -0
  353. package/src/dashboard/slash-runtime/dashboard-handlers.ts +100 -28
  354. package/src/dashboard/slash-runtime/model-choices.ts +35 -0
  355. package/src/dashboard/term-slash-runtime.ts +15 -0
  356. package/src/dashboard/turn-preamble.ts +30 -2
  357. package/src/dashboard/turn-session-layers.ts +176 -0
  358. package/src/dashboard/turn-stream-formatter.ts +14 -6
  359. package/src/dashboard/turn-stream-presentation-applier.ts +8 -0
  360. package/src/domains/release-tool.ts +8 -9
  361. package/src/domains/surface-events.ts +4 -1
  362. package/src/domains/watch-default-scheduler.ts +8 -9
  363. package/src/fold-stack.ts +24 -1
  364. package/src/git-fs/dirty.ts +32 -4
  365. package/src/git-fs/index.ts +43 -1
  366. package/src/graph-runner/runner.ts +1 -0
  367. package/src/harness/harness-gc.ts +32 -5
  368. package/src/index.ts +14 -1
  369. package/src/input/external-input-queue.ts +219 -0
  370. package/src/interactive-terminal-modal.ts +13 -0
  371. package/src/llm/route-decision.ts +25 -0
  372. package/src/llm-stream-retry-display.ts +59 -0
  373. package/src/llm.ts +253 -55
  374. package/src/log-entry.ts +3 -3
  375. package/src/log-pane/search.ts +29 -4
  376. package/src/loops/agent-reply.ts +256 -0
  377. package/src/loops/budget.ts +37 -7
  378. package/src/loops/loop-cli.ts +3 -2
  379. package/src/loops/msg-address.ts +57 -0
  380. package/src/loops/msg-wake.ts +282 -0
  381. package/src/loops/orchestrator/inbox.ts +60 -3
  382. package/src/loops/orchestrator/tick.ts +24 -4
  383. package/src/loops/registry.ts +42 -4
  384. package/src/memory.ts +20 -5
  385. package/src/native-tool-catalog.ts +125 -0
  386. package/src/nexus/api/http-server.ts +5 -0
  387. package/src/nexus/api/ops-api.ts +2 -0
  388. package/src/nexus/api/project-autopsy.ts +127 -0
  389. package/src/nexus/api/terminals.ts +3 -0
  390. package/src/nexus/api/workflow-approvals.ts +2 -0
  391. package/src/nexus/onboarding/first-boot-wizard.ts +56 -2
  392. package/src/oauth/codex-account-store.ts +15 -3
  393. package/src/oauth/codex-billing-route.ts +31 -0
  394. package/src/ops/overview-collect.ts +19 -2
  395. package/src/panes/log-pane.ts +67 -8
  396. package/src/persona/presets.ts +44 -0
  397. package/src/plugins/maker/wizard-generate.ts +6 -4
  398. package/src/preview/terminal.ts +14 -1
  399. package/src/prompt-cache/types.ts +2 -0
  400. package/src/prompt-enhance/enhance.ts +24 -8
  401. package/src/prompt-library/universal-preamble.ts +273 -56
  402. package/src/pty-shell/pty-control-ipc.ts +4 -1
  403. package/src/pty-shell/pty-manifest.ts +77 -5
  404. package/src/pty-shell/registry.ts +19 -2
  405. package/src/pty-shell/tui-run-state.ts +253 -0
  406. package/src/release-loop/light-rc.ts +28 -3
  407. package/src/release-loop/rehearsal.ts +1 -1
  408. package/src/render.ts +5 -1
  409. package/src/seat-loop/seat-report.ts +42 -2
  410. package/src/self-dev/run-supervisor.ts +71 -5
  411. package/src/self-dev/shard-aggregate.ts +2 -0
  412. package/src/self-dev/shard-run.ts +23 -2
  413. package/src/self-health/signatures.ts +132 -0
  414. package/src/self-implement/doctor-visit.ts +118 -0
  415. package/src/self-implement/gate-cli.ts +11 -2
  416. package/src/self-implement/goal-author-decompose.ts +80 -16
  417. package/src/self-implement/goal-author.ts +114 -72
  418. package/src/self-implement/goal-authoring-grounding.ts +1 -1
  419. package/src/self-implement/goal-file-name.ts +65 -0
  420. package/src/self-implement/ground-goal.ts +2 -1
  421. package/src/self-implement/host-regate.ts +14 -0
  422. package/src/self-implement/review-mustfix-class.ts +115 -0
  423. package/src/self-implement/run-ledger.ts +111 -7
  424. package/src/self-implement/running-runs.ts +10 -6
  425. package/src/self-implement/self-implement-runtime.ts +32 -0
  426. package/src/session/pending-input.ts +62 -11
  427. package/src/session-runtime/index.ts +7 -1
  428. package/src/skills/tools/ops-ledger.ts +707 -0
  429. package/src/skills/tools/persistent-grounding.ts +47 -7
  430. package/src/skills/tools/shell.ts +117 -1
  431. package/src/status/bar.ts +32 -2
  432. package/src/status/status-provider-info.ts +58 -0
  433. package/src/task-agent/rejudge-on-head.ts +4 -1
  434. package/src/task-agent/remote-rejudge-bind.ts +34 -5
  435. package/src/task-agent/repair-cycle.ts +13 -0
  436. package/src/task-orchestrator/surfaces/kubectl-transient-retry.ts +51 -0
  437. package/src/task-orchestrator/surfaces/pod-command-job.ts +63 -7
  438. package/src/task-orchestrator/surfaces/pod-install-slots.ts +6 -11
  439. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +76 -0
  440. package/src/task-orchestrator/surfaces/self-implement-pod.ts +107 -33
  441. package/src/terminal/session-registry.ts +6 -0
  442. package/src/thinking-line.ts +12 -3
  443. package/src/tool-runtime/index.ts +4 -0
  444. package/src/tool-runtime/ops-ledger-runtimes.ts +84 -0
  445. package/src/tool-runtime/ref-consult-runtime.ts +17 -2
  446. package/src/tool-runtime/run-shell-runtime.ts +4 -1
  447. package/src/tool-runtime/self-cognition-runtimes.ts +5 -1
  448. package/src/tui.ts +5 -0
  449. package/src/user-config.ts +54 -6
  450. package/src/ux-sim/fake-llm.ts +29 -0
  451. package/src/ux-sim/in-process-cli.ts +175 -0
  452. package/src/version/packed-revision.json +1 -1
  453. package/apps/pwa/out/_next/static/chunks/1027.a0f04663d24c2779.js +0 -1
  454. package/apps/pwa/out/_next/static/chunks/1038.676007ae505822e7.js +0 -1
  455. package/apps/pwa/out/_next/static/chunks/1113.a37eadf7f740d955.js +0 -1
  456. package/apps/pwa/out/_next/static/chunks/112-fa7c526c20ce1405.js +0 -1
  457. package/apps/pwa/out/_next/static/chunks/1144.5fa1fa1d48dbcd12.js +0 -36
  458. package/apps/pwa/out/_next/static/chunks/1146.80d15ea7c6e6ee95.js +0 -1
  459. package/apps/pwa/out/_next/static/chunks/1157.f08bf2b70915e176.js +0 -148
  460. package/apps/pwa/out/_next/static/chunks/119b405e.8fdd0e44d1ff37aa.js +0 -1
  461. package/apps/pwa/out/_next/static/chunks/1296.04560d98e73fbf51.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/1314-f604ba013ec535b0.js +0 -1
  463. package/apps/pwa/out/_next/static/chunks/1454-29d1d773d5996a49.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/1464.f3209af0d8ae4ff2.js +0 -1
  465. package/apps/pwa/out/_next/static/chunks/1729-d73dd25e564679d4.js +0 -1
  466. package/apps/pwa/out/_next/static/chunks/1843.5924c24295243261.js +0 -27
  467. package/apps/pwa/out/_next/static/chunks/1987.e28149724b92918b.js +0 -1
  468. package/apps/pwa/out/_next/static/chunks/2066-5ca18ffa5a4be68b.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/2240.d10a66695155fd93.js +0 -1
  470. package/apps/pwa/out/_next/static/chunks/2391.e2cbc98d4abbb41a.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/2528.3868070ef1be69f9.js +0 -24
  472. package/apps/pwa/out/_next/static/chunks/2566-734cb83bbd405886.js +0 -1
  473. package/apps/pwa/out/_next/static/chunks/2697.76ca2ac3efef6f3b.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/275.0e6bad414729bfa0.js +0 -32
  475. package/apps/pwa/out/_next/static/chunks/2803-33bdae771855a8d1.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/3143.257997a5f1ed79df.js +0 -34
  477. package/apps/pwa/out/_next/static/chunks/3259-86f3be56e43eaf6a.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/3280-e177c33bfbdcfb0a.js +0 -1
  479. package/apps/pwa/out/_next/static/chunks/3294-2b6a6d45a46a6c1c.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/3309.364573ceedbdfd5f.js +0 -1
  481. package/apps/pwa/out/_next/static/chunks/3522.758840fc5e7fe630.js +0 -287
  482. package/apps/pwa/out/_next/static/chunks/3525-a7c989c1a661e880.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/3694.b1a66387756458c0.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/370.124f9e678a76fc01.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/3797-9643105335e660fe.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/4084.15ecaf4240bd9e77.js +0 -286
  487. package/apps/pwa/out/_next/static/chunks/4089-b3382b8843114eee.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/4293.928a8d573c16aab7.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/4402.f9238a3b18a7bd43.js +0 -1
  490. package/apps/pwa/out/_next/static/chunks/4490-9b090b0f9427f902.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/4548.13502d0ca3b4f862.js +0 -8
  492. package/apps/pwa/out/_next/static/chunks/4599-548bc96cda44a5a7.js +0 -1
  493. package/apps/pwa/out/_next/static/chunks/4625.206574e33a9e7ae8.js +0 -104
  494. package/apps/pwa/out/_next/static/chunks/4862-392c9a71f0d8dfb4.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/5054.2906d1b02542edc5.js +0 -149
  496. package/apps/pwa/out/_next/static/chunks/5102-c822bbbee5a022a4.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/5194-8c93f2e7e4b6f717.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/5305-bacd7eca0b9a5848.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/5311.9071ee3f44fd7ff5.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/5369.9f34353442daa421.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/589-49d730cb8138b397.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/5904-264a6412ae3c9028.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/5980.728531d5c566535c.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/599-56f2c0a5cc4a7295.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/6011.f525002e21bef0ac.js +0 -23
  506. package/apps/pwa/out/_next/static/chunks/6132.4381ab93683f1acf.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/6149.2e698635e454d8f6.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/6356-0afafc4230cf9767.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/6406.64756073f7df35b8.js +0 -77
  510. package/apps/pwa/out/_next/static/chunks/6479-16e62aedafa0e310.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/6599.b5246b46a2453329.js +0 -64
  512. package/apps/pwa/out/_next/static/chunks/6610.5c26eec011565acb.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/666.37d18474edc1c552.js +0 -2
  514. package/apps/pwa/out/_next/static/chunks/6904.a0b5b1ed4f2d2c20.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/7247-1f4aba94aba50d9f.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/7274-e71a7c5b7760cd02.js +0 -1
  517. package/apps/pwa/out/_next/static/chunks/7290.1fcaeef3adb5d0d4.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/7477-2c64e42760f82f33.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/7505-47002b76ff1aef6c.js +0 -1
  520. package/apps/pwa/out/_next/static/chunks/7600-11884ca4da68e5d9.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/7607.40d8bb3689697ccb.js +0 -62
  522. package/apps/pwa/out/_next/static/chunks/7752.5cbdd0b433c54af9.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/7763.f51fcc19ca1414ec.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/7785.846140c859b1adf6.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/7807-a0fdac6393e0bf36.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/7837-20a63b4b7e9342b1.js +0 -1
  527. package/apps/pwa/out/_next/static/chunks/800.7815414cf280545d.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/8085-1e5fce59500a2cc2.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/8100.415f2105faa63e97.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/8290.701aa42ed13aa767.js +0 -226
  531. package/apps/pwa/out/_next/static/chunks/83a80514-b897b64df43ce108.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/8444.d9c74214a3145a43.js +0 -93
  533. package/apps/pwa/out/_next/static/chunks/8569.98c915534928c7f9.js +0 -24
  534. package/apps/pwa/out/_next/static/chunks/8591.b1c7f876e5ec7cfb.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/8715-f63756021d3ab989.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/8879.776c2ec7732aa114.js +0 -115
  537. package/apps/pwa/out/_next/static/chunks/8881.ddca15b3c82c490c.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/8946.5da5c87f32a2e1a8.js +0 -41
  539. package/apps/pwa/out/_next/static/chunks/9117.080b9b75be90e14d.js +0 -74
  540. package/apps/pwa/out/_next/static/chunks/9167.f3ecb28f367d6e69.js +0 -94
  541. package/apps/pwa/out/_next/static/chunks/9224.66095370ee28c93b.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/9238-0682b013c83d6449.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/9449.d3ed795da4befb1c.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/949.1e7d45ccb71580aa.js +0 -90
  545. package/apps/pwa/out/_next/static/chunks/9638-d268329f2c6f4f8d.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/9842-d6644eb53d3dc6bf.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/9863.94ca3263e760696e.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/9938.b23e4d4dfa0114cd.js +0 -79
  549. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d9babd8795f396a5.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/app/approvals/page-5ab1e47978577c5e.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-24453f6a302816b4.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/app/board/page-6c131d30bb1cf871.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/app/bots/page-dc0772b11861af51.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/app/chat/page-5159dc8752c6cd29.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/app/consult/page-c5a2478861c08b87.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/app/control/page-f722a9dec084e08b.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/app/decisions/page-256ffd365d32e100.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e0de78ae7b99f01c.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/app/editor/page-cfbdc44b708d9801.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/app/exec/page-4c741eb760f2f77c.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/app/field/page-e9ba98f5f1440a21.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/app/healthz/route-d9babd8795f396a5.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/app/inside/page-dafc901bb1b72b5f.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/app/intake/page-2f6f303fa114ec24.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/app/layout-1634081c5272006c.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/app/live/page-ced0bcfc6542b3fc.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/app/live-run/page-bb1f05cd51c38944.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/app/market/page-db069b48a59c8c00.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-f736324afa2117c1.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/app/not-found-435f5e2faf02bc01.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/app/observatory/page-497e0eedf20e7890.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-a8d28fdf995e16ea.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-8966452228753c5e.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fd5d18656cb432b6.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/outputs/page-5663779cb1a37609.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/page-66a67eb19ebd976b.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/reflection/page-3b492aa78cf3c4a6.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c71267e7681da982.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/app/sessions/page-a21d1e1797172692.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-cb249e81ed339318.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/app/settings/page-781cfc5114e097da.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-478157214db6a023.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/app/setup/layout-d9babd8795f396a5.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/app/setup/page-86141f12cf090b7f.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/app/share/page-7256c73bb1c36751.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/app/showroom/page-5c738ca7adef3de5.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/app/tasks/page-0138c8091ec17224.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/app/term/page-cc2f24f16d85e735.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/app/today/page-979d318a534e92da.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/app/trace/page-182d394f7e6e096b.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/app/vault/page-21050928a697ed7a.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-44b9d807005a9030.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/app/workflows/page-601fb77340e63c9a.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/app/workspace/page-75d3fb5d47af0edf.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-11bf9e5725a72c22.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/dcf24383-2f82e35f2d827393.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/e117f801.e92bf10242653497.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/e87d89b9.2e71c0ae475d28a1.js +0 -122
  599. package/apps/pwa/out/_next/static/chunks/framework-bf135b997155e90e.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/main-5571537543bea91c.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/main-app-25c51c7df7f3a442.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/pages/_app-e3b2c1f5d82abd65.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/pages/_error-083f2e23e9bc3641.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/webpack-e94d22b7a028217b.js +0 -1
  605. package/src/dashboard/bench-slash-runtime.ts +0 -40
  606. package/src/dashboard/input/search-modal-router.ts +0 -9
  607. package/src/dashboard/modals/pane-key-router.ts +0 -27
  608. package/src/dashboard/view-slash-runtime.ts +0 -48
  609. /package/apps/pwa/out/_next/static/{y1ltt7oCZxVpC6zVPhZ2O → cIpv5nU9AycwYWZI9H589}/_ssgManifest.js +0 -0
@@ -0,0 +1,305 @@
1
+ // 🪪 L2-lite — TUI 가 자기 자리 로컬 지시(`AGENTS.local.md`)를 «만들고 이어 쓴다» (TUI-SEAT-CONTINUITY · 2026-10-14).
2
+ //
3
+ // S: 자리(`~/elanous-hq/seats/<자리>`)에서 TUI 를 다시 띄우면 지난 세션에 무엇을 하다 나갔는지 모른다.
4
+ // TUI 는 파일 기억(`buildMemoryInjection`)을 받지 않고 턴·세션 끝 기억 쓰기도 없다 — 연속성 장치가 0 이다.
5
+ // A: 둘을 한다.
6
+ // ① 생성 — 자리 디렉터리에서 뜰 때 로컬 지시 파일이 «하나도» 없으면 템플릿으로 `AGENTS.local.md` 를 만든다.
7
+ // 재료: seat-state/<자리>/README.md 머리 ⊕ 자리 이름 ⊕ 저장소 AGENTS.md §제1원칙 요지(출처 줄) ⊕ «## 시작하면» 기본 절차.
8
+ // ⛔ 사람이 쓴 파일은 절대 덮어쓰지 않는다 — `AGENTS.local.md` 든 `CLAUDE.local.md` 든 있으면 생성 0
9
+ // (`CLAUDE.local.md` 만 있는데 `AGENTS.local.md` 를 만들면 앵커 로더가 사람 파일을 shadowed 로 가린다).
10
+ // ② 이어쓰기 — «지난 세션»은 TUI 가 «통째로 소유하는» 별도 파일(자리 루트 `.AGENTS.local.last-session.md` · git 제외)에
11
+ // 대화가 끝날 때(`/quit`·Ctrl+C·SIGINT/SIGTERM = process 'exit' · `/session new`·`clear`) 5줄 이내로 쓴다(tmp ⊕ rename).
12
+ // ⛔ 사람 지시 파일은 «고치지 않는다» — 사람 파일 안의 블록을 갈아 쓰면 잠금 없이는 경쟁 창을 0 으로 못 만든다(#27505 r1~r4).
13
+ // 재료는 대화 기록(마지막 요청·마지막 답 요지·열린 일 후보·다음 점검 시각 후보) — LLM 호출 없이 동기로(종료 경로).
14
+ // 실패해도 종료를 막지 않는다.
15
+ // ③ 다음 기동 때 L0 앵커 로더(`universal-preamble.ts`)가 그 파일을 층 ④(로컬 지시) 뒤 조각으로 싣는다.
16
+ // 관측: `tui.local-instructions` created / create-skipped / last-session-written / last-session-skipped.
17
+ // ⛔ 생성은 cwd 가 `/seats/<자리>` 일 때만 — `COORD_ID` 만으로는 아무 저장소 디렉터리에 파일을 만들지 않는다.
18
+
19
+ import { existsSync, lstatSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
20
+ import { homedir } from 'node:os';
21
+ import { randomBytes } from 'node:crypto';
22
+ import { dirname, join } from 'node:path';
23
+ import { debug } from '../debug/log.js';
24
+
25
+ export const LOCAL_INSTRUCTIONS_FILE = 'AGENTS.local.md';
26
+ const COMPAT_LOCAL_FILE = 'CLAUDE.local.md';
27
+ /** TUI 가 통째로 소유하는 «지난 세션» 파일 — 자리 루트에 둔다. L0 앵커 로더가 같은 이름을 읽는다. */
28
+ export const LAST_SESSION_FILE = '.AGENTS.local.last-session.md';
29
+ const SEAT_DIR_IN_PATH = /^(.*?\/seats\/([A-Za-z][A-Za-z0-9_-]{0,63}))(?:\/|$)/;
30
+ const README_HEAD_MAX = 1200;
31
+ const PRINCIPLE_MAX = 1500;
32
+ const MAX_LAST_SESSION_LINES = 5;
33
+ const LINE_MAX = 200;
34
+
35
+ /** cwd 가 `/seats/<자리>` 아래면 자리 루트 디렉터리와 자리 이름. */
36
+ export function seatDirFromCwd(cwd: string): { seat: string; dir: string } | null {
37
+ const m = SEAT_DIR_IN_PATH.exec(cwd);
38
+ if (!m) return null;
39
+ return { seat: m[2]!.toUpperCase(), dir: m[1]! };
40
+ }
41
+
42
+ function readHead(path: string, maxChars: number): string | null {
43
+ try {
44
+ if (!statSync(path).isFile()) return null;
45
+ const raw = readFileSync(path, 'utf8');
46
+ if (raw.length <= maxChars) return raw.trim();
47
+ const cut = raw.slice(0, maxChars);
48
+ return `${cut.slice(0, Math.max(0, cut.lastIndexOf('\n'))).trim()}\n…(이하 생략 — 원문을 읽어라)`;
49
+ } catch {
50
+ return null;
51
+ }
52
+ }
53
+
54
+ function findAncestorFile(startDir: string, filename: string): string | null {
55
+ let dir = startDir;
56
+ for (;;) {
57
+ const candidate = join(dir, filename);
58
+ if (existsSync(candidate)) return candidate;
59
+ const parent = dirname(dir);
60
+ if (parent === dir) return null;
61
+ dir = parent;
62
+ }
63
+ }
64
+
65
+ /** 저장소 AGENTS.md 의 «제1원칙» 절에서 요지(북극성·넘버원 룰·SCQA 문법)를 뽑는다. 원문 복제가 아니라 발췌 ⊕ 출처. */
66
+ export function extractFirstPrinciple(agentsMd: string): string | null {
67
+ const lines = agentsMd.split(/\r?\n/);
68
+ const start = lines.findIndex(line => /^##\s.*제1원칙/.test(line));
69
+ if (start < 0) return null;
70
+ let end = lines.length;
71
+ for (let i = start + 1; i < lines.length; i++) {
72
+ if (/^##\s/.test(lines[i]!)) { end = i; break; }
73
+ }
74
+ const section = lines.slice(start + 1, end);
75
+ const picked: string[] = [];
76
+ for (let i = 0; i < section.length; i++) {
77
+ const line = section[i]!;
78
+ if (/\*\*북극성\*\*/.test(line)) {
79
+ picked.push(line);
80
+ const next = section[i + 1];
81
+ if (next && next.trim() && !/^\*\*/.test(next.trim())) picked.push(next);
82
+ } else if (/\*\*넘버원 룰\*\*/.test(line) || /\*\*문법 = `SCQA`\*\*/.test(line)) {
83
+ picked.push(line);
84
+ }
85
+ }
86
+ const body = (picked.length ? picked : section.filter(l => l.trim() && !l.startsWith('>'))).join('\n').trim();
87
+ if (!body) return null;
88
+ return body.length > PRINCIPLE_MAX ? `${body.slice(0, PRINCIPLE_MAX)}…` : body;
89
+ }
90
+
91
+ export function renderLocalInstructionsTemplate(input: { seat: string; readmeHead: string | null; principle: string | null; at: string }): string {
92
+ const out = [
93
+ `# ${input.seat} 자리 — 로컬 지시 (TUI 가 ${input.at} 에 만들었다 · 사람이 고쳐도 된다)`,
94
+ '',
95
+ `너는 **${input.seat}** 자리의 엘라누스 TUI 다. 이 파일은 git 에 안 올라가는 «이 자리만의» 지시이고, 저장소 공용 지시(AGENTS.md)와 다르면 이 파일이 우선한다.`,
96
+ '',
97
+ '## 자리 정본 (seat-state README 머리)',
98
+ input.readmeHead ?? `- 미관측: ~/elanous-hq/seat-state/${input.seat}/README.md 없음 — 역할은 사람에게 묻고 이 절을 채워라.`,
99
+ '',
100
+ ];
101
+ if (input.principle) {
102
+ out.push('## 제1원칙 (요지)', '> 정본 = 저장소 AGENTS.md §제1원칙 — 아래는 발췌다. 어긋나면 정본이 이긴다.', '', input.principle, '');
103
+ }
104
+ out.push(
105
+ '## 시작하면',
106
+ `- 우편함을 읽는다: \`eln msg list --to ${input.seat}\` — 안 읽은 우편 수와 처리할 것을 먼저 말한다.`,
107
+ `- 자리 인계를 읽는다: ~/elanous-hq/seat-state/${input.seat}/HANDOFF.md (있으면).`,
108
+ '- 앵커의 «지난 세션» 조각(TUI 가 `.AGENTS.local.last-session.md` 에 남긴다)의 열린 일을 이어받고, 다음 점검 시각을 정해 말한다.',
109
+ '',
110
+ );
111
+ return out.join('\n');
112
+ }
113
+
114
+ export interface SeatLocalDeps {
115
+ home?: string;
116
+ now?: () => Date;
117
+ /** 시험 심 — 생성(wx) 직후, 경쟁 확인 «전»에 불린다(사람이 그 틈에 파일을 만들거나 고치는 경우 재현). */
118
+ afterCreateForTest?: (path: string) => void;
119
+ }
120
+
121
+ /** 자리 디렉터리에서 로컬 지시 파일이 하나도 없으면 템플릿으로 만든다. 결과를 첫 화면 한 줄에 쓴다. */
122
+ /** 경로에 «무엇이든» 있나 — 링크는 대상이 없어도 있다(lstat). */
123
+ function entryPresent(path: string): boolean {
124
+ try { lstatSync(path); return true; } catch { return false; }
125
+ }
126
+
127
+ export function ensureSeatLocalInstructions(cwd: string, deps: SeatLocalDeps = {}): { status: 'created' | 'exists' | 'not-seat' | 'error'; path?: string; missingPrinciple?: boolean } {
128
+ const seatDir = seatDirFromCwd(cwd);
129
+ if (!seatDir) return { status: 'not-seat' };
130
+ const path = join(seatDir.dir, LOCAL_INSTRUCTIONS_FILE);
131
+ try {
132
+ for (const name of [LOCAL_INSTRUCTIONS_FILE, COMPAT_LOCAL_FILE]) {
133
+ const existing = join(seatDir.dir, name);
134
+ // ⛔ «링크 자체»의 존재로 판정한다(lstat) — 대상이 없는 링크도 «있음»이다(existsSync 는 그것을 «없음»으로 본다).
135
+ if (entryPresent(existing)) {
136
+ // ⛔ 덮어쓰기 0 — 제1원칙 절이 없으면 «제안»만 한다(읽을 수 없는 링크면 제안도 안 한다).
137
+ let body = '';
138
+ try { body = readFileSync(existing, 'utf8'); } catch { body = '제1원칙'; }
139
+ const missingPrinciple = !/제1원칙/.test(body);
140
+ debug.log('tui.local-instructions', 'create-skipped', { seat: seatDir.seat, path: existing, reason: 'exists', missingPrinciple });
141
+ return { status: 'exists', path: existing, missingPrinciple };
142
+ }
143
+ }
144
+ const home = deps.home ?? homedir();
145
+ const readmeHead = readHead(join(home, 'elanous-hq', 'seat-state', seatDir.seat, 'README.md'), README_HEAD_MAX);
146
+ const agentsPath = findAncestorFile(seatDir.dir, 'AGENTS.md');
147
+ const principle = agentsPath ? extractFirstPrinciple(readFileSync(agentsPath, 'utf8')) : null;
148
+ const text = renderLocalInstructionsTemplate({ seat: seatDir.seat, readmeHead, principle, at: (deps.now?.() ?? new Date()).toISOString() });
149
+ // `wx` = 없을 때만 만든다 — 확인과 쓰기 사이에 사람이 만든 파일도 덮지 않는다.
150
+ writeFileSync(path, text, { flag: 'wx' });
151
+ deps.afterCreateForTest?.(path);
152
+ // 경쟁: 확인과 생성 사이에 사람이 호환 파일을 만들었으면 우리 파일이 그것을 가린다 — 방금 만든 것을 거둔다.
153
+ if (entryPresent(join(seatDir.dir, COMPAT_LOCAL_FILE))) {
154
+ // ⛔ «방금 쓴 내용과 같을 때만» 지운다 — 그 사이 사람이 고쳤으면 사람 문면을 지우지 않고 둘 다 남긴다(관측).
155
+ let unchanged = false;
156
+ try { unchanged = readFileSync(path, 'utf8') === text; } catch { unchanged = false; }
157
+ if (unchanged) rmSync(path, { force: true });
158
+ debug.log('tui.local-instructions', 'create-skipped', { seat: seatDir.seat, path, reason: 'compat-appeared', removedOwn: unchanged });
159
+ return { status: 'exists', path: join(seatDir.dir, COMPAT_LOCAL_FILE), missingPrinciple: false };
160
+ }
161
+ debug.log('tui.local-instructions', 'created', { seat: seatDir.seat, path, chars: text.length, hasReadme: readmeHead !== null, hasPrinciple: principle !== null });
162
+ return { status: 'created', path };
163
+ } catch (err) {
164
+ debug.log('tui.local-instructions', 'create-skipped', { seat: seatDir.seat, path, reason: 'error', error: err instanceof Error ? err.message : String(err) });
165
+ return { status: 'error', path };
166
+ }
167
+ }
168
+
169
+ // ── «지난 세션» 이어쓰기 ────────────────────────────────────────────────
170
+
171
+ export interface SessionMessage {
172
+ role: string;
173
+ content: unknown;
174
+ }
175
+
176
+ function messageText(content: unknown): string {
177
+ if (typeof content === 'string') return content;
178
+ if (Array.isArray(content)) {
179
+ return content
180
+ .map(block => (block && typeof block === 'object' && (block as { type?: unknown }).type === 'text' ? String((block as { text?: unknown }).text ?? '') : ''))
181
+ .filter(Boolean)
182
+ .join('\n');
183
+ }
184
+ return '';
185
+ }
186
+
187
+ /** 대시보드는 사람 턴을 `Context:\n…\n\nQuestion: <질문>` 으로 감싸 history 에 넣는다(turn-message-runtime.ts) — 질문만 꺼낸다. */
188
+ function userQuestion(text: string): string {
189
+ const marker = '\n\nQuestion: ';
190
+ if (!text.startsWith('Context:') || !text.includes(marker)) return text;
191
+ return text.slice(text.lastIndexOf(marker) + marker.length);
192
+ }
193
+
194
+ function oneLine(text: string): string {
195
+ const flat = text.replace(/\s+/g, ' ').trim();
196
+ return flat.length > LINE_MAX ? `${flat.slice(0, LINE_MAX - 1)}…` : flat;
197
+ }
198
+
199
+ /** 대화 기록에서 «지난 세션» 5줄 이내. 사람 턴이 없으면 null(쓸 것이 없다). */
200
+ export function summarizeSession(history: readonly SessionMessage[], meta: { endedAt: string; reason: string }): string[] | null {
201
+ const turns = history
202
+ .filter(m => m.role === 'user' || m.role === 'assistant')
203
+ .map(m => ({ role: m.role, text: (m.role === 'user' ? userQuestion(messageText(m.content)) : messageText(m.content)).trim() }))
204
+ .filter(t => t.text);
205
+ const userTurns = turns.filter(t => t.role === 'user');
206
+ if (userTurns.length === 0) return null;
207
+ const lastUserIdx = turns.map(t => t.role).lastIndexOf('user');
208
+ const lastAssistantIdx = turns.map(t => t.role).lastIndexOf('assistant');
209
+ // 마지막 요청에 답하기 «전»에 끝났으면 그 앞 답을 이 요청의 답처럼 적지 않는다.
210
+ const unanswered = lastAssistantIdx < lastUserIdx;
211
+ const lastAnswer = lastAssistantIdx >= 0 ? turns[lastAssistantIdx]!.text : '';
212
+ const answerLines = lastAnswer.split(/\r?\n/).map(l => l.trim()).filter(Boolean);
213
+ const open = answerLines.filter(l => /(다음|남은|열린|후속|미완|대기|TODO|할 일|이어서)/i.test(l)).slice(0, 2);
214
+ const nextCheck = /(\d{1,2}:\d{2})/.exec(open.join(' ') || lastAnswer)?.[1];
215
+ const lines = [
216
+ `- 끝: ${meta.endedAt} · ${meta.reason} · 사람 턴 ${userTurns.length}`,
217
+ unanswered
218
+ ? `- 마지막 요청(답 없이 끝남 — 이어서 처리할 일): ${oneLine(userTurns.at(-1)!.text)}`
219
+ : `- 마지막 요청: ${oneLine(userTurns.at(-1)!.text)}`,
220
+ ];
221
+ if (answerLines.length) lines.push(`- ${unanswered ? '그 전 답 요지' : '마지막 답 요지'}: ${oneLine(answerLines[0]!)}`);
222
+ const fromPrev = unanswered ? '(그 전 답에서 — 마지막 요청의 후속이 아니다) ' : '';
223
+ lines.push(`- 열린 일: ${open.length ? `${fromPrev}${open.map(oneLine).join(' / ')}` : '미관측(답에 «다음·남은·열린» 줄 없음) — 자리 우편·HANDOFF 로 확인'}`);
224
+ if (nextCheck) lines.push(`- 다음 점검 시각(${unanswered ? '그 전 답에서' : '답에서'}): ${nextCheck}`);
225
+ return lines.slice(0, MAX_LAST_SESSION_LINES);
226
+ }
227
+
228
+ /** «지난 세션» 파일 본문 — 머리 한 줄 ⊕ 요약 줄. */
229
+ export function renderLastSessionFile(lines: readonly string[]): string {
230
+ return `## 지난 세션 (TUI 가 대화 끝마다 갈아 쓴다 · 사람이 고치지 않는 파일)\n${lines.join('\n')}\n`;
231
+ }
232
+
233
+ /** 대화 끝에 «지난 세션»을 TUI 소유 파일에 쓴다(동기 · 종료 경로 · tmp ⊕ rename). 사람 지시 파일은 건드리지 않는다. 실패는 관측만. */
234
+ export function writeLastSession(cwd: string, history: readonly SessionMessage[], reason: string, deps: SeatLocalDeps = {}): 'written' | 'skipped' {
235
+ const seatDir = seatDirFromCwd(cwd);
236
+ if (!seatDir) return 'skipped';
237
+ const path = join(seatDir.dir, LAST_SESSION_FILE);
238
+ let tmp: string | null = null;
239
+ try {
240
+ const lines = summarizeSession(history, { endedAt: (deps.now?.() ?? new Date()).toISOString(), reason });
241
+ if (!lines) {
242
+ debug.log('tui.local-instructions', 'last-session-skipped', { seat: seatDir.seat, reason: 'no-user-turn' });
243
+ return 'skipped';
244
+ }
245
+ // 이 이름이 링크면(누가 심었으면) 따라가 쓰지 않는다.
246
+ if (existsSync(path) && lstatSync(path).isSymbolicLink()) {
247
+ debug.log('tui.local-instructions', 'last-session-skipped', { seat: seatDir.seat, path, reason: 'symlink' });
248
+ return 'skipped';
249
+ }
250
+ const text = renderLastSessionFile(lines);
251
+ tmp = `${path}.tmp-${process.pid}-${randomBytes(6).toString('hex')}`;
252
+ writeFileSync(tmp, text, { flag: 'wx', mode: 0o600 });
253
+ renameSync(tmp, path);
254
+ tmp = null;
255
+ debug.log('tui.local-instructions', 'last-session-written', { seat: seatDir.seat, path, reason, lines: lines.length, chars: text.length });
256
+ return 'written';
257
+ } catch (err) {
258
+ debug.log('tui.local-instructions', 'last-session-skipped', { seat: seatDir.seat, reason: 'error', error: err instanceof Error ? err.message : String(err) });
259
+ return 'skipped';
260
+ } finally {
261
+ if (tmp) { try { if (!lstatSync(tmp).isSymbolicLink()) rmSync(tmp, { force: true }); } catch { /* 없으면 그만 */ } }
262
+ }
263
+ }
264
+
265
+ export interface SessionRecorderDeps {
266
+ getCwd: () => string;
267
+ getHistory: () => readonly SessionMessage[];
268
+ onExit?: (fn: () => void) => void;
269
+ }
270
+
271
+ let recorder: SessionRecorderDeps | null = null;
272
+ let recordedThisConversation = false;
273
+ // 대화의 기록 대상 디렉터리 — 대화가 «시작될 때» 고정한다(도중 cwd 를 옮겨도 다른 자리 파일에 쓰지 않게).
274
+ let conversationCwd: string | null = null;
275
+
276
+ export function resetSessionRecorderForTest(): void {
277
+ recorder = null;
278
+ recordedThisConversation = false;
279
+ conversationCwd = null;
280
+ }
281
+
282
+ /** 대화 끝 기록 — 같은 대화에서 두 번 쓰지 않는다(`/session new` 뒤 `exit` 등). */
283
+ export function recordSeatSessionEnd(reason: string): void {
284
+ if (!recorder || recordedThisConversation) return;
285
+ const cwd = conversationCwd ?? recorder.getCwd();
286
+ if (writeLastSession(cwd, recorder.getHistory(), reason) === 'written') recordedThisConversation = true;
287
+ }
288
+
289
+ /** 새 대화가 시작됐다 — 기록 대상을 지금 cwd 로 다시 고정하고, 다음 끝에서 다시 쓴다. */
290
+ export function markSeatConversationStarted(): void {
291
+ recordedThisConversation = false;
292
+ conversationCwd = recorder?.getCwd() ?? null;
293
+ }
294
+
295
+ /** 대시보드가 부팅 때 한 번 건다. `/quit`·Ctrl+C·SIGINT/SIGTERM 은 모두 process 'exit' 로 끝난다(tui.ts 핸들러가 process.exit). */
296
+ export function installSeatSessionRecorder(deps: SessionRecorderDeps): void {
297
+ const first = recorder === null;
298
+ recorder = deps;
299
+ conversationCwd = deps.getCwd();
300
+ if (!first) return;
301
+ const onExit = deps.onExit ?? ((fn: () => void) => { process.on('exit', fn); });
302
+ onExit(() => {
303
+ try { recordSeatSessionEnd('exit'); } catch { /* 종료는 언제나 끝까지 간다 */ }
304
+ });
305
+ }
@@ -272,7 +272,8 @@
272
272
  // `../index.ts`) instead of importing the type — keeps this module free
273
273
  // of circular dependency on dashboard/index.ts.
274
274
 
275
- import { tuiNowSlash } from '../../context-bus/context-now-surfaces.js';
275
+ import { renderTuiNow, tuiNowSlash } from '../../context-bus/context-now-surfaces.js';
276
+ import { contextNowInWorker } from '../../context-bus/context-now.js';
276
277
  import { handleTuiChatPersona, type TuiChatPersonaSelection } from './chat-persona.js';
277
278
  import { createWishCard } from '../../intake-plane/wish-card.js';
278
279
  import { CardStore } from '../../task-cards/card-store.js';
@@ -284,6 +285,8 @@ import { resolveRepositoryDesignCheck } from '../../cli/repo-cli.js';
284
285
  import { renderDesignCheckLines, type DesignCheckTone } from '../../design/design-check-render.js';
285
286
  import { handleDesignPick } from './design-pick.js';
286
287
  import { createDecideSlashHandler } from './decide-slash.js';
288
+ import { startSeatBootConversation } from '../seat-boot-preamble.js';
289
+ import { markSeatConversationStarted, recordSeatSessionEnd } from '../seat-local-instructions.js';
287
290
  import type { DecisionLedger } from '../../decisions/decision-ledger.js';
288
291
  import { listDesignDirections, parseDeclaredDirection } from '../../design/design-directions.js';
289
292
  import {
@@ -343,7 +346,7 @@ import { terminalModalRouter } from '../input/terminal-modal-router.js';
343
346
  import { termSize, stripAnsi } from '../../tui.js';
344
347
  import { SLASH_COMMANDS } from '../../chat/index.js';
345
348
  import { buildEssentialHelpLines } from './help-from-registry.js';
346
- import { HUMAN_MODEL_WORDS, MODEL_CODE_NAMES, humanWordForModel, modelChangeLine, modelOverviewLines, resolveModelChoice } from './model-choices.js';
349
+ import { HUMAN_MODEL_WORDS, MODEL_CODE_NAMES, humanWordForModel, modelChangeLine, modelOverviewLines, modelScopeLine, modelSwitchScope, parseModelSlashArgs, resolveModelChoice } from './model-choices.js';
347
350
  import type { FoldMode } from '../../log-entry.js';
348
351
  import { resolveDashboardChatMainLogCommand } from '../input/chat-main-log-command.js';
349
352
  import {
@@ -358,7 +361,7 @@ import { debug } from '../../debug/log.js';
358
361
  import { resolveDebugCompanionTargets } from '../../window/debug-window-consumers.js';
359
362
  import { getPromptBankStore, buildPromptInjection } from '../../prompt-bank/index.js';
360
363
  import { inspectActiveProvider } from '../../provider-summary.js';
361
- import { currentRouteDecision, formatRouteDecisionSummary, resolveRouteDecision, type RouteDecision } from '../../llm/route-decision.js';
364
+ import { currentRouteDecision, formatRouteDecisionSummary, resolveRouteDecision, sessionModelPin, setSessionModelPin, type RouteDecision } from '../../llm/route-decision.js';
362
365
  import {
363
366
  listSessions as sessionListSessions,
364
367
  resolveSessionId as sessionResolveId,
@@ -954,6 +957,8 @@ export interface DashboardSlashContext {
954
957
  // Fold mode
955
958
  getLogFoldMode(): FoldMode;
956
959
  setLogFoldMode(mode: FoldMode): void;
960
+ /** #19 — put every static fold in one state; returns how many changed. */
961
+ setAllFolds?(expanded: boolean): number;
957
962
  // Solo (chat-only) toggle — flips chatOnlyMode + manages HUD mode segment.
958
963
  /** Returns the new chatOnlyMode value after toggle. */
959
964
  toggleSolo(): boolean;
@@ -1071,6 +1076,7 @@ export interface DashboardSlashContext {
1071
1076
  termSlash: {
1072
1077
  /** Line formatters (existing factory output type re-used). */
1073
1078
  slashRuntime: DashboardTermSlashRuntime;
1079
+ openNewTerminal(command?: string): void;
1074
1080
 
1075
1081
  /** Terminal session registry (the modal-pty side). */
1076
1082
  sessionRegistry: {
@@ -1413,8 +1419,10 @@ export function buildDashboardSlashRegistry(nowDeps?: ContextNowDeps, decideLedg
1413
1419
  ctx.setChatScrollOffset(-1);
1414
1420
  });
1415
1421
 
1416
- registry.register(['now'], (args, ctx) => {
1417
- for (const line of tuiNowSlash(args, nowDeps)) ctx.pushChatLine(line);
1422
+ registry.register(['now'], async (args, ctx) => {
1423
+ const lines = nowDeps ? tuiNowSlash(args, nowDeps)
1424
+ : renderTuiNow(await contextNowInWorker({ topic: args.join(' ').trim() }));
1425
+ for (const line of lines) ctx.pushChatLine(line);
1418
1426
  });
1419
1427
 
1420
1428
  registry.register('loops', async (args, ctx) => {
@@ -2977,6 +2985,10 @@ export function buildDashboardSlashRegistry(nowDeps?: ContextNowDeps, decideLedg
2977
2985
  ctx.setChatScrollOffset(-1);
2978
2986
  return;
2979
2987
  }
2988
+ if (sub === 'new') {
2989
+ ctx.termSlash.openNewTerminal(args.slice(1).join(' ').trim() || undefined);
2990
+ return;
2991
+ }
2980
2992
  if (sub === 'list') {
2981
2993
  const alive = sessionRegistry.list();
2982
2994
  if (alive.length === 0) {
@@ -4019,6 +4031,10 @@ export function buildDashboardSlashRegistry(nowDeps?: ContextNowDeps, decideLedg
4019
4031
  }
4020
4032
 
4021
4033
  if (seSub === 'new' || seSub === 'clear') {
4034
+ // 🪪 L2-lite — 비우기 «전»에 이 대화의 «지난 세션»을 자리 로컬 지시에 남긴다(실패해도 진행).
4035
+ try {
4036
+ recordSeatSessionEnd(seSub === 'new' ? 'session-new' : 'session-clear');
4037
+ } catch { /* 기록이 새 대화를 막지 않는다 */ }
4022
4038
  if (seSub === 'new') {
4023
4039
  try {
4024
4040
  const { suggestProjectForFolder } = await import('../../project/project-store.js');
@@ -4044,6 +4060,12 @@ export function buildDashboardSlashRegistry(nowDeps?: ContextNowDeps, decideLedg
4044
4060
  ctx.chatLines.push(ctx.success(prev
4045
4061
  ? ` ✓ cleared history + detached ${prev.slice(0, 8)}`
4046
4062
  : ` ✓ cleared history`));
4063
+ // 🪪 L1 — 새 대화 = 새 자리 부트 카드.
4064
+ // ⛔ 정적 import · 동기 호출 — history 를 비운 «같은 틱»에 카드 캐시를 비운다(비동기 대기 틈에 새 턴이 옛 카드를 읽지 않게).
4065
+ try {
4066
+ startSeatBootConversation({ reason: seSub === 'new' ? 'session-new' : 'session-clear' });
4067
+ markSeatConversationStarted();
4068
+ } catch { /* 부트 카드가 새 대화를 막지 않는다 */ }
4047
4069
  ctx.setChatScrollOffset(-1);
4048
4070
  return;
4049
4071
  }
@@ -4474,6 +4496,22 @@ export function buildDashboardSlashRegistry(nowDeps?: ContextNowDeps, decideLedg
4474
4496
  ctx.setChatScrollOffset(-1);
4475
4497
  return;
4476
4498
  }
4499
+ if (logCommand.kind === 'fold-all') {
4500
+ if (!ctx.logSlash.setAllFolds) {
4501
+ // A host without a fold controller cannot know whether anything is folded — say so, not «nothing».
4502
+ debug.log('log.fold', 'slash-set-all', { expanded: logCommand.expanded, changed: null, reason: 'no-fold-controller' });
4503
+ emitReplyToChat(ctx, ctx.warning(' fold controls are not available in this view'));
4504
+ ctx.setChatScrollOffset(-1);
4505
+ return;
4506
+ }
4507
+ const changed = ctx.logSlash.setAllFolds(logCommand.expanded);
4508
+ debug.log('log.fold', 'slash-set-all', { expanded: logCommand.expanded, changed });
4509
+ emitReplyToChat(ctx, ctx.muted(changed > 0
4510
+ ? ` ${logCommand.expanded ? 'unfolded' : 'folded'} ${changed} block${changed === 1 ? '' : 's'}`
4511
+ : ` (nothing to ${logCommand.expanded ? 'unfold' : 'fold'})`));
4512
+ ctx.setChatScrollOffset(-1);
4513
+ return;
4514
+ }
4477
4515
  if (logCommand.kind === 'fold') {
4478
4516
  const action = resolveDashboardLogFoldAction(logCommand.mode, ctx.logSlash.getLogFoldMode());
4479
4517
  if (action.kind === 'set-mode') {
@@ -5302,9 +5340,10 @@ export function buildDashboardSlashRegistry(nowDeps?: ContextNowDeps, decideLedg
5302
5340
  // previews an unpinned request without changing provider/model state.
5303
5341
  if (sub === 'route') {
5304
5342
  const cfg = getUserConfig();
5343
+ const previewPin = sessionModelPin('dashboard', cfg.llm.provider);
5305
5344
  const text = args.slice(1).join(' ').trim();
5306
5345
  const decision = text
5307
- ? resolveRouteDecision({ provider: cfg.llm.provider, configuredModel: inspectActiveProvider().model, text, routePolicy: cfg.llm.routePolicy })
5346
+ ? resolveRouteDecision({ provider: cfg.llm.provider, configuredModel: inspectActiveProvider().model, text, routePolicy: cfg.llm.routePolicy, ...(previewPin ? { explicitModel: previewPin.model } : {}) })
5308
5347
  : currentRouteDecision('dashboard');
5309
5348
  ctx.chatLines.push(ctx.accent(`❯ /provider route${text ? '' : ' (current)'}`));
5310
5349
  if (!decision) ctx.chatLines.push(ctx.muted(' 아직 이 세션에서 실행된 route가 없습니다. `/provider route <요청>`으로 미리보기 합니다.'));
@@ -6062,24 +6101,35 @@ export function buildDashboardSlashRegistry(nowDeps?: ContextNowDeps, decideLedg
6062
6101
  // /model — 지금 모델(사람 낱말) + 고르기
6063
6102
  // /model 빠름|보통|깊음 — 지금 provider 의 budget·better·best 티어 (model-choices.ts)
6064
6103
  // /model <코드명> — codex·terra·sol·luna·opus·sonnet·grok (그대로 동작)
6104
+ // /model <x> --global — 설정 파일(전역)에 저장 · /model reset — 세션 핀 해제
6105
+ // ⭐ 기본은 «이 세션» 핀이다(TUI-MODEL-SESSION-SCOPE · 10-14): config 의 llm.model 만 바꾸면 codex 티어 정책이
6106
+ // 그것을 무시해 실제 턴은 그대로 sol 이었다(OPT 21:33). 핀은 다음 턴 explicitModel 로 들어가 정책을 이긴다.
6065
6107
  // effort(low/med/high)는 /reasoning. NL 미지원(대표 OK·slash-only).
6066
- const arg = (args[0] ?? '').toLowerCase().trim();
6108
+ const { arg, global } = parseModelSlashArgs(args);
6067
6109
  const curCfg = getUserConfig();
6068
6110
  const curProvider = curCfg.llm.provider;
6069
- const curModel = curCfg.llm.model;
6111
+ const pin = sessionModelPin('dashboard', curProvider);
6112
+ const curModel = pin?.model ?? curCfg.llm.model;
6070
6113
  const curReasoning = effectiveReasoningLevel(curCfg.llm, curProvider, curModel);
6071
6114
  if (!arg) {
6072
6115
  const [, codes] = modelOverviewLines(curProvider, curModel, curReasoning);
6073
6116
  // A model outside the 빠름/보통/깊음 map (codename or custom) says so explicitly instead of dropping the tier slot.
6074
6117
  const tierName = humanWordForModel(curProvider, curModel, curReasoning) ?? '단계 밖';
6075
- ctx.chatLines.push(`지금: ${curModel?.trim() || '기본 모델'} (${tierName} · 생각 ${curReasoning}) · 고르기: /model ${HUMAN_MODEL_WORDS.join(' | ')}`);
6118
+ ctx.chatLines.push(`지금: ${curModel?.trim() || '기본 모델'} (${tierName} · 생각 ${curReasoning}${pin ? ' · 이 세션 핀' : ''}) · 고르기: /model ${HUMAN_MODEL_WORDS.join(' | ')}`);
6076
6119
  ctx.chatLines.push(ctx.muted(codes));
6077
6120
  ctx.setChatScrollOffset(-1);
6078
6121
  return;
6079
6122
  }
6123
+ if (arg === 'reset') {
6124
+ setSessionModelPin('dashboard', null);
6125
+ debug.log('llm.model-choice', 'session-pin-cleared', { hadPin: pin !== null, configModel: curCfg.llm.model ?? null }, { level: 'info' });
6126
+ ctx.chatLines.push(ctx.muted(`/model reset: 세션 핀 ${pin ? `해제 (${pin.model})` : '없음'} — 다음 턴은 설정·정책대로`));
6127
+ ctx.setChatScrollOffset(-1);
6128
+ return;
6129
+ }
6080
6130
  const resolution = resolveModelChoice(arg, curProvider);
6081
6131
  if (resolution.kind === 'needs-provider') {
6082
- debug.log('dashboard.model', 'human-word-needs-provider', { word: resolution.word, provider: curProvider });
6132
+ debug.log('llm.model-choice', 'human-word-needs-provider', { word: resolution.word, provider: curProvider });
6083
6133
  ctx.chatLines.push(ctx.muted(`/model ${resolution.word}: provider 가 auto 라 고를 사다리가 없다 — /provider 로 먼저 하나를 고르거나 코드명(${MODEL_CODE_NAMES.join('/')})을 쓴다.`));
6084
6134
  ctx.setChatScrollOffset(-1);
6085
6135
  return;
@@ -6090,29 +6140,51 @@ export function buildDashboardSlashRegistry(nowDeps?: ContextNowDeps, decideLedg
6090
6140
  return;
6091
6141
  }
6092
6142
  const { target } = resolution;
6143
+ const scope = modelSwitchScope(target.provider, curProvider, global);
6144
+ if (scope === 'needs-global') {
6145
+ ctx.chatLines.push(ctx.muted(`/model ${arg}: provider 가 ${curProvider} → ${target.provider} 로 바뀌는 선택은 세션 핀이 안 된다 — /model ${arg} --global 로 설정에 저장한다.`));
6146
+ ctx.setChatScrollOffset(-1);
6147
+ return;
6148
+ }
6093
6149
  // A human word picks a whole tier (model ⊕ reasoning, like /reasoning it clears the codex override);
6094
- // a code name changes the model only.
6150
+ // a code name changes the model only. Reasoning has no per-turn override, so only --global sets it.
6095
6151
  const tierReasoning = resolution.kind === 'human' ? resolution.reasoningLevel : undefined;
6096
- saveUserConfig({
6097
- ...curCfg,
6098
- llm: {
6099
- ...curCfg.llm,
6100
- provider: target.provider,
6101
- model: target.model,
6102
- ...(tierReasoning ? { reasoningLevel: tierReasoning, codexReasoning: undefined } : {}),
6103
- },
6104
- });
6105
- reloadUserConfig();
6106
- if (tierReasoning) ctx.refreshReasoningHudSegment();
6107
- debug.log('dashboard.model', 'switch', {
6152
+ if (scope === 'global') {
6153
+ saveUserConfig({
6154
+ ...curCfg,
6155
+ llm: {
6156
+ ...curCfg.llm,
6157
+ provider: target.provider,
6158
+ model: target.model,
6159
+ ...(tierReasoning ? { reasoningLevel: tierReasoning, codexReasoning: undefined } : {}),
6160
+ },
6161
+ });
6162
+ reloadUserConfig();
6163
+ if (tierReasoning) ctx.refreshReasoningHudSegment();
6164
+ }
6165
+ // --global 도 이 세션은 핀으로 «즉시» 반영한다 — config 만 쓰면 codex 티어 정책이 configuredModel 을
6166
+ // 무시해 다음 턴에 안 먹는다(1R 리뷰 mf). 다른 세션은 그 세션의 routePolicy 를 따른다.
6167
+ setSessionModelPin('dashboard', { provider: target.provider, model: target.model });
6168
+ // 감사 한 줄 — 종전 범주 `dashboard.model` 은 렌더 접두(`dashboard`)라 기본 음소거돼 로그 스토어에 0회였다
6169
+ // (src/mss/logging/render-categories.ts). 판정 이벤트는 렌더 밖 범주에 둔다.
6170
+ debug.log('llm.model-choice', 'switch', {
6171
+ scope,
6108
6172
  via: resolution.kind,
6109
6173
  choice: resolution.kind === 'human' ? resolution.tier : resolution.name,
6110
- from: { provider: curProvider, model: curModel ?? null },
6174
+ from: { provider: curProvider, model: curModel ?? null, pinned: pin !== null },
6111
6175
  to: target,
6112
- reasoning: tierReasoning ?? null,
6113
- });
6114
- ctx.chatLines.push(modelChangeLine({ provider: curProvider, model: curModel, reasoning: curReasoning }, resolution));
6115
- ctx.chatLines.push(ctx.muted(' └─ 다음 턴부터 반영 · 실행 뱃지(#4442)로 확인'));
6176
+ reasoning: scope === 'global' ? (tierReasoning ?? null) : null,
6177
+ configWritten: scope === 'global',
6178
+ }, { level: 'info' });
6179
+ // 세션 범위는 생각 깊이를 안 바꾼다 — 모델 줄에 티어의 깊이를 «바뀐 값»처럼 쓰지 않고, 남는 깊이를 말한다
6180
+ // (2R 리뷰 — 한 응답 안의 «생각 medium» 과 «생각 깊이는 그대로 high» 모순).
6181
+ if (scope === 'session' && resolution.kind === 'human') {
6182
+ const { reasoningLevel: _tierReasoning, ...modelOnly } = resolution;
6183
+ ctx.chatLines.push(`${modelChangeLine({ provider: curProvider, model: curModel, reasoning: curReasoning }, modelOnly)} · 생각 ${curReasoning} 그대로`);
6184
+ } else {
6185
+ ctx.chatLines.push(modelChangeLine({ provider: curProvider, model: curModel, reasoning: curReasoning }, resolution));
6186
+ }
6187
+ ctx.chatLines.push(ctx.muted(modelScopeLine(scope, scope === 'session' && tierReasoning ? { tier: tierReasoning, current: curReasoning } : undefined)));
6116
6188
  ctx.setChatScrollOffset(-1);
6117
6189
  });
6118
6190
 
@@ -123,3 +123,38 @@ export function modelChangeLine(
123
123
  const providerNote = resolution.target.provider === before.provider ? '' : ` · provider ${resolution.target.provider}`;
124
124
  return `모델: ${currentLabel(before.provider, before.model, before.reasoning)} → ${after} (${resolution.target.model}${reasoningNote})${providerNote}`;
125
125
  }
126
+
127
+ /** `/model` arguments: the choice word plus the `--global` flag (TUI-MODEL-SESSION-SCOPE · 10-14). */
128
+ export function parseModelSlashArgs(args: readonly string[]): { arg: string; global: boolean } {
129
+ const global = args.some((a) => a.trim().toLowerCase() === '--global');
130
+ const arg = args.find((a) => !a.trim().startsWith('--'))?.trim().toLowerCase() ?? '';
131
+ return { arg, global };
132
+ }
133
+
134
+ /**
135
+ * Where a `/model` choice lands. The default is this TUI session only (a pin that the next turn sends as an
136
+ * explicit model, so it beats the Codex tier policy); `--global` writes config. A choice on another provider
137
+ * can't be a session pin — the turn carries a model, not a provider — so it needs `--global`.
138
+ */
139
+ export function modelSwitchScope(
140
+ targetProvider: LLMProviderName,
141
+ currentProvider: LLMProviderName,
142
+ global: boolean,
143
+ ): 'session' | 'global' | 'needs-global' {
144
+ if (global) return 'global';
145
+ return targetProvider === currentProvider ? 'session' : 'needs-global';
146
+ }
147
+
148
+ /** The muted line under a switch: what scope it took and when it applies — no promise the code doesn't keep. */
149
+ export function modelScopeLine(
150
+ scope: 'session' | 'global',
151
+ reasoning?: { tier: ReasoningLevel; current: ReasoningLevel },
152
+ ): string {
153
+ const where = scope === 'session'
154
+ ? ' └─ 이 세션만 · 다음 턴부터 · 설정 파일은 그대로 (전역은 /model <이름> --global · 해제 /model reset)'
155
+ : ' └─ 설정 파일(전역)에 저장 · 이 세션은 다음 턴부터 · 다른 세션은 그 세션의 routePolicy 를 따른다 (codex 기본 정책이면 단계 모델이 이긴다)';
156
+ const think = reasoning && reasoning.tier !== reasoning.current
157
+ ? ` · 생각 깊이는 그대로 ${reasoning.current} (이 단계는 ${reasoning.tier} — /reasoning ${reasoning.tier})`
158
+ : '';
159
+ return where + think;
160
+ }
@@ -1,3 +1,17 @@
1
+ import { resolve } from 'node:path';
2
+
3
+ /** The workdir is the source of truth for a seat shell; env is only a fallback. */
4
+ export function resolveTuiShellSeat(cwd: string, coordId?: string): string {
5
+ const parts = resolve(cwd).split(/[\\/]/);
6
+ const seatIndex = parts.lastIndexOf('seats');
7
+ const fromPath = seatIndex >= 0 ? parts[seatIndex + 1] : undefined;
8
+ const valid = (value: string | undefined): value is string =>
9
+ value !== undefined && /^[A-Za-z0-9_-]{1,64}$/.test(value);
10
+ if (valid(fromPath)) return fromPath;
11
+ const fromEnv = coordId?.trim();
12
+ return valid(fromEnv) ? fromEnv : 'unknown';
13
+ }
14
+
1
15
  export interface DashboardPersistedSessionEntry {
2
16
  id: string;
3
17
  title: string;
@@ -109,6 +123,7 @@ export function createDashboardTermSlashRuntime(
109
123
  '',
110
124
  deps.accent('\u276f /term'),
111
125
  deps.muted('Usage:'),
126
+ deps.muted(' /term new [command] Open a shell PTY (Ctrl+Shift+T or Alt+T).'),
112
127
  deps.muted(' /term list List all alive sessions (fg / bg / exited).'),
113
128
  deps.muted(' /term attach <id> Bring a backgrounded session to foreground.'),
114
129
  deps.muted(' /term detach Send foreground session to background (PTY survives).'),