elanous 0.2.22 → 0.2.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +7 -0
- package/README.md +32 -22
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/chunks/{119fc678.6f591cdb84ca5791.js → 0673cc54.8e2ef1c23e49e190.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{a9f2b54d-40c16bd0efdb04b8.js → 0a09e062-34f747a17d8d8c2e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{f8626309.a4e5d362b1d55e59.js → 0e3acd34.d42b2ef87fdf4234.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +77 -0
- package/apps/pwa/out/_next/static/chunks/{7175-350f4ce2873bc038.js → 1325-dc3f3c21eb181cb4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +34 -0
- package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +24 -0
- package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6767.8e6c5f6e744fcd9f.js → 1505.5826671109111e75.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7327-2d69fb321ba73389.js → 1669-da843ed73aa301f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +36 -0
- package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +122 -0
- package/apps/pwa/out/_next/static/chunks/2528.0af5c0e1fad88df6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +62 -0
- package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/272-b23d2e92161d11fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7899.597af4a9996c907f.js → 2721.bc9a8f36bd85c07a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +149 -0
- package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3961-fbef064c213b2b18.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +309 -0
- package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{d70879db.c66c56a95a91efc6.js → 4c5e95ce.83e9b16add6fcd8c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6158.566c890adc06a459.js → 5313.1697309c532b9856.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{79b78388.663188133449d707.js → 53746282.1be36038d1abd949.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5578.ac963634373b28c6.js +286 -0
- package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5967-c0a80f8ffe5d4050.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1268.0840ff91e083fcbd.js → 5974.360f8441eb0ac1ec.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +74 -0
- package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6571-926ddf024a6ad5df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +64 -0
- package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9832.2ab2e818013574c7.js → 6702.ebbd165d5e4a4a14.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +32 -0
- package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +24 -0
- package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +93 -0
- package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6110.1297d4093fdfbb0d.js → 740.90b31555290236a9.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +148 -0
- package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +226 -0
- package/apps/pwa/out/_next/static/chunks/{9070.067c106528ec1ae6.js → 7518.49161e8f5814abdb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +27 -0
- package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +115 -0
- package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7905.b230b9d06cb4ad5d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8194.484f51e273d9abd2.js → 8264.00e434fbd02e9311.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +8 -0
- package/apps/pwa/out/_next/static/chunks/{088d8e8a.8069543d082bec12.js → 83cfc5c8.349535543c1548b6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +23 -0
- package/apps/pwa/out/_next/static/chunks/{1948.5f35b39eef222a94.js → 8438.ee7f0df3b3f6fcb4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4588.ad3364cb7fb97ada.js → 8532.a86e99acf9b761cb.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/8569.b853a8daa8f31d12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8925-2abfb48af477fb7f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{88729267.9c6c000157c83f2f.js → 89849432.9eaa2f4c9c010965.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +90 -0
- package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +94 -0
- package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +41 -0
- package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +287 -0
- package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +79 -0
- package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3522-1de1319d028ac89c.js → 9502-32c5dc22e8f120f5.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +104 -0
- package/apps/pwa/out/_next/static/chunks/{7630.2b9a68659053ff4e.js → 9976.8f28864317639fe6.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d5341ac96203a983.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-0160ab83c8685a12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-55c631c032dcc47e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-ad3bd8084048bee4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-e6784759a2531031.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-5c5d0e370f495ef6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-c325e21543cd48a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/{page-80ed511e02c81412.js → page-6168a7c43e6ef8f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-31417d3604154a6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-e9606dc0bdec9305.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-a648bc464c9dc754.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-25bb425afdb27541.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-32d72fdef1afe11a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-d27b794c8ba76bbb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-2bd9ce9c020d02d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a34096245e63b9f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-22170f4f00a15496.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-4cc66d22ca4ec502.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-83b14c729fcea837.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-6e2781c523dad761.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-26dd415c8f13f341.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-ccdb83ed40c8d724.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-7ad3de8fa06fdea9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-015c02c4fec4023e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-6b0ae5b5c42f6d2f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-786111f30b6f0969.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-48fb31810693c357.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e17cce5e2ed0fee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-cb154acadb025414.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-16258e956ea93fc2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-c2dd2b19c93f90ab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-85f35dd1dd96ae87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-d3c007c8a0ddd7ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7837ce2aacb97b04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7350ee93f4fe1033.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-00723458575f2b19.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-745d9b6c015076f8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-736d33c7414a8a1a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-119be9a0444d2482.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-fa806c018833e332.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-c782041b5f5199ba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-d431fbdea6ad93dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-0c056abff82b9891.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-242d668e4fbf72c4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-847c3de6ca8a4416.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-81dd0d8ae923ed72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-74e69ba2c8e970d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-70038f41ae7cf931.js +1 -0
- package/apps/pwa/out/_next/static/chunks/b4e12462-5fab4a813a63dadd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{f6b7c9ba.64a895b8b2fedbdc.js → ce383d63.d2ede338788ed18e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{framework-5c169757551134ed.js → framework-b2763b10dc6b3836.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +1 -0
- package/apps/pwa/out/_next/static/css/5619d59e87eddf66.css +1 -0
- package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
- package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → rfkMm4movqkqMebBrCXiR}/_buildManifest.js +1 -1
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +24 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +22 -22
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +24 -23
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/catalog/models/anthropic/claude-haiku-5-5.yaml +32 -0
- package/catalog/models/anthropic/claude-opus-5-5.yaml +5 -0
- package/catalog/models/anthropic/claude-sonnet-5-5.yaml +31 -0
- package/catalog/models/anthropic/claude-sonnet-5.yaml +8 -2
- package/catalog/models/openai/gpt-6-astra.yaml +6 -0
- package/catalog/models/openai/gpt-6-luna.yaml +6 -0
- package/catalog/models/openai/gpt-6-sol.yaml +6 -0
- package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
- package/graphs/log-horizon/recipes.yaml +3 -0
- package/graphs/release/recipes.yaml +1 -1
- package/graphs/release/release-loop.yaml +6 -2
- package/graphs/release-rehearsal/recipes.yaml +12 -0
- package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
- package/package.json +4 -1
- package/scripts/bench-report.ts +82 -3
- package/scripts/ci-typecheck-changed.ts +10 -1
- package/scripts/hq/hq-fence-wrapper.sh +148 -0
- package/scripts/lib/typecheck-ratchet.ts +51 -0
- package/scripts/openai-relay-server.ts +5 -1
- package/scripts/release-loop/docs-node.ts +258 -43
- package/scripts/release-loop/gate-method.ts +59 -0
- package/scripts/release-loop/gate-node.ts +73 -7
- package/scripts/release-loop/gate-wall.ts +208 -0
- package/scripts/release-loop/known-issues-node.ts +53 -8
- package/scripts/release-loop/publish-at.ts +14 -0
- package/scripts/release-loop/publish-node.ts +17 -2
- package/scripts/release-loop/resume-release.ts +34 -4
- package/scripts/release-loop/resume.ts +53 -0
- package/scripts/release-loop/shard-plan.ts +3 -11
- package/scripts/release-loop/tui-node-checks.ts +22 -0
- package/scripts/release-loop/unattended-release.ts +8 -1
- package/scripts/rhythm/daily.ts +51 -2
- package/scripts/rhythm/weekly.ts +3 -2
- package/scripts/tsc-main-safety-net.ts +189 -0
- package/scripts/usage-rollup.ts +8 -4
- package/src/acp/codex-plugins.ts +48 -6
- package/src/agent/monad-agent-turn.ts +67 -5
- package/src/agent/run-context.ts +10 -0
- package/src/agent/tool-profile.ts +28 -2
- package/src/agent-mission/acp-judge.ts +8 -2
- package/src/agent-mission/capabilities-cli.ts +16 -1
- package/src/agent-mission/driver.ts +1 -1
- package/src/agent-mission/pr-review-watch.ts +6 -2
- package/src/agent-mission/review-loop.ts +33 -5
- package/src/agent-substrate/acp-reviewer.ts +17 -8
- package/src/agent-substrate/pr-reviewer.ts +164 -28
- package/src/agent-substrate/review-intent.ts +6 -4
- package/src/agent-substrate/self-review-cli.ts +111 -16
- package/src/agent-substrate/shard-boundary-intent.ts +92 -26
- package/src/ask-user-question/pending-questions.ts +8 -2
- package/src/autopilot/build/llm-conflict-merge.ts +216 -12
- package/src/autopilot/codebase-grounding.ts +44 -0
- package/src/autopilot/llm-control-brain.ts +13 -1
- package/src/autopilot/mission-codebase-gate.ts +8 -77
- package/src/autopilot/pr-manager.ts +12 -3
- package/src/boot/acp-server.ts +4 -7
- package/src/boot/acp-socket-path.ts +7 -0
- package/src/briefing/brief-items.ts +21 -13
- package/src/chat/index.ts +12 -3
- package/src/cli/agent-cli.ts +20 -0
- package/src/cli/brief-cli.ts +27 -21
- package/src/cli/cli-user-error.ts +9 -2
- package/src/cli/log-event-names.ts +3 -0
- package/src/cli/logs-cli.ts +1 -0
- package/src/cli/mcp-login.ts +111 -37
- package/src/cli/plugin-cli.ts +21 -1
- package/src/cli/pod-cli.ts +26 -0
- package/src/cli/pr-cli.ts +30 -2
- package/src/cli/pr-land-overlap-evidence.ts +131 -0
- package/src/cli/release-cli.ts +53 -11
- package/src/cli/self-update.ts +173 -10
- package/src/cli/skills-cli.ts +12 -3
- package/src/cli/tasks-cli.ts +133 -27
- package/src/context-bus/context-first.ts +51 -2
- package/src/context-bus/context-now-surfaces.ts +13 -2
- package/src/context-bus/long-term-memory.ts +3 -1
- package/src/context-bus/nightly-condense.ts +3 -2
- package/src/core-turn/run-goal-loop.ts +86 -2
- package/src/dashboard/chat-fold.ts +20 -0
- package/src/dashboard/first-screen-band.ts +151 -1
- package/src/dashboard/index.ts +27 -5
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -3
- package/src/dashboard/stale-install-check.ts +13 -2
- package/src/dashboard/turn-stream-formatter.ts +25 -0
- package/src/debug/log-diet.ts +159 -0
- package/src/debug/log.ts +52 -17
- package/src/display/coordinator.ts +25 -2
- package/src/domains/coo-admin-tool.ts +27 -0
- package/src/domains/cron-match.ts +1 -0
- package/src/domains/outbound-alert.ts +17 -6
- package/src/domains/release-tool.ts +119 -10
- package/src/domains/schedule-registry.ts +10 -7
- package/src/domains/schedule-runner.ts +1 -0
- package/src/elanous-config-dir.ts +2 -2
- package/src/elanous-daemon.ts +3 -3
- package/src/execution-loop/launch-gate.ts +1 -1
- package/src/expression/i18n/messages.en.ts +5 -0
- package/src/expression/i18n/messages.ja.ts +5 -0
- package/src/expression/i18n/messages.ko.ts +5 -0
- package/src/expression/i18n/messages.zh.ts +5 -0
- package/src/expression/i18n/types.ts +8 -0
- package/src/github/pr-labels.ts +1 -0
- package/src/graph-runner/runner.ts +54 -5
- package/src/harness/dispatch-backpressure.ts +259 -0
- package/src/harness/harness-cli-command.ts +107 -28
- package/src/harness/harness-seams.ts +2 -20
- package/src/harness/harness-substrate-default.ts +72 -1
- package/src/harness/nested-elanous-policy.ts +4 -2
- package/src/hq/fence-wrapper.ts +7 -0
- package/src/hq/hq.ts +33 -2
- package/src/hq/lease.ts +13 -0
- package/src/hq/seats.ts +114 -18
- package/src/index.ts +163 -64
- package/src/intake-plane/collect-github.ts +19 -1
- package/src/intake-plane/digest.ts +45 -20
- package/src/intake-plane/lens.ts +36 -8
- package/src/intelligence-map/model-alias.ts +6 -0
- package/src/intelligence-map/model-catalog.ts +41 -0
- package/src/knowledge/kgs/pack.ts +5 -2
- package/src/knowledge/kgs/sqlite-store.ts +15 -0
- package/src/knowledge/tools/knowledge-query.ts +20 -2
- package/src/knowledge/write.ts +234 -2
- package/src/llm/bedrock-provider.ts +175 -0
- package/src/llm/bedrock.ts +345 -0
- package/src/llm/provider-credentials.ts +3 -1
- package/src/llm.ts +306 -35
- package/src/loops/budget.ts +150 -0
- package/src/loops/orchestrator/seat-share.ts +6 -49
- package/src/loops/orchestrator/traffic.ts +5 -81
- package/src/market/signed-index.ts +42 -0
- package/src/mcp/mcp-oauth.ts +136 -17
- package/src/model-tier/llm-tier-map.ts +48 -4
- package/src/models/prompts.ts +22 -1
- package/src/mss/logging/horizon-watch.ts +168 -0
- package/src/mss/logging/log-store.ts +204 -15
- package/src/native-tool-catalog.ts +1 -1
- package/src/nexus/api/consult-requests.ts +7 -10
- package/src/nexus/api/discord-trigger-bot.ts +6 -3
- package/src/nexus/api/error-reports.ts +30 -8
- package/src/nexus/api/http-server.ts +8 -0
- package/src/nexus/api/loop-resources.ts +42 -0
- package/src/nexus/api/outbound-report.ts +8 -3
- package/src/nexus/api/telegram-trigger-bot.ts +6 -3
- package/src/nexus/index.ts +10 -0
- package/src/nexus/outbound/format.ts +2 -0
- package/src/nexus/outbound/router.ts +198 -13
- package/src/oauth/codex-account-rotation.ts +16 -18
- package/src/oauth/codex-account-store.ts +134 -5
- package/src/oauth/fallback-chain.ts +28 -6
- package/src/onboarding.ts +2 -1
- package/src/plugins/adapters/claude-package.ts +4 -12
- package/src/plugins/core/capability-policy.ts +141 -0
- package/src/plugins/core/host.ts +21 -8
- package/src/plugins/core/manifest.ts +19 -2
- package/src/plugins/core/trust-store.ts +15 -0
- package/src/plugins/core/types.ts +12 -0
- package/src/plugins/install/market-fetch.ts +68 -16
- package/src/plugins/install/plugin-install.ts +187 -16
- package/src/plugins/maker/plugin-maker.ts +25 -20
- package/src/plugins/maker/wizard-generate.ts +16 -2
- package/src/policy/llm-policy.ts +14 -1
- package/src/process/pid-liveness.ts +1 -1
- package/src/prompt-cache/openai.ts +10 -6
- package/src/prompt-cache/openrouter.ts +94 -0
- package/src/prompt-enhance/enhance.ts +46 -5
- package/src/prompt-library/family-prompt-coverage.ts +1 -0
- package/src/prompt-library/universal-preamble.ts +2 -2
- package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
- package/src/registry/loader.ts +6 -1
- package/src/release-loop/checklist.ts +24 -9
- package/src/release-loop/feature-store.ts +3 -0
- package/src/release-loop/gate-shards.ts +48 -4
- package/src/release-loop/landed-to-green.ts +81 -0
- package/src/release-loop/light-rc.ts +11 -1
- package/src/release-loop/merged-pr-checklist.ts +10 -0
- package/src/release-loop/placement.ts +91 -22
- package/src/release-loop/rehearsal.ts +317 -0
- package/src/release-loop/release-schedule.ts +13 -1
- package/src/release-loop/rubric-types.ts +1 -0
- package/src/release-loop/rubric.ts +2 -2
- package/src/retro/daily.ts +23 -9
- package/src/seat-loop/seat-loop.ts +34 -1
- package/src/seat-loop/traffic-signal.ts +44 -0
- package/src/self-dev/ask-launch-flow.ts +2 -2
- package/src/self-dev/dev-cli.ts +67 -3
- package/src/self-dev/dev-pipeline.ts +4 -6
- package/src/self-dev/draft-residue.ts +463 -0
- package/src/self-dev/draft-sweep.ts +151 -10
- package/src/self-dev/draft-triage-rules.ts +27 -1
- package/src/self-dev/launch-preflight-text.ts +549 -0
- package/src/self-dev/launch-preflight.ts +10 -545
- package/src/self-dev/orchestrate-cli.ts +57 -2
- package/src/self-dev/orchestrate-summary-line.ts +13 -0
- package/src/self-dev/orchestrate.ts +8 -135
- package/src/self-dev/review-provider-fallback.ts +115 -19
- package/src/self-dev/run-store.ts +1 -3
- package/src/self-dev/run-supervisor.ts +3 -22
- package/src/self-dev/run-types.ts +178 -0
- package/src/self-dev/shard-aggregate.ts +61 -13
- package/src/self-dev/shard-plan.ts +5 -1
- package/src/self-dev/shard-run.ts +23 -5
- package/src/self-dev/supervisor-verdict-edges.ts +2 -4
- package/src/self-implement/blocked-draft-policy.ts +3 -19
- package/src/self-implement/draft-on-stop-mode.ts +18 -0
- package/src/self-implement/follow-up-goals.ts +114 -38
- package/src/self-implement/gate-baseline-reap.ts +157 -0
- package/src/self-implement/gate-baseline.ts +78 -16
- package/src/self-implement/gate-cli.ts +12 -2
- package/src/self-implement/gate-remote.ts +17 -6
- package/src/self-implement/goal-author.ts +24 -4
- package/src/self-implement/goal-digest.ts +19 -0
- package/src/self-implement/graph-overlay-condition.ts +4 -0
- package/src/self-implement/headless-elanous-driver.ts +11 -9
- package/src/self-implement/host-regate.ts +120 -29
- package/src/self-implement/l8-merge-queue.ts +67 -5
- package/src/self-implement/merge-train.ts +131 -0
- package/src/self-implement/off-diff-evidence.ts +9 -0
- package/src/self-implement/orchestrator.ts +133 -16
- package/src/self-implement/review-finding-recurrence.ts +28 -0
- package/src/self-implement/rework-policy.ts +2 -1
- package/src/self-implement/round-summary-card.ts +63 -0
- package/src/self-implement/run-ledger.ts +4 -3
- package/src/self-implement/run-step-projection.ts +147 -0
- package/src/self-implement/run-stop.ts +1 -1
- package/src/self-implement/seams.ts +36 -3
- package/src/self-implement/self-implement-cli.ts +3 -1
- package/src/self-implement/train-gate-remote.ts +158 -0
- package/src/session-runtime/index.ts +10 -1
- package/src/session-runtime/retry-api.ts +11 -1
- package/src/skills/gift-install.ts +119 -0
- package/src/skills/runner.ts +59 -2
- package/src/skills/skill-feedback.ts +31 -1
- package/src/skills/skill-tier.ts +1 -0
- package/src/smart-wizard/capability-index.ts +231 -0
- package/src/smart-wizard/rung.ts +74 -0
- package/src/steward/launch.ts +20 -9
- package/src/steward/triage.ts +4 -2
- package/src/storage/file-lock.ts +8 -1
- package/src/task-agent/actions.ts +4 -0
- package/src/task-agent/card-evidence.ts +59 -13
- package/src/task-agent/judge.ts +4 -3
- package/src/task-agent/land-worktree.ts +201 -0
- package/src/task-agent/live-move-history.ts +133 -0
- package/src/task-agent/live-moves.ts +106 -19
- package/src/task-agent/parent-host.ts +117 -8
- package/src/task-agent/rejudge-on-head.ts +297 -0
- package/src/task-agent/review-result-capture.ts +218 -0
- package/src/task-agent/shadow.ts +103 -7
- package/src/task-agent/task-hand.ts +136 -11
- package/src/task-orchestrator/surfaces/pod-child-providers.ts +29 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +16 -2
- package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +93 -12
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +25 -2
- package/src/task-orchestrator/surfaces/pod-pool.ts +66 -14
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +259 -36
- package/src/task-orchestrator/surfaces/self-implement.ts +6 -2
- package/src/telegram-service.ts +5 -1
- package/src/telegram.ts +17 -4
- package/src/time/format.ts +13 -4
- package/src/tool-runtime/goal-author-runtime.ts +1 -0
- package/src/tool-runtime/self-cognition-catalog.ts +23 -0
- package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
- package/src/user-config.ts +132 -24
- package/src/ux-sim/slash-menu-frames.ts +168 -0
- package/src/version/packed-revision.json +1 -1
- package/src/web-terminal/preview-tap-registry.ts +5 -2
- package/src/workflow-runtime/triggers/scheduler.ts +1 -0
- package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
- package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
- package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
- package/apps/pwa/out/_next/static/chunks/1307-08b716476f1d50af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
- package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
- package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
- package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
- package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
- package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
- package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
- package/apps/pwa/out/_next/static/chunks/2489-d238d3e2eb5b2bf5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
- package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3857-5985236d9307f676.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
- package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
- package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
- package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
- package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5633-d6852385000738ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
- package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5977-5b9e8a45a5b0c823.js +0 -1
- package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
- package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
- package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
- package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
- package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
- package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
- package/apps/pwa/out/_next/static/chunks/8857-aa1cc4ac90af4d40.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
- package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9247-55bcfbb0e8057f59.js +0 -1
- package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
- package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-88459e0903da2803.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d85c43f46f58716b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-4e645600579ae952.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-87edbfd19117823b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-7f0c2b7801ac6a54.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-bf1f030a9d1adffd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-cbaf66b1e1804adf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-9f5610caaa06178c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-ec8f3575e339de74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-86d753e460f1a989.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-4166a7d51cf0a57d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-2a19c5cd3b562580.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-b6a09cde2e07521a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-f7eae1518ca0c353.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-456a8573ad811381.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-8462d6a543cbb2d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-2974cdfb87c0f9c9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-f927ffa25f3c86d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-abd86cd832aaa011.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-79daf68f6256adaa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8c3f168fc3f91939.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-786fb4504d0f2fa9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-75209f14597dcb8f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-bf30affe3a85af7e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1187a44b7515434b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-3d0910185a66ed54.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f401ee1dd5a26e25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-5dfe7604fd842784.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-76cf838050a8d681.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-7ec8e289b4c14df6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-8c8ac17d52be2a79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-d359ab048d63a9d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-b8b345c880bf78d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-f151cc10ad026940.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9875f103057da433.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-9789328af9a9aa62.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-bf495a1e284f4e00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-a263d94bca4be22a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-3962eab8ec58d16e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-9abcfac07e02a542.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-bee49f927c333abb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-bac2d56dcb02d955.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-937cbcc13176295c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d09495594f7f480d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-69cb93d1a2e57e0e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-72ec543928d67c3e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-82906eeda0186a7b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
- package/apps/pwa/out/_next/static/css/f2bd5257e6af88d8.css +0 -1
- /package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → rfkMm4movqkqMebBrCXiR}/_ssgManifest.js +0 -0
package/src/skills/runner.ts
CHANGED
|
@@ -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
|
|
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
|
+
}
|
package/src/steward/launch.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { closeSync, mkdirSync, openSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { join, resolve } from 'node:path';
|
|
4
|
+
import { getElanousConfigDir } from '../elanous-config-dir.js';
|
|
5
|
+
import { resolveHqLaunchSeat } from '../hq/seats.js';
|
|
4
6
|
import { debug } from '../debug/log.js';
|
|
5
7
|
import { publishInsideEvent } from '../nexus/api/inside-events.js';
|
|
6
8
|
import { redactSecrets } from '../task-cards/card-store.js';
|
|
@@ -42,9 +44,11 @@ export interface LaunchDeps {
|
|
|
42
44
|
settings: StewardSettings;
|
|
43
45
|
ledger: LaunchLedger;
|
|
44
46
|
/** Injected command boundary; the production adapter runs only argv, never a shell. */
|
|
45
|
-
command?: (args: string[]) => { exitCode: number; stdout: string; stderr?: string };
|
|
46
|
-
spawn?: (args: string[], log: string) => { pid: number };
|
|
47
|
+
command?: (args: string[], seat?: string) => { exitCode: number; stdout: string; stderr?: string };
|
|
48
|
+
spawn?: (args: string[], log: string, seat?: string) => { pid: number };
|
|
47
49
|
gate?: (goalId: string, budget: BudgetDecision | 'unknown') => PreLaunchGateDecision;
|
|
50
|
+
/** Production commands run from the registered OP view; tests can supply an isolated view. */
|
|
51
|
+
launchSeat?: () => string;
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
const RUN_ID = /\brun-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/i;
|
|
@@ -52,7 +56,7 @@ const DEFAULT_POOL = 'pool-node-b@node-b:8';
|
|
|
52
56
|
// `harness budget --json` outcomes: proceed | next-provider | wait-reset | stop. next-provider still runs (the harness switches provider itself).
|
|
53
57
|
const BUDGET_PROCEED: readonly string[] = ['proceed', 'next-provider'];
|
|
54
58
|
const launchMode = (settings: StewardSettings): 'off' | 'shadow' | 'live' => launchModeOf(settings.mode ?? settings.launch ?? 'shadow');
|
|
55
|
-
const cli = (args: string[]) => [
|
|
59
|
+
const cli = (args: string[]) => [process.execPath, resolve(import.meta.dir, '../../bin/elanous.mjs'), ...(process.env.NODE_ENV === 'test' ? ['--test'] : []), ...args];
|
|
56
60
|
const sourceOf = (issue: TriageIssue): string => /^출처: (telegram|pwa|tui|cli)$/m.exec(issue.body)?.[1] ?? `linear:${issue.identifier}`;
|
|
57
61
|
const promptOf = (issue: TriageIssue): string => `${issue.title}\n${issue.body.slice(0, 1500)}`;
|
|
58
62
|
const argvFor = (issue: TriageIssue, settings: StewardSettings): string[] =>
|
|
@@ -100,15 +104,19 @@ export function planLaunches(rows: ScheduledDecision[], issues: TriageIssue[], l
|
|
|
100
104
|
return { launches, hitl };
|
|
101
105
|
}
|
|
102
106
|
|
|
103
|
-
function
|
|
104
|
-
|
|
107
|
+
function stewardLaunchSeat(): string {
|
|
108
|
+
return resolveHqLaunchSeat('OP', getElanousConfigDir());
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function runCommand(args: string[], cwd = resolve(import.meta.dir, '../..')): { exitCode: number; stdout: string; stderr: string } {
|
|
112
|
+
const result = Bun.spawnSync(args, { cwd, stdout: 'pipe', stderr: 'pipe' });
|
|
105
113
|
return { exitCode: result.exitCode, stdout: result.stdout.toString(), stderr: result.stderr.toString() };
|
|
106
114
|
}
|
|
107
115
|
|
|
108
|
-
function spawnDetached(args: string[], log: string): { pid: number } {
|
|
116
|
+
function spawnDetached(args: string[], log: string, seat = stewardLaunchSeat()): { pid: number } {
|
|
109
117
|
const fd = openSync(log, 'a');
|
|
110
118
|
try {
|
|
111
|
-
const child = Bun.spawn(args, { cwd:
|
|
119
|
+
const child = Bun.spawn(args, { cwd: seat, stdout: fd, stderr: fd, stdin: 'ignore', detached: true });
|
|
112
120
|
child.unref();
|
|
113
121
|
return { pid: child.pid };
|
|
114
122
|
} finally { closeSync(fd); }
|
|
@@ -149,9 +157,12 @@ export function launch(item: LaunchItem, deps: LaunchDeps): LaunchEntry {
|
|
|
149
157
|
// L6: a launch must remain on the isolated Pod pool, never fall back to the host or another substrate.
|
|
150
158
|
if (!/^[a-zA-Z0-9_-]+(?:@[a-zA-Z0-9._-]+(?::[1-9][0-9]*)?)?$/.test(settings.podPool ?? DEFAULT_POOL))
|
|
151
159
|
return blocked('blocked-location', 'invalid steward pod pool');
|
|
160
|
+
let seat: string;
|
|
161
|
+
try { seat = (deps.launchSeat ?? stewardLaunchSeat)(); }
|
|
162
|
+
catch (error) { return blocked('blocked-location', `steward OP seat unavailable: ${String(error)}`); }
|
|
152
163
|
let budget: BudgetDecision | 'unknown' = 'unknown';
|
|
153
164
|
try {
|
|
154
|
-
const result = command(cli(['harness', 'budget', '--json']));
|
|
165
|
+
const result = command(cli(['harness', 'budget', '--json']), seat);
|
|
155
166
|
const decision = result.exitCode === 0 ? lastJson(result.stdout) : {};
|
|
156
167
|
if (!BUDGET_PROCEED.includes(String(decision.outcome)))
|
|
157
168
|
return blocked('skipped-budget', result.exitCode === 0 ? JSON.stringify(decision.reasons ?? ['budget unavailable']) : result.stderr ?? 'budget unavailable');
|
|
@@ -171,7 +182,7 @@ export function launch(item: LaunchItem, deps: LaunchDeps): LaunchEntry {
|
|
|
171
182
|
ledger.launches[key] = entry;
|
|
172
183
|
saveLaunchLedger(root, ledger);
|
|
173
184
|
try {
|
|
174
|
-
entry.pid = (deps.spawn ?? spawnDetached)(argvFor(item.issue, settings), entry.log).pid;
|
|
185
|
+
entry.pid = (deps.spawn ?? spawnDetached)(argvFor(item.issue, settings), entry.log, seat).pid;
|
|
175
186
|
} catch (error) {
|
|
176
187
|
entry.status = 'failed';
|
|
177
188
|
entry.reason = redactSecrets(String(error));
|
package/src/steward/triage.ts
CHANGED
|
@@ -62,6 +62,8 @@ export interface StewardDeps {
|
|
|
62
62
|
launchSettings?: Pick<StewardSettings, 'mode' | 'launch' | 'maxParallel' | 'podPool'>;
|
|
63
63
|
launchCommand?: LaunchDeps['command'];
|
|
64
64
|
spawnLaunch?: LaunchDeps['spawn'];
|
|
65
|
+
/** Isolated OP view for tests; production resolves the registered HQ seat (launch.ts stewardLaunchSeat). */
|
|
66
|
+
launchSeat?: LaunchDeps['launchSeat'];
|
|
65
67
|
launchGate?: LaunchDeps['gate'];
|
|
66
68
|
outcomeNotify?: Pick<OutcomeNotifyDeps, 'document' | 'message' | 'worktreeCommand' | 'loadOrigin' | 'loadOrigins'>;
|
|
67
69
|
/** Internal command boundary: the current sync has already claimed this pid. */
|
|
@@ -450,7 +452,7 @@ export async function runStewardStage(stage: 'sync' | 'triage' | 'schedule' | 'r
|
|
|
450
452
|
}); } catch { /* logging must not change the schedule */ }
|
|
451
453
|
writeFileSync(schedule, JSON.stringify(rows));
|
|
452
454
|
const ledger = readLaunchLedger(root);
|
|
453
|
-
const launchDeps: LaunchDeps = { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch, gate: deps.launchGate };
|
|
455
|
+
const launchDeps: LaunchDeps = { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch, gate: deps.launchGate, launchSeat: deps.launchSeat };
|
|
454
456
|
const cardDeps = { root, store: deps.cardStore, now: deps.now };
|
|
455
457
|
collectOutcomes(ledger, launchDeps);
|
|
456
458
|
const plan = planLaunches(rows, issues, ledger, settings);
|
|
@@ -510,7 +512,7 @@ export async function runStewardStage(stage: 'sync' | 'triage' | 'schedule' | 'r
|
|
|
510
512
|
writeFileSync(path, JSON.stringify(state));
|
|
511
513
|
}
|
|
512
514
|
const ledger = readLaunchLedger(root);
|
|
513
|
-
const outcomes = collectOutcomes(ledger, { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch });
|
|
515
|
+
const outcomes = collectOutcomes(ledger, { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch, launchSeat: deps.launchSeat });
|
|
514
516
|
for (const outcome of outcomes) {
|
|
515
517
|
const issue = issues.find(item => item.identifier === outcome.issue) ??
|
|
516
518
|
{ identifier: outcome.issue, title: outcome.title, ref: '', body: '' };
|
package/src/storage/file-lock.ts
CHANGED
|
@@ -46,7 +46,7 @@ export interface LockOpts {
|
|
|
46
46
|
* (a holder killed with -9 must not wedge waiters for `staleMs`).
|
|
47
47
|
*/
|
|
48
48
|
breakDeadHolder?: boolean;
|
|
49
|
-
/**
|
|
49
|
+
/** Called once, the first time the lock is found held by someone else. */
|
|
50
50
|
onWait?: (holder: string) => void;
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -137,6 +137,7 @@ export async function acquireLockAsync(lockPath: string, opts: LockOpts = {}): P
|
|
|
137
137
|
const heartbeatMs = Math.max(50, Math.floor(staleMs / 3));
|
|
138
138
|
// ⭐ **소유 토큰** — inode 보다 강하다(inode 는 재사용된다). 파일 내용이 곧 소유 증명이다.
|
|
139
139
|
const token = `${process.pid}:${randomUUID()}`;
|
|
140
|
+
let waited = false;
|
|
140
141
|
|
|
141
142
|
for (let attempt = 0; attempt < maxTries; attempt += 1) {
|
|
142
143
|
try {
|
|
@@ -187,6 +188,12 @@ export async function acquireLockAsync(lockPath: string, opts: LockOpts = {}): P
|
|
|
187
188
|
} catch {
|
|
188
189
|
continue;
|
|
189
190
|
}
|
|
191
|
+
if (!waited && opts.onWait) {
|
|
192
|
+
waited = true;
|
|
193
|
+
let holder = '';
|
|
194
|
+
try { holder = readFileSync(lockPath, 'utf8').trim(); } catch { /* gone */ }
|
|
195
|
+
try { opts.onWait(holder); } catch { /* observer only */ }
|
|
196
|
+
}
|
|
190
197
|
await new Promise((resolve) => { setTimeout(resolve, retryBusyMs); });
|
|
191
198
|
}
|
|
192
199
|
}
|
|
@@ -164,6 +164,10 @@ export async function executeNextAction(action: NextAction, deps: ActionDeps): P
|
|
|
164
164
|
parsed = item as typeof parsed;
|
|
165
165
|
} catch { return record('failed', 'invalid review JSON'); }
|
|
166
166
|
if (parsed.reviewed !== true) return record('failed', 'review was not performed');
|
|
167
|
+
// TA-LAND-MUSTFIX-ZERO — «pass» 라도 must-fix 가 남았거나 수를 못 읽으면 land 로 가지 않는다(#25941 `canAuto` 와 같은 축).
|
|
168
|
+
// `self review --json` 은 mustFix 배열을 «항상» 싣는다 — 배열이 아니면 «0» 이 아니라 «모름»으로 읽는다(fail-closed).
|
|
169
|
+
if (parsed.verdict === 'pass' && (!Array.isArray(parsed.mustFix) || !parsed.mustFix.every(fix => typeof fix === 'string'))) return card('review-must-fix-unknown: pass verdict without a readable must-fix list');
|
|
170
|
+
if (parsed.verdict === 'pass' && parsed.mustFix!.length > 0) return card(`review-warn-with-must-fix: pass verdict carries ${parsed.mustFix!.length} must-fix`);
|
|
167
171
|
if (parsed.verdict === 'pass') { record('done', 'review pass'); return executeNextAction({ ...action, kind: 'land', history: [...(action.history ?? []), 'review pass'] }, deps); }
|
|
168
172
|
if (parsed.verdict === 'fail' && Array.isArray(parsed.mustFix) && parsed.mustFix.length > 0 && parsed.mustFix.every(fix => typeof fix === 'string' && fix.trim())) { record('done', 'review fail'); return executeNextAction({ ...action, kind: 'retry', mustFix: parsed.mustFix, history: [...(action.history ?? []), 'review fail'] }, deps); }
|
|
169
173
|
return card('review verdict or must-fix unavailable');
|