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
@@ -4,7 +4,8 @@ import { readFileSync, realpathSync, statSync } from 'node:fs';
4
4
  import { dirname, join, resolve } from 'node:path';
5
5
  import { runGitCommand } from '../git-fs/runner.js';
6
6
  import { debug } from '../debug/log.js';
7
- import { getPty, listPty, requestPtyTakeover } from '../pty-shell/registry.js';
7
+ import { getPty, listPty, renamePty, requestPtyTakeover } from '../pty-shell/registry.js';
8
+ import { describePtyRunState, readCheckoutHead, readCurrentInstallRecord, shortSha, type InstalledRecord, type PtyRunStateView } from '../pty-shell/tui-run-state.js';
8
9
  import { getPtyManifest, isProcessAlive, listPtyManifest, listPtyManifestRows, listPtyManifestRowsAt, ptyManifestDbPath, readPtyManifestFrame, reapDeadPtyManifest, reapDeadPtyManifestAt, reapStalePtyManifest, removePtyManifest, PTY_MANIFEST_CLOSED_TTL_MS, PTY_MANIFEST_STALE_MS, type PtyManifestExternalReapResult, type PtyManifestRow } from '../pty-shell/pty-manifest.js';
9
10
  import { readPtyEventsAfter, readPtyEventsAfterAt, type PtyEventLogReadResult, type PtyEventRow } from '../pty-shell/pty-event-log.js';
10
11
  import { resolvePtyRef, type PtyRefItem } from '../pty-shell/pty-ref.js';
@@ -36,7 +37,7 @@ interface PtyTakeoverCommandResult { readonly exitCode: 0 | 1 | 2; readonly mess
36
37
  * 보냈다. 둘 다 원인이 같다: `pty list` 가 **id·kind·alive 만** 줘서 *"내가 방금 띄웠으니 이게 내 것"*
37
38
  * 이라는 **추론**이 유일한 소유 근거였다. workdir 은 registry handle 과 manifest 양쪽에 이미
38
39
  * 있었고 **목록이 안 보여줬을 뿐**이다. ⇒ 보여 주면 소유가 추론이 아니라 조회가 된다. */
39
- type PtyListItem = PtyRefItem & { readonly source: 'local' | 'remote'; readonly alive: boolean; readonly mode?: PtyHandle['accessMode']; readonly workdir?: string; readonly runId?: string; readonly terminalOriginCategory?: PtyManifestRow['terminalOriginCategory']; readonly terminalOriginReason?: string; readonly externalToolName?: string };
40
+ type PtyListItem = PtyRefItem & { readonly source: 'local' | 'remote'; readonly alive: boolean; readonly mode?: PtyHandle['accessMode']; readonly workdir?: string; readonly purpose?: string; readonly runId?: string; readonly terminalOriginCategory?: PtyManifestRow['terminalOriginCategory']; readonly terminalOriginReason?: string; readonly externalToolName?: string };
40
41
  /** ⚠️ 내부 타입 — 파일 밖 production 소비자 없음(dead export 금지·review). `readLivePtyAddressBook`
41
42
  * 가 이 형태를 돌려주지만 호출부(테스트 포함)는 값만 쓰고 타입명을 import 하지 않는다. */
42
43
  interface DeadPtyRef extends PtyRefItem {
@@ -59,6 +60,7 @@ export interface FederatedPtyRef {
59
60
  readonly nickname?: string;
60
61
  readonly runId?: string;
61
62
  readonly workdir?: string;
63
+ readonly purpose?: string;
62
64
  readonly terminalOriginCategory?: PtyManifestRow['terminalOriginCategory'];
63
65
  readonly terminalOriginReason?: string;
64
66
  readonly externalToolName?: string;
@@ -82,14 +84,14 @@ export interface FederatedPtyListing {
82
84
  * ⛔ 살아있는 것만 싣는다 — 죽은 owner 까지 섞으면 *"밖에서 몰 수 있는 것"* 목록이 아니게 된다. */
83
85
  export function federatedPtyRefs(
84
86
  targets: readonly { name: string; dbPath: string }[],
85
- readRows: (dbPath: string) => readonly { id: string; kind: string; nickname?: string; runId?: string; workdir?: string; terminalOriginCategory?: PtyManifestRow['terminalOriginCategory']; terminalOriginReason?: string; externalToolName?: string; alive: boolean; ownerPid?: number; ptyPid?: number; instance?: string; updatedAt?: number }[],
87
+ readRows: (dbPath: string) => readonly { id: string; kind: string; nickname?: string; runId?: string; workdir?: string; purpose?: string; terminalOriginCategory?: PtyManifestRow['terminalOriginCategory']; terminalOriginReason?: string; externalToolName?: string; alive: boolean; ownerPid?: number; ptyPid?: number; instance?: string; updatedAt?: number }[],
86
88
  alive: (pid: number) => boolean = isProcessAlive,
87
89
  ): FederatedPtyListing {
88
90
  const seen = new Set<string>();
89
91
  const out: FederatedPtyRef[] = [];
90
92
  const unreadable: string[] = [];
91
93
  for (const target of targets) {
92
- let rows: readonly { id: string; kind: string; nickname?: string; runId?: string; workdir?: string; terminalOriginCategory?: PtyManifestRow['terminalOriginCategory']; terminalOriginReason?: string; externalToolName?: string; alive: boolean; ownerPid?: number; ptyPid?: number; instance?: string; updatedAt?: number }[];
94
+ let rows: readonly { id: string; kind: string; nickname?: string; runId?: string; workdir?: string; purpose?: string; terminalOriginCategory?: PtyManifestRow['terminalOriginCategory']; terminalOriginReason?: string; externalToolName?: string; alive: boolean; ownerPid?: number; ptyPid?: number; instance?: string; updatedAt?: number }[];
93
95
  try {
94
96
  rows = readRows(target.dbPath);
95
97
  } catch {
@@ -105,7 +107,7 @@ export function federatedPtyRefs(
105
107
  // ⚠️ 같은 물리 뿌리가 두 이름으로 등록될 수 있다 ⇒ id 로 dedup(먼저 만난 이름을 남긴다).
106
108
  if (seen.has(row.id)) continue;
107
109
  seen.add(row.id);
108
- out.push({ instance: row.instance || target.name, id: row.id, kind: row.kind, alive: true, sourceRoot: target.dbPath, ownerProcessAlive, ...(row.nickname ? { nickname: row.nickname } : {}), ...(row.runId ? { runId: row.runId } : {}), ...(row.workdir ? { workdir: row.workdir } : {}), ...(row.terminalOriginCategory ? { terminalOriginCategory: row.terminalOriginCategory } : {}), ...(row.terminalOriginReason ? { terminalOriginReason: row.terminalOriginReason } : {}), ...(row.externalToolName ? { externalToolName: row.externalToolName } : {}), ...(row.updatedAt === undefined ? {} : { updatedAt: row.updatedAt }) });
110
+ out.push({ instance: row.instance || target.name, id: row.id, kind: row.kind, alive: true, sourceRoot: target.dbPath, ownerProcessAlive, ...(row.nickname ? { nickname: row.nickname } : {}), ...(row.runId ? { runId: row.runId } : {}), ...(row.workdir ? { workdir: row.workdir } : {}), ...(row.purpose ? { purpose: row.purpose } : {}), ...(row.terminalOriginCategory ? { terminalOriginCategory: row.terminalOriginCategory } : {}), ...(row.terminalOriginReason ? { terminalOriginReason: row.terminalOriginReason } : {}), ...(row.externalToolName ? { externalToolName: row.externalToolName } : {}), ...(row.updatedAt === undefined ? {} : { updatedAt: row.updatedAt }) });
109
111
  }
110
112
  }
111
113
  return { refs: out, unreadable };
@@ -380,7 +382,14 @@ export interface PtyTakeoverCommandDeps {
380
382
  getPty(id: string): PtyControlTarget | undefined;
381
383
  requestPtyTakeover(id: string, actor: 'human'): boolean;
382
384
  requestRemote(id: string, action: PtyControlAction, payload?: PtyControlPayload, options?: PtyControlRequestOptions): Promise<PtyControlResult>;
385
+ /** Local (same-process) rename; default = registry renamePty. */
386
+ renameLocal?(id: string, nickname: string): boolean;
383
387
  readManifestFrame?(id: string): { readonly frame: string; readonly frameAt: number } | null;
388
+ /** 한 행 판독 — `pty state` 의 턴·판 칸. 기본 = 이 인스턴스 manifest(getPtyManifest). */
389
+ readManifestRow?(id: string): PtyManifestRow | null;
390
+ /** 지금 설치본(commit ⊕ installedAt) · 체크아웃 HEAD — stale 판정의 비교 대상. 주입 = 시험. */
391
+ readInstalledBuild?(): InstalledRecord;
392
+ readCheckoutHead?(codeRoot: string): string | undefined;
384
393
  listManifestRows?(): readonly PtyManifestRow[];
385
394
  listManifestRowsAt?(dbPath: string): readonly PtyManifestRow[];
386
395
  currentManifestDbPath?(): string;
@@ -445,6 +454,7 @@ interface RemoteTerminalListItem {
445
454
  readonly instance?: string;
446
455
  readonly alive?: boolean;
447
456
  readonly workdir?: string;
457
+ readonly purpose?: string;
448
458
  readonly terminalOriginCategory?: PtyManifestRow['terminalOriginCategory'];
449
459
  readonly terminalOriginReason?: string;
450
460
  readonly externalToolName?: string;
@@ -457,7 +467,7 @@ interface RemoteTerminalListItem {
457
467
 
458
468
  export function listPtyRefs(
459
469
  localHandles: readonly Pick<PtyHandle, 'id' | 'kind' | 'nickname' | 'isAlive' | 'accessMode' | 'workdir'>[],
460
- manifestRows: readonly { id: string; kind: string; nickname?: string; runId?: string; alive: boolean; workdir?: string; terminalOriginCategory?: PtyManifestRow['terminalOriginCategory']; terminalOriginReason?: string; externalToolName?: string }[],
470
+ manifestRows: readonly { id: string; kind: string; nickname?: string; runId?: string; alive: boolean; workdir?: string; purpose?: string; terminalOriginCategory?: PtyManifestRow['terminalOriginCategory']; terminalOriginReason?: string; externalToolName?: string }[],
461
471
  ): PtyListItem[] {
462
472
  // ⭐ 로컬 우선 — 같은 id 가 양쪽에 있으면 **로컬 handle 이 진실**이다(같은 프로세스의 실시간 상태).
463
473
  // manifest 의 `alive` 는 하트비트 기반이라 stale 할 수 있어(프로세스가 죽어도 한동안 alive=1),
@@ -469,13 +479,14 @@ export function listPtyRefs(
469
479
  return {
470
480
  id: handle.id, kind: handle.kind, source: 'local' as const, alive: handle.isAlive(), mode: handle.accessMode,
471
481
  ...(handle.nickname ? { nickname: handle.nickname } : {}), ...(handle.workdir ? { workdir: handle.workdir } : {}),
482
+ ...(manifest?.purpose ? { purpose: manifest.purpose } : {}),
472
483
  ...(manifest?.terminalOriginCategory ? { terminalOriginCategory: manifest.terminalOriginCategory } : {}),
473
484
  ...(manifest?.terminalOriginReason ? { terminalOriginReason: manifest.terminalOriginReason } : {}),
474
485
  ...(manifest?.externalToolName ? { externalToolName: manifest.externalToolName } : {}),
475
486
  };
476
487
  });
477
488
  const ids = new Set(local.map((item) => item.id));
478
- return [...local, ...manifestRows.filter((row) => !ids.has(row.id)).map((row) => ({ id: row.id, kind: row.kind, source: 'remote' as const, alive: row.alive, ...(row.nickname ? { nickname: row.nickname } : {}), ...(row.workdir ? { workdir: row.workdir } : {}), ...(row.runId ? { runId: row.runId } : {}), ...(row.terminalOriginCategory ? { terminalOriginCategory: row.terminalOriginCategory } : {}), ...(row.terminalOriginReason ? { terminalOriginReason: row.terminalOriginReason } : {}), ...(row.externalToolName ? { externalToolName: row.externalToolName } : {}) }))];
489
+ return [...local, ...manifestRows.filter((row) => !ids.has(row.id)).map((row) => ({ id: row.id, kind: row.kind, source: 'remote' as const, alive: row.alive, ...(row.nickname ? { nickname: row.nickname } : {}), ...(row.workdir ? { workdir: row.workdir } : {}), ...(row.purpose ? { purpose: row.purpose } : {}), ...(row.runId ? { runId: row.runId } : {}), ...(row.terminalOriginCategory ? { terminalOriginCategory: row.terminalOriginCategory } : {}), ...(row.terminalOriginReason ? { terminalOriginReason: row.terminalOriginReason } : {}), ...(row.externalToolName ? { externalToolName: row.externalToolName } : {}) }))];
479
490
  }
480
491
 
481
492
  export function readLivePtyAddressBook(): PtyAddressBook {
@@ -505,6 +516,9 @@ export function readLivePtyAddressBook(): PtyAddressBook {
505
516
 
506
517
  const liveDeps: PtyTakeoverCommandDeps = {
507
518
  getPty, requestPtyTakeover, requestRemote: requestRemotePtyControl, readManifestFrame: readPtyManifestFrame,
519
+ readManifestRow: getPtyManifest,
520
+ readInstalledBuild: () => readCurrentInstallRecord(),
521
+ readCheckoutHead,
508
522
  // `find`/`retire` must prove before removal: this reader never invokes any reaper.
509
523
  listManifestRows: listPtyManifestRows,
510
524
  listManifestRowsAt: listPtyManifestRowsAt,
@@ -662,6 +676,7 @@ function mapResult(action: string, ptyId: string, control: PtyControlResult, dep
662
676
  deps.log(action, { ptyId, action, ...safe, from: control.from, to: control.to });
663
677
  if (action === 'takeover') return { exitCode: 0, message: `pty takeover: ${ptyId} is now human write-owned` };
664
678
  if (action === 'release') return { exitCode: 0, message: `pty release: ${ptyId} returned to ${control.to ?? 'its prior'} mode` };
679
+ if (action === 'rename') return { exitCode: 0, message: `pty rename: ${ptyId} is now named ${String(safe.nickname ?? '')}` };
665
680
  return { exitCode: 0, message: `pty ${action}: delivered to ${ptyId}` };
666
681
  }
667
682
  const reason = control.reason ?? control.status;
@@ -1341,6 +1356,17 @@ function formatPtyWorktreeProvenance(raw: PtyWorktreeProvenance): string {
1341
1356
  ].join(' ');
1342
1357
  }
1343
1358
 
1359
+ function formatPtyPurpose(raw: PtyWorktreeProvenance, explicit?: string): string {
1360
+ const provenance = normalizePtyWorktreeProvenance(raw);
1361
+ return provenance.known || !explicit?.trim()
1362
+ ? formatPtyWorktreeProvenance(provenance)
1363
+ : `purpose=${singleLinePtyCell(explicit)}`;
1364
+ }
1365
+
1366
+ function ptyPurposeKnown(raw: PtyWorktreeProvenance, explicit?: string): boolean {
1367
+ return normalizePtyWorktreeProvenance(raw).known || Boolean(explicit?.trim());
1368
+ }
1369
+
1344
1370
  function terminalOriginFields(row: Pick<PtyManifestRow, 'terminalOriginCategory' | 'terminalOriginReason' | 'externalToolName'>): { readonly terminalOriginCategory: NonNullable<PtyManifestRow['terminalOriginCategory']>; readonly terminalOriginReason: string; readonly externalToolName?: string } {
1345
1371
  const category = row.terminalOriginCategory;
1346
1372
  const reason = row.terminalOriginReason;
@@ -1383,6 +1409,7 @@ interface PtyListJsonRow extends PtyWebAddress {
1383
1409
  readonly id: string;
1384
1410
  readonly kind: string;
1385
1411
  readonly nickname?: string;
1412
+ readonly purpose?: string;
1386
1413
  readonly runId?: string;
1387
1414
  readonly instance: string | 'unknown';
1388
1415
  readonly sourceRoot: PtyManifestSourceRoot | 'unknown';
@@ -1448,6 +1475,7 @@ function ptyListJsonRow(row: PtyManifestRow, instance: string, sourceRoot: PtyMa
1448
1475
  id: row.id,
1449
1476
  kind: row.kind,
1450
1477
  ...(row.nickname ? { nickname: row.nickname } : {}),
1478
+ ...(row.purpose ? { purpose: row.purpose } : {}),
1451
1479
  ...(row.runId ? { runId: row.runId } : {}),
1452
1480
  instance,
1453
1481
  sourceRoot,
@@ -1561,6 +1589,7 @@ function parseRemoteTerminalItem(value: unknown): RemoteTerminalListItem | null
1561
1589
  id,
1562
1590
  ...(stringOrUndefined(row.kind) ? { kind: stringOrUndefined(row.kind) } : {}),
1563
1591
  ...(stringOrUndefined(row.nickname) ? { nickname: stringOrUndefined(row.nickname) } : {}),
1592
+ ...(stringOrUndefined(row.purpose) ? { purpose: stringOrUndefined(row.purpose) } : {}),
1564
1593
  ...(stringOrUndefined(row.runId) ? { runId: stringOrUndefined(row.runId) } : {}),
1565
1594
  ...(stringOrUndefined(row.instance) ? { instance: stringOrUndefined(row.instance) } : {}),
1566
1595
  ...(typeof row.alive === 'boolean' ? { alive: row.alive } : {}),
@@ -1723,6 +1752,7 @@ function remotePtyListJsonRow(row: RemoteTerminalListItem): PtyListJsonRow {
1723
1752
  id: row.id,
1724
1753
  kind: row.kind ?? 'unknown',
1725
1754
  ...(row.nickname ? { nickname: row.nickname } : {}),
1755
+ ...(row.purpose ? { purpose: row.purpose } : {}),
1726
1756
  ...(row.runId ? { runId: row.runId } : {}),
1727
1757
  instance: row.instance ?? 'unknown',
1728
1758
  sourceRoot: row.sourceRoot ?? 'unknown',
@@ -1755,7 +1785,7 @@ function formatRemotePtyListRow(row: RemoteTerminalListItem): string {
1755
1785
  // ***사실 주장***인데 우리는 그 기계에서 git 을 «돌린 적이 없다». 우리가 아는 것은
1756
1786
  // 「그 응답이 그 칸을 안 실었다」뿐이고, 그것은 «저쪽에 기록이 없다»와 다른 값이다.
1757
1787
  const provenance: PtyWorktreeProvenance = { known: false, provenanceReason: 'unknown' };
1758
- return `${row.id}\t${row.kind ?? 'unknown'}\t${row.nickname ?? '-'}\tremote\t${alive}\t?\t${row.workdir ?? '-'}\t${row.runId ?? '-'}\tunknown\t${origin}\t${formatPtyWorktreeProvenance(provenance)}`;
1788
+ return `${row.id}\t${row.kind ?? 'unknown'}\t${row.nickname ?? '-'}\tremote\t${alive}\t?\t${row.workdir ?? '-'}\t${row.runId ?? '-'}\tunknown\t${origin}\t${formatPtyPurpose(provenance, row.purpose)}`;
1759
1789
  }
1760
1790
 
1761
1791
  async function runPtyListRemote(
@@ -1816,7 +1846,7 @@ async function runPtyListRemote(
1816
1846
  const rendered = fetched.terminals.map((row) => formatRemotePtyListRow(row));
1817
1847
  return {
1818
1848
  exitCode: 0,
1819
- message: [...rendered, `purpose-known rows: 0/${rendered.length}`].join('\n'),
1849
+ message: [...rendered, `purpose-known rows: ${fetched.terminals.filter((row) => Boolean(row.purpose?.trim())).length}/${rendered.length}`].join('\n'),
1820
1850
  };
1821
1851
  }
1822
1852
 
@@ -1913,7 +1943,7 @@ export function runPtyList(
1913
1943
  const ownerRunUsage = classifyPtyOwnerRunUsage(ref.ownerProcessAlive, runTerminated);
1914
1944
  const provenance = (deps.resolveWorktreeProvenance ?? resolvePtyWorktreeProvenance)(ref.workdir);
1915
1945
  if (ownerRunUsage === 'terminated-live-owner') deps.log('owner-run-terminated', { ptyId: ref.id, runId: ref.runId ?? '' });
1916
- return { known: normalizePtyWorktreeProvenance(provenance).known, line: `${formatFederatedRef(ref, ownerRunUsage)}\t${formatTerminalOrigin(ref)}\t${formatPtyWorktreeProvenance(provenance)}${pwa ? `\t${formatPtyWebAddress(ptyWebAddress(ref.id, pwa))}` : ''}` };
1946
+ return { known: ptyPurposeKnown(provenance, ref.purpose), line: `${formatFederatedRef(ref, ownerRunUsage)}\t${formatTerminalOrigin(ref)}\t${formatPtyPurpose(provenance, ref.purpose)}${pwa ? `\t${formatPtyWebAddress(ptyWebAddress(ref.id, pwa))}` : ''}` };
1917
1947
  });
1918
1948
  return { exitCode: 0, message: [...rendered.map(({ line }) => line), `purpose-known rows: ${rendered.filter(({ known }) => known).length}/${rendered.length}`, ...partial].join('\n') };
1919
1949
  }
@@ -1934,9 +1964,14 @@ export function runPtyList(
1934
1964
  deps.log('list', { count: refs.length });
1935
1965
  if (refs.length === 0) return { exitCode: 0, message: `${ptyListEmptyNotice(opts)}\npurpose-known rows: 0/0` };
1936
1966
  const pwa = deps.resolveNexusPwa?.();
1967
+ // 판 칸(맨 끝) — 설치본 기록은 목록 한 번에 한 번만 읽는다.
1968
+ // 설치본 판독기가 없는 구성(시험 deps)은 이 칸을 안 낸다 — 기계마다 다른 값이 목록에 새지 않게.
1969
+ const manifestRowById = new Map((deps.readInstalledBuild ? deps.listManifestRows?.() ?? [] : []).map((row) => [row.id, row] as const));
1970
+ let installedOnce: InstalledRecord | undefined;
1971
+ const installed = (): InstalledRecord => (installedOnce ??= deps.readInstalledBuild?.() ?? {});
1937
1972
  const rendered = refs.map((ref) => {
1938
1973
  const provenance = (deps.resolveWorktreeProvenance ?? resolvePtyWorktreeProvenance)(ref.workdir);
1939
- return { known: normalizePtyWorktreeProvenance(provenance).known, line: `${ref.id}\t${ref.kind}\t${ref.nickname ?? '-'}\t${ref.source}\t${ref.alive ? 'alive' : 'dead'}\t${ref.mode ?? '?'}\t${ref.workdir ?? '-'}\t${ref.runId ?? '-'}${ownerRunUsageById.has(ref.id) ? `\t${ownerRunUsageById.get(ref.id)}` : ''}\t${formatTerminalOrigin(ref)}\t${formatPtyWorktreeProvenance(provenance)}${pwa ? `\t${formatPtyWebAddress(ptyWebAddress(ref.id, pwa))}` : ''}` };
1974
+ return { known: ptyPurposeKnown(provenance, ref.purpose), line: `${ref.id}\t${ref.kind}\t${ref.nickname ?? '-'}\t${ref.source}\t${ref.alive ? 'alive' : 'dead'}\t${ref.mode ?? '?'}\t${ref.workdir ?? '-'}\t${ref.runId ?? '-'}${ownerRunUsageById.has(ref.id) ? `\t${ownerRunUsageById.get(ref.id)}` : ''}\t${formatTerminalOrigin(ref)}\t${formatPtyPurpose(provenance, ref.purpose)}${pwa ? `\t${formatPtyWebAddress(ptyWebAddress(ref.id, pwa))}` : ''}${formatListRunColumn(manifestRowById.get(ref.id), deps, installed)}` };
1940
1975
  });
1941
1976
  return {
1942
1977
  exitCode: 0,
@@ -2025,12 +2060,56 @@ const WAITABLE_FRAME_STATES: readonly Exclude<FrameState, 'unknown'>[] = ['idle'
2025
2060
  export async function runPtyState(ref: string, deps: PtyTakeoverCommandDeps = liveDeps, json = false): Promise<PtyTakeoverCommandResult> {
2026
2061
  const acquired = await acquirePtyScreen(ref, deps);
2027
2062
  if ('exitCode' in acquired) return acquired;
2028
- if (acquired.control.status !== 'success') return { exitCode: 1, message: formatSnapshotResult(acquired.id, acquired.control) };
2063
+ // ⭐ `state` 는 화면 분류(추정)고 `turn` 은 TUI 가 스스로 적은 값이다 — 둘을 섞지 않는다.
2064
+ const run = ptyRunStateFor(acquired.id, deps);
2065
+ if (acquired.control.status !== 'success') {
2066
+ // 화면을 못 읽어도 기록된 턴·판은 낸다(state=unknown + 화면 실패 사유). 기록이 하나도 없으면 종전 실패 그대로.
2067
+ if (run.turn === 'unknown' && run.build === null) return { exitCode: 1, message: formatSnapshotResult(acquired.id, acquired.control) };
2068
+ const screenUnavailable = acquired.control.reason ?? acquired.control.status;
2069
+ deps.log('state-screen-unavailable', { ptyId: acquired.id, reason: screenUnavailable, turn: run.turn });
2070
+ return formatPtyStateResult(acquired.id, { state: 'unknown', label: null }, run, deps.now?.() ?? Date.now(), json, screenUnavailable);
2071
+ }
2029
2072
  const verdict = classifyFrameState(acquired.control.screen ?? '');
2030
2073
  const at = deps.now?.() ?? Date.now();
2074
+ if (run.turn === 'unknown' || run.stale === null) deps.log('state-run-unknown', { ptyId: acquired.id, turn: run.turn, staleReason: run.staleReason, hasBuild: run.build !== null });
2075
+ return formatPtyStateResult(acquired.id, { state: verdict.state, label: verdict.matchedLabel }, run, at, json);
2076
+ }
2077
+
2078
+ function formatPtyStateResult(id: string, screen: { state: string; label?: string | null }, run: PtyRunStateView, at: number, json: boolean, screenUnavailable?: string): PtyTakeoverCommandResult {
2031
2079
  return { exitCode: 0, message: json
2032
- ? JSON.stringify({ id: acquired.id, state: verdict.state, label: verdict.matchedLabel, at })
2033
- : `pty state: ${acquired.id} state=${verdict.state} label=${verdict.matchedLabel ?? '-'}` };
2080
+ ? JSON.stringify({
2081
+ id, state: screen.state, label: screen.label, at,
2082
+ ...(screenUnavailable ? { screenUnavailable } : {}),
2083
+ turn: run.turn, ...(run.turnAt !== undefined ? { turnAt: run.turnAt } : {}),
2084
+ build: run.build ? { version: run.build.version, sha: run.build.sha, source: run.build.source } : null,
2085
+ installed: run.installed, stale: run.stale, staleReason: run.staleReason,
2086
+ })
2087
+ : `pty state: ${id} state=${screen.state} label=${screen.label ?? '-'}${screenUnavailable ? ` screen=unavailable(${screenUnavailable})` : ''} turn=${run.turn} build=${formatRunBuild(run)} installed=${shortSha(run.installed)} stale=${run.stale ?? 'unknown'}${run.stale === null ? '' : ` (${run.staleReason})`}` };
2088
+ }
2089
+
2090
+ function ptyRunStateFor(id: string, deps: PtyTakeoverCommandDeps): PtyRunStateView {
2091
+ let row: PtyManifestRow | null = null;
2092
+ try { row = deps.readManifestRow?.(id) ?? null; } catch { row = null; }
2093
+ // 판독기 미주입이면 «모른다»로 — 기본 판독(실 설치본·git)은 liveDeps 가 싣는다.
2094
+ return describePtyRunState(row, {
2095
+ readInstalled: deps.readInstalledBuild ?? (() => ({})),
2096
+ readCheckoutHead: deps.readCheckoutHead ?? (() => undefined),
2097
+ });
2098
+ }
2099
+
2100
+ function formatRunBuild(run: PtyRunStateView): string {
2101
+ return run.build ? `${run.build.version}@${shortSha(run.build.sha)}(${run.build.source})` : 'unknown';
2102
+ }
2103
+
2104
+ /** `pty list` 한 칸 — 판을 적는 행(TUI)만. `run=<sha>` · 낡았으면 `,stale` · 옛 행 추정은 `run=?,stale`. */
2105
+ function formatListRunColumn(row: PtyManifestRow | undefined, deps: PtyTakeoverCommandDeps, installed: () => InstalledRecord): string {
2106
+ if (!row || (!row.build && row.kind !== 'tui')) return '';
2107
+ const run = describePtyRunState(row, {
2108
+ readInstalled: installed,
2109
+ ...(deps.readCheckoutHead ? { readCheckoutHead: deps.readCheckoutHead } : {}),
2110
+ });
2111
+ if (!run.build && run.stale !== true) return '';
2112
+ return `\trun=${run.build?.sha ? shortSha(run.build.sha) : '?'}${run.stale === true ? ',stale' : ''}`;
2034
2113
  }
2035
2114
 
2036
2115
  export async function runPtyWait(ref: string, until: string, options: { readonly timeoutMs?: number; readonly pollMs?: number } = {}, deps: PtyTakeoverCommandDeps = liveDeps): Promise<PtyTakeoverCommandResult> {
@@ -2054,6 +2133,15 @@ export async function runPtyWait(ref: string, until: string, options: { readonly
2054
2133
  }
2055
2134
 
2056
2135
  export function runPtyText(ref: string, text: string, appendEnter = false, deps: PtyTakeoverCommandDeps = liveDeps, actor: PtyWriteActor = 'human'): Promise<PtyTakeoverCommandResult> { return inject(ref, 'input-text', text + (appendEnter ? '\r' : ''), { length: text.length + (appendEnter ? 1 : 0) }, deps, actor); }
2136
+ /** `pty text --when-idle` — 화면이 idle 로 분류될 때까지 기다린 뒤 넣는다. 못 기다렸으면 «안 넣고» rc=1.
2137
+ * ⭐ 맨 `elanous` TUI 는 기다리지 않아도 턴 중·입력 중 글을 별도 대기열로 돌린다(`input/external-input-queue`) —
2138
+ * 이 플래그는 그 밖의 대상(외부 CLI 자식 등)에서 «언제 들어갔나»를 rc 로 받고 싶을 때 쓴다. */
2139
+ export async function runPtyTextWhenIdle(ref: string, text: string, appendEnter: boolean, options: { readonly timeoutMs?: number; readonly pollMs?: number }, deps: PtyTakeoverCommandDeps = liveDeps, actor: PtyWriteActor = 'human'): Promise<PtyTakeoverCommandResult> {
2140
+ const waited = await runPtyWait(ref, 'idle', options, deps);
2141
+ if (waited.exitCode !== 0) return { exitCode: 1, message: `pty text --when-idle: not delivered · ${waited.message}` };
2142
+ const typed = await runPtyText(ref, text, appendEnter, deps, actor);
2143
+ return { ...typed, message: `${waited.message}\n${typed.message}` };
2144
+ }
2057
2145
  export function runPtyKey(ref: string, key: string, repeat = 1, deps: PtyTakeoverCommandDeps = liveDeps, actor: PtyWriteActor = 'human'): Promise<PtyTakeoverCommandResult> {
2058
2146
  if (!Number.isInteger(repeat) || repeat < 1) return Promise.resolve({ exitCode: 1, message: 'pty key: repeat must be a positive integer' });
2059
2147
  try { const normalized = key.trim().toLowerCase(); return inject(ref, 'input-key', resolvePtySpecialKey(normalized).repeat(repeat), { key: normalized, repeat }, deps, actor); } catch (error) { return Promise.resolve({ exitCode: 1, message: `pty key: ${(error as Error).message}` }); }
@@ -2091,6 +2179,20 @@ export async function runPtyResize(ref: string, cols: number, rows: number, deps
2091
2179
  ? { status: 'denied', reason: 'write-arbiter' }
2092
2180
  : { status: 'failed', reason: 'resize-error' }, deps, observed);
2093
2181
  }
2182
+ /** `pty rename <ref> <name>` — 별명만 바꾼다(소유권 아님 · resize 와 같은 길: 로컬이면 바로, 아니면 소유자 IPC).
2183
+ * ⭐ 맨 `elanous` TUI 행(`tui:<pid>`)도 받는다 — 소유자 쪽 renamePty 가 제어 대상의 manifest 행을 고친다.
2184
+ * 별명 충돌은 기존 rename 규칙 그대로다(거부하지 않는다 · 같은 별명 둘이면 ref 해석이 ambiguous 로 거부). */
2185
+ export async function runPtyRename(ref: string, name: string, deps: PtyTakeoverCommandDeps = liveDeps, actor: PtyWriteActor = 'human'): Promise<PtyTakeoverCommandResult> {
2186
+ const nickname = name.trim();
2187
+ if (!nickname) return { exitCode: 1, message: 'pty rename: name must not be empty' };
2188
+ const refResult = resolveId(ref, 'rename', deps); if (typeof refResult !== 'string') return refResult;
2189
+ const id = refResult;
2190
+ const observed = { nickname, actor };
2191
+ const handle = deps.getPty(id);
2192
+ if (!handle) return mapResult('rename', id, await deps.requestRemote(id, 'rename', { nickname }, { actor }), deps, observed);
2193
+ const renamed = (deps.renameLocal ?? renamePty)(id, nickname);
2194
+ return mapResult('rename', id, renamed ? { status: 'success' } : { status: 'unknown-pty' }, deps, observed);
2195
+ }
2094
2196
  export function registerPtyTakeoverCommands(program: Command, deps: PtyTakeoverCommandDeps = liveDeps, toolInstallDeps: ToolInstallDeps = {}): void {
2095
2197
  const pty = program.command('pty').description(
2096
2198
  // ⭐ `<ref>` = id · nickname · unique prefix — **ref 를 받는 하위명령**이 resolvePtyRef 로 해석한다(`list` 는 인자 없음).
@@ -2181,10 +2283,15 @@ export function registerPtyTakeoverCommands(program: Command, deps: PtyTakeoverC
2181
2283
  return actor ? next(actor) : Promise.resolve({ exitCode: 1, message: `pty: --actor must be 'human' or 'agent' (got ${opts.actor})` });
2182
2284
  };
2183
2285
  pty.command('text <ref> <text>').option('--enter', 'append Enter (CR) after the text').option('-r', 'inject text on the default remote bookmark (does not take a value)').option('--remote <name>', 'inject text on a named remote bookmark').option(...ACTOR_FLAG)
2184
- .description('Inject literal text — no newline unless --enter').action((id: string, text: string, opts: { enter?: boolean; actor?: string; r?: boolean; remote?: string }) => run(() => {
2286
+ .option('--when-idle', 'wait until the screen classifies as idle before injecting; rc=1 and nothing injected on timeout (the bare elanous TUI already queues text sent mid-turn or over a typed draft as a separate message)')
2287
+ .option('--idle-timeout <ms>', 'max wait for --when-idle in milliseconds', '600000')
2288
+ .description('Inject literal text — no newline unless --enter').action((id: string, text: string, opts: { enter?: boolean; actor?: string; r?: boolean; remote?: string; whenIdle?: boolean; idleTimeout: string }) => run(() => {
2185
2289
  const remote = opts.remote ?? (opts.r === true ? true : undefined);
2290
+ if (opts.whenIdle === true && remote !== undefined) return Promise.resolve({ exitCode: 1 as const, message: 'pty text: --when-idle is local-only (remote bookmarks are not supported)' });
2186
2291
  return withActor(opts, (actor) => remote === undefined
2187
- ? runPtyText(id, text, Boolean(opts.enter), deps, actor)
2292
+ ? (opts.whenIdle === true
2293
+ ? runPtyTextWhenIdle(id, text, Boolean(opts.enter), { timeoutMs: Number(opts.idleTimeout) }, deps, actor)
2294
+ : runPtyText(id, text, Boolean(opts.enter), deps, actor))
2188
2295
  : runPtyRemoteControl('text', id, remote, { action: 'input-text', chars: text + (opts.enter === true ? '\r' : '') }, deps));
2189
2296
  }));
2190
2297
  pty.command('key <ref> <key>').option('-n, --repeat <count>', 'repetitions', '1').option('-r', 'inject a key on the default remote bookmark (does not take a value)').option('--remote <name>', 'inject a key on a named remote bookmark').option(...ACTOR_FLAG)
@@ -2208,6 +2315,8 @@ export function registerPtyTakeoverCommands(program: Command, deps: PtyTakeoverC
2208
2315
  if (remote !== undefined && actor === 'agent') return { exitCode: 1, message: 'pty mouse: remote HTTP cannot verify same-run agent ownership; use the owner IPC instead' };
2209
2316
  return remote === undefined ? runPtyMouse(id, input, deps, actor) : runPtyRemoteControl('mouse', id, remote, { action: 'input-mouse', ...input }, deps);
2210
2317
  })));
2318
+ pty.command('rename <ref> <name>').option(...ACTOR_FLAG)
2319
+ .description("Rename a live PTY's nickname (incl. the bare elanous TUI row tui:<pid>) — later refs can use the new name").action((id: string, name: string, opts: { actor?: string }) => run(() => withActor(opts, (actor) => runPtyRename(id, name, deps, actor))));
2211
2320
  pty.command('resize <ref> <cols> <rows>').option(...ACTOR_FLAG)
2212
2321
  .description('Resize the PTY (gated by the same access matrix as input)').action((id: string, cols: string, rows: string, opts: { actor?: string }) => run(() => withActor(opts, (actor) => runPtyResize(id, Number(cols), Number(rows), deps, actor))));
2213
2322
  }
@@ -53,6 +53,7 @@ import { autoStartScheduledRelease, type AutoStartDeferral } from '../release-lo
53
53
  import { runRehearsalTick, type RehearsalDeps } from '../release-loop/rehearsal.js';
54
54
  import { landingFreezeMessage, LandingFrozenError, readLandingFreeze } from '../release-loop/landing-freeze.js';
55
55
  import { formatLightRc, runLightRc, type LightRcDeps } from '../release-loop/light-rc.js';
56
+ import { applyWatchList, formatGateHistory, gateHistory, ghMergedPrs } from '../../scripts/release-loop/gate-history.js';
56
57
  import { registerRfcCommands } from './rfc-cli.js';
57
58
 
58
59
  export const DEFAULT_PUBLIC_REPO = 'ElanvitalAI/elanous';
@@ -1140,14 +1141,15 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
1140
1141
  .option('--remote <host>', '게이트 호스트(기본 config gateRemote.host)')
1141
1142
  .option('--local', '원격 대신 이 기계에서 돌린다(원격 자식이 이것으로 다시 불린다)')
1142
1143
  .option('--shards <n>', '시험 분할 수', '4')
1144
+ .option('--rehearsal-tui', '리허설 전용 TUI 화면 점검(원격 자식 전달)')
1143
1145
  .option('--json', '결과 한 줄 JSON(stdout) · 사람 줄은 stderr')
1144
- .action(async (o: { version: string; base?: string; head?: string; remote?: string; local?: boolean; shards: string; json?: boolean }) => {
1146
+ .action(async (o: { version: string; base?: string; head?: string; remote?: string; local?: boolean; shards: string; rehearsalTui?: boolean; json?: boolean }) => {
1145
1147
  // The root strips `--local` from argv (remote-bookmark attach) before Commander sees it — same read as `self gate`.
1146
1148
  const local = !!o.local || process.argv.slice(2).includes('--local');
1147
1149
  await jsonAction(o.json, async (log) => {
1148
1150
  if (o.remote !== undefined && local) throw new Error('release light-rc: --remote and --local cannot be combined');
1149
1151
  const shards = Number(o.shards);
1150
- const result = await runLightRc(o.version, { base: o.base, head: o.head, remote: o.remote, local, shards, ledgerRoot: releaseRunDeps.ledgerRoot, log: (l) => console.error(l) }, lightRcDeps);
1152
+ const result = await runLightRc(o.version, { base: o.base, head: o.head, remote: o.remote, local, shards, rehearsalTui: o.rehearsalTui, ledgerRoot: releaseRunDeps.ledgerRoot, log: (l) => console.error(l) }, lightRcDeps);
1151
1153
  for (const line of formatLightRc(result)) log(line);
1152
1154
  return result;
1153
1155
  }, (r) => r.ok);
@@ -1191,6 +1193,46 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
1191
1193
  ...(o.gateExecutor !== undefined && result.state.inputOverrides?.length ? { gateExecutor: result.state.inputOverrides.at(-1) } : {}) };
1192
1194
  }, (r) => r.status === 'done' || r.status === 'awaiting-approval');
1193
1195
  });
1196
+ release.command('gate-history')
1197
+ .description('GATE-FAIL-HISTORY (0.2.29) — 판을 넘는 게이트 실패 표 — 모든 release-loop·light-rc 런 원장 ⊕ gate-verdict 에서 시험 파일별 introduced·preexisting·env·flaky 횟수 · 마지막 실패 판 · 원인 PR(수리 PR 본문 «원인 #N»)')
1198
+ .option('--since <판|일>', '이 판(x.y.z)부터 · 또는 그 날(YYYY-MM-DD) 이후 시작된 런부터')
1199
+ .option('--top <n>', '가장 자주 깨지는 순 상위 n 줄', '20')
1200
+ .option('--apply-watchlist', '감시 목록(최근 3판 중 2판 이상 새 실패·흔들림)을 release/light-rc-always.txt 에 자동 추가(없는 줄만)')
1201
+ .option('--json', '결과 한 줄 JSON(stdout) · 사람 줄은 stderr')
1202
+ .action(async (o: { since?: string; top: string; applyWatchlist?: boolean; json?: boolean }) => {
1203
+ const log = o.json ? console.error : console.log;
1204
+ try {
1205
+ const top = Number(o.top);
1206
+ if (!/^\d+$/.test(o.top) || !Number.isSafeInteger(top)) throw new CliUserError(`--top 은 0 이상의 정수다: ${o.top}`);
1207
+ const instanceRoots = [effectiveInstanceRoot()];
1208
+ const ledgerRoots = getElanousConfigDirOverride() ? [effectiveInstanceRoot()] : [releaseRunDeps.ledgerRoot ?? releaseLedgerRoot()];
1209
+ const report = gateHistory({ instanceRoots, ledgerRoots, since: o.since }, { mergedPrs: ghMergedPrs });
1210
+ let applied = { added: [] as string[], file: 'release/light-rc-always.txt' };
1211
+ if (o.applyWatchlist && report.watchList.length) {
1212
+ const file = applied.file;
1213
+ const text = existsSync(file) ? readFileSync(file, 'utf8') : '# LIGHT-RC (0.2.19) — tests `release light-rc` always runs, whatever changed since the previous cut.\n# One repository-relative path per line · `#` starts a comment.\n';
1214
+ const next = applyWatchList(text, report.watchList);
1215
+ if (next.added.length) {
1216
+ writeFileSync(file, next.text, { mode: 0o644 });
1217
+ debug.log('release.gate-history', 'watchlist-applied', { added: next.added, file });
1218
+ }
1219
+ applied = { added: next.added, file };
1220
+ }
1221
+ if (o.json) await writeStdoutJson(`${JSON.stringify({ ...report, rows: report.rows.slice(0, top), top, ...(o.applyWatchlist ? { applied } : {}) })}\n`);
1222
+ else {
1223
+ for (const line of formatGateHistory(report, top)) log(line);
1224
+ if (o.applyWatchlist) {
1225
+ if (!report.watchList.length) log('감시 목록에 추가할 파일이 없다');
1226
+ else if (!applied.added.length) log(`감시 목록은 이미 있다: ${report.watchList.join(' · ')}`);
1227
+ else log(`✅ 감시 목록 ${applied.added.length}줄 추가: ${applied.added.join(' · ')} → ${applied.file}`);
1228
+ }
1229
+ }
1230
+ } catch (e) {
1231
+ if (o.json) await writeStdoutJson(`${JSON.stringify({ ok: false, error: (e as Error).message })}\n`);
1232
+ else console.error(`⛔ ${(e as Error).message}`);
1233
+ process.exitCode = 1;
1234
+ }
1235
+ });
1194
1236
  release.command('rehearsal').description('판 일정에서 컷 전 가벼운 RC 두 단계').command('tick')
1195
1237
  .description('15분 틱: 다음 판 컷 −7h · −150m RC 계획(기본 보기만)')
1196
1238
  .option('--apply', '도장 선점 후 해당 단계 실행')
@@ -202,7 +202,8 @@ function hasFlag(args: readonly string[], name: string): boolean {
202
202
  * ⚠️ 늙을 수 있는 목록이라 ***시험이 감시한다*** — `src/index.ts` 의 루트 옵션 선언을
203
203
  * 읽어 `<값>` 을 받는 것이 전부 여기 있는지 확인한다(`root value-taking flags are enumerated`).
204
204
  * ⇒ 루트에 값 받는 플래그를 더하면 그 시험이 «먼저» 깨진다. */
205
- export const ROOT_FLAGS_TAKING_VALUE = new Set(['--remote', '--config-dir']);
205
+ // ⭐ `--name <name>` = 대시보드 TUI 별명(dashboard-name-flag.ts) — 값이 다음 토큰이라 `elanous --name op -r` 의 `-r` 이 루트로 남게 센다.
206
+ export const ROOT_FLAGS_TAKING_VALUE = new Set(['--remote', '--config-dir', '--name']);
206
207
 
207
208
  /** 이 토큰이 루트 «선행 플래그 구간» 안에 있나 — 즉 전역 선처리가 소유하나.
208
209
  * ⛔ 없으면 다른 명령의 `-r` 을 «탈취»한다(`autopilot link … -r friend`).
@@ -78,19 +78,41 @@ function contextFacts(snapshot: unknown): string[] {
78
78
  return facts.slice(0, MAX_ROWS);
79
79
  }
80
80
 
81
- export function renderSeatBootCard(seat: SeatRole, sections: ReadonlyArray<{ title: string; source: string; updated: string; rows: readonly string[]; reason?: string }>, facts: readonly string[], contextUpdated = '미상'): string {
82
- const out = [`# ${seat} 자리 부팅 카드`, '', '## 현재 구조화 관측', '출처: elanous://context-now', `갱신: ${clean(contextUpdated)}`, ...(facts.length ? facts.map(row => `- ${clean(row)}`) : ['- 미관측: contextNow 구조화 facts/events 없음'])];
81
+ export type SeatBootSection = { title: string; source: string; updated: string; rows: readonly string[]; reason?: string };
82
+
83
+ /** `facts === null` 이면 contextNow 절을 «생략»한다(TUI 부트 카드 — 턴 경로에서 버스를 안 읽는다). */
84
+ export function renderSeatBootCard(seat: string, sections: ReadonlyArray<SeatBootSection>, facts: readonly string[] | null, contextUpdated = '미상'): string {
85
+ const out = facts === null
86
+ ? [`# ${seat} 자리 부팅 카드`]
87
+ : [`# ${seat} 자리 부팅 카드`, '', '## 현재 구조화 관측', '출처: elanous://context-now', `갱신: ${clean(contextUpdated)}`, ...(facts.length ? facts.map(row => `- ${clean(row)}`) : ['- 미관측: contextNow 구조화 facts/events 없음'])];
83
88
  for (const section of sections) out.push('', `## ${section.title}`, `출처: ${clean(section.source)}`, `갱신: ${clean(section.updated)}`, ...(section.rows.length ? section.rows.map(row => `- ${clean(row)}`) : [`- ${clean(section.reason ?? '미관측')}`]));
84
89
  return out.join('\n');
85
90
  }
86
91
 
92
+ /** 자리 카드의 파일·우편 절(동기) — `eln seat boot` 와 TUI 세션 부트(`dashboard/seat-boot-preamble.ts`)가 같이 쓴다. */
93
+ export function collectSeatBootSections(seat: string, options: { home: string; msgPath: string }): { sections: SeatBootSection[]; unread: number | null } {
94
+ const root = join(options.home, 'elanous-hq', 'seat-state');
95
+ const seatDir = join(root, seat);
96
+ let unread: number | null = null;
97
+ try { unread = readUnreadCount(seat, options.msgPath); }
98
+ catch { /* unavailable is not a measured zero */ }
99
+ const sections: SeatBootSection[] = [
100
+ { title: 'msg 원장', source: options.msgPath, updated: unread === null ? '미상' : new Date().toISOString(), rows: [`안 읽은 msg ${unread ?? '미관측'} (${seat})`] },
101
+ { title: 'HANDOFF', ...metadata(options.home, root, join(seatDir, 'HANDOFF.md'), 'markdown') },
102
+ { title: 'inbox', ...metadata(options.home, root, join(seatDir, 'inbox.md'), 'markdown') },
103
+ { title: '수확 주장', ...metadata(options.home, root, join(seatDir, 'harvest-claims.tsv'), 'tsv') },
104
+ { title: '예약', ...metadata(options.home, root, join(seatDir, 'scheduled.tsv'), 'tsv') },
105
+ { title: '공통 메모리 색인', ...metadata(options.home, root, join(root, 'memory', 'MEMORY.md'), 'memory') },
106
+ ];
107
+ return { sections, unread };
108
+ }
109
+
87
110
  export function registerSeatBootCommands(command: Command, options: { home?: () => string; contextNow?: () => unknown; msgPath?: () => string } = {}): void {
88
111
  command.command('boot <seat>').description('현재 자리 카드 — 허용된 메타데이터만 읽기 전용 표시')
89
112
  .action(async (rawSeat: string) => {
90
113
  const seat = rawSeat.toUpperCase();
91
114
  if (!(SEAT_ROLES as readonly string[]).includes(seat)) { console.error(`seat boot: unknown seat ${rawSeat} (OP|TC|MK|UX)`); process.exitCode = 2; return; }
92
115
  const home = options.home?.() ?? homedir();
93
- const root = join(home, 'elanous-hq', 'seat-state');
94
116
  let facts: string[] = [];
95
117
  let contextUpdated = '미상';
96
118
  try {
@@ -102,19 +124,7 @@ export function registerSeatBootCommands(command: Command, options: { home?: ()
102
124
  contextUpdated = typeof context.at === 'string' ? clean(context.at) : '시각 미관측';
103
125
  facts = contextFacts(snapshot);
104
126
  } catch { facts = []; contextUpdated = '미관측: contextNow 조회 실패'; }
105
- const seatDir = join(root, seat);
106
- const msgPath = options.msgPath?.() ?? defaultMsgStorePath();
107
- let unread: number | null = null;
108
- try { unread = readUnreadCount(seat, msgPath); }
109
- catch { /* unavailable is not a measured zero */ }
110
- const sections = [
111
- { title: 'msg 원장', source: msgPath, updated: unread === null ? '미상' : new Date().toISOString(), rows: [`안 읽은 msg ${unread ?? '미관측'} (${seat})`] },
112
- { title: 'HANDOFF', ...metadata(home, root, join(seatDir, 'HANDOFF.md'), 'markdown') },
113
- { title: 'inbox', ...metadata(home, root, join(seatDir, 'inbox.md'), 'markdown') },
114
- { title: '수확 주장', ...metadata(home, root, join(seatDir, 'harvest-claims.tsv'), 'tsv') },
115
- { title: '예약', ...metadata(home, root, join(seatDir, 'scheduled.tsv'), 'tsv') },
116
- { title: '공통 메모리 색인', ...metadata(home, root, join(root, 'memory', 'MEMORY.md'), 'memory') },
117
- ];
127
+ const sections = collectSeatBootSections(seat, { home, msgPath: options.msgPath?.() ?? defaultMsgStorePath() }).sections;
118
128
  console.log(renderSeatBootCard(seat as SeatRole, sections, facts, contextUpdated));
119
129
  });
120
130
  }
@@ -1493,8 +1493,11 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
1493
1493
  try {
1494
1494
  if (!id) {
1495
1495
  const { bindMirroredRemoteRejudgeCards } = await import('../task-agent/remote-rejudge-bind.js');
1496
+ const { mirrorRemoteRunLedgers } = await import('../task-agent/parent-host.js');
1496
1497
  const cards = readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(statePath).tasks ?? {};
1497
- const binding = await bindMirroredRemoteRejudgeCards(cards, statePath);
1498
+ const binding = await bindMirroredRemoteRejudgeCards(cards, statePath, deps.cardRunEvidence?.ssh
1499
+ ? { mirror: (target, runId, root) => mirrorRemoteRunLedgers(target, runId, root, deps.cardRunEvidence!.ssh) }
1500
+ : {});
1498
1501
  try { debug.log('task-agent', 'remote-rejudge-bind', binding); } catch { /* fail-soft */ }
1499
1502
  }
1500
1503
  ids = id ? [id] : rejudgeCandidates(readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(statePath).tasks ?? {});
@@ -1503,6 +1506,8 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
1503
1506
  }
1504
1507
  const { configuredTaskAgentLiveMoves } = await import('../task-agent/live-moves.js');
1505
1508
  const liveMoves = deps.rejudge?.liveMoves ?? await configuredTaskAgentLiveMoves();
1509
+ const repairBudget = opts.all ? { max: (await import('../user-config.js')).getUserConfig().taskAgent?.repairMaxPerTick ?? 3,
1510
+ requested: 0, capped: 0 } : undefined;
1506
1511
  const all = [];
1507
1512
  for (const cardId of ids) {
1508
1513
  await mirrorRemoteCardLedger(cardId, deps);
@@ -1510,7 +1515,8 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
1510
1515
  try { debug.log('task-agent', 'card-binding-replay-failed', { card: cardId, reason: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
1511
1516
  }
1512
1517
  let outcomes: Awaited<ReturnType<typeof rejudgeCardOnHead>>;
1513
- try { outcomes = await rejudgeCardOnHead(cardId, { ...deps.rejudge, liveMoves, live: { ...deps.rejudge?.live, statePath } }); } catch (error) {
1518
+ try { outcomes = await rejudgeCardOnHead(cardId, { ...deps.rejudge, liveMoves,
1519
+ ...(repairBudget ? { repairBudget } : {}), live: { ...deps.rejudge?.live, statePath } }); } catch (error) {
1514
1520
  // 카드 하나의 예외가 --all 의 나머지 카드 판단을 멈추지 않게 — 사유를 남기고 다음 카드로.
1515
1521
  const reason = (error instanceof Error ? error.message : String(error)).slice(-300);
1516
1522
  try { debug.log('task-agent', 'rejudge-on-head', { card: cardId, pr: null, fromHead: null, toHead: null, step: 'target', decision: 'rejudge-threw', reason }, { level: 'warn' }); } catch { /* fail-soft */ }