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
|
@@ -22,7 +22,8 @@ import { templateForGoalType } from '../self-implement/graph-templates.js';
|
|
|
22
22
|
import { appendRunLedgerEntry, listRunLedgers, loadFederatedRunLedger, loadRunLedger, queryRunScreenKey, runLedgerDir, type RunLedgerEntry, type RunLedgerMatch, type RunLedgerWriter } from '../self-implement/run-ledger.js';
|
|
23
23
|
import { classifyPodExit, type PodExitClass } from '../task-orchestrator/surfaces/pod-failure-reason.js';
|
|
24
24
|
import type { PodChildEvidence } from '../task-orchestrator/surfaces/self-implement.js';
|
|
25
|
-
import { classifyPodExitStop, recordRunStop, runStopRecorded, RUN_STOP_EVENT } from '../self-implement/run-stop.js';
|
|
25
|
+
import { classifyPodExitStop, readRunStopRecord, recordRunStop, runStopRecorded, RUN_STOP_EVENT } from '../self-implement/run-stop.js';
|
|
26
|
+
import { captureStopKnowhowCandidate } from '../self-implement/stop-autoheal.js';
|
|
26
27
|
import { ensureOpenRouterChildModelLive, resolveChildLlmEffort, resolveImplementationChildModel } from '../self-dev/dev-cli.js';
|
|
27
28
|
import { resolveHarnessTarget } from '../self-implement/harness-target-options.js';
|
|
28
29
|
import { buildRunProgressRows, isPartialRunningRuns, queryRunningRuns, renderRunProgressTable } from '../self-implement/running-runs.js';
|
|
@@ -450,7 +451,7 @@ export function classifyHarnessPodExit(
|
|
|
450
451
|
loadCheckpoint?: typeof loadSelfDevRun;
|
|
451
452
|
runId?: string;
|
|
452
453
|
} = {},
|
|
453
|
-
): { lines: string[]; reason: PodExitReason | 'pod-failure' } {
|
|
454
|
+
): { lines: string[]; reason: PodExitReason | 'pod-failure'; podErrorCode?: 'pod-job-failed' } {
|
|
454
455
|
const occupiedNewLine = output.split('\n').find((line) =>
|
|
455
456
|
/^\[self-dev\] run run-[a-z0-9_-]{8,64} \[preflight:new-path-occupied:[0-9a-f-]{36}\] /.test(line));
|
|
456
457
|
const observedRunId = deps.runId ?? harnessPodRunId(output);
|
|
@@ -475,6 +476,7 @@ export function classifyHarnessPodExit(
|
|
|
475
476
|
}
|
|
476
477
|
let podFailure: string | undefined;
|
|
477
478
|
let podJobFailed = false;
|
|
479
|
+
let podJobFailedFromResult = false;
|
|
478
480
|
let podChildFailed = false;
|
|
479
481
|
for (const line of output.split('\n').reverse()) {
|
|
480
482
|
if (!line.trimStart().startsWith('[{') || !line.includes('"error"')) continue;
|
|
@@ -487,6 +489,7 @@ export function classifyHarnessPodExit(
|
|
|
487
489
|
if (typeof error?.code !== 'string' || typeof error.message !== 'string' || !error.code.startsWith('pod-')) continue;
|
|
488
490
|
podFailure = error.message;
|
|
489
491
|
podJobFailed = error.code === 'pod-job-failed';
|
|
492
|
+
podJobFailedFromResult = podJobFailed;
|
|
490
493
|
podChildFailed = error.code === 'pod-child-failed';
|
|
491
494
|
break;
|
|
492
495
|
}
|
|
@@ -505,7 +508,7 @@ export function classifyHarnessPodExit(
|
|
|
505
508
|
if (podFailure) {
|
|
506
509
|
const childError = podJobFailed ? podFailure.split('childError=')[1]?.split('\\n', 1)[0]?.split('\n', 1)[0] : undefined;
|
|
507
510
|
try { debug.log('harness.pod', 'exit-classified', { runId, reason: 'pod-failure', status: exit.status, signal: exit.signal ?? null }); } catch { /* observation is fail-soft */ }
|
|
508
|
-
return { reason: 'pod-failure', lines: [podChildFailed
|
|
511
|
+
return { reason: 'pod-failure', ...(podJobFailedFromResult ? { podErrorCode: 'pod-job-failed' as const } : {}), lines: [podChildFailed
|
|
509
512
|
? `Pod 안 자식이 실패했다 — ${podFailure.split('\\n', 1)[0]}`
|
|
510
513
|
: podJobFailed && childError && childError !== 'no-result-line'
|
|
511
514
|
? `Pod 안 자식이 실패했다 — ${childError}`
|
|
@@ -769,7 +772,7 @@ async function onPod(opts: unknown, entrance: 'cli-harness-ask' | 'cli-harness-s
|
|
|
769
772
|
export function recordHarnessPodStop(
|
|
770
773
|
runId: string | undefined,
|
|
771
774
|
status: number,
|
|
772
|
-
classified: { reason: string; lines: string[] },
|
|
775
|
+
classified: { reason: string; lines: string[]; podErrorCode?: 'pod-job-failed' },
|
|
773
776
|
output?: string,
|
|
774
777
|
deps: { loadLedger?: typeof loadRunLedger; record?: typeof recordRunStop; write?: RunLedgerWriter } = {},
|
|
775
778
|
): boolean {
|
|
@@ -805,11 +808,32 @@ export function recordHarnessPodStop(
|
|
|
805
808
|
}
|
|
806
809
|
// The classified line is our own one-line verdict («Pod 안 자식이 실패했다 — OOMKilled»), not the raw output tail.
|
|
807
810
|
const verdict = classified.lines[0]?.split(' — ').slice(1).join(' — ').trim();
|
|
808
|
-
(deps.record ?? recordRunStop)({
|
|
811
|
+
const stopEntry = (deps.record ?? recordRunStop)({
|
|
809
812
|
runId, site: 'pod-exit', class: scopeEscape ? 'scope-escape' : classifyPodExitStop(classified.reason),
|
|
810
813
|
cause: `Pod exit ${status}: ${scopeEscape ? 'scope-escape' : classified.reason}${verdict ? ` — ${verdict}` : ''}`,
|
|
811
814
|
evidenceRef, nextMove, ...(childEvidence ? { childEvidence } : {}),
|
|
815
|
+
...(classified.podErrorCode === 'pod-job-failed' ? { terminationReason: classified.podErrorCode } : {}),
|
|
812
816
|
}, ...(deps.write ? [deps.write] : []));
|
|
817
|
+
// Host-only Pod exits do not pass through orchestrator.autohealRecordedStop. Capture the
|
|
818
|
+
// exact Job failure here, after the durable stop write, without initiating a heal action.
|
|
819
|
+
if (classified.podErrorCode === 'pod-job-failed' && stopEntry) {
|
|
820
|
+
try {
|
|
821
|
+
const record = readRunStopRecord(stopEntry);
|
|
822
|
+
if (record) {
|
|
823
|
+
const goalId = ledger?.find((entry) => entry.goalId)?.goalId;
|
|
824
|
+
const captured = captureStopKnowhowCandidate({ runId, ...(goalId ? { goalId } : {}), record },
|
|
825
|
+
join(effectiveInstanceRoot(), 'self-implement', 'knowhow-candidates'));
|
|
826
|
+
if (captured) debug.log('self-implement.autoheal', 'knowhow-candidate', {
|
|
827
|
+
runId, cell: captured.candidate.cell, reason: captured.candidate.reason,
|
|
828
|
+
created: captured.created, occurrences: captured.candidate.occurrences, path: captured.path,
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
} catch (error) {
|
|
832
|
+
try { debug.log('self-implement.autoheal', 'knowhow-candidate-failed', {
|
|
833
|
+
runId, error: error instanceof Error ? error.message : String(error),
|
|
834
|
+
}); } catch { /* observation is fail-soft */ }
|
|
835
|
+
}
|
|
836
|
+
}
|
|
813
837
|
return true;
|
|
814
838
|
} catch { return false; /* ledger observation cannot change Pod output or exit */ }
|
|
815
839
|
}
|
|
@@ -2378,8 +2402,9 @@ function githubRemoteRepository(url: string): string | undefined {
|
|
|
2378
2402
|
interface GraphqlPrDetail {
|
|
2379
2403
|
readonly files: string[] | null;
|
|
2380
2404
|
readonly comments: string[] | null;
|
|
2381
|
-
readonly reviews: Array<{ state?: string; body?: string }> | null;
|
|
2405
|
+
readonly reviews: Array<{ state?: string; body?: string; submittedAt?: string; commitOid?: string }> | null;
|
|
2382
2406
|
readonly headSha: string | null;
|
|
2407
|
+
readonly headCommittedAt: string | null;
|
|
2383
2408
|
readonly mergeCommit: { oid: string; message: string } | null;
|
|
2384
2409
|
}
|
|
2385
2410
|
|
|
@@ -2407,10 +2432,10 @@ async function graphqlPrDetails(repository: string, numbers: readonly number[],
|
|
|
2407
2432
|
// Fields the batch could not prove complete (each one is read again over REST by the caller).
|
|
2408
2433
|
const incompleteFields = { files: 0, comments: 0, reviews: 0 };
|
|
2409
2434
|
await mapBounded(batches, DRAFT_SWEEP_CONCURRENCY, async (batch) => {
|
|
2410
|
-
const fields = batch.map((number) => `p${number}: pullRequest(number: ${number}) { number headRefOid `
|
|
2435
|
+
const fields = batch.map((number) => `p${number}: pullRequest(number: ${number}) { number headRefOid headRef { target { ... on Commit { committedDate } } } `
|
|
2411
2436
|
+ 'files(first: 100) { totalCount nodes { path } pageInfo { hasNextPage } } '
|
|
2412
2437
|
+ 'comments(first: 100) { totalCount nodes { body } pageInfo { hasNextPage } } '
|
|
2413
|
-
+ 'reviews(first: 100) { totalCount nodes { state body } pageInfo { hasNextPage } } '
|
|
2438
|
+
+ 'reviews(first: 100) { totalCount nodes { state body submittedAt commit { oid } } pageInfo { hasNextPage } } '
|
|
2414
2439
|
+ 'mergeCommit { oid message } }').join(' ');
|
|
2415
2440
|
const query = `query { repository(owner: ${JSON.stringify(owner)}, name: ${JSON.stringify(name)}) { ${fields} } }`;
|
|
2416
2441
|
let repositoryNode: Record<string, unknown> | undefined;
|
|
@@ -2421,9 +2446,10 @@ async function graphqlPrDetails(repository: string, numbers: readonly number[],
|
|
|
2421
2446
|
if (!repositoryNode || typeof repositoryNode !== 'object' || Array.isArray(repositoryNode)) { failedBatches += 1; return; }
|
|
2422
2447
|
for (const number of batch) {
|
|
2423
2448
|
const pr = repositoryNode[`p${number}`] as {
|
|
2424
|
-
number?: number; headRefOid?: string;
|
|
2449
|
+
number?: number; headRefOid?: string; headRef?: { target?: { committedDate?: string } | null } | null;
|
|
2425
2450
|
files?: GraphqlConnection<{ path?: string }>; comments?: GraphqlConnection<{ body?: string }>;
|
|
2426
|
-
reviews?: GraphqlConnection<{ state?: string; body?: string
|
|
2451
|
+
reviews?: GraphqlConnection<{ state?: string; body?: string; submittedAt?: string; commit?: { oid?: string } | null }>;
|
|
2452
|
+
mergeCommit?: { oid?: string; message?: string } | null;
|
|
2427
2453
|
} | null | undefined;
|
|
2428
2454
|
if (!pr || pr.number !== number) continue;
|
|
2429
2455
|
const files = completeNodes(pr.files);
|
|
@@ -2433,8 +2459,10 @@ async function graphqlPrDetails(repository: string, numbers: readonly number[],
|
|
|
2433
2459
|
files: files && files.every((file) => typeof file?.path === 'string') ? files.map((file) => file.path!) : null,
|
|
2434
2460
|
comments: comments && comments.every((comment) => typeof comment?.body === 'string') ? comments.map((comment) => comment.body!) : null,
|
|
2435
2461
|
reviews: reviews && reviews.every((review) => review && typeof review === 'object')
|
|
2436
|
-
? reviews.map((review) => ({ state: review.state, body: review.body
|
|
2462
|
+
? reviews.map((review) => ({ state: review.state, body: review.body, submittedAt: review.submittedAt,
|
|
2463
|
+
commitOid: review.commit?.oid })) : null,
|
|
2437
2464
|
headSha: typeof pr.headRefOid === 'string' && pr.headRefOid ? pr.headRefOid : null,
|
|
2465
|
+
headCommittedAt: typeof pr.headRef?.target?.committedDate === 'string' ? pr.headRef.target.committedDate : null,
|
|
2438
2466
|
mergeCommit: pr.mergeCommit && typeof pr.mergeCommit.oid === 'string' && typeof pr.mergeCommit.message === 'string'
|
|
2439
2467
|
? { oid: pr.mergeCommit.oid, message: pr.mergeCommit.message } : null,
|
|
2440
2468
|
};
|
|
@@ -2565,30 +2593,80 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
|
|
|
2565
2593
|
}
|
|
2566
2594
|
throw new Error(`${what === 'review' ? 'Review' : what === 'same-cell' ? 'Same-cell' : 'Landing'} comment inventory exceeded pagination limit`);
|
|
2567
2595
|
};
|
|
2596
|
+
const reviewsFor = async (repository: string, number: number): Promise<Array<{ state?: string; body?: string; submittedAt?: string; commitOid?: string }>> => {
|
|
2597
|
+
const reviews: Array<{ state?: string; body?: string; submittedAt?: string; commitOid?: string }> = [];
|
|
2598
|
+
for (let page = 1; page <= 100; page++) {
|
|
2599
|
+
const batch = await ghJsonAsync<Array<{ state?: string; body?: string; submitted_at?: string; commit_id?: string }>>(
|
|
2600
|
+
['api', `repos/${repository}/pulls/${number}/reviews?per_page=100&page=${page}`]);
|
|
2601
|
+
if (!Array.isArray(batch) || batch.length > 100) throw new Error('Incomplete review inventory');
|
|
2602
|
+
reviews.push(...batch.map((review) => ({ state: review.state, body: review.body,
|
|
2603
|
+
submittedAt: review.submitted_at, commitOid: review.commit_id })));
|
|
2604
|
+
if (batch.length < 100) return reviews;
|
|
2605
|
+
}
|
|
2606
|
+
throw new Error('Review inventory exceeded pagination limit');
|
|
2607
|
+
};
|
|
2608
|
+
const checkRunsFor = async (repository: string, sha: string): Promise<Array<{ conclusion?: string | null }> | undefined> => {
|
|
2609
|
+
const runs: Array<{ conclusion?: string | null }> = [];
|
|
2610
|
+
for (let page = 1; page <= 100; page++) {
|
|
2611
|
+
const result = await ghJsonAsync<{ total_count?: number; check_runs?: Array<{ conclusion?: string | null }> }>(
|
|
2612
|
+
['api', `repos/${repository}/commits/${sha}/check-runs?per_page=100&page=${page}`]);
|
|
2613
|
+
if (!Array.isArray(result?.check_runs) || result.check_runs.length > 100) throw new Error('Incomplete check-run inventory');
|
|
2614
|
+
runs.push(...result.check_runs);
|
|
2615
|
+
if (Number.isSafeInteger(result.total_count) && runs.length >= result.total_count!) return runs;
|
|
2616
|
+
if (result.check_runs.length < 100) return Number.isSafeInteger(result.total_count) && runs.length < result.total_count! ? undefined : runs;
|
|
2617
|
+
}
|
|
2618
|
+
return undefined;
|
|
2619
|
+
};
|
|
2620
|
+
const headCommitTimeFor = async (repository: string, number: number): Promise<string | undefined> => {
|
|
2621
|
+
let latest: string | undefined;
|
|
2622
|
+
for (let page = 1; page <= 100; page++) {
|
|
2623
|
+
const batch = await ghJsonAsync<Array<{ commit?: { committer?: { date?: string } } }>>(
|
|
2624
|
+
['api', `repos/${repository}/pulls/${number}/commits?per_page=100&page=${page}`]);
|
|
2625
|
+
if (!Array.isArray(batch) || batch.length > 100) throw new Error('Incomplete PR commit inventory');
|
|
2626
|
+
for (const commit of batch) {
|
|
2627
|
+
const date = commit.commit?.committer?.date;
|
|
2628
|
+
if (!date || !Number.isFinite(Date.parse(date))) throw new Error('Incomplete PR commit timestamp');
|
|
2629
|
+
latest = date;
|
|
2630
|
+
}
|
|
2631
|
+
if (batch.length < 100) return latest;
|
|
2632
|
+
}
|
|
2633
|
+
throw new Error('PR commit inventory exceeded pagination limit');
|
|
2634
|
+
};
|
|
2568
2635
|
const reviewGateForDraft = async (draft: SweepDraft, repository: string): Promise<SweepReviewGate | undefined> => {
|
|
2569
2636
|
const cached = await detailFor(repository, draft.number);
|
|
2570
2637
|
const sha = cached?.headSha
|
|
2571
2638
|
?? (await ghJsonAsync<{ head?: { sha?: string } }>(['api', `repos/${repository}/pulls/${draft.number}`]))?.head?.sha;
|
|
2572
2639
|
if (!sha) return undefined;
|
|
2640
|
+
const reviews = cached?.reviews ?? await reviewsFor(repository, draft.number);
|
|
2641
|
+
if (!Array.isArray(reviews)) throw new Error('Incomplete review inventory');
|
|
2573
2642
|
const comments = cached?.comments ?? await issueCommentsFor(repository, draft.number, 'review');
|
|
2574
|
-
const
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2643
|
+
const legacyText = [...comments, ...reviews.map((review) => review.body ?? '')].join('\n');
|
|
2644
|
+
const currentHeadReviews = reviews.filter((review) => review && typeof review === 'object'
|
|
2645
|
+
&& review.commitOid === sha
|
|
2646
|
+
&& typeof review.submittedAt === 'string' && Number.isFinite(Date.parse(review.submittedAt)))
|
|
2647
|
+
.sort((a, b) => Date.parse(a.submittedAt!) - Date.parse(b.submittedAt!));
|
|
2648
|
+
const latestHeadReview = currentHeadReviews.at(-1);
|
|
2649
|
+
const triageReview = latestHeadReview?.state === 'APPROVED' ? 'approved'
|
|
2650
|
+
: latestHeadReview?.state === 'CHANGES_REQUESTED' ? 'changes-requested'
|
|
2651
|
+
: latestHeadReview?.state === 'COMMENTED' ? 'commented'
|
|
2652
|
+
: latestHeadReview?.state === 'DISMISSED' ? 'dismissed'
|
|
2653
|
+
: latestHeadReview?.state === 'PENDING' ? 'pending' : 'unknown';
|
|
2578
2654
|
const [status, checkRuns] = await Promise.all([
|
|
2579
2655
|
ghJsonAsync<{ state?: string }>(['api', `repos/${repository}/commits/${sha}/status`]),
|
|
2580
|
-
|
|
2656
|
+
checkRunsFor(repository, sha),
|
|
2581
2657
|
]);
|
|
2582
|
-
|
|
2583
|
-
const
|
|
2584
|
-
|
|
2585
|
-
&& conclusions.
|
|
2658
|
+
const conclusions = checkRuns?.map((run) => run.conclusion ?? null) ?? [];
|
|
2659
|
+
const gatePass = status?.state === 'success'
|
|
2660
|
+
&& checkRuns !== undefined && conclusions.length > 0
|
|
2661
|
+
&& conclusions.every((conclusion) => conclusion === 'success' || conclusion === 'skipped' || conclusion === 'neutral');
|
|
2586
2662
|
const gateFail = status?.state === 'failure' || status?.state === 'error'
|
|
2587
2663
|
|| conclusions.some((conclusion) => conclusion === 'failure' || conclusion === 'cancelled' || conclusion === 'timed_out' || conclusion === 'action_required');
|
|
2588
2664
|
return {
|
|
2589
|
-
...(reviews.some((review) => review.state === 'APPROVED') || /(?:^|\n)\s*VERDICT:\s*PASS\b/i.test(
|
|
2590
|
-
|
|
2665
|
+
...(reviews.some((review) => review.state === 'APPROVED') || /(?:^|\n)\s*VERDICT:\s*PASS\b/i.test(legacyText)
|
|
2666
|
+
? { review: 'pass' as const } : {}),
|
|
2667
|
+
...(mustFixRemains(legacyText) ? { mustFix: true } : {}),
|
|
2591
2668
|
...(gatePass && !gateFail ? { gate: 'pass' as const } : gateFail ? { gate: 'fail' as const } : {}),
|
|
2669
|
+
triageReview,
|
|
2592
2670
|
};
|
|
2593
2671
|
};
|
|
2594
2672
|
const claimCommentsFor = async (repository: string, number: number): Promise<string[]> => {
|
|
@@ -2618,11 +2696,15 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
|
|
|
2618
2696
|
const prs = (await listed(open, repository, 'open')).filter((pr) => pr.draft);
|
|
2619
2697
|
await prefetchDetails(repository, prs.map((pr) => pr.number));
|
|
2620
2698
|
const matches = ledgerMatches ??= listRunLedgers().matches;
|
|
2621
|
-
return mapBounded(prs, DRAFT_SWEEP_CONCURRENCY, async (pr): Promise<SweepDraft> =>
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2699
|
+
return mapBounded(prs, DRAFT_SWEEP_CONCURRENCY, async (pr): Promise<SweepDraft> => {
|
|
2700
|
+
return {
|
|
2701
|
+
number: pr.number, title: pr.title, branch: pr.head.ref,
|
|
2702
|
+
labels: pr.labels.map((item) => item.name), createdAt: pr.created_at, body: pr.body ?? undefined,
|
|
2703
|
+
changedFiles: await prFiles(repository, pr.number),
|
|
2704
|
+
...(pr.updated_at ? { updatedAt: pr.updated_at } : {}),
|
|
2705
|
+
runId: currentDraftSweepRunId(matches, repository, pr.number),
|
|
2706
|
+
};
|
|
2707
|
+
});
|
|
2626
2708
|
})());
|
|
2627
2709
|
return draftRows.get(repository)!;
|
|
2628
2710
|
};
|
|
@@ -2677,6 +2759,8 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
|
|
|
2677
2759
|
},
|
|
2678
2760
|
listDrafts: async (page, perPage, repository): Promise<SweepDraft[]> =>
|
|
2679
2761
|
(await enrichedDrafts(repository)).slice((page - 1) * perPage, page * perPage),
|
|
2762
|
+
getHeadCommitTime: async (repository, number) => (await detailFor(repository, number))?.headCommittedAt
|
|
2763
|
+
?? await headCommitTimeFor(repository, number).catch(() => undefined),
|
|
2680
2764
|
listMerged: async (page, perPage, repository): Promise<SweepMergedPr[]> =>
|
|
2681
2765
|
(await enrichedMerged(repository)).slice((page - 1) * perPage, page * perPage),
|
|
2682
2766
|
getRunStatus: async (draft, repository) => runStatusFor(draft, repository),
|
|
@@ -2943,7 +3027,7 @@ function installHarnessDraftSweepCommand(harnessCmd: Command, deps: HarnessDraft
|
|
|
2943
3027
|
owner: 'unknown', ownerSource: 'unknown', step: 'replay', reason: sweepFailureReason(error) });
|
|
2944
3028
|
}
|
|
2945
3029
|
}
|
|
2946
|
-
const result: DraftSweepResult = await runDraftSweep({ repository, apply: opts.apply === true, adapters: deps.adapters ?? github!,
|
|
3030
|
+
const result: DraftSweepResult = await runDraftSweep({ repository, apply: opts.apply === true, includeTriage: opts.json === true, adapters: deps.adapters ?? github!,
|
|
2947
3031
|
closeCap: cap.closeCap, closeCapSource: cap.closeCapSource, alreadyClosed: replayClosed });
|
|
2948
3032
|
const reason = result.error ? sweepFailureReason(result.error) : undefined;
|
|
2949
3033
|
const ttlStarted = Date.now();
|
|
@@ -209,6 +209,39 @@ export function recentBurst(root: string, now: Date | number, { lookbackMs = 15
|
|
|
209
209
|
return recent.sort((a, b) => Date.parse(a.lastAt) - Date.parse(b.lastAt)).at(-1) ?? null;
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
+
/** 사고 선례 1건 — 현재 사고 이전의 같은 reason 종료 기록(결정론 · 기록된 실제 exit 만). */
|
|
213
|
+
export interface IncidentPrecedent {
|
|
214
|
+
runId: string;
|
|
215
|
+
reason: string;
|
|
216
|
+
status: number | null;
|
|
217
|
+
signal: string | null;
|
|
218
|
+
at: string;
|
|
219
|
+
lastLines?: string[];
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* 사고 선례 연결 — 현재 사고(reason·at) 이전에 같은 reason 으로 종료된 기록된 실제 exit 만
|
|
224
|
+
* 돌려준다(유사 과거 지어내기 금지 · readRunExits 재사용 · READ-ONLY). 현재 runId 는 제외하고
|
|
225
|
+
* 시간 내림차순, 기본 5건까지. 기록이 없으면 빈 배열(«기록 없음»).
|
|
226
|
+
*/
|
|
227
|
+
export function findIncidentPrecedents(
|
|
228
|
+
current: { reason: string; at: string; runId?: string },
|
|
229
|
+
root: string,
|
|
230
|
+
{ limit = 5 }: { limit?: number } = {},
|
|
231
|
+
): IncidentPrecedent[] {
|
|
232
|
+
const at = Date.parse(current.at);
|
|
233
|
+
if (!current.reason.trim() || !Number.isFinite(at)) return [];
|
|
234
|
+
return readRunExits(root)
|
|
235
|
+
.filter((row) => row.reason === current.reason && row.runId !== current.runId
|
|
236
|
+
&& Date.parse(row.at) < at)
|
|
237
|
+
.sort((a, b) => Date.parse(b.at) - Date.parse(a.at) || b.runId.localeCompare(a.runId))
|
|
238
|
+
.slice(0, Math.max(0, limit))
|
|
239
|
+
.map((row) => ({
|
|
240
|
+
runId: row.runId, reason: row.reason, status: row.status, signal: row.signal, at: row.at,
|
|
241
|
+
...(Array.isArray(row.lastLines) ? { lastLines: row.lastLines } : {}),
|
|
242
|
+
}));
|
|
243
|
+
}
|
|
244
|
+
|
|
212
245
|
export function formatIncidentBurstWarning(burst: IncidentBurst): string {
|
|
213
246
|
const time = new Date(Date.parse(burst.lastAt) + KST_OFFSET_MS).toISOString().slice(11, 16);
|
|
214
247
|
const owner = burst.seat || burst.entrance ? ` [seat=${burst.seat ?? '-'} entrance=${burst.entrance ?? '-'}]` : '';
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
2
|
+
import { closeSync, constants, fstatSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, writeSync } from 'node:fs';
|
|
3
|
+
import { join, parse, resolve } from 'node:path';
|
|
4
|
+
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
5
|
+
import { debug } from '../debug/log.js';
|
|
6
|
+
|
|
7
|
+
/** Product ledger of the raw first text a launch entrance received (say · hand · ask-file).
|
|
8
|
+
* Auxiliary evidence: preparing or appending never refuses a launch — failures are observed. */
|
|
9
|
+
export interface LaunchUtteranceStart {
|
|
10
|
+
readonly event: 'start';
|
|
11
|
+
readonly launchId: string;
|
|
12
|
+
readonly source: 'say' | 'hand' | 'ask-file';
|
|
13
|
+
readonly utterance: string;
|
|
14
|
+
/** sha256 of the UTF-8 bytes of `utterance` (or of the raw bytes when given). */
|
|
15
|
+
readonly sha256: string;
|
|
16
|
+
/** Present only when the raw source bytes are not lossless UTF-8 (ask-file). */
|
|
17
|
+
readonly utteranceBase64?: string;
|
|
18
|
+
/** Present for `say`: the exact argv words the process received. */
|
|
19
|
+
readonly argv?: readonly string[];
|
|
20
|
+
/** The entrance was asked for a plan only (`--dry-run`) — the text was received, nothing launched. */
|
|
21
|
+
readonly dryRun?: true;
|
|
22
|
+
readonly at: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface LaunchUtteranceInput {
|
|
26
|
+
readonly source: LaunchUtteranceStart['source'];
|
|
27
|
+
readonly utterance: string;
|
|
28
|
+
readonly launchId: string;
|
|
29
|
+
readonly rawBytes?: Uint8Array;
|
|
30
|
+
readonly argv?: readonly string[];
|
|
31
|
+
readonly dryRun?: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const LAUNCH_ID = /^tl-[0-9a-f]{12}$/;
|
|
35
|
+
const DATE_FILE = /^\d{4}-\d{2}-\d{2}\.jsonl$/;
|
|
36
|
+
const DAY_MS = 86_400_000;
|
|
37
|
+
|
|
38
|
+
/** Env contract of the one explicit hand→say pair (set by the hand launcher, consumed once by say). */
|
|
39
|
+
export const HAND_LAUNCH_ID_ENV = 'ELANOUS_HAND_LAUNCH_ID';
|
|
40
|
+
export const HAND_LAUNCH_SHA256_ENV = 'ELANOUS_HAND_LAUNCH_SHA256';
|
|
41
|
+
export const HAND_LAUNCH_RUN_ENV = 'ELANOUS_HAND_LAUNCH_RUN';
|
|
42
|
+
/** base64 of the hand's exact original text (untrimmed), so the paired child can re-record it byte-exact. */
|
|
43
|
+
export const HAND_LAUNCH_ORIGINAL_ENV = 'ELANOUS_HAND_LAUNCH_ORIGINAL_B64';
|
|
44
|
+
const MAX_ORIGINAL_ENV_BYTES = 64 * 1024;
|
|
45
|
+
|
|
46
|
+
/** Same `tl-<12 hex>` shape the hand card contract already carries; minted fresh in every process. */
|
|
47
|
+
export function newLaunchUtteranceId(): string { return `tl-${randomBytes(6).toString('hex')}`; }
|
|
48
|
+
export function isLaunchUtteranceId(value: unknown): value is string { return typeof value === 'string' && LAUNCH_ID.test(value); }
|
|
49
|
+
export function utteranceSha256(value: string | Uint8Array): string { return createHash('sha256').update(value).digest('hex'); }
|
|
50
|
+
|
|
51
|
+
/** Env a hand launcher passes to its say child so that pair — and only that pair — shares the ID.
|
|
52
|
+
* `sentence` is the exact argv word the say child receives; `original` is the hand's untrimmed text. */
|
|
53
|
+
export function handLaunchPairEnv(launchId: string, sentence: string, runId: string, original?: string): Record<string, string> {
|
|
54
|
+
const originalB64 = original === undefined ? undefined : Buffer.from(original, 'utf8').toString('base64');
|
|
55
|
+
return {
|
|
56
|
+
[HAND_LAUNCH_ID_ENV]: launchId, [HAND_LAUNCH_SHA256_ENV]: utteranceSha256(sentence), [HAND_LAUNCH_RUN_ENV]: runId,
|
|
57
|
+
...(originalB64 !== undefined && originalB64.length <= MAX_ORIGINAL_ENV_BYTES ? { [HAND_LAUNCH_ORIGINAL_ENV]: originalB64 } : {}),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Hand launcher seam: only a `harness say <sentence>` launch with a launchId ⊕ runId gets the pair env
|
|
62
|
+
* (ID ⊕ sentence sha ⊕ runId ⊕ exact original). Any other launch context passes through unchanged. */
|
|
63
|
+
export function withHandLaunchPairContext<C extends { launchId?: string; runId?: string; env: Record<string, string>; launchUtterance?: string }>(
|
|
64
|
+
args: readonly string[], context: C,
|
|
65
|
+
): C {
|
|
66
|
+
const sayAt = args.indexOf('say');
|
|
67
|
+
const sentence = args.at(-1);
|
|
68
|
+
if (!context.launchId || !context.runId || sayAt < 1 || args[sayAt - 1] !== 'harness' || sentence === undefined || sayAt === args.length - 1) return context;
|
|
69
|
+
return { ...context, env: { ...context.env, ...handLaunchPairEnv(context.launchId, sentence, context.runId, context.launchUtterance) } };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Resolve the say launchId: inherit only when the env pair matches this exact sentence and run, then
|
|
73
|
+
* remove the pair from `env` so no descendant or later say in this process can reuse the ID.
|
|
74
|
+
* When paired, `utterance` is the hand's exact original text (falls back to the sentence). */
|
|
75
|
+
export function consumeHandLaunchId(sentence: string, env: NodeJS.ProcessEnv = process.env, runIdEnv = 'ELANOUS_RUN_ID'): {
|
|
76
|
+
launchId: string; inherited: boolean; utterance: string;
|
|
77
|
+
} {
|
|
78
|
+
const inherited = env[HAND_LAUNCH_ID_ENV];
|
|
79
|
+
const sha = env[HAND_LAUNCH_SHA256_ENV];
|
|
80
|
+
const run = env[HAND_LAUNCH_RUN_ENV];
|
|
81
|
+
const originalB64 = env[HAND_LAUNCH_ORIGINAL_ENV];
|
|
82
|
+
for (const key of [HAND_LAUNCH_ID_ENV, HAND_LAUNCH_SHA256_ENV, HAND_LAUNCH_RUN_ENV, HAND_LAUNCH_ORIGINAL_ENV]) delete env[key];
|
|
83
|
+
const paired = isLaunchUtteranceId(inherited) && sha === utteranceSha256(sentence)
|
|
84
|
+
&& typeof run === 'string' && run.length > 0 && env[runIdEnv] === run;
|
|
85
|
+
if (inherited !== undefined && !paired) {
|
|
86
|
+
try { debug.log('harness.launch-utterance', 'inherit-refused', { hasSha: sha !== undefined, hasRun: run !== undefined }); } catch { /* fail-soft */ }
|
|
87
|
+
}
|
|
88
|
+
if (!paired) return { launchId: newLaunchUtteranceId(), inherited: false, utterance: sentence };
|
|
89
|
+
const original = originalB64 === undefined ? undefined : Buffer.from(originalB64, 'base64').toString('utf8');
|
|
90
|
+
const utterance = original !== undefined && original.trim() === sentence.trim() ? original : sentence;
|
|
91
|
+
return { launchId: inherited, inherited: true, utterance };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Symlink policy over every component of `path`, parents included: a symlink owned by the system
|
|
95
|
+
* (uid 0 — e.g. macOS `/var` · `/tmp`) is an OS alias and allowed; any other symlink is refused, so a
|
|
96
|
+
* user-made link can never redirect one instance's ledger into another instance. */
|
|
97
|
+
export function assertLedgerPathPolicy(path: string): void {
|
|
98
|
+
if (!path.trim()) throw new Error('ledger path must not be empty');
|
|
99
|
+
const absolute = resolve(path);
|
|
100
|
+
let part = parse(absolute).root;
|
|
101
|
+
for (const segment of absolute.slice(part.length).split('/').filter(Boolean)) {
|
|
102
|
+
part = join(part, segment);
|
|
103
|
+
let stat;
|
|
104
|
+
try { stat = lstatSync(part); } catch (error) {
|
|
105
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return;
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
if (stat.isSymbolicLink() && stat.uid !== 0) throw new Error(`ledger symlink refused: ${part}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function launchUtteranceDir(root: string = effectiveInstanceRoot()): string {
|
|
113
|
+
return join(resolve(root), 'launch-utterances');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function observeFailure(operation: 'prepare' | 'append' | 'query', error: unknown, extra: Record<string, unknown> = {}): void {
|
|
117
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
118
|
+
try { debug.log('harness.launch-utterance', `${operation}-failed`, { operation, reason, ...extra }, { level: 'warn' }); } catch { /* logging must not block launch */ }
|
|
119
|
+
try { console.error(`[launch-utterance] ${operation} failed: ${reason}`); } catch { /* fail-soft */ }
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function buildRow(input: LaunchUtteranceInput, now: Date): LaunchUtteranceStart {
|
|
123
|
+
const raw = input.rawBytes;
|
|
124
|
+
const lossy = raw !== undefined && !Buffer.from(input.utterance, 'utf8').equals(Buffer.from(raw));
|
|
125
|
+
return {
|
|
126
|
+
event: 'start',
|
|
127
|
+
launchId: input.launchId,
|
|
128
|
+
source: input.source,
|
|
129
|
+
utterance: input.utterance,
|
|
130
|
+
sha256: utteranceSha256(raw ?? input.utterance),
|
|
131
|
+
...(lossy ? { utteranceBase64: Buffer.from(raw).toString('base64') } : {}),
|
|
132
|
+
...(input.argv ? { argv: [...input.argv] } : {}),
|
|
133
|
+
...(input.dryRun === true ? { dryRun: true as const } : {}),
|
|
134
|
+
at: now.toISOString(),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Append one start row to this instance's date file. Returns whether it landed; never throws. */
|
|
139
|
+
export function recordLaunchUtterance(
|
|
140
|
+
input: LaunchUtteranceInput,
|
|
141
|
+
root: string = effectiveInstanceRoot(),
|
|
142
|
+
now: Date = new Date(),
|
|
143
|
+
): boolean {
|
|
144
|
+
let dir: string;
|
|
145
|
+
let row: string;
|
|
146
|
+
try {
|
|
147
|
+
if (!isLaunchUtteranceId(input.launchId)) throw new Error(`invalid launchId: ${String(input.launchId)}`);
|
|
148
|
+
dir = launchUtteranceDir(root);
|
|
149
|
+
assertLedgerPathPolicy(dir);
|
|
150
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
151
|
+
assertLedgerPathPolicy(dir);
|
|
152
|
+
if (!lstatSync(dir).isDirectory()) throw new Error(`ledger dir is not a directory: ${dir}`);
|
|
153
|
+
row = `${JSON.stringify(buildRow(input, now))}\n`;
|
|
154
|
+
} catch (error) { observeFailure('prepare', error, { source: input.source, launchId: input.launchId }); return false; }
|
|
155
|
+
try {
|
|
156
|
+
const file = join(dir, `${now.toISOString().slice(0, 10)}.jsonl`);
|
|
157
|
+
const fd = openSync(file, constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | constants.O_NOFOLLOW, 0o600);
|
|
158
|
+
try {
|
|
159
|
+
if (!fstatSync(fd).isFile()) throw new Error(`ledger file is not a regular file: ${file}`);
|
|
160
|
+
writeSync(fd, row);
|
|
161
|
+
} finally { closeSync(fd); }
|
|
162
|
+
try { debug.log('harness.launch-utterance', 'recorded', { source: input.source, launchId: input.launchId }); } catch { /* fail-soft */ }
|
|
163
|
+
return true;
|
|
164
|
+
} catch (error) { observeFailure('append', error, { source: input.source, launchId: input.launchId }); return false; }
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function readNoFollow(file: string): string {
|
|
168
|
+
const fd = openSync(file, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
169
|
+
try {
|
|
170
|
+
if (!fstatSync(fd).isFile()) throw new Error(`ledger file is not a regular file: ${file}`);
|
|
171
|
+
return readFileSync(fd, 'utf8');
|
|
172
|
+
} finally { closeSync(fd); }
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** Reads only this instance's date files that overlap [now - sinceMs, now], and rows inside that window. */
|
|
176
|
+
export function queryLaunchUtterances(options: { root?: string; sinceMs?: number; now?: Date } = {}): LaunchUtteranceStart[] {
|
|
177
|
+
const now = options.now ?? new Date();
|
|
178
|
+
const sinceMs = options.sinceMs ?? DAY_MS;
|
|
179
|
+
if (!Number.isFinite(sinceMs) || sinceMs < 0 || sinceMs > 31 * DAY_MS) throw new Error('invalid ledger query window');
|
|
180
|
+
const until = now.getTime();
|
|
181
|
+
const from = until - sinceMs;
|
|
182
|
+
const dir = launchUtteranceDir(options.root);
|
|
183
|
+
let names: string[];
|
|
184
|
+
try {
|
|
185
|
+
assertLedgerPathPolicy(dir);
|
|
186
|
+
if (!lstatSync(dir).isDirectory()) throw new Error(`ledger dir is not a directory: ${dir}`);
|
|
187
|
+
names = readdirSync(dir);
|
|
188
|
+
} catch (error) {
|
|
189
|
+
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') observeFailure('query', error);
|
|
190
|
+
return [];
|
|
191
|
+
}
|
|
192
|
+
const rows: LaunchUtteranceStart[] = [];
|
|
193
|
+
for (const name of names.filter((n) => DATE_FILE.test(n)).sort()) {
|
|
194
|
+
const day = Date.parse(`${name.slice(0, 10)}T00:00:00.000Z`);
|
|
195
|
+
if (!Number.isFinite(day) || day > until || day + DAY_MS <= from) continue;
|
|
196
|
+
let text: string;
|
|
197
|
+
try { text = readNoFollow(join(dir, name)); } catch (error) { observeFailure('query', error, { file: name }); continue; }
|
|
198
|
+
for (const line of text.split('\n')) {
|
|
199
|
+
if (!line) continue;
|
|
200
|
+
try {
|
|
201
|
+
const row = JSON.parse(line) as LaunchUtteranceStart;
|
|
202
|
+
const at = Date.parse(row.at);
|
|
203
|
+
if (row.event === 'start' && typeof row.utterance === 'string' && Number.isFinite(at) && at >= from && at <= until) rows.push(row);
|
|
204
|
+
} catch { /* skip torn line */ }
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return rows;
|
|
208
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Phase detector for implementation discipline.
|
|
2
2
|
//
|
|
3
|
-
// Given the current turn's user text, classify into one of
|
|
3
|
+
// Given the current turn's user text, classify into one of four
|
|
4
4
|
// phases. The system-prompt builder reads this result to decide
|
|
5
5
|
// which discipline guidance (if any) to inject as a system message.
|
|
6
6
|
//
|
|
@@ -8,15 +8,16 @@
|
|
|
8
8
|
// plan-loaded — PLAN-*.md / HANDOFF-*.md / SPEC-*.md file-ref
|
|
9
9
|
// OR Korean/English doc keyword (핸드오프, 플랜
|
|
10
10
|
// 문서, handoff, plan doc, 스펙 문서).
|
|
11
|
+
// design-first — implementation request contains an explicit new
|
|
12
|
+
// project, empty repository, or from-scratch signal.
|
|
11
13
|
// implementation-ready — starts with an implementation verb
|
|
12
14
|
// (구현/implement/build/포팅/port/만들어) AND
|
|
13
15
|
// NOT paired with an exploration verb
|
|
14
16
|
// (설명/분석/리뷰).
|
|
15
17
|
// idle — everything else.
|
|
16
18
|
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
// diving into edits, even if the user also said "구현해".
|
|
19
|
+
// An explicit new-project request wins over plan-loaded; otherwise the
|
|
20
|
+
// existing plan-loaded and implementation-ready precedence is unchanged.
|
|
20
21
|
|
|
21
22
|
import type { DetectInput, ImplPhase } from './types.js';
|
|
22
23
|
|
|
@@ -38,6 +39,11 @@ const DOC_KEYWORDS = [
|
|
|
38
39
|
];
|
|
39
40
|
|
|
40
41
|
const IMPL_VERB_RE = /(^|[\s\u3000])(구현|implement|build|포팅|port|만들어)/i;
|
|
42
|
+
const PROJECT_IMPL_VERB_RE = /(^|[\s\u3000])(구현|implement|build|포팅|port|개발|develop|생성|create|만들어)/i;
|
|
43
|
+
const NEW_PROJECT_SIGNAL_RE = /(?:새(?:로운)?\s*(?:저장소|프로젝트)|빈\s*저장소|(?:new|empty)\s+(?:repository|repo|project)\b)/i;
|
|
44
|
+
const FROM_SCRATCH_RE = /(?:\bfrom\s+scratch\b|처음부터)/i;
|
|
45
|
+
const PROJECT_TARGET_RE = /(?:\b(?:project|app|service)\b|프로젝트|앱|서비스|웹앱)/i;
|
|
46
|
+
const FUNCTION_TARGET_RE = /(?:함수|function|method)/i;
|
|
41
47
|
|
|
42
48
|
// Exploration verbs that, when co-occurring with an implementation
|
|
43
49
|
// verb, downgrade the turn to idle. "이 함수 구현 방식 분석해줘"
|
|
@@ -58,6 +64,12 @@ export function detectImplPhase(input: DetectInput): ImplPhase {
|
|
|
58
64
|
if (!trimmed) return 'idle';
|
|
59
65
|
const lower = trimmed.toLowerCase();
|
|
60
66
|
|
|
67
|
+
const explicitProjectScope = NEW_PROJECT_SIGNAL_RE.test(trimmed)
|
|
68
|
+
|| (FROM_SCRATCH_RE.test(trimmed) && PROJECT_TARGET_RE.test(trimmed) && !FUNCTION_TARGET_RE.test(trimmed));
|
|
69
|
+
if (explicitProjectScope && PROJECT_IMPL_VERB_RE.test(trimmed)) {
|
|
70
|
+
return 'design-first';
|
|
71
|
+
}
|
|
72
|
+
|
|
61
73
|
if (FILE_REF_RE.test(trimmed) || hasDocKeyword(lower)) {
|
|
62
74
|
return 'plan-loaded';
|
|
63
75
|
}
|
|
@@ -23,6 +23,15 @@ const PLAN_LOADED_PROMPT = `# 플랜/핸드오프 문서 참조 감지
|
|
|
23
23
|
5. "should I proceed?" 같은 열린 질문 금지 — 확정된 선택지(2~4개) 로 묻거나 plan 을 제출.
|
|
24
24
|
6. 사용자 확인이 명확히 있을 때만 Edit/Write 로 진입.`;
|
|
25
25
|
|
|
26
|
+
const DESIGN_FIRST_PROMPT = `# 새 프로젝트 구현 요청 — RFC 먼저
|
|
27
|
+
|
|
28
|
+
사용자가 새 저장소나 새 프로젝트의 구현을 요청했습니다. 앱 코드·프로젝트 설정을 쓰거나 시험을 실행하기 전에 저장소 루트에 RFC.md 초안을 작성하고 명시적 승인을 요청하세요.
|
|
29
|
+
|
|
30
|
+
1. 요청에 PLAN/HANDOFF/SPEC 문서가 있으면 먼저 읽고 RFC 초안에 목표·범위·비목표·설계·수용 기준을 반영하세요.
|
|
31
|
+
2. RFC 초안과 결정이 필요한 항목을 제시하고 승인을 요청하세요.
|
|
32
|
+
3. 승인 전에는 애플리케이션 코드·설정을 만들거나 시험을 실행하지 마세요.
|
|
33
|
+
4. 승인 뒤 RFC와 대조해 구현을 시작하세요.`;
|
|
34
|
+
|
|
26
35
|
const IMPLEMENTATION_READY_PROMPT = `# 명시적 구현 요청 감지
|
|
27
36
|
|
|
28
37
|
사용자가 구현을 요청했습니다. **구현 요청 자체가 실행 승인입니다.** 계획을 설명한 뒤 멈추지 말고, 이번 턴 안에서 실제 코드 편집(Edit/Write)까지 진행하세요.
|
|
@@ -79,6 +88,7 @@ function promptWithNativeStructure(phase: ImplPhase, enabledTools: readonly Nati
|
|
|
79
88
|
const { listNativeToolDisplayNamesByKind } = require('../native-tool-catalog.js') as typeof import('../native-tool-catalog.js');
|
|
80
89
|
const namesByKind = listNativeToolDisplayNamesByKind(enabledTools);
|
|
81
90
|
switch (phase) {
|
|
91
|
+
case 'design-first': return DESIGN_FIRST_PROMPT;
|
|
82
92
|
case 'plan-loaded': {
|
|
83
93
|
let prompt = PLAN_LOADED_PROMPT;
|
|
84
94
|
prompt = replaceDirective(prompt, '1. 먼저 Read 로 문서 전체를 읽으세요 (offset/limit 없이).', namesByKind, ['read']);
|
|
@@ -111,6 +121,7 @@ export function promptForPhase(phase: ImplPhase, options: ImplDisciplinePromptOp
|
|
|
111
121
|
}
|
|
112
122
|
switch (phase) {
|
|
113
123
|
case 'plan-loaded': return PLAN_LOADED_PROMPT;
|
|
124
|
+
case 'design-first': return DESIGN_FIRST_PROMPT;
|
|
114
125
|
case 'implementation-ready': return IMPLEMENTATION_READY_PROMPT;
|
|
115
126
|
case 'idle': return '';
|
|
116
127
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// Implementation-discipline phase types.
|
|
2
2
|
//
|
|
3
|
-
// The detector maps a user turn to one of
|
|
3
|
+
// The detector maps a user turn to one of four phases; the
|
|
4
4
|
// system-prompt builder emits different guidance per phase. State is
|
|
5
5
|
// derived per-turn (stateless) so a wrong classification self-heals
|
|
6
6
|
// on the next turn.
|
|
7
7
|
|
|
8
|
-
export type ImplPhase = 'idle' | 'plan-loaded' | 'implementation-ready';
|
|
8
|
+
export type ImplPhase = 'idle' | 'plan-loaded' | 'design-first' | 'implementation-ready';
|
|
9
9
|
|
|
10
10
|
export interface DetectInput {
|
|
11
11
|
/** Raw user text for the current turn. */
|