elanous 0.2.22 → 0.2.23

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 (705) hide show
  1. package/NOTICE +7 -0
  2. package/README.md +32 -22
  3. package/apps/pwa/out/404/index.html +1 -1
  4. package/apps/pwa/out/404.html +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{119fc678.6f591cdb84ca5791.js → 0673cc54.8e2ef1c23e49e190.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/{a9f2b54d-40c16bd0efdb04b8.js → 0a09e062-34f747a17d8d8c2e.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/{f8626309.a4e5d362b1d55e59.js → 0e3acd34.d42b2ef87fdf4234.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +77 -0
  9. package/apps/pwa/out/_next/static/chunks/{7175-350f4ce2873bc038.js → 1325-dc3f3c21eb181cb4.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +34 -0
  11. package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +24 -0
  12. package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/{6767.8e6c5f6e744fcd9f.js → 1505.5826671109111e75.js} +2 -2
  14. package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/{7327-2d69fb321ba73389.js → 1669-da843ed73aa301f5.js} +1 -1
  21. package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +36 -0
  23. package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +122 -0
  24. package/apps/pwa/out/_next/static/chunks/2528.0af5c0e1fad88df6.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +62 -0
  27. package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/272-b23d2e92161d11fd.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{7899.597af4a9996c907f.js → 2721.bc9a8f36bd85c07a.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +149 -0
  35. package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3961-fbef064c213b2b18.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +309 -0
  39. package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{d70879db.c66c56a95a91efc6.js → 4c5e95ce.83e9b16add6fcd8c.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/{6158.566c890adc06a459.js → 5313.1697309c532b9856.js} +2 -2
  52. package/apps/pwa/out/_next/static/chunks/{79b78388.663188133449d707.js → 53746282.1be36038d1abd949.js} +1 -1
  53. package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5578.ac963634373b28c6.js +286 -0
  56. package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5967-c0a80f8ffe5d4050.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/{1268.0840ff91e083fcbd.js → 5974.360f8441eb0ac1ec.js} +1 -1
  59. package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +74 -0
  64. package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/6571-926ddf024a6ad5df.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +64 -0
  69. package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/{9832.2ab2e818013574c7.js → 6702.ebbd165d5e4a4a14.js} +1 -1
  71. package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +32 -0
  73. package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +24 -0
  74. package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +93 -0
  78. package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/{6110.1297d4093fdfbb0d.js → 740.90b31555290236a9.js} +2 -2
  83. package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +148 -0
  84. package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +226 -0
  85. package/apps/pwa/out/_next/static/chunks/{9070.067c106528ec1ae6.js → 7518.49161e8f5814abdb.js} +1 -1
  86. package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +27 -0
  87. package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +115 -0
  90. package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7905.b230b9d06cb4ad5d.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{8194.484f51e273d9abd2.js → 8264.00e434fbd02e9311.js} +16 -16
  97. package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +8 -0
  99. package/apps/pwa/out/_next/static/chunks/{088d8e8a.8069543d082bec12.js → 83cfc5c8.349535543c1548b6.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +23 -0
  101. package/apps/pwa/out/_next/static/chunks/{1948.5f35b39eef222a94.js → 8438.ee7f0df3b3f6fcb4.js} +1 -1
  102. package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/{4588.ad3364cb7fb97ada.js → 8532.a86e99acf9b761cb.js} +2 -2
  105. package/apps/pwa/out/_next/static/chunks/8569.b853a8daa8f31d12.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8925-2abfb48af477fb7f.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/{88729267.9c6c000157c83f2f.js → 89849432.9eaa2f4c9c010965.js} +3 -3
  110. package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +90 -0
  111. package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +94 -0
  112. package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +41 -0
  114. package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +287 -0
  116. package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +79 -0
  117. package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/{3522-1de1319d028ac89c.js → 9502-32c5dc22e8f120f5.js} +3 -3
  120. package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +104 -0
  123. package/apps/pwa/out/_next/static/chunks/{7630.2b9a68659053ff4e.js → 9976.8f28864317639fe6.js} +16 -16
  124. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d5341ac96203a983.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-0160ab83c8685a12.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/board/page-55c631c032dcc47e.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ad3bd8084048bee4.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/bots/page-e6784759a2531031.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/ceo/page-5c5d0e370f495ef6.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/chat/page-c325e21543cd48a8.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/consult/{page-80ed511e02c81412.js → page-6168a7c43e6ef8f5.js} +1 -1
  133. package/apps/pwa/out/_next/static/chunks/app/control/page-31417d3604154a6d.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/decisions/page-e9606dc0bdec9305.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/design-check/page-a648bc464c9dc754.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/editor/page-25bb425afdb27541.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/exec/page-32d72fdef1afe11a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/field/page-d27b794c8ba76bbb.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/inside/page-2bd9ce9c020d02d4.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/intake/page-a34096245e63b9f2.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/layout-22170f4f00a15496.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live/page-4cc66d22ca4ec502.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live-run/page-83b14c729fcea837.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/loops/page-6e2781c523dad761.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/market/page-26dd415c8f13f341.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-ccdb83ed40c8d724.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/morning/page-7ad3de8fa06fdea9.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/not-found-015c02c4fec4023e.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/observatory/page-6b0ae5b5c42f6d2f.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-786111f30b6f0969.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-48fb31810693c357.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e17cce5e2ed0fee.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/outputs/page-cb154acadb025414.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/page-16258e956ea93fc2.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/reflection/page-c2dd2b19c93f90ab.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-85f35dd1dd96ae87.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/sessions/page-d3c007c8a0ddd7ee.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7837ce2aacb97b04.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/page-7350ee93f4fe1033.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-00723458575f2b19.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/page-745d9b6c015076f8.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/share/page-736d33c7414a8a1a.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/showroom/page-119be9a0444d2482.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/tasks/page-fa806c018833e332.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/term/page-c782041b5f5199ba.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/today/page-d431fbdea6ad93dd.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/trace/page-0c056abff82b9891.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/vault/page-242d668e4fbf72c4.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-847c3de6ca8a4416.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/page-81dd0d8ae923ed72.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workspace/page-74e69ba2c8e970d4.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-70038f41ae7cf931.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/b4e12462-5fab4a813a63dadd.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/{f6b7c9ba.64a895b8b2fedbdc.js → ce383d63.d2ede338788ed18e.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/{framework-5c169757551134ed.js → framework-b2763b10dc6b3836.js} +1 -1
  179. package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +1 -0
  184. package/apps/pwa/out/_next/static/css/5619d59e87eddf66.css +1 -0
  185. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
  186. package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → rfkMm4movqkqMebBrCXiR}/_buildManifest.js +1 -1
  187. package/apps/pwa/out/approvals/index.html +1 -1
  188. package/apps/pwa/out/approvals/index.txt +23 -23
  189. package/apps/pwa/out/autopilot/index.html +1 -1
  190. package/apps/pwa/out/autopilot/index.txt +23 -23
  191. package/apps/pwa/out/board/index.html +1 -1
  192. package/apps/pwa/out/board/index.txt +23 -23
  193. package/apps/pwa/out/botlab/index.html +1 -1
  194. package/apps/pwa/out/botlab/index.txt +22 -22
  195. package/apps/pwa/out/bots/index.html +1 -1
  196. package/apps/pwa/out/bots/index.txt +22 -22
  197. package/apps/pwa/out/ceo/index.html +1 -1
  198. package/apps/pwa/out/ceo/index.txt +23 -23
  199. package/apps/pwa/out/chat/index.html +1 -1
  200. package/apps/pwa/out/chat/index.txt +22 -22
  201. package/apps/pwa/out/consult/index.html +1 -1
  202. package/apps/pwa/out/consult/index.txt +23 -23
  203. package/apps/pwa/out/control/index.html +1 -1
  204. package/apps/pwa/out/control/index.txt +23 -23
  205. package/apps/pwa/out/decisions/index.html +1 -1
  206. package/apps/pwa/out/decisions/index.txt +22 -22
  207. package/apps/pwa/out/design-check/index.html +1 -1
  208. package/apps/pwa/out/design-check/index.txt +23 -23
  209. package/apps/pwa/out/editor/index.html +1 -1
  210. package/apps/pwa/out/editor/index.txt +24 -23
  211. package/apps/pwa/out/exec/index.html +1 -1
  212. package/apps/pwa/out/exec/index.txt +23 -23
  213. package/apps/pwa/out/field/index.html +1 -1
  214. package/apps/pwa/out/field/index.txt +23 -23
  215. package/apps/pwa/out/healthz +1 -1
  216. package/apps/pwa/out/index.html +1 -1
  217. package/apps/pwa/out/index.txt +22 -22
  218. package/apps/pwa/out/inside/index.html +1 -1
  219. package/apps/pwa/out/inside/index.txt +22 -22
  220. package/apps/pwa/out/intake/index.html +1 -1
  221. package/apps/pwa/out/intake/index.txt +23 -23
  222. package/apps/pwa/out/live/index.html +1 -1
  223. package/apps/pwa/out/live/index.txt +23 -23
  224. package/apps/pwa/out/live-run/index.html +1 -1
  225. package/apps/pwa/out/live-run/index.txt +24 -23
  226. package/apps/pwa/out/loops/index.html +1 -1
  227. package/apps/pwa/out/loops/index.txt +22 -22
  228. package/apps/pwa/out/market/index.html +1 -1
  229. package/apps/pwa/out/market/index.txt +22 -22
  230. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  231. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  232. package/apps/pwa/out/morning/index.html +1 -1
  233. package/apps/pwa/out/morning/index.txt +23 -23
  234. package/apps/pwa/out/observatory/index.html +1 -1
  235. package/apps/pwa/out/observatory/index.txt +23 -23
  236. package/apps/pwa/out/ops/checklist/index.html +1 -1
  237. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  238. package/apps/pwa/out/ops/release/index.html +1 -1
  239. package/apps/pwa/out/ops/release/index.txt +22 -22
  240. package/apps/pwa/out/ops/seats/index.html +1 -1
  241. package/apps/pwa/out/ops/seats/index.txt +22 -22
  242. package/apps/pwa/out/outputs/index.html +1 -1
  243. package/apps/pwa/out/outputs/index.txt +22 -22
  244. package/apps/pwa/out/reflection/index.html +1 -1
  245. package/apps/pwa/out/reflection/index.txt +23 -23
  246. package/apps/pwa/out/scheduler/index.html +1 -1
  247. package/apps/pwa/out/scheduler/index.txt +23 -23
  248. package/apps/pwa/out/sessions/index.html +1 -1
  249. package/apps/pwa/out/sessions/index.txt +22 -22
  250. package/apps/pwa/out/settings/devices/index.html +1 -1
  251. package/apps/pwa/out/settings/devices/index.txt +23 -23
  252. package/apps/pwa/out/settings/index.html +1 -1
  253. package/apps/pwa/out/settings/index.txt +23 -23
  254. package/apps/pwa/out/setup/done/index.html +1 -1
  255. package/apps/pwa/out/setup/done/index.txt +23 -23
  256. package/apps/pwa/out/setup/index.html +1 -1
  257. package/apps/pwa/out/setup/index.txt +23 -23
  258. package/apps/pwa/out/share/index.html +1 -1
  259. package/apps/pwa/out/share/index.txt +23 -23
  260. package/apps/pwa/out/showroom/index.html +1 -1
  261. package/apps/pwa/out/showroom/index.txt +22 -22
  262. package/apps/pwa/out/tasks/index.html +1 -1
  263. package/apps/pwa/out/tasks/index.txt +23 -23
  264. package/apps/pwa/out/term/index.html +1 -1
  265. package/apps/pwa/out/term/index.txt +23 -23
  266. package/apps/pwa/out/today/index.html +1 -1
  267. package/apps/pwa/out/today/index.txt +23 -23
  268. package/apps/pwa/out/trace/index.html +1 -1
  269. package/apps/pwa/out/trace/index.txt +23 -23
  270. package/apps/pwa/out/vault/index.html +1 -1
  271. package/apps/pwa/out/vault/index.txt +23 -23
  272. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  273. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  274. package/apps/pwa/out/workflows/index.html +1 -1
  275. package/apps/pwa/out/workflows/index.txt +23 -23
  276. package/apps/pwa/out/workspace/index.html +1 -1
  277. package/apps/pwa/out/workspace/index.txt +23 -23
  278. package/apps/pwa/out/worktrees/index.html +1 -1
  279. package/apps/pwa/out/worktrees/index.txt +23 -23
  280. package/catalog/models/anthropic/claude-haiku-5-5.yaml +32 -0
  281. package/catalog/models/anthropic/claude-opus-5-5.yaml +5 -0
  282. package/catalog/models/anthropic/claude-sonnet-5-5.yaml +31 -0
  283. package/catalog/models/anthropic/claude-sonnet-5.yaml +8 -2
  284. package/catalog/models/openai/gpt-6-astra.yaml +6 -0
  285. package/catalog/models/openai/gpt-6-luna.yaml +6 -0
  286. package/catalog/models/openai/gpt-6-sol.yaml +6 -0
  287. package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
  288. package/graphs/log-horizon/recipes.yaml +3 -0
  289. package/graphs/release/recipes.yaml +1 -1
  290. package/graphs/release/release-loop.yaml +6 -2
  291. package/graphs/release-rehearsal/recipes.yaml +12 -0
  292. package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
  293. package/package.json +4 -1
  294. package/scripts/bench-report.ts +82 -3
  295. package/scripts/ci-typecheck-changed.ts +10 -1
  296. package/scripts/hq/hq-fence-wrapper.sh +148 -0
  297. package/scripts/lib/typecheck-ratchet.ts +51 -0
  298. package/scripts/openai-relay-server.ts +5 -1
  299. package/scripts/release-loop/docs-node.ts +258 -43
  300. package/scripts/release-loop/gate-method.ts +59 -0
  301. package/scripts/release-loop/gate-node.ts +73 -7
  302. package/scripts/release-loop/gate-wall.ts +208 -0
  303. package/scripts/release-loop/known-issues-node.ts +53 -8
  304. package/scripts/release-loop/publish-at.ts +14 -0
  305. package/scripts/release-loop/publish-node.ts +17 -2
  306. package/scripts/release-loop/resume-release.ts +34 -4
  307. package/scripts/release-loop/resume.ts +53 -0
  308. package/scripts/release-loop/shard-plan.ts +3 -11
  309. package/scripts/release-loop/tui-node-checks.ts +22 -0
  310. package/scripts/release-loop/unattended-release.ts +8 -1
  311. package/scripts/rhythm/daily.ts +51 -2
  312. package/scripts/rhythm/weekly.ts +3 -2
  313. package/scripts/tsc-main-safety-net.ts +189 -0
  314. package/scripts/usage-rollup.ts +8 -4
  315. package/src/acp/codex-plugins.ts +48 -6
  316. package/src/agent/monad-agent-turn.ts +67 -5
  317. package/src/agent/run-context.ts +10 -0
  318. package/src/agent/tool-profile.ts +28 -2
  319. package/src/agent-mission/acp-judge.ts +8 -2
  320. package/src/agent-mission/capabilities-cli.ts +16 -1
  321. package/src/agent-mission/driver.ts +1 -1
  322. package/src/agent-mission/pr-review-watch.ts +6 -2
  323. package/src/agent-mission/review-loop.ts +33 -5
  324. package/src/agent-substrate/acp-reviewer.ts +17 -8
  325. package/src/agent-substrate/pr-reviewer.ts +164 -28
  326. package/src/agent-substrate/review-intent.ts +6 -4
  327. package/src/agent-substrate/self-review-cli.ts +111 -16
  328. package/src/agent-substrate/shard-boundary-intent.ts +92 -26
  329. package/src/ask-user-question/pending-questions.ts +8 -2
  330. package/src/autopilot/build/llm-conflict-merge.ts +216 -12
  331. package/src/autopilot/codebase-grounding.ts +44 -0
  332. package/src/autopilot/llm-control-brain.ts +13 -1
  333. package/src/autopilot/mission-codebase-gate.ts +8 -77
  334. package/src/autopilot/pr-manager.ts +12 -3
  335. package/src/boot/acp-server.ts +4 -7
  336. package/src/boot/acp-socket-path.ts +7 -0
  337. package/src/briefing/brief-items.ts +21 -13
  338. package/src/chat/index.ts +12 -3
  339. package/src/cli/agent-cli.ts +20 -0
  340. package/src/cli/brief-cli.ts +27 -21
  341. package/src/cli/cli-user-error.ts +9 -2
  342. package/src/cli/log-event-names.ts +3 -0
  343. package/src/cli/logs-cli.ts +1 -0
  344. package/src/cli/mcp-login.ts +111 -37
  345. package/src/cli/plugin-cli.ts +21 -1
  346. package/src/cli/pod-cli.ts +26 -0
  347. package/src/cli/pr-cli.ts +30 -2
  348. package/src/cli/pr-land-overlap-evidence.ts +131 -0
  349. package/src/cli/release-cli.ts +53 -11
  350. package/src/cli/self-update.ts +173 -10
  351. package/src/cli/skills-cli.ts +12 -3
  352. package/src/cli/tasks-cli.ts +133 -27
  353. package/src/context-bus/context-first.ts +51 -2
  354. package/src/context-bus/context-now-surfaces.ts +13 -2
  355. package/src/context-bus/long-term-memory.ts +3 -1
  356. package/src/context-bus/nightly-condense.ts +3 -2
  357. package/src/core-turn/run-goal-loop.ts +86 -2
  358. package/src/dashboard/chat-fold.ts +20 -0
  359. package/src/dashboard/first-screen-band.ts +151 -1
  360. package/src/dashboard/index.ts +27 -5
  361. package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -3
  362. package/src/dashboard/stale-install-check.ts +13 -2
  363. package/src/dashboard/turn-stream-formatter.ts +25 -0
  364. package/src/debug/log-diet.ts +159 -0
  365. package/src/debug/log.ts +52 -17
  366. package/src/display/coordinator.ts +25 -2
  367. package/src/domains/coo-admin-tool.ts +27 -0
  368. package/src/domains/cron-match.ts +1 -0
  369. package/src/domains/outbound-alert.ts +17 -6
  370. package/src/domains/release-tool.ts +119 -10
  371. package/src/domains/schedule-registry.ts +10 -7
  372. package/src/domains/schedule-runner.ts +1 -0
  373. package/src/elanous-config-dir.ts +2 -2
  374. package/src/elanous-daemon.ts +3 -3
  375. package/src/execution-loop/launch-gate.ts +1 -1
  376. package/src/expression/i18n/messages.en.ts +5 -0
  377. package/src/expression/i18n/messages.ja.ts +5 -0
  378. package/src/expression/i18n/messages.ko.ts +5 -0
  379. package/src/expression/i18n/messages.zh.ts +5 -0
  380. package/src/expression/i18n/types.ts +8 -0
  381. package/src/github/pr-labels.ts +1 -0
  382. package/src/graph-runner/runner.ts +54 -5
  383. package/src/harness/dispatch-backpressure.ts +259 -0
  384. package/src/harness/harness-cli-command.ts +107 -28
  385. package/src/harness/harness-seams.ts +2 -20
  386. package/src/harness/harness-substrate-default.ts +72 -1
  387. package/src/harness/nested-elanous-policy.ts +4 -2
  388. package/src/hq/fence-wrapper.ts +7 -0
  389. package/src/hq/hq.ts +33 -2
  390. package/src/hq/lease.ts +13 -0
  391. package/src/hq/seats.ts +114 -18
  392. package/src/index.ts +163 -64
  393. package/src/intake-plane/collect-github.ts +19 -1
  394. package/src/intake-plane/digest.ts +45 -20
  395. package/src/intake-plane/lens.ts +36 -8
  396. package/src/intelligence-map/model-alias.ts +6 -0
  397. package/src/intelligence-map/model-catalog.ts +41 -0
  398. package/src/knowledge/kgs/pack.ts +5 -2
  399. package/src/knowledge/kgs/sqlite-store.ts +15 -0
  400. package/src/knowledge/tools/knowledge-query.ts +20 -2
  401. package/src/knowledge/write.ts +234 -2
  402. package/src/llm/bedrock-provider.ts +175 -0
  403. package/src/llm/bedrock.ts +345 -0
  404. package/src/llm/provider-credentials.ts +3 -1
  405. package/src/llm.ts +306 -35
  406. package/src/loops/budget.ts +150 -0
  407. package/src/loops/orchestrator/seat-share.ts +6 -49
  408. package/src/loops/orchestrator/traffic.ts +5 -81
  409. package/src/market/signed-index.ts +42 -0
  410. package/src/mcp/mcp-oauth.ts +136 -17
  411. package/src/model-tier/llm-tier-map.ts +48 -4
  412. package/src/models/prompts.ts +22 -1
  413. package/src/mss/logging/horizon-watch.ts +168 -0
  414. package/src/mss/logging/log-store.ts +204 -15
  415. package/src/native-tool-catalog.ts +1 -1
  416. package/src/nexus/api/consult-requests.ts +7 -10
  417. package/src/nexus/api/discord-trigger-bot.ts +6 -3
  418. package/src/nexus/api/error-reports.ts +30 -8
  419. package/src/nexus/api/http-server.ts +8 -0
  420. package/src/nexus/api/loop-resources.ts +42 -0
  421. package/src/nexus/api/outbound-report.ts +8 -3
  422. package/src/nexus/api/telegram-trigger-bot.ts +6 -3
  423. package/src/nexus/index.ts +10 -0
  424. package/src/nexus/outbound/format.ts +2 -0
  425. package/src/nexus/outbound/router.ts +198 -13
  426. package/src/oauth/codex-account-rotation.ts +16 -18
  427. package/src/oauth/codex-account-store.ts +134 -5
  428. package/src/oauth/fallback-chain.ts +28 -6
  429. package/src/onboarding.ts +2 -1
  430. package/src/plugins/adapters/claude-package.ts +4 -12
  431. package/src/plugins/core/capability-policy.ts +141 -0
  432. package/src/plugins/core/host.ts +21 -8
  433. package/src/plugins/core/manifest.ts +19 -2
  434. package/src/plugins/core/trust-store.ts +15 -0
  435. package/src/plugins/core/types.ts +12 -0
  436. package/src/plugins/install/market-fetch.ts +68 -16
  437. package/src/plugins/install/plugin-install.ts +187 -16
  438. package/src/plugins/maker/plugin-maker.ts +25 -20
  439. package/src/plugins/maker/wizard-generate.ts +16 -2
  440. package/src/policy/llm-policy.ts +14 -1
  441. package/src/process/pid-liveness.ts +1 -1
  442. package/src/prompt-cache/openai.ts +10 -6
  443. package/src/prompt-cache/openrouter.ts +94 -0
  444. package/src/prompt-enhance/enhance.ts +46 -5
  445. package/src/prompt-library/family-prompt-coverage.ts +1 -0
  446. package/src/prompt-library/universal-preamble.ts +2 -2
  447. package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
  448. package/src/registry/loader.ts +6 -1
  449. package/src/release-loop/checklist.ts +24 -9
  450. package/src/release-loop/feature-store.ts +3 -0
  451. package/src/release-loop/gate-shards.ts +48 -4
  452. package/src/release-loop/landed-to-green.ts +81 -0
  453. package/src/release-loop/light-rc.ts +11 -1
  454. package/src/release-loop/merged-pr-checklist.ts +10 -0
  455. package/src/release-loop/placement.ts +91 -22
  456. package/src/release-loop/rehearsal.ts +317 -0
  457. package/src/release-loop/release-schedule.ts +13 -1
  458. package/src/release-loop/rubric-types.ts +1 -0
  459. package/src/release-loop/rubric.ts +2 -2
  460. package/src/retro/daily.ts +23 -9
  461. package/src/seat-loop/seat-loop.ts +34 -1
  462. package/src/seat-loop/traffic-signal.ts +44 -0
  463. package/src/self-dev/ask-launch-flow.ts +2 -2
  464. package/src/self-dev/dev-cli.ts +67 -3
  465. package/src/self-dev/dev-pipeline.ts +4 -6
  466. package/src/self-dev/draft-residue.ts +463 -0
  467. package/src/self-dev/draft-sweep.ts +151 -10
  468. package/src/self-dev/draft-triage-rules.ts +27 -1
  469. package/src/self-dev/launch-preflight-text.ts +549 -0
  470. package/src/self-dev/launch-preflight.ts +10 -545
  471. package/src/self-dev/orchestrate-cli.ts +57 -2
  472. package/src/self-dev/orchestrate-summary-line.ts +13 -0
  473. package/src/self-dev/orchestrate.ts +8 -135
  474. package/src/self-dev/review-provider-fallback.ts +115 -19
  475. package/src/self-dev/run-store.ts +1 -3
  476. package/src/self-dev/run-supervisor.ts +3 -22
  477. package/src/self-dev/run-types.ts +178 -0
  478. package/src/self-dev/shard-aggregate.ts +61 -13
  479. package/src/self-dev/shard-plan.ts +5 -1
  480. package/src/self-dev/shard-run.ts +23 -5
  481. package/src/self-dev/supervisor-verdict-edges.ts +2 -4
  482. package/src/self-implement/blocked-draft-policy.ts +3 -19
  483. package/src/self-implement/draft-on-stop-mode.ts +18 -0
  484. package/src/self-implement/follow-up-goals.ts +114 -38
  485. package/src/self-implement/gate-baseline-reap.ts +157 -0
  486. package/src/self-implement/gate-baseline.ts +78 -16
  487. package/src/self-implement/gate-cli.ts +12 -2
  488. package/src/self-implement/gate-remote.ts +17 -6
  489. package/src/self-implement/goal-author.ts +24 -4
  490. package/src/self-implement/goal-digest.ts +19 -0
  491. package/src/self-implement/graph-overlay-condition.ts +4 -0
  492. package/src/self-implement/headless-elanous-driver.ts +11 -9
  493. package/src/self-implement/host-regate.ts +120 -29
  494. package/src/self-implement/l8-merge-queue.ts +67 -5
  495. package/src/self-implement/merge-train.ts +131 -0
  496. package/src/self-implement/off-diff-evidence.ts +9 -0
  497. package/src/self-implement/orchestrator.ts +133 -16
  498. package/src/self-implement/review-finding-recurrence.ts +28 -0
  499. package/src/self-implement/rework-policy.ts +2 -1
  500. package/src/self-implement/round-summary-card.ts +63 -0
  501. package/src/self-implement/run-ledger.ts +4 -3
  502. package/src/self-implement/run-step-projection.ts +147 -0
  503. package/src/self-implement/run-stop.ts +1 -1
  504. package/src/self-implement/seams.ts +36 -3
  505. package/src/self-implement/self-implement-cli.ts +3 -1
  506. package/src/self-implement/train-gate-remote.ts +158 -0
  507. package/src/session-runtime/index.ts +10 -1
  508. package/src/session-runtime/retry-api.ts +11 -1
  509. package/src/skills/gift-install.ts +119 -0
  510. package/src/skills/runner.ts +59 -2
  511. package/src/skills/skill-feedback.ts +31 -1
  512. package/src/skills/skill-tier.ts +1 -0
  513. package/src/smart-wizard/capability-index.ts +231 -0
  514. package/src/smart-wizard/rung.ts +74 -0
  515. package/src/steward/launch.ts +20 -9
  516. package/src/steward/triage.ts +4 -2
  517. package/src/storage/file-lock.ts +8 -1
  518. package/src/task-agent/actions.ts +4 -0
  519. package/src/task-agent/card-evidence.ts +59 -13
  520. package/src/task-agent/judge.ts +4 -3
  521. package/src/task-agent/land-worktree.ts +201 -0
  522. package/src/task-agent/live-move-history.ts +133 -0
  523. package/src/task-agent/live-moves.ts +106 -19
  524. package/src/task-agent/parent-host.ts +117 -8
  525. package/src/task-agent/rejudge-on-head.ts +297 -0
  526. package/src/task-agent/review-result-capture.ts +218 -0
  527. package/src/task-agent/shadow.ts +103 -7
  528. package/src/task-agent/task-hand.ts +136 -11
  529. package/src/task-orchestrator/surfaces/pod-child-providers.ts +29 -0
  530. package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
  531. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +16 -2
  532. package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
  533. package/src/task-orchestrator/surfaces/pod-lease.ts +93 -12
  534. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +25 -2
  535. package/src/task-orchestrator/surfaces/pod-pool.ts +66 -14
  536. package/src/task-orchestrator/surfaces/self-implement-pod.ts +259 -36
  537. package/src/task-orchestrator/surfaces/self-implement.ts +6 -2
  538. package/src/telegram-service.ts +5 -1
  539. package/src/telegram.ts +17 -4
  540. package/src/time/format.ts +13 -4
  541. package/src/tool-runtime/goal-author-runtime.ts +1 -0
  542. package/src/tool-runtime/self-cognition-catalog.ts +23 -0
  543. package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
  544. package/src/user-config.ts +132 -24
  545. package/src/ux-sim/slash-menu-frames.ts +168 -0
  546. package/src/version/packed-revision.json +1 -1
  547. package/src/web-terminal/preview-tap-registry.ts +5 -2
  548. package/src/workflow-runtime/triggers/scheduler.ts +1 -0
  549. package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
  550. package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
  551. package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
  552. package/apps/pwa/out/_next/static/chunks/1307-08b716476f1d50af.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
  554. package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
  555. package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
  556. package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
  558. package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
  563. package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
  572. package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
  573. package/apps/pwa/out/_next/static/chunks/2489-d238d3e2eb5b2bf5.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
  586. package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/3857-5985236d9307f676.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
  594. package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
  599. package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
  601. package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
  605. package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/5633-d6852385000738ef.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
  610. package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/5977-5b9e8a45a5b0c823.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
  615. package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
  616. package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
  618. package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
  619. package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
  627. package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
  630. package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
  640. package/apps/pwa/out/_next/static/chunks/8857-aa1cc4ac90af4d40.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
  643. package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/9247-55bcfbb0e8057f59.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
  647. package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
  648. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/approvals/page-88459e0903da2803.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d85c43f46f58716b.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/board/page-4e645600579ae952.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/botlab/page-87edbfd19117823b.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/bots/page-7f0c2b7801ac6a54.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/ceo/page-bf1f030a9d1adffd.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/chat/page-cbaf66b1e1804adf.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/control/page-9f5610caaa06178c.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/decisions/page-ec8f3575e339de74.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/design-check/page-86d753e460f1a989.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/editor/page-4166a7d51cf0a57d.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/exec/page-2a19c5cd3b562580.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/field/page-b6a09cde2e07521a.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/inside/page-f7eae1518ca0c353.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/intake/page-456a8573ad811381.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/layout-8462d6a543cbb2d9.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/live/page-2974cdfb87c0f9c9.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f927ffa25f3c86d1.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/loops/page-abd86cd832aaa011.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/market/page-79daf68f6256adaa.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8c3f168fc3f91939.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/morning/page-786fb4504d0f2fa9.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/not-found-75209f14597dcb8f.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/observatory/page-bf30affe3a85af7e.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1187a44b7515434b.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-3d0910185a66ed54.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f401ee1dd5a26e25.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/outputs/page-5dfe7604fd842784.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/page-76cf838050a8d681.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7ec8e289b4c14df6.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-8c8ac17d52be2a79.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/sessions/page-d359ab048d63a9d9.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-b8b345c880bf78d1.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/settings/page-f151cc10ad026940.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9875f103057da433.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/setup/page-9789328af9a9aa62.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/share/page-bf495a1e284f4e00.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/showroom/page-a263d94bca4be22a.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/tasks/page-3962eab8ec58d16e.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/term/page-9abcfac07e02a542.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/today/page-bee49f927c333abb.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/trace/page-bac2d56dcb02d955.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/vault/page-937cbcc13176295c.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d09495594f7f480d.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/workflows/page-69cb93d1a2e57e0e.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/workspace/page-72ec543928d67c3e.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-82906eeda0186a7b.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
  704. package/apps/pwa/out/_next/static/css/f2bd5257e6af88d8.css +0 -1
  705. /package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → rfkMm4movqkqMebBrCXiR}/_ssgManifest.js +0 -0
@@ -17,6 +17,7 @@ import { recordOutbound } from '../../src/domains/outbound-alert.js';
17
17
  import { listSelfDevRuns, runSummaryLine, selfDevRunsDir } from '../../src/self-dev/run-store.js';
18
18
  import { runDraftSweep } from '../../src/self-dev/draft-sweep.js';
19
19
  import { retroBriefingLines } from '../../src/retro/daily.js';
20
+ import { dispatchCooAdmin } from '../../src/domains/coo-admin-tool.js';
20
21
 
21
22
  export type Section<T> = { status: 'ok'; value: T } | { status: 'unreadable'; reason: string };
22
23
  export type Landing = { title: string; seat: string; mergedAt: string; prNumber?: number };
@@ -348,6 +349,47 @@ function sendReview(file: string, text: string, target: { chatId: number; botTok
348
349
  finally { db.close(); }
349
350
  }
350
351
 
352
+ function adminSection(markdown: string): string {
353
+ return markdown.split('## ⑧ 행정\n')[1]?.split('\n\n## ')[0]?.trim() ?? '측정 불가 · 행정 절 없음';
354
+ }
355
+
356
+ function adminMessage(markdown: string): string {
357
+ const text = adminSection(markdown);
358
+ if (text.length <= 1_800) return `## ⑧ 행정\n${text}`;
359
+ // Keep the full ordered read in the report. Reserve one dated link from each required
360
+ // category before spending the remaining transport budget on earlier deadlines.
361
+ const groups: { heading: string; items: string[] }[] = [];
362
+ for (const line of text.split('\n')) {
363
+ if (/^(?:지난 기한|14일 안 기한) \d+건$/.test(line) || line.startsWith('그 밖 · ')) {
364
+ groups.push({ heading: line, items: [] });
365
+ } else if (line.startsWith('- ') && groups.length) {
366
+ groups.at(-1)!.items.push(line);
367
+ } else if (line.startsWith(' https://') && groups.at(-1)?.items.length) {
368
+ const group = groups.at(-1)!;
369
+ group.items[group.items.length - 1] += `\n${line}`;
370
+ }
371
+ }
372
+ if (!groups.some(group => group.heading.startsWith('지난 기한 ')) || !groups.some(group => group.heading.startsWith('14일 안 기한 ')))
373
+ return `## ⑧ 행정\n${text.slice(0, 1_800)}\n… 전체 목록은 리뷰 파일 참조`;
374
+ const compact = (item: string) => item.replace(/^(- [^\n]*? · (?:Urgent|High|우선순위 [^ ·]+) · )([^\n]*?)( · 대표 손이 필요한 날 \d{4}-\d{2}-\d{2})?(\n https:\/\/[^\n]+)$/, (_match, prefix: string, title: string, action: string | undefined, link: string) =>
375
+ `${prefix}${title.length > 90 ? `${title.slice(0, 89)}…` : title}${action ?? ''}${link}`);
376
+ const selected = groups.map(group => ({ heading: group.heading, items: group.items.length ? [compact(group.items[0]!)] : [] }));
377
+ const warning = text.startsWith('조회 상한 250건 ·') ? `${text.split('\n', 1)[0]}\n` : '';
378
+ const render = () => warning + selected.map(group => `${group.heading}\n${group.items.join('\n') || '없음'}`).join('\n');
379
+ const priorityOrder = [...groups.keys()].sort((a, b) =>
380
+ Number(!groups[a]!.heading.startsWith('14일 안 기한 ')) - Number(!groups[b]!.heading.startsWith('14일 안 기한 ')) || a - b);
381
+ for (const i of priorityOrder) {
382
+ const source = groups[i]!;
383
+ for (const item of source.items.slice(selected[i]!.items.length)) {
384
+ const next = compact(item);
385
+ if (render().length + next.length + 1 + '\n… 전체 목록은 리뷰 파일 참조'.length > 1_800) break;
386
+ selected[i]!.items.push(next);
387
+ }
388
+ }
389
+ const omitted = groups.some((group, i) => group.items.length > selected[i]!.items.length);
390
+ return `## ⑧ 행정\n${render()}${omitted ? '\n… 전체 목록은 리뷰 파일 참조' : ''}`;
391
+ }
392
+
351
393
  function newsMessage(markdown: string): string | null {
352
394
  const section = markdown.split('## ⑦ 외부 동향\n')[1]?.split('\n\n## ')[0];
353
395
  if (!section || section.startsWith('못 읽음 ·')) return null;
@@ -366,6 +408,7 @@ function sendNewsAfterReview(delivery: DeliveryResult, file: string, markdown: s
366
408
  export type DailyDeps = { now?: () => Date; root?: string; vaultRoot?: string | null; sendEnabled?: boolean; repoRoot?: string; repoName?: string;
367
409
  landings?: (now: Date) => Promise<Landing[]>; release?: () => Promise<Release>; loops?: () => Promise<Loop[]>;
368
410
  grid?: () => Promise<Seat[]>; decisions?: () => Promise<Pending[]>; news?: () => Promise<News[]>;
411
+ cooAdmin?: (now: Date) => Promise<string>;
369
412
  target?: { chatId: number; botToken: string };
370
413
  send?: (request: DailySendRequest) => DailySendConfirmation | null; receipt?: (key: string) => DeliveryReceipt;
371
414
  recordDelivery?: (text: string, kind: 'ops-report') => void;
@@ -426,7 +469,7 @@ export async function runDaily(options: { dryRun?: boolean; noNews?: boolean; st
426
469
  catch (error) { sendError = `발송 설정 못 읽음 · ${shortReason(reasonOf(error))}`; deliveryState = 'unknown'; }
427
470
  }
428
471
  if (options.stage === 'deliver' && !options.dryRun && enabled) {
429
- const text = `${header}\n\n## 위험 톱 5\n${riskBlock}${suggestionBlock ? `\n\n## PROACT1-LITE 제안\n${suggestionBlock}` : ''}\n\n${file}`;
472
+ const text = `${header}\n\n## 위험 톱 5\n${riskBlock}${suggestionBlock ? `\n\n## PROACT1-LITE 제안\n${suggestionBlock}` : ''}\n\n${adminMessage(markdown)}\n\n${file}`;
430
473
  chars = `${text}\n${receiptKey}`.length;
431
474
  let resolved: ReturnType<typeof recipient> = null;
432
475
  try { resolved = recipient(deps); }
@@ -468,6 +511,12 @@ export async function runDaily(options: { dryRun?: boolean; noNews?: boolean; st
468
511
  news: options.noNews ? unreadable('건너뜀 (--no-news)') : await safe(async () => cleanNews(await (deps.news ?? collectNews)())),
469
512
  };
470
513
  const review = composeDaily(parts, now);
514
+ const readAdmin = deps.cooAdmin ?? ((date: Date) => dispatchCooAdmin({}, { now: date, briefing: true }));
515
+ const admin = await safe(() => readAdmin(now));
516
+ const adminText = admin.status === 'unreadable' ? `측정 불가 · ${admin.reason}`
517
+ : admin.value.startsWith('Linear 키가 없습니다') || admin.value.startsWith('못 읽었습니다(')
518
+ ? `측정 불가 · ${shortReason(admin.value)}` : admin.value;
519
+ review.markdown += `\n## ⑧ 행정\n${adminText}\n`;
471
520
  const root = deps.root ?? effectiveInstanceRoot();
472
521
  const observed = await safe(async (): Promise<ProactSignals> => {
473
522
  if (deps.proactSignals) return deps.proactSignals();
@@ -553,7 +602,7 @@ export async function runDaily(options: { dryRun?: boolean; noNews?: boolean; st
553
602
  let chars = 0;
554
603
  let target = 'unknown';
555
604
  if (!options.dryRun && options.stage !== 'collect' && enabled) {
556
- const text = `${review.header}\n\n## 위험 톱 5\n${review.risks.map((r, i) => `${i + 1}. ${r.name} — ${r.score}점 · ${r.reason}`).join('\n') || '확인된 위험 없음'}${recorded ? `\n\n## PROACT1-LITE 제안\n${recorded}` : ''}${retroBlock}\n\n${file}`;
605
+ const text = `${review.header}\n\n## 위험 톱 5\n${review.risks.map((r, i) => `${i + 1}. ${r.name} — ${r.score}점 · ${r.reason}`).join('\n') || '확인된 위험 없음'}${recorded ? `\n\n## PROACT1-LITE 제안\n${recorded}` : ''}${retroBlock}\n\n${adminMessage(review.markdown)}\n\n${file}`;
557
606
  chars = `${text}\n${receiptKey}`.length;
558
607
  let resolved: ReturnType<typeof recipient> = null;
559
608
  try { resolved = recipient(deps); }
@@ -135,7 +135,8 @@ function compose(parts: WeeklyParts, key: string, now: Date, versions: Section<s
135
135
  `# 주간 미팅 — ${key} (KST)`, header,
136
136
  section('landings', parts.landings, list => {
137
137
  const seats = [...new Set(list.map(i => i.seat))].sort(sortNames).map(s => `${s} ${list.filter(i => i.seat === s).length}`).join(' · ');
138
- return `총 ${list.length}건 · 자리별 ${seats || '없음'}\n발행된 판: ${versions.status === 'ok' ? versions.value.join(', ') || '없음' : `못 읽음 · ${versions.reason}`}`;
138
+ const shown = list.slice(0, 10);
139
+ return `총 ${list.length}건 · 자리별 ${seats || '없음'}\n발행된 판: ${versions.status === 'ok' ? versions.value.join(', ') || '없음' : `못 읽음 · ${versions.reason}`}\n지난주 지표: 착지 ${list.length}건 · 발행 ${versions.status === 'ok' ? `${versions.value.length}판` : `못 읽음 · ${versions.reason}`}\n지난주 착지:\n${shown.map(i => `- ${i.title} (${i.seat} · ${i.mergedAt})`).join('\n') || '없음'}${list.length > shown.length ? `\n외 ${list.length - shown.length}건` : ''}`;
139
140
  }),
140
141
  section('release', parts.release, r => `${r.version}: green ${r.green}/${r.total} · 다음 판 ${r.nextVersion ?? '미정'} ${r.nextGreen ?? '못 읽음'}/${r.nextTotal ?? '못 읽음'} · 다음 컷 ${r.cutAt ?? '미정'}\nred 칸: ${r.red.map(i => i.name).join(', ') || '없음'}`),
141
142
  section('issues', parts.issues, list => list.map(i => `- ${i.id} ${i.title} · ${i.owner} · 기한 ${i.due}`).join('\n') || '열린 현안 없음'),
@@ -226,7 +227,7 @@ export async function runWeekly(options: { dryRun?: boolean; stage?: 'collect' |
226
227
  };
227
228
  const issues = await safe(async () => issueHistory(root));
228
229
  const parts: WeeklyParts = {
229
- landings: await safe(() => deps.landings ? deps.landings(now, { from, to }) : collectLandings(now, { from, to }, { repoRoot: deps.repoRoot, repoName: deps.repoName })),
230
+ landings: await safe(() => deps.landings ? deps.landings(now, { from, to }) : collectLandings(now, { from, to }, { repoRoot: deps.repoRoot, repoName: deps.repoName, stateRoot: root })),
230
231
  release: await safe(deps.release ?? (() => collectWeeklyRelease(now, root))),
231
232
  issues: issues.status === 'ok' ? { status: 'ok', value: [...latest(issues.value).values()].filter(i => i.status === 'open') } : issues,
232
233
  followThrough: issues.status === 'ok' ? { status: 'ok', value: [...new Set([
@@ -0,0 +1,189 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
3
+ import { dirname, join, resolve } from 'node:path';
4
+ import { debug } from '../src/debug/log.js';
5
+ import { effectiveInstanceRoot } from '../src/instance/resolve.js';
6
+ import { GATE_REMOTE_DEFAULTS, isValidGateHost, resolveGateRemoteSettings, runOnRemote, type ExecResult, type RemoteRunOptions, type RemoteRunOutcome } from '../src/self-implement/gate-remote.js';
7
+ import { getUserConfig } from '../src/user-config.js';
8
+ import { parseTypecheckErrors, tscEnv } from '../src/typecheck-ratchet.js';
9
+ import { compareDiagnostics, normalizeDiagnostics, type NormalizedDiagnostic } from './tsc-baseline-comparison.js';
10
+
11
+ const TSC_ARGV = ['bunx', 'tsc', '--noEmit', '-p', 'tsconfig.gate.json', '--incremental', 'false'];
12
+ const COMMIT = /^[0-9a-f]{40}$/i;
13
+ const UNMEASURABLE = /\berror TS(?:2688|5083|6053):/;
14
+
15
+ export interface SafetyNetEntry {
16
+ at: string;
17
+ commit: string;
18
+ outcome: 'clean' | 'added' | 'unmeasured' | 'baseline';
19
+ total: number;
20
+ added: NormalizedDiagnostic[];
21
+ removed: number;
22
+ ms: number;
23
+ host: string;
24
+ /** Full measured snapshot: `added` alone cannot serve as the next day's baseline. */
25
+ diagnostics?: NormalizedDiagnostic[];
26
+ }
27
+
28
+ export interface SafetyNetDeps {
29
+ local?: (cmd: string, args: string[], cwd: string, options?: { env?: NodeJS.ProcessEnv }) => ExecResult;
30
+ remote?: (options: RemoteRunOptions) => RemoteRunOutcome;
31
+ compare?: typeof compareDiagnostics;
32
+ exists?: (path: string) => boolean;
33
+ instanceRoot?: () => string;
34
+ settings?: () => ReturnType<typeof resolveGateRemoteSettings>;
35
+ now?: () => number;
36
+ observed?: (entry: { commit: string; outcome: SafetyNetEntry['outcome']; total: number; added: number; removed: number; ms: number; host: string }) => void;
37
+ }
38
+
39
+ const realLocal: NonNullable<SafetyNetDeps['local']> = (cmd, args, cwd, options) => {
40
+ const result = spawnSync(cmd, args, { cwd, encoding: 'utf8', maxBuffer: 64 * 1024 * 1024, ...(options?.env ? { env: options.env } : {}) });
41
+ return { rc: result.status, stdout: result.stdout ?? '', stderr: result.stderr ?? '', ...(result.error ? { error: String(result.error) } : {}) };
42
+ };
43
+
44
+ function flags(argv: readonly string[]): { local: boolean; host?: string; ledger?: string; json: boolean } {
45
+ let local = false;
46
+ let host: string | undefined;
47
+ let ledger: string | undefined;
48
+ let json = false;
49
+ for (let i = 0; i < argv.length; i++) {
50
+ const arg = argv[i];
51
+ if (arg === '--local') local = true;
52
+ else if (arg === '--json') json = true;
53
+ else if (arg === '--remote' || arg === '--ledger') {
54
+ const value = argv[++i];
55
+ if (!value || value.startsWith('--')) throw new Error(`${arg} requires a value`);
56
+ if (arg === '--remote') host = value;
57
+ else ledger = value;
58
+ } else throw new Error(`unknown argument: ${arg}`);
59
+ }
60
+ if (local && host) throw new Error('--local and --remote cannot be combined');
61
+ if (host && !isValidGateHost(host)) throw new Error(`invalid --remote host: ${host}`);
62
+ return { local, host, ledger, json };
63
+ }
64
+
65
+ function measuredSnapshot(path: string): NormalizedDiagnostic[] | undefined {
66
+ if (!existsSync(path)) return undefined;
67
+ const rows = readFileSync(path, 'utf8').trim().split('\n').filter(Boolean);
68
+ for (let i = rows.length - 1; i >= 0; i--) {
69
+ const entry = JSON.parse(rows[i]!) as SafetyNetEntry;
70
+ if (entry.outcome === 'unmeasured') continue;
71
+ if (!Array.isArray(entry.diagnostics) || !entry.diagnostics.every((d) => d && typeof d.file === 'string' && typeof d.code === 'string' && typeof d.message === 'string')) {
72
+ throw new Error('last measured ledger entry has no valid diagnostic snapshot');
73
+ }
74
+ return entry.diagnostics;
75
+ }
76
+ return undefined;
77
+ }
78
+
79
+ function diagnosticsOf(result: { rc: number | null; stdout: string; stderr: string; error?: string }, root: string): NormalizedDiagnostic[] | undefined {
80
+ const output = `${result.stdout}\n${result.stderr}`;
81
+ if (result.error || result.rc === null || (result.rc !== 0 && result.rc !== 1 && result.rc !== 2) || UNMEASURABLE.test(output)
82
+ || /heap out of memory|Ineffective mark-compacts near heap limit/i.test(output)) return undefined;
83
+ const parsed = parseTypecheckErrors(output);
84
+ const errorLines = output.split(/\r?\n/).filter((line) => /\berror TS\d+:/.test(line));
85
+ if (parsed.length !== errorLines.length || (result.rc === 0 && errorLines.length > 0) || (result.rc !== 0 && parsed.length === 0)) return undefined;
86
+ if (output.split(/\r?\n/).some((line) => line.trim() && !/^.+\(\d+,\d+\):\s+error\s+TS\d+:/.test(line) && !/^\s+/.test(line)
87
+ && !/^Found \d+ errors?\.?$/.test(line))) return undefined;
88
+ return normalizeDiagnostics(parsed, root);
89
+ }
90
+
91
+ export async function runSafetyNet(repo: string, argv: readonly string[] = [], deps: SafetyNetDeps = {}): Promise<{ exitCode: number; entry: SafetyNetEntry; json: boolean }> {
92
+ const input = flags(argv);
93
+ const run = deps.local ?? realLocal;
94
+ const remote = deps.remote ?? runOnRemote;
95
+ const exists = deps.exists ?? existsSync;
96
+ const root = deps.instanceRoot?.() ?? effectiveInstanceRoot();
97
+ const settings = deps.settings?.() ?? (input.local ? GATE_REMOTE_DEFAULTS : resolveGateRemoteSettings(getUserConfig().gateRemote));
98
+ const host = input.local ? 'local' : (input.host ?? settings.host ?? GATE_REMOTE_DEFAULTS.host);
99
+ if (host !== 'local' && !isValidGateHost(host)) throw new Error(`invalid gateRemote host: ${host}`);
100
+ const ledger = resolve(input.ledger ?? join(root, 'tsc-safety-net', 'ledger.jsonl'));
101
+ const worktree = join(root, 'tsc-safety-net', 'worktree');
102
+ const started = (deps.now ?? Date.now)();
103
+ let commit = '';
104
+ let diagnostics: NormalizedDiagnostic[] | undefined;
105
+ let reason: string | undefined;
106
+ let dependencyFailed = false;
107
+ const git = (args: string[], cwd: string): ExecResult => {
108
+ const env = { ...process.env };
109
+ delete env.GIT_DIR; delete env.GIT_WORK_TREE; delete env.GIT_COMMON_DIR;
110
+ return run('git', args, cwd, { env });
111
+ };
112
+ const checked = (args: string[], cwd: string): ExecResult => {
113
+ const result = git(args, cwd);
114
+ if (result.error || result.rc !== 0) throw new Error(`git ${args.join(' ')}: ${result.error ?? result.stderr ?? `rc=${result.rc}`}`);
115
+ return result;
116
+ };
117
+ try {
118
+ checked(['fetch', 'origin', '+refs/heads/main:refs/remotes/origin/main'], repo);
119
+ commit = checked(['rev-parse', '--verify', 'origin/main^{commit}'], repo).stdout.trim();
120
+ if (!COMMIT.test(commit)) throw new Error('origin/main did not resolve to a commit');
121
+ if (!exists(worktree)) {
122
+ mkdirSync(dirname(worktree), { recursive: true });
123
+ checked(['worktree', 'add', '--detach', worktree, commit], repo);
124
+ } else {
125
+ const listed = checked(['worktree', 'list', '--porcelain'], repo).stdout;
126
+ if (!listed.split('\n').some((line) => line === `worktree ${worktree}`)) throw new Error('worktree path is not a registered git worktree');
127
+ }
128
+ const status = checked(['status', '--porcelain'], worktree).stdout;
129
+ if (status.trim()) checked(['reset', '--hard'], worktree);
130
+ // Porcelain status omits ignored files, including stale .ts files from a previous measurement.
131
+ checked(['clean', '-fdx', '-e', 'node_modules'], worktree);
132
+ checked(['checkout', '--detach', 'origin/main'], worktree);
133
+ if (checked(['rev-parse', 'HEAD'], worktree).stdout.trim() !== commit || checked(['status', '--porcelain'], worktree).stdout.trim()) throw new Error('worktree is not clean at origin/main');
134
+ if (input.local) {
135
+ // The retained node_modules may belong to yesterday's lockfile; frozen install reconciles it to this checkout.
136
+ dependencyFailed = true;
137
+ const install = run('bun', ['install', '--frozen-lockfile'], worktree);
138
+ if (install.rc !== 0 || install.error || !exists(join(worktree, 'node_modules'))) {
139
+ throw new Error(`local dependencies unavailable: ${install.error ?? install.stderr ?? `rc=${install.rc}`}`);
140
+ }
141
+ dependencyFailed = false;
142
+ const result = run(TSC_ARGV[0]!, TSC_ARGV.slice(1), worktree, { env: tscEnv() });
143
+ diagnostics = diagnosticsOf(result, worktree);
144
+ if (!diagnostics) reason = 'local tsc did not produce a complete measurement';
145
+ } else {
146
+ const result = remote({ repo: worktree, host, mirror: settings.mirror, hostCap: settings.hostCap, argv: TSC_ARGV });
147
+ if (result.kind === 'ran') {
148
+ if (result.commit !== commit) throw new Error('remote measured a different commit');
149
+ diagnostics = diagnosticsOf({ rc: result.rc, stdout: result.stdout.toString('utf8'), stderr: result.stderr.toString('utf8') }, worktree);
150
+ if (!diagnostics) reason = 'remote tsc did not produce a complete measurement';
151
+ } else reason = result.kind === 'busy' ? 'remote busy' : `remote infra: ${result.reason}`;
152
+ }
153
+ } catch (error) {
154
+ reason = error instanceof Error ? error.message : String(error);
155
+ }
156
+ let previous: NormalizedDiagnostic[] | undefined;
157
+ try { previous = measuredSnapshot(ledger); }
158
+ catch (error) { diagnostics = undefined; reason = `ledger unreadable: ${error instanceof Error ? error.message : String(error)}`; }
159
+ const comparison = diagnostics && previous ? (deps.compare ?? compareDiagnostics)(diagnostics, previous) : undefined;
160
+ if (comparison?.kind === 'unavailable') reason = `comparison unavailable: ${comparison.reason}`;
161
+ const outcome: SafetyNetEntry['outcome'] = !diagnostics || comparison?.kind === 'unavailable'
162
+ ? 'unmeasured' : !previous ? 'baseline' : comparison?.kind === 'added' ? 'added' : 'clean';
163
+ const entry: SafetyNetEntry = {
164
+ at: new Date((deps.now ?? Date.now)()).toISOString(), commit, outcome, total: diagnostics?.length ?? 0,
165
+ added: comparison && comparison.kind !== 'unavailable' ? comparison.added : [],
166
+ removed: comparison && comparison.kind !== 'unavailable' ? comparison.removed.length : 0,
167
+ ms: (deps.now ?? Date.now)() - started, host,
168
+ ...(outcome !== 'unmeasured' && diagnostics ? { diagnostics } : {}),
169
+ };
170
+ if (!dependencyFailed) {
171
+ mkdirSync(dirname(ledger), { recursive: true });
172
+ appendFileSync(ledger, `${JSON.stringify(entry)}\n`);
173
+ }
174
+ const observation = { commit, outcome, total: entry.total, added: entry.added.length, removed: entry.removed, ms: entry.ms, host };
175
+ (deps.observed ?? ((data) => debug.log('tsc.safety-net', 'run', data)))(observation);
176
+ if (reason) console.error(`[tsc.safety-net] ${reason}`);
177
+ return { exitCode: outcome === 'unmeasured' ? 2 : outcome === 'added' ? 1 : 0, entry, json: input.json };
178
+ }
179
+
180
+ if (import.meta.main) {
181
+ try {
182
+ const result = await runSafetyNet(process.cwd(), process.argv.slice(2));
183
+ console.log(result.json ? JSON.stringify(result.entry) : `[tsc.safety-net] ${result.entry.outcome} commit=${result.entry.commit} total=${result.entry.total} added=${result.entry.added.length} removed=${result.entry.removed} host=${result.entry.host}`);
184
+ process.exitCode = result.exitCode;
185
+ } catch (error) {
186
+ console.error(`[tsc.safety-net] unmeasured: ${error instanceof Error ? error.message : String(error)}`);
187
+ process.exitCode = 2;
188
+ }
189
+ }
@@ -2,14 +2,14 @@
2
2
  // 실행 칸(Pod 등)이 사라지기 «전»에 자기 llm.usage 를 한 줄로 요약해 stdout 에 — 슈퍼바이저가 호스트로 가져간다.
3
3
  // RFC-fleet-supervisor-substrates-benchmark-and-token-accounting §A2·F2 · 2026-09-25.
4
4
  // bun scripts/usage-rollup.ts [--since 6h]
5
- // 출력: ELANOUS_USAGE_ROLLUP {"substrate","runId","armId","truncated","rows":[{site,provider,model,calls,inputTokens,outputTokens,cacheReadInputTokens,usdKnown,unknownCostCalls}],"total":{…}}
5
+ // 출력: ELANOUS_USAGE_ROLLUP {"substrate","runId","armId","truncated","rows":[{site,provider,model,calls,inputTokens,outputTokens,cacheReadInputTokens,cacheCreationInputTokens,usdKnown,unknownCostCalls}],"total":{…}}
6
6
  // ⛔ 의존성 없음(설치본 `elanous` 만 부른다) — clone 에 node_modules 가 없어도 돈다.
7
7
  // ⛔ 비용을 모르는 호출(cost.kind≠known)은 0 으로 합치지 않고 따로 센다.
8
8
  // ⛔ `--all --include-test` 로 «그 기계의 모든 우주»를 읽는다 — Pod(자기 스토어뿐)에서는 그것이 곧 그 칸의 사용량이지만,
9
9
  // 호스트(맥)에서 돌리면 테스트 우주·워크트리·다른 트랙의 런까지 섞인다(📏 09-25: 운영만 16회 vs 전체 124회). 호스트 집계용이 아니다.
10
10
  import { spawnSync } from 'node:child_process';
11
11
 
12
- export interface UsageRow { site: string; provider: string; model: string; calls: number; inputTokens: number; outputTokens: number; cacheReadInputTokens: number; usdKnown: number; unknownCostCalls: number; includedCalls: number; apiEquivalentUsd: number }
12
+ export interface UsageRow { site: string; provider: string; model: string; calls: number; inputTokens: number; outputTokens: number; cacheReadInputTokens: number; cacheCreationInputTokens: number; cacheCreationUnmeasuredCalls: number; usdKnown: number; unknownCostCalls: number; includedCalls: number; apiEquivalentUsd: number }
13
13
 
14
14
  export function rollup(lines: readonly string[]): { rows: UsageRow[]; truncated: boolean } {
15
15
  const by = new Map<string, UsageRow>();
@@ -20,14 +20,18 @@ export function rollup(lines: readonly string[]): { rows: UsageRow[]; truncated:
20
20
  let r: { event?: string; data?: Record<string, unknown> };
21
21
  try { r = JSON.parse(line); } catch { continue; }
22
22
  if (r.event !== 'llm-usage' || !r.data) continue;
23
- const d = r.data as { site?: string; provider?: string; billingProvider?: string; model?: string; inputTokens?: number; outputTokens?: number; cacheReadInputTokens?: number; cost?: { kind?: string; usd?: number } };
23
+ const d = r.data as { site?: string; provider?: string; billingProvider?: string; model?: string; inputTokens?: number; outputTokens?: number; cacheReadInputTokens?: number; cacheCreationInputTokens?: number; cost?: { kind?: string; usd?: number } };
24
24
  const provider = d.billingProvider ?? d.provider ?? '?'; // ⭐ 과금 주체 우선(B10)
25
25
  const key = `${d.site ?? '?'}|${provider}|${d.model ?? '?'}`;
26
- const row = by.get(key) ?? { site: d.site ?? '?', provider, model: d.model ?? '?', calls: 0, inputTokens: 0, outputTokens: 0, cacheReadInputTokens: 0, usdKnown: 0, unknownCostCalls: 0, includedCalls: 0, apiEquivalentUsd: 0 };
26
+ const row = by.get(key) ?? { site: d.site ?? '?', provider, model: d.model ?? '?', calls: 0, inputTokens: 0, outputTokens: 0, cacheReadInputTokens: 0, cacheCreationInputTokens: 0, cacheCreationUnmeasuredCalls: 0, usdKnown: 0, unknownCostCalls: 0, includedCalls: 0, apiEquivalentUsd: 0 };
27
27
  row.calls++;
28
28
  row.inputTokens += Number(d.inputTokens ?? 0);
29
29
  row.outputTokens += Number(d.outputTokens ?? 0);
30
30
  row.cacheReadInputTokens += Number(d.cacheReadInputTokens ?? 0);
31
+ // ⭐ 캐시 «쓰기»(Anthropic cache_creation_input_tokens) — 빠지면 호스트 원장이 0 으로 보고 재매김 $ 가 쓰기 비용을 잃는다.
32
+ row.cacheCreationInputTokens += Number(d.cacheCreationInputTokens ?? 0);
33
+ // 캐시 읽기는 보고했는데 쓰기 칸이 없는 호출은 쓰기량을 «모른다» — 0 으로 접지 않고 따로 센다(호스트 재매김이 이 수를 보고 멈춘다).
34
+ if (d.cacheReadInputTokens !== undefined && d.cacheCreationInputTokens === undefined) row.cacheCreationUnmeasuredCalls++;
31
35
  // ⛔ «모름»을 0 으로 접지 않는다 — partial 의 «알려진 몫»은 더하고, 모르는 호출은 따로 센다(BACKLOG C5).
32
36
  // ⭐ 구독·local(`included`)은 청구 0 이고 «모름»이 아니다 — 따로 세고 API 환산가는 별도 합(BACKLOG C6).
33
37
  if (d.cost?.kind === 'included') { row.includedCalls++; if (typeof (d.cost as { apiEquivalentUsd?: number }).apiEquivalentUsd === 'number') row.apiEquivalentUsd += (d.cost as { apiEquivalentUsd: number }).apiEquivalentUsd; }
@@ -15,7 +15,7 @@
15
15
  // installations don't churn quickly and a BackendPickerChip re-render
16
16
  // should not trigger a fresh RPC roundtrip every time.
17
17
 
18
- import type { CodexAppServerClient } from './codex-app-server-client.js';
18
+ import { spawnCodexAppServer, type CodexAppServerClient } from './codex-app-server-client.js';
19
19
 
20
20
  export interface CodexPlugin {
21
21
  /** Plugin slug as reported by codex (e.g. "gmail", "google-calendar"). */
@@ -43,13 +43,55 @@ export interface FetchCodexPluginsOpts {
43
43
  noCache?: boolean;
44
44
  }
45
45
 
46
+ /** Uncached inventory probe: distinguish no session / RPC failure from an empty installed list. */
47
+ export async function readCodexPluginsObservation(client: CodexAppServerClient | null | undefined): Promise<
48
+ { status: 'ok'; plugins: ReadonlyArray<CodexPlugin> } | { status: 'unknown'; plugins: readonly [] }
49
+ > {
50
+ if (!client) return { status: 'unknown', plugins: [] };
51
+ try {
52
+ const response = await client.request<Record<string, never>, unknown>('plugin/list', {});
53
+ if (!isWellFormedPluginList(response)) return { status: 'unknown', plugins: [] };
54
+ return { status: 'ok', plugins: parseCodexPluginsResponse(response) };
55
+ } catch { return { status: 'unknown', plugins: [] }; }
56
+ }
57
+
58
+ /** Every marketplace and plugin row must have the shape the projector reads; a damaged or changed
59
+ * RPC response is unknown, never a confirmed empty install list. */
60
+ function isWellFormedPluginList(response: unknown): boolean {
61
+ if (!response || typeof response !== 'object') return false;
62
+ const marketplaces = (response as { marketplaces?: unknown }).marketplaces;
63
+ if (!Array.isArray(marketplaces)) return false;
64
+ return marketplaces.every(market => !!market && typeof market === 'object'
65
+ && typeof (market as { name?: unknown }).name === 'string' && (market as { name: string }).name.length > 0
66
+ && Array.isArray((market as { plugins?: unknown }).plugins)
67
+ && ((market as { plugins: unknown[] }).plugins).every(plugin => !!plugin && typeof plugin === 'object'
68
+ && typeof (plugin as { name?: unknown }).name === 'string' && (plugin as { name: string }).name.length > 0));
69
+ }
70
+
71
+ export type CodexPluginObservation = Awaited<ReturnType<typeof readCodexPluginsObservation>>;
72
+
73
+ /** Isolated read-only RPC probe; always closes its own app-server process. */
74
+ export async function readCodexPluginsFromAppServer(
75
+ spawn: typeof spawnCodexAppServer = spawnCodexAppServer,
76
+ ): Promise<CodexPluginObservation> {
77
+ let server: ReturnType<typeof spawnCodexAppServer>;
78
+ try { server = spawn({ requestTimeoutMs: 5000 }); }
79
+ catch { return { status: 'unknown', plugins: [] }; }
80
+ try {
81
+ await server.client.request('initialize', {
82
+ clientInfo: { name: 'elanous', version: '0.x' }, capabilities: { experimentalApi: true },
83
+ });
84
+ return await readCodexPluginsObservation(server.client);
85
+ } catch { return { status: 'unknown', plugins: [] }; }
86
+ finally {
87
+ try { await server.client.close(); }
88
+ finally { server.child.kill(); }
89
+ }
90
+ }
91
+
46
92
  /** Query codex `plugin/list` and project the response into the
47
93
  * BackendPickerChip-ready shape. Cached per client for 5 min.
48
- *
49
- * Returns an empty array when:
50
- * - `client` is null/undefined (no active codex session)
51
- * - the RPC throws (timeout / closed / codex error) — soft-fail
52
- * with stale cache if available, otherwise [] */
94
+ * Returns [] for no client or RPC failure (stale cache when available). */
53
95
  export async function fetchCodexPlugins(
54
96
  client: CodexAppServerClient | null | undefined,
55
97
  opts: FetchCodexPluginsOpts = {},
@@ -16,7 +16,7 @@
16
16
 
17
17
  import { existsSync } from 'node:fs';
18
18
  import type { UserConfig } from '../user-config.js';
19
- import { runTurn } from '../session/chat.js';
19
+ import { runTurn, type RunTurnOpts } from '../session/chat.js';
20
20
  import type { SessionSource } from '../session/index.js';
21
21
  import { buildContinuationAgentTools } from '../dispatch/continuation-turn-runner.js';
22
22
  import { buildTerminalCapableTurn } from './terminal-surface.js';
@@ -56,6 +56,54 @@ function recentSentContext(): string {
56
56
  } catch { return ''; }
57
57
  }
58
58
 
59
+ interface ToolRun { id: string; name: string; result?: unknown }
60
+
61
+ const TOOL_RESULT_CLIP_CHARS = 1500;
62
+ const TOOL_RESULT_MAX_RUNS = 12;
63
+
64
+ function clipToolResult(result: unknown): string {
65
+ if (result === undefined) return '(결과 없음)';
66
+ let text: string;
67
+ try { text = typeof result === 'string' ? result : JSON.stringify(result) ?? String(result); } catch { text = String(result); }
68
+ return text.length > TOOL_RESULT_CLIP_CHARS ? `${text.slice(0, TOOL_RESULT_CLIP_CHARS)}…` : text;
69
+ }
70
+
71
+ /** 툴만 부르고 최종 텍스트가 빈 턴 — 관측을 남기고 툴 결과 요약 재턴을 한 번 돌린다. 재턴도 비면 바닥줄이 아니라
72
+ * 실패 문구를 돌려준다. 세션 재생은 role:'tool' 기록을 빼므로 재턴 프롬프트가 툴 결과를 직접 싣는다. */
73
+ async function recoverEmptyAnswer(args: {
74
+ runTurnImpl: typeof runTurn;
75
+ opts: RunTurnOpts;
76
+ llmOpts: RunTurnOpts['llmOpts'];
77
+ systemPrompt: string;
78
+ toolRuns: ToolRun[];
79
+ surface: SessionSource;
80
+ }): Promise<string> {
81
+ const { runTurnImpl, opts, llmOpts, systemPrompt, toolRuns, surface } = args;
82
+ let message = '';
83
+ let sawToolCall = false;
84
+ let retryText = '';
85
+ try {
86
+ const summary = toolRuns.slice(-TOOL_RESULT_MAX_RUNS)
87
+ .map((run) => `- ${run.name}: ${clipToolResult(run.result)}`).join('\n');
88
+ const retry = await runTurnImpl({
89
+ ...opts,
90
+ userText: `[툴 결과 요약 재턴] 아래 툴 실행 결과를 근거로 사용자 질문에 대한 최종 답을 텍스트로 작성하세요. 툴은 더 부르지 마세요.\n\n사용자 질문: ${opts.userText}\n\n툴 결과:\n${summary}`,
91
+ onDelta: (delta) => { message += delta; },
92
+ onToolCall: () => { message = ''; sawToolCall = true; },
93
+ onToolResult: () => {},
94
+ skipMemoryInjection: true,
95
+ llmOpts,
96
+ systemPrompt,
97
+ tools: [],
98
+ });
99
+ retryText = (sawToolCall ? message : retry.text)?.trim() ?? '';
100
+ } catch { /* 재턴 실패는 아래 실패 문구로 */ }
101
+ debug.log('agent.turn', 'empty-answer', {
102
+ surface, sessionId: opts.sessionId, toolCalls: toolRuns.length, recovered: retryText !== '',
103
+ });
104
+ return retryText || `⚠️ 답을 만들지 못했다 — 툴 ${toolRuns.length}개 실행`;
105
+ }
106
+
59
107
  /** Build the tool-enabled elanous self runTurn for a messenger surface:
60
108
  * the full agent tool surface (Read/Grep/Glob/ListDir/Edit/Write +
61
109
  * Bash + PtyShell + search), plus — when the finance domain pack is
@@ -229,6 +277,8 @@ export function makeElanousAgentRunTurn(cfg: UserConfig, surface: SessionSource,
229
277
  llmOpts = terminal.llmOpts;
230
278
  let currentMessage = '';
231
279
  let sawToolCall = false;
280
+ const toolRuns: ToolRun[] = [];
281
+ const systemPrompt = terminal.systemPromptParts.join('\n\n');
232
282
  return runTurnImpl({
233
283
  ...opts,
234
284
  onDelta: (delta) => {
@@ -238,21 +288,33 @@ export function makeElanousAgentRunTurn(cfg: UserConfig, surface: SessionSource,
238
288
  onToolCall: (call) => {
239
289
  currentMessage = '';
240
290
  sawToolCall = true;
291
+ toolRuns.push({ id: call.id, name: call.name });
241
292
  opts.onToolCall?.(call);
242
293
  },
294
+ onToolResult: (call) => {
295
+ const run = toolRuns.find((candidate) => candidate.id === call.id);
296
+ if (run) run.result = call.result;
297
+ opts.onToolResult?.(call);
298
+ },
243
299
  llmOpts,
244
- systemPrompt: terminal.systemPromptParts.join('\n\n'),
300
+ systemPrompt,
245
301
  tools: terminal.specs,
246
302
  dispatchTool: terminal.dispatch,
247
- }).then((result) => {
303
+ }).then(async (result) => {
248
304
  // /cancel self-awareness — when the turn was aborted mid-run (user hit
249
305
  // `/cancel`), the tool loop returns with little/no final text. Substitute
250
306
  // a CLEAR cancellation marker so (a) the user gets an ack, and (b) it is
251
307
  // the text recorded to cross-surface memory (recordInboundTurn) — so the
252
308
  // NEXT turn's memory_recall knows the task was CANCELLED, not silently
253
309
  // dropped or still running. Only turnAbort (=/cancel) aborts this signal.
254
- const wasAborted = opts.signal?.aborted === true;
255
- const answer = sawToolCall ? currentMessage.trim() : result.text;
310
+ let wasAborted = opts.signal?.aborted === true;
311
+ let answer = sawToolCall ? currentMessage.trim() : result.text;
312
+ // Telegram only: other messenger surfaces (Discord …) keep their current final-answer behaviour.
313
+ if (!wasAborted && sawToolCall && !answer && surface === 'telegram') {
314
+ answer = await recoverEmptyAnswer({ runTurnImpl, opts, llmOpts, systemPrompt, toolRuns, surface });
315
+ // A /cancel that lands during the retry turn still wins over the retry answer or the failure sentence.
316
+ if (opts.signal?.aborted === true) { wasAborted = true; answer = ''; }
317
+ }
256
318
  const responseText = wasAborted
257
319
  ? (answer?.trim()
258
320
  ? `${answer}\n\n⏹️ 이 작업은 /cancel 로 취소되었습니다 (실행 중이던 Bash/PTY 종료됨).`
@@ -9,6 +9,7 @@
9
9
 
10
10
  import { normalizeChildLlmProvider } from '../self-dev/dev-cli.js';
11
11
  import { providerEnvKey } from '../llm/provider-credentials.js';
12
+ import { bedrockChildRelayEnv } from '../llm/bedrock.js';
12
13
 
13
14
  export type RunContext = 'production' | 'benchmark' | 'simulator' | 'self-build';
14
15
 
@@ -78,6 +79,12 @@ function childLocalEndpointEnv(provider: string): Record<string, string> {
78
79
  return url ? { LOCAL_LLM_URL: url } : {};
79
80
  }
80
81
 
82
+ /** BEDROCK-PROVIDER — Bedrock 자격은 «파일»(~/.aws · HOME 으로 자식이 그대로 읽는다)과 «env»(AWS_*) 둘 다에 산다.
83
+ * env 쪽은 replace env 라 상속이 없으므로 이름 목록대로 릴레이한다(값은 싣기만 하고 어디에도 찍지 않는다). */
84
+ function childBedrockEnv(provider: string): Record<string, string> {
85
+ return provider === 'bedrock' ? bedrockChildRelayEnv() : {};
86
+ }
87
+
81
88
  /** The family classifier is model-id based, so preserve local-provider identity
82
89
  * across the replace-env child boundary without changing non-local model IDs. */
83
90
  function childRelayModel(provider: string, model: string): string {
@@ -102,6 +109,7 @@ export function childLlmSelectionEnv(selection?: ChildLlmSelection): Record<stri
102
109
  ...(selection.effort ? { ELANOUS_ESCALATE_EFFORT: selection.effort } : {}),
103
110
  ...childProviderKeyEnv(provider),
104
111
  ...childLocalEndpointEnv(provider),
112
+ ...childBedrockEnv(provider),
105
113
  };
106
114
  }
107
115
  // ⛔⭐ 상속 갈래도 local 이면 «주소»를 같이 넘긴다(BACKLOG B12 · 2026-09-25).
@@ -112,5 +120,7 @@ export function childLlmSelectionEnv(selection?: ChildLlmSelection): Record<stri
112
120
  ...(process.env.ELANOUS_LLM_PROVIDER !== undefined ? { ELANOUS_LLM_PROVIDER: process.env.ELANOUS_LLM_PROVIDER } : {}),
113
121
  ...(process.env.ELANOUS_LLM_MODEL !== undefined ? { ELANOUS_LLM_MODEL: process.env.ELANOUS_LLM_MODEL } : {}),
114
122
  ...(inheritedProvider ? childLocalEndpointEnv(inheritedProvider) : {}),
123
+ // 상속 갈래도 bedrock 이면 AWS_* 를 같이 넘긴다(명시 갈래와 같은 규칙 — replace env 라 자동 상속이 없다).
124
+ ...(inheritedProvider ? childBedrockEnv(inheritedProvider) : {}),
115
125
  };
116
126
  }
@@ -15,11 +15,27 @@
15
15
  // ELANOUS_CHILD_TOOL_PROFILE=full 전부
16
16
  // ELANOUS_CHILD_TOOL_PROFILE=finance,ops 기본 ⊕ 고른 묶음
17
17
  // (없음) coding(기본)
18
+ //
19
+ // 🩸 CHILD-TOOL-PROFILE-TRIM(10-10 실측 · base 0317d73034 · Plan 켬): `coding` 이 33개 중 27개(스키마 26,742자)를
20
+ // 남겼다 — 판·자리 운영·회수·스킬·서브에이전트 도구가 «어느 묶음에도 안 들어서» 기본으로 갔을 뿐이다.
21
+ // ⇒ 화이트리스트를 따로 두지 않고(09-25 설계 유지) 그것들을 새 묶음 넷(admin · recall · skills · subagent)으로 옮긴다.
22
+ // ⇒ `coding` 의 기대 집합 = Read · Grep · Glob · ListDir · Edit · Write · Bash · Plan · MarkStepDone(9개).
23
+ // 빠진 묶음은 상황 신호(골 문면)와 ToolSearch(전체 목록에서 찾는다)로 계속 닿는다.
24
+
25
+ import { debug } from '../debug/log.js';
18
26
 
19
27
  /** 추가 묶음 — 코딩 기본에서 빠지고 «고르면 더해지는» 도구들. 접두 ⊕ 정확한 이름. */
20
28
  export const TOOL_EXTRA_GROUPS = {
21
29
  finance: { prefixes: ['finance_', 'conatus_'], names: [] as string[] },
22
30
  ops: { prefixes: [] as string[], names: ['schedule_manage', 'session_manage', 'autopilot_missions', 'ops_status', 'se_build', 'mission_decide'] },
31
+ /** 판·자리·결정 운영 — 코딩 일에는 안 쓴다. */
32
+ admin: { prefixes: ['release_'], names: ['coo_admin', 'ops_seats', 'decisions_pending', 'proact_meter'] },
33
+ /** 기억·회수·관측 조회. */
34
+ recall: { prefixes: [] as string[], names: ['memory_recall', 'fact_check', 'self_recall', 'context_now', 'logs_query'] },
35
+ /** 스킬 목록·실행. */
36
+ skills: { prefixes: [] as string[], names: ['elanous_skills_list', 'skill_exec'] },
37
+ /** 서브에이전트 — ⚠️ 기본에서 빼도 완주율이 안 떨어지는지는 아직 안 쟀다(SMALL-MODEL-BENCH 가 잰다). 신호·ToolSearch 로 되살린다. */
38
+ subagent: { prefixes: [] as string[], names: ['Agent', 'AgentOutput', 'AgentReply', 'AgentStop', 'AgentList'] },
23
39
  } as const;
24
40
  export type ToolExtraGroup = keyof typeof TOOL_EXTRA_GROUPS;
25
41
  const ALL_GROUPS = Object.keys(TOOL_EXTRA_GROUPS) as ToolExtraGroup[];
@@ -45,6 +61,10 @@ export function activeToolProfile(env: NodeJS.ProcessEnv = process.env): ToolPro
45
61
  export const SITUATIONAL_GROUP_SIGNALS: Record<ToolExtraGroup, RegExp> = {
46
62
  finance: /금융|주식|종목|주가|시세|매매|포트폴리오|포지션|투자|백테스트|13F|재무|finance_|conatus|stock|ticker|portfolio|backtest|trading/i,
47
63
  ops: /스케줄|크론|예약 실행|오토파일럿|미션 결정|운영 상태|schedule_manage|autopilot|ops_status|mission_decide|cron/i,
64
+ admin: /release_(status|change)|coo_admin|ops_seats|decisions_pending|proact_meter|판 칸|칸 근거|칸 상태|체크리스트 칸|checklist (set|status)|결정 대기|자리 현황/i,
65
+ recall: /memory_recall|fact_check|self_recall|context_now|logs_query|기억 조회|기억을 (찾|조회|회수)|자기 이력|사실 확인|팩트 ?체크/i,
66
+ skills: /elanous_skills_list|skill_exec|스킬(을)? 실행|스킬 목록|run (a|the) skill/i,
67
+ subagent: /서브\s?에이전트|하위\s?에이전트|sub-?agents?|에이전트를 (띄|병렬)|병렬 에이전트|Agent(Output|Reply|Stop|List)\b|Agent 도구/i,
48
68
  };
49
69
 
50
70
  export function situationalToolGroups(goalText: string | undefined): ToolExtraGroup[] {
@@ -58,9 +78,15 @@ export function situationalToolGroups(goalText: string | undefined): ToolExtraGr
58
78
  * ③ 둘 다 없으면 `coding`(다이어트) */
59
79
  export function childToolProfile(env: NodeJS.ProcessEnv = process.env, goalText?: string): string {
60
80
  const explicit = env.ELANOUS_CHILD_TOOL_PROFILE?.trim();
61
- if (explicit) return explicit;
81
+ if (explicit) {
82
+ const parsed = parseToolProfile(explicit);
83
+ debug.log('agent.tool-profile', 'child-profile-chosen', { source: 'env', raw: explicit, profile: parsed?.name ?? 'coding', groups: parsed ? [...parsed.groups] : [] });
84
+ return explicit;
85
+ }
62
86
  const groups = situationalToolGroups(goalText);
63
- return groups.length ? groups.join(',') : 'coding';
87
+ const profile = groups.length ? groups.join(',') : 'coding';
88
+ debug.log('agent.tool-profile', 'child-profile-chosen', { source: groups.length ? 'situational' : 'default', profile, groups, goalChars: goalText?.length ?? 0 });
89
+ return profile;
64
90
  }
65
91
 
66
92
  /** 기본 모드에서 뺀 묶음을 자식에게 «한 줄»로 알린다 — 필요하면 ToolSearch 로 불러 쓴다(스키마는 안 싣는다). */