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
|
@@ -60,8 +60,8 @@ export const AGENT_TOOL_DEFAULT_MAX_TURNS = 20;
|
|
|
60
60
|
export const AGENT_TOOL_TURNS_CEILING = 50;
|
|
61
61
|
|
|
62
62
|
/** Numeric ceiling on concurrent `run_in_background` Agent-tool fan-out.
|
|
63
|
-
*
|
|
64
|
-
*
|
|
63
|
+
* Enforced at exactly one point in `dispatchAgent` (see the
|
|
64
|
+
* `background-fanout-limit` block: after dedup, before `noteSeen`). */
|
|
65
65
|
export const AGENT_TOOL_BACKGROUND_FANOUT_CEILING = 8;
|
|
66
66
|
|
|
67
67
|
/** Clamp a caller-supplied `max_turns` onto `[1, AGENT_TOOL_TURNS_CEILING]`.
|
|
@@ -82,7 +82,9 @@ export function stripAgentToolForOneLevelNesting<T extends { name: string }>(
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
/** Live `run_in_background` tasks occupy fan-out slots until they terminal.
|
|
85
|
-
*
|
|
85
|
+
* Counts a task list (e.g. `globalAgentRegistry.list()`). `dispatchAgent`
|
|
86
|
+
* enforces the per-session ceiling over its own reservation ledger
|
|
87
|
+
* (`backgroundFanoutSlots`) instead — see that field's doc. */
|
|
86
88
|
export function countLiveBackgroundFanout(
|
|
87
89
|
tasks: ReadonlyArray<{ background?: boolean; state?: string }>,
|
|
88
90
|
): number {
|
|
@@ -95,6 +97,35 @@ export function countLiveBackgroundFanout(
|
|
|
95
97
|
return n;
|
|
96
98
|
}
|
|
97
99
|
|
|
100
|
+
/** Fallback fan-out session key for dispatches that carry no
|
|
101
|
+
* `sessionCache` (agent-cli, one-off callers). All of their slots share
|
|
102
|
+
* one process-wide bucket so the ceiling still binds for them. */
|
|
103
|
+
const UNSCOPED_BACKGROUND_FANOUT_SESSION: object = Object.freeze({});
|
|
104
|
+
|
|
105
|
+
/** Fan-out slots by session (the dispatching session's `SessionCache`
|
|
106
|
+
* identity; WeakMap so a dropped session releases its key together with
|
|
107
|
+
* the cache instance). A slot is RESERVED in the same synchronous block
|
|
108
|
+
* as the ceiling check inside `dispatchAgent` — concurrent dispatches
|
|
109
|
+
* that interleave at the async definition-resolution awaits cannot all
|
|
110
|
+
* pass the check before any of them registers — and RELEASED when the
|
|
111
|
+
* registered task reaches a terminal state (done/error/aborted) via
|
|
112
|
+
* `globalAgentRegistry.onTaskDone`. A dispatch that throws before it
|
|
113
|
+
* registers releases its own reservation (see
|
|
114
|
+
* `releaseReservedFanoutSlot` inside `dispatchAgent`). */
|
|
115
|
+
const backgroundFanoutSlots = new WeakMap<object, number>();
|
|
116
|
+
|
|
117
|
+
/** Count this session's live fan-out slots (reserved or running). */
|
|
118
|
+
export function countSessionBackgroundFanout(session: object): number {
|
|
119
|
+
return backgroundFanoutSlots.get(session) ?? 0;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Release one of this session's fan-out slots (floors at zero). */
|
|
123
|
+
function releaseBackgroundFanoutSlot(session: object): void {
|
|
124
|
+
const live = backgroundFanoutSlots.get(session);
|
|
125
|
+
if (live === undefined || live <= 1) backgroundFanoutSlots.delete(session);
|
|
126
|
+
else backgroundFanoutSlots.set(session, live - 1);
|
|
127
|
+
}
|
|
128
|
+
|
|
98
129
|
/** Fallback agent when subagent_type is missing or unresolvable. The
|
|
99
130
|
* loader picks this up from src/agents/general-purpose.md — built
|
|
100
131
|
* inline below as a defensive default in case that file is removed. */
|
|
@@ -374,19 +405,22 @@ export async function dispatchAgent(
|
|
|
374
405
|
// burn another turn on the same work. Return a stub that points
|
|
375
406
|
// the parent back to its existing history. Parents stuck in a
|
|
376
407
|
// "keep re-spawning Data Collector" loop escape via this gate.
|
|
377
|
-
|
|
378
|
-
|
|
408
|
+
const sessionCache = opts.sessionCache;
|
|
409
|
+
const cacheKey = sessionCache
|
|
410
|
+
? agentCacheKey(requestedType, requestedType, prompt)
|
|
411
|
+
: undefined;
|
|
412
|
+
if (sessionCache && cacheKey) {
|
|
379
413
|
// Key strategy: description is noisy (parents sometimes vary the
|
|
380
414
|
// label between calls); we hash the FUNCTIONAL signature only
|
|
381
415
|
// — subagent_type + prompt. Same prompt to same agent = same
|
|
382
416
|
// expected work, regardless of how the call was labelled.
|
|
383
|
-
const hit =
|
|
417
|
+
const hit = sessionCache.check(cacheKey);
|
|
384
418
|
if (hit) {
|
|
385
419
|
const label = `Agent[${requestedType}] "${description.slice(0, 60)}"`;
|
|
386
420
|
logDedupHit('agent.dedup', label, hit, {
|
|
387
421
|
requestedType,
|
|
388
422
|
description: description.slice(0, 80),
|
|
389
|
-
consecutive:
|
|
423
|
+
consecutive: sessionCache.consecutiveHits,
|
|
390
424
|
});
|
|
391
425
|
|
|
392
426
|
// Runtime-level block: same treatment as Read. When the parent
|
|
@@ -395,16 +429,16 @@ export async function dispatchAgent(
|
|
|
395
429
|
// tool_result carries is_error=true. Soft stubs have been
|
|
396
430
|
// observed to produce 6+ retries in the wild; an error break
|
|
397
431
|
// the reflex loop more reliably.
|
|
398
|
-
if (
|
|
432
|
+
if (sessionCache.consecutiveHits >= CONSECUTIVE_DEDUP_BLOCK_THRESHOLD) {
|
|
399
433
|
debug.log('agent.dedup', 'consecutive-block', {
|
|
400
434
|
requestedType,
|
|
401
435
|
description: description.slice(0, 80),
|
|
402
|
-
consecutive:
|
|
436
|
+
consecutive: sessionCache.consecutiveHits,
|
|
403
437
|
threshold: CONSECUTIVE_DEDUP_BLOCK_THRESHOLD,
|
|
404
438
|
});
|
|
405
439
|
throw new Error(
|
|
406
440
|
`RUNTIME BLOCKED — Agent[${requestedType}] "${description.slice(0, 60)}" ` +
|
|
407
|
-
`has been spawned ${
|
|
441
|
+
`has been spawned ${sessionCache.consecutiveHits} times in a row with ` +
|
|
408
442
|
`no intervening progress. The previous sub-agent's final message is in ` +
|
|
409
443
|
`your conversation history above — use that. Spawn an Agent with a ` +
|
|
410
444
|
`DIFFERENT persona (different subagent_type or a substantively different ` +
|
|
@@ -420,9 +454,9 @@ export async function dispatchAgent(
|
|
|
420
454
|
// ~500 chars of history noise per hit. We now emit the debug
|
|
421
455
|
// event past threshold for traceability but return the normal
|
|
422
456
|
// "spawn a different persona" stub — same message every hit.
|
|
423
|
-
if (
|
|
457
|
+
if (sessionCache.totalHits >= DEDUP_CASCADE_HALT_THRESHOLD) {
|
|
424
458
|
debug.log('agent.dedup', 'cascade-threshold', {
|
|
425
|
-
totalHits:
|
|
459
|
+
totalHits: sessionCache.totalHits,
|
|
426
460
|
threshold: DEDUP_CASCADE_HALT_THRESHOLD,
|
|
427
461
|
requestedType,
|
|
428
462
|
description: description.slice(0, 80),
|
|
@@ -444,7 +478,79 @@ export async function dispatchAgent(
|
|
|
444
478
|
taskId: 'dedup',
|
|
445
479
|
};
|
|
446
480
|
}
|
|
447
|
-
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// ── TUI-AGENT-CAPS-FU: background fan-out ceiling ──
|
|
484
|
+
//
|
|
485
|
+
// The ONE enforcement point for AGENT_TOOL_BACKGROUND_FANOUT_CEILING, and
|
|
486
|
+
// it sits exactly between the dedup short-circuit above and `noteSeen`
|
|
487
|
+
// below on purpose:
|
|
488
|
+
// • after dedup — a repeat of an already-answered prompt still gets the
|
|
489
|
+
// dedup stub instead of a fan-out refusal (it never reaches here);
|
|
490
|
+
// • before `noteSeen` — a refused launch must NOT register its cache
|
|
491
|
+
// key. Otherwise the caller's retry (same prompt, once a slot opens)
|
|
492
|
+
// would be answered with "you already got this result" even though no
|
|
493
|
+
// child ever ran, permanently poisoning the cache with a spawn that
|
|
494
|
+
// never happened.
|
|
495
|
+
//
|
|
496
|
+
// Live slots are counted over the shared task ledger: `background` tasks
|
|
497
|
+
// that have not reached a terminal state (done / error / aborted). So a
|
|
498
|
+
// slot re-opens the moment any background agent finishes, which is what
|
|
499
|
+
// lets the next launch through again.
|
|
500
|
+
let fanoutSession: object | undefined;
|
|
501
|
+
if (runInBackground) {
|
|
502
|
+
// Per-session scope: slots count against THIS session's cache
|
|
503
|
+
// identity (shared fallback bucket for cache-less callers), so a
|
|
504
|
+
// busy OTHER session cannot starve this one's first launch.
|
|
505
|
+
fanoutSession = opts.sessionCache ?? UNSCOPED_BACKGROUND_FANOUT_SESSION;
|
|
506
|
+
const liveBackground = countSessionBackgroundFanout(fanoutSession);
|
|
507
|
+
if (liveBackground >= AGENT_TOOL_BACKGROUND_FANOUT_CEILING) {
|
|
508
|
+
debug.log('agent.spawn', 'background-fanout-limit', {
|
|
509
|
+
cid: debugCorrelationId,
|
|
510
|
+
requestedType,
|
|
511
|
+
description: description.slice(0, 80),
|
|
512
|
+
liveBackground,
|
|
513
|
+
ceiling: AGENT_TOOL_BACKGROUND_FANOUT_CEILING,
|
|
514
|
+
}, { level: 'warn' });
|
|
515
|
+
// Not spawned: no registry task, no provider call, no cache entry.
|
|
516
|
+
// taskId is a sentinel (like 'dedup' above) so a caller can tell a
|
|
517
|
+
// refusal from a real spawn without parsing the prose.
|
|
518
|
+
return {
|
|
519
|
+
output:
|
|
520
|
+
`NOT SPAWNED — ${liveBackground} background agents are already live and the ` +
|
|
521
|
+
`fan-out ceiling is ${AGENT_TOOL_BACKGROUND_FANOUT_CEILING}. A slot reopens as ` +
|
|
522
|
+
`soon as one of them reaches a terminal state (done/error/aborted); its result ` +
|
|
523
|
+
`then arrives as a task-notification. Either wait for one to finish, fold this ` +
|
|
524
|
+
`work into an existing background spawn, or re-issue it without ` +
|
|
525
|
+
`run_in_background so it runs in the foreground.`,
|
|
526
|
+
agent: requestedType,
|
|
527
|
+
cid: debugCorrelationId,
|
|
528
|
+
durationMs: 0,
|
|
529
|
+
maxTurns: requestedMaxTurns,
|
|
530
|
+
taskId: 'background-fanout-limit',
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
if (fanoutSession !== undefined) {
|
|
536
|
+
// Atomic reservation: taken in the SAME synchronous block as the
|
|
537
|
+
// ceiling check above, before any await — concurrent dispatches
|
|
538
|
+
// cannot all pass the check and push this session past the ceiling
|
|
539
|
+
// while their definitions resolve. Released when the registered
|
|
540
|
+
// task terminals (see the onTaskDone subscription at spawn); a
|
|
541
|
+
// dispatch that throws before registering releases it in the finally
|
|
542
|
+
// below, including failures from definition resolution and lazy imports.
|
|
543
|
+
backgroundFanoutSlots.set(fanoutSession, countSessionBackgroundFanout(fanoutSession) + 1);
|
|
544
|
+
}
|
|
545
|
+
const releaseReservedFanoutSlot = (): void => {
|
|
546
|
+
if (fanoutSession === undefined) return;
|
|
547
|
+
releaseBackgroundFanoutSlot(fanoutSession);
|
|
548
|
+
fanoutSession = undefined;
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
try {
|
|
552
|
+
if (sessionCache && cacheKey) {
|
|
553
|
+
sessionCache.noteSeen(cacheKey, `Agent[${requestedType}] ${description.slice(0, 60)}`);
|
|
448
554
|
}
|
|
449
555
|
|
|
450
556
|
// Resolve the agent definition. Try the 4-layer resolver first;
|
|
@@ -536,7 +642,9 @@ export async function dispatchAgent(
|
|
|
536
642
|
});
|
|
537
643
|
} catch (error) {
|
|
538
644
|
const message = error instanceof Error ? error.message : String(error);
|
|
539
|
-
if (!message.includes('is not inside a git repo'))
|
|
645
|
+
if (!message.includes('is not inside a git repo')) {
|
|
646
|
+
throw error;
|
|
647
|
+
}
|
|
540
648
|
childCwd = opts.cwd ?? getSessionCwd();
|
|
541
649
|
appliedIsolation = 'cwd';
|
|
542
650
|
debug.log('agent.spawn', 'worktree-fallback-cwd', {
|
|
@@ -679,6 +787,19 @@ export async function dispatchAgent(
|
|
|
679
787
|
...(runInBackground ? { background: true } : {}),
|
|
680
788
|
});
|
|
681
789
|
|
|
790
|
+
// Terminal release for this dispatch's reserved fan-out slot: the
|
|
791
|
+
// registry fires this exactly once per task when it reaches a
|
|
792
|
+
// terminal state (done/error/aborted); until then the slot counts as
|
|
793
|
+
// occupied against this session's ceiling above.
|
|
794
|
+
if (fanoutSession !== undefined) {
|
|
795
|
+
const fanoutSlotSession = fanoutSession;
|
|
796
|
+
const fanoutSlotSubscription = globalAgentRegistry.onTaskDone((task) => {
|
|
797
|
+
if (!task || task.id !== handle.task.id) return;
|
|
798
|
+
fanoutSlotSubscription.dispose();
|
|
799
|
+
releaseBackgroundFanoutSlot(fanoutSlotSession);
|
|
800
|
+
});
|
|
801
|
+
fanoutSession = undefined; // the terminal subscription owns the release now
|
|
802
|
+
}
|
|
682
803
|
// Forward parent abort to the spawned task. The registry owns the
|
|
683
804
|
// child's controller; we just chain ours into it.
|
|
684
805
|
if (opts.signal) {
|
|
@@ -907,4 +1028,9 @@ export async function dispatchAgent(
|
|
|
907
1028
|
...(childCwd ? { cwd: childCwd } : {}),
|
|
908
1029
|
...(appliedIsolation ? { isolation: appliedIsolation } : {}),
|
|
909
1030
|
};
|
|
1031
|
+
} finally {
|
|
1032
|
+
// The registered task owns its slot after the handoff above. Every
|
|
1033
|
+
// pre-registration throw leaves fanoutSession set and releases it here.
|
|
1034
|
+
releaseReservedFanoutSlot();
|
|
1035
|
+
}
|
|
910
1036
|
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { LLMToolSpec } from '../../llm.js';
|
|
2
|
+
import { openMsgStore, validateMessageEnvelope, type Message, type MsgStore } from '../../msg/msg-store.js';
|
|
3
|
+
|
|
4
|
+
export interface MsgAskDeps {
|
|
5
|
+
openStore?: () => MsgStore;
|
|
6
|
+
sleep?: (ms: number) => Promise<void>;
|
|
7
|
+
monotonicNow?: () => number;
|
|
8
|
+
wallNow?: () => number;
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface MsgAskResult extends Record<string, unknown> {
|
|
13
|
+
output: string;
|
|
14
|
+
ok: boolean;
|
|
15
|
+
question: Message;
|
|
16
|
+
reply: Message | null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function buildMsgAskTool(): LLMToolSpec {
|
|
20
|
+
return {
|
|
21
|
+
name: 'MsgAsk',
|
|
22
|
+
description: 'Post a durable seat question, then wait for the first message whose replyTo points to it. A timeout or cancellation keeps the posted question and returns its ID for later follow-up.',
|
|
23
|
+
parameters: {
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: {
|
|
26
|
+
from: { type: 'string', description: 'Asking seat (ALL cannot send).' },
|
|
27
|
+
to: { type: 'string', description: 'Recipient seat.' },
|
|
28
|
+
question: { type: 'string', description: 'Nonempty question body.' },
|
|
29
|
+
waitSeconds: { type: 'integer', description: 'Wait 0–300 seconds; default 60.' },
|
|
30
|
+
},
|
|
31
|
+
required: ['from', 'to', 'question'],
|
|
32
|
+
additionalProperties: false,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function dispatchMsgAsk(rawArgs: Record<string, unknown>, deps: MsgAskDeps = {}): Promise<MsgAskResult> {
|
|
38
|
+
const waitRaw = rawArgs.waitSeconds ?? 60;
|
|
39
|
+
if (typeof waitRaw !== 'number' || !Number.isSafeInteger(waitRaw) || waitRaw < 0 || waitRaw > 300) {
|
|
40
|
+
throw new Error("'waitSeconds' must be an integer between 0 and 300");
|
|
41
|
+
}
|
|
42
|
+
const envelope = validateMessageEnvelope({
|
|
43
|
+
from: rawArgs.from,
|
|
44
|
+
to: rawArgs.to,
|
|
45
|
+
body: rawArgs.question,
|
|
46
|
+
});
|
|
47
|
+
if (envelope.to === 'ALL') throw new Error("'to' must name one recipient seat for MsgAsk");
|
|
48
|
+
const monotonicNow = deps.monotonicNow ?? (() => performance.now());
|
|
49
|
+
const wallNow = deps.wallNow ?? Date.now;
|
|
50
|
+
const sleep = deps.sleep ?? ((ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)));
|
|
51
|
+
const store = deps.openStore?.() ?? openMsgStore();
|
|
52
|
+
try {
|
|
53
|
+
if (deps.signal?.aborted) throw new Error('ask cancelled before posting');
|
|
54
|
+
const question = store.post(envelope);
|
|
55
|
+
const startedAt = monotonicNow();
|
|
56
|
+
const wallStartedAt = wallNow();
|
|
57
|
+
const deadline = startedAt + waitRaw * 1000;
|
|
58
|
+
const wallDeadline = Date.parse(question.createdAt) + waitRaw * 1000;
|
|
59
|
+
// Ledger timestamps are wall time while the wait budget is monotonic.
|
|
60
|
+
// If the two clocks diverge materially, preserve the question ID and
|
|
61
|
+
// make the uncertain result explicit instead of accepting a late reply.
|
|
62
|
+
const clockAdjusted = () => Math.abs((wallNow() - wallStartedAt) - (monotonicNow() - startedAt)) > 250;
|
|
63
|
+
let afterId = 0;
|
|
64
|
+
do {
|
|
65
|
+
if (deps.signal?.aborted) {
|
|
66
|
+
return { output: `MsgAsk #${question.id} posted; wait cancelled`, ok: false, question, reply: null };
|
|
67
|
+
}
|
|
68
|
+
if (clockAdjusted()) {
|
|
69
|
+
return { output: `MsgAsk #${question.id} posted; clock adjusted during wait, inspect linked replies`, ok: false, question, reply: null };
|
|
70
|
+
}
|
|
71
|
+
const replies = store.listReplies(question.id, 1000, afterId);
|
|
72
|
+
if (clockAdjusted()) {
|
|
73
|
+
return { output: `MsgAsk #${question.id} posted; clock adjusted during wait, inspect linked replies`, ok: false, question, reply: null };
|
|
74
|
+
}
|
|
75
|
+
for (const reply of replies) {
|
|
76
|
+
afterId = reply.id;
|
|
77
|
+
// A replyTo link alone does not prove the intended seat answered.
|
|
78
|
+
// A wall-clock timestamp can move backwards by less than the clock
|
|
79
|
+
// adjustment guard. Never accept a reply once monotonic time expired.
|
|
80
|
+
// This conservatively leaves replies observed late for follow-up.
|
|
81
|
+
if (reply.from === question.to && reply.to === question.from
|
|
82
|
+
&& monotonicNow() <= deadline && Date.parse(reply.createdAt) <= wallDeadline) {
|
|
83
|
+
return { output: `MsgAsk #${question.id} → reply #${reply.id}: ${reply.body}`, ok: true, question, reply };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const remaining = deadline - monotonicNow();
|
|
87
|
+
if (deps.signal?.aborted) {
|
|
88
|
+
return { output: `MsgAsk #${question.id} posted; wait cancelled`, ok: false, question, reply: null };
|
|
89
|
+
}
|
|
90
|
+
if (remaining <= 0) {
|
|
91
|
+
return { output: `MsgAsk #${question.id} posted; no linked reply within ${waitRaw}s`, ok: false, question, reply: null };
|
|
92
|
+
}
|
|
93
|
+
// A full page may repeat forever. Yield so timers and AbortSignal
|
|
94
|
+
// callbacks can run before asking SQLite for the next page.
|
|
95
|
+
await sleep(replies.length === 1000 ? 0 : Math.min(100, remaining));
|
|
96
|
+
} while (true);
|
|
97
|
+
} finally {
|
|
98
|
+
store.close();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// OP TUI turns previously drove `elanous msg list/post/ack` and
|
|
4
4
|
// `elanous release checklist list/move/set/add` through RunShell:
|
|
5
5
|
// 1.3–2s of CLI startup per call, 30+ spawns per turn, and the CLI's
|
|
6
|
-
// human-oriented stdout amplifying TUI screen defects. These
|
|
6
|
+
// human-oriented stdout amplifying TUI screen defects. These
|
|
7
7
|
// tools reuse the SAME durable services in-process —
|
|
8
8
|
//
|
|
9
9
|
// • msg tools → src/msg/msg-store.ts (the SQLite ledger `elanous msg`
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
// • checklist tools → src/release-loop/checklist.ts + feature-store.ts
|
|
12
12
|
// (the same per-version ledger, claim history, seat/OP move rules)
|
|
13
13
|
//
|
|
14
|
+
// MsgAsk joins this family through msg-ask.ts; the other dispatchers live here.
|
|
14
15
|
// The permission and audit contract is preserved 1:1:
|
|
15
16
|
// • writes record the actor from ELANOUS_TRACK (seat identity),
|
|
16
17
|
// • ChecklistMove keeps the CLI routing — anonymous (no ELANOUS_TRACK)
|
|
@@ -41,6 +41,17 @@ export const WAKEUP_MAX_CALLS_PER_TURN = 6;
|
|
|
41
41
|
export const WAKEUP_REPEAT_INVALID_ERROR =
|
|
42
42
|
'repeatMinutes 는 반복 간격(분 · 1 이상)이다 — 한 번만 깨우려면 repeatMinutes 를 빼거나 0 으로 두고 delaySeconds 또는 at 만 줘라';
|
|
43
43
|
|
|
44
|
+
function formatWakeupTimeConflictError(req: ScheduleWakeupRequest): string {
|
|
45
|
+
const corrected = { ...req };
|
|
46
|
+
delete corrected.at;
|
|
47
|
+
delete corrected.atProvided;
|
|
48
|
+
return `at 과 delaySeconds 는 둘 중 하나만 줄 수 있다 — 교정 인자 예시(at 을 빼고 delaySeconds 사용): ${JSON.stringify(corrected)}. 같은 인자를 다시 보내지 말고 이 교정 인자로 한 번만 재시도하라`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function canonicalToolArgs(args: Record<string, unknown>): string {
|
|
52
|
+
return JSON.stringify(Object.fromEntries(Object.entries(args).sort(([a], [b]) => a.localeCompare(b))));
|
|
53
|
+
}
|
|
54
|
+
|
|
44
55
|
export type WakeupTimerHandle = unknown;
|
|
45
56
|
|
|
46
57
|
export interface WakeupEntry {
|
|
@@ -79,7 +90,9 @@ export interface WakeupSchedulerDeps {
|
|
|
79
90
|
|
|
80
91
|
export type ScheduleWakeupRequest = {
|
|
81
92
|
/** «HH:MM»(로컬 시각 · 지났으면 내일). delaySeconds 와 둘 중 하나. */
|
|
82
|
-
at?:
|
|
93
|
+
at?: unknown;
|
|
94
|
+
/** Host tool must preserve property presence even when the provider sent a non-string value. */
|
|
95
|
+
atProvided?: boolean;
|
|
83
96
|
delaySeconds?: number;
|
|
84
97
|
reason: string;
|
|
85
98
|
/** 반복 간격(분). 첫 발화는 at/delaySeconds — 둘 다 없으면 지금부터 repeatMinutes 뒤. 0 = 일회성(생략과 같다). */
|
|
@@ -93,7 +106,7 @@ export type ScheduleWakeupResult =
|
|
|
93
106
|
export type CancelWakeupResult = { ok: true } | { ok: false; error: string; capped?: boolean };
|
|
94
107
|
|
|
95
108
|
export interface WakeupScheduler {
|
|
96
|
-
schedule(req: ScheduleWakeupRequest): ScheduleWakeupResult;
|
|
109
|
+
schedule(req: ScheduleWakeupRequest, requestKey?: string): ScheduleWakeupResult;
|
|
97
110
|
list(): WakeupEntry[];
|
|
98
111
|
cancel(id: string): boolean;
|
|
99
112
|
/** cancel 과 같되 거부 사유(없는 id · 턴 상한)를 값으로 낸다 — LLM 도구가 쓴다. */
|
|
@@ -151,12 +164,24 @@ export function createWakeupScheduler(deps: WakeupSchedulerDeps): WakeupSchedule
|
|
|
151
164
|
const maxCallsPerTurn = deps.maxCallsPerTurn ?? WAKEUP_MAX_CALLS_PER_TURN;
|
|
152
165
|
let callTurnKey: string | null = null;
|
|
153
166
|
let callCount = 0;
|
|
167
|
+
const conflictErrors = new Map<string, string>();
|
|
168
|
+
|
|
169
|
+
const readTurnId = (): string | null => deps.currentTurnId?.() ?? null;
|
|
154
170
|
|
|
155
|
-
/** 한 턴 호출 상한 — 넘었으면 거부 문구, 아니면 null. 턴
|
|
156
|
-
const loopCapError = (action: 'schedule' | 'cancel'): string | null => {
|
|
157
|
-
if (
|
|
158
|
-
|
|
159
|
-
|
|
171
|
+
/** 한 턴 호출 상한 — 넘었으면 거부 문구, 아니면 null. 턴 경계가 unknown 이면 cap·dedupe 상태를 버린다. */
|
|
172
|
+
const loopCapError = (action: 'schedule' | 'cancel', observedTurnId = readTurnId()): string | null => {
|
|
173
|
+
if (observedTurnId === null) {
|
|
174
|
+
callTurnKey = null;
|
|
175
|
+
callCount = 0;
|
|
176
|
+
conflictErrors.clear();
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
const turnId = observedTurnId;
|
|
180
|
+
if (turnId !== callTurnKey) {
|
|
181
|
+
callTurnKey = turnId;
|
|
182
|
+
callCount = 0;
|
|
183
|
+
conflictErrors.clear();
|
|
184
|
+
}
|
|
160
185
|
callCount += 1;
|
|
161
186
|
if (callCount <= maxCallsPerTurn) return null;
|
|
162
187
|
log('tui.wakeup', 'loop-capped', { turnId, count: callCount, max: maxCallsPerTurn, action });
|
|
@@ -252,20 +277,35 @@ export function createWakeupScheduler(deps: WakeupSchedulerDeps): WakeupSchedule
|
|
|
252
277
|
};
|
|
253
278
|
|
|
254
279
|
return {
|
|
255
|
-
schedule(req) {
|
|
280
|
+
schedule(req, requestKey) {
|
|
256
281
|
const t = now();
|
|
257
282
|
const reason = (req.reason ?? '').replace(/\s+/g, ' ').trim();
|
|
258
283
|
const reject = (error: string): ScheduleWakeupResult => {
|
|
259
284
|
log('tui.wakeup', 'rejected', { id: null, reason: 'invalid', error });
|
|
260
285
|
return { ok: false, error };
|
|
261
286
|
};
|
|
262
|
-
|
|
287
|
+
// Every schedule attempt consumes the per-turn budget before validation.
|
|
288
|
+
const turnId = readTurnId();
|
|
289
|
+
const capped = loopCapError('schedule', turnId);
|
|
263
290
|
if (capped) return { ok: false, error: capped };
|
|
291
|
+
// Presence is the contract: invalidly typed `at` values from the host
|
|
292
|
+
// must still conflict with delaySeconds rather than silently disappear.
|
|
293
|
+
const hasAt = req.atProvided ?? req.at !== undefined;
|
|
294
|
+
const hasDelay = req.delaySeconds !== undefined;
|
|
295
|
+
if (hasAt && hasDelay) {
|
|
296
|
+
const key = requestKey ?? canonicalToolArgs(req as Record<string, unknown>);
|
|
297
|
+
if (turnId !== null) {
|
|
298
|
+
const previousError = conflictErrors.get(key);
|
|
299
|
+
if (previousError !== undefined) {
|
|
300
|
+
return { ok: false, error: `${previousError} — 같은 충돌 인자의 재시도는 억제했다` };
|
|
301
|
+
}
|
|
302
|
+
if (conflictErrors.size < maxCallsPerTurn) conflictErrors.set(key, formatWakeupTimeConflictError(req));
|
|
303
|
+
}
|
|
304
|
+
const error = formatWakeupTimeConflictError(req);
|
|
305
|
+
return reject(error);
|
|
306
|
+
}
|
|
264
307
|
if (!reason) return reject('reason 이 비었다 — 깨어나서 무엇을 할지 한 줄로 적어라');
|
|
265
308
|
if (entries.size >= maxEntries) return reject(`예약 상한 ${maxEntries}개 — list 로 보고 cancel 뒤 다시`);
|
|
266
|
-
const hasAt = typeof req.at === 'string' && req.at.trim() !== '';
|
|
267
|
-
const hasDelay = typeof req.delaySeconds === 'number';
|
|
268
|
-
if (hasAt && hasDelay) return reject('at 과 delaySeconds 는 둘 중 하나만');
|
|
269
309
|
let repeatMs: number | undefined;
|
|
270
310
|
// ⭐ 0 = 일회성(생략과 같다) — 모델이 «한 번만»을 0 으로 부른다(라이브 실측). 음수·NaN·1 미만 소수는 거부.
|
|
271
311
|
if (req.repeatMinutes !== undefined && req.repeatMinutes !== 0) {
|
|
@@ -276,7 +316,8 @@ export function createWakeupScheduler(deps: WakeupSchedulerDeps): WakeupSchedule
|
|
|
276
316
|
}
|
|
277
317
|
let dueAt: number;
|
|
278
318
|
if (hasAt) {
|
|
279
|
-
|
|
319
|
+
if (typeof req.at !== 'string') return reject(`at 은 «HH:MM» 문자열이어야 한다 — 받은 값 ${JSON.stringify(req.at)}`);
|
|
320
|
+
const resolved = resolveWakeupAt(req.at, t);
|
|
280
321
|
if (resolved === null) return reject(`at 은 «HH:MM»(24시간) 꼴 — 받은 값 ${JSON.stringify(req.at)}`);
|
|
281
322
|
dueAt = resolved;
|
|
282
323
|
} else if (hasDelay) {
|
|
@@ -342,7 +383,7 @@ export function buildScheduleWakeupHostTool(scheduler: WakeupScheduler): LLMTool
|
|
|
342
383
|
name: SCHEDULE_WAKEUP_TOOL_NAME,
|
|
343
384
|
description:
|
|
344
385
|
'Wake THIS TUI later with an internal turn: when you would write «다음 점검 HH:MM» and end the turn, call this instead so the check actually happens. '
|
|
345
|
-
+ 'action=schedule (default) needs reason plus one of at ("HH:MM" local, past → tomorrow) / delaySeconds (≥60) / repeatMinutes (≥1; repeats expire after 7 days). '
|
|
386
|
+
+ 'action=schedule (default) needs reason plus one of at ("HH:MM" local, past → tomorrow) / delaySeconds (≥60) / repeatMinutes (≥1; repeats expire after 7 days). Never provide both at and delaySeconds; the schema requires one timing variant. '
|
|
346
387
|
+ 'ONE-SHOT (wake once): give only delaySeconds or at and OMIT repeatMinutes (0 also means one-shot). Set repeatMinutes only when you really want it to repeat. '
|
|
347
388
|
+ `action=list shows pending wakeups; action=cancel needs id. Limits: ≥60s ahead, ≤7 days, at most 5 pending, at most ${WAKEUP_MAX_CALLS_PER_TURN} schedule/cancel calls per turn. `
|
|
348
389
|
+ 'If the TUI is busy or the human is typing at that time it retries once a minute later, then gives up (repeats move to the next tick). '
|
|
@@ -358,6 +399,11 @@ export function buildScheduleWakeupHostTool(scheduler: WakeupScheduler): LLMTool
|
|
|
358
399
|
id: { type: 'string', description: 'Wakeup id for action=cancel (from schedule/list).' },
|
|
359
400
|
},
|
|
360
401
|
required: [],
|
|
402
|
+
oneOf: [
|
|
403
|
+
{ not: { anyOf: [{ required: ['at'] }, { required: ['delaySeconds'] }] } },
|
|
404
|
+
{ required: ['at'], not: { required: ['delaySeconds'] } },
|
|
405
|
+
{ required: ['delaySeconds'], not: { required: ['at'] } },
|
|
406
|
+
],
|
|
361
407
|
},
|
|
362
408
|
handler: async (args) => {
|
|
363
409
|
const action = typeof args.action === 'string' ? args.action : 'schedule';
|
|
@@ -368,12 +414,15 @@ export function buildScheduleWakeupHostTool(scheduler: WakeupScheduler): LLMTool
|
|
|
368
414
|
return r.ok ? { cancelled: id } : { error: r.error };
|
|
369
415
|
}
|
|
370
416
|
if (action !== 'schedule') return { error: `unknown action ${JSON.stringify(action)}` };
|
|
371
|
-
const
|
|
417
|
+
const atProvided = Object.prototype.hasOwnProperty.call(args, 'at');
|
|
418
|
+
const request: ScheduleWakeupRequest = {
|
|
372
419
|
reason: typeof args.reason === 'string' ? args.reason : '',
|
|
373
|
-
|
|
420
|
+
atProvided,
|
|
421
|
+
...(atProvided ? { at: args.at } : {}),
|
|
374
422
|
...(typeof args.delaySeconds === 'number' ? { delaySeconds: args.delaySeconds } : {}),
|
|
375
423
|
...(typeof args.repeatMinutes === 'number' ? { repeatMinutes: args.repeatMinutes } : {}),
|
|
376
|
-
}
|
|
424
|
+
};
|
|
425
|
+
const result = scheduler.schedule(request, canonicalToolArgs(args));
|
|
377
426
|
return result.ok ? { scheduled: describeEntry(result.entry) } : { error: result.error };
|
|
378
427
|
},
|
|
379
428
|
};
|
|
@@ -5,7 +5,7 @@ import { opSeatStatePath, readTrafficSignal } from '../seat-loop/traffic-signal.
|
|
|
5
5
|
|
|
6
6
|
const SEATS = ['OP', 'MK', 'TC', 'UX'] as const;
|
|
7
7
|
type Seat = typeof SEATS[number];
|
|
8
|
-
export type HygieneCell = { id: string; owner?: string | null; status: string };
|
|
8
|
+
export type HygieneCell = { id: string; owner?: string | null; status: string; title?: string };
|
|
9
9
|
export type HygieneNotice = { to: Seat; key: string; body: string };
|
|
10
10
|
export type HygieneDeps = {
|
|
11
11
|
root: string;
|
|
@@ -45,7 +45,7 @@ export function starvingCycles(log: string): { reasons: Record<string, number> }
|
|
|
45
45
|
return { reasons };
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
type HoldMeta = { id?: unknown; op?: unknown; reason?: unknown; until?: unknown };
|
|
48
|
+
type HoldMeta = { id?: unknown; op?: unknown; reason?: unknown; until?: unknown; kind?: unknown; confirmedAt?: unknown; at?: unknown; title?: unknown };
|
|
49
49
|
function holdMetadata(path: string): Map<string, HoldMeta> {
|
|
50
50
|
const latest = new Map<string, HoldMeta>();
|
|
51
51
|
for (const line of (readOptional(path) ?? '').split(/\r?\n/)) {
|
|
@@ -65,6 +65,10 @@ function untilTime(value: unknown): number | null {
|
|
|
65
65
|
return Number.isFinite(time) ? time : null;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
function confirmedTime(value: unknown): number | null {
|
|
69
|
+
return typeof value === 'string' && /^\d{12}$/.test(value) ? untilTime(value) : null;
|
|
70
|
+
}
|
|
71
|
+
|
|
68
72
|
export function inspectHoldHygiene(deps: HygieneDeps): HygieneNotice[] {
|
|
69
73
|
const notices: HygieneNotice[] = [];
|
|
70
74
|
const dir = deps.dispatcherDir ?? opSeatStatePath('feeder');
|
|
@@ -88,11 +92,25 @@ export function inspectHoldHygiene(deps: HygieneDeps): HygieneNotice[] {
|
|
|
88
92
|
if (!SEATS.some(seat => seat === owner)) continue;
|
|
89
93
|
const meta = metadata.get(cell.id);
|
|
90
94
|
const reason = meta?.op === 'add' && typeof meta.reason === 'string' ? meta.reason.trim() : '';
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
95
|
+
let attention = '';
|
|
96
|
+
if (meta?.kind === '손작업') {
|
|
97
|
+
const confirmed = confirmedTime(meta.confirmedAt ?? meta.at);
|
|
98
|
+
if (confirmed === null) attention = '재확인 시각 없음';
|
|
99
|
+
else if (deps.now.getTime() - confirmed >= 24 * 60 * 60_000) attention = '24h 재확인 지연';
|
|
100
|
+
} else if (meta?.kind === '재발사금지') {
|
|
101
|
+
if (typeof meta.title !== 'string' || !meta.title || typeof cell.title !== 'string' || !cell.title) attention = '제목 기준 확인 불가';
|
|
102
|
+
else if (cell.title !== meta.title) attention = '칸 제목 변경';
|
|
103
|
+
} else if (meta?.kind === '선행대기' || meta?.kind === undefined || meta?.kind === '') {
|
|
104
|
+
const expiry = untilTime(meta?.until);
|
|
105
|
+
if (expiry === null) attention = 'until 확인 불가';
|
|
106
|
+
else if (expiry <= deps.now.getTime()) attention = `until ${String(meta?.until)} 지남`;
|
|
107
|
+
} else attention = 'hold 종류 확인 불가';
|
|
108
|
+
if (reason && !attention) continue;
|
|
109
|
+
const guidance = meta?.kind === '손작업' ? '재확인 시각·사유를 판단해 OP에 알려 주세요.'
|
|
110
|
+
: meta?.kind === '재발사금지' ? '칸 제목과 기준 제목·사유를 대조해 OP에 알려 주세요.'
|
|
111
|
+
: '풀기/유지(사유·until)를 판단해 OP에 알려 주세요.';
|
|
94
112
|
notices.push({ to: owner as Seat, key: `hold:${cell.id}:${owner}`,
|
|
95
|
-
body: `노랑 칸 ${cell.id} traffic hold: ${!reason ? '사유 없음' : `사유 ${reason}`} ${
|
|
113
|
+
body: `노랑 칸 ${cell.id} traffic hold: ${!reason ? '사유 없음' : `사유 ${reason}`} ${attention ? `· ${attention}` : ''}. ${guidance} 자동 해제하지 않습니다.` });
|
|
96
114
|
}
|
|
97
115
|
return notices;
|
|
98
116
|
}
|
|
@@ -15,16 +15,19 @@ export interface ReleaseDayDecision {
|
|
|
15
15
|
reason?: string;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
/**
|
|
18
|
+
/** Green-back waits for both the scheduled publish end and the actual publication record. */
|
|
19
19
|
export function decideReleaseDayPhase(schedule: ReleaseSchedule, now: Date, publishedAt: string | null): ReleaseDayDecision {
|
|
20
20
|
const cut = Date.parse(schedule.cutAt);
|
|
21
21
|
const land = schedule.landBy ? Date.parse(schedule.landBy) : cut;
|
|
22
22
|
const gate = cut - 30 * 60_000;
|
|
23
23
|
const time = now.getTime();
|
|
24
|
+
const published = publishedAt ? Date.parse(publishedAt) : Number.NaN;
|
|
25
|
+
const publishEnd = schedule.publishAt ? Date.parse(schedule.publishAt) : published;
|
|
26
|
+
const greenAt = Number.isFinite(published) && Number.isFinite(publishEnd) ? Math.max(published, publishEnd) : Number.NaN;
|
|
24
27
|
let phase: ReleaseDayPhase = 'none';
|
|
25
28
|
let dueAt: string | null = null;
|
|
26
|
-
if (
|
|
27
|
-
phase = 'green-back'; dueAt = publishedAt;
|
|
29
|
+
if (time >= greenAt) {
|
|
30
|
+
phase = 'green-back'; dueAt = publishEnd >= published ? schedule.publishAt ?? publishedAt : publishedAt;
|
|
28
31
|
} else if (time >= cut) {
|
|
29
32
|
phase = 'cut-run'; dueAt = schedule.cutAt;
|
|
30
33
|
} else if (time >= land) {
|
|
@@ -133,6 +136,7 @@ export function runReleaseDayShadow(deps: ReleaseDayShadowDeps = {}): ReleaseDay
|
|
|
133
136
|
continue;
|
|
134
137
|
}
|
|
135
138
|
const publishedAt = publication.kind === 'published' ? publication.at : null;
|
|
139
|
+
// The steward graph tick records this judgment only; release CLI actions remain outside this shadow boundary.
|
|
136
140
|
const decision = decideReleaseDayPhase(schedule, now, publishedAt);
|
|
137
141
|
let recorded = false;
|
|
138
142
|
if (decision.phase !== 'none') {
|