elanous 0.2.34 → 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/{L04y73dlwKeTW-GetaTF3 → T1mBQqmkwKDLGtyisDCOd}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{5014f970-22bef0b5210f7d60.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/{2124.ed5bf480cea7f85b.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/1674.2a65fd5668e1cc5f.js +1 -0
- 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/1993-c0007b7ad0c0ef41.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8368.014caa8de2f5af34.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/2625.5d870aa999f33db1.js +34 -0
- 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/{1644.35dd25240ae24e4b.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/{3121.779fafe3e44612c5.js → 3589.5444a06bcf6e775c.js} +1 -1
- 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/{9131-fce7256c4180c4a5.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/4346.8601952e73bf5803.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6053-d893974de92e6198.js → 4441-875b97f5821ed58a.js} +1 -1
- 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/{1895-60ed0e341c658bd4.js → 4705-194e64e47ca0fbdb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5576-82d3703636d5c4b9.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/{7431.3051e9b8a4372d2d.js → 5101.e32282718f99ed6f.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +1 -0
- 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/{2987-30cf9c2eb7b8bdd5.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/56d372f2.681ab4ec4c998fae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7386.5d8e7e42e818dfb6.js → 5852.db1f7449f4f74612.js} +2 -2
- 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/{3110.0a7065f25c841818.js → 6236.e18cced2d5ba6afb.js} +3 -3
- 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/6b89c8bd.24df687a820500b3.js +1 -0
- 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/{7005.1623d2aea78eb85f.js → 7385.50a308a477bdfc21.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6086.913a69e6fa3e4a8b.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/8219.baa715d1deee80e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +1 -0
- 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/{7193-cf355cca5ba6c5d5.js → 8437-8d5492094b166cfa.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2554.3b5e200f5f5cfcd6.js → 8444.4c26b379ca2b9596.js} +4 -4
- 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/{2547.dd27303624cb4da8.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/{9550.d5f76828f972058c.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/{8548.036c344973968847.js → 938.66ad1ef0e5abae1c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3414.172ad4ca2d9b08e8.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/967-2aa39b2d04b4c690.js +1 -0
- 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/{6740.43de73fc427c9fe2.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-406b47745b53f269.js +1 -0
- 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-d7bff0f0905a662c.js → page-26e6c18a1a750cf6.js} +1 -1
- 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-47c5d4db587266bd.js +1 -0
- 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-df3445b207ceceab.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/{9a8cb466.cc9fc9e6e46038aa.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/{4fa33ebd.21c1bd5b294496e6.js → cbe38a15.5a032598e39970c6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{abb4b98b.163e0f56e84ae35d.js → d06f9160.a3d9062f95de8ad7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9b48c871.204d5d13e7809bd0.js → da5176c6.6773b6c5994e1d99.js} +1 -1
- 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 +3 -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 +4 -0
- package/graphs/catalog/catalog.yaml +1 -1
- package/graphs/default-loop.yaml +57 -3
- package/graphs/document-loop.yaml +51 -3
- package/graphs/implement-loop.yaml +53 -4
- package/graphs/journey/ta-journey.yaml +11 -1
- 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/operate-loop.yaml +51 -3
- package/graphs/research-loop.yaml +137 -3
- package/graphs/test-diet/test-diet.yaml +3 -0
- package/package.json +1 -1
- package/scripts/coord-role-pack.ts +19 -6
- package/scripts/hq/standby-snapshot.ts +17 -12
- 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-node.ts +181 -22
- package/scripts/release-loop/gate-partial.ts +65 -11
- package/scripts/release-loop/gate-radius-live.ts +177 -0
- package/scripts/release-loop/gate-radius-shadow.ts +1 -1
- package/scripts/release-loop/node-verdict.ts +12 -1
- package/scripts/release-loop/npm-publish-node.ts +66 -12
- package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
- package/scripts/release-loop/pwa-remote.ts +166 -0
- package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
- package/scripts/release-loop/resume-release.ts +41 -4
- package/scripts/release-loop/unattended-release.ts +2 -0
- 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/agent/self-ambient-cache.ts +8 -0
- package/src/agent-substrate/acp-reviewer.ts +39 -4
- package/src/agent-substrate/pr-reviewer.ts +17 -0
- package/src/agent-substrate/self-review-cli.ts +62 -13
- package/src/autopilot/pr-manager.ts +215 -36
- 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/cli/agent-cli.ts +13 -2
- package/src/cli/doctor-cli.ts +4 -1
- package/src/cli/light-entry-route.ts +46 -6
- package/src/cli/pod-cli.ts +77 -3
- package/src/cli/pr-cli.ts +5 -2
- package/src/cli/pr-land-pod-shadow-job.ts +3 -0
- package/src/cli/release-checklist-read-cli.ts +79 -0
- package/src/cli/release-cli.ts +72 -102
- package/src/cli/remote-resolve.ts +1 -1
- package/src/cli/root-tui-entry.ts +48 -0
- package/src/cli/sim-cli.ts +22 -0
- package/src/cli/tasks-cli.ts +540 -31
- package/src/cli/usage-cli.ts +13 -11
- package/src/clipboard/history.ts +179 -13
- package/src/config.ts +8 -1
- package/src/dashboard/chat/acp-chat.ts +8 -0
- package/src/dashboard/index.ts +78 -10
- package/src/dashboard/render/theme-resolver.ts +33 -4
- package/src/domains/schedule-registry.ts +16 -2
- package/src/git-fs/idle-refresh.ts +76 -0
- package/src/git-fs/index.ts +18 -7
- package/src/git-fs/worktree.ts +42 -4
- package/src/graph-kinds/registry.ts +2 -2
- package/src/graph-runner/runner.ts +153 -10
- package/src/grok/credential.ts +10 -3
- package/src/harness/harness-cli-command.ts +112 -28
- package/src/harness/harness-incidents.ts +33 -0
- 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 +496 -143
- package/src/intake-plane/already-built-hint.ts +4 -2
- package/src/intake-plane/requirement-funnel.ts +29 -1
- package/src/light-cli.ts +27 -11
- 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 +213 -56
- package/src/model-tier/llm-tier-map.ts +15 -1
- package/src/native-tool-catalog.ts +15 -1
- package/src/nexus/api/loop-resources.ts +13 -1
- package/src/oauth/codex.ts +7 -0
- package/src/ops/overview-collect.ts +18 -3
- package/src/ops/overview.ts +20 -7
- package/src/pr-tool/census.ts +261 -27
- package/src/pty-shell/pty-manifest.ts +7 -0
- package/src/release-loop/checklist.ts +24 -0
- package/src/release-loop/landed-but-yellow.ts +129 -5
- package/src/release-loop/light-rc.ts +1 -0
- package/src/release-loop/rehearsal.ts +2 -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 +137 -11
- 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 +1 -0
- package/src/self-dev/harness-run-cli.ts +3 -15
- package/src/self-dev/orchestrate-cli-text.ts +10 -0
- package/src/self-dev/review-provider-fallback.ts +35 -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 +56 -17
- package/src/self-implement/gate-cli.ts +1 -0
- package/src/self-implement/gate-remote.ts +31 -20
- package/src/self-implement/goal-author-decompose.ts +275 -47
- package/src/self-implement/goal-author.ts +250 -0
- 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 +14 -3
- package/src/self-implement/orchestrator.ts +152 -45
- package/src/self-implement/rework-budget-judgment.ts +5 -8
- package/src/self-implement/run-stop.ts +10 -1
- package/src/self-implement/running-runs.ts +29 -1
- package/src/self-implement/scope-adjacency.ts +113 -0
- package/src/self-implement/seams.ts +127 -24
- package/src/self-implement/stop-autoheal.ts +87 -1
- package/src/session-runtime/index.ts +1 -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/steward/hold-hygiene.ts +24 -6
- package/src/steward/triage-budget.ts +194 -0
- package/src/steward/triage.ts +20 -3
- package/src/task-agent/actions.ts +69 -1
- package/src/task-agent/green-sweep.ts +4 -0
- package/src/task-agent/live-moves.ts +160 -4
- package/src/task-agent/parent-host.ts +123 -3
- package/src/task-agent/shadow.ts +7 -1
- package/src/task-agent/task-hand.ts +54 -41
- package/src/task-agent/tier-split.ts +127 -0
- package/src/task-agent/work-order-build.ts +2 -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 +33 -0
- package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-command-job.ts +45 -7
- 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-manifest-test-normalize.ts +8 -2
- package/src/task-orchestrator/surfaces/pod-provenance.ts +76 -0
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +18 -0
- package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +6 -2
- package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +3 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +37 -5
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +368 -36
- package/src/task-orchestrator/surfaces/self-implement.ts +23 -0
- package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
- 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/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.ts +4 -2
- 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/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/1162.c69abda138c7ce43.js +0 -79
- package/apps/pwa/out/_next/static/chunks/1449-1fede62af84c3e43.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1598-13fc845935e816df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1639.62c5e16fa20d242f.js +0 -94
- package/apps/pwa/out/_next/static/chunks/1661-adb8b2babc9aaf8c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2147.107c0fc6146fb15a.js +0 -23
- package/apps/pwa/out/_next/static/chunks/2202-ef1c9b000c3074fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2247.1e326638ee43e672.js +0 -115
- package/apps/pwa/out/_next/static/chunks/2268.56e1e3d58180abae.js +0 -8
- package/apps/pwa/out/_next/static/chunks/2469-606819c812414021.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2593.e53c1620c0bb3599.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2690.e96671114222676a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2898-79ee1a5cc0cd9d13.js +0 -1
- package/apps/pwa/out/_next/static/chunks/298.26099a9f65e5c8ff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2992.51fc2a7295bd8139.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3001-5a52788c813b6113.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3014-291245fba9df7b5b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3068.ee78201f0251a18d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3083.cd399a17e9365f78.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3103.84470c8445962f04.js +0 -34
- package/apps/pwa/out/_next/static/chunks/3117-e1c474683fd1f824.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3251-2c17bd5a91f8de2e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/326.3fb32322bb2ddf6d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3411-f87314c6c66ebc73.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3421-7ff7fbaa156985a7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3498.cf2a15a8a9e5b926.js +0 -226
- package/apps/pwa/out/_next/static/chunks/381.f55dc63ea87735e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3819.163d4777f0a597f6.js +0 -32
- package/apps/pwa/out/_next/static/chunks/3837.722e053fb9f321ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4129-ab0a6189f1778633.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4361.93d14ba594b3a035.js +0 -104
- package/apps/pwa/out/_next/static/chunks/4364.7a7eb19cceb67d2f.js +0 -286
- package/apps/pwa/out/_next/static/chunks/4406.d71f506f7c3ee9d3.js +0 -149
- package/apps/pwa/out/_next/static/chunks/4461.2ad1514180ae7e29.js +0 -148
- package/apps/pwa/out/_next/static/chunks/4479.bd309cbe0e3842ee.js +0 -64
- package/apps/pwa/out/_next/static/chunks/4522-05966f777d66d13b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4543-9a3e9812e845de65.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4557.f8f1d84a0d90d590.js +0 -74
- package/apps/pwa/out/_next/static/chunks/4589-79b11542179ef58c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4633-9f8f9f88ffbb8f5c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4831.23af4d10c0697b5e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4983.5951b85724f61f2a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5028-f0722e6114c313e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5249.96a848656b582a93.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5311.16e0ffbfa5468b80.js +0 -62
- package/apps/pwa/out/_next/static/chunks/5446.edf141cff9ef647d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5489.ec2dd1b5272a19dc.js +0 -24
- package/apps/pwa/out/_next/static/chunks/559.df87695df637920c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5618-5c88f2f70178c4ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5764.05487bf0b73ddb6b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5930.e678826c3f831aab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5dfb57f7.f2e3305326202474.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6200-cefd6f33f59d765e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6314-edeba650ae686ac9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6316-bc9a9b74d7842d79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6476-13b9779b73528008.js +0 -1
- package/apps/pwa/out/_next/static/chunks/666-04db3ac4c8e3c66f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/670.682e55106ef915a6.js +0 -77
- package/apps/pwa/out/_next/static/chunks/6816.b7ba9d0a1a4a46a7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/690-fbbcc777f189af37.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6989.0d3d4020e5cb3df6.js +0 -90
- package/apps/pwa/out/_next/static/chunks/7217-d17393fe7af78fa6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7232.24edbd938a69c8d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7295cd1e.b4b557908888eeee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7323.adb02de21991883c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7448.478958ffbbba0ac0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7537.ba2208c5c656b8a3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7562.948255cbc3e79d33.js +0 -41
- package/apps/pwa/out/_next/static/chunks/7596-962ae6db6cfc9c83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7671.cff51beac212a2ba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7883.3916734ee16d3e58.js +0 -27
- package/apps/pwa/out/_next/static/chunks/7952.b192c31b6a0e00cc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/801.5b24e81eded22d1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8176.8c9a8613f5a01ac1.js +0 -36
- package/apps/pwa/out/_next/static/chunks/819e78a6.fa3dd7f7da19bf61.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8220-78978450c3183d8d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8221-eb60b5bc692a3361.js +0 -1
- package/apps/pwa/out/_next/static/chunks/826.e9a26064f474949e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8459-a351487a4480f584.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8482-75823d513a4ce151.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8488.8da515248cda3f3a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8584.388a1779d9b203af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8637.a55e098e61ffefb8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8817.61bb7ffbba502ecb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9207-8e6a12db30373f32.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9263-00ae932c62696a86.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9318.caafc3a130e8769c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/932.da3fb55951882562.js +0 -93
- package/apps/pwa/out/_next/static/chunks/9433.002f8426ac75b6b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9464.dd631a5a14b1d660.js +0 -24
- package/apps/pwa/out/_next/static/chunks/9739.8d5f36ac67a3b236.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9743.beeabb9d5f86abe4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9843-a23d3f32dc43f715.js +0 -1
- package/apps/pwa/out/_next/static/chunks/994-28211077c7c587d5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-3b4c947f174e33d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-369d5ce99483f859.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-63c0ed0eb26e5fce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-62802c6003bc85cc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-ecb41560d4e77be9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-7b65ad8130c93e95.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-8755477c15a9060c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-5725447dd972c471.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-b979de0591a69375.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-6d0796bf4633751a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-59c31dc0394e67b4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-12dfc95f6cc5c718.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-25788244e66aa4dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-a2555dc705466322.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-4fb31eb476dcbad3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-3b4c947f174e33d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-578729adbeaa40cb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a1d20fffbec35205.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-4a558f94516b8004.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-9e3834705b86145e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-cb1c5fe746ea4014.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-9ee320507356582a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66fd183b74835886.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-3272a064a01a9927.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-f281b7a7f6ef2529.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-d45a65f8b7124fcd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-e9c1fe684dd19a66.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-b8322932fc6e34de.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-82c66d9af2290575.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-63c6752009c97b05.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-bb33d42ebc358aec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-7e4c9379197d7214.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-38bf1e9a7001732b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-2e5b752012389d56.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-398c0faa173203f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-002f53a965b6445c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7f75997f61a26269.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-3b4c947f174e33d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-05631753294f23fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-edd700fd2cc3d7f8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-105f83ecb4594365.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-5823e87d2017f19c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-b51ca09566c03de7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-8aacd5ded5dbac60.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-bae3365a0b3c6a8e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ed52b48ff1aa7fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-b6f8cad35fe00946.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-6d25ceda500d2457.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-b6401a5f2c962fe8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/ebf6cf5e.0d2f887b040e80fb.js +0 -122
- package/apps/pwa/out/_next/static/chunks/f09ec7d7-d29abe23edcbb193.js +0 -1
- package/apps/pwa/out/_next/static/chunks/ffdc3a04.b9c23c1b28dd4a96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-9322cb8a56ac081c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-2fbab294e49a1561.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-f36729f56621a8f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-2a62e450b47c6114.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-5e17f7b445f34d43.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-b4263e2190ea7adf.js +0 -1
- /package/apps/pwa/out/_next/static/{L04y73dlwKeTW-GetaTF3 → T1mBQqmkwKDLGtyisDCOd}/_ssgManifest.js +0 -0
|
@@ -33,6 +33,12 @@ import { getTheme } from '../../themes/index.js';
|
|
|
33
33
|
// same shape `pluginHost.loadThemeTokens` produces — not a full ThemeTokens.
|
|
34
34
|
export type PluginThemeLoader = (id: string) => ThemeTokenInput | null | undefined;
|
|
35
35
|
|
|
36
|
+
export interface PluginThemeAppliedEvent {
|
|
37
|
+
id: string;
|
|
38
|
+
tokensCount: number;
|
|
39
|
+
source: 'plugin';
|
|
40
|
+
}
|
|
41
|
+
|
|
36
42
|
export interface ResolveActiveThemeOptions {
|
|
37
43
|
/** Raw `dashboard.theme` value from user-config. Shape is flexible:
|
|
38
44
|
* `null` | `string` | `{ active: string, ... }` | `{ tokens: {...} }`. */
|
|
@@ -44,17 +50,19 @@ export interface ResolveActiveThemeOptions {
|
|
|
44
50
|
* (so a broken plugin doesn't crash the dashboard) but reported
|
|
45
51
|
* here for visibility. */
|
|
46
52
|
onPluginError?: (message: string) => void;
|
|
53
|
+
/** Called after plugin tokens have been merged into the resolved theme. */
|
|
54
|
+
onPluginApplied?: (event: PluginThemeAppliedEvent) => void;
|
|
47
55
|
}
|
|
48
56
|
|
|
49
57
|
/** Resolve the active dashboard theme from user-config, with preset
|
|
50
58
|
* + plugin + default fallback layers. Pure function — no I/O. */
|
|
51
59
|
export function resolveActiveTheme(opts: ResolveActiveThemeOptions): ThemeTokens {
|
|
52
|
-
const { raw, loadPlugin, onPluginError } = opts;
|
|
60
|
+
const { raw, loadPlugin, onPluginError, onPluginApplied } = opts;
|
|
53
61
|
|
|
54
62
|
// Extract active name + user overrides from the raw user-config
|
|
55
63
|
// value. The config shape evolved over time — handle all known
|
|
56
64
|
// forms defensively.
|
|
57
|
-
const activeName =
|
|
65
|
+
const activeName = getActiveThemeName(raw);
|
|
58
66
|
const rawOverrides: ThemeTokenInput | undefined = extractOverrides(raw);
|
|
59
67
|
|
|
60
68
|
// Branch 1: preset registry hit.
|
|
@@ -70,10 +78,20 @@ export function resolveActiveTheme(opts: ResolveActiveThemeOptions): ThemeTokens
|
|
|
70
78
|
try {
|
|
71
79
|
const contributed = loadPlugin(activeName);
|
|
72
80
|
if (contributed) {
|
|
73
|
-
|
|
81
|
+
const resolved = mergeThemeTokens(
|
|
74
82
|
mergeThemeTokens(DEFAULT_THEME_TOKENS, contributed),
|
|
75
83
|
rawOverrides ?? {},
|
|
76
84
|
);
|
|
85
|
+
try {
|
|
86
|
+
onPluginApplied?.({
|
|
87
|
+
id: activeName,
|
|
88
|
+
tokensCount: countTokenLeaves(contributed),
|
|
89
|
+
source: 'plugin',
|
|
90
|
+
});
|
|
91
|
+
} catch {
|
|
92
|
+
// Observation failures must not discard an already-resolved theme.
|
|
93
|
+
}
|
|
94
|
+
return resolved;
|
|
77
95
|
}
|
|
78
96
|
} catch (err: unknown) {
|
|
79
97
|
const message =
|
|
@@ -86,7 +104,18 @@ export function resolveActiveTheme(opts: ResolveActiveThemeOptions): ThemeTokens
|
|
|
86
104
|
return resolveThemeTokens(raw);
|
|
87
105
|
}
|
|
88
106
|
|
|
89
|
-
function
|
|
107
|
+
function countTokenLeaves(value: unknown, isRoot = true): number {
|
|
108
|
+
if (value === null || value === undefined) return 0;
|
|
109
|
+
if (typeof value !== 'object') return 1;
|
|
110
|
+
if (Array.isArray(value)) {
|
|
111
|
+
return value.reduce((count, item) => count + countTokenLeaves(item, false), 0);
|
|
112
|
+
}
|
|
113
|
+
return Object.entries(value as Record<string, unknown>)
|
|
114
|
+
.filter(([key]) => !isRoot || key !== 'name')
|
|
115
|
+
.reduce((count, [, item]) => count + countTokenLeaves(item, false), 0);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function getActiveThemeName(raw: unknown): string | null {
|
|
90
119
|
if (typeof raw === 'string') return raw.trim() || null;
|
|
91
120
|
if (raw && typeof raw === 'object' && !Array.isArray(raw)) {
|
|
92
121
|
const active = (raw as Record<string, unknown>).active;
|
|
@@ -381,9 +381,17 @@ export function readCrontab(): string {
|
|
|
381
381
|
export function inventoryCrontab(db: Database, opts: { crontab?: string; now?: string } = {}): { total: number; added: number; disabled: number; vanished: number } {
|
|
382
382
|
const text = opts.crontab ?? readCrontab();
|
|
383
383
|
const now = opts.now ?? new Date().toISOString();
|
|
384
|
-
const
|
|
384
|
+
const nowMs = Date.parse(now);
|
|
385
|
+
const existing = new Map((db.prepare(`SELECT id, name, command, source, run_via, cron, category, enabled, disabled_reason, last_seen, raw FROM schedule_registry`).all() as Array<{
|
|
385
386
|
id: string; name: string; command: string | null; source: string; run_via: string;
|
|
387
|
+
cron: string | null; category: string; enabled: number;
|
|
388
|
+
disabled_reason: string | null; last_seen: string | null; raw: string | null;
|
|
386
389
|
}>).map(r => [r.id, r]));
|
|
390
|
+
const lastSeenDue = (lastSeen: string | null): boolean => {
|
|
391
|
+
if (!lastSeen) return true;
|
|
392
|
+
const lastSeenMs = Date.parse(lastSeen);
|
|
393
|
+
return !Number.isFinite(lastSeenMs) || !Number.isFinite(nowMs) || nowMs - lastSeenMs >= 10 * 60_000;
|
|
394
|
+
};
|
|
387
395
|
let total = 0, added = 0, disabled = 0, vanished = 0;
|
|
388
396
|
const seenIds = new Set<string>();
|
|
389
397
|
for (const line of text.split('\n')) {
|
|
@@ -398,8 +406,10 @@ export function inventoryCrontab(db: Database, opts: { crontab?: string; now?: s
|
|
|
398
406
|
const off = parseDisabledCronLine(line);
|
|
399
407
|
if (!off) continue;
|
|
400
408
|
const offId = cronEntryId(off.cron, unwrapCronCommand(off.command));
|
|
401
|
-
|
|
409
|
+
const prior = existing.get(offId);
|
|
410
|
+
if (prior?.source !== 'crontab' || prior.run_via === 'trigger') continue;
|
|
402
411
|
seenIds.add(offId);
|
|
412
|
+
if (prior.enabled === 0 && prior.disabled_reason === 'manual' && !lastSeenDue(prior.last_seen)) continue;
|
|
403
413
|
db.run(`UPDATE schedule_registry SET enabled = 0, disabled_reason = 'manual', last_seen = ? WHERE id = ?`, [now, offId]);
|
|
404
414
|
disabled++;
|
|
405
415
|
continue;
|
|
@@ -417,6 +427,10 @@ export function inventoryCrontab(db: Database, opts: { crontab?: string; now?: s
|
|
|
417
427
|
// trigger's state (including an explicit disable). Keep the migrated row intact.
|
|
418
428
|
if (prior?.run_via === 'trigger') continue;
|
|
419
429
|
if (!prior) added++;
|
|
430
|
+
const unchanged = prior?.source === 'crontab' && prior.name === name && prior.cron === parsed.cron
|
|
431
|
+
&& prior.command === parsed.command && prior.category === category
|
|
432
|
+
&& prior.enabled === 1 && prior.disabled_reason == null && prior.raw === line.trim();
|
|
433
|
+
if (unchanged && !lastSeenDue(prior.last_seen)) continue;
|
|
420
434
|
db.run(
|
|
421
435
|
`INSERT INTO schedule_registry (id, name, source, cron, command, category, domain, enabled, last_seen, managed_by, raw)
|
|
422
436
|
VALUES (?, ?, 'crontab', ?, ?, ?, 'finance', 1, ?, 'manual', ?)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { debug } from '../debug/log.js';
|
|
2
|
+
|
|
3
|
+
/** Keep git status responsive while active, then back off after two idle minutes. */
|
|
4
|
+
export function dashboardIdleMs(now: number, lastInputAt: number, streaming: boolean): number {
|
|
5
|
+
// A model turn is active work even when it produces no terminal input.
|
|
6
|
+
// Do not age the dashboard into idle cadence until that stream finishes.
|
|
7
|
+
return streaming ? 0 : Math.max(0, now - lastInputAt);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function gitDirtyRefreshIntervalMs(idleMs: number): number {
|
|
11
|
+
return idleMs >= 2 * 60_000 ? 60_000 : 5_000;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// CLASSIC-IDLE-GIT-POLL (대표 10-21 «classic 백그라운드가 너무 무겁다») — a classic TUI left alone for five
|
|
15
|
+
// minutes spawned 63 git children (dirty probe ⊕ snapshot keep-warm). After this many idle ms the poller
|
|
16
|
+
// stops spawning git; the next input (or any activity that resets the idle clock) warms once and resumes.
|
|
17
|
+
export const GIT_POLL_IDLE_PAUSE_MS = 2 * 60_000;
|
|
18
|
+
|
|
19
|
+
export interface IdleGitPollState { active: boolean; reason: string }
|
|
20
|
+
|
|
21
|
+
export interface IdleGitPollDeps {
|
|
22
|
+
/** Idle ms right now (`dashboardIdleMs` — a running stream counts as active). */
|
|
23
|
+
idleMs: () => number;
|
|
24
|
+
/** One regular pass while active: dirty probe ⊕ snapshot keep-warm. */
|
|
25
|
+
poll: (idleMs: number) => void;
|
|
26
|
+
/** The one warm when polling resumes after a pause. */
|
|
27
|
+
warm: () => void;
|
|
28
|
+
/** Run the warm off the input path (default: a 0ms timer — after the key has been handled and painted). */
|
|
29
|
+
defer?: (fn: () => void) => void;
|
|
30
|
+
/** Transition record (default: `debug.log('git-fs.idle', 'poll-state', …)`). */
|
|
31
|
+
log?: (state: IdleGitPollState) => void;
|
|
32
|
+
pauseAfterMs?: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface IdleGitPoll {
|
|
36
|
+
/** The periodic timer body: pauses once idle, resumes (with one warm) when activity is back. */
|
|
37
|
+
tick(): void;
|
|
38
|
+
/** Called on the input path. Costs one boolean check while active; when paused it only schedules the warm. */
|
|
39
|
+
noteActivity(reason?: string): void;
|
|
40
|
+
isActive(): boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function createIdleGitPoll(deps: IdleGitPollDeps): IdleGitPoll {
|
|
44
|
+
const pauseAfterMs = deps.pauseAfterMs ?? GIT_POLL_IDLE_PAUSE_MS;
|
|
45
|
+
const log = deps.log ?? ((state: IdleGitPollState) => debug.log('git-fs.idle', 'poll-state', state));
|
|
46
|
+
const defer = deps.defer ?? ((fn: () => void) => {
|
|
47
|
+
const timer = setTimeout(fn, 0);
|
|
48
|
+
(timer as unknown as { unref?: () => void }).unref?.();
|
|
49
|
+
});
|
|
50
|
+
let active = true;
|
|
51
|
+
const setActive = (next: boolean, reason: string): boolean => {
|
|
52
|
+
if (active === next) return false;
|
|
53
|
+
active = next;
|
|
54
|
+
try { log({ active, reason }); } catch { /* observation must not break polling */ }
|
|
55
|
+
return true;
|
|
56
|
+
};
|
|
57
|
+
const warm = (): void => { try { deps.warm(); } catch { /* fail-soft */ } };
|
|
58
|
+
return {
|
|
59
|
+
tick() {
|
|
60
|
+
const idleMs = deps.idleMs();
|
|
61
|
+
if (idleMs >= pauseAfterMs) {
|
|
62
|
+
setActive(false, 'idle');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// Activity that did not come through `noteActivity` (a stream, an edit) — resume here.
|
|
66
|
+
if (setActive(true, 'activity')) warm();
|
|
67
|
+
deps.poll(idleMs);
|
|
68
|
+
},
|
|
69
|
+
noteActivity(reason = 'input') {
|
|
70
|
+
if (active) return;
|
|
71
|
+
setActive(true, reason);
|
|
72
|
+
defer(warm);
|
|
73
|
+
},
|
|
74
|
+
isActive: () => active,
|
|
75
|
+
};
|
|
76
|
+
}
|
package/src/git-fs/index.ts
CHANGED
|
@@ -94,6 +94,8 @@ interface CacheEntry {
|
|
|
94
94
|
dirty: DirtyCount | null;
|
|
95
95
|
aheadBehind: AheadBehind | null;
|
|
96
96
|
lastDirtyProbeAt: number;
|
|
97
|
+
/** Prevent an older asynchronous probe from replacing a synchronous refresh. */
|
|
98
|
+
dirtyVersion: number;
|
|
97
99
|
watcher: GitFileWatcher;
|
|
98
100
|
listeners: Set<() => void>;
|
|
99
101
|
}
|
|
@@ -139,6 +141,7 @@ function ensureEntry(cwd: string): CacheEntry | null {
|
|
|
139
141
|
dirty: null,
|
|
140
142
|
aheadBehind: null,
|
|
141
143
|
lastDirtyProbeAt: 0,
|
|
144
|
+
dirtyVersion: 0,
|
|
142
145
|
watcher,
|
|
143
146
|
listeners: new Set(),
|
|
144
147
|
};
|
|
@@ -212,6 +215,8 @@ export function refreshDirty(
|
|
|
212
215
|
lastDirtyProbeAt: entry.lastDirtyProbeAt,
|
|
213
216
|
};
|
|
214
217
|
}
|
|
218
|
+
// A synchronous save wins over any asynchronous probe that began before it.
|
|
219
|
+
entry.dirtyVersion += 1;
|
|
215
220
|
entry.dirty = probeDirty(entry.located.root);
|
|
216
221
|
entry.aheadBehind = probeAheadBehind(entry.located.root);
|
|
217
222
|
entry.lastDirtyProbeAt = Date.now();
|
|
@@ -268,13 +273,19 @@ function probeDirtyAsyncFor(entry: CacheEntry, opts: { fresh: boolean }): Promis
|
|
|
268
273
|
const running = dirtyInFlight.get(entry);
|
|
269
274
|
if (running && !opts.fresh) return running;
|
|
270
275
|
const root = entry.located.root;
|
|
271
|
-
const start = (): Promise<GitStatusView> =>
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
276
|
+
const start = (): Promise<GitStatusView> => {
|
|
277
|
+
const version = entry.dirtyVersion;
|
|
278
|
+
return Promise.all([probeDirtyAsync(root), probeAheadBehindAsync(root)])
|
|
279
|
+
.then(([dirty, aheadBehind]) => {
|
|
280
|
+
if (entry.dirtyVersion === version) {
|
|
281
|
+
entry.dirtyVersion += 1;
|
|
282
|
+
entry.dirty = dirty;
|
|
283
|
+
entry.aheadBehind = aheadBehind;
|
|
284
|
+
entry.lastDirtyProbeAt = Date.now();
|
|
285
|
+
}
|
|
286
|
+
return viewOf(entry);
|
|
287
|
+
});
|
|
288
|
+
};
|
|
278
289
|
const probe = (running ? running.then(start, start) : start())
|
|
279
290
|
.finally(() => { if (dirtyInFlight.get(entry) === probe) dirtyInFlight.delete(entry); });
|
|
280
291
|
dirtyInFlight.set(entry, probe);
|
package/src/git-fs/worktree.ts
CHANGED
|
@@ -24,15 +24,51 @@ const GIT_TIMEOUT_MS = 30_000;
|
|
|
24
24
|
* ⛔ 깊이 없이 얕은 저장소로 다른 브랜치를 fetch 하면 그 브랜치의 «전 이력»을 받는다(실측 193s vs 4s · 30s 에 SIGTERM). */
|
|
25
25
|
const SHALLOW_BASE_FETCH_DEPTH = 50;
|
|
26
26
|
const WORKTREE_ADD_TIMEOUT_MS = 5 * 60_000;
|
|
27
|
+
const WORKTREE_ADD_TIMEOUT_PER_TRACKED_FILE_MS = 600_000 / 25_000;
|
|
28
|
+
const WORKTREE_ADD_TIMEOUT_MAX_MS = 15 * 60_000;
|
|
29
|
+
const TRACKED_FILE_COUNT_MAX_BUFFER = 16 * 1024 * 1024;
|
|
27
30
|
|
|
28
31
|
export interface WorktreeAddDeps {
|
|
29
32
|
spawn?: (command: string, args: string[], options: { cwd: string; encoding: 'utf8'; timeout: number; maxBuffer: number }) => SpawnSyncReturns<string>;
|
|
33
|
+
countTrackedFiles?: (repoRoot: string, ref?: string) => number | null;
|
|
30
34
|
}
|
|
31
35
|
|
|
32
|
-
function
|
|
36
|
+
function countTrackedFiles(repoRoot: string, ref?: string): number | null {
|
|
37
|
+
const args = ref ? ['ls-tree', '-r', '-z', '--name-only', ref] : ['ls-files', '-z'];
|
|
38
|
+
const result = spawnSync('git', args, {
|
|
39
|
+
cwd: repoRoot,
|
|
40
|
+
encoding: 'utf8',
|
|
41
|
+
timeout: GIT_TIMEOUT_MS,
|
|
42
|
+
maxBuffer: TRACKED_FILE_COUNT_MAX_BUFFER,
|
|
43
|
+
});
|
|
44
|
+
if (result.status !== 0 || result.error) return null;
|
|
45
|
+
const output = result.stdout ?? '';
|
|
46
|
+
if (output.length === 0) return 0;
|
|
47
|
+
let count = 0;
|
|
48
|
+
for (const character of output) if (character === '\0') count++;
|
|
49
|
+
return count;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
type WorktreeAddTimeout = { ms: number; trackedFileCount: number | null; source: 'config' | 'tracked-files' | 'fallback' };
|
|
53
|
+
|
|
54
|
+
function worktreeAddTimeoutForTrackedFileCount(trackedFileCount: number | null): WorktreeAddTimeout {
|
|
55
|
+
if (trackedFileCount === null || !Number.isSafeInteger(trackedFileCount) || trackedFileCount < 0) {
|
|
56
|
+
return { ms: WORKTREE_ADD_TIMEOUT_MS, trackedFileCount: null, source: 'fallback' };
|
|
57
|
+
}
|
|
58
|
+
const scaledMs = Math.ceil(trackedFileCount * WORKTREE_ADD_TIMEOUT_PER_TRACKED_FILE_MS);
|
|
59
|
+
return { ms: Math.min(WORKTREE_ADD_TIMEOUT_MAX_MS, Math.max(WORKTREE_ADD_TIMEOUT_MS, scaledMs)), trackedFileCount, source: 'tracked-files' };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function worktreeAddTimeoutForRepo(
|
|
63
|
+
repoRoot: string,
|
|
64
|
+
countTrackedFilesForRepo: (repoRoot: string, ref?: string) => number | null = countTrackedFiles,
|
|
65
|
+
trackedFileRef?: string,
|
|
66
|
+
): WorktreeAddTimeout {
|
|
33
67
|
const seconds = getUserConfig().harness?.worktreeAddTimeoutSec;
|
|
34
|
-
|
|
35
|
-
|
|
68
|
+
if (typeof seconds === 'number' && Number.isSafeInteger(seconds) && seconds > 0 && seconds <= 2_147_483) {
|
|
69
|
+
return { ms: seconds * 1000, trackedFileCount: null, source: 'config' };
|
|
70
|
+
}
|
|
71
|
+
return worktreeAddTimeoutForTrackedFileCount(countTrackedFilesForRepo(repoRoot, trackedFileRef));
|
|
36
72
|
}
|
|
37
73
|
|
|
38
74
|
function worktreeAddFailureLines(stderr: string): { lastProgress: string | null; details: string[] } {
|
|
@@ -729,7 +765,9 @@ export function createWorktree(opts: CreateWorktreeOpts, deps: WorktreeAddDeps =
|
|
|
729
765
|
// ★ 병렬 안전 재시도(2026-07-21) — 동시 worktree add 가 git 락에서 경쟁하면 즉시 실패 → 락/일시적
|
|
730
766
|
// 에러면 백오프 재시도(패자가 승자의 락 해제를 기다렸다 성공). non-transient 는 재시도 없이 throw.
|
|
731
767
|
const MAX_ATTEMPTS = 6;
|
|
732
|
-
const
|
|
768
|
+
const addTimeout = worktreeAddTimeoutForRepo(repoRoot, deps.countTrackedFiles ?? countTrackedFiles, baseCheckout);
|
|
769
|
+
const addTimeoutMs = addTimeout.ms;
|
|
770
|
+
debug.log('git-fs.worktree', 'add.start', { branch, timeoutMs: addTimeoutMs, trackedFileCount: addTimeout.trackedFileCount, timeoutSource: addTimeout.source });
|
|
733
771
|
const addSpawn = deps.spawn ?? spawnSync;
|
|
734
772
|
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
|
|
735
773
|
const res = addSpawn(
|
|
@@ -20,13 +20,13 @@ export interface NodeKindEntry {
|
|
|
20
20
|
run?: NodeKindRun;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export const HARNESS_CORE_KINDS = ['agent', 'gate', 'git', 'judge', 'observe', 'hitl', 'subgraph', 'prompt'] as const;
|
|
23
|
+
export const HARNESS_CORE_KINDS = ['agent', 'gate', 'git', 'judge', 'observe', 'hitl', 'subgraph', 'prompt', 'classify'] as const;
|
|
24
24
|
|
|
25
25
|
// Workflow validation, the palette, and executor variant labels read the same keys.
|
|
26
26
|
export const WORKFLOW_CORE_KINDS = ['prompt', 'bash', 'skill', 'cft', 'approval', 'if', 'switch', 'iteration', 'classify', 'extract', 'set', 'filter', 'template', 'http', 'showroom', 'task', 'scheduleTrigger', 'webhookTrigger', 'discordTrigger', 'telegramTrigger', 'manualTrigger', 'chatTrigger', 'subworkflow', 'knowledge'] as const;
|
|
27
27
|
|
|
28
28
|
const descriptions: Record<GraphKind, readonly string[]> = {
|
|
29
|
-
harness: ['Run an agent', 'Check an execution gate', 'Perform git operations', 'Judge an outcome', 'Observe a result', 'Request human input', 'Run a child graph', 'Run an LLM prompt'],
|
|
29
|
+
harness: ['Run an agent', 'Check an execution gate', 'Perform git operations', 'Judge an outcome', 'Observe a result', 'Request human input', 'Run a child graph', 'Run an LLM prompt', 'Classify input'],
|
|
30
30
|
workflow: ['Run an LLM prompt', 'Run a shell command', 'Invoke a skill', 'Invoke a CFT method', 'Request approval', 'Branch on a condition', 'Select a case', 'Iterate items', 'Classify input', 'Extract structured data', 'Assign variables', 'Filter items', 'Render a template', 'Make an HTTP request', 'Run a showroom', 'Create a task', 'Start on a schedule', 'Start on a webhook', 'Start on Discord', 'Start on Telegram', 'Start manually', 'Start on chat', 'Call another workflow', 'Search the vault for context'],
|
|
31
31
|
};
|
|
32
32
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createHash, randomUUID } from 'node:crypto';
|
|
2
2
|
import { execFile, spawnSync } from 'node:child_process';
|
|
3
|
-
import { existsSync, linkSync, lstatSync, mkdirSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmdirSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { existsSync, linkSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmdirSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { dirname, join, resolve, sep } from 'node:path';
|
|
5
|
+
import { tmpdir } from 'node:os';
|
|
5
6
|
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
|
|
6
7
|
import { getElanousConfigDir, getElanousConfigDirOverride } from '../elanous-config-dir.js';
|
|
7
8
|
import { debug } from '../debug/log.js';
|
|
@@ -23,8 +24,9 @@ export { UnitNotFoundError } from '../self-implement/graph-unit-resolver.js';
|
|
|
23
24
|
import { createGraphVariant, type GraphVariantPlan } from '../self-implement/graph-variant.js';
|
|
24
25
|
import { psProcessStartMs, START_TOLERANCE_MS } from '../harness/harness-stop.js';
|
|
25
26
|
import { executeBashNode } from '../workflow-runtime/nodes/bash.js';
|
|
27
|
+
import { executeClassifyNode } from '../workflow-runtime/nodes/classify.js';
|
|
26
28
|
import { interpolate } from '../workflow-runtime/variables.js';
|
|
27
|
-
import type { BashNode, NodeExecContext, WorkflowDeps } from '../workflow-runtime/types.js';
|
|
29
|
+
import type { BashNode, ClassifyNode, NodeExecContext, NodeOutput, WorkflowDeps } from '../workflow-runtime/types.js';
|
|
28
30
|
import { releaseResumeAcceptedRegressions, releaseResumeGateExecutor, releaseResumeGatePodPool, releaseResumeWaiver, type AcceptedRegression, type GateExecutorOverride, type GatePodPoolOverride } from '../../scripts/release-loop/resume.js';
|
|
29
31
|
|
|
30
32
|
type BashRun = WorkflowDeps['runBash'];
|
|
@@ -83,6 +85,47 @@ function topLevelTerminalStatus(graphId: string, terminal: string): 'done' | 'fa
|
|
|
83
85
|
return terminal === 'done' || terminal === 'failed' ? terminal : undefined;
|
|
84
86
|
}
|
|
85
87
|
|
|
88
|
+
/** HARNESS-FULL-GRAPH-LOOPS — the four goal loops are self-implement harness templates: their recipes are
|
|
89
|
+
* catalog roles (no `recipes.yaml` sidecar) and some edges branch on `changed-files`. `graph run` can only
|
|
90
|
+
* *plan* them: `--dry-run` walks the declared success route; a real run is refused (the harness owns effects). */
|
|
91
|
+
const HARNESS_LOOP_GRAPH_IDS: ReadonlySet<string> = new Set(['default-loop', 'document-loop', 'operate-loop', 'research-loop']);
|
|
92
|
+
|
|
93
|
+
type PlannedStep = { outcome?: string; to: string };
|
|
94
|
+
|
|
95
|
+
/** Shortest declared route (map/to edges only — fallbacks are not a success branch) to a terminal that maps to `done`.
|
|
96
|
+
* Ties keep the first declared outcome, so the plan follows the YAML's own order. A unit call only takes its first
|
|
97
|
+
* declared exit (the same stand-in a plain dry run uses) — its `rework` exit is a shortcut, not the success path. */
|
|
98
|
+
function planHarnessLoopRoute(graph: GraphTemplateSpec, unitSuccessExit: (nodeId: string) => string | undefined): Map<string, PlannedStep> {
|
|
99
|
+
const candidates = new Map<string, PlannedStep[]>();
|
|
100
|
+
for (const node of graph.nodes) {
|
|
101
|
+
const edge = graph.edges.find((e) => e.from === node.nodeId);
|
|
102
|
+
if (!edge) continue;
|
|
103
|
+
const exit = unitSuccessExit(node.nodeId);
|
|
104
|
+
candidates.set(node.nodeId, edge.to !== undefined ? [{ to: edge.to }]
|
|
105
|
+
: Object.entries(edge.map ?? {}).filter(([outcome]) => exit === undefined || outcome === exit).map(([outcome, to]) => ({ outcome, to })));
|
|
106
|
+
}
|
|
107
|
+
const distance = new Map<string, number>();
|
|
108
|
+
for (const terminal of graph.terminalNodes) if (topLevelTerminalStatus(graph.graphId, terminal) === 'done') distance.set(terminal, 0);
|
|
109
|
+
const route = new Map<string, PlannedStep>();
|
|
110
|
+
for (let changed = true; changed;) {
|
|
111
|
+
changed = false;
|
|
112
|
+
for (const [nodeId, steps] of candidates) {
|
|
113
|
+
if (graph.terminalNodes.includes(nodeId)) continue;
|
|
114
|
+
let best: { step: PlannedStep; d: number } | undefined;
|
|
115
|
+
for (const step of steps) {
|
|
116
|
+
const d = distance.get(step.to);
|
|
117
|
+
if (d !== undefined && (!best || d + 1 < best.d)) best = { step, d: d + 1 };
|
|
118
|
+
}
|
|
119
|
+
if (best && (distance.get(nodeId) ?? Infinity) > best.d) {
|
|
120
|
+
distance.set(nodeId, best.d);
|
|
121
|
+
route.set(nodeId, best.step);
|
|
122
|
+
changed = true;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return route;
|
|
127
|
+
}
|
|
128
|
+
|
|
86
129
|
export interface GraphRunState {
|
|
87
130
|
graphId: string;
|
|
88
131
|
runId: string;
|
|
@@ -125,6 +168,46 @@ export interface GraphRunState {
|
|
|
125
168
|
statePath: string;
|
|
126
169
|
}
|
|
127
170
|
|
|
171
|
+
export interface GraphClassifyInput {
|
|
172
|
+
arguments: string;
|
|
173
|
+
classify: ClassifyNode['classify'];
|
|
174
|
+
/** Production consumer that asked for the verdict, so one ledger shape separates callers. */
|
|
175
|
+
caller?: string;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Run the workflow classifier as a persisted harness graph node. The workflow verdict is unchanged. */
|
|
179
|
+
export async function runGraphClassifyNode(node: ClassifyNode, ctx: NodeExecContext, callLLM: WorkflowDeps['callLLM'],
|
|
180
|
+
meta: { caller?: string } = {}): Promise<NodeOutput> {
|
|
181
|
+
const dir = mkdtempSync(join(tmpdir(), 'elanous-graph-classify-'));
|
|
182
|
+
try {
|
|
183
|
+
const path = join(dir, 'graph.yaml');
|
|
184
|
+
writeFileSync(join(dir, 'recipes.yaml'), '{}\n');
|
|
185
|
+
writeFileSync(path, stringifyYaml({
|
|
186
|
+
graph_id: 'self-implement-classify', version: 1, entry_node: 'classify', terminal_nodes: ['done', 'failed'],
|
|
187
|
+
nodes: [
|
|
188
|
+
{ node_id: 'classify', kind: 'classify', recipe: 'none', max_visits: 1 },
|
|
189
|
+
{ node_id: 'done', kind: 'gate', recipe: 'none', max_visits: 1 },
|
|
190
|
+
{ node_id: 'failed', kind: 'gate', recipe: 'none', max_visits: 1 },
|
|
191
|
+
],
|
|
192
|
+
edges: [{ from: 'classify', on: 'outcome', map: { ok: 'done', fail: 'failed' } }],
|
|
193
|
+
}));
|
|
194
|
+
const run = await runGraph(path, { input: { arguments: ctx.arguments, classify: node.classify,
|
|
195
|
+
...(meta.caller === undefined ? {} : { caller: meta.caller }) } satisfies GraphClassifyInput,
|
|
196
|
+
quiet: true,
|
|
197
|
+
deps: { callLLM: async (prompt) => callLLM({ prompt, ...(ctx.resolvedModel === undefined ? {} : { model: ctx.resolvedModel }),
|
|
198
|
+
...(ctx.resolvedProvider === undefined ? {} : { provider: ctx.resolvedProvider }),
|
|
199
|
+
...(ctx.signal === undefined ? {} : { signal: ctx.signal }) }) } });
|
|
200
|
+
const recorded = lastJsonObject(run.nodes[0]?.output);
|
|
201
|
+
if (!recorded || typeof recorded.durationMs !== 'number' || typeof recorded.ok !== 'boolean' || !('output' in recorded)) {
|
|
202
|
+
throw new Error(`classify graph did not record a result: ${run.statePath}`);
|
|
203
|
+
}
|
|
204
|
+
return { ok: recorded.ok, output: recorded.output, durationMs: recorded.durationMs,
|
|
205
|
+
...(typeof recorded.error === 'string' ? { error: recorded.error } : {}) };
|
|
206
|
+
} finally {
|
|
207
|
+
rmSync(dir, { recursive: true, force: true });
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
128
211
|
export interface GraphRunOptions {
|
|
129
212
|
input?: unknown;
|
|
130
213
|
/** Bytes already checked by the tick gate, used for a current-graph start or legacy resume. */
|
|
@@ -135,6 +218,8 @@ export interface GraphRunOptions {
|
|
|
135
218
|
resumeRunId?: string;
|
|
136
219
|
resumeGraphId?: string;
|
|
137
220
|
fromNodeId?: string;
|
|
221
|
+
/** Embedded runs (a classify verdict inside self-implement) keep the per-node `[graph]` stderr lines off the caller's terminal; debug.log still records every node. */
|
|
222
|
+
quiet?: boolean;
|
|
138
223
|
/** Release-only: accept the recorded failed node without executing it, and expose its regression to known-issues. */
|
|
139
224
|
releaseWaiver?: { nodeId: string; reason: string; requestedRegressions: AcceptedRegression[]; acceptedRegressions: AcceptedRegression[]; unmeasured?: string };
|
|
140
225
|
/** Release-only: add accepted issues independently of a waiver at a restart boundary. */
|
|
@@ -614,7 +699,15 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
614
699
|
throw new Error(`unsupported terminal node: ${terminal} (expected ${graph.unit ? graph.unit.exits.join(' or ') : 'done or failed'})`);
|
|
615
700
|
}
|
|
616
701
|
}
|
|
617
|
-
const
|
|
702
|
+
const recipePath = graphMode === 'snapshot' ? join(snapshotDir!, 'recipes.yaml') : join(dirname(path), 'recipes.yaml');
|
|
703
|
+
// A harness loop template without a command sidecar is planned, never executed, by this runner.
|
|
704
|
+
const harnessLoopTemplate = !graph.unit && HARNESS_LOOP_GRAPH_IDS.has(graph.graphId) && graphMode === 'current' && !existsSync(recipePath);
|
|
705
|
+
if (harnessLoopTemplate && (options.dryRun !== true || options.resumeRunId)) {
|
|
706
|
+
debug.log('graph.run', 'harness-loop-refused', { graphId: graph.graphId, path: resolve(path), why: 'real-run' });
|
|
707
|
+
throw new Error(`harness loop template ${graph.graphId} runs through the self-implement harness — graph run only plans it with --dry-run`);
|
|
708
|
+
}
|
|
709
|
+
const harnessLoopRoute = harnessLoopTemplate ? planHarnessLoopRoute(graph, (nodeId) => units.get(nodeId)?.template.unit?.exits[0]) : undefined;
|
|
710
|
+
const recipeSource = harnessLoopTemplate ? '{}\n' : readFileSync(recipePath, 'utf8');
|
|
618
711
|
if (graphMode === 'snapshot' && saved?.graphSnapshot &&
|
|
619
712
|
(createHash('sha256').update(source).digest('hex') !== saved.graphSnapshot.graphSha ||
|
|
620
713
|
createHash('sha256').update(recipeSource).digest('hex') !== saved.graphSnapshot.recipesSha)) {
|
|
@@ -626,10 +719,20 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
626
719
|
const approvalSourceHash = createHash('sha256').update(variantSource).update('\0').update(recipeSource).digest('hex');
|
|
627
720
|
// Resolve all commands before executing any node; an unknown recipe must never produce a partial publication.
|
|
628
721
|
for (const node of graph.nodes) {
|
|
722
|
+
if (node.kind === 'classify' && node.recipe !== 'none') throw new Error(`classify node cannot execute a recipe: ${node.nodeId}`);
|
|
629
723
|
if (node.recipe === 'none') continue;
|
|
630
724
|
const resolved = resolveNodeRecipe(node, recipes, catalogRoles);
|
|
725
|
+
// Harness loop recipes are labels the self-implement harness dispatches by node id (most are outside the
|
|
726
|
+
// node catalog — graph-catalog.test.ts); a planned loop never executes them, and a real run is refused above.
|
|
727
|
+
if (harnessLoopRoute) continue;
|
|
631
728
|
if (!resolved.command && !resolved.prompt && !resolved.approval) throw new Error(`unknown command recipe for ${node.nodeId}: ${node.recipe}`);
|
|
632
729
|
}
|
|
730
|
+
if (harnessLoopRoute) {
|
|
731
|
+
if (!harnessLoopRoute.has(graph.entryNode)) throw new Error(`harness loop ${graph.graphId} has no declared route from ${graph.entryNode} to a success terminal`);
|
|
732
|
+
const planned: string[] = [graph.entryNode];
|
|
733
|
+
for (let at = harnessLoopRoute.get(graph.entryNode); at; at = harnessLoopRoute.get(at.to)) planned.push(at.to);
|
|
734
|
+
debug.log('graph.run', 'harness-loop-plan', { graphId: graph.graphId, path: resolve(path), route: planned });
|
|
735
|
+
}
|
|
633
736
|
const graphId = safeSegment(graph.graphId);
|
|
634
737
|
const isReleaseLoop = graphId === 'release-loop';
|
|
635
738
|
// A copied or saved release graph is still a release graph. Its path cannot grant or revoke
|
|
@@ -951,7 +1054,7 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
951
1054
|
const startedAt = performance.now();
|
|
952
1055
|
const nodeStartedAt = new Date().toISOString();
|
|
953
1056
|
if (!resumingCompleted) state.currentNode = { nodeId: current, startedAt: nodeStartedAt };
|
|
954
|
-
console.error(`[graph] ${current} start (0.00s)`);
|
|
1057
|
+
if (!options.quiet) console.error(`[graph] ${current} start (0.00s)`);
|
|
955
1058
|
debug.log('graph.run', 'node', { graphId, runId, nodeId: current, phase: 'start', dryRun: state.dryRun });
|
|
956
1059
|
publishInsideEvent({ kind: 'node', graphId, runId, nodeId: current, phase: 'start' });
|
|
957
1060
|
log('node-start', { graphId, runId, nodeId: current, visit: visits.get(current), dryRun: state.dryRun });
|
|
@@ -1030,7 +1133,12 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1030
1133
|
state.executed++;
|
|
1031
1134
|
}
|
|
1032
1135
|
let unitExecuted = false;
|
|
1033
|
-
|
|
1136
|
+
const plannedStep: PlannedStep | undefined = harnessLoopRoute?.get(current);
|
|
1137
|
+
if (harnessLoopRoute && !graph.terminalNodes.includes(current)) {
|
|
1138
|
+
if (!plannedStep) throw new Error(`harness loop ${graphId} has no declared success route from ${current}`);
|
|
1139
|
+
// The planned outcome stands in for the harness node (or unit) that a real loop run would execute.
|
|
1140
|
+
output = JSON.stringify({ outcome: plannedStep.outcome ?? 'ok', dryRun: true, plannedNext: plannedStep.to });
|
|
1141
|
+
} else if (units.has(current) && !waiving && state.dryRun && !resumingCompleted) {
|
|
1034
1142
|
// Dry run plans the walk only: no child run, no unit event, no unitCalls entry; the first declared exit stands in.
|
|
1035
1143
|
output = JSON.stringify({ outcome: units.get(current)!.template.unit!.exits[0], dryRun: true });
|
|
1036
1144
|
} else if (units.has(current) && !waiving && !resumingCompleted) {
|
|
@@ -1132,6 +1240,39 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1132
1240
|
}
|
|
1133
1241
|
state.executed++;
|
|
1134
1242
|
}
|
|
1243
|
+
if (node.kind === 'classify' && !waiving && !state.dryRun && !resumingCompleted) {
|
|
1244
|
+
const input = state.input as GraphClassifyInput | undefined;
|
|
1245
|
+
const classify = input?.classify;
|
|
1246
|
+
if (!input || typeof input.arguments !== 'string' || !classify || typeof classify.input !== 'string' ||
|
|
1247
|
+
!Array.isArray(classify.classes) || !classify.classes.length || !classify.classes.every(c => typeof c === 'string' && c.length > 0) ||
|
|
1248
|
+
(classify.retries !== undefined && (!Number.isSafeInteger(classify.retries) || classify.retries < 0)) ||
|
|
1249
|
+
(classify.retryDelayMs !== undefined && (!Number.isSafeInteger(classify.retryDelayMs) || classify.retryDelayMs < 0))) {
|
|
1250
|
+
throw new Error('classify node requires input.arguments and a valid input.classify');
|
|
1251
|
+
}
|
|
1252
|
+
try {
|
|
1253
|
+
const result = await executeClassifyNode({ id: current, classify }, {
|
|
1254
|
+
arguments: input.arguments, artifactsDir: dirname(statePath), outputs: {},
|
|
1255
|
+
resolvedProvider: undefined, resolvedModel: undefined, toolPolicy: {},
|
|
1256
|
+
}, { callLLM: async ({ prompt }) => {
|
|
1257
|
+
if (!options.deps?.callLLM) throw new Error('classify node requires an injected LLM (deps.callLLM)');
|
|
1258
|
+
return options.deps.callLLM(prompt);
|
|
1259
|
+
}, runBash: async () => ({ stdout: '', stderr: '', exitCode: 0 }) });
|
|
1260
|
+
output = JSON.stringify({ input: input.arguments, ok: result.ok, verdict: result.output, output: result.output,
|
|
1261
|
+
durationMs: result.durationMs, ...(result.error ? { error: result.error } : {}) });
|
|
1262
|
+
ok = result.ok;
|
|
1263
|
+
error = result.error;
|
|
1264
|
+
} catch (cause) {
|
|
1265
|
+
ok = false;
|
|
1266
|
+
error = cause instanceof Error ? cause.message : String(cause);
|
|
1267
|
+
output = JSON.stringify({ input: input.arguments, ok, verdict: 'unknown', output: 'unknown', durationMs: 0, error });
|
|
1268
|
+
}
|
|
1269
|
+
const recorded = lastJsonObject(output);
|
|
1270
|
+
debug.log('graph.classify', 'node-result', { graphId, runId, nodeId: current, caller: input.caller ?? null,
|
|
1271
|
+
input: input.arguments, inputChars: input.arguments.length, classes: classify.classes,
|
|
1272
|
+
verdict: recorded?.verdict ?? 'unknown', output: recorded?.output ?? 'unknown', ok,
|
|
1273
|
+
...(error ? { error } : {}) });
|
|
1274
|
+
state.executed++;
|
|
1275
|
+
}
|
|
1135
1276
|
const seconds = Number(((performance.now() - startedAt) / 1000).toFixed(2));
|
|
1136
1277
|
// A wall clock stepped back mid-node must not record an end before the start.
|
|
1137
1278
|
const nodeEndedAt = new Date(Math.max(Date.now(), Date.parse(nodeStartedAt))).toISOString();
|
|
@@ -1152,7 +1293,7 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1152
1293
|
output = JSON.stringify({ outcome: ok ? 'approved' : 'rejected', graphId, runId, nodeId: current,
|
|
1153
1294
|
...(state.pending?.decidedBy === undefined ? {} : { decidedBy: state.pending.decidedBy }), decidedAt: state.pending?.decidedAt ?? null });
|
|
1154
1295
|
}
|
|
1155
|
-
state.nodes.push({ nodeId: current, ok, exit, executed: !waiving && ((!!command && (!state.dryRun || !!command.dry_run_command)) || (!!prompt && !state.dryRun) || unitExecuted), ...((waiving || units.has(current) || ((command || prompt || approval) && (!state.dryRun || !!command?.dry_run_command))) && output !== undefined ? { output } : {}), ...(error ? { error } : {}),
|
|
1296
|
+
state.nodes.push({ nodeId: current, ok, exit, executed: !waiving && ((!!command && (!state.dryRun || !!command.dry_run_command)) || (!!prompt && !state.dryRun) || (node.kind === 'classify' && !state.dryRun) || unitExecuted), ...((waiving || harnessLoopRoute || units.has(current) || ((command || prompt || approval || node.kind === 'classify') && (!state.dryRun || !!command?.dry_run_command))) && output !== undefined ? { output } : {}), ...(error ? { error } : {}),
|
|
1156
1297
|
...(waiving ? { waiver: { reason: options.releaseWaiver!.reason, at: nodeEndedAt, ...(options.releaseWaiver!.unmeasured === undefined ? {} : { unmeasured: options.releaseWaiver!.unmeasured }), original: { exit: waivedRecord!.exit, ...(waivedRecord!.output === undefined ? {} : { output: waivedRecord!.output }), ...(waivedRecord!.error === undefined ? {} : { error: waivedRecord!.error }) } } } : {}),
|
|
1157
1298
|
...(approval && state.pending ? { ...(state.pending.decidedBy === undefined ? {} : { decidedBy: state.pending.decidedBy }), decidedAt: state.pending.decidedAt } : {}),
|
|
1158
1299
|
startedAt: nodeStartedAt, endedAt: nodeEndedAt, seconds });
|
|
@@ -1165,9 +1306,9 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1165
1306
|
delete state.pending;
|
|
1166
1307
|
delete state.approvalSourceHash;
|
|
1167
1308
|
}
|
|
1168
|
-
const reported = waiving || units.has(current) || (prompt && !state.dryRun) || (command && (!state.dryRun || command.dry_run_command)) ? lastJsonObject(resumingCompleted ? completed?.output : output)?.outcome : undefined;
|
|
1169
|
-
const namedOutcome = typeof reported === 'string' ? reported : undefined;
|
|
1170
|
-
console.error(`[graph] ${current} ${ok ? 'ok' : 'fail'} (${seconds.toFixed(2)}s)`);
|
|
1309
|
+
const reported: unknown = waiving || harnessLoopRoute || units.has(current) || (prompt && !state.dryRun) || (command && (!state.dryRun || command.dry_run_command)) ? lastJsonObject(resumingCompleted ? completed?.output : output)?.outcome : undefined;
|
|
1310
|
+
const namedOutcome: string | undefined = typeof reported === 'string' ? reported : undefined;
|
|
1311
|
+
if (!options.quiet) console.error(`[graph] ${current} ${ok ? 'ok' : 'fail'} (${seconds.toFixed(2)}s)`);
|
|
1171
1312
|
debug.log('graph.run', 'node', { graphId, runId, nodeId: current, phase: ok ? 'ok' : 'fail', seconds, exit });
|
|
1172
1313
|
publishInsideEvent({ kind: 'node', graphId, runId, nodeId: current, phase: ok ? 'ok' : 'fail', seconds });
|
|
1173
1314
|
publishInsideEvent({ kind: 'verdict', graphId, runId, nodeId: current, verdict: ok ? 'ok' : 'fail', ...(namedOutcome === undefined ? {} : { outcome: namedOutcome }) });
|
|
@@ -1225,7 +1366,9 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1225
1366
|
}
|
|
1226
1367
|
persist();
|
|
1227
1368
|
}
|
|
1228
|
-
|
|
1369
|
+
// A planned harness loop follows its route directly: `changed-files` edges have no runner condition.
|
|
1370
|
+
current = plannedStep ? plannedStep.to
|
|
1371
|
+
: nextNode(graph.edges, current, state.dryRun && !command?.dry_run_command ? 'ok' : ok ? 'ok' : 'fail', namedOutcome);
|
|
1229
1372
|
resumedGrowth = false;
|
|
1230
1373
|
if (current !== undefined) publishInsideEvent({ kind: 'edge', graphId, runId, from: fromNodeId, to: current });
|
|
1231
1374
|
if (current === undefined) {
|
package/src/grok/credential.ts
CHANGED
|
@@ -87,6 +87,8 @@ export interface GrokCredential {
|
|
|
87
87
|
baseUrl: string;
|
|
88
88
|
/** Bearer 값. ⛔ 로그·관측에 실지 마라. */
|
|
89
89
|
token: string;
|
|
90
|
+
/** Expiry for the selected subscription scope; absent for API-key credentials. */
|
|
91
|
+
expiresAt?: string | null;
|
|
90
92
|
/** 이 자격에 «반드시» 붙어야 하는 헤더(Authorization 제외). */
|
|
91
93
|
headers: Record<string, string>;
|
|
92
94
|
/** 관측용 — 값이 아니라 «출처»만. */
|
|
@@ -120,8 +122,10 @@ function readSubscriptionToken(
|
|
|
120
122
|
}
|
|
121
123
|
if (!parsed || typeof parsed !== 'object') return null;
|
|
122
124
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
type SubscriptionToken = { token: string; expiresAt: string | null; userId: string | null; ms: number };
|
|
126
|
+
let best: SubscriptionToken | null = null;
|
|
127
|
+
let hqMirror: SubscriptionToken | null = null;
|
|
128
|
+
for (const [scopeName, scope] of Object.entries(parsed as Record<string, unknown>)) {
|
|
125
129
|
if (!scope || typeof scope !== 'object') continue;
|
|
126
130
|
const s = scope as GrokAuthScope;
|
|
127
131
|
if (typeof s.key !== 'string' || s.key.length === 0) continue;
|
|
@@ -133,9 +137,11 @@ function readSubscriptionToken(
|
|
|
133
137
|
userId: typeof s.user_id === 'string' ? s.user_id : null,
|
|
134
138
|
ms: Number.isNaN(ms) ? Number.NEGATIVE_INFINITY : ms,
|
|
135
139
|
};
|
|
140
|
+
if (scopeName === 'https://auth.x.ai::hq-mirror') hqMirror = cand;
|
|
136
141
|
if (best === null || cand.ms > best.ms) best = cand;
|
|
137
142
|
}
|
|
138
|
-
|
|
143
|
+
const selected = hqMirror ?? best;
|
|
144
|
+
return selected ? { token: selected.token, expiresAt: selected.expiresAt, userId: selected.userId } : null;
|
|
139
145
|
}
|
|
140
146
|
|
|
141
147
|
/** 호스트 발급 문이 응답에 실을 access. user id 는 반환하지 않는다. */
|
|
@@ -302,6 +308,7 @@ function readGrokCredential(opts: {
|
|
|
302
308
|
kind: 'subscription',
|
|
303
309
|
baseUrl: GROK_SUBSCRIPTION_BASE_URL,
|
|
304
310
|
token: sub.token,
|
|
311
|
+
expiresAt: sub.expiresAt,
|
|
305
312
|
headers: grokSubscriptionHeaders({
|
|
306
313
|
...(opts.model ? { model: opts.model } : {}),
|
|
307
314
|
userId: sub.userId,
|