elanous 0.2.22 → 0.2.24
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/{aBi6EyMtLsrl7J8eH4kF7 → Q-7iofoxOEv1WX18S35of}/_buildManifest.js +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-0eed0fb0aab716b6.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-aaae04ed1d32622f.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-3b9fc39362473ae7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f2b62c19ca68fef8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-d7602d489edf5f37.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-24282bf9f90031a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-8b7c5ab6b5bc8d64.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-4eb84d454f8c3415.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-b2e494bdad57fcb5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/{page-80ed511e02c81412.js → page-c0ab229673a8b0eb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-3e2b45f3c36dbac4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-c22aa511b28743ad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-26345242e4049f55.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-bf88c0f558d8ef54.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-52fec523e5b5d3ad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-67723dfdcde92b31.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-22725e2570f1126b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-1891335950d68b70.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-3267af1ebdc73cf5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-c314b75c11234998.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-9f9c85415f61782b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-c1d4276059085587.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-833aab587f26ad4c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8526c17ae38e6a50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-f998637a8402115c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-b7bb53828b17b335.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-1b1850de0257e46d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6f23159fedb41f67.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1d809a87139dd024.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-da9e570234d481fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-b92caddb5c715f30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-8ce3a38e210b810a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-57ffeeb6019440fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-abbb417bf514630b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-2c2b3f29cec1efa4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-9369279f72fc7b51.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-64861f14039499c3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ddc4c93efd8ab94b.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-901a1391b81053bc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-68d9bbaac9841a58.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-b5c0c996f329371e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-89881ccbcf728978.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-0e87a803b3d7165e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-58d4e5cb30ef4871.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-02ce4c3b5f39e4d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-e620d1bb8eadcec2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-acf868c64d77f950.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-54fa605fa6dba457.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-bc79f0833533fa84.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-d5c4398eea03d8f3.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/72becfd42807b50d.css +1 -0
- package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
- 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/catalog/models/openrouter/deepseek-v4-pro-0813.yaml +39 -0
- package/catalog/models/openrouter/deepseek-v4.1-flash.yaml +38 -0
- package/catalog/models/openrouter/glm-5.3-flash.yaml +35 -0
- package/catalog/providers/openrouter.yaml +2 -0
- package/graphs/implement-loop.yaml +31 -0
- package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
- package/graphs/log-horizon/recipes.yaml +3 -0
- package/graphs/ops/harness-gc.yaml +17 -0
- package/graphs/ops/recipes.yaml +3 -0
- package/graphs/overlays/README.md +1 -1
- package/graphs/overlays/stop-heal-ladder.yaml +105 -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/add-api-key.sh +1 -1
- package/scripts/bench-report.ts +82 -3
- package/scripts/ci-typecheck-changed.ts +80 -14
- package/scripts/fleet/bedrock-pod-secret.ts +122 -0
- package/scripts/fleet/node-setup-linux.sh +97 -0
- package/scripts/fleet/node-setup.sh +11 -0
- package/scripts/fleet/zai-pod-secret.ts +86 -0
- package/scripts/hq/hq-fence-wrapper.sh +148 -0
- package/scripts/land-global-checks.ts +3 -0
- package/scripts/lib/typecheck-ratchet.ts +51 -0
- package/scripts/measure-log-diet-2.ts +213 -0
- package/scripts/measure-tsc-affected-roots.ts +289 -0
- package/scripts/openai-relay-server.ts +5 -1
- package/scripts/release-loop/docs-node.ts +258 -43
- package/scripts/release-loop/gate-executor.ts +28 -0
- package/scripts/release-loop/gate-method.ts +59 -0
- package/scripts/release-loop/gate-node.ts +335 -33
- 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 +40 -4
- package/scripts/release-loop/resume.ts +94 -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 +29 -7
- package/scripts/rhythm/daily.ts +51 -2
- package/scripts/rhythm/weekly.ts +3 -2
- package/scripts/tsc-baseline-cache.ts +147 -0
- package/scripts/tsc-main-safety-net.ts +189 -0
- package/scripts/usage-rollup.ts +64 -8
- package/src/acp/codex-plugins.ts +48 -6
- package/src/agent/monad-agent-turn.ts +67 -5
- package/src/agent/run-context.ts +20 -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 +19 -4
- package/src/agent-mission/pr-review-watch.ts +6 -2
- package/src/agent-mission/resource-ladder.ts +8 -3
- package/src/agent-mission/review-loop.ts +41 -7
- package/src/agent-substrate/acp-implementer.ts +139 -0
- package/src/agent-substrate/acp-reviewer.ts +17 -8
- package/src/agent-substrate/pr-reviewer.ts +191 -28
- package/src/agent-substrate/review-intent.ts +6 -4
- package/src/agent-substrate/self-review-cli.ts +155 -21
- 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/mission-critique.ts +18 -5
- package/src/autopilot/mission-feasibility-negotiate.ts +11 -10
- package/src/autopilot/mission-trace.ts +12 -1
- package/src/autopilot/pr-manager.ts +12 -3
- package/src/autopilot/system-lookback-run.ts +16 -10
- package/src/bench/bench.ts +183 -0
- 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/budget/fetchers/grok.ts +15 -5
- package/src/budget/llm-cost.ts +37 -5
- package/src/budget/types.ts +8 -2
- package/src/budget/unified-usage.ts +88 -6
- package/src/chat/index.ts +12 -3
- package/src/cli/agent-cli.ts +20 -0
- package/src/cli/bench-cli.ts +34 -0
- package/src/cli/brief-cli.ts +27 -21
- package/src/cli/cli-user-error.ts +9 -2
- package/src/cli/guardian-cli.ts +26 -1
- package/src/cli/image-cli.ts +101 -0
- package/src/cli/log-event-names.ts +7 -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 +90 -5
- package/src/cli/pr-land-overlap-evidence.ts +279 -0
- package/src/cli/release-cli.ts +63 -12
- package/src/cli/rfc-status.ts +52 -2
- package/src/cli/self-update.ts +277 -10
- package/src/cli/skills-cli.ts +12 -3
- package/src/cli/tasks-cli.ts +241 -30
- package/src/cli/usage-cli.ts +91 -8
- 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 +87 -2
- package/src/dashboard/ad-run-setup-bindings.ts +279 -0
- package/src/dashboard/chat-fold.ts +20 -0
- package/src/dashboard/first-screen-band.ts +151 -1
- package/src/dashboard/index.ts +45 -281
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -3
- package/src/dashboard/stale-install-check.ts +24 -2
- package/src/dashboard/turn-stream-formatter.ts +25 -0
- package/src/debug/log-diet.ts +190 -0
- package/src/debug/log.ts +70 -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 +158 -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/error-report/report.ts +21 -4
- 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 +2 -0
- package/src/graph-runner/graph-cli.ts +42 -1
- package/src/graph-runner/runner.ts +218 -8
- package/src/grok/usage.ts +23 -2
- package/src/grounding/ref-index.ts +253 -0
- package/src/harness/dispatch-backpressure.ts +267 -0
- package/src/harness/harness-clean.ts +199 -78
- package/src/harness/harness-cli-command.ts +229 -35
- package/src/harness/harness-gc.ts +331 -0
- package/src/harness/harness-seams.ts +2 -20
- package/src/harness/harness-stop.ts +4 -2
- package/src/harness/harness-substrate-default.ts +214 -8
- package/src/harness/launch-registry.ts +6 -0
- package/src/harness/nested-elanous-policy.ts +4 -2
- package/src/harness/worktree-branch-prefix.ts +9 -0
- package/src/hq/fence-wrapper.ts +7 -0
- package/src/hq/fence.ts +187 -0
- package/src/hq/hq.ts +33 -2
- package/src/hq/lease.ts +13 -0
- package/src/hq/seats.ts +133 -21
- package/src/images/image-ledger.ts +179 -0
- package/src/index.ts +250 -69
- package/src/instance/child-scope.ts +32 -1
- package/src/instance/dev-project.ts +133 -0
- package/src/instance/resolve.ts +24 -0
- package/src/instance/spawn-elanous.ts +45 -0
- 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/intake-plane/ref-prefetch.ts +110 -0
- package/src/intelligence-map/model-alias.ts +6 -0
- package/src/intelligence-map/model-catalog.ts +113 -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-eventstream.ts +215 -0
- package/src/llm/bedrock-provider.ts +248 -0
- package/src/llm/bedrock.ts +491 -0
- package/src/llm/openrouter-byok-cost.ts +96 -0
- package/src/llm/openrouter-deepseek.ts +151 -0
- package/src/llm/openrouter-upstream-pins.config.ts +25 -0
- package/src/llm/provider-credentials.ts +3 -1
- package/src/llm/zai-coding-plan.ts +700 -0
- package/src/llm.ts +383 -41
- package/src/loops/budget.ts +150 -0
- package/src/loops/checker.ts +148 -9
- package/src/loops/orchestrator/resync-shadow.ts +34 -7
- 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/maturity/feature-maturity.ts +2 -2
- package/src/mcp/mcp-oauth.ts +136 -17
- package/src/model-tier/llm-tier-map.ts +52 -4
- package/src/models/prompts.ts +23 -1
- package/src/mss/logging/horizon-watch.ts +168 -0
- package/src/mss/logging/log-store.ts +262 -26
- 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/missions.ts +73 -2
- package/src/nexus/api/ops-api.ts +18 -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 +17 -75
- package/src/nexus/outbound/format.ts +2 -0
- package/src/nexus/outbound/router.ts +198 -13
- package/src/nexus/tools-kind.ts +78 -0
- package/src/oauth/codex-account-rotation.ts +55 -20
- package/src/oauth/codex-account-store.ts +451 -23
- package/src/oauth/fallback-chain.ts +75 -15
- package/src/onboarding/first-run.ts +37 -18
- package/src/onboarding/web-first.ts +20 -2
- package/src/onboarding.ts +2 -1
- package/src/ops/machine-heartbeat.ts +185 -0
- package/src/ops/overview-cache.ts +175 -0
- package/src/ops/overview.ts +8 -0
- 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 +13 -6
- package/src/prompt-cache/openrouter.ts +94 -0
- package/src/prompt-cache/types.ts +5 -0
- package/src/prompt-enhance/enhance.ts +69 -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 +107 -23
- 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/requirements/requirement-ledger.ts +536 -0
- package/src/retro/daily.ts +26 -12
- package/src/seat-loop/seat-loop.ts +66 -11
- 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 +109 -11
- package/src/self-dev/dev-pipeline.ts +11 -8
- package/src/self-dev/draft-residue.ts +475 -0
- package/src/self-dev/draft-sweep.ts +254 -10
- package/src/self-dev/draft-triage-rules.ts +27 -1
- package/src/self-dev/graph-journey-route.ts +6 -0
- 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 +82 -5
- package/src/self-dev/orchestrate-summary-line.ts +13 -0
- package/src/self-dev/orchestrate.ts +49 -141
- 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 +190 -36
- package/src/self-dev/run-types.ts +191 -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 +3 -4
- package/src/self-implement/blocked-draft-policy.ts +3 -19
- package/src/self-implement/budget-gate.ts +53 -13
- package/src/self-implement/child-context-composition.ts +139 -0
- package/src/self-implement/child-llm-preference.ts +13 -5
- package/src/self-implement/claude-acp-implement.ts +67 -0
- package/src/self-implement/draft-on-stop-mode.ts +18 -0
- package/src/self-implement/flex-signals.ts +59 -0
- package/src/self-implement/follow-up-goals.ts +114 -38
- package/src/self-implement/frozen-merges.ts +8 -3
- 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-decompose.ts +10 -2
- package/src/self-implement/goal-author.ts +48 -13
- package/src/self-implement/goal-digest.ts +19 -0
- package/src/self-implement/graph-overlay-condition.ts +32 -0
- package/src/self-implement/graph-overlay-yaml.ts +41 -7
- package/src/self-implement/graph-templates.ts +33 -1
- package/src/self-implement/graph-yaml.ts +56 -0
- package/src/self-implement/headless-elanous-driver.ts +11 -9
- package/src/self-implement/heal-intake.ts +5 -1
- 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 +271 -25
- 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/running-runs.ts +75 -5
- package/src/self-implement/seams.ts +83 -4
- package/src/self-implement/self-implement-cli.ts +12 -5
- package/src/self-implement/stop-autoheal.ts +69 -2
- 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/session-runtime/retry-policy.ts +2 -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 +22 -10
- package/src/steward/triage-budget.ts +62 -0
- package/src/steward/triage.ts +87 -24
- package/src/storage/file-lock.ts +8 -1
- package/src/task-agent/actions.ts +66 -5
- package/src/task-agent/card-evidence.ts +59 -13
- package/src/task-agent/completion-evidence.ts +5 -0
- package/src/task-agent/cover.ts +101 -3
- package/src/task-agent/judge.ts +20 -3
- package/src/task-agent/land-order-ledger.ts +95 -0
- package/src/task-agent/land-worktree.ts +201 -0
- package/src/task-agent/live-move-history.ts +219 -0
- package/src/task-agent/live-moves.ts +451 -34
- package/src/task-agent/parent-host.ts +117 -8
- package/src/task-agent/rejudge-on-head.ts +352 -0
- package/src/task-agent/review-prior-fix.ts +146 -0
- package/src/task-agent/review-result-capture.ts +218 -0
- package/src/task-agent/run-adopt.ts +136 -0
- package/src/task-agent/shadow.ts +154 -14
- package/src/task-agent/task-hand.ts +186 -14
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +38 -5
- package/src/task-orchestrator/surfaces/pod-bedrock-child.ts +74 -0
- package/src/task-orchestrator/surfaces/pod-child-default.ts +50 -0
- package/src/task-orchestrator/surfaces/pod-child-providers.ts +42 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +94 -7
- package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +110 -17
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +32 -3
- package/src/task-orchestrator/surfaces/pod-pool.ts +86 -18
- package/src/task-orchestrator/surfaces/pod-zai-child.ts +101 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +463 -50
- package/src/task-orchestrator/surfaces/self-implement.ts +25 -3
- 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/typecheck-ratchet.ts +1 -0
- package/src/user-config.ts +180 -32
- 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/registry.ts +59 -0
- package/src/workflow-runtime/triggers/scheduler.ts +1 -0
- package/src/workflow-runtime/triggers/webhook-source.ts +35 -5
- 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 → Q-7iofoxOEv1WX18S35of}/_ssgManifest.js +0 -0
|
@@ -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
|
-
import { join
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { getElanousConfigDir } from '../elanous-config-dir.js';
|
|
5
|
+
import { installedCliArgv, 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[]) => installedCliArgv([...(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,20 @@ 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
|
+
/** Read commands run in the registered OP seat as well: the tree this module was loaded from may be a stale clone. */
|
|
112
|
+
function runCommand(args: string[], cwd = stewardLaunchSeat()): { exitCode: number; stdout: string; stderr: string } {
|
|
113
|
+
const result = Bun.spawnSync(args, { cwd, stdout: 'pipe', stderr: 'pipe' });
|
|
105
114
|
return { exitCode: result.exitCode, stdout: result.stdout.toString(), stderr: result.stderr.toString() };
|
|
106
115
|
}
|
|
107
116
|
|
|
108
|
-
function spawnDetached(args: string[], log: string): { pid: number } {
|
|
117
|
+
function spawnDetached(args: string[], log: string, seat = stewardLaunchSeat()): { pid: number } {
|
|
109
118
|
const fd = openSync(log, 'a');
|
|
110
119
|
try {
|
|
111
|
-
const child = Bun.spawn(args, { cwd:
|
|
120
|
+
const child = Bun.spawn(args, { cwd: seat, stdout: fd, stderr: fd, stdin: 'ignore', detached: true });
|
|
112
121
|
child.unref();
|
|
113
122
|
return { pid: child.pid };
|
|
114
123
|
} finally { closeSync(fd); }
|
|
@@ -149,9 +158,12 @@ export function launch(item: LaunchItem, deps: LaunchDeps): LaunchEntry {
|
|
|
149
158
|
// L6: a launch must remain on the isolated Pod pool, never fall back to the host or another substrate.
|
|
150
159
|
if (!/^[a-zA-Z0-9_-]+(?:@[a-zA-Z0-9._-]+(?::[1-9][0-9]*)?)?$/.test(settings.podPool ?? DEFAULT_POOL))
|
|
151
160
|
return blocked('blocked-location', 'invalid steward pod pool');
|
|
161
|
+
let seat: string;
|
|
162
|
+
try { seat = (deps.launchSeat ?? stewardLaunchSeat)(); }
|
|
163
|
+
catch (error) { return blocked('blocked-location', `steward OP seat unavailable: ${String(error)}`); }
|
|
152
164
|
let budget: BudgetDecision | 'unknown' = 'unknown';
|
|
153
165
|
try {
|
|
154
|
-
const result = command(cli(['harness', 'budget', '--json']));
|
|
166
|
+
const result = command(cli(['harness', 'budget', '--json']), seat);
|
|
155
167
|
const decision = result.exitCode === 0 ? lastJson(result.stdout) : {};
|
|
156
168
|
if (!BUDGET_PROCEED.includes(String(decision.outcome)))
|
|
157
169
|
return blocked('skipped-budget', result.exitCode === 0 ? JSON.stringify(decision.reasons ?? ['budget unavailable']) : result.stderr ?? 'budget unavailable');
|
|
@@ -171,7 +183,7 @@ export function launch(item: LaunchItem, deps: LaunchDeps): LaunchEntry {
|
|
|
171
183
|
ledger.launches[key] = entry;
|
|
172
184
|
saveLaunchLedger(root, ledger);
|
|
173
185
|
try {
|
|
174
|
-
entry.pid = (deps.spawn ?? spawnDetached)(argvFor(item.issue, settings), entry.log).pid;
|
|
186
|
+
entry.pid = (deps.spawn ?? spawnDetached)(argvFor(item.issue, settings), entry.log, seat).pid;
|
|
175
187
|
} catch (error) {
|
|
176
188
|
entry.status = 'failed';
|
|
177
189
|
entry.reason = redactSecrets(String(error));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { debug } from '../debug/log.js';
|
|
3
3
|
import type { TriageDecision, TriageIssue } from './triage.js';
|
|
4
|
+
import { InvalidWorkingBackwardsDraft } from './working-backwards.js';
|
|
4
5
|
|
|
5
6
|
export interface HashedTriageDecision extends TriageDecision {
|
|
6
7
|
inputHash: string;
|
|
@@ -125,3 +126,64 @@ export async function triageWithinBudget({ issues, previous, judge, tracks, conc
|
|
|
125
126
|
debug.log('steward.triage', 'budget', stats);
|
|
126
127
|
return { decisions, stats };
|
|
127
128
|
}
|
|
129
|
+
|
|
130
|
+
export interface CarriedDraft<T> {
|
|
131
|
+
wish: T;
|
|
132
|
+
/** `deadline` = never started before the stage deadline; `timeout` = per-item or stage deadline hit mid-draft. */
|
|
133
|
+
reason: 'timeout' | 'deadline' | 'error';
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
type DraftOutcome<T> = { kind: 'drafted' } | { kind: 'invalid' } | { kind: 'carried'; reason: CarriedDraft<T>['reason'] };
|
|
137
|
+
|
|
138
|
+
export async function draftWithinBudget<T>({ wishes, draft, concurrency = 4, perItemMs = 120_000, deadlineMs = 240_000, now = Date.now }: {
|
|
139
|
+
wishes: T[];
|
|
140
|
+
/** `expired` rejects once this item's own deadline passes; drafts should race their slow calls against it. */
|
|
141
|
+
draft: (wish: T, expired: Promise<never>) => Promise<void>;
|
|
142
|
+
concurrency?: number;
|
|
143
|
+
perItemMs?: number;
|
|
144
|
+
deadlineMs?: number;
|
|
145
|
+
now?: () => number;
|
|
146
|
+
}): Promise<{ drafted: T[]; carried: Array<CarriedDraft<T>>; invalid: T[]; stats: { drafted: number; carried: number; invalid: number } }> {
|
|
147
|
+
const end = now() + deadlineMs;
|
|
148
|
+
const slots = Number.isFinite(concurrency) ? Math.max(1, Math.floor(concurrency)) : 4;
|
|
149
|
+
const outcomes: Array<DraftOutcome<T> | undefined> = new Array(wishes.length);
|
|
150
|
+
let stageTimer: ReturnType<typeof setTimeout> | undefined;
|
|
151
|
+
const stageExpired = new Promise<void>(resolve => { stageTimer = setTimeout(resolve, Math.max(0, end - now())); });
|
|
152
|
+
const timedOut = Symbol('draft-timeout');
|
|
153
|
+
let cursor = 0;
|
|
154
|
+
const worker = async (): Promise<void> => {
|
|
155
|
+
while (cursor < wishes.length) {
|
|
156
|
+
const remaining = end - now();
|
|
157
|
+
if (remaining <= 0) return;
|
|
158
|
+
const index = cursor++;
|
|
159
|
+
let itemTimer: ReturnType<typeof setTimeout> | undefined;
|
|
160
|
+
const expired = new Promise<never>((_, reject) => { itemTimer = setTimeout(() => reject(timedOut), Math.min(perItemMs, remaining)); });
|
|
161
|
+
// The draft may finish without ever racing this promise — never leave its rejection unhandled.
|
|
162
|
+
expired.catch(() => undefined);
|
|
163
|
+
const work = Promise.resolve().then(() => draft(wishes[index]!, expired));
|
|
164
|
+
const settled = work.then(() => undefined, () => undefined);
|
|
165
|
+
try {
|
|
166
|
+
await Promise.race([work, expired]);
|
|
167
|
+
outcomes[index] = { kind: 'drafted' };
|
|
168
|
+
} catch (error) {
|
|
169
|
+
outcomes[index] = error instanceof InvalidWorkingBackwardsDraft ? { kind: 'invalid' }
|
|
170
|
+
: { kind: 'carried', reason: error === timedOut ? 'timeout' : 'error' };
|
|
171
|
+
// A timed-out draft keeps its concurrency slot until the underlying call settles or the stage ends.
|
|
172
|
+
await Promise.race([settled, stageExpired]);
|
|
173
|
+
} finally { if (itemTimer) clearTimeout(itemTimer); }
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
try {
|
|
177
|
+
await Promise.all(Array.from({ length: Math.min(slots, wishes.length) }, () => worker()));
|
|
178
|
+
} finally { if (stageTimer) clearTimeout(stageTimer); }
|
|
179
|
+
const result = { drafted: [] as T[], carried: [] as Array<CarriedDraft<T>>, invalid: [] as T[] };
|
|
180
|
+
for (const [index, wish] of wishes.entries()) {
|
|
181
|
+
const outcome = outcomes[index];
|
|
182
|
+
if (outcome?.kind === 'drafted') result.drafted.push(wish);
|
|
183
|
+
else if (outcome?.kind === 'invalid') result.invalid.push(wish);
|
|
184
|
+
else result.carried.push({ wish, reason: outcome?.kind === 'carried' ? outcome.reason : 'deadline' });
|
|
185
|
+
}
|
|
186
|
+
const stats = { drafted: result.drafted.length, carried: result.carried.length, invalid: result.invalid.length };
|
|
187
|
+
debug.log('steward.triage', 'draft-budget', stats);
|
|
188
|
+
return { ...result, stats };
|
|
189
|
+
}
|
package/src/steward/triage.ts
CHANGED
|
@@ -8,6 +8,10 @@ import { getUserConfig } from '../user-config.js';
|
|
|
8
8
|
import { emitDecision } from '../live/detail-switch.js';
|
|
9
9
|
import { debug, redactSecretText } from '../debug/log.js';
|
|
10
10
|
import { loopEvent } from '../loops/observe.js';
|
|
11
|
+
import { checkLoops, daemonScheduleEntries, entriesFromRegistry, extendHealthyLauncher, launcherEvidence, notifyOwners, scheduleFindings, versionEvidence, type CheckEntry } from '../loops/checker.js';
|
|
12
|
+
import { listSchedules, schedulesDbPath, type ScheduleRow } from '../domains/schedule-registry.js';
|
|
13
|
+
import { Database } from 'bun:sqlite';
|
|
14
|
+
import { defaultLoopRoot, listAllLoops, listLoops } from '../loops/registry.js';
|
|
11
15
|
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
12
16
|
import { redactSecrets } from '../task-cards/card-store.js';
|
|
13
17
|
import { directiveHash } from './directive.js';
|
|
@@ -17,7 +21,7 @@ import { planLaunches, launch, collectOutcomes, raiseHitl, readLaunchLedger, sav
|
|
|
17
21
|
import { listFabricExecutionCandidates } from '../self-dev/fabric-plan-core.js';
|
|
18
22
|
import { InvalidWorkingBackwardsDraft, recordWorkingBackwardsOnCards } from './working-backwards.js';
|
|
19
23
|
import { CardStore } from '../task-cards/card-store.js';
|
|
20
|
-
import { triageWithinBudget } from './triage-budget.js';
|
|
24
|
+
import { draftWithinBudget, triageWithinBudget } from './triage-budget.js';
|
|
21
25
|
import { askSteward, classifyIssue, installedCapabilities, planIssues, ruleJudgment, unsafeReason, type ClassifiedIssue, type StewardAsk } from './triage-plan.js';
|
|
22
26
|
import { failureAlertText, markStageStart, markStageEnd, readFailureStreak, shouldAlert, writeFailureStreak, type FailureStreak, type StewardStage } from './failure-streak.js';
|
|
23
27
|
|
|
@@ -59,13 +63,20 @@ export interface StewardDeps {
|
|
|
59
63
|
ask?: StewardAsk;
|
|
60
64
|
/** Maximum time for each working-backwards wish draft in schedule (milliseconds). */
|
|
61
65
|
draftItemMs?: number;
|
|
66
|
+
/** Maximum time for the whole wish-drafting phase in schedule (milliseconds); wishes still undrafted are carried. */
|
|
67
|
+
draftDeadlineMs?: number;
|
|
62
68
|
launchSettings?: Pick<StewardSettings, 'mode' | 'launch' | 'maxParallel' | 'podPool'>;
|
|
63
69
|
launchCommand?: LaunchDeps['command'];
|
|
64
70
|
spawnLaunch?: LaunchDeps['spawn'];
|
|
71
|
+
/** Isolated OP view for tests; production resolves the registered HQ seat (launch.ts stewardLaunchSeat). */
|
|
72
|
+
launchSeat?: LaunchDeps['launchSeat'];
|
|
65
73
|
launchGate?: LaunchDeps['gate'];
|
|
66
74
|
outcomeNotify?: Pick<OutcomeNotifyDeps, 'document' | 'message' | 'worktreeCommand' | 'loadOrigin' | 'loadOrigins'>;
|
|
67
75
|
/** Internal command boundary: the current sync has already claimed this pid. */
|
|
68
76
|
stageOwnedByCommand?: boolean;
|
|
77
|
+
/** Isolated scheduler inventory for this tick; production reads the unified registry. */
|
|
78
|
+
scheduleInventory?: () => CheckEntry[];
|
|
79
|
+
daemonSchedules?: () => ScheduleRow[];
|
|
69
80
|
}
|
|
70
81
|
|
|
71
82
|
/** rescue launches/harvests like live (HQ-SEAT). */
|
|
@@ -312,6 +323,61 @@ function logStageFailure(root: string, stage: StewardStage, reason: string): voi
|
|
|
312
323
|
if (runId) try { rmSync(tickDecisionPath(root, runId), { force: true }); } catch { /* Observation must not change the failure. */ }
|
|
313
324
|
logTickDecision(root, 'failed', `${stage}: ${reason}`);
|
|
314
325
|
}
|
|
326
|
+
const SCHEDULE_CHECK_MS = 15 * 60_000;
|
|
327
|
+
|
|
328
|
+
/** Called by runStewardStage(sync) under its stage slot, never from the checker CLI. */
|
|
329
|
+
async function checkStewardSchedules(root: string, settings: StewardSettings, deps: StewardDeps): Promise<void> {
|
|
330
|
+
const now = (deps.now ?? (() => new Date()))();
|
|
331
|
+
const marker = join(root, 'steward', 'schedule-check.json');
|
|
332
|
+
let previous: { at?: string } = {};
|
|
333
|
+
try { previous = JSON.parse(readFileSync(marker, 'utf8')) as typeof previous; }
|
|
334
|
+
catch (error) { if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error; }
|
|
335
|
+
const elapsed = now.getTime() - Date.parse(previous.at ?? '');
|
|
336
|
+
if (Number.isFinite(elapsed) && elapsed >= 0 && elapsed < SCHEDULE_CHECK_MS) return;
|
|
337
|
+
const inventory = deps.scheduleInventory ?? (() => {
|
|
338
|
+
const repo = deps.root ? process.cwd() : defaultLoopRoot();
|
|
339
|
+
const registryOptions = { now, root: repo, stateRoot: root,
|
|
340
|
+
...(deps.root ? { schedules: [] } : {}) };
|
|
341
|
+
const { entries } = entriesFromRegistry({ now, listAllLoops: () => listAllLoops(registryOptions) });
|
|
342
|
+
const graphs = listLoops(registryOptions);
|
|
343
|
+
const byId = new Map(graphs.map(graph => [graph.id, graph.file]));
|
|
344
|
+
return versionEvidence(launcherEvidence(entries.map(entry => byId.has(entry.id)
|
|
345
|
+
? { ...entry, file: byId.get(entry.id) } : entry), root), repo, root);
|
|
346
|
+
});
|
|
347
|
+
const daemonRows = deps.daemonSchedules ?? (() => {
|
|
348
|
+
const path = deps.root ? join(root, 'schedules.db') : schedulesDbPath();
|
|
349
|
+
if (!existsSync(path)) return [];
|
|
350
|
+
try {
|
|
351
|
+
const db = new Database(path, { readonly: true });
|
|
352
|
+
try { return listSchedules(db); } finally { db.close(); }
|
|
353
|
+
} catch (error) {
|
|
354
|
+
debug.log('steward.schedule-check', 'daemon-inventory-unavailable', { reason: redactSecretText(String(error)) });
|
|
355
|
+
return [];
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
const entries = inventory();
|
|
359
|
+
const seen = new Set(entries.map(entry => entry.id));
|
|
360
|
+
const checked = checkLoops([...entries, ...daemonScheduleEntries(daemonRows(), now).filter(row => !seen.has(row.id))], now);
|
|
361
|
+
const findings = scheduleFindings(checked, now);
|
|
362
|
+
if (settings.mode === 'live') {
|
|
363
|
+
let recovered = 0;
|
|
364
|
+
const unresolved = findings.filter(finding => {
|
|
365
|
+
try {
|
|
366
|
+
if (extendHealthyLauncher(root, finding, now)) { recovered++; return false; }
|
|
367
|
+
} catch (error) {
|
|
368
|
+
debug.log('steward.schedule-check', 'recovery-failed', { id: finding.id, reason: redactSecretText(String(error)) });
|
|
369
|
+
}
|
|
370
|
+
return true;
|
|
371
|
+
});
|
|
372
|
+
const remainingChecks = checked.filter(row => unresolved.some(finding => finding.id === row.id && finding.kind === row.state));
|
|
373
|
+
const ownerRequests = notifyOwners(remainingChecks, { root, now }, unresolved);
|
|
374
|
+
const opEscalations = notifyOwners(remainingChecks, { root, now }, unresolved, true);
|
|
375
|
+
debug.log('steward.schedule-check', 'routing', { ownerRequests, opEscalations, recovered });
|
|
376
|
+
}
|
|
377
|
+
debug.log('steward.schedule-check', 'checked', { count: checked.length, findings: findings.length, mode: settings.mode });
|
|
378
|
+
writeFileSync(marker, JSON.stringify({ at: now.toISOString() }));
|
|
379
|
+
}
|
|
380
|
+
|
|
315
381
|
function readState(path: string): { issues: Record<string, string>; digestDay?: string } {
|
|
316
382
|
try { return JSON.parse(readFileSync(path, 'utf8')) as ReturnType<typeof readState>; }
|
|
317
383
|
catch (error) { if ((error as NodeJS.ErrnoException).code === 'ENOENT') return { issues: {} }; throw error; }
|
|
@@ -341,6 +407,11 @@ export async function runStewardStage(stage: 'sync' | 'triage' | 'schedule' | 'r
|
|
|
341
407
|
const runId = (graphRunId() ?? process.env.ELANOUS_RUN_ID?.trim()) || `steward-stage-${randomUUID()}`;
|
|
342
408
|
let outcome: 'ok' | 'fail' = 'fail';
|
|
343
409
|
try {
|
|
410
|
+
if (stage === 'sync') {
|
|
411
|
+
// The schedule check is an add-on to sync: its failure is observed, never allowed to stop the Linear sync.
|
|
412
|
+
try { await checkStewardSchedules(root, settings, deps); }
|
|
413
|
+
catch (error) { debug.log('steward.schedule-check', 'failed', { reason: redactSecretText(String(error)) }, { level: 'warn' }); }
|
|
414
|
+
}
|
|
344
415
|
const key = await (deps.getSecret ?? getSecretAsync)('connector.linear.apiKey');
|
|
345
416
|
if (!key) throw new Error('connector.linear.apiKey missing');
|
|
346
417
|
if (stage === 'sync') {
|
|
@@ -418,27 +489,19 @@ export async function runStewardStage(stage: 'sync' | 'triage' | 'schedule' | 'r
|
|
|
418
489
|
const carried = new Set<string>();
|
|
419
490
|
if (store) try {
|
|
420
491
|
recordTriageOnCards(wishes, issues, { root, store, now: deps.now });
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
if (error instanceof InvalidWorkingBackwardsDraft) {
|
|
435
|
-
invalid.add(wish.issue);
|
|
436
|
-
debug.log('steward.stage', 'draft-invalid', { issue: wish.issue });
|
|
437
|
-
} else {
|
|
438
|
-
carried.add(wish.issue);
|
|
439
|
-
debug.log('steward.schedule', 'draft-carried', { issue: wish.issue, reason: error === timedOut ? 'timeout' : 'error' });
|
|
440
|
-
}
|
|
441
|
-
} finally { if (timer) clearTimeout(timer); }
|
|
492
|
+
const outcome = await draftWithinBudget({
|
|
493
|
+
wishes, perItemMs: deps.draftItemMs ?? 120_000, deadlineMs: deps.draftDeadlineMs ?? 240_000,
|
|
494
|
+
// Bound the ask itself so a late answer cannot write to a store closed after this tick.
|
|
495
|
+
draft: (wish, expired) => recordWorkingBackwardsOnCards([wish], issues, store,
|
|
496
|
+
(prompt, role) => Promise.race([(deps.ask ?? askSteward)(prompt, role), expired])),
|
|
497
|
+
});
|
|
498
|
+
for (const wish of outcome.invalid) {
|
|
499
|
+
invalid.add(wish.issue);
|
|
500
|
+
debug.log('steward.stage', 'draft-invalid', { issue: wish.issue });
|
|
501
|
+
}
|
|
502
|
+
for (const { wish, reason } of outcome.carried) {
|
|
503
|
+
carried.add(wish.issue);
|
|
504
|
+
debug.log('steward.schedule', 'draft-carried', { issue: wish.issue, reason });
|
|
442
505
|
}
|
|
443
506
|
} finally { if (!deps.cardStore) store.close(); }
|
|
444
507
|
if (invalid.size || carried.size) rows = rows.map(row => invalid.has(row.issue)
|
|
@@ -450,7 +513,7 @@ export async function runStewardStage(stage: 'sync' | 'triage' | 'schedule' | 'r
|
|
|
450
513
|
}); } catch { /* logging must not change the schedule */ }
|
|
451
514
|
writeFileSync(schedule, JSON.stringify(rows));
|
|
452
515
|
const ledger = readLaunchLedger(root);
|
|
453
|
-
const launchDeps: LaunchDeps = { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch, gate: deps.launchGate };
|
|
516
|
+
const launchDeps: LaunchDeps = { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch, gate: deps.launchGate, launchSeat: deps.launchSeat };
|
|
454
517
|
const cardDeps = { root, store: deps.cardStore, now: deps.now };
|
|
455
518
|
collectOutcomes(ledger, launchDeps);
|
|
456
519
|
const plan = planLaunches(rows, issues, ledger, settings);
|
|
@@ -510,7 +573,7 @@ export async function runStewardStage(stage: 'sync' | 'triage' | 'schedule' | 'r
|
|
|
510
573
|
writeFileSync(path, JSON.stringify(state));
|
|
511
574
|
}
|
|
512
575
|
const ledger = readLaunchLedger(root);
|
|
513
|
-
const outcomes = collectOutcomes(ledger, { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch });
|
|
576
|
+
const outcomes = collectOutcomes(ledger, { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch, launchSeat: deps.launchSeat });
|
|
514
577
|
for (const outcome of outcomes) {
|
|
515
578
|
const issue = issues.find(item => item.identifier === outcome.issue) ??
|
|
516
579
|
{ identifier: outcome.issue, title: outcome.title, ref: '', body: '' };
|