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
@@ -9,13 +9,16 @@ import { join } from 'node:path';
9
9
  import type { Command } from 'commander';
10
10
  import { collectUnifiedUsage, formatUnifiedUsage } from '../budget/unified-usage.js';
11
11
  import { consumeCodexResetCredits, listCodexResetCredits } from '../budget/codex-reset-credits.js';
12
- import { rollupRunUsage, type RunUsageInput } from '../budget/run-usage-rollup.js';
12
+ import { excludeCoveredPodRawRows, rollupRunUsage, type RunUsageInput } from '../budget/run-usage-rollup.js';
13
13
  import { dedupePodRollupRows } from '../../scripts/usage-rollup.js';
14
14
  import { formatUsageOutcomes, outcomeTableHasCodexGrokUnknown, queryUsageOutcomes, type UsageOutcomesDeps, type UsageOutcomesReport } from '../budget/usage-outcomes.js';
15
15
  import { LogStore, logsDbPath, type LogQuery, type LogStoreRow } from '../mss/logging/log-store.js';
16
16
  import { LOGS_SINCE_OPTION, parseSince } from './logs-cli.js';
17
17
  import { formatCodexCreditPlan, type CodexCreditPlan } from '../budget/codex-credit-plan.js';
18
18
  import { codexCreditPlanFromDisk } from './codex-credit-plan-view.js';
19
+ import { getUserConfig } from '../user-config.js';
20
+ import { defaultSshRunner, type SshRunner } from '../task-agent/parent-host.js';
21
+ import { shellQuote } from '../task-agent/task-hand.js';
19
22
 
20
23
  export interface UsageCliDeps {
21
24
  readonly collect?: typeof collectUnifiedUsage;
@@ -24,6 +27,9 @@ export interface UsageCliDeps {
24
27
  readonly out?: { log: (s: string) => void };
25
28
  /** Read-only LogStore query seam; returns stored llm-usage rows, newest first. */
26
29
  readonly readRunLogs?: (query: LogQuery) => LogStoreRow[];
30
+ /** Federation seams: the configured TA parent hosts plus this HQ host, and bounded SSH. */
31
+ readonly usageHosts?: () => { local: string; remote: string[] };
32
+ readonly ssh?: SshRunner;
27
33
  /** 시험 심 — 실물 네트워크를 안 탄다. */
28
34
  readonly list?: typeof listCodexResetCredits;
29
35
  readonly consume?: typeof consumeCodexResetCredits;
@@ -61,8 +67,16 @@ function readRunLogs(query: LogQuery): LogStoreRow[] {
61
67
  }
62
68
  }
63
69
 
70
+ function configuredUsageHosts(): { local: string; remote: string[] } {
71
+ const config = getUserConfig();
72
+ const local = config.hq?.hostName?.trim() || '';
73
+ const parents = config.taskAgent?.parentHost;
74
+ const entries = Array.isArray(parents) ? parents : parents ? [parents] : [];
75
+ return { local, remote: [...new Set(entries.map((entry) => entry.host?.trim()).filter((host): host is string => !!host && host !== local))] };
76
+ }
77
+
64
78
  type UsageAxis = 'stage' | 'model' | 'account';
65
- type ExtendedRunUsageInput = RunUsageInput & { stage?: string | null; account?: string | null };
79
+ type ExtendedRunUsageInput = RunUsageInput & { stage?: string | null; account?: string | null; origin?: string; podJob?: string; job?: string; measured?: boolean };
66
80
  type AxisUsageRow = {
67
81
  stage?: string;
68
82
  model?: string;
@@ -82,15 +96,78 @@ type AxisUsageRow = {
82
96
  rankUsd: number;
83
97
  };
84
98
 
99
+ type FederatedUsageRow = {
100
+ runId?: string; role?: string; site?: string; stage?: string; model?: string; account?: string;
101
+ billingProvider?: string; billing?: string; hostIds: string[]; rankUsd?: number;
102
+ calls: number; inputTokens: number; outputTokens: number; cacheReadInputTokens: number;
103
+ cacheCreationInputTokens: number; reasoningOutputTokens: number; usdKnown: number;
104
+ unknownCostCalls: number; includedCalls: number; apiEquivalentUsd: number;
105
+ };
106
+ type HostMeasurement = { host: string; status: 'ok' | 'unmeasured'; reason?: string };
107
+ const SUM_FIELDS = ['calls', 'inputTokens', 'outputTokens', 'cacheReadInputTokens', 'cacheCreationInputTokens', 'reasoningOutputTokens', 'usdKnown', 'unknownCostCalls', 'includedCalls', 'apiEquivalentUsd'] as const;
108
+ const SSH_HOST = /^[A-Za-z0-9][A-Za-z0-9._@-]{0,127}$/;
109
+
110
+ function validUsageRows(value: unknown, axis: 'run' | 'role' | UsageAxis): value is FederatedUsageRow[] {
111
+ if (!Array.isArray(value)) return false;
112
+ const key = axis === 'run' ? 'runId' : axis;
113
+ return value.every((candidate) => {
114
+ if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) return false;
115
+ const row = candidate as Record<string, unknown>;
116
+ return typeof row[key] === 'string' && Array.isArray(row.hostIds)
117
+ && row.hostIds.every((host: unknown) => typeof host === 'string')
118
+ && (axis !== 'run' && axis !== 'role'
119
+ || ['model', 'billingProvider', 'billing', ...(axis === 'role' ? ['site'] : [])]
120
+ .every((field) => typeof row[field] === 'string'))
121
+ && SUM_FIELDS.every((field) => {
122
+ const number = row[field];
123
+ return typeof number === 'number' && Number.isFinite(number) && number >= 0;
124
+ })
125
+ && (axis !== 'stage' && axis !== 'model' && axis !== 'account'
126
+ || typeof row.rankUsd === 'number' && Number.isFinite(row.rankUsd));
127
+ });
128
+ }
129
+
130
+ function mergeUsageRows(groups: readonly FederatedUsageRow[][], axis: 'run' | 'role' | UsageAxis): FederatedUsageRow[] {
131
+ const merged = new Map<string, FederatedUsageRow>();
132
+ for (const rows of groups) for (const row of rows) {
133
+ const key = axis === 'run' ? JSON.stringify([row.runId, row.model, row.billingProvider, row.billing])
134
+ : axis === 'role' ? JSON.stringify([row.role, row.site, row.model, row.billingProvider, row.billing])
135
+ : JSON.stringify(row[axis]);
136
+ const previous = merged.get(key);
137
+ if (!previous) { merged.set(key, { ...row, hostIds: [...row.hostIds] }); continue; }
138
+ for (const field of SUM_FIELDS) previous[field] += row[field];
139
+ previous.hostIds = [...new Set([...previous.hostIds, ...row.hostIds])];
140
+ if (axis === 'stage' || axis === 'model' || axis === 'account') previous.rankUsd = previous.usdKnown + previous.apiEquivalentUsd;
141
+ }
142
+ return [...merged.values()];
143
+ }
144
+
145
+ function readRemoteUsage(host: string, axis: 'run' | 'role' | UsageAxis, opts: { run?: string; sinceMs?: number }, ssh: SshRunner): { rows?: FederatedUsageRow[]; reason?: string } {
146
+ if (!SSH_HOST.test(host)) return { reason: '호스트 이름 오류' };
147
+ const args = ['eln', '--config-dir', '"$HOME"/.elanous', 'usage', 'runs', '--by', shellQuote(axis), '--json'];
148
+ if (opts.run !== undefined) args.push('--run', shellQuote(opts.run));
149
+ if (opts.sinceMs !== undefined) args.push('--since', shellQuote(new Date(opts.sinceMs).toISOString()));
150
+ try {
151
+ // The local usage command returns [] when its store is absent. Check the
152
+ // same configured store first so federation cannot count absence as zero.
153
+ const result = ssh(host, 'test -f "$HOME"/.elanous/logs/logs.db || { echo usage-store-missing >&2; exit 68; }; ' + args.join(' '), 20_000);
154
+ if (result.status === 68 || result.stderr.includes('usage-store-missing')) return { reason: '원격 logs.db 없음' };
155
+ if (result.status !== 0) return { reason: result.status === null ? '시간 초과 또는 SSH 실패' : `SSH/원격 명령 rc=${result.status}` };
156
+ const parsed: unknown = JSON.parse(result.stdout);
157
+ return validUsageRows(parsed, axis) ? { rows: parsed } : { reason: '원격 JSON 형식 오류' };
158
+ } catch { return { reason: '원격 JSON 또는 SSH 실행 오류' }; }
159
+ }
160
+
85
161
  function usageData(row: LogStoreRow, unwrapPod = false): ExtendedRunUsageInput | null {
86
162
  if (row.category !== 'llm.usage' || row.event !== 'llm-usage' || !row.data) return null;
87
163
  try {
88
164
  let value: unknown = JSON.parse(row.data);
89
165
  if (!value || typeof value !== 'object' || Array.isArray(value)) return null;
90
- const wrapper = value as { origin?: unknown; originalData?: unknown };
91
- if (unwrapPod && wrapper.origin === 'pod') {
92
- value = typeof wrapper.originalData === 'string' ? JSON.parse(wrapper.originalData) : wrapper.originalData;
93
- if (!value || typeof value !== 'object' || Array.isArray(value)) return null;
166
+ const wrapper = value as { origin?: unknown; podJob?: unknown; originalData?: unknown };
167
+ if (unwrapPod && wrapper.origin === 'pod' && wrapper.originalData !== undefined) {
168
+ const original = typeof wrapper.originalData === 'string' ? JSON.parse(wrapper.originalData) : wrapper.originalData;
169
+ if (!original || typeof original !== 'object' || Array.isArray(original)) return null;
170
+ value = { ...original, origin: 'pod', podJob: wrapper.podJob };
94
171
  }
95
172
  return value as ExtendedRunUsageInput;
96
173
  } catch { return null; }
@@ -176,8 +253,9 @@ export function registerUsageCommand(program: Command, deps: UsageCliDeps = {}):
176
253
  .option('--run <runId>', '런 ID 정확 일치')
177
254
  .option('--by <axis>', '집계 축 (run | role | stage | model | account)', 'run')
178
255
  .option(...LOGS_SINCE_OPTION)
256
+ .option('--hosts <scope>', '호스트 연합 (all: 이 호스트 + 설정된 taskAgent.parentHost)')
179
257
  .option('--json', '집계 행 JSON 출력')
180
- .action((opts: { run?: string; by: string; since?: string; json?: boolean }, command: Command) => {
258
+ .action((opts: { run?: string; by: string; since?: string; hosts?: string; json?: boolean }, command: Command) => {
181
259
  const json = opts.json || command.optsWithGlobals<{ json?: boolean }>().json;
182
260
  if (!isUsageAxis(opts.by)) {
183
261
  out.log('⛔ --by 는 run | role | stage | model | account');
@@ -190,16 +268,71 @@ export function registerUsageCommand(program: Command, deps: UsageCliDeps = {}):
190
268
  exit(2);
191
269
  return;
192
270
  }
193
- const rows = (deps.readRunLogs ?? readRunLogs)({
194
- exactCategories: ['llm.usage'], events: ['llm-usage'],
195
- ...(sinceMs !== undefined ? { sinceMs } : {}),
196
- });
271
+ if (opts.hosts !== undefined && opts.hosts !== 'all') {
272
+ out.log(`⛔ --hosts 는 all 만 지원: '${opts.hosts}'`);
273
+ exit(2);
274
+ return;
275
+ }
276
+ const localUnavailable = opts.hosts === 'all' && !deps.readRunLogs && !existsSync(logsDbPath())
277
+ ? '로컬 logs.db 없음' : undefined;
278
+ const emitFederated = (localRows: FederatedUsageRow[], localFailure?: string): void => {
279
+ const roster = (deps.usageHosts ?? configuredUsageHosts)();
280
+ if (!roster.local) {
281
+ const reason = 'hq.hostName 설정 없음 — 로컬 호스트와 원격 중복 여부를 확인할 수 없음';
282
+ const hosts = [...new Set(roster.remote)].map((host) => ({ host, status: 'unmeasured' as const, reason: '로컬 식별 불가로 조회 중지' }));
283
+ if (json) out.log(JSON.stringify({ rows: [], hosts, complete: false, reason }, null, 2));
284
+ else out.log(`호스트 연합: 못 잼 (${reason})`);
285
+ return;
286
+ }
287
+ const hosts: HostMeasurement[] = [localFailure
288
+ ? { host: roster.local, status: 'unmeasured', reason: localFailure }
289
+ : { host: roster.local, status: 'ok' }];
290
+ const parts: FederatedUsageRow[][] = localFailure ? [] : [localRows];
291
+ const rosterReason = roster.remote.length === 0 ? 'taskAgent.parentHost 설정 없음' : undefined;
292
+ for (const host of [...new Set(roster.remote.filter((name) => name !== roster.local))]) {
293
+ const remote = readRemoteUsage(host, opts.by as 'run' | 'role' | UsageAxis,
294
+ { run: opts.run, sinceMs }, deps.ssh ?? defaultSshRunner);
295
+ if (remote.rows) { hosts.push({ host, status: 'ok' }); parts.push(remote.rows); }
296
+ else hosts.push({ host, status: 'unmeasured', reason: remote.reason ?? '원인 미상' });
297
+ }
298
+ const complete = !rosterReason && hosts.every((host) => host.status === 'ok');
299
+ const rows = mergeUsageRows(parts, opts.by as 'run' | 'role' | UsageAxis);
300
+ if (opts.by === 'role') rows.sort((a, b) => b.calls - a.calls);
301
+ if (opts.by === 'stage' || opts.by === 'model' || opts.by === 'account') rows.sort((a, b) => (b.rankUsd ?? 0) - (a.rankUsd ?? 0) || b.calls - a.calls);
302
+ if (json) { out.log(JSON.stringify({ rows, hosts, complete, ...(rosterReason ? { reason: rosterReason } : {}) }, null, 2)); return; }
303
+ out.log(`호스트 ${hosts.filter((host) => host.status === 'ok').length}/${hosts.length} 측정 · ${complete ? '완결' : '부분 합계'}`);
304
+ if (rosterReason) out.log(`호스트 목록: 못 잼 (${rosterReason})`);
305
+ for (const host of hosts) if (host.status === 'unmeasured') out.log(`${host.host}: 못 잼 (${host.reason})`);
306
+ if (rows.length === 0) { out.log('(일치하는 런 사용량 없음)'); return; }
307
+ for (const row of rows) {
308
+ if (opts.by === 'stage' || opts.by === 'model' || opts.by === 'account') out.log(formatAxisUsage(row as AxisUsageRow, opts.by));
309
+ else if (opts.by === 'role') out.log(`${row.role} ${row.site} ${row.model} ${row.billingProvider}/${row.billing} calls=${row.calls} input=${row.inputTokens} output=${row.outputTokens} usdKnown=${row.usdKnown} unknownCostCalls=${row.unknownCostCalls} includedCalls=${row.includedCalls} apiEquivalentUsd=${row.apiEquivalentUsd}`);
310
+ else out.log(`${row.runId} ${row.model} ${row.billingProvider}/${row.billing} hosts=${row.hostIds.join(',') || '(none)'} calls=${row.calls} input=${row.inputTokens} output=${row.outputTokens} cacheRead=${row.cacheReadInputTokens} cacheCreation=${row.cacheCreationInputTokens} reasoning=${row.reasoningOutputTokens} usdKnown=${row.usdKnown} unknownCostCalls=${row.unknownCostCalls} includedCalls=${row.includedCalls} apiEquivalentUsd=${row.apiEquivalentUsd}`);
311
+ }
312
+ };
313
+ let rows: LogStoreRow[] = [];
314
+ let localFailure = localUnavailable;
315
+ if (!localFailure) {
316
+ try {
317
+ rows = (deps.readRunLogs ?? readRunLogs)({
318
+ exactCategories: ['llm.usage'], events: ['llm-usage'],
319
+ ...(sinceMs !== undefined ? { sinceMs } : {}),
320
+ });
321
+ } catch (error) {
322
+ if (opts.hosts !== 'all') throw error;
323
+ localFailure = '로컬 logs.db 조회 실패';
324
+ }
325
+ }
197
326
  const unwrapPod = opts.by === 'stage' || opts.by === 'model' || opts.by === 'account';
198
327
  // ⭐ METER-POD-ROLLUP-GAP-2 — Pod 사용량 재방출 행(podRollupKey)은 «더 완전한 한 행»만 센다(키 없는 행은 그대로).
199
- const inputs = dedupePodRollupRows(rows.map((row) => usageData(row, unwrapPod)).filter((data): data is ExtendedRunUsageInput => data !== null))
328
+ const selected = rows.map((row) => usageData(row, unwrapPod))
329
+ .filter((data): data is ExtendedRunUsageInput => data !== null)
200
330
  .filter((data) => opts.run === undefined || data.runId === opts.run);
331
+ // A returned Pod raw row and its host rollup describe the same usage. Keep raw rows when no measured rollup exists.
332
+ const inputs = dedupePodRollupRows(unwrapPod ? excludeCoveredPodRawRows(selected) : selected);
201
333
  if (opts.by === 'stage' || opts.by === 'model' || opts.by === 'account') {
202
334
  const report = rollupByAxis(inputs, opts.by);
335
+ if (opts.hosts === 'all') { emitFederated(report, localFailure); return; }
203
336
  if (json) {
204
337
  out.log(JSON.stringify(report, null, 2));
205
338
  return;
@@ -209,6 +342,7 @@ export function registerUsageCommand(program: Command, deps: UsageCliDeps = {}):
209
342
  return;
210
343
  }
211
344
  const report = rollupRunUsage(inputs, { by: opts.by });
345
+ if (opts.hosts === 'all') { emitFederated(report, localFailure); return; }
212
346
  if (opts.by === 'role') report.sort((a, b) => b.calls - a.calls);
213
347
  if (json) {
214
348
  out.log(JSON.stringify(report, null, 2));
@@ -0,0 +1,84 @@
1
+ import type { Command } from 'commander';
2
+ import { logsDbPath } from '../mss/logging/log-store.js';
3
+ import { readUsageDaily, type DailyUsageRow } from '../budget/usage-daily-store.js';
4
+
5
+ type Axis = 'day' | 'model' | 'role' | 'stage' | 'account';
6
+ const metricFields = ['calls', 'inputTokens', 'outputTokens', 'cacheReadInputTokens', 'cacheCreationInputTokens',
7
+ 'reasoningOutputTokens', 'usdKnown', 'unknownCostCalls', 'includedCalls', 'apiEquivalentUsd'] as const;
8
+ type Period = 'day' | 'hour';
9
+ type Summary = Pick<DailyUsageRow, typeof metricFields[number]> & { period: string; key: string };
10
+
11
+ export function summarizeDailyUsage(rows: readonly DailyUsageRow[], axis: Axis, period: Period = 'day'): Summary[] {
12
+ const groups = new Map<string, Summary>();
13
+ for (const row of rows) {
14
+ const bucket = row[period];
15
+ const key = axis === 'day' ? bucket : row[axis];
16
+ const id = JSON.stringify([bucket, key]);
17
+ let summary = groups.get(id);
18
+ if (!summary) {
19
+ summary = { period: bucket, key, calls: 0, inputTokens: 0, outputTokens: 0, cacheReadInputTokens: 0,
20
+ cacheCreationInputTokens: 0, reasoningOutputTokens: 0, usdKnown: 0, unknownCostCalls: 0,
21
+ includedCalls: 0, apiEquivalentUsd: 0 };
22
+ groups.set(id, summary);
23
+ }
24
+ for (const field of metricFields) summary[field] += row[field];
25
+ }
26
+ return [...groups.values()].sort((a, b) => a.period.localeCompare(b.period) || a.key.localeCompare(b.key));
27
+ }
28
+
29
+ export function registerUsageDailyCommand(program: Command, deps: {
30
+ path?: () => string; read?: typeof readUsageDaily;
31
+ out?: (line: string) => void; exit?: (code: number) => void;
32
+ } = {}): void {
33
+ const usage = program.commands.find((command) => command.name() === 'usage');
34
+ if (!usage) throw new Error('usage command must be registered before usage daily');
35
+ const out = deps.out ?? console.log;
36
+ const exit = deps.exit ?? ((code: number) => { process.exitCode = code; });
37
+ usage.command('daily')
38
+ .description('현재 logs.db에 남은 호스트 시간·일 LLM 사용량 (UTC)')
39
+ .option('--since <day>', 'UTC 시작일 YYYY-MM-DD')
40
+ .option('--period <period>', 'day | hour', 'day')
41
+ .option('--by <axis>', 'day | model | role | stage | account', 'day')
42
+ .option('--json', 'JSON 출력')
43
+ .action((opts: { since?: string; period: string; by: string; json?: boolean }) => {
44
+ const parsedSince = opts.since === undefined ? null : Date.parse(`${opts.since}T00:00:00Z`);
45
+ if (!['day', 'model', 'role', 'stage', 'account'].includes(opts.by) || !['day', 'hour'].includes(opts.period)
46
+ || opts.since !== undefined && (!/^\d{4}-\d{2}-\d{2}$/.test(opts.since)
47
+ || !Number.isFinite(parsedSince) || new Date(parsedSince!).toISOString().slice(0, 10) !== opts.since)) {
48
+ const detail = '--period day|hour · --by day|model|role|stage|account · --since YYYY-MM-DD (UTC)';
49
+ if (opts.json) out(JSON.stringify({ status: 'error', reason: 'invalid-arguments', detail }));
50
+ else out(`⛔ ${detail}`);
51
+ exit(2); return;
52
+ }
53
+ const path = (deps.path ?? logsDbPath)();
54
+ const scope = { source: 'current-logs-db', sinceDay: opts.since ?? null, timeZone: 'UTC' };
55
+ const unavailable = (reason: 'logs-db-missing' | 'logs-db-unreadable', detail?: string) => {
56
+ if (opts.json) out(JSON.stringify({ status: 'unmeasured', hostStatus: 'unmeasured', podStatus: 'unmeasured',
57
+ reason, scope, ...(detail === undefined ? {} : { detail }), rows: [] }));
58
+ else out(`사용량 집계 불가: ${reason === 'logs-db-missing' ? 'logs.db 없음' : 'logs.db 읽기 실패'} · UTC${opts.since ? ` · ${opts.since} 이후` : ''} · Pod 사용량 측정 불가${detail ? ` (${detail})` : ''}`);
59
+ exit(1);
60
+ };
61
+ let source: ReturnType<typeof readUsageDaily>;
62
+ try {
63
+ source = (deps.read ?? readUsageDaily)(path, opts.since);
64
+ }
65
+ catch (error) {
66
+ unavailable('logs-db-unreadable', String(error)); return;
67
+ }
68
+ if (source === null) {
69
+ unavailable('logs-db-missing'); return;
70
+ }
71
+ const report = { status: 'partial', hostStatus: 'measured-within-current-logs-horizon',
72
+ podStatus: 'unmeasured', podObservedRows: source.podObservedRows,
73
+ unclassifiedRows: source.unclassifiedRows, sourceMaxId: source.sourceMaxId,
74
+ scope,
75
+ timeZone: 'UTC', period: opts.period, by: opts.by,
76
+ rows: summarizeDailyUsage(source.rows, opts.by as Axis, opts.period as Period) };
77
+ if (opts.json) { out(JSON.stringify(report)); return; }
78
+ out(`집계 범위: 현재 logs.db에 남은 로그 · UTC${opts.since ? ` · ${opts.since} 이후` : ''} (보존 기간 밖은 포함되지 않음)`);
79
+ out(`Pod 사용량: 측정 불가 · 위 범위에서 ${report.podObservedRows}행 관측 (0행도 사용량 0을 뜻하지 않음)`);
80
+ if (report.unclassifiedRows > 0) out(`분류 불가 사용량: 측정 불가 · 위 범위에서 ${report.unclassifiedRows}행 관측`);
81
+ if (!report.rows.length) { out('(현재 로그에 남은 호스트 사용량 없음 · 과거 로그는 복구 불가)'); return; }
82
+ for (const row of report.rows) out(`${row.period} ${opts.by}=${row.key} calls=${row.calls} input=${row.inputTokens} output=${row.outputTokens} cacheRead=${row.cacheReadInputTokens} usdKnown=${row.usdKnown} unknownCostCalls=${row.unknownCostCalls}`);
83
+ });
84
+ }
@@ -1,5 +1,6 @@
1
1
  import { existsSync, lstatSync, readdirSync, readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
+ import { isMainThread, parentPort, workerData, Worker } from 'node:worker_threads';
3
4
  import { queryRunningRuns, type QueriedRunningRunsResult } from '../self-implement/running-runs.js';
4
5
  import { loadRunLedger } from '../self-implement/run-ledger.js';
5
6
  import { localLoopRows } from '../dashboard/slash-runtime/loops-table.js';
@@ -8,6 +9,7 @@ import { debug, redactSecretText } from '../debug/log.js';
8
9
  import { DecisionLedger, type DecisionEntry } from '../decisions/decision-ledger.js';
9
10
  import { listChecklist, devVersion, type Checklist } from '../release-loop/checklist.js';
10
11
  import { effectiveInstanceRoot } from '../instance/resolve.js';
12
+ import { setElanousConfigDir } from '../elanous-config-dir.js';
11
13
  import { seatDay, seatLedgerPath, type SeatEntry } from '../seat-loop/seat-loop.js';
12
14
  import { listCoordEvents, type CoordEvent } from './coord-events.js';
13
15
  import { filterPublicDemoContext } from './context-now-public.js';
@@ -50,6 +52,18 @@ function todaySeatEntries(now: Date): Array<{ entry: SeatEntry; source: string }
50
52
  });
51
53
  }
52
54
 
55
+ function seatFact({ entry, source }: { entry: SeatEntry; source: string }): Extract<ContextFact, { kind: 'seat' }> {
56
+ return { kind: 'seat', seat: entry.seat, at: entry.at, status: entry.status,
57
+ id: entry.item?.id ?? null, title: entry.item?.source === 'checklist'
58
+ ? redactSecretText(entry.item.title.split(/\r?\n/, 1)[0] ?? '').slice(0, 120) : null, source };
59
+ }
60
+
61
+ /** The TUI status line needs seat facts only; it must not scan release or run ledgers. */
62
+ export function seatStatusNow(now = new Date()): ContextNowAnswer {
63
+ return { at: `${now.toISOString().slice(0, 16)}:00.000Z`, topic: null,
64
+ facts: todaySeatEntries(now).map(seatFact), events: [], guide: [] };
65
+ }
66
+
53
67
  const runSource = 'elanous://self-implement/running-runs';
54
68
  const releaseSource = 'elanous://graph-runs/release-loop';
55
69
  const scheduleSource = 'elanous://schedules';
@@ -143,11 +157,7 @@ export function contextNow(options: { topic?: string; limit?: number; audience?:
143
157
  facts.push({ kind: 'decision', id: item.id, title: redactSecretText(item.title.split(/\r?\n/, 1)[0] ?? '').slice(0, 120),
144
158
  status: item.status, dueAt: item.dueAt ?? null, source: `elanous://decisions/${encodeURIComponent(item.id)}` });
145
159
  }
146
- for (const { entry, source } of (deps.seatEntries ?? todaySeatEntries)(now)) {
147
- facts.push({ kind: 'seat', seat: entry.seat, at: entry.at, status: entry.status,
148
- id: entry.item?.id ?? null, title: entry.item?.source === 'checklist'
149
- ? redactSecretText(entry.item.title.split(/\r?\n/, 1)[0] ?? '').slice(0, 120) : null, source });
150
- }
160
+ facts.push(...(deps.seatEntries ?? todaySeatEntries)(now).map(seatFact));
151
161
  const rawEvents = (deps.events ?? (since => listCoordEvents({ since })))(new Date(now.getTime() - 7 * 86_400_000).toISOString());
152
162
  const chronologicalEvents = rawEvents.slice().sort((a, b) => a.at.localeCompare(b.at));
153
163
  const matches = (text: string) => !topic || text.toLocaleLowerCase().includes(topic.toLocaleLowerCase());
@@ -199,3 +209,70 @@ export function contextNow(options: { topic?: string; limit?: number; audience?:
199
209
  debug.log('context.now', 'answer', { topic, facts: answer.facts, events: answer.events });
200
210
  return options.audience === 'public-demo' ? filterPublicDemoContext(answer, deps.brandCheck) : answer;
201
211
  }
212
+
213
+ const workerAnswers = new Map<string, { promise: Promise<ContextNowAnswer>; expiresAt: number }>();
214
+ const WORKER_ANSWER_TTL_MS = 5_000;
215
+ const WORKER_SCAN_TIMEOUT_MS = 60_000;
216
+ let workerScanTail: Promise<void> = Promise.resolve();
217
+
218
+ /** Keep the ledger scan off the TUI event loop. Repeated identical reads share one scan. */
219
+ export function contextNowInWorker(options: Parameters<typeof contextNow>[0] = {}): Promise<ContextNowAnswer> {
220
+ const stateRoot = process.env.ELANOUS_STATE_DIR;
221
+ const selectedRoot = effectiveInstanceRoot();
222
+ const key = JSON.stringify([selectedRoot, stateRoot ?? null, options.topic ?? null, options.limit ?? null, options.audience ?? null]);
223
+ const now = Date.now();
224
+ for (const [cachedKey, cached] of workerAnswers) {
225
+ if (cached.expiresAt < now) workerAnswers.delete(cachedKey);
226
+ }
227
+ const cached = workerAnswers.get(key);
228
+ if (cached) return cached.promise;
229
+ // Distinct topics queue behind the active scan instead of multiplying the same costly ledger walk.
230
+ const promise = workerScanTail.then(() => scanContextNowInWorker(options, stateRoot, selectedRoot));
231
+ workerScanTail = promise.then(() => undefined, () => undefined);
232
+ const entry = { promise, expiresAt: Infinity };
233
+ workerAnswers.set(key, entry);
234
+ void promise.then(() => { entry.expiresAt = Date.now() + WORKER_ANSWER_TTL_MS; }, () => { workerAnswers.delete(key); });
235
+ return promise;
236
+ }
237
+
238
+ export function scanContextNowInWorker(options: Parameters<typeof contextNow>[0], stateRoot: string | undefined, selectedRoot: string,
239
+ createWorker: () => Worker = () => new Worker(new URL(import.meta.url), { workerData: { kind: 'context-now' } }),
240
+ timeoutMs = WORKER_SCAN_TIMEOUT_MS): Promise<ContextNowAnswer> {
241
+ const worker = createWorker();
242
+ return new Promise((resolve, reject) => {
243
+ let settled = false;
244
+ const timeout = setTimeout(() => {
245
+ debug.log('context.now', 'worker-timeout', { timeoutMs, topic: options?.topic ?? null, selectedRoot });
246
+ finish(new Error(`context_now worker timed out after ${timeoutMs}ms`));
247
+ }, timeoutMs);
248
+ const finish = (error?: Error, answer?: ContextNowAnswer): void => {
249
+ if (settled) return;
250
+ settled = true;
251
+ clearTimeout(timeout);
252
+ void worker.terminate();
253
+ if (error) reject(error);
254
+ else resolve(answer!);
255
+ };
256
+ worker.on('message', (message: { answer?: ContextNowAnswer; error?: string }) => {
257
+ if (message.error) finish(new Error(message.error));
258
+ else if (message.answer) finish(undefined, message.answer);
259
+ });
260
+ worker.on('error', error => finish(error instanceof Error ? error : new Error(String(error))));
261
+ worker.on('exit', code => { if (!settled) finish(new Error(`context_now worker exited before answering: ${code}`)); });
262
+ // Preserve both caller roots: a programmatic config override is not inherited by workers.
263
+ worker.postMessage({ options, stateRoot, selectedRoot });
264
+ });
265
+ }
266
+
267
+ const contextWorkerPort = parentPort;
268
+ if (!isMainThread && contextWorkerPort && workerData?.kind === 'context-now') {
269
+ contextWorkerPort.on('message', ({ options, stateRoot, selectedRoot }: { options: Parameters<typeof contextNow>[0]; stateRoot?: string; selectedRoot: string }) => {
270
+ try {
271
+ if (stateRoot === undefined) delete process.env.ELANOUS_STATE_DIR;
272
+ else process.env.ELANOUS_STATE_DIR = stateRoot;
273
+ setElanousConfigDir(selectedRoot);
274
+ contextWorkerPort.postMessage({ answer: contextNow(options) });
275
+ }
276
+ catch (error) { contextWorkerPort.postMessage({ error: error instanceof Error ? error.message : String(error) }); }
277
+ });
278
+ }
@@ -0,0 +1,41 @@
1
+ // 인증 거절(401)로 끝난 턴을 «조용한 완료»가 아니라 처방 한 줄로 드러낸다(TUI 결함 #22 · 10-14).
2
+ //
3
+ // `runCoreTurn` 은 인증 거절을 `stopReason: 'auth_rejected'` 로 «돌려준다»(던지지 않는다) —
4
+ // 재인증과 버그를 가르려는 설계다. 그런데 ACP 브리지가 그 값을 안 읽어서 TUI 엔 «✔ 완료»만 떴다.
5
+ // 브리지는 이 오류를 던져 서버의 실패 경로(`prompt-failed`)와 TUI 의 오류 줄로 보낸다.
6
+ //
7
+ // ⚠️ 문면은 #27498(실패 지문 사전 · `src/self-health/signatures.ts`)의 «⚠ 원인 → 처방 · 원문» 형식을
8
+ // 따른 «임시 상수»다 — 그 PR 이 착지하면 사전 항목(`auth-rejected`)으로 옮기고 이 상수는 지운다.
9
+
10
+ import { redactSecretText } from '../debug/log.js';
11
+
12
+ export const AUTH_REJECTED_NOTICE = '⚠ 모델 공급자가 인증을 거절(401) → 다시 로그인하거나 계정 확인(eln usage)';
13
+
14
+ const RAW_PREVIEW_MAX = 120;
15
+
16
+ /** 원문 첫 줄을 비밀값 가림 ⊕ 제어 문자 제거 ⊕ 길이 상한으로 줄인다(화면 한 줄을 넘기지 않게). */
17
+ export function authRejectedRawPreview(raw: string | undefined): string {
18
+ const firstLine = (redactSecretText(raw ?? '').split(/\r\n|\r|\n/, 1)[0] ?? '')
19
+ // 단독 CR·ESC 같은 터미널 제어 문자가 오류 줄을 덮어쓰지 않게 공백으로(리뷰 r2 should-fix).
20
+ .replace(/[\u0000-\u001f\u007f-\u009f]/g, ' ')
21
+ .trim();
22
+ return firstLine.length > RAW_PREVIEW_MAX ? `${firstLine.slice(0, RAW_PREVIEW_MAX)}…` : firstLine;
23
+ }
24
+
25
+ /** 처방 한 줄 — 원문이 있으면 꼬리에 붙인다. 줄바꿈은 넣지 않는다(오류 줄이 넘치지 않게). */
26
+ export function formatAuthRejectedNotice(raw: string | undefined): string {
27
+ const preview = authRejectedRawPreview(raw);
28
+ return preview ? `${AUTH_REJECTED_NOTICE} · 원문: ${preview}` : AUTH_REJECTED_NOTICE;
29
+ }
30
+
31
+ /** 브리지가 던지는 오류. `status` 를 401 로 둬 상위의 인증 판정(`isAuthRejectionError`)과도 맞는다. */
32
+ export class CoreTurnAuthRejectedError extends Error {
33
+ readonly status = 401;
34
+ readonly rawMessage: string;
35
+
36
+ constructor(raw: string | undefined) {
37
+ super(formatAuthRejectedNotice(raw));
38
+ this.name = 'CoreTurnAuthRejectedError';
39
+ this.rawMessage = redactSecretText(raw ?? '');
40
+ }
41
+ }
@@ -23,7 +23,7 @@
23
23
  import { isAuthRejectionError, streamLLMWithTools } from '../llm.js';
24
24
  import { drainPendingUserInput } from '../session/pending-input.js';
25
25
  import type { StreamWithToolsHandlers } from '../llm.js';
26
- import { debug, withAmbientSessionScope } from '../debug/log.js';
26
+ import { debug, redactSecretText, withAmbientSessionScope } from '../debug/log.js';
27
27
  import { applyDeferredTools } from '../session-runtime/tier-flip.js';
28
28
  import { resolveSessionSurfaceProfile } from '../session-runtime/index.js';
29
29
  import type {
@@ -133,6 +133,9 @@ export async function runCoreTurn(
133
133
  accumulatedText = full;
134
134
  ctx.callbacks?.onText?.(delta, full);
135
135
  },
136
+ ...(ctx.callbacks?.onFinalAnswerSupplement
137
+ ? { onFinalAnswerSupplement: (info: { answer: string; supplement: string; finalText: string }) => ctx.callbacks?.onFinalAnswerSupplement?.(info) }
138
+ : {}),
136
139
  // This async boundary deliberately returns the dispatcher's fulfilled value
137
140
  // or rejection, not its Promise object identity, so completion is recorded.
138
141
  dispatchTool: async (name, args, c) => {
@@ -283,6 +286,7 @@ export async function runCoreTurn(
283
286
  ...(ctx.sessionId !== undefined ? { sessionId: ctx.sessionId } : {}),
284
287
  ...(ctx.maxToolTurns !== undefined ? { maxTurns: ctx.maxToolTurns } : {}),
285
288
  ...(ctx.modelOverride !== undefined ? { model: ctx.modelOverride } : {}),
289
+ ...(ctx.callbacks?.onResolvedProvider !== undefined ? { onResolvedProvider: ctx.callbacks.onResolvedProvider } : {}),
286
290
  ...(ctx.budgetGrant !== undefined ? { budgetGrant: ctx.budgetGrant } : {}),
287
291
  // ⭐⭐⭐ `B3`(2026-08-19 · 대표 지시 ②) — 도는 턴 «안»으로 들어오는 사용자 발화의 배수구.
288
292
  // ⛔ 종전엔 스트리밍 중 친 발화가 ***턴이 끝난 뒤***에야 나갔다.
@@ -307,9 +311,16 @@ export async function runCoreTurn(
307
311
  };
308
312
  } catch (err) {
309
313
  const stopReason = classifyStopReason(err, ctx.signal);
310
- if (stopReason === 'aborted' || stopReason === 'auth_rejected') {
314
+ if (stopReason === 'aborted') {
311
315
  return { stopReason, finalText: accumulatedText };
312
316
  }
317
+ if (stopReason === 'auth_rejected') {
318
+ return {
319
+ stopReason,
320
+ finalText: accumulatedText,
321
+ errorMessage: redactSecretText(err instanceof Error ? err.message : String(err)),
322
+ };
323
+ }
313
324
  throw err;
314
325
  }
315
326
  });
@@ -164,6 +164,11 @@ export function buildUpdateGoalToolSpec(): LLMToolSpec {
164
164
  };
165
165
  }
166
166
 
167
+ /** 반려·재요청은 모델에게만 가는 내부 지시다 — 사용자 답에 그 사정(«완료 주장이 거부됐다»·«죄송합니다»)이 새지 않게 한다
168
+ * (10-14 OPT 점검: evidence·rejected 판정 14회가 사용자 답의 사과 문장으로 나왔다). */
169
+ export const GOAL_INTERNAL_NOTICE_RULE =
170
+ '이 반려·재요청은 내부 지시다. 사용자에게 보이는 답에 «완료 주장이 거부됐다/어긋났다»·«죄송합니다» 같은 내부 사정을 쓰지 말고, 고친 결과와 사실만 말하라.';
171
+
167
172
  /** 목표 실행 계약 — 첫 turn 앞에 leading system 메시지로 주입. codex 자체 prompt.md /
168
173
  * ext-goal continuation.md 의 지속·anti-shrink·증거완료 언어 이식. ASCII + 한국어. */
169
174
  export const GOAL_SYSTEM_PREAMBLE = [
@@ -173,6 +178,7 @@ export const GOAL_SYSTEM_PREAMBLE = [
173
178
  '- 완료는 증거로 판정한다. 모든 요구사항/산출물/검증에 대해 실제 현재 상태에서 증거를 확인하라. 불확실하거나 간접적인 증거는 미달성으로 보고 계속하라.',
174
179
  `- 목표가 실제로 완전히 끝났고 증거로 확인됐을 때만 ${UPDATE_GOAL_TOOL_NAME} 도구를 status="complete" 로 호출하고 evidence 에 그 증거를 적어 종료하라. 완료 신호는 이 도구 호출뿐이다(텍스트 문장이 아니다).`,
175
180
  '- 아직 할 일이 남았으면 멈추거나 허락을 구하지 말고 다음 최고가치 스텝을 바로 실행하라.',
181
+ `- [continue]·[finalize]·[evidence required]·[evidence mismatch]·[tool call rejected] 같은 반려·재요청은 내부 지시다. 사용자에게 보이는 답에 «완료 주장이 거부됐다/어긋났다»·«죄송합니다» 같은 내부 사정을 쓰지 말고, ${UPDATE_GOAL_TOOL_NAME} 호출도 답에서 설명하지 마라.`,
176
182
  ].join('\n');
177
183
 
178
184
  /** 미완 판정 시 재주입하는 continuation 프롬프트(user turn). */
@@ -186,6 +192,7 @@ export const GOAL_CONTINUATION_PROMPT = [
186
192
  '예산이 곧 소진된다거나 그만두고 싶다는 이유로 완료를 선언하지 마라.',
187
193
  `진짜로 진행이 막혔고(같은 장애가 반복) 대안도 없을 때만 ${UPDATE_GOAL_TOOL_NAME} 도구를 status="blocked" 로 호출하고 무엇이 왜 막혔는지 evidence 에 적어라. 단지 어렵거나 느리거나 불확실하다는 이유로는 쓰지 마라.`,
188
194
  `모든 요구사항이 증거로 충족됐다면, ${UPDATE_GOAL_TOOL_NAME} 도구를 status="complete" + evidence 로 호출해 종료하라.`,
195
+ GOAL_INTERNAL_NOTICE_RULE,
189
196
  ].join('\n');
190
197
 
191
198
  /** 감독 메모 블록의 머리말 — 자식이 「이것은 부모가 보낸 것」임을 «구별»하게 한다. */
@@ -198,6 +205,7 @@ export const GOAL_READBACK_PROMPT = [
198
205
  `완료를 텍스트로만 말했다. 텍스트 문장은 완료 신호가 아니다 — 완료가 사실이면 ${UPDATE_GOAL_TOOL_NAME} 도구를 status="complete" 로 호출하고 evidence 에 현재 상태에서 실제로 확인한 증거(파일·명령출력·테스트·PR)를 적어라.`,
199
206
  '아직 미충족 항목이 있으면 완료를 주장하지 말고 다음 스텝을 지금 실행하라.',
200
207
  '이미 사용자에게 한 답을 다시 쓰지 마라 — 새 사실이 없으면 텍스트 없이 update_goal 만 호출하라.',
208
+ GOAL_INTERNAL_NOTICE_RULE,
201
209
  ].join('\n');
202
210
 
203
211
  /** GOAL-LOOP-INTENT-STALL (0.2.24 · OP or-audit-1010) — 구현 자식이 «도구를 한 번도 안 부르고 말만 한 턴»에
@@ -222,6 +230,7 @@ export const GOAL_EVIDENCE_REQUIRED_PROMPT = [
222
230
  '[evidence required]',
223
231
  `${UPDATE_GOAL_TOOL_NAME}(status="complete") 를 호출했지만 evidence 가 비어 있어 완료로 인정하지 않는다.`,
224
232
  '현재 상태(파일·명령출력·테스트결과·PR)에서 실제로 확인한 증거를 evidence 에 채워 다시 호출하거나, 미충족 항목을 마저 실행하라.',
233
+ GOAL_INTERNAL_NOTICE_RULE,
225
234
  ].join('\n');
226
235
 
227
236
  /** evidence-mismatch 반려 재주입 (OH8 후속 PR-2) — update_goal(complete) 를 호출했으나 그 턴까지의
@@ -236,6 +245,7 @@ export function buildEvidenceMismatchPrompt(fail: number, unmatchedFilters: read
236
245
  `(fail=${fail}, unmatched=${unmatched}). 완료 증거와 실제 테스트 결과가 어긋난다 — 완료로 인정하지 않는다.`,
237
246
  '테스트를 실제로 통과시키거나(fail=0 · 모든 필터 매칭), 완료 주장을 철회하고 남은 작업을 마저 실행하라.',
238
247
  '통과한 run_tests 없이 complete 를 다시 주장하지 마라.',
248
+ GOAL_INTERNAL_NOTICE_RULE,
239
249
  ].join('\n');
240
250
  }
241
251
 
@@ -245,6 +255,7 @@ export function buildRejectedToolCompletionPrompt(rejectedTools: readonly string
245
255
  '[tool call rejected]',
246
256
  `${UPDATE_GOAL_TOOL_NAME}(status="complete") 를 호출했지만 이 turn 에 ${rejectedTools.join(', ')} 도구 호출이 거부되어 실행되지 않았다. 완료 증거와 실제 도구 결과가 어긋난다 — 완료로 인정하지 않는다.`,
247
257
  '거부된 작업을 실제로 다시 실행하거나 완료 주장을 철회하고 남은 작업을 마저 실행하라.',
258
+ GOAL_INTERNAL_NOTICE_RULE,
248
259
  ].join('\n');
249
260
  }
250
261
 
@@ -301,6 +312,8 @@ export interface GoalLoopResult {
301
312
  stopReason: GoalLoopStopReason;
302
313
  /** 목표가 증거 기준 완료로 선언됐는지(update_goal(complete)+evidence 감지). */
303
314
  goalComplete: boolean;
315
+ /** `auth_rejected` 로 끝났을 때 — 마지막 코어 턴의 공급자 오류 원문(비밀값 가림). */
316
+ errorMessage?: string;
304
317
  }
305
318
 
306
319
  /** 완료 마커 감지(deprecated fallback) — 마커가 산문 안에 우연히 포함(예: "상수 값은
@@ -856,7 +869,10 @@ export async function runGoalLoop(
856
869
  sessionId: ctx.sessionId, ...runAttribution, iterations, stopReason: lastResult.stopReason,
857
870
  finalChars: lastResult.finalText.length,
858
871
  }, { level: 'error' });
859
- return finish({ finalText: lastResult.finalText, iterations, stopReason: lastResult.stopReason, goalComplete: false });
872
+ return finish({
873
+ finalText: lastResult.finalText, iterations, stopReason: lastResult.stopReason, goalComplete: false,
874
+ ...(lastResult.errorMessage !== undefined ? { errorMessage: lastResult.errorMessage } : {}),
875
+ });
860
876
  }
861
877
 
862
878
  // Evidence-less completion is not authoritative; only retry after stop and terminal outcomes