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
|
@@ -17,9 +17,14 @@ import { dirname, join, resolve } from 'node:path';
|
|
|
17
17
|
import { fileURLToPath } from 'node:url';
|
|
18
18
|
|
|
19
19
|
import { debug } from '../debug/log.js';
|
|
20
|
+
import { createHerdrAgentReporter, type HerdrAgentReporterLike } from './herdr-agent-report.js';
|
|
20
21
|
import { runGitCommand } from '../git-fs/runner.js';
|
|
21
22
|
import { codeRevision, packageVersion, readInstallMetadataCommit } from '../version/code-revision.js';
|
|
22
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
buildStaleInstallRelaunchCommand,
|
|
25
|
+
formatStaleInstallNotice,
|
|
26
|
+
versionedDashboardInstallDir,
|
|
27
|
+
} from '../dashboard/stale-install-check.js';
|
|
23
28
|
import {
|
|
24
29
|
updatePtyManifestBuild, updatePtyManifestTurn,
|
|
25
30
|
type PtyBuildIdentity, type PtyManifestRow, type PtyTurnState,
|
|
@@ -138,6 +143,86 @@ export function judgeBuildStaleness(input: {
|
|
|
138
143
|
return { stale: null, reason: 'unknown' };
|
|
139
144
|
}
|
|
140
145
|
|
|
146
|
+
// ── 매 턴 자기 건강 한 줄(TUI-SELF-HEALTH-LINE · 0.2.34) ──
|
|
147
|
+
//
|
|
148
|
+
// 대시보드 턴 프리앰블에 매 턴 실리는 자기 관측 한 줄: «실행 판 vs 설치본» 낡음 판정
|
|
149
|
+
// (judgeBuildStaleness ⊕ readCurrentInstallRecord — 이미 있는 실물)에 «직전 30분 자기 오류»
|
|
150
|
+
// ·«크레딧 사용» 재료를 얹는다. 낡은 판이면 재기동 필요를 말하되 안내 문면·재기동 명령은
|
|
151
|
+
// stale-install-check 의 기존 재료(formatStaleInstallNotice · buildStaleInstallRelaunchCommand)를
|
|
152
|
+
// 그대로 쓴다 — 문면을 두벌로 만들지 않는다.
|
|
153
|
+
//
|
|
154
|
+
// ⚠️ 미결(이 모듈이 정하지 않는다): ① 직전 30분 창에서 «어떤 이벤트를 자기 오류로 세는지» —
|
|
155
|
+
// 호출자가 집계해 count·sample 로 넘긴다. ② 크레딧 사용 재료를 무엇으로 잴지 — 호출자가 만든
|
|
156
|
+
// 값을 넘긴다. 두 축은 계약이 정해지는 즉시 호출부에서 주입하면 된다.
|
|
157
|
+
|
|
158
|
+
export interface SelfHealthErrors {
|
|
159
|
+
/** 직전 30분 창의 자기 오류 건수. 0 = 오류 없음. */
|
|
160
|
+
readonly count: number;
|
|
161
|
+
/** 오류를 대표하는 한 줄(첫 오류 요약 등). 없으면 개수만 말한다. */
|
|
162
|
+
readonly sample?: string;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface SelfHealthLineDeps {
|
|
166
|
+
/** 기동 판 — 기본 runningBuild(기동 때 한 번 잡힌 값). */
|
|
167
|
+
readonly build?: () => PtyBuildIdentity;
|
|
168
|
+
/** 지금 current 설치본 기록 — 기본 readCurrentInstallRecord. */
|
|
169
|
+
readonly readInstalled?: () => InstalledRecord;
|
|
170
|
+
/** 체크아웃 HEAD 재독기 — 기동 판이 checkout 일 때만 불린다. 기본 readCheckoutHead. */
|
|
171
|
+
readonly readCheckoutHead?: (codeRoot: string) => string | undefined;
|
|
172
|
+
/** 재기동 명령에 얹을 대화 id — 없으면 안내 문면만. */
|
|
173
|
+
readonly sessionId?: string;
|
|
174
|
+
/** 새 판 안내 회차(formatStaleInstallNotice notifiedCount) — 기본 1. */
|
|
175
|
+
readonly notifiedCount?: number;
|
|
176
|
+
/** 크레딧 사용 재료(호출자가 만든 값) — 없으면 그 축은 생략된다. */
|
|
177
|
+
readonly creditUsage?: string;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** 매 턴 자기 건강 한 줄. 판 축 재료가 깨져도 오류·크레딧 축은 살리고, 말할 것이 없으면 null —
|
|
181
|
+
* 줄이 턴을 막지 않는다(fail-soft). */
|
|
182
|
+
export function buildSelfHealthLine(
|
|
183
|
+
errors: SelfHealthErrors | null | undefined,
|
|
184
|
+
deps: SelfHealthLineDeps = {},
|
|
185
|
+
): string | null {
|
|
186
|
+
const segments: string[] = [];
|
|
187
|
+
try {
|
|
188
|
+
const build = (deps.build ?? runningBuild)();
|
|
189
|
+
const installed = (deps.readInstalled ?? readCurrentInstallRecord)();
|
|
190
|
+
let checkoutHead: string | undefined;
|
|
191
|
+
if (build.source === 'checkout' && build.codeRoot) {
|
|
192
|
+
checkoutHead = (deps.readCheckoutHead ?? readCheckoutHead)(build.codeRoot);
|
|
193
|
+
}
|
|
194
|
+
const staleness = judgeBuildStaleness({ build, installed, ...(checkoutHead ? { checkoutHead } : {}) });
|
|
195
|
+
segments.push(`실행 판 ${build.version}@${shortSha(build.sha)}(${build.source})`);
|
|
196
|
+
if (staleness.stale === true) {
|
|
197
|
+
const relaunch = deps.sessionId
|
|
198
|
+
? ` · 다시 띄우기: ${buildStaleInstallRelaunchCommand(deps.sessionId)}`
|
|
199
|
+
: '';
|
|
200
|
+
if (staleness.reason === 'installed-moved' && build.sha && installed.sha) {
|
|
201
|
+
segments.push(`낡은 판 — 재기동 필요: ${formatStaleInstallNotice(
|
|
202
|
+
{ state: 'changed', bootCommit: build.sha, installedCommit: installed.sha },
|
|
203
|
+
deps.notifiedCount ?? 1,
|
|
204
|
+
)}${relaunch}`);
|
|
205
|
+
} else {
|
|
206
|
+
segments.push(`낡은 판(${staleness.reason}) — 재기동 필요${relaunch}`);
|
|
207
|
+
}
|
|
208
|
+
} else if (staleness.stale === false) {
|
|
209
|
+
segments.push(`판 최신(${staleness.reason})`);
|
|
210
|
+
} else {
|
|
211
|
+
// stale=null 은 «안 낡았다»가 아니다 — 못 잼을 못 잼으로 말한다.
|
|
212
|
+
segments.push(`판 낡음 모름(${staleness.reason})`);
|
|
213
|
+
}
|
|
214
|
+
} catch {
|
|
215
|
+
// 판 축 재료가 깨져도 오류·크레딧 축은 살린다 — 관측이 턴을 막지 않는다.
|
|
216
|
+
}
|
|
217
|
+
if (errors) {
|
|
218
|
+
segments.push(errors.count > 0
|
|
219
|
+
? `직전 30분 자기 오류 ${errors.count}건${errors.sample ? ` — 대표: ${errors.sample}` : ''}`
|
|
220
|
+
: '직전 30분 자기 오류 0건');
|
|
221
|
+
}
|
|
222
|
+
if (deps.creditUsage) segments.push(`크레딧 사용 ${deps.creditUsage}`);
|
|
223
|
+
return segments.length > 0 ? `[자기 건강] ${segments.join(' · ')}` : null;
|
|
224
|
+
}
|
|
225
|
+
|
|
141
226
|
// ── 판독(CLI) ──
|
|
142
227
|
|
|
143
228
|
export type PtyTurnView = PtyTurnState | 'unknown';
|
|
@@ -230,6 +315,12 @@ export interface TuiRunStateRecorderDeps {
|
|
|
230
315
|
readonly writeBuild?: (id: string, build: PtyBuildIdentity) => boolean;
|
|
231
316
|
readonly writeTurn?: (id: string, turn: PtyTurnState, at: number) => boolean;
|
|
232
317
|
readonly log?: (event: string, data: Record<string, unknown>) => void;
|
|
318
|
+
/**
|
|
319
|
+
* herdr pane 신고기. 생략 시: `writeTurn` 을 주입하지 않은 기본 녹음기만
|
|
320
|
+
* `createHerdrAgentReporter` 를 만든다(시험이 실 herdr 를 안 건드리게).
|
|
321
|
+
* `null` 이면 신고하지 않는다.
|
|
322
|
+
*/
|
|
323
|
+
readonly herdr?: HerdrAgentReporterLike | null;
|
|
233
324
|
}
|
|
234
325
|
|
|
235
326
|
interface ActiveRecorder {
|
|
@@ -237,7 +328,11 @@ interface ActiveRecorder {
|
|
|
237
328
|
readonly now: () => number;
|
|
238
329
|
readonly writeTurn: (id: string, turn: PtyTurnState, at: number) => boolean;
|
|
239
330
|
readonly log: (event: string, data: Record<string, unknown>) => void;
|
|
331
|
+
readonly herdr: HerdrAgentReporterLike | null;
|
|
332
|
+
/** manifest 에 실제로 적힌 마지막 턴. 실패면 안 바뀐다(재시도). */
|
|
240
333
|
last?: PtyTurnState;
|
|
334
|
+
/** herdr 에 마지막으로 알린 턴. manifest 성패와 따로 둔다. */
|
|
335
|
+
herdrLast?: PtyTurnState;
|
|
241
336
|
}
|
|
242
337
|
|
|
243
338
|
let active: ActiveRecorder | null = null;
|
|
@@ -249,6 +344,10 @@ export function startTuiRunStateRecorder(surfaceId: string, deps: TuiRunStateRec
|
|
|
249
344
|
const now = deps.now ?? Date.now;
|
|
250
345
|
const log = deps.log ?? defaultLog;
|
|
251
346
|
const writeTurn = deps.writeTurn ?? updatePtyManifestTurn;
|
|
347
|
+
// 기본 신고기는 기본 manifest 쓰기와 짝일 때만. writeTurn 주입(시험)은 herdr 를 안 만든다.
|
|
348
|
+
const herdr = deps.herdr !== undefined
|
|
349
|
+
? deps.herdr
|
|
350
|
+
: (deps.writeTurn ? null : createHerdrAgentReporter({ sessionId: surfaceId }));
|
|
252
351
|
let build: PtyBuildIdentity | undefined;
|
|
253
352
|
try { build = (deps.build ?? runningBuild)(); } catch (error) {
|
|
254
353
|
log('build-resolve-failed', { ptyId: surfaceId, error: error instanceof Error ? error.message : String(error) });
|
|
@@ -257,10 +356,15 @@ export function startTuiRunStateRecorder(surfaceId: string, deps: TuiRunStateRec
|
|
|
257
356
|
const ok = (() => { try { return (deps.writeBuild ?? updatePtyManifestBuild)(surfaceId, build); } catch { return false; } })();
|
|
258
357
|
log(ok ? 'build-recorded' : 'build-write-failed', { ptyId: surfaceId, sha: build.sha, version: build.version, source: build.source });
|
|
259
358
|
}
|
|
260
|
-
|
|
359
|
+
// 기동 순서: 판 → manifest 초기 idle → herdr 신고. herdr start 가 idle 을 신고하므로 초기 idle 을 turn 으로 다시 안 보낸다.
|
|
360
|
+
const recorder: ActiveRecorder = { surfaceId, now, writeTurn, log, herdr, herdrLast: herdr ? 'idle' : undefined };
|
|
261
361
|
active = recorder;
|
|
262
362
|
writeTurnState(recorder, 'idle');
|
|
263
|
-
|
|
363
|
+
if (herdr) { try { herdr.start(); } catch { /* 신고 실패가 녹음기를 깨지 않는다 */ } }
|
|
364
|
+
return () => {
|
|
365
|
+
if (herdr) { try { herdr.release(); } catch { /* 종료 경로를 깨지 않는다 */ } }
|
|
366
|
+
if (active === recorder) active = null;
|
|
367
|
+
};
|
|
264
368
|
}
|
|
265
369
|
|
|
266
370
|
/** 대시보드가 턴 시작(busy)·끝(idle)에 부른다. 녹음기가 없으면(자기보고 꺼짐) 아무것도 안 한다. */
|
|
@@ -276,6 +380,16 @@ function writeTurnState(recorder: ActiveRecorder, turn: PtyTurnState): void {
|
|
|
276
380
|
if (ok) recorder.last = turn;
|
|
277
381
|
// 실패는 관측으로 남긴다 — 바깥 제어자는 그 사이 «unknown/낡은 값»을 본다. 성공은 남기지 않는다(턴마다 두 줄은 소음).
|
|
278
382
|
else recorder.log('turn-write-failed', { ptyId: recorder.surfaceId, turn, at });
|
|
383
|
+
// herdr 는 manifest 쓰기 성패와 무관하게, 값이 바뀔 때 알린다(같은 값 재시도는 한 번만).
|
|
384
|
+
if (recorder.herdr && recorder.herdrLast !== turn) {
|
|
385
|
+
// 신고가 동기로 던지면 «보낸 상태» 로 적지 않는다 — herdr 가 아는 값(herdrLast)과 다음 전이를 비교해 다시 보낸다(r4 리뷰 sf).
|
|
386
|
+
try {
|
|
387
|
+
recorder.herdr.turn(turn);
|
|
388
|
+
recorder.herdrLast = turn;
|
|
389
|
+
} catch (error) {
|
|
390
|
+
recorder.log('herdr-turn-threw', { turn, error: error instanceof Error ? error.message : String(error) });
|
|
391
|
+
}
|
|
392
|
+
}
|
|
279
393
|
}
|
|
280
394
|
|
|
281
395
|
export function resetTuiRunStateForTesting(): void {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
2
3
|
import { readFileSync, statSync } from 'node:fs';
|
|
3
4
|
import { isAbsolute, join } from 'node:path';
|
|
4
5
|
import * as store from './feature-store.js';
|
|
@@ -131,20 +132,77 @@ function mentionedPaths(text: string): string[] {
|
|
|
131
132
|
return [...text.matchAll(PATH_TOKEN)].map((match) => match[1]!).filter((path) => !path.split('/').includes('..'));
|
|
132
133
|
}
|
|
133
134
|
|
|
135
|
+
/** `docs/goal-context/03-verification-menu.md` §선택 원칙: merge SHA·타입검사는 수용선이 아니다. */
|
|
136
|
+
export const MERGE_OR_TYPECHECK_ONLY_REAL_WARNING = '- 완료 경계 실물: merge sha·타입검사만으로는 실물이 아니다 — docs/goal-context/03-verification-menu.md 에서 동작을 재는 방법을 고른다';
|
|
137
|
+
/** 통합 이력·정적 타입 상태만 말하는 낱말(조사 뗀 꼴). 이 밖의 낱말이 하나라도 있으면 실물 주장으로 본다. */
|
|
138
|
+
const MERGE_OR_TYPECHECK_WORD = /^(?:pr|merge|merged|머지|병합|착지|landed|land|sha|merge-sha|commit|커밋|origin|main|tsc|typecheck|type-check|typecheck-changed|타입검사|타입|검사|type|check|changed|통과|pass|passed|green|clean|errors?|error|오류|에러|없음|후|뒤|완료|확인|and|및|만|됨|된다)$/i;
|
|
139
|
+
const MERGE_OR_TYPECHECK_SIGNAL = /^(?:merge|merged|머지|병합|착지|landed|land|sha|merge-sha|tsc|typecheck|type-check|타입검사)$/i;
|
|
140
|
+
const KOREAN_PARTICLE_TAIL = /(?:했다|했음|하였다|했고|함|으로|로|이|가|은|는|을|를|와|과|에|의|만|됨|된|된다)$/u;
|
|
141
|
+
|
|
142
|
+
/** 「완료 경계 실물」 값이 merge sha·PR 착지·타입검사 낱말로만 이뤄졌나(동작 관측이 하나도 없나). */
|
|
143
|
+
export function isMergeOrTypecheckOnlyEvidence(value: string): boolean {
|
|
144
|
+
const words = value.split(/[\s.!?。…~`'"·,⊕+()[\]:;/=|→-]+/u).map((word) => word.replace(/^#/, '')).filter(Boolean);
|
|
145
|
+
if (!words.length) return false;
|
|
146
|
+
let signal = false;
|
|
147
|
+
for (const raw of words) {
|
|
148
|
+
if (/^\d+$/.test(raw) || /^[0-9a-f]{7,40}$/i.test(raw)) continue;
|
|
149
|
+
let word = raw;
|
|
150
|
+
for (let strip = 0; strip < 3 && !MERGE_OR_TYPECHECK_WORD.test(word); strip++) word = word.replace(KOREAN_PARTICLE_TAIL, '');
|
|
151
|
+
if (!MERGE_OR_TYPECHECK_WORD.test(word)) return false;
|
|
152
|
+
if (MERGE_OR_TYPECHECK_SIGNAL.test(word)) signal = true;
|
|
153
|
+
}
|
|
154
|
+
return signal;
|
|
155
|
+
}
|
|
156
|
+
|
|
134
157
|
/** Shadow check at checklist authorship. Callers supply the origin/main file probe and merged-PR file reader. */
|
|
135
158
|
export function inspectChecklistTargetPaths(input: {
|
|
136
159
|
title: string; evidence?: string; refs?: readonly string[]; dispatchKind?: ChecklistDispatchKind;
|
|
137
|
-
}, deps: { existsAtMain: (path: string) => boolean; mergedPrFiles?: (number: number) => readonly string[] }): {
|
|
160
|
+
}, deps: { existsAtMain: (path: string) => boolean; objectTypeAtMain?: (path: string) => 'blob' | 'tree' | 'commit' | 'blocked-blob' | 'blocked-gitlink' | 'unavailable' | null; mergedPrFiles?: (number: number) => readonly string[] }): {
|
|
138
161
|
targets: string[]; warnings: string[]; candidates: string[];
|
|
139
162
|
} {
|
|
140
163
|
const lines = input.title.split(/\r?\n/);
|
|
141
164
|
const first = /^대상 경로:\s*(.*)$/.exec(lines[0] ?? '');
|
|
142
|
-
const
|
|
143
|
-
const
|
|
165
|
+
const rawTargets = first?.[1]?.split(' · ').map((path) => path.trim()) ?? [];
|
|
166
|
+
const validPath = (path: string): boolean => path.length > 0 && path.length < 4096
|
|
167
|
+
&& !path.startsWith('/') && !path.includes('\\') && !/[\u0000-\u001f\u007f]/u.test(path)
|
|
168
|
+
&& path.split('/').every((segment) => segment !== '' && segment !== '.' && segment !== '..');
|
|
169
|
+
const targets = [...new Set(rawTargets.filter(validPath))];
|
|
170
|
+
const misplacedNewFiles = lines.slice(2).filter((line) => /^신설:\s*/.test(line));
|
|
171
|
+
const rawNewFiles = lines.slice(1, 2).filter((line) => /^신설:\s*/.test(line))
|
|
172
|
+
.flatMap((line) => line.slice('신설:'.length).split(' · ').map((path) => path.trim()));
|
|
173
|
+
const newFiles = new Set(rawNewFiles.filter(validPath));
|
|
144
174
|
const warnings: string[] = [];
|
|
145
175
|
if ((input.dispatchKind ?? 'code') === 'code') {
|
|
146
|
-
if (!first || !first[1]!.trim()
|
|
147
|
-
|
|
176
|
+
if (!first || !first[1]!.trim()) warnings.push('첫 줄 대상 경로가 없다');
|
|
177
|
+
else if (targets.length !== rawTargets.length || targets.length === 0) warnings.push('첫 줄은 실제 파일 경로만 « · »로 구분한다');
|
|
178
|
+
if (misplacedNewFiles.length) warnings.push('신설: 선언은 제목 둘째 줄에만 둔다');
|
|
179
|
+
for (const path of rawNewFiles) if (!validPath(path)) warnings.push(`신설: ${path || '(빈 항목)'}: 정확한 새 파일 경로가 아니다`);
|
|
180
|
+
for (const path of targets) {
|
|
181
|
+
const objectType = deps.objectTypeAtMain?.(path);
|
|
182
|
+
const exists = objectType ? objectType === 'blob' : deps.existsAtMain(path);
|
|
183
|
+
if (objectType === 'unavailable') warnings.push(`${path}: origin/main Git 조회 실패 · 대상 검증 불가`);
|
|
184
|
+
if (objectType === 'tree' || objectType === 'commit') warnings.push(`${path}: origin/main의 ${objectType === 'tree' ? '디렉터리' : 'gitlink'}는 파일 대상이 아니다`);
|
|
185
|
+
if (objectType === 'blocked-blob' || objectType === 'blocked-gitlink')
|
|
186
|
+
warnings.push(`${path}: origin/main의 상위 ${objectType === 'blocked-blob' ? '파일' : 'gitlink'} 아래에는 신설할 수 없다`);
|
|
187
|
+
if (!exists && !newFiles.has(path)) warnings.push(`${path}: origin/main에 없는 파일 · 신설: 줄에 해당 경로 선언 필요`);
|
|
188
|
+
if (exists && newFiles.has(path)) warnings.push(`${path}: 이미 있는 파일은 신설:에서 뺀다`);
|
|
189
|
+
}
|
|
190
|
+
for (const path of newFiles) if (!targets.includes(path)) warnings.push(`${path}: 신설: 경로가 첫 줄 대상에 없다`);
|
|
191
|
+
for (const path of newFiles) {
|
|
192
|
+
const objectType = deps.objectTypeAtMain?.(path);
|
|
193
|
+
if (objectType === 'unavailable' && !targets.includes(path))
|
|
194
|
+
warnings.push(`${path}: origin/main Git 조회 실패 · 신설 검증 불가`);
|
|
195
|
+
if ((objectType === 'tree' || objectType === 'commit') && !targets.includes(path))
|
|
196
|
+
warnings.push(`${path}: origin/main의 ${objectType === 'tree' ? '디렉터리' : 'gitlink'}는 신설 파일이 아니다`);
|
|
197
|
+
if ((objectType === 'blocked-blob' || objectType === 'blocked-gitlink') && !targets.includes(path))
|
|
198
|
+
warnings.push(`${path}: origin/main의 상위 ${objectType === 'blocked-blob' ? '파일' : 'gitlink'} 아래에는 신설할 수 없다`);
|
|
199
|
+
}
|
|
200
|
+
for (const label of ['코드', '실물', '증거 명령']) {
|
|
201
|
+
if (!lines.some((line) => line.startsWith(`- 완료 경계 ${label}:`) && line.slice(`- 완료 경계 ${label}:`.length).trim()))
|
|
202
|
+
warnings.push(`- 완료 경계 ${label}: 줄이 없다`);
|
|
203
|
+
}
|
|
204
|
+
const real = lines.find((line) => line.startsWith('- 완료 경계 실물:'))?.slice('- 완료 경계 실물:'.length).trim();
|
|
205
|
+
if (real && isMergeOrTypecheckOnlyEvidence(real)) warnings.push(MERGE_OR_TYPECHECK_ONLY_REAL_WARNING);
|
|
148
206
|
}
|
|
149
207
|
if (!warnings.length) return { targets, warnings, candidates: [] };
|
|
150
208
|
const sources = [input.title, input.evidence ?? '', ...(input.refs ?? [])].join('\n');
|
|
@@ -302,6 +360,46 @@ export function setItem(v: string, id: string, patch: { status?: ChecklistStatus
|
|
|
302
360
|
return setItemGuarded(v, id, patch, by);
|
|
303
361
|
}
|
|
304
362
|
|
|
363
|
+
/** Remove only the exact machine-authored line; preserve all other evidence bytes and blank lines. */
|
|
364
|
+
export function withoutDispatchSkipLine(evidence: string, line: string | null): string {
|
|
365
|
+
if (!line) return evidence;
|
|
366
|
+
if (evidence === line) return '';
|
|
367
|
+
if (evidence.endsWith(`\n${line}`)) return evidence.slice(0, -line.length - 1);
|
|
368
|
+
if (evidence.startsWith(`${line}\n`)) return evidence.slice(line.length + 1);
|
|
369
|
+
return evidence.replace(`\n${line}\n`, '\n');
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/** Record one dispatcher refusal on the same title snapshot, without overwriting a person's evidence. */
|
|
373
|
+
export function noteDispatchSkip(v: string, id: string, reason: string, expectedTitle: string, by: string): Checklist {
|
|
374
|
+
if (!by.trim()) throw new CliUserError('건너뜀 기록 주체가 비었다');
|
|
375
|
+
const detail = reason.replace(/[\r\n\t]+/g, ' ').trim().slice(0, 300);
|
|
376
|
+
if (!detail) throw new CliUserError('건너뜀 사유가 비었다');
|
|
377
|
+
return mutate(v, (data) => {
|
|
378
|
+
const item = data.items.find((entry) => entry.id === id);
|
|
379
|
+
if (!item) throw new CliUserError(`없는 칸: ${id}`);
|
|
380
|
+
if (item.title !== expectedTitle) throw new CliUserError(`칸 제목이 바뀌어 건너뜀 근거를 기록하지 않았다: ${id}`);
|
|
381
|
+
const marker = createHash('sha256').update(`${v}\0${id}\0${expectedTitle}`).digest('hex').slice(0, 16);
|
|
382
|
+
const line = `디스패처 건너뜀 [${marker}]: ${detail}`;
|
|
383
|
+
const prior = item.evidence ?? '';
|
|
384
|
+
const previous = data.history.filter((entry) => entry.id === id && entry.field === 'dispatch-skip').at(-1)?.to;
|
|
385
|
+
const oldLine = typeof previous === 'string' ? previous : null;
|
|
386
|
+
if (oldLine === line && prior.split(/\r?\n/).includes(line)) return false;
|
|
387
|
+
const priorLines = prior.split('\n');
|
|
388
|
+
const oldIndex = oldLine ? priorLines.findIndex((entry) => entry.replace(/\r$/, '') === oldLine) : -1;
|
|
389
|
+
const next = oldIndex >= 0
|
|
390
|
+
? priorLines.map((entry, index) => index === oldIndex ? entry.replace(oldLine!, line) : entry).join('\n')
|
|
391
|
+
: prior ? `${prior}\n${line}` : line;
|
|
392
|
+
if (next === prior) return false;
|
|
393
|
+
const at = new Date().toISOString();
|
|
394
|
+
item.evidence = next;
|
|
395
|
+
item.updatedAt = at;
|
|
396
|
+
item.updatedBy = by;
|
|
397
|
+
change(data, id, 'evidence', prior, next, by, at);
|
|
398
|
+
change(data, id, 'dispatch-skip', oldLine, line, by, at);
|
|
399
|
+
return true;
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
|
|
305
403
|
/** Apply a measured verdict only while the release cell is still the snapshot that was judged. */
|
|
306
404
|
export function setItemIfSnapshot(v: string, id: string, patch: Parameters<typeof setItem>[2], by: string, expected: Pick<ChecklistItem, 'title' | 'status' | 'evidence'>): Checklist {
|
|
307
405
|
return setItemGuarded(v, id, patch, by, expected);
|
|
@@ -8,7 +8,7 @@ import { CliUserError } from '../cli/cli-user-error.js';
|
|
|
8
8
|
import { debug } from '../debug/log.js';
|
|
9
9
|
import { getUserConfig } from '../user-config.js';
|
|
10
10
|
import { hqSeenGenerationPath, readHqLease, readSeenGeneration } from '../hq/hq.js';
|
|
11
|
-
import { devVersion, type Checklist, type ChecklistHistory, type ChecklistItem } from './checklist.js';
|
|
11
|
+
import { devVersion, withoutDispatchSkipLine, type Checklist, type ChecklistHistory, type ChecklistItem } from './checklist.js';
|
|
12
12
|
|
|
13
13
|
export function validateVersion(version: string): void {
|
|
14
14
|
if (!/^\d+\.\d+\.\d+(?:-(?:rc|alpha|beta)\.\d+)?$/.test(version)) throw new CliUserError(`체크리스트 판이 아니다: ${version}`);
|
|
@@ -487,7 +487,7 @@ export function move(id: string, from: string, to: string, by: string, released
|
|
|
487
487
|
return result;
|
|
488
488
|
} finally { db.close(); }
|
|
489
489
|
}
|
|
490
|
-
export function retitle(id: string, title: string, by: string, released = releasedVersion(), dev = devVersion()): void {
|
|
490
|
+
export function retitle(id: string, title: string, by: string, released = releasedVersion(), dev = devVersion(), validate?: (item: ChecklistItem, version: string) => void): void {
|
|
491
491
|
if (!title.trim()) throw new CliUserError('칸 제목이 비었다');
|
|
492
492
|
importLegacyAll();
|
|
493
493
|
const db = open();
|
|
@@ -500,10 +500,27 @@ export function retitle(id: string, title: string, by: string, released = releas
|
|
|
500
500
|
if (!versions.length) throw new CliUserError(`없는 칸: ${id}`);
|
|
501
501
|
const changed = versions.filter((row) => row.title !== title);
|
|
502
502
|
if (!changed.length && old.title === title) return false;
|
|
503
|
+
// Retitle changes every assignment for this id. Validate every affected
|
|
504
|
+
// version under the same transaction before the first title write.
|
|
505
|
+
for (const { version } of changed) {
|
|
506
|
+
const item = snapshot(db, version, released, dev).items.find((entry) => entry.id === id);
|
|
507
|
+
if (item) validate?.(item, version);
|
|
508
|
+
}
|
|
503
509
|
const at = new Date().toISOString();
|
|
504
510
|
db.query('UPDATE features SET title = ? WHERE id = ?').run(title, id);
|
|
505
511
|
db.query('UPDATE assignments SET title_override = NULL WHERE feature_id = ?').run(id);
|
|
506
512
|
for (const { version, title: previousTitle } of changed) {
|
|
513
|
+
const raw = db.query('SELECT evidence FROM assignments WHERE feature_id = ? AND version = ?').get(id, version) as { evidence: string | null };
|
|
514
|
+
const last = db.query('SELECT "to" AS value FROM events WHERE feature_id = ? AND version = ? AND field = ? ORDER BY seq DESC LIMIT 1')
|
|
515
|
+
.get(id, version, 'dispatch-skip') as { value: string | null } | null;
|
|
516
|
+
const managedLine = last?.value ? JSON.parse(last.value) as string | null : null;
|
|
517
|
+
const priorEvidence = raw.evidence ?? '';
|
|
518
|
+
const nextEvidence = withoutDispatchSkipLine(priorEvidence, managedLine);
|
|
519
|
+
if (nextEvidence !== priorEvidence) {
|
|
520
|
+
db.query('UPDATE assignments SET evidence = ? WHERE feature_id = ? AND version = ?').run(nextEvidence || null, id, version);
|
|
521
|
+
record(db, version, { at, by, id, field: 'evidence', from: priorEvidence, to: nextEvidence, released, dev });
|
|
522
|
+
record(db, version, { at, by, id, field: 'dispatch-skip', from: managedLine, to: null, released, dev });
|
|
523
|
+
}
|
|
507
524
|
db.query('UPDATE assignments SET updated_at = ?, updated_by = ? WHERE feature_id = ? AND version = ?').run(at, by, id, version);
|
|
508
525
|
record(db, version, { at, by, id, field: 'title', from: previousTitle, to: title, released, dev });
|
|
509
526
|
}
|
|
@@ -23,9 +23,64 @@ export function evidencePlan(rows: readonly LandedButYellowRow[]): Array<{ id: s
|
|
|
23
23
|
}));
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
interface PrIndex {
|
|
27
|
+
/** Shape of the list when indexed — a mismatch means the caller changed the array in place. */
|
|
28
|
+
length: number;
|
|
29
|
+
firstNumber: number | undefined;
|
|
30
|
+
lastNumber: number | undefined;
|
|
31
|
+
/** PR positions per body `칸:` line id — the whole-line label the matcher accepts. */
|
|
32
|
+
cellIds: Map<string, number[]>;
|
|
33
|
+
/** PR positions per maximal ASCII-alphanumeric run in the title or body. */
|
|
34
|
+
runs: Map<string, number[]>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const ALNUM_RUN = /[A-Za-z0-9]+/g;
|
|
38
|
+
const CELL_LINE = /^[ \t]*칸(?:[ \t]*:[ \t]*|[ \t]+)([A-Za-z0-9_-]+(?:[ \t]*,[ \t]*[A-Za-z0-9_-]+)*)[ \t]*$/;
|
|
39
|
+
const prIndexes = new WeakMap<readonly MergedChecklistPr[], PrIndex>();
|
|
40
|
+
|
|
41
|
+
function push(map: Map<string, number[]>, key: string, position: number): void {
|
|
42
|
+
const list = map.get(key);
|
|
43
|
+
if (!list) map.set(key, [position]);
|
|
44
|
+
else if (list[list.length - 1] !== position) list.push(position);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Built once per PR list (the open audit reuses one list across every version). Contract: callers treat the list as
|
|
49
|
+
* read-only after passing it. A cheap guard still re-indexes when the length or the first/last PR number changed;
|
|
50
|
+
* an in-place edit that keeps all three is not detected.
|
|
51
|
+
*/
|
|
52
|
+
function prIndex(prs: readonly MergedChecklistPr[]): PrIndex {
|
|
53
|
+
const cached = prIndexes.get(prs);
|
|
54
|
+
if (cached && cached.length === prs.length && cached.firstNumber === prs[0]?.number && cached.lastNumber === prs[prs.length - 1]?.number) return cached;
|
|
55
|
+
const index: PrIndex = { length: prs.length, firstNumber: prs[0]?.number, lastNumber: prs[prs.length - 1]?.number, cellIds: new Map(), runs: new Map() };
|
|
56
|
+
prs.forEach((pr, position) => {
|
|
57
|
+
const body = pr.body ?? '';
|
|
58
|
+
for (const line of body.split('\n')) {
|
|
59
|
+
const match = CELL_LINE.exec(line.endsWith('\r') ? line.slice(0, -1) : line);
|
|
60
|
+
for (const candidate of match?.[1]?.split(',') ?? []) push(index.cellIds, candidate.trim(), position);
|
|
61
|
+
}
|
|
62
|
+
for (const text of [pr.title, body]) for (const [run] of text.matchAll(ALNUM_RUN)) push(index.runs, run, position);
|
|
63
|
+
});
|
|
64
|
+
prIndexes.set(prs, index);
|
|
65
|
+
return index;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* PRs that can match `id` at all — a necessary condition, never a verdict. Every non-cell-line basis needs `id`
|
|
70
|
+
* in the title or body with no ASCII letter/digit on either side, so its leading alphanumeric run appears there
|
|
71
|
+
* as a maximal run. Ids that do not start with a letter or digit fall back to every PR.
|
|
72
|
+
*/
|
|
73
|
+
function candidatePositions(index: PrIndex, id: string, total: number): number[] {
|
|
74
|
+
const lead = /^[A-Za-z0-9]+/.exec(id)?.[0];
|
|
75
|
+
if (!lead) return Array.from({ length: total }, (_, position) => position);
|
|
76
|
+
const merged = new Set([...(index.cellIds.get(id) ?? []), ...(index.runs.get(lead) ?? [])]);
|
|
77
|
+
return [...merged].sort((a, b) => a - b);
|
|
78
|
+
}
|
|
79
|
+
|
|
26
80
|
/** Prefer a dedicated body cell line over title evidence; incidental mentions only qualify for long ids. */
|
|
27
81
|
export function landedButYellow(items: readonly ChecklistItem[], prs: readonly MergedChecklistPr[], { owner }: { owner?: string } = {}): LandedButYellowRow[] {
|
|
28
82
|
const rows: LandedButYellowRow[] = [];
|
|
83
|
+
const index = prIndex(prs);
|
|
29
84
|
for (const item of items) {
|
|
30
85
|
if (item.status !== 'yellow' && item.status !== 'red') continue;
|
|
31
86
|
if (owner !== undefined && !ownerMatches(item.owner, owner)) continue;
|
|
@@ -37,11 +92,10 @@ export function landedButYellow(items: readonly ChecklistItem[], prs: readonly M
|
|
|
37
92
|
: new RegExp(`^${id}(?:\\s|$)`);
|
|
38
93
|
const explicitTitle = new RegExp(`(?<![A-Za-z0-9])${id}\\s+(?:수확|(?:첫|둘째|셋째)\\s*조각)(?![A-Za-z0-9가-힣])|\\(${id}\\)`);
|
|
39
94
|
const rank: Record<PrMatchBasis, number> = { 'cell-line': 0, 'title-strong': 1, mention: 2 };
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
});
|
|
95
|
+
const cellLines = new Set(index.cellIds.get(item.id) ?? []);
|
|
96
|
+
const matched = candidatePositions(index, item.id, prs.length).flatMap((position) => {
|
|
97
|
+
const pr = prs[position]!;
|
|
98
|
+
const cellLine = cellLines.has(position);
|
|
45
99
|
const basis: PrMatchBasis | undefined = cellLine ? 'cell-line'
|
|
46
100
|
: titleStart.test(pr.title) || explicitTitle.test(pr.title) ? 'title-strong'
|
|
47
101
|
: !shortId && (word.test(pr.title) || word.test(pr.body ?? '')) ? 'mention' : undefined;
|
|
@@ -58,3 +112,73 @@ export function landedButYellow(items: readonly ChecklistItem[], prs: readonly M
|
|
|
58
112
|
}
|
|
59
113
|
return rows.sort((a, b) => Number(b.newer) - Number(a.newer));
|
|
60
114
|
}
|
|
115
|
+
|
|
116
|
+
export interface MergedPrRunResult { status: number | null; stdout: string; stderr: string }
|
|
117
|
+
/** One `gh` invocation; resolves when the process exits. */
|
|
118
|
+
export type MergedPrRunner = (command: string, args: readonly string[], cwd: string) => Promise<MergedPrRunResult>;
|
|
119
|
+
|
|
120
|
+
export const MERGED_PR_LIMIT = 400;
|
|
121
|
+
/** Concurrent `gh pr list` calls once the first page is full (LANDED-YELLOW-FAST · 10-21 prod: 24 sequential calls ≈ 145s). */
|
|
122
|
+
export const MERGED_PR_CONCURRENCY = 6;
|
|
123
|
+
const DAY_MS = 86_400_000;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Merged PRs since `since` (UTC date). One call answers when it returns fewer than the cap. Otherwise the range
|
|
127
|
+
* splits into UTC-day windows fetched with a concurrency cap; a full window is halved down to one second as before,
|
|
128
|
+
* and a full one-second window probes one extra row to tell exactly 400 from truncation.
|
|
129
|
+
* The returned set and the truncation flag match the former sequential bisection; only call shape and time differ.
|
|
130
|
+
*/
|
|
131
|
+
export async function fetchMergedChecklistPrs(since: string, now: Date, run: MergedPrRunner, cwd: string,
|
|
132
|
+
{ concurrency = MERGED_PR_CONCURRENCY }: { concurrency?: number } = {}): Promise<{ prs: MergedChecklistPr[]; truncated: boolean; calls: number }> {
|
|
133
|
+
let calls = 0;
|
|
134
|
+
const fetch = async (lower: string, upper?: string, limit = MERGED_PR_LIMIT): Promise<MergedChecklistPr[]> => {
|
|
135
|
+
const search = `merged:>=${lower}${upper ? ` merged:<${upper}` : ''}`;
|
|
136
|
+
calls++;
|
|
137
|
+
const r = await run('gh', ['pr', 'list', '--state', 'merged', '--search', search, '--limit', String(limit), '--json', 'number,title,body,mergedAt'], cwd);
|
|
138
|
+
if (r.status !== 0) throw new Error(`병합 PR 조회(gh) 실패 rc=${r.status}: ${(r.stderr || r.stdout).trim().slice(0, 400)}`);
|
|
139
|
+
const page = JSON.parse(r.stdout.trim()) as MergedChecklistPr[];
|
|
140
|
+
if (!Array.isArray(page)) throw new Error('병합 PR 조회(gh): 배열이 아니다');
|
|
141
|
+
return page;
|
|
142
|
+
};
|
|
143
|
+
const first = await fetch(since);
|
|
144
|
+
if (first.length < MERGED_PR_LIMIT) return { prs: first, truncated: false, calls };
|
|
145
|
+
// Bounded pool: at most `concurrency` gh processes at once; a failure stops new calls and rejects.
|
|
146
|
+
let active = 0;
|
|
147
|
+
let failed: unknown;
|
|
148
|
+
const waiting: Array<() => void> = [];
|
|
149
|
+
const limited = async <T>(task: () => Promise<T>): Promise<T> => {
|
|
150
|
+
while (active >= Math.max(1, concurrency) && failed === undefined) await new Promise<void>((resolve) => waiting.push(resolve));
|
|
151
|
+
if (failed !== undefined) throw failed;
|
|
152
|
+
active++;
|
|
153
|
+
try { return await task(); }
|
|
154
|
+
catch (error) { failed ??= error; throw error; }
|
|
155
|
+
finally { active--; if (failed !== undefined) for (const wake of waiting.splice(0)) wake(); else waiting.shift()?.(); }
|
|
156
|
+
};
|
|
157
|
+
let truncated = false;
|
|
158
|
+
const visit = async (start: number, end: number): Promise<MergedChecklistPr[]> => {
|
|
159
|
+
const from = new Date(start).toISOString();
|
|
160
|
+
const to = new Date(end).toISOString();
|
|
161
|
+
const page = await limited(() => fetch(from, to));
|
|
162
|
+
if (page.length < MERGED_PR_LIMIT) return page;
|
|
163
|
+
if (end - start <= 1000) {
|
|
164
|
+
// The second-precision search cannot be subdivided; probe one extra row to distinguish exactly 400 from a real truncation.
|
|
165
|
+
const probe = await limited(() => fetch(from, to, MERGED_PR_LIMIT + 1));
|
|
166
|
+
if (probe.length > MERGED_PR_LIMIT) truncated = true;
|
|
167
|
+
return probe.slice(0, MERGED_PR_LIMIT);
|
|
168
|
+
}
|
|
169
|
+
const middle = start + Math.floor((end - start) / 2000) * 1000;
|
|
170
|
+
const [left, right] = await Promise.all([visit(start, middle), visit(middle, end)]);
|
|
171
|
+
return [...left, ...right];
|
|
172
|
+
};
|
|
173
|
+
const lower = Date.parse(`${since}T00:00:00Z`);
|
|
174
|
+
const upper = Math.max(lower + 1000, Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1));
|
|
175
|
+
const windows: Array<[number, number]> = [];
|
|
176
|
+
for (let start = lower; start < upper; start += DAY_MS) windows.push([start, Math.min(start + DAY_MS, upper)]);
|
|
177
|
+
const settled = await Promise.allSettled(windows.map(([start, end]) => visit(start, end)));
|
|
178
|
+
const rejected = settled.find((result): result is PromiseRejectedResult => result.status === 'rejected');
|
|
179
|
+
if (rejected) throw failed ?? rejected.reason;
|
|
180
|
+
// Chronological window order, first occurrence wins — the same de-duplication as before.
|
|
181
|
+
const unique = new Map<number, MergedChecklistPr>();
|
|
182
|
+
for (const result of settled) for (const pr of (result as PromiseFulfilledResult<MergedChecklistPr[]>).value) if (!unique.has(pr.number)) unique.set(pr.number, pr);
|
|
183
|
+
return { prs: [...unique.values()], truncated, calls };
|
|
184
|
+
}
|
|
@@ -209,6 +209,7 @@ export async function runLightRc(version: string, opts: LightRcOptions = {}, dep
|
|
|
209
209
|
};
|
|
210
210
|
const captured: Buffer[] = [];
|
|
211
211
|
const rc = await (deps.dispatch ?? dispatchHeavyCheck)({
|
|
212
|
+
// Keep the self-gate contract: an unavailable remote leaves this release check unmeasured; do not start a heavy gate locally.
|
|
212
213
|
tool: 'self-gate', repo: cwd, installPwa: true, refs: [base], json: true, commit: measuredCommit,
|
|
213
214
|
// The host re-runs this command with --local (and ELANOUS_GATE_REMOTE_CHILD=1), so it never recurses.
|
|
214
215
|
remoteArgv: (sha) => ['bun', 'bin/elanous.mjs', 'release', 'light-rc', '--version', version, '--base', sha(base), '--head', measuredCommit, '--shards', String(shards), ...(opts.fixedShardDistribution ? ['--fixed-shard-distribution'] : []), '--local', '--json', ...(opts.rehearsalTui ? ['--rehearsal-tui'] : [])],
|
|
@@ -6,7 +6,7 @@ import { resolveRepositoryName } from '../harness/repository-name.js';
|
|
|
6
6
|
import { getElanousConfigDirOverride } from '../elanous-config-dir.js';
|
|
7
7
|
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
8
8
|
import { userConfigPath } from '../user-config.js';
|
|
9
|
-
import { addItem, checklistHistory,
|
|
9
|
+
import { addItem, checklistHistory, listChecklist, ownerMatches, parseOwner, setItem, validateCeoLoad, type ChecklistItem } from './checklist.js';
|
|
10
10
|
import { assignedVersions, move, releasedVersion } from './feature-store.js';
|
|
11
11
|
import { debug } from '../debug/log.js';
|
|
12
12
|
import { kstDay, listSchedules, type ReleaseSchedule } from './release-schedule.js';
|
|
@@ -455,8 +455,15 @@ export function planPullForward(deps: PullForwardDeps): RebalanceResult {
|
|
|
455
455
|
else incomplete.add(item.id);
|
|
456
456
|
}
|
|
457
457
|
const targetPathsReady = (title: string): boolean => {
|
|
458
|
-
const
|
|
459
|
-
|
|
458
|
+
const lines = title.split(/\r?\n/);
|
|
459
|
+
const first = /^대상 경로:\s*(.*)$/.exec(lines[0] ?? '');
|
|
460
|
+
if (!first) return false;
|
|
461
|
+
// Pull-forward reads existing cells. Preserve its original path token and
|
|
462
|
+
// second-line 신설: rules; strict authoring has a separate, richer contract.
|
|
463
|
+
const paths = [...first[1]!.matchAll(/(?:^|[^A-Za-z0-9_.\/-])((?:(?:[A-Za-z0-9_.-]+\/)+)?[A-Za-z0-9_.-]+\.(?:ts|tsx|js|jsx|mjs|cjs|json|md|yaml|yml|sh|py|css|html|toml|sql|rs|swift))(?![A-Za-z0-9_.\/-])/g)]
|
|
464
|
+
.map((match) => match[1]!).filter((path) => !path.split('/').includes('..'));
|
|
465
|
+
const legacyNewFile = /^신설:\s*/.test(lines[1] ?? '');
|
|
466
|
+
return paths.length > 0 && paths.every((path) => deps.targetPathExists(path) || legacyNewFile);
|
|
460
467
|
};
|
|
461
468
|
const candidates = snapshots.get(source.version)!.filter((item) =>
|
|
462
469
|
(item.priority === 'P0' || item.priority === 'P1') && item.status !== 'green' && item.status !== 'done'
|