elanous 0.2.21 → 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 (780) 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-111cabe4d1fd69ae.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/{MObU8ujkMciAKr6ljAV05 → 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/catalog/catalog.yaml +1 -1
  288. package/graphs/drafts/recipes.yaml +2 -2
  289. package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
  290. package/graphs/log-horizon/recipes.yaml +3 -0
  291. package/graphs/release/recipes.yaml +1 -1
  292. package/graphs/release/release-loop.yaml +6 -2
  293. package/graphs/release-rehearsal/recipes.yaml +12 -0
  294. package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
  295. package/graphs/test-diet/recipes.yaml +3 -0
  296. package/graphs/test-diet/test-diet.yaml +3 -1
  297. package/package.json +4 -1
  298. package/scripts/bench-report.ts +82 -3
  299. package/scripts/ci-typecheck-changed.ts +10 -1
  300. package/scripts/f-session-monitor.ts +69 -0
  301. package/scripts/hq/hq-fence-wrapper.sh +148 -0
  302. package/scripts/hq/standby-snapshot.ts +7 -3
  303. package/scripts/knowledge-compress.ts +11 -0
  304. package/scripts/lib/typecheck-ratchet.ts +51 -0
  305. package/scripts/nightly-docops.ts +90 -3
  306. package/scripts/openai-relay-server.ts +5 -1
  307. package/scripts/release-loop/docs-node.ts +258 -43
  308. package/scripts/release-loop/gate-method.ts +59 -0
  309. package/scripts/release-loop/gate-node.ts +73 -7
  310. package/scripts/release-loop/gate-wall.ts +208 -0
  311. package/scripts/release-loop/known-issues-node.ts +53 -8
  312. package/scripts/release-loop/publish-at.ts +14 -0
  313. package/scripts/release-loop/publish-node.ts +17 -2
  314. package/scripts/release-loop/resume-release.ts +34 -4
  315. package/scripts/release-loop/resume.ts +53 -0
  316. package/scripts/release-loop/shard-plan.ts +3 -11
  317. package/scripts/release-loop/tui-node-checks.ts +22 -0
  318. package/scripts/release-loop/unattended-release.ts +8 -1
  319. package/scripts/research-coo-admin-dates.ts +39 -0
  320. package/scripts/rhythm/daily.ts +51 -2
  321. package/scripts/rhythm/weekly.ts +3 -2
  322. package/scripts/skills/public-check.ts +7 -2
  323. package/scripts/smart-merge/resync-shadow.ts +5 -3
  324. package/scripts/test-diet/lib.ts +81 -1
  325. package/scripts/test-diet/node.ts +48 -2
  326. package/scripts/tsc-main-safety-net.ts +189 -0
  327. package/scripts/usage-rollup.ts +8 -4
  328. package/scripts/verify-coo-admin-evidence.ts +83 -0
  329. package/src/acp/client.ts +4 -2
  330. package/src/acp/codex-plugins.ts +48 -6
  331. package/src/agent/monad-agent-turn.ts +67 -5
  332. package/src/agent/run-context.ts +14 -0
  333. package/src/agent/tool-profile.ts +28 -2
  334. package/src/agent-env/profile.ts +25 -5
  335. package/src/agent-mission/acp-judge.ts +8 -2
  336. package/src/agent-mission/capabilities-cli.ts +16 -1
  337. package/src/agent-mission/driver.ts +27 -13
  338. package/src/agent-mission/pr-review-watch.ts +6 -2
  339. package/src/agent-mission/review-loop.ts +33 -5
  340. package/src/agent-mission/supervisor-metrics.ts +17 -2
  341. package/src/agent-substrate/acp-reviewer.ts +25 -9
  342. package/src/agent-substrate/pr-reviewer.ts +175 -32
  343. package/src/agent-substrate/review-intent.ts +106 -5
  344. package/src/agent-substrate/self-review-cli.ts +111 -16
  345. package/src/agent-substrate/shard-boundary-intent.ts +92 -26
  346. package/src/ask-user-question/pending-questions.ts +8 -2
  347. package/src/autopilot/build/llm-conflict-merge.ts +238 -20
  348. package/src/autopilot/codebase-grounding.ts +44 -0
  349. package/src/autopilot/llm-control-brain.ts +13 -1
  350. package/src/autopilot/mission-codebase-gate.ts +8 -77
  351. package/src/autopilot/pr-manager.ts +30 -11
  352. package/src/away/release-watch.ts +47 -8
  353. package/src/boot/acp-server.ts +4 -7
  354. package/src/boot/acp-socket-path.ts +7 -0
  355. package/src/briefing/brief-items.ts +123 -22
  356. package/src/chat/index.ts +13 -3
  357. package/src/cli/agent-cli.ts +20 -0
  358. package/src/cli/brief-cli.ts +46 -22
  359. package/src/cli/cli-user-error.ts +9 -2
  360. package/src/cli/config-classify.ts +83 -0
  361. package/src/cli/control-cli.ts +14 -0
  362. package/src/cli/decisions-cli.ts +26 -16
  363. package/src/cli/log-event-names.ts +3 -0
  364. package/src/cli/logs-cli.ts +1 -0
  365. package/src/cli/logs-model-input.ts +1 -1
  366. package/src/cli/mcp-login.ts +111 -37
  367. package/src/cli/plugin-cli.ts +21 -1
  368. package/src/cli/pod-cli.ts +26 -0
  369. package/src/cli/pr-cli.ts +94 -9
  370. package/src/cli/pr-land-overlap-evidence.ts +131 -0
  371. package/src/cli/release-cli.ts +74 -15
  372. package/src/cli/self-update.ts +173 -10
  373. package/src/cli/skills-cli.ts +12 -3
  374. package/src/cli/tasks-cli.ts +241 -28
  375. package/src/connectors/types.ts +6 -6
  376. package/src/context-bus/context-first.ts +51 -2
  377. package/src/context-bus/context-now-surfaces.ts +29 -0
  378. package/src/context-bus/coord-events.ts +32 -4
  379. package/src/context-bus/long-term-memory.ts +26 -7
  380. package/src/context-bus/nightly-condense.ts +170 -21
  381. package/src/control/control-status.ts +87 -0
  382. package/src/control-plane/light-member.ts +5 -3
  383. package/src/control-plane/member.ts +172 -7
  384. package/src/core-turn/run-goal-loop.ts +108 -3
  385. package/src/dashboard/chat-fold.ts +20 -0
  386. package/src/dashboard/first-screen-band.ts +151 -1
  387. package/src/dashboard/index.ts +27 -5
  388. package/src/dashboard/slash-runtime/dashboard-handlers.ts +14 -3
  389. package/src/dashboard/stale-install-check.ts +13 -2
  390. package/src/dashboard/turn-stream-formatter.ts +25 -0
  391. package/src/debug/log-diet.ts +159 -0
  392. package/src/debug/log.ts +52 -17
  393. package/src/decisions/decision-cards.ts +20 -1
  394. package/src/decisions/decision-ledger.ts +11 -8
  395. package/src/decisions/web-push-decision-cards.ts +19 -3
  396. package/src/discord-self-message.ts +2 -2
  397. package/src/display/coordinator.ts +25 -2
  398. package/src/domains/coo-admin-dates.evidence.json +876 -0
  399. package/src/domains/coo-admin-tool.ts +75 -14
  400. package/src/domains/cron-match.ts +1 -0
  401. package/src/domains/ops-status.ts +53 -0
  402. package/src/domains/outbound-alert.ts +41 -7
  403. package/src/domains/release-tool.ts +119 -10
  404. package/src/domains/schedule-registry.ts +10 -7
  405. package/src/domains/schedule-runner.ts +1 -0
  406. package/src/elanous-config-dir.ts +2 -2
  407. package/src/elanous-daemon.ts +3 -3
  408. package/src/exec-requests/planner.ts +6 -0
  409. package/src/execution-loop/launch-gate.ts +1 -1
  410. package/src/expression/i18n/messages.en.ts +5 -0
  411. package/src/expression/i18n/messages.ja.ts +5 -0
  412. package/src/expression/i18n/messages.ko.ts +5 -0
  413. package/src/expression/i18n/messages.zh.ts +5 -0
  414. package/src/expression/i18n/types.ts +8 -0
  415. package/src/github/pr-labels.ts +1 -0
  416. package/src/graph-kinds/registry.ts +6 -6
  417. package/src/graph-runner/graph-cli.ts +34 -2
  418. package/src/graph-runner/graph-run-api.ts +7 -0
  419. package/src/graph-runner/graph-tick.ts +73 -12
  420. package/src/graph-runner/runner.ts +94 -13
  421. package/src/graph-unify/wf-to-graph.ts +79 -0
  422. package/src/graph-wizard/generate.ts +34 -2
  423. package/src/graph-wizard/steps.ts +13 -0
  424. package/src/harness/dispatch-backpressure.ts +259 -0
  425. package/src/harness/harness-cli-command.ts +227 -50
  426. package/src/harness/harness-queue.ts +58 -14
  427. package/src/harness/harness-seams.ts +2 -20
  428. package/src/harness/harness-substrate-default.ts +72 -1
  429. package/src/harness/launch-advice.ts +23 -0
  430. package/src/harness/nested-elanous-policy.ts +4 -2
  431. package/src/hq/fence-wrapper.ts +7 -0
  432. package/src/hq/hq.ts +33 -2
  433. package/src/hq/lease.ts +13 -0
  434. package/src/hq/seats.ts +114 -18
  435. package/src/index.ts +199 -71
  436. package/src/intake-plane/collect-github.ts +19 -1
  437. package/src/intake-plane/digest.ts +45 -20
  438. package/src/intake-plane/lens.ts +36 -8
  439. package/src/intelligence-map/model-alias.ts +6 -0
  440. package/src/intelligence-map/model-catalog.ts +41 -0
  441. package/src/knowledge/conclusion-compress.ts +93 -0
  442. package/src/knowledge/kgs/pack.ts +5 -2
  443. package/src/knowledge/kgs/sqlite-store.ts +15 -0
  444. package/src/knowledge/know-find.ts +9 -2
  445. package/src/knowledge/query.ts +20 -0
  446. package/src/knowledge/tools/knowledge-query.ts +20 -2
  447. package/src/knowledge/write.ts +234 -2
  448. package/src/llm/bedrock-provider.ts +175 -0
  449. package/src/llm/bedrock.ts +345 -0
  450. package/src/llm/provider-credentials.ts +3 -1
  451. package/src/llm.ts +332 -51
  452. package/src/loops/budget.ts +150 -0
  453. package/src/loops/neighbor-runtime.ts +88 -0
  454. package/src/loops/orchestrator/author-depth.ts +29 -11
  455. package/src/loops/orchestrator/overlap.ts +7 -1
  456. package/src/loops/orchestrator/resync-shadow.ts +1 -1
  457. package/src/loops/orchestrator/seat-share.ts +6 -49
  458. package/src/loops/orchestrator/tick.ts +35 -2
  459. package/src/loops/orchestrator/traffic.ts +6 -80
  460. package/src/loops/registry.ts +5 -0
  461. package/src/market/publish.ts +17 -1
  462. package/src/market/signed-index.ts +42 -0
  463. package/src/maturity/feature-maturity.ts +2 -1
  464. package/src/mcp/mcp-oauth.ts +136 -17
  465. package/src/model-tier/llm-tier-map.ts +48 -4
  466. package/src/models/prompts.ts +22 -1
  467. package/src/mss/logging/horizon-watch.ts +168 -0
  468. package/src/mss/logging/log-store.ts +204 -15
  469. package/src/mss/logging/redaction.ts +17 -0
  470. package/src/native-tool-catalog.ts +1 -1
  471. package/src/nexus/api/consult-requests.ts +7 -10
  472. package/src/nexus/api/discord-trigger-bot.ts +6 -3
  473. package/src/nexus/api/draft-metrics.ts +22 -8
  474. package/src/nexus/api/error-reports.ts +30 -8
  475. package/src/nexus/api/graph-peer-edit.ts +77 -0
  476. package/src/nexus/api/graph-wizard-api.ts +9 -1
  477. package/src/nexus/api/graphs-api.ts +145 -7
  478. package/src/nexus/api/http-server.ts +101 -8
  479. package/src/nexus/api/loop-resources.ts +42 -0
  480. package/src/nexus/api/outbound-report.ts +8 -3
  481. package/src/nexus/api/plugins-market.ts +24 -0
  482. package/src/nexus/api/telegram-trigger-bot.ts +6 -3
  483. package/src/nexus/index.ts +13 -2
  484. package/src/nexus/outbound/format.ts +2 -0
  485. package/src/nexus/outbound/router.ts +198 -13
  486. package/src/oauth/claude-pty-maturity.ts +24 -0
  487. package/src/oauth/codex-account-rotation.ts +16 -18
  488. package/src/oauth/codex-account-store.ts +134 -5
  489. package/src/oauth/fallback-chain.ts +50 -15
  490. package/src/onboarding.ts +2 -1
  491. package/src/plugins/adapters/claude-package.ts +4 -12
  492. package/src/plugins/core/capability-policy.ts +141 -0
  493. package/src/plugins/core/host.ts +21 -8
  494. package/src/plugins/core/manifest.ts +19 -2
  495. package/src/plugins/core/trust-store.ts +15 -0
  496. package/src/plugins/core/types.ts +12 -0
  497. package/src/plugins/install/market-fetch.ts +68 -16
  498. package/src/plugins/install/plugin-install.ts +187 -16
  499. package/src/plugins/maker/market-bundle.ts +9 -0
  500. package/src/plugins/maker/plugin-maker.ts +32 -21
  501. package/src/plugins/maker/wizard-generate.ts +87 -9
  502. package/src/policy/llm-policy.ts +24 -6
  503. package/src/process/pid-liveness.ts +1 -1
  504. package/src/prompt-cache/openai.ts +10 -6
  505. package/src/prompt-cache/openrouter.ts +94 -0
  506. package/src/prompt-enhance/enhance.ts +46 -5
  507. package/src/prompt-library/family-prompt-coverage.ts +1 -0
  508. package/src/prompt-library/universal-preamble.ts +2 -2
  509. package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
  510. package/src/registry/loader.ts +6 -1
  511. package/src/release-loop/checklist-board.ts +27 -0
  512. package/src/release-loop/checklist.ts +62 -9
  513. package/src/release-loop/feature-store.ts +3 -0
  514. package/src/release-loop/gate-shards.ts +48 -4
  515. package/src/release-loop/landed-to-green.ts +81 -0
  516. package/src/release-loop/light-rc.ts +11 -1
  517. package/src/release-loop/merged-pr-checklist.ts +10 -0
  518. package/src/release-loop/placement.ts +91 -22
  519. package/src/release-loop/rehearsal.ts +317 -0
  520. package/src/release-loop/release-schedule.ts +13 -1
  521. package/src/release-loop/rubric-types.ts +1 -0
  522. package/src/release-loop/rubric.ts +2 -2
  523. package/src/retro/daily.ts +23 -9
  524. package/src/seat-address/seat-address.ts +1 -0
  525. package/src/seat-loop/seat-loop.ts +208 -21
  526. package/src/seat-loop/seat-report.ts +29 -1
  527. package/src/seat-loop/traffic-signal.ts +44 -0
  528. package/src/self-dev/ask-launch-flow.ts +2 -2
  529. package/src/self-dev/dev-cli.ts +157 -11
  530. package/src/self-dev/dev-pipeline.ts +18 -1
  531. package/src/self-dev/draft-residue.ts +463 -0
  532. package/src/self-dev/draft-sweep.ts +195 -17
  533. package/src/self-dev/draft-triage-rules.ts +27 -1
  534. package/src/self-dev/launch-preflight-text.ts +549 -0
  535. package/src/self-dev/launch-preflight.ts +10 -545
  536. package/src/self-dev/orchestrate-cli.ts +57 -2
  537. package/src/self-dev/orchestrate-summary-line.ts +13 -0
  538. package/src/self-dev/orchestrate.ts +9 -133
  539. package/src/self-dev/review-provider-fallback.ts +179 -0
  540. package/src/self-dev/run-store.ts +1 -3
  541. package/src/self-dev/run-supervisor.ts +8 -23
  542. package/src/self-dev/run-types.ts +178 -0
  543. package/src/self-dev/shard-aggregate.ts +61 -13
  544. package/src/self-dev/shard-plan.ts +5 -1
  545. package/src/self-dev/shard-run.ts +23 -5
  546. package/src/self-dev/supervisor-verdict-edges.ts +2 -4
  547. package/src/self-implement/blocked-draft-policy.ts +3 -19
  548. package/src/self-implement/draft-on-stop-mode.ts +18 -0
  549. package/src/self-implement/follow-up-goals.ts +114 -38
  550. package/src/self-implement/gate-baseline-reap.ts +157 -0
  551. package/src/self-implement/gate-baseline.ts +78 -16
  552. package/src/self-implement/gate-cli.ts +12 -2
  553. package/src/self-implement/gate-remote.ts +17 -6
  554. package/src/self-implement/goal-author.ts +24 -4
  555. package/src/self-implement/goal-digest.ts +19 -0
  556. package/src/self-implement/graph-overlay-condition.ts +4 -0
  557. package/src/self-implement/harness-policy-gates.ts +7 -5
  558. package/src/self-implement/headless-elanous-driver.ts +11 -9
  559. package/src/self-implement/host-regate.ts +148 -43
  560. package/src/self-implement/l8-merge-queue.ts +147 -13
  561. package/src/self-implement/merge-train.ts +131 -0
  562. package/src/self-implement/off-diff-evidence.ts +9 -0
  563. package/src/self-implement/orchestrator.ts +201 -43
  564. package/src/self-implement/review-finding-recurrence.ts +28 -0
  565. package/src/self-implement/rework-policy.ts +2 -1
  566. package/src/self-implement/round-summary-card.ts +63 -0
  567. package/src/self-implement/run-ledger.ts +4 -3
  568. package/src/self-implement/run-step-projection.ts +147 -0
  569. package/src/self-implement/run-stop.ts +1 -1
  570. package/src/self-implement/seams.ts +41 -6
  571. package/src/self-implement/self-implement-cli.ts +6 -0
  572. package/src/self-implement/train-gate-remote.ts +158 -0
  573. package/src/session-runtime/index.ts +10 -1
  574. package/src/session-runtime/retry-api.ts +11 -1
  575. package/src/shell-env-bootstrap.ts +19 -4
  576. package/src/skills/gift-install.ts +119 -0
  577. package/src/skills/runner.ts +59 -2
  578. package/src/skills/skill-feedback.ts +31 -1
  579. package/src/skills/skill-tier.ts +1 -0
  580. package/src/smart-wizard/capability-index.ts +231 -0
  581. package/src/smart-wizard/rung.ts +74 -0
  582. package/src/steward/launch.ts +20 -9
  583. package/src/steward/triage.ts +29 -10
  584. package/src/storage/file-lock.ts +40 -4
  585. package/src/task-agent/actions.ts +4 -0
  586. package/src/task-agent/card-evidence.ts +59 -13
  587. package/src/task-agent/completion-evidence.ts +31 -3
  588. package/src/task-agent/cover.ts +61 -0
  589. package/src/task-agent/judge.ts +4 -3
  590. package/src/task-agent/land-worktree.ts +201 -0
  591. package/src/task-agent/live-move-history.ts +133 -0
  592. package/src/task-agent/live-moves.ts +222 -12
  593. package/src/task-agent/parent-host.ts +117 -8
  594. package/src/task-agent/rejudge-on-head.ts +297 -0
  595. package/src/task-agent/review-result-capture.ts +218 -0
  596. package/src/task-agent/shadow.ts +118 -7
  597. package/src/task-agent/task-hand.ts +138 -11
  598. package/src/task-orchestrator/surfaces/pod-child-providers.ts +29 -0
  599. package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
  600. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +16 -2
  601. package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
  602. package/src/task-orchestrator/surfaces/pod-lease.ts +93 -12
  603. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +25 -2
  604. package/src/task-orchestrator/surfaces/pod-pool.ts +203 -28
  605. package/src/task-orchestrator/surfaces/self-implement-pod.ts +259 -36
  606. package/src/task-orchestrator/surfaces/self-implement.ts +11 -0
  607. package/src/telegram-commands.ts +8 -0
  608. package/src/telegram-project-command.ts +6 -0
  609. package/src/telegram-service.ts +5 -1
  610. package/src/telegram.ts +17 -4
  611. package/src/time/format.ts +13 -4
  612. package/src/tool-runtime/goal-author-runtime.ts +1 -0
  613. package/src/tool-runtime/self-cognition-catalog.ts +23 -0
  614. package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
  615. package/src/typecheck-ratchet.ts +2 -1
  616. package/src/user-config.ts +167 -28
  617. package/src/ux-sim/slash-menu-frames.ts +168 -0
  618. package/src/version/packed-revision.json +1 -1
  619. package/src/web-terminal/preview-tap-registry.ts +5 -2
  620. package/src/workflow-runtime/executor.ts +24 -2
  621. package/src/workflow-runtime/triggers/registry.ts +27 -0
  622. package/src/workflow-runtime/triggers/schedule-source.ts +30 -3
  623. package/src/workflow-runtime/triggers/scheduler.ts +1 -0
  624. package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
  625. package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
  626. package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
  627. package/apps/pwa/out/_next/static/chunks/1307-c97eba9fb72a9a5e.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
  629. package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
  630. package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
  631. package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
  633. package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
  638. package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
  647. package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
  648. package/apps/pwa/out/_next/static/chunks/2489-ff55a35b202c0f94.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
  661. package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/3857-995ea9f5ef33d71e.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
  669. package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
  674. package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
  676. package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
  680. package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
  684. package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/5977-59fedea50d13c762.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
  689. package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
  690. package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
  692. package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
  693. package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
  701. package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
  704. package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
  714. package/apps/pwa/out/_next/static/chunks/8857-f1762140ef9a96b1.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
  717. package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/9247-7581825d511a64c0.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
  721. package/apps/pwa/out/_next/static/chunks/9497-b0e758d1cd4ae8d7.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
  723. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/approvals/page-937c92292a4ab4f0.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d781be3e3a9cfd74.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/board/page-b0a80997903852d8.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/botlab/page-2b1263165630d9c8.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea998f7f5d156bea.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/ceo/page-33c328b64ca508f8.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/chat/page-e2d6bed48ac20120.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/control/page-544dd4bd4847eeb7.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/decisions/page-3ee191319bf97d87.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e4bcb2c503dab04b.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/editor/page-300897dcbbd5ed76.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/exec/page-a449f1ed472b81c2.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/field/page-9045094d6d3b5cd0.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/inside/page-c06673596849ef45.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/intake/page-103fa3191c1b2e08.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/layout-9f81233f29dcd409.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/live/page-be8b4615c919e36c.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/live-run/page-c685b104e0dfa609.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/app/loops/page-8d693331cfbb6add.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/market/page-cef4f30a4c22fae1.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66ea1b54fc83fa15.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/morning/page-7a12f61be4a579d1.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/not-found-c85b0589591a99c9.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/observatory/page-725a4da02dd129eb.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-8cc707bd09a497d9.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-90b55be1f15ce0e8.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cb16606e08be65db.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/outputs/page-16dc64b74ed6a40a.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/page-21bec4afeb2f0917.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/reflection/page-dc39ee7a36d26385.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-84ae759f76053672.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/sessions/page-3db58ddb61fe2be9.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c5315e30f3528dc4.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/settings/page-2fe368efb6de3b6a.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8d04132dd0ac5e10.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/setup/page-f23484de467c9ea3.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/share/page-c69762987b751174.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/showroom/page-5456692bda39aafb.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d75f7cd65845ce98.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/term/page-5603f5e568b25ce3.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/today/page-d2cc0f4e89f42028.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/trace/page-a6eb73b8a4840f1c.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/vault/page-c0a3f4d10edb83fa.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6c0b88068c143f15.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/workflows/page-7f8d7fcdf058a845.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/workspace/page-22163556cd38bc88.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-141436fd26dd56fc.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
  779. package/apps/pwa/out/_next/static/css/e81df11490b4413b.css +0 -1
  780. /package/apps/pwa/out/_next/static/{MObU8ujkMciAKr6ljAV05 → rfkMm4movqkqMebBrCXiR}/_ssgManifest.js +0 -0
@@ -91,6 +91,8 @@ export interface PublishResult {
91
91
  ok: boolean;
92
92
  sequence: number;
93
93
  published: Array<{ name: string; version: string; sha256: string; bundled: string[] }>;
94
+ /** With keepExisting: previous index entries whose name has no folder under pluginsDir, carried over unchanged. */
95
+ kept: Array<{ name: string; version: string; sha256: string }>;
94
96
  skipped: Array<{ dir: string; reason: string; hits?: InternalRefHit[] }>;
95
97
  /** Published anyway, but a reviewer should look (e.g. a third-party graph relying on core recipes). */
96
98
  warnings: Array<{ dir: string; graph: string; reason: 'third-party-core-recipe'; recipes: string[] }>;
@@ -103,6 +105,8 @@ export function publishMarket(input: {
103
105
  market: { name: string; displayName: string };
104
106
  key: { keyId: string; privateKeyPem: string };
105
107
  source?: { repoUrl: string; sha: string; basePath: string };
108
+ /** Carry over previous entries whose name is not a plugin folder under pluginsDir (entry, archive and unpacked files untouched). */
109
+ keepExisting?: boolean;
106
110
  now?: Date;
107
111
  }): PublishResult {
108
112
  let sequence = 1;
@@ -307,6 +311,18 @@ export function publishMarket(input: {
307
311
  published.push({ name: manifest.name, version: manifest.version, sha256, bundled });
308
312
  debug.log('market.publish', 'bundled', { name: manifest.name, version: manifest.version, skills: bundled });
309
313
  }
314
+ const kept: PublishResult['kept'] = [];
315
+ if (input.keepExisting && previous) {
316
+ // Folders under pluginsDir own their names (even when skipped); every other previous entry stays as it was.
317
+ const present = new Set(readdirSync(input.pluginsDir).filter(dir => lstatSync(join(input.pluginsDir, dir)).isDirectory()));
318
+ for (const item of previous.plugins) {
319
+ if (present.has(item.name)) continue;
320
+ plugins.push(item);
321
+ kept.push({ name: item.name, version: item.version, sha256: item.artifact.sha256 });
322
+ debug.log('market.publish', 'kept', { name: item.name, version: item.version });
323
+ }
324
+ plugins.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
325
+ }
310
326
  const index: MarketplaceIndex = { name: input.market.name, interface: { displayName: input.market.displayName },
311
327
  sequence, generatedAt: (input.now ?? new Date()).toISOString(), plugins };
312
328
  const bytes = Buffer.from(JSON.stringify(index, null, 2) + '\n');
@@ -345,7 +361,7 @@ export function publishMarket(input: {
345
361
  signatureText: readFileSync(join(input.outDir, 'index.sig'), 'utf8'), trustedKeys });
346
362
  if (!verified.ok) throw new Error(`index verification failed: ${verified.reason}: ${verified.detail}`);
347
363
  for (const item of published) debug.log('market.publish', 'published', { name: item.name, version: item.version, sequence });
348
- return { ok: !skipped.some(item => item.reason === 'internal-reference'), sequence, published, skipped, warnings };
364
+ return { ok: !skipped.some(item => item.reason === 'internal-reference'), sequence, published, kept, skipped, warnings };
349
365
  } catch (error) {
350
366
  const rawReason = error instanceof Error ? error.message : 'unknown-error';
351
367
  const reason = input.key.privateKeyPem && rawReason.includes(input.key.privateKeyPem) ? 'invalid signing key' : rawReason;
@@ -1,10 +1,31 @@
1
1
  import { createHash, createPublicKey, generateKeyPairSync, sign, verify } from 'node:crypto';
2
2
 
3
+ export interface MarketplaceArtifact {
4
+ sha256: string;
5
+ bytes: number;
6
+ key: string;
7
+ }
8
+
9
+ export interface MarketplaceScopedPack {
10
+ name: string;
11
+ version: string;
12
+ description?: string;
13
+ artifact: MarketplaceArtifact;
14
+ visibility: 'public' | 'internal';
15
+ enterpriseId?: string;
16
+ }
17
+
18
+ export interface MarketplaceLoopBundle extends MarketplaceScopedPack {
19
+ graphs?: string[];
20
+ }
21
+
3
22
  export interface MarketplaceIndex {
4
23
  name: string;
5
24
  interface: { displayName: string };
6
25
  sequence: number;
7
26
  generatedAt?: string;
27
+ knowledgePacks?: MarketplaceScopedPack[];
28
+ loopBundles?: MarketplaceLoopBundle[];
8
29
  plugins: Array<{
9
30
  name: string;
10
31
  source: { source: string; [key: string]: unknown };
@@ -57,6 +78,27 @@ function invalidIndex(value: unknown): string | null {
57
78
  if (value.generatedAt !== undefined && !string(value.generatedAt)) return 'generatedAt: expected string';
58
79
  if (!Array.isArray(value.plugins)) return 'plugins: expected array';
59
80
 
81
+ for (const collection of ['knowledgePacks', 'loopBundles'] as const) {
82
+ const entries = value[collection];
83
+ if (entries === undefined) continue;
84
+ if (!Array.isArray(entries)) return `${collection}: expected array`;
85
+ for (const [i, entry] of entries.entries()) {
86
+ const field = (name: string) => `${collection}[${i}] (${record(entry) && string(entry.name) ? entry.name : 'unnamed'}).${name}`;
87
+ if (!record(entry)) return field('expected object');
88
+ if (!string(entry.name) || !entry.name.trim()) return field('name: expected non-empty string');
89
+ if (!string(entry.version) || !entry.version.trim()) return field('version: expected non-empty string');
90
+ if (entry.description !== undefined && !string(entry.description)) return field('description: expected string');
91
+ if (entry.visibility !== 'public' && entry.visibility !== 'internal') return field('visibility: expected public or internal');
92
+ if (entry.visibility === 'internal' && (!string(entry.enterpriseId) || !entry.enterpriseId.trim())) return field('enterpriseId: required for internal entry');
93
+ if (entry.visibility === 'public' && entry.enterpriseId !== undefined) return field('enterpriseId: not allowed for public entry');
94
+ if (!record(entry.artifact)) return field('artifact: expected object');
95
+ if (!string(entry.artifact.sha256) || !/^[a-fA-F0-9]{64}$/.test(entry.artifact.sha256)) return field('artifact.sha256: expected 64 hex characters');
96
+ if (!Number.isSafeInteger(entry.artifact.bytes) || (entry.artifact.bytes as number) < 0) return field('artifact.bytes: expected non-negative integer');
97
+ if (!string(entry.artifact.key) || !entry.artifact.key.trim()) return field('artifact.key: expected non-empty string');
98
+ if (collection === 'loopBundles' && entry.graphs !== undefined && !stringArray(entry.graphs)) return field('graphs: expected string array');
99
+ }
100
+ }
101
+
60
102
  for (const [i, plugin] of value.plugins.entries()) {
61
103
  const field = (name: string) => `plugins[${i}] (${record(plugin) && string(plugin.name) ? plugin.name : 'unnamed'}).${name}`;
62
104
  if (!record(plugin)) return field('expected object');
@@ -117,6 +117,7 @@ export const FEATURE_MATURITY = {
117
117
  widget: 'tool',
118
118
  log: 'tool',
119
119
  loops: 'beta',
120
+ board: 'beta',
120
121
  persona: 'beta', // G3 b — 대화별 페르소나(GOAL-BENCH B7 #23836)
121
122
  memory: 'beta',
122
123
  export: 'stable',
@@ -161,7 +162,7 @@ export const FEATURE_MATURITY = {
161
162
  ping: 'stable', provider: 'stable', sessions: 'stable', fork: 'stable', resume: 'stable',
162
163
  decisions: 'stable', work: 'stable', cancel: 'stable',
163
164
  skills: 'beta', skill: 'beta', digest: 'beta', intake: 'beta', ad: 'beta',
164
- taste: 'beta', missions: 'beta', attach: 'beta', detach: 'beta', now: 'beta', loops: 'beta', runs: 'beta', release: 'beta', away: 'beta', project: 'beta', wish: 'beta',
165
+ taste: 'beta', missions: 'beta', attach: 'beta', detach: 'beta', now: 'beta', loops: 'beta', runs: 'beta', board: 'beta', release: 'beta', away: 'beta', project: 'beta', wish: 'beta',
165
166
  brain: 'tool', cc: 'tool', cdx: 'tool', gem: 'tool', local: 'tool',
166
167
  harness: 'ops',
167
168
  // Existing commands outside the CXO four-grade menu list are owner-only.
@@ -5,9 +5,8 @@
5
5
  // 다시 실어 보내는 «잇는» 모듈. 주소를 코드에 박지 않는다 — 호스트는
6
6
  // 전부 그 401 안내에서 그때 얻는다.
7
7
  //
8
- // 경계: 브라우저에서 누르는 구간은 만들지 않는다. 인가 주소를 조립해
9
- // AuthorizeHandler 로 돌려주는 데까지가 이 착지다.
10
- // 경계: 장치 코드 흐름은 다루지 않는다.
8
+ // 브라우저 승인은 호출자(aside/CLI)의 책임이다. 브라우저를 쓸 수 없고
9
+ // 인가 서버가 RFC 8628 을 광고할 때는 장치 코드로 자격을 얻는다.
11
10
  // 경계: 새 CLI 하위 명령은 더하지 않는다.
12
11
 
13
12
  import { join } from 'node:path';
@@ -36,6 +35,7 @@ export type McpOAuthErrorCode =
36
35
  | 'identity-mismatch'
37
36
  | 's256-unsupported'
38
37
  | 'registration'
38
+ | 'device'
39
39
  | 'state-mismatch'
40
40
  | 'token'
41
41
  | 'refresh';
@@ -70,9 +70,10 @@ export interface ProtectedResourceMetadata {
70
70
 
71
71
  export interface AuthorizationServerMetadata {
72
72
  issuer: string;
73
- authorizationEndpoint: string;
73
+ authorizationEndpoint?: string;
74
74
  tokenEndpoint: string;
75
75
  registrationEndpoint?: string;
76
+ deviceAuthorizationEndpoint?: string;
76
77
  codeChallengeMethodsSupported: string[];
77
78
  }
78
79
 
@@ -81,6 +82,9 @@ export interface ClientRegistration {
81
82
  clientSecret?: string;
82
83
  /** 동적 등록 때 쓴 redirect_uri. 옛 등록에는 없다. */
83
84
  redirectUri?: string;
85
+ /** Registered now but not stored yet: the store still holds another client's tokens, so this registration is
86
+ * committed only with its own tokens (exchangeAuthorizationCode). A cancelled login leaves the store as it was. */
87
+ pending?: boolean;
84
88
  }
85
89
 
86
90
  export interface AuthorizationRequest {
@@ -90,6 +94,8 @@ export interface AuthorizationRequest {
90
94
  redirectUri: string;
91
95
  issuer: string;
92
96
  clientId: string;
97
+ /** Set when the client registration is pending (see ClientRegistration.pending); in memory only. */
98
+ pendingRegistration?: { clientSecret?: string };
93
99
  scope?: string;
94
100
  resource?: string;
95
101
  }
@@ -364,14 +370,14 @@ export async function discoverAuthorizationServer(
364
370
  const issuer = stringField(body, 'issuer');
365
371
  const authorizationEndpoint = stringField(body, 'authorization_endpoint');
366
372
  const tokenEndpoint = stringField(body, 'token_endpoint');
367
- if (!issuer || !authorizationEndpoint || !tokenEndpoint) {
373
+ if (!issuer || !tokenEndpoint || (!authorizationEndpoint && !stringField(body, 'device_authorization_endpoint'))) {
368
374
  throw new McpOAuthError(
369
375
  'discovery',
370
376
  'authorization server metadata is missing issuer, authorization_endpoint, or token_endpoint',
371
377
  );
372
378
  }
373
379
  requireHttpUrl(issuer, 'issuer');
374
- requireHttpUrl(authorizationEndpoint, 'authorization_endpoint');
380
+ if (authorizationEndpoint) requireHttpUrl(authorizationEndpoint, 'authorization_endpoint');
375
381
  requireHttpUrl(tokenEndpoint, 'token_endpoint');
376
382
  // ⛔⭐⭐ RFC 8414 §3.3 — 돌려받은 `issuer` 는 «우리가 물어본» 인가서버
377
383
  // 식별자와 «같아야» 한다. 안 대조하면 metadata 를 쥔 쪽이 남의 issuer 를
@@ -385,11 +391,14 @@ export async function discoverAuthorizationServer(
385
391
  }
386
392
  const registrationEndpoint = stringField(body, 'registration_endpoint');
387
393
  if (registrationEndpoint) requireHttpUrl(registrationEndpoint, 'registration_endpoint');
394
+ const deviceAuthorizationEndpoint = stringField(body, 'device_authorization_endpoint');
395
+ if (deviceAuthorizationEndpoint) requireHttpUrl(deviceAuthorizationEndpoint, 'device_authorization_endpoint');
388
396
  return {
389
397
  issuer,
390
- authorizationEndpoint,
398
+ ...(authorizationEndpoint ? { authorizationEndpoint } : {}),
391
399
  tokenEndpoint,
392
400
  ...(registrationEndpoint ? { registrationEndpoint } : {}),
401
+ ...(deviceAuthorizationEndpoint ? { deviceAuthorizationEndpoint } : {}),
393
402
  codeChallengeMethodsSupported: stringList(body, 'code_challenge_methods_supported'),
394
403
  };
395
404
  }
@@ -468,13 +477,15 @@ export function loadStoredRegistration(
468
477
 
469
478
  export async function ensureClientRegistration(
470
479
  metadata: AuthorizationServerMetadata,
471
- opts: McpOAuthRuntimeOpts & { forceReregister?: boolean } = {},
480
+ opts: McpOAuthRuntimeOpts & { forceReregister?: boolean; deviceCode?: boolean } = {},
472
481
  ): Promise<ClientRegistration> {
473
482
  const path = storePath(opts);
474
483
  if (!opts.forceReregister) {
475
484
  const stored = loadStoredRegistration(metadata.issuer, { storePath: path });
476
- // 옛 등록은 redirect_uri 기록이 없다 — 재사용하면 포트 불일치로 영원히 막힌다.
477
- if (stored?.redirectUri) return stored;
485
+ // Browser registrations require a bound loopback URI. Device authorization reuses a client without one
486
+ // (a prior device client — its stored refresh token stays paired with it), or any client when it cannot register.
487
+ if (stored && opts.deviceCode && (!stored.redirectUri || !metadata.registrationEndpoint)) return stored;
488
+ if (stored?.redirectUri && !opts.deviceCode) return stored;
478
489
  }
479
490
  if (!metadata.registrationEndpoint) {
480
491
  throw new McpOAuthError(
@@ -493,9 +504,9 @@ export async function ensureClientRegistration(
493
504
  },
494
505
  body: JSON.stringify({
495
506
  client_name: CLIENT_NAME,
496
- redirect_uris: [redirectUri],
497
- grant_types: ['authorization_code', 'refresh_token'],
498
- response_types: ['code'],
507
+ ...(opts.deviceCode ? {} : { redirect_uris: [redirectUri] }),
508
+ grant_types: opts.deviceCode ? ['urn:ietf:params:oauth:grant-type:device_code', 'refresh_token'] : ['authorization_code', 'refresh_token'],
509
+ response_types: opts.deviceCode ? [] : ['code'],
499
510
  token_endpoint_auth_method: 'none',
500
511
  application_type: 'native',
501
512
  }),
@@ -519,8 +530,15 @@ export async function ensureClientRegistration(
519
530
  const registration: ClientRegistration = {
520
531
  clientId,
521
532
  ...(clientSecret ? { clientSecret } : {}),
522
- redirectUri,
533
+ ...(opts.deviceCode ? {} : { redirectUri }),
523
534
  };
535
+ // A device client is stored only with its first tokens (authorizeMcpDevice): until a device login succeeds,
536
+ // the stored registration and the refresh token paired with it stay as they were.
537
+ if (opts.deviceCode) return registration;
538
+ // A browser registration over another client's live tokens (e.g. after a device login) waits for its own
539
+ // tokens: storing it now would orphan the stored refresh token if this approval is cancelled or fails.
540
+ const existing = loadTokens(metadata.issuer, path);
541
+ if (existing?.tokens.refreshToken && existing.accountUuid && existing.accountUuid !== clientId) return { ...registration, pending: true };
524
542
  persistRegistration(metadata.issuer, registration, path);
525
543
  return registration;
526
544
  }
@@ -546,6 +564,7 @@ export function buildAuthorizationRequest(
546
564
  'authorization server does not advertise code_challenge_methods_supported=S256',
547
565
  );
548
566
  }
567
+ if (!metadata.authorizationEndpoint) throw new McpOAuthError('discovery', 'authorization server has no authorization_endpoint for browser login');
549
568
  const pkce = generatePkcePair();
550
569
  const redirectUri = opts.redirectUri ?? DEFAULT_REDIRECT_URI;
551
570
  const url = new URL(metadata.authorizationEndpoint);
@@ -565,6 +584,7 @@ export function buildAuthorizationRequest(
565
584
  redirectUri,
566
585
  issuer: metadata.issuer,
567
586
  clientId: registration.clientId,
587
+ ...(registration.pending ? { pendingRegistration: registration.clientSecret ? { clientSecret: registration.clientSecret } : {} } : {}),
568
588
  ...(scope ? { scope } : {}),
569
589
  ...(opts.resource ? { resource: opts.resource } : {}),
570
590
  };
@@ -673,13 +693,107 @@ function persistTokens(
673
693
  authMode: AUTH_MODE,
674
694
  ...(clientId ? { accountUuid: clientId } : {}),
675
695
  ...(clientSecret ? { organizationUuid: clientSecret } : {}),
676
- ...(existing?.redirectUri ? { redirectUri: existing.redirectUri } : {}),
696
+ // A loopback URI belongs to the client that registered it — never carry it onto a different (device) client.
697
+ ...(existing?.redirectUri && (!registration || registration.clientId === existing.accountUuid) ? { redirectUri: existing.redirectUri } : {}),
677
698
  mirrorCodex: false,
678
699
  },
679
700
  path,
680
701
  );
681
702
  }
682
703
 
704
+ export interface McpDeviceAuthorization {
705
+ userCode: string;
706
+ verificationUri: string;
707
+ verificationUriComplete?: string;
708
+ }
709
+
710
+ /** RFC 8628: only an advertised endpoint enables the fallback; tokens use the same issuer store. */
711
+ export async function authorizeMcpDevice(
712
+ metadata: AuthorizationServerMetadata,
713
+ registration: ClientRegistration,
714
+ opts: McpOAuthRuntimeOpts & {
715
+ scope?: string;
716
+ resource?: string;
717
+ onDeviceCode: (code: McpDeviceAuthorization) => Promise<void> | void;
718
+ sleep?: (ms: number) => Promise<void>;
719
+ now?: () => number;
720
+ },
721
+ ): Promise<OAuthTokens> {
722
+ const endpoint = metadata.deviceAuthorizationEndpoint;
723
+ if (!endpoint) throw new McpOAuthError('device', 'authorization server does not advertise device_authorization_endpoint');
724
+ const fetchFn = fetchImpl(opts);
725
+ const post = async (url: string, fields: Record<string, string | undefined>) => {
726
+ let response: Awaited<ReturnType<McpOAuthFetch>>;
727
+ try {
728
+ response = await fetchFn(url, {
729
+ method: 'POST',
730
+ headers: { accept: 'application/json', 'content-type': 'application/x-www-form-urlencoded' },
731
+ body: formBody(fields),
732
+ });
733
+ } catch (error) {
734
+ throw new McpOAuthError('device', `device authorization request failed: ${error instanceof Error ? error.message : String(error)}`);
735
+ }
736
+ const text = await response.text();
737
+ return { status: response.status, body: parseJsonObject(text, 'device authorization response', 'device') };
738
+ };
739
+ const started = await post(endpoint, {
740
+ client_id: registration.clientId,
741
+ client_secret: registration.clientSecret,
742
+ scope: opts.scope,
743
+ resource: opts.resource,
744
+ });
745
+ const deviceCode = stringField(started.body, 'device_code');
746
+ const userCode = stringField(started.body, 'user_code');
747
+ const verificationUri = stringField(started.body, 'verification_uri');
748
+ if (started.status < 200 || started.status >= 300 || !deviceCode || !userCode || !verificationUri) {
749
+ const error = stringField(started.body, 'error');
750
+ throw new McpOAuthError('device', `device authorization returned HTTP ${started.status}${error ? ` (${error})` : ''} or missing required fields`);
751
+ }
752
+ requireHttpUrl(verificationUri, 'verification_uri');
753
+ const verificationUriComplete = stringField(started.body, 'verification_uri_complete');
754
+ if (verificationUriComplete) requireHttpUrl(verificationUriComplete, 'verification_uri_complete');
755
+ const seconds = started.body.expires_in;
756
+ if (typeof seconds !== 'number' || !Number.isFinite(seconds) || seconds <= 0) {
757
+ throw new McpOAuthError('device', 'device authorization response has invalid expires_in');
758
+ }
759
+ const now = opts.now ?? Date.now;
760
+ const deadline = now() + Math.min(seconds * 1000, 15 * 60_000);
761
+ let interval = typeof started.body.interval === 'number' && Number.isFinite(started.body.interval) && started.body.interval > 0
762
+ ? Math.max(1000, started.body.interval * 1000) : 5000;
763
+ await opts.onDeviceCode({ userCode, verificationUri, ...(verificationUriComplete ? { verificationUriComplete } : {}) });
764
+ const sleep = opts.sleep ?? ((ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)));
765
+ let attempts = 0;
766
+ while (now() < deadline) {
767
+ if (++attempts > Math.ceil(Math.min(seconds, 900)) + 1) throw new McpOAuthError('device', 'device authorization polling limit exceeded');
768
+ await sleep(Math.min(interval, deadline - now()));
769
+ if (now() >= deadline) break;
770
+ const polled = await post(metadata.tokenEndpoint, {
771
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
772
+ device_code: deviceCode,
773
+ client_id: registration.clientId,
774
+ client_secret: registration.clientSecret,
775
+ resource: opts.resource,
776
+ });
777
+ if (polled.status >= 200 && polled.status < 300) {
778
+ const accessToken = stringField(polled.body, 'access_token');
779
+ if (!accessToken) throw new McpOAuthError('token', 'device token response is missing access_token');
780
+ const tokens: OAuthTokens = {
781
+ accessToken,
782
+ refreshToken: stringField(polled.body, 'refresh_token') ?? '',
783
+ expiresAt: expiresAtFromSeconds(polled.body.expires_in),
784
+ tokenType: stringField(polled.body, 'token_type') ?? 'Bearer',
785
+ ...(stringField(polled.body, 'scope') ? { scope: stringField(polled.body, 'scope') } : {}),
786
+ };
787
+ persistTokens(metadata.issuer, tokens, registration, storePath(opts));
788
+ return tokens;
789
+ }
790
+ const error = stringField(polled.body, 'error');
791
+ if (error === 'slow_down') interval += 5000;
792
+ else if (error !== 'authorization_pending') throw new McpOAuthError('device', `device token request returned HTTP ${polled.status} (${error ?? 'unknown'})`);
793
+ }
794
+ throw new McpOAuthError('device', 'device authorization expired before approval');
795
+ }
796
+
683
797
  export async function exchangeAuthorizationCode(
684
798
  metadata: AuthorizationServerMetadata,
685
799
  request: AuthorizationRequest,
@@ -688,7 +802,10 @@ export async function exchangeAuthorizationCode(
688
802
  ): Promise<OAuthTokens> {
689
803
  const code = verifyAuthorizationCallback(request, callback);
690
804
  const path = storePath(opts);
691
- const registration = loadStoredRegistration(metadata.issuer, { storePath: path });
805
+ const pending = request.pendingRegistration;
806
+ const registration: ClientRegistration | null = pending
807
+ ? { clientId: request.clientId, ...(pending.clientSecret ? { clientSecret: pending.clientSecret } : {}), redirectUri: request.redirectUri }
808
+ : loadStoredRegistration(metadata.issuer, { storePath: path });
692
809
  const tokens = await postToken(
693
810
  metadata.tokenEndpoint,
694
811
  {
@@ -703,7 +820,9 @@ export async function exchangeAuthorizationCode(
703
820
  fetchImpl(opts),
704
821
  'token',
705
822
  );
706
- persistTokens(
823
+ // A pending registration is committed together with the tokens it just earned.
824
+ if (pending) persistRegistration(metadata.issuer, registration!, path, tokens);
825
+ else persistTokens(
707
826
  metadata.issuer,
708
827
  tokens,
709
828
  registration ?? { clientId: request.clientId },
@@ -400,21 +400,50 @@ const GROK: TierMap = {
400
400
  // kimi·qwen·glm 의 «첫 실제 경로». 사다리는 이름 기억이 아니라 ***실물 `/api/v1/models` 사실***로 골랐다
401
401
  // (2026-09-23 실측 · 전 칸 `tools`·`reasoning` 지원 · 가격 $/MTok 입력/출력):
402
402
  // budget qwen3.8-flash 0.15/0.47 1M
403
- // balanced glm-5.3 0.84/2.64 1.31M ← 기본(OPENROUTER_MODEL)
403
+ // balanced glm-5.3 0.039/4.8 1.05M ← 기본(OPENROUTER_MODEL)
404
+ // 별도 모델 glm-5.3-flash 가격·창 미측정 (0으로 기록하지 않는다)
405
+ // 📏 OP 10-10 OpenRouter 실측: GLM-5.3 입력 $0.039/MTok · 출력 $4.8/MTok · 창 1.05M.
404
406
  // better qwen3.8-max-0902 2/6 1M
405
407
  // best kimi-k3 3/15 1.05M
406
- // ⇒ 가격순이면서 세 벤더를 «다» 덮는다. ⛔ 가격·창은 늙는다 — 카탈로그(`openrouter/*` 폴드)가 canonical.
408
+ // ⚠️ GLM 가격 갱신·flash 단가 미측정으로 가격순 주장은 보류한다. 가격·창은 늙는다 — 카탈로그(`openrouter/*` 폴드)가 canonical.
407
409
  // `shipping` = «생성된다»(배선 계약). 도구 호출·도구 루프·elanous 실제 프롬프트 3/3 실측(리서치 문서 §9).
408
410
  // ⚠️ `loaded` 의 reasoningLevel 은 wire 로 «안» 간다 — 측정상 OpenRouter `reasoning.effort` 를 보내면
409
411
  // kimi·glm 이 «덜» 생각한다(필드 없음이 최대). 그래서 옮기지 않았다 — 리서치 문서 §9.
410
412
  const OPENROUTER: TierMap = {
411
413
  budget: { model: 'openrouter/qwen/qwen3.8-flash', label: 'Qwen 3.8 Flash (OpenRouter)', rationale: 'Fast · cheap · 1M ctx', status: 'shipping' },
412
- balanced: { model: 'openrouter/z-ai/glm-5.3', label: 'GLM 5.3 (OpenRouter)', rationale: 'Default · 1.31M ctx', status: 'shipping' },
414
+ balanced: { model: 'openrouter/z-ai/glm-5.3', label: 'GLM 5.3 (OpenRouter)', rationale: 'Default · $0.039/$4.8 per MTok · 1.05M ctx', status: 'shipping' },
413
415
  better: { model: 'openrouter/qwen/qwen3.8-max-0902', label: 'Qwen 3.8 Max (OpenRouter)', rationale: 'Higher quality', status: 'shipping' },
414
416
  best: { model: 'openrouter/moonshotai/kimi-k3', label: 'Kimi K3 (OpenRouter)', rationale: 'Best · Kimi flagship', status: 'shipping' },
415
417
  loaded: { model: 'openrouter/moonshotai/kimi-k3', reasoningLevel: 'high', label: 'Kimi K3 · reasoning high (OpenRouter)', rationale: 'Loaded · deep multi-step', status: 'shipping' },
416
418
  };
417
419
 
420
+ // ── AWS Bedrock (BEDROCK-PROVIDER · 2026-10-11) ───────────────────
421
+ // ⭐ 판단: ANTHROPIC 사다리의 «추론 수준·역할 배치»를 그대로 두고, 모델은 Bedrock 메시지 엔드포인트에서
422
+ // 확인한 5.5 계열 id(`src/llm/bedrock.ts` BEDROCK_MODELS · 출처 platform.claude.com «Claude in Amazon Bedrock»
423
+ // Supported models)로만 채운다. 아래 칸(budget·balanced)은 ANTHROPIC 이 haiku-4-5·sonnet-5 를 쓰지만, 이 PR 이
424
+ // 카탈로그에 올린 Bedrock id 는 5.5 셋뿐이라 같은 등급의 5.5(haiku-5-5·sonnet-5-5)로 올렸다.
425
+ // ⛔ bedrock 은 명시 선택 전용 — 이 표는 `--role-llm <role>=bedrock/<tier>` 같은 «명시» 해석에만 쓰인다.
426
+ // ⚠️ status = `wip`: 실 AWS 호출(계정별 5.5 접근 조건)을 아직 안 쟀고, 셋업 키 감지 표(PROVIDER_ENV_SPEC)에도
427
+ // 없다(자격이 API 키가 아니라 AWS 체인이라). 첫 실호출 스모크 뒤 `shipping` 으로 올린다.
428
+ const BEDROCK: TierMap = {
429
+ budget: { model: 'anthropic.claude-haiku-5-5', reasoningLevel: 'off', label: 'Claude Haiku 5.5 (Bedrock)', rationale: 'Fast · cheap · bulk/classification', status: 'wip' },
430
+ balanced: { model: 'anthropic.claude-sonnet-5-5', reasoningLevel: 'off', label: 'Claude Sonnet 5.5 (Bedrock)', rationale: 'Default · everyday coding (BEDROCK_DEFAULT_MODEL)', status: 'wip' },
431
+ better: { model: 'anthropic.claude-opus-5-5', reasoningLevel: 'medium', label: 'Claude Opus 5.5 · thinking medium (Bedrock)', rationale: 'ANTHROPIC better 와 같은 배치(구현 = Opus 5.5)', status: 'wip' },
432
+ best: { model: 'anthropic.claude-opus-5-5', reasoningLevel: 'medium', label: 'Claude Opus 5.5 · thinking medium (Bedrock)', rationale: 'Best reasoning · architecture', status: 'wip' },
433
+ loaded: { model: 'anthropic.claude-opus-5-5', reasoningLevel: 'high', label: 'Claude Opus 5.5 · extended thinking (Bedrock)', rationale: 'Loaded · deep multi-step', status: 'wip' },
434
+ };
435
+
436
+ /** 가격·창 미측정이라 기존 tier 배치를 바꾸지 않고 명시 모델로만 고르는 칸.
437
+ * 소비 경로 = `lookupOpenRouterModelSpec()` ← `resolveRunFallback()`(openrouter 폴백 판정의 관측·ROUTE 결정). */
438
+ const OPENROUTER_EXPLICIT_MODELS: Readonly<Record<string, LlmTierSpec>> = {
439
+ 'z-ai/glm-5.3-flash': {
440
+ model: 'openrouter/z-ai/glm-5.3-flash',
441
+ label: 'GLM 5.3 Flash (OpenRouter)',
442
+ rationale: 'Fast · 가격/창 미측정',
443
+ status: 'shipping',
444
+ },
445
+ };
446
+
418
447
  // ── Combined lookup ─────────────────────────────────────────────────
419
448
 
420
449
  /** Subset of LLMProviderName that has a tier ladder defined here.
@@ -433,6 +462,7 @@ export const LLM_TIER_MAP_BY_PROVIDER: Readonly<Record<LlmTierProvider, TierMap>
433
462
  glm: GLM,
434
463
  grok: GROK,
435
464
  openrouter: OPENROUTER,
465
+ bedrock: BEDROCK,
436
466
  } as const;
437
467
 
438
468
  /** 사람이 쓰는 tier 별칭 → canonical ModelTier. "grok low tier" 같은 자연어 헷갈림을 SSOT 로 흡수한다.
@@ -454,9 +484,23 @@ export function parseTierArg(raw: string): ModelTier | undefined {
454
484
  * tsc 는 배열 누락을 못 잡는다(2026-09-23 `#19900` 이 `openrouter` 를 빠뜨려 배선 계약 자가 그것을
455
485
  * 한 번도 누르지 않았다). 자 = `provider-wiring-contract.test.ts`. */
456
486
  export const TIER_PROVIDERS: readonly LlmTierProvider[] = [
457
- 'anthropic', 'openai', 'openai-codex', 'gemini', 'grok', 'local', 'kimi', 'qwen', 'glm', 'openrouter',
487
+ 'anthropic', 'openai', 'openai-codex', 'gemini', 'grok', 'local', 'kimi', 'qwen', 'glm', 'openrouter', 'bedrock',
458
488
  ];
459
489
 
490
+ /** OpenRouter 모델 id(`openrouter/<vendor>/<model>` 또는 `<vendor>/<model>`)의 tier-map 칸.
491
+ * 명시 칸(`glm-5.3-flash` 등) → 5-tier 사다리 순으로 찾는다. 모르면 undefined(«미등록»을 기본값으로 접지 않는다). */
492
+ export function lookupOpenRouterModelSpec(model: string): LlmTierSpec | undefined {
493
+ const bare = model.trim().replace(/^openrouter\//, '');
494
+ if (!bare) return undefined;
495
+ const explicit = OPENROUTER_EXPLICIT_MODELS[bare];
496
+ if (explicit) return explicit;
497
+ const wanted = `openrouter/${bare}`;
498
+ for (const tier of ['budget', 'balanced', 'better', 'best'] as const) {
499
+ if (OPENROUTER[tier].model === wanted) return OPENROUTER[tier];
500
+ }
501
+ return undefined;
502
+ }
503
+
460
504
  /** Resolve the spec for (provider, tier).
461
505
  * `auto` and unknown providers have no concrete provider ladder, so both use
462
506
  * Anthropic's balanced default instead of crossing into the Codex family.
@@ -29,8 +29,12 @@ export type ModelFamily =
29
29
  | 'grok'
30
30
  | 'gemini'
31
31
  | 'local'
32
+ | 'open-weight'
32
33
  | 'other';
33
34
 
35
+ /** OpenRouter gateway prefix for OpenAI-served models (see OR-FAMILY-GPT6 in getModelFamily). */
36
+ const OPENROUTER_OPENAI_PREFIX = 'openrouter/openai/';
37
+
34
38
  /** Infer the family from a model id. Mirrors `inferProviderFromModel`
35
39
  * in llm.ts but returns a finer-grained tag (codex vs other gpt,
36
40
  * specifically, because codex-family has the worst observed tool-
@@ -45,6 +49,23 @@ export function getModelFamily(modelId: string | undefined): ModelFamily {
45
49
  if (m.includes('grok')) return 'grok';
46
50
  if (m.startsWith('gemini-')) return 'gemini';
47
51
  if (m.startsWith('local:')) return 'local';
52
+ // OR-FAMILY-GPT6 — `openrouter/openai/<gpt-* | o1-/o3-/o4-*>` is the same model the direct
53
+ // path serves; when its bare id is 'gpt' there (gpt-6-*, gpt-4*, o-series) it gets 'gpt' here
54
+ // too, so it carries the gpt prompt pieces (hygiene addon · preamble addendum · chat variant ·
55
+ // tool-hint cap). Without this it fell to 'other'. ⛔ A 'codex' verdict (bare gpt-5*) is NOT
56
+ // taken: in llm.ts 'codex' also switches tool-loop behaviour (inspect/repair stops, Read
57
+ // auto-narrowing, exploration exemptions, idle timeout) — not just prompt text — and that is a
58
+ // separate decision. Ids with `codex` in them were already 'codex' above. Gateway-prefixed ids
59
+ // only — bare `openai/...` ids are not touched (same LM Studio reason as below).
60
+ if (m.startsWith(OPENROUTER_OPENAI_PREFIX) && getModelFamily(m.slice(OPENROUTER_OPENAI_PREFIX.length)) === 'gpt') {
61
+ return 'gpt';
62
+ }
63
+ // OpenRouter gateway ids only (`openrouter/<vendor>/<model>`). Bare vendor ids such as
64
+ // `qwen/qwen3-coder-30b` stay 'other' on purpose: LM Studio publishes native ids in that
65
+ // same shape (see getModelTier's local pattern), and this family must not reach local runs.
66
+ if (m.startsWith('openrouter/') && (m.includes('glm') || m.includes('kimi') || m.includes('qwen'))) {
67
+ return 'open-weight';
68
+ }
48
69
  return 'other';
49
70
  }
50
71
 
@@ -68,7 +89,7 @@ export function getModelFamily(modelId: string | undefined): ModelFamily {
68
89
  // localhost).
69
90
 
70
91
  import type { LLMProviderName } from '../user-config.js';
71
- import type { SkillTier } from '../skills/runner.js';
92
+ import type { SkillTier } from '../skills/skill-tier.js';
72
93
  import { LLM_TIER_MAP_BY_PROVIDER, TIER_PROVIDERS } from '../model-tier/llm-tier-map.js';
73
94
 
74
95
  function matchesAny(s: string, needles: string[]): boolean {