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
package/src/llm.ts CHANGED
@@ -3,6 +3,10 @@
3
3
  // Auto-routes based on model name prefix, or picks the first available provider.
4
4
 
5
5
  import { createHash } from 'node:crypto';
6
+ import { testFakeLlmEnabled, testFakeLlmProvider } from './ux-sim/fake-llm.js';
7
+ import { realpathSync } from 'node:fs';
8
+ import { resolve } from 'node:path';
9
+ import { globalAnchorPath } from './prompt-library/universal-preamble.js';
6
10
  import type { LLMUsage } from './prompt-cache/types.js';
7
11
  import { applyOpenRouterCacheControl, openRouterPromptCacheFamily } from './prompt-cache/openrouter.js';
8
12
  import { detectLocale, type Locale } from './expression/locale.js';
@@ -27,8 +31,11 @@ import {
27
31
  dispatchWithParallelSafety,
28
32
  isSafeForParallel,
29
33
  } from './session-runtime/parallel-dispatch.js';
34
+ import { createRetryDisplayGate, type RetryDisplayStep } from './llm-stream-retry-display.js';
30
35
  import {
31
36
  DoomLoopTracker,
37
+ backoffMs,
38
+ classifyError,
32
39
  decideRetry,
33
40
  fingerprintError,
34
41
  decideProviderFallback,
@@ -336,6 +343,8 @@ export type ToolChoice = 'auto' | 'required' | 'none' | { name: string };
336
343
 
337
344
  export interface LLMOpts {
338
345
  model?: string;
346
+ /** Reports the provider and model actually attempted, including fallbacks. */
347
+ onResolvedProvider?(provider: string, model: string): void;
339
348
  temperature?: number;
340
349
  maxTokens?: number;
341
350
  signal?: AbortSignal;
@@ -4228,17 +4237,11 @@ function permitsAutomaticProviderFallback(opts: LLMOpts & { provider?: LLMProvid
4228
4237
  }
4229
4238
  }
4230
4239
 
4231
- function configuredFallbackProviders(): LLMProvider[] {
4240
+ function configuredFallbackChainSteps(): readonly string[] {
4232
4241
  try {
4233
4242
  const { getUserConfig } = require('./user-config.js') as typeof import('./user-config.js');
4234
4243
  const { normalizeFallbackChain } = require('./oauth/fallback-chain.js') as typeof import('./oauth/fallback-chain.js');
4235
- const { chain } = normalizeFallbackChain(getUserConfig().llm.fallbackChain);
4236
- const out: LLMProvider[] = [];
4237
- for (const name of providerNamesFromFallbackChain(chain)) {
4238
- const provider = PROVIDERS[name];
4239
- if (provider) out.push(provider);
4240
- }
4241
- return out;
4244
+ return normalizeFallbackChain(getUserConfig().llm.fallbackChain).chain;
4242
4245
  } catch (err) {
4243
4246
  // ⛔ 조용히 삼키면 「설정을 못 읽었다」가 「폴백 후보가 없다」로 «둔갑»한다 —
4244
4247
  // 호출자는 그것을 `fallback candidates exhausted` 로 보고 사람에게 그렇게 말한다.
@@ -4250,35 +4253,116 @@ function configuredFallbackProviders(): LLMProvider[] {
4250
4253
  }
4251
4254
  }
4252
4255
 
4253
- function remainingFallbackProviderNames(
4256
+ /** 체인 칸 하나가 후보에서 «왜» 빠졌나. ⭐ `exhausted` 를 설명 가능하게 하려고 남긴다(TUI-STREAM-RETRY).
4257
+ * `folded-into-earlier-step` = `codex-credits` 처럼 앞 칸과 같은 provider 로 접힌 칸 — 접는 동작 자체는
4258
+ * `providerNamesFromFallbackChain` 소유이고 여기선 «기록만» 한다. */
4259
+ export type FallbackCandidateSkipReason =
4260
+ | 'already-attempted'
4261
+ | 'not-available'
4262
+ | 'folded-into-earlier-step'
4263
+ | 'unknown-step';
4264
+
4265
+ export interface FallbackCandidateSkip {
4266
+ step: string;
4267
+ provider?: string;
4268
+ reason: FallbackCandidateSkipReason;
4269
+ }
4270
+
4271
+ function explainFallbackCandidates(
4254
4272
  attemptedProviders: ReadonlySet<string>,
4255
4273
  opts: LLMOpts & { provider?: LLMProvider },
4256
- ): string[] {
4274
+ chain: readonly string[] = configuredFallbackChainSteps(),
4275
+ ): { candidates: string[]; skipped: FallbackCandidateSkip[] } {
4257
4276
  // Priority:
4258
4277
  // 1. per-call opts.provider → no fallback (caller pinned the route)
4259
4278
  // 2. llm.provider === 'auto' → ⭐ 2026-09-24 결정: `llm.fallbackChain` 을 «먼저»(codex-rotate→openai-codex · grok),
4260
4279
  // 그다음 체인이 «다루지 않는» 자동 후보(anthropic·gemini·local). 체인이 grok 을 뺐으면 grok 으로 새지 않는다.
4261
4280
  // 종전엔 auto 가 체인을 통째로 무시하고 AUTOMATIC_PROVIDER_ORDER 만 걸었다.
4262
4281
  // 3. otherwise → configured llm.fallbackChain (read from config; never baked here)
4263
- if (opts.provider) return [];
4282
+ const candidates: string[] = [];
4283
+ const skipped: FallbackCandidateSkip[] = [];
4284
+ if (opts.provider) return { candidates, skipped };
4285
+ const seen = new Set<string>();
4286
+ const consider = (step: string, provider: LLMProvider) => {
4287
+ if (attemptedProviders.has(provider.name)) skipped.push({ step, provider: provider.name, reason: 'already-attempted' });
4288
+ else if (!provider.available()) skipped.push({ step, provider: provider.name, reason: 'not-available' });
4289
+ else candidates.push(provider.name);
4290
+ };
4291
+ for (const step of chain) {
4292
+ const name = providerNamesFromFallbackChain([step])[0];
4293
+ const provider = name ? PROVIDERS[name] : undefined;
4294
+ if (!name || !provider) {
4295
+ skipped.push({ step, ...(name ? { provider: name } : {}), reason: 'unknown-step' });
4296
+ continue;
4297
+ }
4298
+ if (seen.has(name)) {
4299
+ skipped.push({ step, provider: name, reason: 'folded-into-earlier-step' });
4300
+ continue;
4301
+ }
4302
+ seen.add(name);
4303
+ consider(step, provider);
4304
+ }
4264
4305
  if (permitsAutomaticProviderFallback(opts)) {
4265
4306
  const chainGoverned = new Set(providerNamesFromFallbackChain(['codex-rotate', 'grok']));
4266
- const ordered: LLMProvider[] = [
4267
- ...configuredFallbackProviders(),
4268
- ...automaticProviderCandidates().filter((candidate) => !chainGoverned.has(candidate.name)),
4269
- ];
4270
- const seen = new Set<string>();
4271
- return ordered
4272
- .filter((candidate) => {
4273
- if (seen.has(candidate.name)) return false;
4274
- seen.add(candidate.name);
4275
- return !attemptedProviders.has(candidate.name) && candidate.available();
4276
- })
4277
- .map((candidate) => candidate.name);
4278
- }
4279
- return configuredFallbackProviders()
4280
- .filter((candidate) => !attemptedProviders.has(candidate.name) && candidate.available())
4281
- .map((candidate) => candidate.name);
4307
+ for (const candidate of automaticProviderCandidates()) {
4308
+ if (chainGoverned.has(candidate.name) || seen.has(candidate.name)) continue;
4309
+ seen.add(candidate.name);
4310
+ consider(`auto:${candidate.name}`, candidate);
4311
+ }
4312
+ }
4313
+ return { candidates, skipped };
4314
+ }
4315
+
4316
+ function remainingFallbackProviderNames(
4317
+ attemptedProviders: ReadonlySet<string>,
4318
+ opts: LLMOpts & { provider?: LLMProvider },
4319
+ ): string[] {
4320
+ return explainFallbackCandidates(attemptedProviders, opts).candidates;
4321
+ }
4322
+
4323
+ /** 폴백 후보를 고르는 «그 순간»에 빠진 칸과 이유를 남긴다 — `provider-fallback-exhausted` 가
4324
+ * 「무엇을 봤고 왜 아무도 안 남았나」를 혼자 말하지 못하던 결손(2026-10-14 TUI 실측) 수리. */
4325
+ function explainAndLogFallbackCandidates(
4326
+ attemptedProviders: ReadonlySet<string>,
4327
+ opts: LLMOpts & { provider?: LLMProvider },
4328
+ context: { failedProvider: string; turn?: number },
4329
+ chain?: readonly string[],
4330
+ ): string[] {
4331
+ const { candidates, skipped } = explainFallbackCandidates(attemptedProviders, opts, chain);
4332
+ debug.log('llm.router', 'fallback-candidates', {
4333
+ ...(context.turn !== undefined ? { turn: context.turn } : {}),
4334
+ failedProvider: context.failedProvider,
4335
+ candidates,
4336
+ skipped,
4337
+ });
4338
+ return candidates;
4339
+ }
4340
+
4341
+ /** 스트림 중 끊김 재시도 상한 — codex `DEFAULT_STREAM_MAX_RETRIES`(5) 와 같은 값. */
4342
+ const STREAM_DISCONNECT_MAX_RETRIES = 5;
4343
+ let streamDisconnectRetryDelayMs: (attempt: number) => number = backoffMs;
4344
+
4345
+ /** @internal 시험 seam — 재시도 대기(기본 `backoffMs`)를 바꾼다. `undefined` 면 원복. */
4346
+ export function _setStreamDisconnectRetryDelayForTest(fn: ((attempt: number) => number) | undefined): void {
4347
+ streamDisconnectRetryDelayMs = fn ?? backoffMs;
4348
+ }
4349
+
4350
+ /** 흐르던 스트림의 끊김을 같은 공급자로 다시 걸어도 되나.
4351
+ * ⛔ 이 스트림에서 tool_call 을 받았거나 image 를 이미 내보냈으면 아니다 — 그 조각을 다시 보내면
4352
+ * 부작용·화면이 두 번 생길 수 있다(실행 전이라도 «추측해서» 버리지 않는다). */
4353
+ function isStreamDisconnectRetryable(err: unknown, pendingCallCount: number, emittedImage: boolean): boolean {
4354
+ if (pendingCallCount > 0 || emittedImage) return false;
4355
+ if (err instanceof OverloadFailoverError) return false;
4356
+ return classifyError(err) === 'network-transient';
4357
+ }
4358
+
4359
+ function sleepUnlessAborted(ms: number, signal?: AbortSignal): Promise<void> {
4360
+ if (ms <= 0 || signal?.aborted) return Promise.resolve();
4361
+ return new Promise((resolve) => {
4362
+ const onAbort = () => { clearTimeout(timer); resolve(); };
4363
+ const timer = setTimeout(() => { signal?.removeEventListener('abort', onAbort); resolve(); }, ms);
4364
+ signal?.addEventListener('abort', onAbort, { once: true });
4365
+ });
4282
4366
  }
4283
4367
 
4284
4368
  /** @internal 시험 seam — auto 폴백 순서(체인 먼저 · 체인이 안 다루는 자동 후보 뒤)를 결정적으로 누른다. */
@@ -4286,6 +4370,14 @@ export function _remainingFallbackProviderNamesForTest(attempted: readonly strin
4286
4370
  return remainingFallbackProviderNames(new Set(attempted), {});
4287
4371
  }
4288
4372
 
4373
+ /** @internal 시험 seam — 체인 칸별 skip 이유 ⊕ `llm.router fallback-candidates` 관측. */
4374
+ export function _explainAndLogFallbackCandidatesForTest(
4375
+ attempted: readonly string[],
4376
+ chain: readonly string[],
4377
+ ): string[] {
4378
+ return explainAndLogFallbackCandidates(new Set(attempted), {}, { failedProvider: attempted[0] ?? 'none' }, chain);
4379
+ }
4380
+
4289
4381
  function terminalFallbackVerdict(
4290
4382
  verdict: ReturnType<typeof decideProviderFallback>,
4291
4383
  attempts: readonly ProviderFallbackAttempt[],
@@ -4388,6 +4480,9 @@ export function getProvider(model?: string): LLMProvider {
4388
4480
  }
4389
4481
  if (PROVIDERS.openrouter!.available()) return PROVIDERS.openrouter!;
4390
4482
 
4483
+ // Gate Pod may intentionally have no credentials. The explicit test env
4484
+ // supplies a deterministic answer only after every real auto candidate failed.
4485
+ if (testFakeLlmEnabled()) return testFakeLlmProvider;
4391
4486
  throw new NoLlmProviderAvailableError();
4392
4487
  }
4393
4488
 
@@ -4725,7 +4820,7 @@ export async function streamLLM(
4725
4820
  debug.log('llm', 'outcome', { provider: activeProvider.name, status: 'error', kind: 'streamLLM', durationMs: Date.now() - started });
4726
4821
  throw err;
4727
4822
  }
4728
- const remaining = remainingFallbackProviderNames(attemptedProviders, opts);
4823
+ const remaining = explainAndLogFallbackCandidates(attemptedProviders, opts, { failedProvider: activeProvider.name });
4729
4824
  const verdict = decideProviderFallback({
4730
4825
  err,
4731
4826
  failedProvider: activeProvider.name,
@@ -4889,6 +4984,11 @@ export interface StreamWithToolsHandlers {
4889
4984
  turnIndex?: number;
4890
4985
  },
4891
4986
  ): Promise<unknown>;
4987
+ /** Optional: the final answer was enriched with a runtime verification
4988
+ * supplement (변경 파일·검증 명령·검증 최신성·루프 마감 상태). Fires just
4989
+ * before the `onText('', enriched)` re-emit so presentation hosts can
4990
+ * keep the user answer to `answer` and send `supplement` to logs. */
4991
+ onFinalAnswerSupplement?(info: { answer: string; supplement: string; finalText: string }): void;
4892
4992
  /** Optional: notify when a tool_call is about to fire (for log line,
4893
4993
  * HUD segment, etc). */
4894
4994
  onToolCall?(call: { id: string; name: string; args: Record<string, unknown> }): void;
@@ -8048,6 +8148,8 @@ export function billingRouteForProvider(provider: string | undefined, model: str
8048
8148
  if (name === 'local') return 'local';
8049
8149
  try {
8050
8150
  const auth = authKindForProvider(name, model);
8151
+ // CREDIT-BILLING-LABEL(10-14) — codex 회전이 크레딧 소진을 정한 호출은 구독이 아니라 크레딧이다.
8152
+ if (auth === 'oauth' && name === 'openai-codex' && codexCreditSpendReason()) return 'credit';
8051
8153
  return auth === 'oauth' ? 'subscription' : auth === 'local' ? 'local' : auth === 'apikey' ? 'api' : 'unknown';
8052
8154
  } catch {
8053
8155
  return 'unknown';
@@ -8087,6 +8189,7 @@ export async function streamLLMWithTools(
8087
8189
  const initial = finalizeStreamingProviderModel(provider, opts.model ?? provider.defaultModel);
8088
8190
  let activeProvider = initial.provider;
8089
8191
  let activeModel = initial.model;
8192
+ opts.onResolvedProvider?.(activeProvider.name, activeModel);
8090
8193
  const attemptedProviders = new Set<string>([activeProvider.name]);
8091
8194
  let blockedProviders: ProviderFallbackAttempt[] = [];
8092
8195
  const effectiveModel = activeModel;
@@ -8588,6 +8691,32 @@ export async function streamLLMWithTools(
8588
8691
  });
8589
8692
  let evCount = 0;
8590
8693
  let lastEvType = 'none';
8694
+ // ⭐ TUI-STREAM-RETRY(2026-10-14 실측) — 200 OK 로 흐르던 스트림이 소켓 끊김으로 죽으면 같은 공급자로
8695
+ // 다시 건다(codex `stream_max_retries` 동형). 이 턴에서 받은 tool_call·image 가 있으면 재시도하지 않는다.
8696
+ let streamDisconnectRetries = 0;
8697
+ let streamEmittedImage = false;
8698
+ // 끊긴 조각을 이력(turnText·fullText)에서 «조용히» 되감는다 — 화면엔 지우라고 알리지 않는다
8699
+ // (TUI 의 빈 델타는 «커밋»이다). 이미 보인 글과 겹치는 재시도 본문은 `retryDisplay` 가 막는다.
8700
+ const retryDisplay = createRetryDisplayGate();
8701
+ const emitRetryDisplayStep = (step: RetryDisplayStep) => {
8702
+ if (step.kind === 'emit') {
8703
+ if (step.delta) handlers.onText(step.delta, fullText);
8704
+ } else if (step.kind === 'diverged') {
8705
+ debug.log('llm.retry', 'stream-retry-display-diverged', { provider: activeProvider.name, turn, textChars: step.text.length }, { level: 'warn' });
8706
+ handlers.onText('', '');
8707
+ if (step.text) handlers.onText(step.text, fullText);
8708
+ }
8709
+ };
8710
+ const rewindDisconnectedStream = () => {
8711
+ if (turnText.length > 0) {
8712
+ fullText = fullText.slice(0, fullText.length - turnText.length);
8713
+ turnText = '';
8714
+ }
8715
+ retryDisplay.arm();
8716
+ turnReasoningDetails = undefined;
8717
+ evCount = 0;
8718
+ lastEvType = 'none';
8719
+ };
8591
8720
  // ⚠️ idle watchdog(2026-07-17) — codex SSE 가 완료 신호 없이 hang 하는 간헐 케이스 방어. 각
8592
8721
  // 이벤트 대기를 idle timeout 과 race — STREAM_IDLE_TIMEOUT_MS 무이벤트면 스트림 정리·탈출(받은
8593
8722
  // 텍스트로 진행). 35분 무한 hang → 자동 복구. 원인 규명은 consume-end 부재/idle-timeout 로그가.
@@ -8600,6 +8729,7 @@ export async function streamLLMWithTools(
8600
8729
  const finalized = finalizeStreamingProviderModel(activeProvider, activeModel);
8601
8730
  activeProvider = finalized.provider;
8602
8731
  activeModel = finalized.model;
8732
+ opts.onResolvedProvider?.(activeProvider.name, activeModel);
8603
8733
  turnOpts = { ...turnOpts, model: activeModel };
8604
8734
  streamIter = activeProvider.streamChat!(history, turnOpts)[Symbol.asyncIterator]();
8605
8735
  }
@@ -8624,16 +8754,49 @@ export async function streamLLMWithTools(
8624
8754
  activeProvider = finalized.provider;
8625
8755
  activeModel = finalized.model;
8626
8756
  attemptedProviders.add(activeProvider.name);
8757
+ streamDisconnectRetries = 0;
8627
8758
  turnOpts = buildTurnOpts();
8628
8759
  streamIter = undefined;
8629
8760
  continue;
8630
8761
  }
8631
8762
  }
8763
+ if (evCount > 0 && isStreamDisconnectRetryable(err, pendingCalls.length, streamEmittedImage) && !opts.signal?.aborted) {
8764
+ const retryData = {
8765
+ provider: activeProvider.name,
8766
+ model: activeModel,
8767
+ turn,
8768
+ scope: 'stream-disconnect',
8769
+ category: 'network-transient',
8770
+ reason: sanitizeProviderFailureReason(err instanceof Error ? err.message : String(err)),
8771
+ evCount,
8772
+ lastEvType,
8773
+ rewoundTextChars: turnText.length,
8774
+ maxRetries: STREAM_DISCONNECT_MAX_RETRIES,
8775
+ };
8776
+ if (streamDisconnectRetries < STREAM_DISCONNECT_MAX_RETRIES) {
8777
+ const delayMs = streamDisconnectRetryDelayMs(streamDisconnectRetries);
8778
+ streamDisconnectRetries++;
8779
+ debug.log('llm.retry', 'retry', { ...retryData, attempt: streamDisconnectRetries, delayMs }, { level: 'warn' });
8780
+ rewindDisconnectedStream();
8781
+ await sleepUnlessAborted(delayMs, opts.signal);
8782
+ if (opts.signal?.aborted) throw err;
8783
+ streamIter = undefined;
8784
+ continue;
8785
+ }
8786
+ debug.log('llm.retry', 'max-attempts-exhausted', { ...retryData, attempt: streamDisconnectRetries }, { level: 'warn' });
8787
+ // 되감았으니 이 턴은 «출력 전» 상태다 — 아래 폴백이 다음 공급자로 깨끗이 넘어갈 수 있다.
8788
+ rewindDisconnectedStream();
8789
+ }
8632
8790
  // 명시 provider 선택만 폴백 대상이 아니다 — `streamLLM` 과 같은 계약으로
8633
8791
  // «원본 오류»를 그대로 올린다. 모델만 전달된 호출은 다음 provider의 기본 모델로 재시도한다.
8634
8792
  if (opts.provider) throw err;
8793
+ if (evCount > 0) {
8794
+ debug.log('llm.router', 'fallback-candidates', {
8795
+ turn, failedProvider: activeProvider.name, candidates: [], skipped: [], outputEmitted: true, evCount, pendingCalls: pendingCalls.length,
8796
+ });
8797
+ }
8635
8798
  const remaining = evCount === 0
8636
- ? remainingFallbackProviderNames(attemptedProviders, opts)
8799
+ ? explainAndLogFallbackCandidates(attemptedProviders, opts, { failedProvider: activeProvider.name, turn })
8637
8800
  : [];
8638
8801
  const verdict = decideProviderFallback({
8639
8802
  err,
@@ -8670,6 +8833,8 @@ export async function streamLLMWithTools(
8670
8833
  activeProvider = finalized.provider;
8671
8834
  activeModel = finalized.model;
8672
8835
  attemptedProviders.add(activeProvider.name);
8836
+ // 재시도 상한은 «공급자마다» — 넘어간 공급자도 스트림 도중 끊김이면 다시 5회까지 건다.
8837
+ streamDisconnectRetries = 0;
8673
8838
  turnOpts = buildTurnOpts();
8674
8839
  streamIter = undefined;
8675
8840
  continue;
@@ -8687,7 +8852,7 @@ export async function streamLLMWithTools(
8687
8852
  if (ev.type === 'text') {
8688
8853
  turnText += ev.delta;
8689
8854
  fullText += ev.delta;
8690
- handlers.onText(ev.delta, fullText);
8855
+ emitRetryDisplayStep(retryDisplay.onText(ev.delta, turnText));
8691
8856
  } else if (ev.type === 'reasoning_details') {
8692
8857
  turnReasoningDetails = ev.details;
8693
8858
  } else if (ev.type === 'tool_call') {
@@ -8724,6 +8889,7 @@ export async function streamLLMWithTools(
8724
8889
  });
8725
8890
  }
8726
8891
  } else if (ev.type === 'image') {
8892
+ streamEmittedImage = true;
8727
8893
  // Y2·1 (2026-05-17) — forward Codex server-tool image result.
8728
8894
  // Only fires when caller opted into opts.serverTools.imageGeneration
8729
8895
  // and the model invoked the built-in tool. No-op when handler
@@ -8780,6 +8946,7 @@ export async function streamLLMWithTools(
8780
8946
  }
8781
8947
 
8782
8948
  // hang 진단 — for-await(SSE 스트림) 정상 종료 확정. 이 로그가 없으면 codex SSE 스트림 hang.
8949
+ emitRetryDisplayStep(retryDisplay.settle(turnText));
8783
8950
  debug.log('llm.stream', 'consume-end', { turn, evCount, lastEvType, textChars: turnText.length, pendingCalls: pendingCalls.length });
8784
8951
  const turnInfo = {
8785
8952
  turn,
@@ -8826,6 +8993,10 @@ export async function streamLLMWithTools(
8826
8993
  verificationLoopState,
8827
8994
  finalization,
8828
8995
  );
8996
+ if (finalText !== visibleText) {
8997
+ const answer = visibleText.trim();
8998
+ handlers.onFinalAnswerSupplement?.({ answer, supplement: finalText.slice(answer.length).trim(), finalText });
8999
+ }
8829
9000
  if (finalText !== fullText) handlers.onText('', finalText);
8830
9001
  emitTurnComplete(finalText);
8831
9002
  return finalText;
@@ -9488,32 +9659,55 @@ export async function streamLLMWithTools(
9488
9659
  | { kind: 'absent' }
9489
9660
  | { kind: 'complete'; label: string }
9490
9661
  | { kind: 'truncated'; label: string };
9491
- const anchorFileState = (systemMessages: LLMMessage[], filename: string): AnchorFileState => {
9492
- const escapedFilename = filename.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
9493
- const opening = new RegExp(`^=== (.+) \\(${escapedFilename}(?: @ [^)]+)?\\) ===$`, 'm');
9494
- const closing = new RegExp(`^=== end ${escapedFilename}(?: @ .+)? ===$`, 'm');
9662
+ const anchorFileState = (systemMessages: LLMMessage[], filename: string, filePath?: string): AnchorFileState => {
9663
+ const opening = /^=== (.+) \(([^()]+?)(?: @ ([^)]+))?\) ===$/gm;
9495
9664
  for (const message of systemMessages) {
9496
9665
  if (message.role !== 'system' || typeof message.content !== 'string') continue;
9497
- const openingMatch = opening.exec(message.content);
9498
- if (openingMatch === null || !closing.test(message.content.slice(openingMatch.index))) continue;
9499
- const contentStart = openingMatch.index + openingMatch[0].length;
9500
- const closingMatch = closing.exec(message.content.slice(contentStart));
9501
- const content = message.content.slice(contentStart, contentStart + (closingMatch?.index ?? 0));
9502
- return content.includes('…[truncated to fit anchor budget]')
9503
- ? { kind: 'truncated', label: openingMatch[1] }
9504
- : { kind: 'complete', label: openingMatch[1] };
9666
+ for (const openingMatch of message.content.matchAll(opening)) {
9667
+ const fencedPath = openingMatch[2]!;
9668
+ const scope = openingMatch[3];
9669
+ if (fencedPath.split('/').pop() !== filename) continue;
9670
+ // The actual project-anchor fence names a filename + its
9671
+ // directory relative to this turn's cwd. Keep the full path
9672
+ // when one is supplied explicitly, never just its basename.
9673
+ const anchorPath = scope === 'instance root'
9674
+ ? globalAnchorPath()
9675
+ : resolve(scope ?? '.', fencedPath);
9676
+ if (filePath !== undefined) {
9677
+ // macOS may spell the same /var path as /private/var in cwd;
9678
+ // Read accepts either. Canonicalize both real files so a
9679
+ // symlink spelling cannot turn a loaded anchor into a miss.
9680
+ const samePath = (path: string): string => {
9681
+ try { return realpathSync(path); } catch { return resolve(path); }
9682
+ };
9683
+ if (!anchorPath || samePath(anchorPath) !== samePath(filePath)) continue;
9684
+ }
9685
+ const contentStart = openingMatch.index + openingMatch[0].length;
9686
+ const escapedPath = fencedPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
9687
+ const escapedScope = scope?.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
9688
+ // Current fences close with their scope. Accept a legacy
9689
+ // scopeless closing fence as well, but never another scope.
9690
+ const closing = new RegExp(`^=== end ${escapedPath}${escapedScope ? `(?: @ ${escapedScope})?` : ''} ===$`, 'm');
9691
+ const closingMatch = closing.exec(message.content.slice(contentStart));
9692
+ if (closingMatch === null) continue;
9693
+ const content = message.content.slice(contentStart, contentStart + closingMatch.index);
9694
+ return content.includes('…[truncated to fit anchor budget]')
9695
+ ? { kind: 'truncated', label: openingMatch[1] }
9696
+ : { kind: 'complete', label: openingMatch[1] };
9697
+ }
9505
9698
  }
9506
9699
  return { kind: 'absent' };
9507
9700
  };
9508
- const anchorStubContext = (filename: string): string => {
9509
- const state = anchorFileState(messages, filename);
9701
+ const anchorStubContext = (filename: string, filePath?: string): string => {
9702
+ const state = anchorFileState(messages, filename, filePath);
9703
+ const namedPath = filePath ?? filename;
9510
9704
  if (state.kind === 'absent') {
9511
- return `\`${filename}\` is not present in the system prompt.`;
9705
+ return `\`${namedPath}\` is not present in the system prompt.`;
9512
9706
  }
9513
9707
  if (state.kind === 'truncated') {
9514
- return `Only a prefix of \`${filename}\` is present in the system prompt under the \`${state.label}\` anchor; the remainder is unavailable.`;
9708
+ return `Only a prefix of \`${namedPath}\` is present in the system prompt under the \`${state.label}\` anchor; the remainder is unavailable.`;
9515
9709
  }
9516
- return `The full text of \`${filename}\` is present in the system prompt under the \`${state.label}\` anchor.`;
9710
+ return `The full text of \`${namedPath}\` is present in the system prompt under the \`${state.label}\` anchor.`;
9517
9711
  };
9518
9712
  // W4-anchor (2026-05-03 PM) — Scope: codex family only. Glob anchor detection is permissive:
9519
9713
  // contains 'AGENTS' or 'CLAUDE' AND contains '.md'. This catches
@@ -9575,11 +9769,10 @@ export async function streamLLMWithTools(
9575
9769
  // instead. A guardian test keeps the repo's own candidates under
9576
9770
  // the cap — see test/prompt-library-universal-preamble.test.ts.
9577
9771
  //
9578
- // Match: file_path's basename equals AGENTS.md or CLAUDE.md
9579
- // (case-sensitive). Catches `AGENTS.md`, `./AGENTS.md`,
9580
- // `/abs/path/AGENTS.md`, `subdir/CLAUDE.md`, etc. Other
9581
- // AGENTS-prefixed files (`AGENTS-helper.md`) are NOT blocked
9582
- // since basename match is strict.
9772
+ // Match only a file whose resolved path corresponds to a complete or
9773
+ // truncated fence in this turn's system prompt. A same-named file in
9774
+ // another directory (or a policy-excluded CLAUDE.md) must remain
9775
+ // readable; a filename alone is not evidence that it was loaded.
9583
9776
  const isAnchorRead = (
9584
9777
  call: { name: string; args: Record<string, unknown> },
9585
9778
  ): { filePath: string } | null => {
@@ -9587,7 +9780,8 @@ export async function streamLLMWithTools(
9587
9780
  const filePath = typeof call.args.file_path === 'string' ? call.args.file_path : '';
9588
9781
  if (filePath.length === 0) return null;
9589
9782
  const basename = filePath.split('/').pop() ?? '';
9590
- if (basename === 'AGENTS.md' || basename === 'CLAUDE.md') {
9783
+ if ((basename === 'AGENTS.md' || basename === 'CLAUDE.md')
9784
+ && anchorFileState(messages, basename, filePath).kind !== 'absent') {
9591
9785
  return { filePath };
9592
9786
  }
9593
9787
  return null;
@@ -9916,7 +10110,7 @@ export async function streamLLMWithTools(
9916
10110
  const filename = anchorRead.filePath.split('/').pop() ?? anchorRead.filePath;
9917
10111
  const stub =
9918
10112
  `ANCHOR READ BLOCKED — \`${anchorRead.filePath}\` matches an anchor-file read. ` +
9919
- `${anchorStubContext(filename)} Move to a source file (e.g. \`src/...\`) for on-disk investigation.`;
10113
+ `${anchorStubContext(filename, anchorRead.filePath)} Move to a source file (e.g. \`src/...\`) for on-disk investigation.`;
9920
10114
  return { result: stub, isError: false, phaseRejected: false };
9921
10115
  }
9922
10116
  // W5-A — Literal-path Glob redirect. Codex uses Glob({pattern:
@@ -10897,6 +11091,7 @@ export async function streamLLMWithTools(
10897
11091
  import type { LLMConfig as UCLLMConfig, UserConfig } from './user-config.js';
10898
11092
  import { loadTokens, readCodexMirrorTokens } from './oauth/store.js';
10899
11093
  import { resolveCodexAccount, effectiveCodexHome } from './oauth/codex-account.js';
11094
+ import { codexCreditSpendReason } from './oauth/codex-billing-route.js';
10900
11095
  import { join } from 'node:path';
10901
11096
  import {
10902
11097
  CODEX_API_BASE_URL, getCodexUserAgent, loadFreshCodexAuthState,
@@ -11620,7 +11815,10 @@ export function getProviderForConfig(
11620
11815
  ? decision.provider.slice('auto:'.length)
11621
11816
  : decision.provider;
11622
11817
  if (provider === 'auto') {
11623
- if (resolvedProviderName === 'auto') throw new NoLlmProviderAvailableError();
11818
+ if (resolvedProviderName === 'auto') {
11819
+ if (testFakeLlmEnabled()) return testFakeLlmProvider;
11820
+ throw new NoLlmProviderAvailableError();
11821
+ }
11624
11822
  if (!isKnownProviderName(resolvedProviderName)) {
11625
11823
  throw new Error(`unknown provider: ${resolvedProviderName}`);
11626
11824
  }
package/src/log-entry.ts CHANGED
@@ -26,7 +26,7 @@
26
26
  // data model. Fold/expand (Phase F4) will need a typed pane later; for
27
27
  // now the strings carry ANSI styling only.
28
28
 
29
- import { FIGURES } from './render.js';
29
+ import { FIGURES, singleLineToolHeaderText } from './render.js';
30
30
  import { C } from './tui.js';
31
31
  import { agentColor } from './agent/color-map.js';
32
32
  import { debug } from './debug/log.js';
@@ -357,7 +357,7 @@ export function summarizeToolCall(
357
357
  : '';
358
358
  const cwd = args.cwd ? ` cwd=${args.cwd}` : '';
359
359
  const mode = args.mode ? ` mode=${args.mode}` : '';
360
- return `${command || '(empty command)'}${cwd}${mode}`;
360
+ return singleLineToolHeaderText(`${command || '(empty command)'}${cwd}${mode}`);
361
361
  }
362
362
  case 'GetDashboardState': {
363
363
  return 'current dashboard snapshot';
@@ -391,7 +391,7 @@ export function renderLogEntry(
391
391
  return [(entry.color ?? C.peach)(entry.label)];
392
392
 
393
393
  case 'tool-header': {
394
- const head = `${C.peach(G.CIRCLE)} ${C.bold(entry.toolName)}(${C.subtext(truncate(entry.summary, width - entry.toolName.length - 4))})`;
394
+ const head = `${C.peach(G.CIRCLE)} ${C.bold(entry.toolName)}(${C.subtext(truncate(singleLineToolHeaderText(entry.summary), width - entry.toolName.length - 4))})`;
395
395
  return [head];
396
396
  }
397
397
 
@@ -10,6 +10,8 @@ import { stripAnsi } from '../tui.js';
10
10
  export interface LogSearchResult {
11
11
  /** Absolute chatLines index where the match was found. */
12
12
  readonly lineIdx: number;
13
+ /** Physical row inside that entry where its first match begins. */
14
+ readonly physicalRowInEntry?: number;
13
15
  /** Stripped-ANSI context window around the match (~80 cols). Leading
14
16
  * `…` when we trimmed the start; trailing `…` when we trimmed the
15
17
  * end, so users see exactly what section of the line matched. */
@@ -26,25 +28,48 @@ export interface LogSearchResult {
26
28
  * same line are folded into the first occurrence (power users can
27
29
  * refine the query if they need multi-per-line hits). */
28
30
  export function findLogMatches(lines: readonly string[], query: string): LogSearchResult[] {
31
+ return scanLogMatches(lines, query, '');
32
+ }
33
+
34
+ export function findVisibleLogMatches(lines: readonly string[], query: string, filterQuery: string): LogSearchResult[] {
35
+ return scanLogMatches(lines, query, filterQuery);
36
+ }
37
+
38
+ function scanLogMatches(lines: readonly string[], query: string, filterQuery: string): LogSearchResult[] {
29
39
  const q = query.trim();
30
40
  if (!q) return [];
31
41
  const qLower = q.toLowerCase();
42
+ const filter = filterQuery.trim().toLowerCase();
32
43
  const results: LogSearchResult[] = [];
33
44
  for (let i = 0; i < lines.length; i++) {
34
45
  const stripped = stripAnsi(lines[i] ?? '');
35
- const idx = stripped.toLowerCase().indexOf(qLower);
46
+ let source = '';
47
+ let idx = -1;
48
+ let physicalRowInEntry = 0;
49
+ const rows = stripped.split(/\r\n|\r|\n/);
50
+ for (let row = 0; row < rows.length; row++) {
51
+ const candidate = rows[row]!;
52
+ if (filter && !candidate.toLowerCase().includes(filter)) continue;
53
+ const match = candidate.toLowerCase().indexOf(qLower);
54
+ if (match < 0) continue;
55
+ source = candidate;
56
+ idx = match;
57
+ physicalRowInEntry = row;
58
+ break;
59
+ }
36
60
  if (idx < 0) continue;
37
61
  const ctxLead = 20; // chars before the match in the preview
38
62
  const ctxTail = 60; // chars after the match end in the preview
39
63
  const srcStart = Math.max(0, idx - ctxLead);
40
- const srcEnd = Math.min(stripped.length, idx + q.length + ctxTail);
64
+ const srcEnd = Math.min(source.length, idx + q.length + ctxTail);
41
65
  const trimmedLeft = srcStart > 0;
42
- const trimmedRight = srcEnd < stripped.length;
43
- const slice = stripped.slice(srcStart, srcEnd);
66
+ const trimmedRight = srcEnd < source.length;
67
+ const slice = source.slice(srcStart, srcEnd);
44
68
  const preview = (trimmedLeft ? '…' : '') + slice + (trimmedRight ? '…' : '');
45
69
  const offsetInPreview = (trimmedLeft ? 1 : 0) + (idx - srcStart);
46
70
  results.push({
47
71
  lineIdx: i,
72
+ physicalRowInEntry,
48
73
  preview,
49
74
  matchStart: offsetInPreview,
50
75
  matchEnd: offsetInPreview + q.length,