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
@@ -65,6 +65,12 @@ const POSIX_SHELLS = new Set(['zsh', 'bash', 'fish', 'sh', 'dash', 'ksh']);
65
65
  let cached: Record<string, string> | null = null;
66
66
  let captured = false;
67
67
 
68
+ // Both the daemon warm path (nexus/index.ts) and PTY's first synchronous capture
69
+ // pass through here. Keep the existing capture events intact; these are additive timings.
70
+ function logBootPhase(phase: string, start: number, outcome: string): void {
71
+ debug.log('boot.phase', phase, { ms: performance.now() - start, outcome });
72
+ }
73
+
68
74
  /** Parse `KEY=VALUE\n` output from `printenv`. Tolerates values that
69
75
  * themselves contain `=`; does not attempt to unescape newlines
70
76
  * (bash/zsh `printenv` emits them literally, which is fine for
@@ -121,10 +127,13 @@ function acceptCapture(stdout: string): Record<string, string> | null {
121
127
  }
122
128
 
123
129
  export function runPrintenvCapture(): Record<string, string> | null {
130
+ const seedStart = performance.now();
124
131
  const seed = captureSeed();
132
+ logBootPhase('login-env.seed', seedStart, seed ? 'ready' : 'unavailable');
125
133
  if (!seed) return null;
126
134
  const { shell, seedEnv } = seed;
127
135
 
136
+ const shellStart = performance.now();
128
137
  let res: ReturnType<typeof spawnSync>;
129
138
  try {
130
139
  res = spawnSync(shell, ['-l', '-i', '-c', 'printenv'], {
@@ -137,13 +146,14 @@ export function runPrintenvCapture(): Record<string, string> | null {
137
146
  // OSC sequences would corrupt our TUI output otherwise.
138
147
  });
139
148
  } catch {
149
+ logBootPhase('login-env.shell', shellStart, 'error');
140
150
  return null;
141
151
  }
142
152
  // ETIMEDOUT with status 0 = the shell outlived the timeout; never trust a late capture.
143
- if (res.error) return null;
144
- if (res.status !== 0 && res.status !== null) return null;
145
- if (res.signal) return null;
146
- return acceptCapture(typeof res.stdout === 'string' ? res.stdout : '');
153
+ const parsed = !res.error && (res.status === 0 || res.status === null) && !res.signal
154
+ ? acceptCapture(typeof res.stdout === 'string' ? res.stdout : '') : null;
155
+ logBootPhase('login-env.shell', shellStart, parsed ? 'ok' : 'failed');
156
+ return parsed;
147
157
  }
148
158
 
149
159
  /** Fill the login-env cache off the event loop (daemon boot). The first web-terminal spawn otherwise ran the
@@ -152,9 +162,12 @@ export function runPrintenvCapture(): Record<string, string> | null {
152
162
  export async function warmCapturedEnv(spawn: typeof Bun.spawn = Bun.spawn): Promise<boolean> {
153
163
  if (captured) return cached !== null;
154
164
  if (process.env.ELANOUS_SKIP_LOGIN_ENV === '1' || process.env.TERM_PROGRAM === 'monad-agent-nested') return false;
165
+ const seedStart = performance.now();
155
166
  const seed = captureSeed();
167
+ logBootPhase('login-env.seed', seedStart, seed ? 'ready' : 'unavailable');
156
168
  if (!seed) return false;
157
169
  const start = Date.now();
170
+ const shellStart = performance.now();
158
171
  try {
159
172
  const proc = spawn([seed.shell, '-l', '-i', '-c', 'printenv'], { env: seed.seedEnv as Record<string, string>, stdin: 'ignore', stdout: 'pipe', stderr: 'ignore' });
160
173
  // A grandchild (e.g. a pyenv rehash) can keep the stdout pipe open after the shell is killed,
@@ -167,6 +180,7 @@ export async function warmCapturedEnv(spawn: typeof Bun.spawn = Bun.spawn): Prom
167
180
  const result = await Promise.race([finished, timedOut]);
168
181
  clearTimeout(timer);
169
182
  const parsed = result && result[1] === 0 ? acceptCapture(result[0]) : null;
183
+ logBootPhase('login-env.shell', shellStart, parsed ? 'ok' : result ? 'failed' : 'timeout');
170
184
  if (captured) return cached !== null; // a synchronous capture won the race
171
185
  if (!parsed) return false;
172
186
  cached = parsed;
@@ -174,6 +188,7 @@ export async function warmCapturedEnv(spawn: typeof Bun.spawn = Bun.spawn): Prom
174
188
  debug.log('shell.envbootstrap.capture', 'warmed', { ok: true, ms: Date.now() - start, keyCount: Object.keys(parsed).length });
175
189
  return true;
176
190
  } catch {
191
+ logBootPhase('login-env.shell', shellStart, 'error');
177
192
  return false;
178
193
  }
179
194
  }
@@ -3,7 +3,13 @@ import { execFileSync } from 'node:child_process';
3
3
  import { cpSync, existsSync, lstatSync, mkdtempSync, mkdirSync, readdirSync, rmSync, writeFileSync } from 'node:fs';
4
4
  import { homedir, tmpdir } from 'node:os';
5
5
  import { join } from 'node:path';
6
+ import { gunzipSync } from 'node:zlib';
6
7
  import { debug } from '../debug/log.js';
8
+ import { ensureInternalMarketIndex, ensureMarketIndex, type MarketFetchOptions } from '../plugins/install/market-fetch.js';
9
+ import { scanPackInternalRefs } from '../market/pack-internal-refs.js';
10
+ import { createPack } from '../knowledge/kgs/pack.js';
11
+ import { KgsSqliteStore } from '../knowledge/kgs/sqlite-store.js';
12
+ import type { KnowledgeCard, KnowledgeKind } from '../knowledge/kgs/types.js';
7
13
 
8
14
  export interface GiftInstallOptions {
9
15
  pack: string;
@@ -23,6 +29,119 @@ export type GiftInstallResult =
23
29
  | { ok: true; names: string[]; paths: string[]; collisions: string[]; needsKeys: boolean; message: string }
24
30
  | { ok: false; reason: string; message: string };
25
31
 
32
+ export type KnowledgePackInstallResult =
33
+ | { ok: true; packId: string; citations: string[] }
34
+ | { ok: false; reason: string };
35
+
36
+ /** Install a named knowledge pack from a configured, signed market; no gift code or skill target is involved. */
37
+ export async function installMarketKnowledgePack(input: {
38
+ pack: string;
39
+ market: string;
40
+ enterpriseId?: string;
41
+ marketOptions?: MarketFetchOptions;
42
+ fetch?: typeof fetch;
43
+ store?: Pick<KgsSqliteStore, 'writePack'>;
44
+ }): Promise<KnowledgePackInstallResult> {
45
+ try {
46
+ const verified = input.enterpriseId
47
+ ? await ensureInternalMarketIndex(input.market, input.enterpriseId, input.marketOptions)
48
+ : await ensureMarketIndex(input.market, input.marketOptions);
49
+ const entry = verified.index.knowledgePacks?.find(item => item.name === input.pack);
50
+ if (!entry || (input.enterpriseId ? entry.visibility !== 'internal' || entry.enterpriseId !== input.enterpriseId : entry.visibility !== 'public')) {
51
+ return { ok: false, reason: 'pack-not-in-verified-market' };
52
+ }
53
+ const key = entry.artifact.key;
54
+ if (!key || key.startsWith('/') || key.includes('\\') || key.split('/').some(part => !part || part === '.' || part === '..')) {
55
+ return { ok: false, reason: 'invalid-artifact-key' };
56
+ }
57
+ const base = new URL(verified.market.url);
58
+ const artifactUrl = new URL(key, base);
59
+ if (key.includes('%') || key.includes('?') || key.includes('#') || base.protocol !== 'https:') return { ok: false, reason: 'invalid-artifact-key' };
60
+ if (artifactUrl.origin !== base.origin || !artifactUrl.pathname.startsWith(base.pathname) || artifactUrl.search || artifactUrl.hash) {
61
+ return { ok: false, reason: 'invalid-artifact-key' };
62
+ }
63
+ if (entry.artifact.bytes > MAX_DOWNLOAD_BYTES) return { ok: false, reason: 'artifact-mismatch' };
64
+ const response = await (input.fetch ?? fetch)(artifactUrl.href, { redirect: 'error' });
65
+ if (!response.ok || response.redirected || (response.url && response.url !== artifactUrl.href)) return { ok: false, reason: 'artifact-download-failed' };
66
+ const reader = response.body?.getReader();
67
+ if (!reader) return { ok: false, reason: 'artifact-download-failed' };
68
+ const chunks: Uint8Array[] = [];
69
+ let length = 0;
70
+ for (;;) {
71
+ const { done, value } = await reader.read();
72
+ if (done) break;
73
+ length += value.byteLength;
74
+ if (length > MAX_DOWNLOAD_BYTES || length > entry.artifact.bytes) { await reader.cancel(); return { ok: false, reason: 'artifact-mismatch' }; }
75
+ chunks.push(value);
76
+ }
77
+ const bytes = Buffer.concat(chunks);
78
+ if (bytes.length !== entry.artifact.bytes ||
79
+ createHash('sha256').update(bytes).digest('hex').toLowerCase() !== entry.artifact.sha256.toLowerCase()) {
80
+ return { ok: false, reason: 'artifact-mismatch' };
81
+ }
82
+ const archive = gunzipSync(bytes, { maxOutputLength: MAX_UNPACKED_BYTES });
83
+ const files = new Map<string, string>();
84
+ const decoder = new TextDecoder('utf-8', { fatal: true });
85
+ let endOffset = 0;
86
+ for (let offset = 0; offset + 512 <= archive.length;) {
87
+ const header = archive.subarray(offset, offset + 512);
88
+ if (header.every(byte => byte === 0)) { endOffset = offset; break; }
89
+ const field = (start: number, end: number) => header.subarray(start, end).toString('utf8').replace(/\0.*$/, '');
90
+ const checksum = parseInt(field(148, 156).trim(), 8);
91
+ const actualChecksum = header.reduce((sum, byte, index) => sum + (index >= 148 && index < 156 ? 32 : byte), 0);
92
+ if (checksum !== actualChecksum) return { ok: false, reason: 'invalid-archive' };
93
+ const size = parseInt(field(124, 136).trim(), 8);
94
+ const name = field(0, 100);
95
+ const prefix = field(345, 500);
96
+ const path = prefix ? `${prefix}/${name}` : name;
97
+ if (!Number.isSafeInteger(size) || size < 0 || !path || path.includes('\\') ||
98
+ path.split('/').some(part => !part || part === '.' || part === '..') || header[156] !== 48 ||
99
+ offset + 512 + size > archive.length || files.has(path)) return { ok: false, reason: 'invalid-archive' };
100
+ files.set(path, decoder.decode(archive.subarray(offset + 512, offset + 512 + size)));
101
+ offset += 512 + Math.ceil(size / 512) * 512;
102
+ if (files.size > MAX_ENTRIES) return { ok: false, reason: 'invalid-archive' };
103
+ }
104
+ if (!endOffset || archive.length - endOffset < 1024 || !archive.subarray(endOffset).every(byte => byte === 0)) return { ok: false, reason: 'invalid-archive' };
105
+ const manifest = JSON.parse(files.get('knowledge-pack.json') ?? 'null') as Record<string, unknown> | null;
106
+ if (files.size !== (Array.isArray(manifest?.content) ? manifest.content.length + 1 : -1)) return { ok: false, reason: 'invalid-content' };
107
+ if (!manifest || manifest.kind !== 'knowledge-pack' || manifest.name !== entry.name || manifest.version !== entry.version ||
108
+ !/^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/.test(entry.name) || !/^\d+\.\d+\.\d+$/.test(entry.version) ||
109
+ typeof manifest.description !== 'string' || !manifest.description || manifest.description.length > 200 ||
110
+ !Array.isArray(manifest.content) || !manifest.content.length ||
111
+ !Array.isArray(manifest.dependencies) || manifest.dependencies.length !== 0 ||
112
+ manifest.visibility !== entry.visibility || typeof manifest.license !== 'string' || !manifest.license ||
113
+ !manifest.signature || typeof manifest.signature !== 'object' ||
114
+ (manifest.signature as Record<string, unknown>).algorithm !== 'ed25519' ||
115
+ (manifest.signature as Record<string, unknown>).keyId !== verified.keyId) return { ok: false, reason: 'invalid-manifest' };
116
+ const now = new Date().toISOString();
117
+ const cards: KnowledgeCard[] = [];
118
+ for (const item of manifest.content) {
119
+ if (!item || typeof item !== 'object') return { ok: false, reason: 'invalid-content' };
120
+ const { path, kind } = item as Record<string, unknown>;
121
+ if (typeof path !== 'string' || !/^content\/[a-z0-9-]+(?:\/[a-z0-9-]+)*\.md$/.test(path) || typeof kind !== 'string' ||
122
+ !['document', 'glossary', 'procedure', 'rule', 'qa'].includes(kind) || !files.has(path)) return { ok: false, reason: 'invalid-content' };
123
+ const body = files.get(path)!;
124
+ cards.push({ schema_version: 2, id: path, createdAt: now, updatedAt: now, author: entry.name,
125
+ title: body.match(/^# (.+)$/m)?.[1] ?? path, body, nature: 'fact',
126
+ kind: ({ procedure: 'playbook', glossary: 'wiki', qa: 'card', rule: 'checklist', document: 'note' } as Record<string, KnowledgeKind>)[kind]!,
127
+ reliability: 'self-reported', source: { kind: 'external', url: artifactUrl.href }, tags: [entry.name] });
128
+ }
129
+ if (cards.length > 200 || new Set(cards.map(card => card.id)).size !== cards.length ||
130
+ scanPackInternalRefs([...files].map(([path, text]) => ({ path, text }))).length) return { ok: false, reason: 'invalid-content' };
131
+ const pack = createPack({ id: { slug: entry.name, version: entry.version }, title: manifest.description as string,
132
+ intent: manifest.description as string, audience: input.enterpriseId ? 'team' : 'public', kind: 'generic',
133
+ author: entry.name, cards });
134
+ if (input.store) input.store.writePack(pack);
135
+ else {
136
+ const store = new KgsSqliteStore();
137
+ try { store.writePack(pack); } finally { store.close(); }
138
+ }
139
+ return { ok: true, packId: `pack:${entry.name}@${entry.version}`, citations: cards.map(card => `pack:${entry.name}@${entry.version}#${card.id}`) };
140
+ } catch {
141
+ return { ok: false, reason: 'knowledge-pack-install-failed' };
142
+ }
143
+ }
144
+
26
145
  // GK1 public bundle: packs/elanous-essentials/plugin.json extensions.ai.elanous.bundle.
27
146
  const ESSENTIAL_SKILLS = ['youtube-master', 'omni-crawl', 'omni-digest', 'diagram-master', 'lecture-note-digitizer'];
28
147
  // A malicious or broken gift must not exhaust the temp disk: cap the download, the unpacked total and the entry count.
@@ -3,6 +3,9 @@
3
3
  // substitute template variables, and run them through the selected LLM provider.
4
4
 
5
5
  import { debug } from '../debug/log.js';
6
+ import type { SkillTier } from './skill-tier.js';
7
+ import { randomUUID } from 'node:crypto';
8
+ import { recordSkillRunSafe, type SkillRun } from './skill-feedback.js';
6
9
  import { readFileSync, readdirSync, existsSync, statSync } from 'fs';
7
10
  import { join } from 'path';
8
11
  import { LOCAL_SKILLS_DIR } from '../config.js';
@@ -307,7 +310,7 @@ export interface SkillManifest {
307
310
  }
308
311
 
309
312
  /** Ordered weak→strong. Session 21. */
310
- export type SkillTier = 'T3' | 'T2' | 'T1';
313
+ export type { SkillTier } from './skill-tier.js';
311
314
  const TIER_RANK: Record<SkillTier, number> = { T3: 1, T2: 2, T1: 3 };
312
315
 
313
316
  /** True when `active` is at least as strong as `min`. Missing `min`
@@ -690,6 +693,9 @@ export interface ExecuteSkillOpts {
690
693
  * pure-builder input so tests and future callers can reason about
691
694
  * the final message shape without opening the SQLite store. */
692
695
  promptBankContext?: string;
696
+ /** Use this provider instead of resolving one from config/model hint
697
+ * (tests and hosts that already hold a provider). */
698
+ provider?: LLMProvider;
693
699
  }
694
700
 
695
701
  export interface ExecuteSkillResult {
@@ -968,6 +974,57 @@ export async function executeSkill(
968
974
  args: string,
969
975
  onChunk: (delta: string, full: string) => void,
970
976
  opts: ExecuteSkillOpts = {},
977
+ ): Promise<ExecuteSkillResult> {
978
+ // SK1: one feedback ledger line per run. Recording is fail-soft — the
979
+ // result returned and the exception thrown are exactly the run's own.
980
+ let started: number | undefined;
981
+ try { started = Date.now(); } catch { /* clock trouble must not block the skill */ }
982
+ const feedback = (outcome: SkillRun['outcome'], failureKind?: string): SkillRun => ({
983
+ skill: manifest.name,
984
+ runId: randomUUID(),
985
+ outcome,
986
+ ...(failureKind ? { failureKind } : {}),
987
+ userCorrected: false,
988
+ retries: 0,
989
+ durationMs: started === undefined ? 0 : Math.max(0, Date.now() - started),
990
+ at: new Date().toISOString(),
991
+ });
992
+ const record = (outcome: SkillRun['outcome'], failureKind?: string): void => {
993
+ try {
994
+ recordSkillRunSafe(feedback(outcome, failureKind));
995
+ } catch (error) {
996
+ // Building the record itself failed — still fail-soft, still observed.
997
+ try {
998
+ debug.log('skill.feedback', 'record-failed', { skill: manifest.name, error: String(error) }, { level: 'warn' });
999
+ } catch { /* never let observation change the skill outcome */ }
1000
+ }
1001
+ };
1002
+ let result: ExecuteSkillResult;
1003
+ try {
1004
+ result = await executeSkillUnrecorded(manifest, args, onChunk, opts);
1005
+ } catch (error) {
1006
+ record('failure', skillFailureKind(error));
1007
+ throw error;
1008
+ }
1009
+ record('success');
1010
+ return result;
1011
+ }
1012
+
1013
+ /** Failure kind for the feedback ledger: the exception's name, else 'error'. */
1014
+ function skillFailureKind(error: unknown): string {
1015
+ try {
1016
+ const name = (error as { name?: unknown } | null)?.name;
1017
+ return typeof name === 'string' && name !== '' ? name : 'error';
1018
+ } catch {
1019
+ return 'error';
1020
+ }
1021
+ }
1022
+
1023
+ async function executeSkillUnrecorded(
1024
+ manifest: SkillManifest,
1025
+ args: string,
1026
+ onChunk: (delta: string, full: string) => void,
1027
+ opts: ExecuteSkillOpts,
971
1028
  ): Promise<ExecuteSkillResult> {
972
1029
  debug.log('skill.router', 'executeSkill', {
973
1030
  skill: manifest.name,
@@ -982,7 +1039,7 @@ export async function executeSkill(
982
1039
  // vars. Previously getProvider(modelHint) — env-only — meant a user
983
1040
  // with config.provider=openai-codex but XAI_API_KEY still in env
984
1041
  // would see every skill fall back to Grok.
985
- const provider: LLMProvider = resolveDefaultProvider(rawModelHint);
1042
+ const provider: LLMProvider = opts.provider ?? resolveDefaultProvider(rawModelHint);
986
1043
  // If the skill's declared model belongs to a DIFFERENT provider
987
1044
  // family than the one user-config resolved to, drop it. Example:
988
1045
  // user has openai-codex configured but a skill's SKILL.md says
@@ -1,5 +1,7 @@
1
- import { appendFileSync, readFileSync } from 'node:fs';
1
+ import { appendFileSync, mkdirSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
2
3
  import { debug } from '../debug/log.js';
4
+ import { effectiveInstanceRoot } from '../instance/resolve.js';
3
5
 
4
6
  export interface SkillRun {
5
7
  skill: string;
@@ -25,6 +27,34 @@ export function appendSkillRun(ledgerPath: string, run: SkillRun): void {
25
27
  appendFileSync(ledgerPath, `${JSON.stringify(run)}\n`, 'utf8');
26
28
  }
27
29
 
30
+ /**
31
+ * Ledger for skill runs: `<root>/skills/feedback.jsonl`, root defaulting to the
32
+ * effective instance (state) root — never a skill folder. Creates the directory.
33
+ */
34
+ export function skillFeedbackLedgerPath(root: string = effectiveInstanceRoot()): string {
35
+ const dir = join(root, 'skills');
36
+ mkdirSync(dir, { recursive: true });
37
+ return join(dir, 'feedback.jsonl');
38
+ }
39
+
40
+ /**
41
+ * Fail-soft record of one skill run: resolving or writing the ledger never
42
+ * throws to the caller; a failure leaves a single `record-failed` observation.
43
+ */
44
+ export function recordSkillRunSafe(run: SkillRun, ledgerPath?: string): void {
45
+ try {
46
+ appendSkillRun(ledgerPath ?? skillFeedbackLedgerPath(), run);
47
+ } catch (error) {
48
+ try {
49
+ debug.log('skill.feedback', 'record-failed', { skill: run.skill, error: String(error) }, { level: 'warn' });
50
+ } catch { /* observation must not break the skill result either */ }
51
+ return;
52
+ }
53
+ try {
54
+ debug.log('skill.feedback', 'recorded', { skill: run.skill, outcome: run.outcome, durationMs: run.durationMs });
55
+ } catch { /* fail-soft */ }
56
+ }
57
+
28
58
  /** Read the JSONL ledger in append order; an absent ledger has no runs. */
29
59
  export function readSkillRuns(ledgerPath: string): SkillRun[] {
30
60
  let text: string;
@@ -0,0 +1 @@
1
+ export type SkillTier = 'T3' | 'T2' | 'T1';
@@ -0,0 +1,231 @@
1
+ import { Database } from 'bun:sqlite';
2
+ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
3
+ import { join, resolve } from 'node:path';
4
+ import { elanousStateRoot } from '../autopilot/state-paths.js';
5
+ import { buildCapabilityMatrix } from '../agent-mission/capability-matrix.js';
6
+ import { createCapabilityReaders } from '../agent-mission/capability-readers.js';
7
+ import type { CapabilityEntry } from '../agent-mission/capability-types.js';
8
+ import { readCodexPluginsFromAppServer, type CodexPluginObservation } from '../acp/codex-plugins.js';
9
+ import { kgsDefaultDbPath } from '../knowledge/kgs/sqlite-store.js';
10
+ import { OFFICIAL_INDEX_KEYS } from '../market/official-keys.js';
11
+ import { verifyIndex, type MarketplaceIndex } from '../market/signed-index.js';
12
+ import { readClaudePackageLedger, type ClaudePackageLedger } from '../plugins/adapters/claude-package.js';
13
+ import { ELANOUS_MARKET_URL } from '../plugins/install/market-fetch.js';
14
+ import { buildSkillIndex, skillIndexProblems, type SkillIndexEntry } from '../skills/index.js';
15
+ import { defaultSkillDirs } from '../user-config.js';
16
+
17
+ export type CapabilitySource = 'skills' | 'plugins' | 'knowledge' | 'codex' | 'claude' | 'market';
18
+ export type CapabilityAuth = 'subscription' | 'free' | 'api-key' | 'paid' | 'unknown';
19
+ export interface IndexedCapability {
20
+ readonly id: string;
21
+ readonly kind: 'skill' | 'plugin' | 'knowledge' | 'connector';
22
+ readonly source: CapabilitySource;
23
+ readonly provenance: string;
24
+ readonly auth: CapabilityAuth;
25
+ readonly state: 'installed' | 'candidate' | 'ready' | 'unavailable' | 'unknown';
26
+ readonly capabilities: readonly string[];
27
+ }
28
+ export interface CapabilityIndex {
29
+ readonly sources: Record<CapabilitySource, 'ok' | 'unknown'>;
30
+ readonly entries: readonly IndexedCapability[];
31
+ }
32
+
33
+ export interface CapabilityIndexReaders {
34
+ skills?: () => readonly SkillIndexEntry[];
35
+ skillProblems?: () => readonly { name: string; dir: string }[];
36
+ plugins?: () => readonly { name: string; market: string }[];
37
+ knowledge?: () => readonly { name: string; provenance: string }[];
38
+ codex?: () => Promise<CodexPluginObservation>;
39
+ claude?: () => ClaudePackageLedger;
40
+ /** Production verifies fetched bytes; tests may inject a checked fixture. */
41
+ market?: () => Promise<MarketplaceIndex>;
42
+ matrix?: () => readonly CapabilityEntry[];
43
+ /** Default-path observations (used only when `skills` / `plugins` are not injected). */
44
+ localSkills?: () => LocalSkillsObservation;
45
+ localPlugins?: () => LocalPluginsObservation;
46
+ /** Already verified by the caller (never accepts unverified JSON). */
47
+ verifiedMarket?: MarketplaceIndex;
48
+ }
49
+
50
+ export interface LocalSkillsObservation {
51
+ readonly entries: readonly SkillIndexEntry[];
52
+ /** Roots that exist (or could not be proven absent) but could not be read. */
53
+ readonly unreadableRoots: readonly string[];
54
+ }
55
+
56
+ /** Per-root read: an unreadable root is reported, readable roots keep their candidates. */
57
+ export function readLocalSkills(dirs: readonly string[] = defaultSkillDirs()): LocalSkillsObservation {
58
+ // A missing root is optional; any other stat/read failure must remain unknown.
59
+ const readable: string[] = [];
60
+ const unreadableRoots: string[] = [];
61
+ for (const dir of dirs) {
62
+ try {
63
+ if (!statSync(dir).isDirectory()) throw new Error('skill root is not a directory');
64
+ readdirSync(dir);
65
+ readable.push(dir);
66
+ } catch (error) {
67
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') continue;
68
+ unreadableRoots.push(dir);
69
+ }
70
+ }
71
+ return { entries: readable.length ? buildSkillIndex(readable) : [], unreadableRoots };
72
+ }
73
+
74
+ /** Strict form: throws when any root is unreadable. */
75
+ export function listLocalSkills(dirs: readonly string[] = defaultSkillDirs()): readonly SkillIndexEntry[] {
76
+ const observed = readLocalSkills(dirs);
77
+ if (observed.unreadableRoots.length) throw new Error(`unreadable skill roots: ${observed.unreadableRoots.join(', ')}`);
78
+ return observed.entries;
79
+ }
80
+
81
+ export interface LocalPluginsObservation {
82
+ readonly plugins: readonly { name: string; market: string }[];
83
+ /** `absent` = ENOENT (no installs recorded); `unreadable` = exists but stat/read/parse failed. */
84
+ readonly ledger: 'ok' | 'absent' | 'unreadable';
85
+ /** Plugin directories that exist (or could not be proven absent) but could not be listed. */
86
+ readonly unreadableDirs: readonly string[];
87
+ }
88
+
89
+ /** ENOENT → absent; every other failure is a read failure, never "no candidates". */
90
+ function statKind(path: string, want: 'any' | 'file' = 'any'): 'present' | 'absent' | 'unreadable' {
91
+ try { const stat = statSync(path); return want === 'file' && !stat.isFile() ? 'absent' : 'present'; }
92
+ catch (error) { return (error as NodeJS.ErrnoException).code === 'ENOENT' ? 'absent' : 'unreadable'; }
93
+ }
94
+
95
+ export function readLocalPlugins(
96
+ ledgerPath: string = join(elanousStateRoot(), 'plugins', 'installed.json'),
97
+ localDirs: readonly string[] = [resolve(import.meta.dir, '../../plugins')],
98
+ ): LocalPluginsObservation {
99
+ const plugins: { name: string; market: string }[] = [];
100
+ let ledger: LocalPluginsObservation['ledger'] = 'absent';
101
+ const ledgerKind = statKind(ledgerPath);
102
+ if (ledgerKind === 'unreadable') ledger = 'unreadable';
103
+ else if (ledgerKind === 'present') {
104
+ try {
105
+ const rows: unknown = JSON.parse(readFileSync(ledgerPath, 'utf8'));
106
+ if (!Array.isArray(rows) || !rows.every(row => row && typeof row.name === 'string' && typeof row.market === 'string')) throw new Error('invalid installed plugin ledger');
107
+ plugins.push(...rows.map(row => ({ name: row.name as string, market: row.market as string })));
108
+ ledger = 'ok';
109
+ } catch { ledger = 'unreadable'; }
110
+ }
111
+ const unreadableDirs: string[] = [];
112
+ for (const dir of localDirs) {
113
+ const kind = statKind(dir);
114
+ if (kind === 'absent') continue;
115
+ const found: { name: string; market: string }[] = [];
116
+ try {
117
+ if (kind === 'unreadable') throw new Error('plugin directory unreadable');
118
+ for (const item of readdirSync(dir, { withFileTypes: true })) {
119
+ if (!item.isDirectory()) continue;
120
+ const path = join(dir, item.name);
121
+ const manifests = [statKind(join(path, 'plugin.ts'), 'file'), statKind(join(path, 'plugin.json'), 'file')];
122
+ if (manifests.includes('present')) found.push({ name: item.name, market: dir });
123
+ else if (manifests.includes('unreadable')) unreadableDirs.push(path);
124
+ }
125
+ plugins.push(...found);
126
+ } catch { unreadableDirs.push(dir); }
127
+ }
128
+ return { plugins, ledger, unreadableDirs };
129
+ }
130
+
131
+ function listLocalKnowledge(): readonly { name: string; provenance: string }[] {
132
+ const path = kgsDefaultDbPath();
133
+ if (!existsSync(path)) throw new Error('knowledge store unavailable');
134
+ const db = new Database(path, { readonly: true, create: false });
135
+ try {
136
+ return (db.query('SELECT slug, version FROM kgs_pack ORDER BY slug, version').all() as Array<{ slug: string; version: string }>)
137
+ .map(row => ({ name: `${row.slug}@${row.version}`, provenance: path }));
138
+ } finally { db.close(); }
139
+ }
140
+
141
+ async function readOfficialMarket(): Promise<MarketplaceIndex> {
142
+ const url = new URL('marketplace.json', ELANOUS_MARKET_URL);
143
+ const [raw, sig] = await Promise.all([fetch(url), fetch(new URL('index.sig', url))]);
144
+ if (!raw.ok || !sig.ok) throw new Error('official index unavailable');
145
+ const checked = verifyIndex({ marketplaceBytes: new Uint8Array(await raw.arrayBuffer()), signatureText: await sig.text(), trustedKeys: OFFICIAL_INDEX_KEYS });
146
+ if (!checked.ok || checked.index.name !== 'elanous') throw new Error('official index unverified');
147
+ return checked.index;
148
+ }
149
+
150
+ function marketAuth(entry: MarketplaceIndex['plugins'][number]): CapabilityAuth {
151
+ const policy = entry.policy?.authentication?.toLowerCase();
152
+ if (policy === 'api-key' || policy === 'api_key') return 'api-key';
153
+ if (policy === 'subscription') return 'subscription';
154
+ if (policy === 'paid') return 'paid';
155
+ if (policy === 'none' || policy === 'free') return 'free';
156
+ return 'unknown';
157
+ }
158
+
159
+ /** Read-only, per-source index. No source failure is interpreted as an empty inventory. */
160
+ export async function buildCapabilityIndex(readers: CapabilityIndexReaders = {}): Promise<CapabilityIndex> {
161
+ const sources: CapabilityIndex['sources'] = { skills: 'ok', plugins: 'ok', knowledge: 'ok', codex: 'ok', claude: 'ok', market: 'ok' };
162
+ const entries: IndexedCapability[] = [];
163
+ const attempt = async (source: CapabilitySource, read: () => Promise<void> | void): Promise<void> => {
164
+ const start = entries.length;
165
+ try { await read(); } catch { sources[source] = 'unknown'; entries.splice(start); }
166
+ };
167
+ await attempt('skills', () => {
168
+ const observed: LocalSkillsObservation = readers.skills
169
+ ? { entries: readers.skills(), unreadableRoots: [] }
170
+ : (readers.localSkills ?? readLocalSkills)();
171
+ for (const skill of observed.entries) entries.push({ id: skill.name, kind: 'skill', source: 'skills', provenance: skill.rootDir, auth: 'unknown', state: 'installed', capabilities: [skill.name] });
172
+ if (observed.unreadableRoots.length) {
173
+ sources.skills = 'unknown';
174
+ for (const dir of observed.unreadableRoots) entries.push({ id: dir, kind: 'skill', source: 'skills', provenance: dir, auth: 'unknown', state: 'unknown', capabilities: [] });
175
+ }
176
+ const problems = (readers.skillProblems ?? skillIndexProblems)();
177
+ if (problems.length) {
178
+ sources.skills = 'unknown';
179
+ for (const problem of problems) entries.push({ id: problem.name, kind: 'skill', source: 'skills', provenance: problem.dir, auth: 'unknown', state: 'unknown', capabilities: [problem.name] });
180
+ }
181
+ });
182
+ let installed: readonly { name: string; market: string }[] | undefined;
183
+ await attempt('plugins', () => {
184
+ if (readers.plugins) installed = readers.plugins();
185
+ else {
186
+ const observed = (readers.localPlugins ?? readLocalPlugins)();
187
+ installed = observed.plugins;
188
+ // Absent ledger keeps the earlier contract (unknown); unreadable ledger/dirs never read as "no installs".
189
+ if (observed.ledger !== 'ok' || observed.unreadableDirs.length) sources.plugins = 'unknown';
190
+ for (const dir of observed.unreadableDirs) entries.push({ id: dir, kind: 'plugin', source: 'plugins', provenance: dir, auth: 'unknown', state: 'unknown', capabilities: [] });
191
+ }
192
+ for (const plugin of installed) entries.push({ id: plugin.name, kind: 'plugin', source: 'plugins', provenance: plugin.market, auth: 'unknown', state: 'installed', capabilities: [plugin.name] });
193
+ });
194
+ await attempt('knowledge', () => {
195
+ for (const pack of (readers.knowledge ?? listLocalKnowledge)()) entries.push({ id: pack.name, kind: 'knowledge', source: 'knowledge', provenance: pack.provenance, auth: 'unknown', state: 'installed', capabilities: [pack.name] });
196
+ });
197
+ await attempt('codex', async () => {
198
+ const observation = await (readers.codex ?? readCodexPluginsFromAppServer)();
199
+ if (observation.status === 'unknown') { sources.codex = 'unknown'; return; }
200
+ for (const plugin of observation.plugins) entries.push({ id: plugin.name, kind: 'plugin', source: 'codex', provenance: plugin.marketplace, auth: 'unknown', state: plugin.enabled ? 'installed' : 'unavailable', capabilities: [plugin.name] });
201
+ });
202
+ await attempt('claude', () => {
203
+ const ledger = (readers.claude ?? readClaudePackageLedger)();
204
+ if (ledger.status !== 'ok') sources.claude = 'unknown';
205
+ for (const pkg of ledger.packages) entries.push({ id: pkg.plugin, kind: 'plugin', source: 'claude', provenance: `${pkg.marketplace}:${pkg.source}`, auth: 'unknown', state: 'installed', capabilities: [pkg.plugin] });
206
+ });
207
+ await attempt('market', async () => {
208
+ const index = readers.verifiedMarket ?? await (readers.market ?? readOfficialMarket)();
209
+ if (index.name !== 'elanous') throw new Error('not official market');
210
+ for (const plugin of index.plugins) {
211
+ entries.push({ id: plugin.name, kind: 'plugin', source: 'market', provenance: `${index.name}:${plugin.source.source}`, auth: marketAuth(plugin),
212
+ state: sources.plugins === 'unknown' ? 'unknown' : installed?.some(row => row.name === plugin.name && row.market === index.name) ? 'installed' : 'candidate',
213
+ capabilities: [plugin.name, ...plugin['ai.elanous'].capabilities, ...(plugin['ai.elanous'].vocab ?? [])] });
214
+ for (const connector of plugin['ai.elanous'].connectors) entries.push({ id: connector.id, kind: 'connector', source: 'market', provenance: `${index.name}:${plugin.name}`, auth: marketAuth(plugin), state: sources.plugins === 'unknown' ? 'unknown' : 'candidate', capabilities: [connector.id] });
215
+ }
216
+ for (const pack of index.knowledgePacks ?? []) {
217
+ if (pack.visibility !== 'public') continue;
218
+ entries.push({ id: pack.name, kind: 'knowledge', source: 'market', provenance: index.name, auth: 'unknown', state: 'candidate', capabilities: [pack.name] });
219
+ }
220
+ });
221
+ // Matrix is an additional service observation, not proof of plugin installation.
222
+ let matrix: readonly CapabilityEntry[] = [];
223
+ try { matrix = (readers.matrix ?? (() => buildCapabilityMatrix(createCapabilityReaders())))(); }
224
+ catch { /* Matrix is supplementary; plugin inventories keep their own observation status. */ }
225
+ for (const service of matrix) {
226
+ // Only backends that are index sources are attributed; grok has no source row here, so it is not relabelled.
227
+ if (!service.service || service.service === '*' || (service.backend !== 'codex' && service.backend !== 'claude')) continue;
228
+ entries.push({ id: service.service, kind: 'connector', source: service.backend, provenance: `${service.backend}:mcp`, auth: 'unknown', state: service.state, capabilities: [service.service] });
229
+ }
230
+ return { sources, entries };
231
+ }
@@ -0,0 +1,74 @@
1
+ // The condition extraction (including any LLM judgment) happens before this deterministic selector.
2
+ export type WizardRung = 'a' | 'b' | 'c' | 'd' | 'e';
3
+ export type GraphValueSignal = 'verification' | 'rework' | 'approval' | 'branching' | 'resume' | 'parallel' | 'resolution';
4
+
5
+ export type RungConditions = {
6
+ capabilityGaps: number;
7
+ graphSignals: readonly GraphValueSignal[];
8
+ recurring: boolean;
9
+ needsMemory: boolean;
10
+ unattended: boolean;
11
+ roles: number;
12
+ differentCadences: boolean;
13
+ differentPermissions: boolean;
14
+ handoffs: number;
15
+ };
16
+
17
+ export type RungDecision = {
18
+ rung: WizardRung;
19
+ reasons: string[];
20
+ rejectedHigher: string[];
21
+ };
22
+
23
+ const graphSignalNames: readonly GraphValueSignal[] = [
24
+ 'verification', 'rework', 'approval', 'branching', 'resume', 'parallel', 'resolution',
25
+ ];
26
+ const rungOrder: readonly WizardRung[] = ['a', 'b', 'c', 'd', 'e'];
27
+
28
+ /** Select the lowest rung sufficient for the supplied, already-established conditions. */
29
+ export function classifyRung(conditions: RungConditions): RungDecision {
30
+ const { capabilityGaps, graphSignals, recurring, needsMemory, unattended, roles,
31
+ differentCadences, differentPermissions, handoffs } = conditions;
32
+ for (const [name, value] of Object.entries({ capabilityGaps, roles, handoffs })) {
33
+ if (!Number.isSafeInteger(value) || value < 0) throw new RangeError(`${name} must be a non-negative safe integer`);
34
+ }
35
+ if (graphSignals.some(signal => !graphSignalNames.includes(signal))) {
36
+ throw new TypeError('graphSignals contains an unknown signal');
37
+ }
38
+
39
+ const distinctSignals = graphSignalNames.filter(signal => graphSignals.includes(signal));
40
+ const graphWorthwhile = distinctSignals.length >= 2;
41
+ const loopNeeded = recurring && (needsMemory || unattended);
42
+ const collectiveNeeded = roles >= 2 && (differentCadences || differentPermissions) && handoffs >= 1;
43
+ let rung: WizardRung = 'a';
44
+ const reasons: string[] = [];
45
+ if (capabilityGaps > 0) {
46
+ rung = 'b';
47
+ reasons.push(`b: capability gaps ${capabilityGaps} > 0`);
48
+ }
49
+ if (graphWorthwhile) {
50
+ rung = 'c';
51
+ reasons.push(`c: ${distinctSignals.length} graph value signals >= 2 (${distinctSignals.join(', ')})`);
52
+ }
53
+ if (loopNeeded) {
54
+ rung = 'd';
55
+ reasons.push(`d: recurring and ${[needsMemory && 'needs memory', unattended && 'unattended'].filter(Boolean).join(' / ')}`);
56
+ }
57
+ if (collectiveNeeded) {
58
+ rung = 'e';
59
+ reasons.push(`e: ${roles} roles >= 2, ${[differentCadences && 'different cadences', differentPermissions && 'different permissions'].filter(Boolean).join(' / ')}, handoffs ${handoffs} >= 1`);
60
+ }
61
+ if (reasons.length === 0) reasons.push('a: no higher-rung condition met; one skill call or short chain suffices');
62
+
63
+ const rejected = {
64
+ b: `b: capability gaps ${capabilityGaps} = 0`,
65
+ c: `c: ${distinctSignals.length} distinct graph value signals < 2`,
66
+ d: `d: ${!recurring ? 'not recurring' : 'neither memory nor unattended execution'}`,
67
+ e: `e: ${[
68
+ roles < 2 && `roles ${roles} < 2`,
69
+ !differentCadences && !differentPermissions && 'neither different cadences nor different permissions',
70
+ handoffs < 1 && `handoffs ${handoffs} < 1`,
71
+ ].filter(Boolean).join('; ')}`,
72
+ };
73
+ return { rung, reasons, rejectedHigher: rungOrder.slice(rungOrder.indexOf(rung) + 1).map(higher => rejected[higher as keyof typeof rejected]) };
74
+ }