elanous 0.2.32 → 0.2.35
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/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/{IVKr3AlRUVLKsw2fh7eXF → T1mBQqmkwKDLGtyisDCOd}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{997ce8a5-2ad501927003b41b.js → 0368f25d-ad84af92fefee68f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +1 -0
- package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +32 -0
- package/apps/pwa/out/_next/static/chunks/{5525.86debf231e181813.js → 1530.0e612369b6fd7ea0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +41 -0
- package/apps/pwa/out/_next/static/chunks/{7391.ebae168025c91b6a.js → 1674.2a65fd5668e1cc5f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +24 -0
- package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +74 -0
- package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7947-d0759430f8042240.js → 1993-c0007b7ad0c0ef41.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{60fb96c9.360b01d8d4927b7b.js → 1c735de4.f993a30bbd3c57c4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5307.60f2209e809bd627.js → 2018.a741297bce759490.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +148 -0
- package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3902.e1e71aaac850a045.js → 2625.5d870aa999f33db1.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +77 -0
- package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +62 -0
- package/apps/pwa/out/_next/static/chunks/3103.0df8da390948bb84.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +90 -0
- package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4174.92ed04922709ac9e.js → 3408.21d1570602f4b6c0.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3589.5444a06bcf6e775c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/359-2250789a2d3499e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +36 -0
- package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9398-6aed28f0a96d0d6f.js → 3677-4215f826f6aa68e5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +79 -0
- package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +122 -0
- package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7371.80c05c653b08e907.js → 4346.8601952e73bf5803.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4441-875b97f5821ed58a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +286 -0
- package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{2940-619bfd8ef337c611.js → 4705-194e64e47ca0fbdb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1335-6731f392c35216eb.js → 4718-17d2af636796a330.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7502.ccd5b8065545edd0.js → 5101.e32282718f99ed6f.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{2001.6c7e0fd02190886c.js → 5154.a118f3957ed14e36.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +23 -0
- package/apps/pwa/out/_next/static/chunks/{5173-233188df2f42c626.js → 5483-dd5d7697f6bdb106.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5637.281e5dec4ea6ecf1.js +94 -0
- package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3267c0e6.d34854e7b3984a6e.js → 56d372f2.681ab4ec4c998fae.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +287 -0
- package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +1 -0
- package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6433.fc573af22bbc9ab7.js → 6236.e18cced2d5ba6afb.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +8 -0
- package/apps/pwa/out/_next/static/chunks/630.fe5a46428d63b013.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +27 -0
- package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +93 -0
- package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6544cb48.a87fe20ddf137be2.js → 6b89c8bd.24df687a820500b3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +149 -0
- package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +104 -0
- package/apps/pwa/out/_next/static/chunks/{2871.0bca6137343b3f76.js → 7385.50a308a477bdfc21.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2985.39ccdecd36848b12.js → 7644.17e37ba6f1d4226e.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8018.a32663f04a6fc5f9.js → 8219.baa715d1deee80e2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4111.2bfedbb233ad206b.js → 8256.e3ac8421a71f82f4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2213.2ccbada92c33ea0f.js → 8444.4c26b379ca2b9596.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +226 -0
- package/apps/pwa/out/_next/static/chunks/8557-e7898769499cd56f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +64 -0
- package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6092.a7f99e68b188ca66.js → 8637.47f5b35afcae5e6b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8714.ff0b7ce3ec3e3ae2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3278.2e5d15b53a4091c8.js → 9214.63a510d39178e997.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +115 -0
- package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9221.7d22eaf353a2d4e7.js → 938.66ad1ef0e5abae1c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6157.0c9af021de4fb31b.js → 9512.5a76207a730e0491.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{69-0a2c8209c6d4a158.js → 967-2aa39b2d04b4c690.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7862.30a8d6482bb238eb.js → 9952.5daf5f94063a2b3e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/{page-a27b1e5a0d1b308f.js → page-406b47745b53f269.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/{page-32866485913d6a04.js → page-47c5d4db587266bd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/{page-04d00ae9b0890349.js → page-dc0a532f5b9196ec.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7a1887c4.f36b88fba31da8fd.js → b2f6ba4d.fb56fdbbf798df33.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/b6705a4f-b9a9047de9eecfd0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b313b242.cb1265eea908db61.js → cbe38a15.5a032598e39970c6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{409f1e57.d0649fc47691ebfe.js → d06f9160.a3d9062f95de8ad7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{0bb0ff36.b8d418980951e5ba.js → da5176c6.6773b6c5994e1d99.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +22 -22
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +22 -22
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +22 -22
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +21 -21
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +21 -21
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +22 -22
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +21 -21
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +22 -22
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +22 -22
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +21 -21
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +22 -22
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +22 -22
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +22 -22
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +22 -22
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +21 -21
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +21 -21
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +22 -22
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +22 -22
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +22 -22
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +21 -21
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +21 -21
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +21 -21
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +22 -22
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +22 -22
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +21 -21
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +21 -21
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +21 -21
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +21 -21
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +22 -22
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +22 -22
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +21 -21
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +22 -22
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +22 -22
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +22 -22
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +22 -22
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +22 -22
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +21 -21
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +22 -22
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +22 -22
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +22 -22
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +22 -22
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +22 -22
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +22 -22
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +22 -22
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +22 -22
- package/bin/elanous.mjs +10 -2
- package/catalog/providers/opengateway.yaml +25 -0
- package/docs/goal-context/01-goal-authoring-checks.md +8 -0
- package/docs/goal-context/03-verification-menu.md +24 -0
- package/docs/goal-context/04-mock-scenarios.md +100 -0
- package/docs/goal-context/README.md +5 -0
- package/graphs/catalog/catalog.yaml +1 -1
- package/graphs/default-loop.yaml +76 -5
- package/graphs/document-loop.yaml +71 -4
- package/graphs/implement-loop.yaml +59 -4
- package/graphs/journey/SCENARIOS.md +33 -0
- package/graphs/journey/recipes.yaml +1 -0
- package/graphs/journey/ta-journey.yaml +94 -0
- package/graphs/journey/units/author/author.yaml +20 -0
- package/graphs/journey/units/author/recipes.yaml +2 -0
- package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
- package/graphs/journey/units/author-dialogue/observe.ts +96 -0
- package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
- package/graphs/journey/units/green/green.yaml +20 -0
- package/graphs/journey/units/green/recipes.yaml +2 -0
- package/graphs/journey/units/pr/pr.yaml +20 -0
- package/graphs/journey/units/pr/recipes.yaml +2 -0
- package/graphs/journey/units/remember/recipes.yaml +2 -0
- package/graphs/journey/units/remember/remember.yaml +20 -0
- package/graphs/operate-loop.yaml +71 -4
- package/graphs/overlays/stop-heal-ladder.yaml +1 -1
- package/graphs/release-rehearsal/recipes.yaml +1 -1
- package/graphs/release-rehearsal/release-rehearsal.yaml +2 -2
- package/graphs/research-loop.yaml +159 -4
- package/graphs/test-diet/test-diet.yaml +3 -0
- package/graphs/units/dispatch-pod/dispatch-pod.yaml +50 -0
- package/graphs/units/dispatch-pod/recipes.yaml +14 -0
- package/graphs/units/entry/entry.yaml +50 -0
- package/graphs/units/entry/recipes.yaml +14 -0
- package/graphs/units/harvest/harvest.yaml +25 -0
- package/graphs/units/harvest/recipes.yaml +4 -0
- package/graphs/units/land/land.yaml +45 -0
- package/graphs/units/land/recipes.yaml +3 -0
- package/graphs/units/recipes.yaml +7 -0
- package/graphs/units/recover.yaml +39 -0
- package/graphs/units/reflect/recipes.yaml +3 -0
- package/graphs/units/reflect/reflect.yaml +15 -0
- package/graphs/units/task-agent-recover-review.yaml +17 -0
- package/graphs/units/task-agent-recover-wait.yaml +17 -0
- package/graphs/units/verbs/make-doc.yaml +34 -0
- package/graphs/units/verbs/recipes.yaml +33 -0
- package/graphs/units/verbs/verify.yaml +55 -0
- package/graphs/work/recipes.yaml +2 -0
- package/graphs/work/research-report.yaml +28 -0
- package/package.json +1 -1
- package/scripts/ci-typecheck-changed.ts +69 -16
- package/scripts/coord-role-pack.ts +19 -6
- package/scripts/docs/generate-graph-anatomy.ts +19 -2
- package/scripts/graph-harvest-unit.ts +22 -0
- package/scripts/graph-units/journey-stub.ts +6 -0
- package/scripts/graph-units/land-enqueue.ts +78 -0
- package/scripts/graph-units/recover-plan.ts +15 -0
- package/scripts/graph-units/reflect-node.ts +88 -0
- package/scripts/graph-units/ta-journey-observe.ts +109 -0
- package/scripts/graph-units/verbs/headless-goal-loop.ts +152 -0
- package/scripts/graph-units/verbs/verify-stage.ts +75 -0
- package/scripts/graph-units/verbs-envelope.ts +139 -0
- package/scripts/hq/standby-snapshot.ts +30 -0
- package/scripts/public-export.ts +43 -1
- package/scripts/ratchets/train-side-invariants.sh +45 -0
- package/scripts/release-loop/auto-approve-node.ts +30 -16
- package/scripts/release-loop/docs-land-node.ts +21 -5
- package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
- package/scripts/release-loop/gate-closure.ts +5 -1
- package/scripts/release-loop/gate-diff.ts +1 -1
- package/scripts/release-loop/gate-node.ts +675 -49
- package/scripts/release-loop/gate-partial.ts +68 -14
- package/scripts/release-loop/gate-radius-live.ts +177 -0
- package/scripts/release-loop/gate-radius-shadow.ts +138 -0
- package/scripts/release-loop/gate-traffic-mode.ts +128 -0
- package/scripts/release-loop/gate-triage-node.ts +5 -2
- package/scripts/release-loop/known-issues-0.2.33-approved.json +194 -0
- package/scripts/release-loop/known-issues-node.ts +77 -8
- package/scripts/release-loop/node-verdict.ts +12 -1
- package/scripts/release-loop/npm-publish-node.ts +66 -12
- package/scripts/release-loop/preflight.ts +93 -7
- package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
- package/scripts/release-loop/publish-node.ts +60 -9
- package/scripts/release-loop/pwa-remote.ts +166 -0
- package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
- package/scripts/release-loop/resume-cap.ts +56 -0
- package/scripts/release-loop/resume-release.ts +155 -19
- package/scripts/release-loop/resume.ts +24 -1
- package/scripts/release-loop/tui-sim-node.ts +8 -2
- package/scripts/release-loop/unattended-release.ts +10 -2
- package/scripts/test-diet/lib.ts +6 -1
- package/scripts/test-diet/node.ts +194 -13
- package/scripts/ux-sim.ts +39 -0
- package/src/acp/core-turn-bridge.ts +20 -5
- package/src/acp/reasoning-thought-buffer.ts +45 -0
- package/src/agent/self-ambient-cache.ts +8 -0
- package/src/agent-substrate/acp-reviewer.ts +90 -15
- package/src/agent-substrate/pr-reviewer.ts +17 -0
- package/src/agent-substrate/review-finding-key.ts +53 -0
- package/src/agent-substrate/self-review-cli.ts +188 -18
- package/src/ask-user-question/pending-questions.ts +1 -1
- package/src/autopilot/pr-manager.ts +393 -65
- package/src/budget/run-usage-rollup.ts +1 -0
- package/src/chat/index.ts +0 -2
- package/src/chat/pickers/modal-runtime.ts +10 -27
- package/src/chat/tool-render/dispatch.ts +62 -10
- package/src/cli/agent-cli.ts +13 -2
- package/src/cli/control-cli.ts +24 -7
- package/src/cli/doctor-cli.ts +4 -1
- package/src/cli/guardian-cli.ts +10 -0
- package/src/cli/light-entry-route.ts +75 -0
- package/src/cli/llm-detect-cli.ts +23 -1
- package/src/cli/pod-cli.ts +77 -3
- package/src/cli/pr-cli.ts +81 -14
- package/src/cli/pr-land-base-read.ts +2 -0
- package/src/cli/pr-land-overlap-evidence.ts +154 -16
- package/src/cli/pr-land-pod-shadow-job.ts +3 -0
- package/src/cli/pr-land-recovery.ts +64 -0
- package/src/cli/pty-takeover-cli.ts +6 -5
- package/src/cli/release-checklist-read-cli.ts +79 -0
- package/src/cli/release-cli.ts +189 -132
- package/src/cli/release-run-if-ready.ts +29 -28
- package/src/cli/release-single-flight.ts +178 -0
- package/src/cli/remote-resolve.ts +1 -1
- package/src/cli/root-tui-entry.ts +48 -0
- package/src/cli/seat-cli.ts +37 -0
- package/src/cli/setup-cli.ts +40 -1
- package/src/cli/sim-cli.ts +22 -0
- package/src/cli/tasks-cli.ts +667 -14
- package/src/cli/usage-cli.ts +13 -11
- package/src/clipboard/history.ts +179 -13
- package/src/config.ts +8 -1
- package/src/control/control-status.ts +8 -3
- package/src/control-plane/ledger.ts +5 -3
- package/src/control-plane/server.ts +5 -3
- package/src/core-turn/short-question.ts +5 -1
- package/src/dashboard/chat/acp-chat.ts +8 -0
- package/src/dashboard/index.ts +114 -77
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +3 -0
- package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
- package/src/dashboard/input/seat-autowake.ts +56 -3
- package/src/dashboard/render/theme-resolver.ts +33 -4
- package/src/dashboard/seat-boot-preamble.ts +1 -1
- package/src/dashboard/slash-runtime/ask-clarification.ts +48 -0
- package/src/dashboard/slash-runtime/dashboard-delegated-slashes.ts +68 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +62 -322
- package/src/dashboard/slash-runtime/dashboard-log-slash.ts +208 -0
- package/src/dashboard/turn-preamble.ts +47 -1
- package/src/dashboard/turn-stream-formatter.ts +34 -1
- package/src/dashboard/turn-stream-runtime.ts +2 -0
- package/src/dashboard/turn-typeahead-prompt-zone.ts +67 -0
- package/src/domains/guardian-tick.ts +54 -2
- package/src/domains/outbound-alert.ts +3 -2
- package/src/domains/schedule-registry.ts +16 -2
- package/src/extractors.ts +3 -1
- package/src/git-fs/idle-refresh.ts +76 -0
- package/src/git-fs/index.ts +18 -7
- package/src/git-fs/retry.ts +4 -0
- package/src/git-fs/runner.ts +2 -0
- package/src/git-fs/worktree.ts +42 -4
- package/src/graph-kinds/registry.ts +2 -2
- package/src/graph-runner/runner.ts +267 -54
- package/src/grok/credential.ts +15 -3
- package/src/harness/harness-cli-command.ts +151 -38
- package/src/harness/harness-incidents.ts +37 -0
- package/src/harness/harness-pod-dispatch.ts +38 -1
- package/src/harness/harness-salvage-cli.ts +14 -2
- package/src/harness/launch-utterance-ledger.ts +208 -0
- package/src/impl-discipline/detector.ts +16 -4
- package/src/impl-discipline/system-prompt.ts +11 -0
- package/src/impl-discipline/types.ts +2 -2
- package/src/index.ts +683 -146
- package/src/intake-plane/already-built-hint.ts +91 -0
- package/src/intake-plane/requirement-funnel.ts +29 -1
- package/src/knowhow/pack.ts +199 -0
- package/src/light-cli.ts +111 -0
- package/src/llm/opengateway-models.ts +11 -0
- package/src/llm/provider-credentials.ts +14 -0
- package/src/llm/provider-detect.ts +8 -1
- package/src/llm/runtime-model-family.ts +2 -1
- package/src/llm.ts +268 -65
- package/src/loops/budget.ts +95 -0
- package/src/loops/msg-wake.ts +8 -2
- package/src/loops/orchestrator/traffic.ts +132 -1
- package/src/model-tier/llm-tier-map.ts +15 -1
- package/src/mss/logging/log-store.ts +4 -5
- package/src/native-tool-catalog.ts +15 -1
- package/src/nexus/api/graphs-api.ts +22 -3
- package/src/nexus/api/http-server.ts +1 -1
- package/src/nexus/api/loop-resources.ts +13 -1
- package/src/nexus/api/ops-api.ts +12 -0
- package/src/oauth/claude-pty-maturity.ts +66 -0
- package/src/oauth/codex-access-mirror.ts +55 -0
- package/src/oauth/codex.ts +7 -0
- package/src/oauth/fallback-chain.ts +1 -1
- package/src/onboarding/first-run.ts +5 -3
- package/src/onboarding/non-interactive.ts +64 -13
- package/src/onboarding.ts +10 -2
- package/src/ops/overview-collect.ts +54 -4
- package/src/ops/overview.ts +31 -7
- package/src/pr-tool/census.ts +282 -30
- package/src/pr-tool/inflight-registry.ts +160 -7
- package/src/prompt-library/gpt6-family-addendum.ts +14 -1
- package/src/pty-shell/herdr-agent-report.ts +442 -0
- package/src/pty-shell/pty-control-ipc.ts +5 -5
- package/src/pty-shell/pty-manifest.ts +7 -0
- package/src/pty-shell/pty-write-outcome.ts +24 -6
- package/src/pty-shell/tui-run-state.ts +117 -3
- package/src/release-loop/checklist.ts +103 -5
- package/src/release-loop/feature-store.ts +19 -2
- package/src/release-loop/landed-but-yellow.ts +129 -5
- package/src/release-loop/light-rc.ts +1 -0
- package/src/release-loop/placement.ts +10 -3
- package/src/release-loop/rehearsal.ts +205 -25
- package/src/release-loop/rubric.ts +16 -2
- package/src/repl/index.ts +174 -17
- package/src/repl/ops-msg-bridge.ts +32 -0
- package/src/self-dev/ask-launch-flow.ts +44 -5
- package/src/self-dev/cli-help-text.ts +17 -0
- package/src/self-dev/dev-cli.ts +11 -9
- package/src/self-dev/draft-residue.ts +37 -1
- package/src/self-dev/draft-sweep.ts +188 -13
- package/src/self-dev/draft-triage-rules.ts +107 -0
- package/src/self-dev/fleet-reduce.ts +3 -2
- package/src/self-dev/graph-front-nodes.ts +112 -0
- package/src/self-dev/graph-journey-nodes.ts +11 -6
- package/src/self-dev/graph-journey-route.ts +60 -6
- package/src/self-dev/harness-run-cli.ts +3 -15
- package/src/self-dev/orchestrate-cli-text.ts +10 -0
- package/src/self-dev/orchestrate.ts +79 -3
- package/src/self-dev/review-provider-fallback.ts +35 -1
- package/src/self-dev/run-supervisor.ts +107 -12
- package/src/self-dev/run-types.ts +5 -1
- package/src/self-dev/self-orchestrate-runtime.ts +1 -11
- package/src/self-dev/shard-aggregate.ts +42 -5
- package/src/self-dev/shard-run.ts +8 -1
- package/src/self-implement/blocked-draft-policy.ts +20 -0
- package/src/self-implement/classify-shadow.ts +3 -7
- package/src/self-implement/doctor-visit.ts +18 -1
- package/src/self-implement/gate-baseline.ts +95 -12
- package/src/self-implement/gate-cli.ts +1 -0
- package/src/self-implement/gate-remote.ts +40 -25
- package/src/self-implement/goal-author-decompose.ts +275 -47
- package/src/self-implement/goal-author-identity.ts +66 -0
- package/src/self-implement/goal-author-preservation-obligation.ts +35 -0
- package/src/self-implement/goal-author.ts +254 -120
- package/src/self-implement/goal-elaborate.ts +295 -0
- package/src/self-implement/goal-refine.ts +270 -0
- package/src/self-implement/graph-overlay-yaml.ts +28 -2
- package/src/self-implement/graph-unit-flatten.ts +103 -0
- package/src/self-implement/graph-unit-resolver.ts +107 -0
- package/src/self-implement/graph-yaml.ts +151 -1
- package/src/self-implement/headless-elanous-driver.ts +1 -0
- package/src/self-implement/knowhow-pack.ts +103 -0
- package/src/self-implement/orchestrator.ts +160 -45
- package/src/self-implement/pod-warm-pool-profile.ts +45 -0
- package/src/self-implement/review-mustfix-class.ts +203 -0
- package/src/self-implement/rework-budget-judgment.ts +5 -8
- package/src/self-implement/run-stop.ts +17 -2
- package/src/self-implement/running-runs.ts +29 -1
- package/src/self-implement/scope-adjacency.ts +113 -0
- package/src/self-implement/seams.ts +138 -4
- package/src/self-implement/stop-autoheal.ts +112 -2
- package/src/session/chat.ts +27 -0
- package/src/session-runtime/index.ts +1 -1
- package/src/session-runtime/retry-policy.ts +2 -1
- package/src/setup/llm-env-detect.ts +5 -0
- package/src/skills/tools/agent.ts +140 -14
- package/src/skills/tools/msg-ask.ts +100 -0
- package/src/skills/tools/ops-ledger.ts +2 -1
- package/src/skills/tools/schedule-wakeup.ts +66 -17
- package/src/steward/hold-hygiene.ts +24 -6
- package/src/steward/release-day.ts +7 -3
- package/src/steward/triage-budget.ts +194 -0
- package/src/steward/triage.ts +57 -7
- package/src/task-agent/actions.ts +69 -1
- package/src/task-agent/green-sweep.ts +4 -0
- package/src/task-agent/harvest-unit.ts +141 -0
- package/src/task-agent/live-moves.ts +257 -15
- package/src/task-agent/parent-host.ts +216 -6
- package/src/task-agent/postland-card.ts +80 -1
- package/src/task-agent/rejudge-on-head.ts +112 -26
- package/src/task-agent/repair-branch-cas.ts +4 -1
- package/src/task-agent/repair-cycle.ts +16 -3
- package/src/task-agent/run-identity.ts +4 -3
- package/src/task-agent/shadow.ts +19 -3
- package/src/task-agent/task-hand.ts +96 -36
- package/src/task-agent/tier-split.ts +127 -0
- package/src/task-agent/work-order-build.ts +24 -0
- package/src/task-agent/work-order.ts +3 -2
- package/src/task-orchestrator/generator-prompt.ts +60 -11
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +72 -3
- package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-command-job.ts +47 -8
- package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
- package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
- package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +86 -8
- package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +8 -2
- package/src/task-orchestrator/surfaces/pod-pool.ts +73 -17
- package/src/task-orchestrator/surfaces/pod-provenance.ts +76 -0
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +72 -4
- package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +32 -5
- package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +3 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +421 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +2 -1
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +588 -71
- package/src/task-orchestrator/surfaces/self-implement.ts +106 -2
- package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
- package/src/tool-runtime/truncation-store.ts +4 -0
- package/src/tui/README.md +2 -0
- package/src/tui/chat/background-job-status.ts +54 -0
- package/src/tui/chat/log-view.ts +80 -0
- package/src/tui/entry.ts +406 -0
- package/src/tui/input/composer.ts +144 -0
- package/src/tui/seat-mail-boot.ts +59 -0
- package/src/tui/slash/compact.ts +100 -0
- package/src/tui/slash/new-session.ts +35 -0
- package/src/tui-client/dashboard-session.ts +10 -1
- package/src/tui-client/local-chat-turn.ts +239 -0
- package/src/tui-client/local-harness-command.ts +63 -0
- package/src/tui-client/local-provider-command.ts +184 -0
- package/src/user-config/coercion.ts +36 -0
- package/src/user-config.ts +22 -43
- package/src/ux-sim/event-monkey.ts +378 -0
- package/src/ux-sim/fake-bin.ts +42 -7
- package/src/ux-sim/fault-nextmove-dispatch.ts +266 -0
- package/src/ux-sim/fault-pod-codex-503.ts +211 -0
- package/src/ux-sim/fault-scope-escape-lift.ts +189 -0
- package/src/ux-sim/scenario.ts +72 -13
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +0 -27
- package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +0 -287
- package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +0 -62
- package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1654.32de4b324981a188.js +0 -23
- package/apps/pwa/out/_next/static/chunks/1834-98b64172bc1efe77.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +0 -149
- package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +0 -41
- package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2898.fd781bc7cf01a7b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +0 -115
- package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +0 -64
- package/apps/pwa/out/_next/static/chunks/3541-ce3a5424ed5ad7f1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +0 -36
- package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +0 -286
- package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +0 -77
- package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +0 -226
- package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +0 -79
- package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +0 -148
- package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5458-16cd7a2b51b74c8c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5543.a438b8ab5a13ea47.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +0 -74
- package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +0 -94
- package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +0 -90
- package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +0 -32
- package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +0 -104
- package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +0 -24
- package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +0 -93
- package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +0 -8
- package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +0 -1
- package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +0 -24
- package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9138.b6e80031afb1d973.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9279-d28c5b7754d010ae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9989.3694300e5f000b14.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-8c66a3b24a745630.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-c219f2ed171131be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +0 -1
- package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +0 -122
- package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +0 -1
- package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +0 -1
- package/src/cli/g6a-registration-probe.ts +0 -16
- /package/apps/pwa/out/_next/static/{IVKr3AlRUVLKsw2fh7eXF → T1mBQqmkwKDLGtyisDCOd}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// TUI-NEXT-COMPACT — next TUI context compaction (auto before a turn · `/compact` now).
|
|
2
|
+
// Wiring only: the threshold (shouldAutoCompact) and the pipeline (runCompactPipeline) run inside the
|
|
3
|
+
// shared session bridge `compactSessionHistory` (src/session/compact-session.ts), the same seam the
|
|
4
|
+
// continuation loop and `elanous session compact` use. Thresholds and anchor counts are the shared
|
|
5
|
+
// `chat.autoCompact` defaults. The REPL child reloads the session file every turn (session/chat.ts
|
|
6
|
+
// runTurn → loadSession), so rewriting the store between turns is what the next model call sees.
|
|
7
|
+
import { debug } from '../../debug/log.js';
|
|
8
|
+
import { compactSessionHistory } from '../../session/compact-session.js';
|
|
9
|
+
import type { CompactProvider } from '../../compact/provider.js';
|
|
10
|
+
import type { ChatAutoCompactConfig } from '../../user-config.js';
|
|
11
|
+
|
|
12
|
+
export const COMPACT_BUSY_STATUS = '응답 중에는 /compact 를 받지 않습니다 · 완료(또는 Esc 취소) 뒤 다시';
|
|
13
|
+
export const COMPACT_NO_SESSION_STATUS = '압축할 대화가 없습니다';
|
|
14
|
+
|
|
15
|
+
export function isCompactCommand(text: string): boolean {
|
|
16
|
+
return text.trim() === '/compact';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Test/embedding seams. Production passes none of these. */
|
|
20
|
+
export interface NextTuiCompactDeps {
|
|
21
|
+
readonly provider?: CompactProvider;
|
|
22
|
+
readonly config?: ChatAutoCompactConfig;
|
|
23
|
+
readonly modelId?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface NextTuiCompactOutcome {
|
|
27
|
+
readonly fired: boolean;
|
|
28
|
+
readonly reason: string;
|
|
29
|
+
readonly before: number;
|
|
30
|
+
readonly after: number;
|
|
31
|
+
readonly ms: number;
|
|
32
|
+
/** Status-line text, or null when an auto check stays silent (under threshold). */
|
|
33
|
+
readonly status: string | null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function compactStatus(before: number, after: number): string {
|
|
37
|
+
return `압축 ${before}→${after} 메시지`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function defaultConfig(): Promise<ChatAutoCompactConfig> {
|
|
41
|
+
const { getUserConfig } = await import('../../user-config.js');
|
|
42
|
+
return getUserConfig().chat.autoCompact;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Same resolution order as the continuation runner (dispatch/continuation-turn-runner.ts). */
|
|
46
|
+
async function defaultModelId(): Promise<string | undefined> {
|
|
47
|
+
try {
|
|
48
|
+
const { getUserConfig } = await import('../../user-config.js');
|
|
49
|
+
const cfg = getUserConfig();
|
|
50
|
+
if (cfg.llm?.model) return cfg.llm.model;
|
|
51
|
+
const { getProviderForConfig } = await import('../../llm.js');
|
|
52
|
+
return getProviderForConfig(cfg).defaultModel;
|
|
53
|
+
} catch {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Compact the next-TUI session once. `force:false` = the pre-turn auto check (fires only over the
|
|
60
|
+
* shared threshold); `force:true` = `/compact` (bypasses the threshold). Never throws: a failure is
|
|
61
|
+
* observed and reported as not fired, so the caller sends its turn uncompacted.
|
|
62
|
+
*/
|
|
63
|
+
export async function compactNextTuiSession(
|
|
64
|
+
sessionId: string,
|
|
65
|
+
input: { readonly force: boolean; readonly modelId?: string | null },
|
|
66
|
+
deps: NextTuiCompactDeps = {},
|
|
67
|
+
): Promise<NextTuiCompactOutcome> {
|
|
68
|
+
const auto = !input.force;
|
|
69
|
+
const started = Date.now();
|
|
70
|
+
try {
|
|
71
|
+
const config = deps.config ?? await defaultConfig();
|
|
72
|
+
if (auto && !config.enabled) return { fired: false, reason: 'disabled', before: 0, after: 0, ms: 0, status: null };
|
|
73
|
+
const modelId = input.modelId ?? deps.modelId ?? await defaultModelId();
|
|
74
|
+
const result = await compactSessionHistory(sessionId, {
|
|
75
|
+
config,
|
|
76
|
+
force: input.force,
|
|
77
|
+
...(modelId ? { modelId } : {}),
|
|
78
|
+
...(deps.provider ? { provider: deps.provider } : {}),
|
|
79
|
+
});
|
|
80
|
+
const ms = Date.now() - started;
|
|
81
|
+
if (result.fired) {
|
|
82
|
+
debug.log('tui.next', 'compact', { auto, before: result.before, after: result.after, ms });
|
|
83
|
+
return { fired: true, reason: result.reason, before: result.before, after: result.after, ms, status: compactStatus(result.before, result.after) };
|
|
84
|
+
}
|
|
85
|
+
if (!auto) debug.log('tui.next', 'compact-skipped', { auto, reason: result.reason, before: result.before, ms });
|
|
86
|
+
return {
|
|
87
|
+
fired: false,
|
|
88
|
+
reason: result.reason,
|
|
89
|
+
before: result.before,
|
|
90
|
+
after: result.after,
|
|
91
|
+
ms,
|
|
92
|
+
status: auto ? null : `압축할 내용 없음 · ${result.before} 메시지`,
|
|
93
|
+
};
|
|
94
|
+
} catch (error) {
|
|
95
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
96
|
+
const ms = Date.now() - started;
|
|
97
|
+
debug.log('tui.next', 'compact-failed', { auto, ms, error: message }, { level: 'warn' });
|
|
98
|
+
return { fired: false, reason: 'error', before: 0, after: 0, ms, status: auto ? null : `압축 실패: ${message}` };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// `/new` (alias `/session new`) — leave a session that outgrew its context without quitting next TUI.
|
|
2
|
+
// The old session is never deleted; only the active marker moves.
|
|
3
|
+
import { debug } from '../../debug/log.js';
|
|
4
|
+
import { createSession, setActiveSessionId } from '../../session/index.js';
|
|
5
|
+
|
|
6
|
+
export const NEW_SESSION_BUSY_STATUS = '응답 중에는 /new 를 받지 않습니다 · 완료(또는 Esc 취소) 뒤 다시';
|
|
7
|
+
|
|
8
|
+
/** Store placeholder for an untitled session (session/index.ts createSession). */
|
|
9
|
+
const UNTITLED = '(new session)';
|
|
10
|
+
|
|
11
|
+
export function isNewSessionCommand(text: string): boolean {
|
|
12
|
+
const normalized = text.trim().split(/\s+/).join(' ');
|
|
13
|
+
return normalized === '/new' || normalized === '/session new';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function nextTuiTitle(meta: { readonly title?: string } | null | undefined): string {
|
|
17
|
+
const title = meta?.title?.split('\n')[0]?.trim() ?? '';
|
|
18
|
+
return !title || title === UNTITLED ? '새 대화' : title;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type NewTuiSessionResult =
|
|
22
|
+
| { readonly kind: 'started'; readonly id: string; readonly status: string }
|
|
23
|
+
| { readonly kind: 'rejected'; readonly status: string };
|
|
24
|
+
|
|
25
|
+
export function requestNewTuiSession(input: { readonly busy: boolean; readonly from: string | null }): NewTuiSessionResult {
|
|
26
|
+
const { busy, from } = input;
|
|
27
|
+
if (busy) {
|
|
28
|
+
debug.log('tui.next', 'session-new-rejected', { from, reason: 'busy' });
|
|
29
|
+
return { kind: 'rejected', status: NEW_SESSION_BUSY_STATUS };
|
|
30
|
+
}
|
|
31
|
+
const id = createSession({ source: 'tui' }).id;
|
|
32
|
+
setActiveSessionId(id);
|
|
33
|
+
debug.log('tui.next', 'session-new', { from, to: id });
|
|
34
|
+
return { kind: 'started', id, status: `새 대화 · 이전 = ${from ? from.slice(0, 8) : '없음'}` };
|
|
35
|
+
}
|
|
@@ -130,6 +130,9 @@ export interface DashboardSendRequest {
|
|
|
130
130
|
* more per turn, provider-dependent). Shape matches
|
|
131
131
|
* `StreamWithToolsHandlers.onUsage` modulo the correlation id. */
|
|
132
132
|
onUsage?(usage: DashboardSessionUsage): void;
|
|
133
|
+
/** TUI-TURN-NARRATION — `agent_thought_chunk` ⊕ `_meta.reasoning: true`(추론 요약 문단).
|
|
134
|
+
* 전에는 usage 봉투가 아니면 버려서 화면에 0줄이었다(결함 #87). */
|
|
135
|
+
onThought?(text: string): void;
|
|
133
136
|
}
|
|
134
137
|
|
|
135
138
|
export interface DashboardSendResult {
|
|
@@ -550,6 +553,7 @@ function buildSendInterceptor(req: DashboardSendRequest): SessionUpdateIntercept
|
|
|
550
553
|
rawInput?: unknown;
|
|
551
554
|
rawOutput?: unknown;
|
|
552
555
|
status?: string;
|
|
556
|
+
_meta?: { reasoning?: unknown };
|
|
553
557
|
};
|
|
554
558
|
};
|
|
555
559
|
const inner = n.update;
|
|
@@ -582,8 +586,13 @@ function buildSendInterceptor(req: DashboardSendRequest): SessionUpdateIntercept
|
|
|
582
586
|
return;
|
|
583
587
|
}
|
|
584
588
|
case 'agent_thought_chunk': {
|
|
585
|
-
if (
|
|
589
|
+
if (inner.content?.type !== 'text') return;
|
|
586
590
|
const text = inner.content.text ?? '';
|
|
591
|
+
if (inner._meta?.reasoning === true) {
|
|
592
|
+
req.onThought?.(text);
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
if (!req.onUsage) return;
|
|
587
596
|
const env = parseElanousUiEnvelope(text);
|
|
588
597
|
if (!env || env.method !== 'usage') return;
|
|
589
598
|
const { id: _id, ...rest } = env.payload as unknown as ElanousUiUsagePayload;
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/** Keep one REPL child per session so background tasks and their completion queue survive turns. */
|
|
2
|
+
import type { NextTuiCompactDeps, NextTuiCompactOutcome } from '../tui/slash/compact.js';
|
|
3
|
+
|
|
4
|
+
const STATUS_PREFIX = 'ELANOUS_TUI_BG_STATUS\t';
|
|
5
|
+
|
|
6
|
+
interface TurnResult {
|
|
7
|
+
event?: string | null;
|
|
8
|
+
turnId?: string | null;
|
|
9
|
+
text?: string;
|
|
10
|
+
error?: string;
|
|
11
|
+
provider?: string;
|
|
12
|
+
model?: string | null;
|
|
13
|
+
}
|
|
14
|
+
interface WaitingTurn {
|
|
15
|
+
turnId: string;
|
|
16
|
+
onDelta?: (text: string) => void;
|
|
17
|
+
resolve: (result: TurnResult) => void;
|
|
18
|
+
reject: (error: Error) => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
class LocalChatSession {
|
|
22
|
+
readonly child: ReturnType<typeof Bun.spawn>;
|
|
23
|
+
readonly exited: Promise<number>;
|
|
24
|
+
private readonly writeInput: (payload: string) => Promise<void>;
|
|
25
|
+
private waiting: WaitingTurn | null = null;
|
|
26
|
+
private stderrTail = '';
|
|
27
|
+
private closed = false;
|
|
28
|
+
private closing: Promise<void> | null = null;
|
|
29
|
+
private invalidated = false;
|
|
30
|
+
private turnCount = 0;
|
|
31
|
+
|
|
32
|
+
constructor(private readonly sessionId: string, cli: string) {
|
|
33
|
+
this.child = Bun.spawn({
|
|
34
|
+
cmd: [process.execPath, cli, 'repl', '--session', sessionId, '--json', '--stdin-jsonl'],
|
|
35
|
+
stdin: 'pipe', stdout: 'pipe', stderr: 'pipe',
|
|
36
|
+
env: { ...process.env, ELANOUS_NEXT_TUI_BG_STATUS: '1', ELANOUS_NEXT_TUI_STREAM: '1' },
|
|
37
|
+
});
|
|
38
|
+
const input = this.child.stdin;
|
|
39
|
+
const output = this.child.stdout;
|
|
40
|
+
const errors = this.child.stderr;
|
|
41
|
+
if (!input || typeof input === 'number' || !output || typeof output === 'number'
|
|
42
|
+
|| !errors || typeof errors === 'number') throw new Error('REPL pipe unavailable');
|
|
43
|
+
this.writeInput = async (payload) => { input.write(payload); await input.flush(); };
|
|
44
|
+
this.exited = this.child.exited;
|
|
45
|
+
void this.readLines(output, (line) => {
|
|
46
|
+
if (!line.trim()) return;
|
|
47
|
+
let result: TurnResult;
|
|
48
|
+
try { result = JSON.parse(line) as TurnResult; }
|
|
49
|
+
catch { this.fail(new Error('invalid REPL JSONL response')); return; }
|
|
50
|
+
const waiting = this.waiting;
|
|
51
|
+
if (!waiting) return;
|
|
52
|
+
if ('turnId' in result && result.turnId !== waiting.turnId) return;
|
|
53
|
+
if (result.event === 'delta') {
|
|
54
|
+
if (result.turnId !== waiting.turnId) return;
|
|
55
|
+
if (typeof result.text === 'string') {
|
|
56
|
+
try { waiting.onDelta?.(result.text); } catch { /* renderer cannot break the turn */ }
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// Future side-channel events cannot complete a turn. Legacy final
|
|
61
|
+
// frames have no event; typed final frames use event=result.
|
|
62
|
+
if ('event' in result && result.event !== 'result') return;
|
|
63
|
+
this.waiting = null;
|
|
64
|
+
waiting.resolve(result);
|
|
65
|
+
}, () => {
|
|
66
|
+
this.invalidate();
|
|
67
|
+
this.fail(new Error('REPL stdout closed'));
|
|
68
|
+
void this.close();
|
|
69
|
+
});
|
|
70
|
+
void this.readLines(errors, (line) => {
|
|
71
|
+
if (line.startsWith(STATUS_PREFIX)) {
|
|
72
|
+
for (const listener of statusListeners.get(sessionId) ?? []) {
|
|
73
|
+
try { listener(line.slice(STATUS_PREFIX.length)); } catch { /* status observers cannot break the turn */ }
|
|
74
|
+
}
|
|
75
|
+
} else if (line.trim()) {
|
|
76
|
+
this.stderrTail = line.trim();
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
void this.exited.then((code) => {
|
|
80
|
+
this.closed = true;
|
|
81
|
+
this.invalidate();
|
|
82
|
+
if (sessions.get(sessionId) === this) sessions.delete(sessionId);
|
|
83
|
+
this.fail(new Error(this.stderrTail || `chat exit ${code}`));
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private async readLines(stream: ReadableStream<Uint8Array>, receive: (line: string) => void, onEnd?: () => void): Promise<void> {
|
|
88
|
+
const reader = stream.getReader();
|
|
89
|
+
const decoder = new TextDecoder();
|
|
90
|
+
let buffer = '';
|
|
91
|
+
try {
|
|
92
|
+
while (true) {
|
|
93
|
+
const { value, done } = await reader.read();
|
|
94
|
+
if (done) break;
|
|
95
|
+
buffer += decoder.decode(value, { stream: true });
|
|
96
|
+
let newline: number;
|
|
97
|
+
while ((newline = buffer.indexOf('\n')) >= 0) {
|
|
98
|
+
receive(buffer.slice(0, newline));
|
|
99
|
+
buffer = buffer.slice(newline + 1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
buffer += decoder.decode();
|
|
103
|
+
if (buffer) receive(buffer);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
this.fail(error instanceof Error ? error : new Error(String(error)));
|
|
106
|
+
} finally {
|
|
107
|
+
reader.releaseLock();
|
|
108
|
+
onEnd?.();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private fail(error: Error): void {
|
|
113
|
+
const waiting = this.waiting;
|
|
114
|
+
this.waiting = null;
|
|
115
|
+
waiting?.reject(error);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private invalidate(): void {
|
|
119
|
+
if (this.invalidated) return;
|
|
120
|
+
this.invalidated = true;
|
|
121
|
+
for (const listener of statusListeners.get(this.sessionId) ?? []) {
|
|
122
|
+
try { listener(null); } catch { /* status observers cannot break teardown */ }
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async turn(prompt: string, writePrompt?: (payload: string) => Promise<void>, onDelta?: (text: string) => void): Promise<TurnResult> {
|
|
127
|
+
if (this.closed) throw new Error('REPL child exited');
|
|
128
|
+
if (this.waiting) throw new Error('REPL turn already running');
|
|
129
|
+
const turnId = `tui-${++this.turnCount}`;
|
|
130
|
+
const payload = `${JSON.stringify({ prompt, id: turnId })}\n`;
|
|
131
|
+
const response = new Promise<TurnResult>((resolve, reject) => { this.waiting = { turnId, onDelta, resolve, reject }; });
|
|
132
|
+
try {
|
|
133
|
+
if (writePrompt) await writePrompt(payload);
|
|
134
|
+
else await this.writeInput(payload);
|
|
135
|
+
} catch (error) {
|
|
136
|
+
this.fail(error instanceof Error ? error : new Error(String(error)));
|
|
137
|
+
}
|
|
138
|
+
return response;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async close(): Promise<void> {
|
|
142
|
+
if (!this.closing) {
|
|
143
|
+
this.closing = (async () => {
|
|
144
|
+
if (!this.closed) {
|
|
145
|
+
this.closed = true;
|
|
146
|
+
this.invalidate();
|
|
147
|
+
try { this.child.kill(); } catch { /* already exited */ }
|
|
148
|
+
}
|
|
149
|
+
await this.exited;
|
|
150
|
+
})();
|
|
151
|
+
}
|
|
152
|
+
await this.closing;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const sessions = new Map<string, LocalChatSession>();
|
|
157
|
+
/** Model the child last answered with, per session — sizes the next pre-turn compaction check. */
|
|
158
|
+
const lastModels = new Map<string, string>();
|
|
159
|
+
|
|
160
|
+
export function localChatModel(sessionId: string): string | null {
|
|
161
|
+
return lastModels.get(sessionId) ?? null;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** TUI-NEXT-COMPACT — pre-turn auto compaction hook (deps are test seams; production passes none). */
|
|
165
|
+
export interface LocalChatTurnCompact {
|
|
166
|
+
readonly deps?: NextTuiCompactDeps;
|
|
167
|
+
readonly onCompact?: (outcome: NextTuiCompactOutcome) => void;
|
|
168
|
+
}
|
|
169
|
+
const statusListeners = new Map<string, Set<(json: string | null) => void>>();
|
|
170
|
+
|
|
171
|
+
export function onLocalChatBackgroundStatus(sessionId: string, listener: (json: string | null) => void): () => void {
|
|
172
|
+
const listeners = statusListeners.get(sessionId) ?? new Set();
|
|
173
|
+
listeners.add(listener);
|
|
174
|
+
statusListeners.set(sessionId, listeners);
|
|
175
|
+
return () => {
|
|
176
|
+
listeners.delete(listener);
|
|
177
|
+
if (listeners.size === 0) statusListeners.delete(sessionId);
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export async function closeLocalChatSession(sessionId: string): Promise<void> {
|
|
182
|
+
const session = sessions.get(sessionId);
|
|
183
|
+
sessions.delete(sessionId);
|
|
184
|
+
lastModels.delete(sessionId);
|
|
185
|
+
await session?.close();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** Run one turn while retaining the child for the next turn. */
|
|
189
|
+
export async function runLocalChatTurn(
|
|
190
|
+
sessionId: string,
|
|
191
|
+
text: string,
|
|
192
|
+
signal: AbortSignal,
|
|
193
|
+
cli = process.argv[1],
|
|
194
|
+
writePrompt?: (payload: string) => Promise<void>,
|
|
195
|
+
onDelta?: (text: string) => void,
|
|
196
|
+
compact: LocalChatTurnCompact = {},
|
|
197
|
+
): Promise<void> {
|
|
198
|
+
if (signal.aborted) throw new Error('응답을 취소했습니다');
|
|
199
|
+
if (!cli) throw new Error('elanous CLI entry is unavailable');
|
|
200
|
+
// The REPL child reloads the session store each turn, so compacting the store here is what this
|
|
201
|
+
// turn's model call sees. Over the shared threshold only; a failure leaves the turn uncompacted.
|
|
202
|
+
// Lazy like this module itself: the compaction path pulls in the LLM router, so next TUI boot stays light.
|
|
203
|
+
const { compactNextTuiSession } = await import('../tui/slash/compact.js');
|
|
204
|
+
const compacted = await compactNextTuiSession(sessionId, { force: false, modelId: localChatModel(sessionId) }, compact.deps);
|
|
205
|
+
if (compacted.fired) {
|
|
206
|
+
try { compact.onCompact?.(compacted); } catch { /* status observers cannot break the turn */ }
|
|
207
|
+
}
|
|
208
|
+
if (signal.aborted) throw new Error('응답을 취소했습니다');
|
|
209
|
+
const session = sessions.get(sessionId) ?? new LocalChatSession(sessionId, cli);
|
|
210
|
+
sessions.set(sessionId, session);
|
|
211
|
+
const abort = (): void => { void closeLocalChatSession(sessionId); };
|
|
212
|
+
signal.addEventListener('abort', abort, { once: true });
|
|
213
|
+
if (signal.aborted) abort();
|
|
214
|
+
let result: TurnResult;
|
|
215
|
+
try {
|
|
216
|
+
result = await session.turn(text, writePrompt, (delta) => {
|
|
217
|
+
if (!signal.aborted) onDelta?.(delta);
|
|
218
|
+
});
|
|
219
|
+
} catch (error) {
|
|
220
|
+
if (signal.aborted) throw new Error('응답을 취소했습니다');
|
|
221
|
+
await closeLocalChatSession(sessionId);
|
|
222
|
+
throw error;
|
|
223
|
+
} finally {
|
|
224
|
+
signal.removeEventListener('abort', abort);
|
|
225
|
+
}
|
|
226
|
+
if (signal.aborted) throw new Error('응답을 취소했습니다');
|
|
227
|
+
// A completed JSONL error frame is a turn failure, not a transport failure:
|
|
228
|
+
// the child still owns live tasks and buffered notifications for retry.
|
|
229
|
+
if (result.error) throw new Error(result.error);
|
|
230
|
+
if (result.model) lastModels.set(sessionId, result.model);
|
|
231
|
+
if (result.provider) {
|
|
232
|
+
try {
|
|
233
|
+
const { debug } = await import('../debug/log.js');
|
|
234
|
+
debug.log('llm.route-decision', 'local-chat-executed', {
|
|
235
|
+
surface: 'tui-local', sessionId, provider: result.provider, model: result.model ?? null,
|
|
236
|
+
});
|
|
237
|
+
} catch { /* observation must not fail a completed turn */ }
|
|
238
|
+
}
|
|
239
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/** Run the existing harness CLI outside the TUI import graph and stream its result. */
|
|
2
|
+
export async function runLocalHarnessCommand(
|
|
3
|
+
command: 'ask' | 'runs',
|
|
4
|
+
goal: string,
|
|
5
|
+
signal: AbortSignal,
|
|
6
|
+
onLine: (line: string) => void,
|
|
7
|
+
cli = process.argv[1],
|
|
8
|
+
): Promise<void> {
|
|
9
|
+
if (signal.aborted) throw new Error('하니스 호출을 취소했습니다');
|
|
10
|
+
if (!cli) throw new Error('elanous CLI entry is unavailable');
|
|
11
|
+
const dryRun = command === 'ask' && goal.startsWith('--dry-run ');
|
|
12
|
+
const objective = dryRun ? goal.slice('--dry-run '.length).trim() : goal;
|
|
13
|
+
if (command === 'ask' && !objective) throw new Error('하니스 목표가 비었습니다');
|
|
14
|
+
const cmd = command === 'runs'
|
|
15
|
+
? [process.execPath, cli, 'harness', 'progress']
|
|
16
|
+
: [process.execPath, cli, 'harness', 'say', '--no-auto-merge', ...(dryRun ? ['--dry-run'] : []), objective];
|
|
17
|
+
const child = Bun.spawn({ cmd, stdin: 'ignore', stdout: 'pipe', stderr: 'pipe', env: process.env });
|
|
18
|
+
let omittedRunRows = 0;
|
|
19
|
+
let shownRunRows = 0;
|
|
20
|
+
const emit = (line: string): void => {
|
|
21
|
+
if (command === 'runs' && shownRunRows >= 16) { omittedRunRows++; return; }
|
|
22
|
+
shownRunRows++;
|
|
23
|
+
onLine(line);
|
|
24
|
+
};
|
|
25
|
+
const abort = (): void => { child.kill(); };
|
|
26
|
+
signal.addEventListener('abort', abort, { once: true });
|
|
27
|
+
if (signal.aborted) abort();
|
|
28
|
+
const readLines = async (stream: ReadableStream<Uint8Array>): Promise<string> => {
|
|
29
|
+
const reader = stream.getReader();
|
|
30
|
+
const decoder = new TextDecoder();
|
|
31
|
+
let pending = '';
|
|
32
|
+
let last = '';
|
|
33
|
+
while (true) {
|
|
34
|
+
const { done, value } = await reader.read();
|
|
35
|
+
pending += decoder.decode(value, { stream: !done });
|
|
36
|
+
let newline = pending.indexOf('\n');
|
|
37
|
+
while (newline >= 0) {
|
|
38
|
+
const line = pending.slice(0, newline).replace(/\r$/, '');
|
|
39
|
+
if (line.trim()) { emit(line); last = line; }
|
|
40
|
+
pending = pending.slice(newline + 1);
|
|
41
|
+
newline = pending.indexOf('\n');
|
|
42
|
+
}
|
|
43
|
+
if (done) break;
|
|
44
|
+
}
|
|
45
|
+
if (pending.trim()) { emit(pending); last = pending; }
|
|
46
|
+
return last;
|
|
47
|
+
};
|
|
48
|
+
try {
|
|
49
|
+
const [outLast, errLast, code] = await Promise.all([
|
|
50
|
+
readLines(child.stdout), readLines(child.stderr), child.exited,
|
|
51
|
+
]);
|
|
52
|
+
if (signal.aborted) throw new Error('하니스 호출을 취소했습니다');
|
|
53
|
+
if (code !== 0) throw new Error(errLast || outLast || `harness exit ${code}`);
|
|
54
|
+
if (omittedRunRows > 0) onLine(`추가 ${omittedRunRows}행 생략 · 전체: eln harness progress`);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
try { child.kill(); } catch { /* already exited */ }
|
|
57
|
+
await child.exited;
|
|
58
|
+
if (signal.aborted) throw new Error('하니스 호출을 취소했습니다');
|
|
59
|
+
throw error;
|
|
60
|
+
} finally {
|
|
61
|
+
signal.removeEventListener('abort', abort);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { loadCatalog } from '../intelligence-map/model-catalog.js';
|
|
2
|
+
import { getUserConfig, PROVIDER_DEFAULT_MODEL, reloadUserConfig } from '../user-config.js';
|
|
3
|
+
|
|
4
|
+
type FetchModels = (url: string, init: RequestInit) => Promise<Response>;
|
|
5
|
+
type ModelList = { ids: string[]; source: 'remote' | 'cache' | 'local'; note?: string };
|
|
6
|
+
|
|
7
|
+
const MODEL_LOOKUP_TIMEOUT_MS = 2_000;
|
|
8
|
+
const MODEL_DISPLAY_LIMIT = 12;
|
|
9
|
+
|
|
10
|
+
/** The provider command is imported only when opened; this cache lives for one TUI process. */
|
|
11
|
+
export class ProviderModelCache {
|
|
12
|
+
private local = new Map<string, string[]>();
|
|
13
|
+
private lastGoodRemote = new Map<string, { apiKey: string | undefined; ids: string[] }>();
|
|
14
|
+
|
|
15
|
+
localModels(provider: string): string[] {
|
|
16
|
+
const cached = this.local.get(provider);
|
|
17
|
+
if (cached) return cached;
|
|
18
|
+
const ids = [...new Set(loadCatalog().catalog.models
|
|
19
|
+
.filter((model) => model.provider === provider)
|
|
20
|
+
.map((model) => model.id))].sort();
|
|
21
|
+
this.local.set(provider, ids);
|
|
22
|
+
return ids;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async models(
|
|
26
|
+
provider: string,
|
|
27
|
+
remoteUrl: string | undefined,
|
|
28
|
+
apiKey: string | undefined,
|
|
29
|
+
signal: AbortSignal,
|
|
30
|
+
refresh = false,
|
|
31
|
+
fetchModels: FetchModels = fetch,
|
|
32
|
+
timeoutMs = MODEL_LOOKUP_TIMEOUT_MS,
|
|
33
|
+
): Promise<ModelList> {
|
|
34
|
+
if (signal.aborted) throw new Error('provider lookup cancelled');
|
|
35
|
+
const local = this.localModels(provider);
|
|
36
|
+
if (!remoteUrl) return { ids: local, source: 'local' };
|
|
37
|
+
const cacheKey = `${provider}\0${remoteUrl}`;
|
|
38
|
+
const cached = this.lastGoodRemote.get(cacheKey);
|
|
39
|
+
const previous = cached && cached.apiKey === apiKey ? cached.ids : undefined;
|
|
40
|
+
if (previous && !refresh) return { ids: previous, source: 'cache' };
|
|
41
|
+
try {
|
|
42
|
+
const ids = await queryRemoteModels(remoteUrl, apiKey, signal, fetchModels, timeoutMs);
|
|
43
|
+
this.lastGoodRemote.set(cacheKey, { apiKey, ids });
|
|
44
|
+
return { ids, source: 'remote' };
|
|
45
|
+
} catch (error) {
|
|
46
|
+
if (signal.aborted) throw error;
|
|
47
|
+
const note = error instanceof Error ? error.message : String(error);
|
|
48
|
+
if (previous) return { ids: previous, source: 'cache', note };
|
|
49
|
+
return { ids: local, source: 'local', note };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const cache = new ProviderModelCache();
|
|
55
|
+
const supportedProvider = (name: string): boolean => Object.prototype.hasOwnProperty.call(PROVIDER_DEFAULT_MODEL, name);
|
|
56
|
+
|
|
57
|
+
async function queryRemoteModels(
|
|
58
|
+
url: string,
|
|
59
|
+
apiKey: string | undefined,
|
|
60
|
+
signal: AbortSignal,
|
|
61
|
+
fetchModels: FetchModels = fetch,
|
|
62
|
+
timeoutMs = MODEL_LOOKUP_TIMEOUT_MS,
|
|
63
|
+
): Promise<string[]> {
|
|
64
|
+
if (signal.aborted) throw new Error('provider lookup cancelled');
|
|
65
|
+
const controller = new AbortController();
|
|
66
|
+
let rejectCancelled: ((reason: Error) => void) | undefined;
|
|
67
|
+
const cancelled = new Promise<never>((_, reject) => { rejectCancelled = reject; });
|
|
68
|
+
const cancel = (): void => {
|
|
69
|
+
controller.abort();
|
|
70
|
+
rejectCancelled?.(new Error('provider lookup cancelled'));
|
|
71
|
+
};
|
|
72
|
+
signal.addEventListener('abort', cancel, { once: true });
|
|
73
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
74
|
+
try {
|
|
75
|
+
if (signal.aborted) throw new Error('provider lookup cancelled');
|
|
76
|
+
const deadline = new Promise<never>((_, reject) => {
|
|
77
|
+
timer = setTimeout(() => {
|
|
78
|
+
reject(new Error('remote model lookup timed out'));
|
|
79
|
+
controller.abort();
|
|
80
|
+
}, timeoutMs);
|
|
81
|
+
});
|
|
82
|
+
const request = (async () => {
|
|
83
|
+
const response = await fetchModels(url, {
|
|
84
|
+
signal: controller.signal,
|
|
85
|
+
headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : {},
|
|
86
|
+
});
|
|
87
|
+
if (!response.ok) throw new Error(`remote model lookup HTTP ${response.status}`);
|
|
88
|
+
const payload = await response.json() as unknown;
|
|
89
|
+
if (!payload || typeof payload !== 'object' || !('data' in payload) || !Array.isArray(payload.data)
|
|
90
|
+
|| payload.data.some((entry: unknown) => !entry || typeof entry !== 'object'
|
|
91
|
+
|| !('id' in entry) || typeof entry.id !== 'string' || entry.id.trim().length === 0)) {
|
|
92
|
+
throw new Error('remote model list is malformed');
|
|
93
|
+
}
|
|
94
|
+
const ids = [...new Set(payload.data.map((entry: { id: string }) => entry.id))].sort();
|
|
95
|
+
if (ids.length === 0) throw new Error('remote model list is empty');
|
|
96
|
+
return ids;
|
|
97
|
+
})();
|
|
98
|
+
return await Promise.race([request, deadline, cancelled]);
|
|
99
|
+
} finally {
|
|
100
|
+
if (timer) clearTimeout(timer);
|
|
101
|
+
signal.removeEventListener('abort', cancel);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function remoteModelsUrl(provider: string, baseUrl: string | undefined): string | undefined {
|
|
106
|
+
if (baseUrl) {
|
|
107
|
+
const base = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;
|
|
108
|
+
const url = new URL('models', base);
|
|
109
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:') throw new Error('invalid base URL');
|
|
110
|
+
return url.toString();
|
|
111
|
+
}
|
|
112
|
+
return provider === 'openrouter' ? 'https://openrouter.ai/api/v1/models' : undefined;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async function setProviderViaCli(provider: string, model: string | undefined, signal: AbortSignal): Promise<void> {
|
|
116
|
+
const cli = process.argv[1];
|
|
117
|
+
if (!cli) throw new Error('elanous CLI entry is unavailable');
|
|
118
|
+
const child = Bun.spawn({
|
|
119
|
+
cmd: [process.execPath, cli, 'provider:set', provider, ...(model ? ['--model', model] : [])],
|
|
120
|
+
stdin: 'ignore', stdout: 'pipe', stderr: 'pipe', env: process.env,
|
|
121
|
+
});
|
|
122
|
+
const abort = (): void => { child.kill(); };
|
|
123
|
+
signal.addEventListener('abort', abort, { once: true });
|
|
124
|
+
if (signal.aborted) abort();
|
|
125
|
+
try {
|
|
126
|
+
const [stdout, stderr, code] = await Promise.all([
|
|
127
|
+
new Response(child.stdout).text(), new Response(child.stderr).text(), child.exited,
|
|
128
|
+
]);
|
|
129
|
+
if (signal.aborted) throw new Error('provider switch cancelled');
|
|
130
|
+
if (code !== 0) throw new Error(stderr.trim().split('\n').at(-1) || stdout.trim().split('\n').at(-1) || `provider:set exit ${code}`);
|
|
131
|
+
reloadUserConfig();
|
|
132
|
+
} finally {
|
|
133
|
+
signal.removeEventListener('abort', abort);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export async function runLocalProviderCommand(
|
|
138
|
+
raw: string,
|
|
139
|
+
signal: AbortSignal,
|
|
140
|
+
onLine: (line: string) => void,
|
|
141
|
+
): Promise<void> {
|
|
142
|
+
if (signal.aborted) throw new Error('provider lookup cancelled');
|
|
143
|
+
const [action, providerArg, modelArg] = raw.trim() ? raw.trim().split(/\s+/) : ['list'];
|
|
144
|
+
const cfg = getUserConfig().llm;
|
|
145
|
+
const current = cfg.provider;
|
|
146
|
+
if (action === 'list') {
|
|
147
|
+
onLine(`현재: ${current}/${cfg.model || PROVIDER_DEFAULT_MODEL[current] || '기본 모델'}`);
|
|
148
|
+
for (const [name, model] of Object.entries(PROVIDER_DEFAULT_MODEL)) {
|
|
149
|
+
if (name === 'auto') continue;
|
|
150
|
+
onLine(`${name === current ? '●' : '○'} ${name} · ${model || '기본 모델'}`);
|
|
151
|
+
}
|
|
152
|
+
onLine('모델: /provider models [provider] · /provider refresh [provider]');
|
|
153
|
+
onLine('전환: /provider use <provider> [model]');
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (action === 'models' || action === 'refresh') {
|
|
157
|
+
const provider = providerArg || current;
|
|
158
|
+
if (!supportedProvider(provider)) throw new Error(`알 수 없는 provider: ${provider}`);
|
|
159
|
+
let url: string | undefined;
|
|
160
|
+
let urlError: string | undefined;
|
|
161
|
+
try {
|
|
162
|
+
url = provider === current ? remoteModelsUrl(provider, cfg.baseUrl) : remoteModelsUrl(provider, undefined);
|
|
163
|
+
} catch {
|
|
164
|
+
urlError = 'invalid base URL';
|
|
165
|
+
}
|
|
166
|
+
const result = await cache.models(provider, url, provider === current ? cfg.apiKey : undefined, signal, action === 'refresh');
|
|
167
|
+
const note = urlError ?? result.note;
|
|
168
|
+
onLine(`${provider} 모델 · ${result.source}${note ? ` (조회 실패: ${note})` : ''}`);
|
|
169
|
+
for (const id of result.ids.slice(0, MODEL_DISPLAY_LIMIT)) onLine(` ${id}`);
|
|
170
|
+
if (result.ids.length > MODEL_DISPLAY_LIMIT) onLine(` 외 ${result.ids.length - MODEL_DISPLAY_LIMIT}개`);
|
|
171
|
+
if (result.ids.length === 0) onLine(' 목록 없음 · /provider use <provider> <model>로 직접 지정 가능');
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (action === 'use') {
|
|
175
|
+
if (!providerArg || !supportedProvider(providerArg)) {
|
|
176
|
+
throw new Error('사용법: /provider use <provider> [model]');
|
|
177
|
+
}
|
|
178
|
+
await setProviderViaCli(providerArg, modelArg, signal);
|
|
179
|
+
const next = getUserConfig().llm;
|
|
180
|
+
onLine(`다음 턴 provider: ${next.provider}/${next.model || '기본 모델'}`);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
throw new Error('사용법: /provider · /provider models [provider] · /provider use <provider> [model]');
|
|
184
|
+
}
|