elanous 0.2.28 → 0.2.29
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/{y1ltt7oCZxVpC6zVPhZ2O → cIpv5nU9AycwYWZI9H589}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{ab4d57c2.e90bc2cb31949045.js → 058a98ba.7eb28d5e6dc03565.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4565-67e4c620597965c8.js → 1015-9cba22a5a4554797.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +8 -0
- package/apps/pwa/out/_next/static/chunks/{1516.83dd2c1b86b4e507.js → 1142.65d002789ab3af7d.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +34 -0
- package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1516.dfaceff3fd2d0e0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +286 -0
- package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +24 -0
- package/apps/pwa/out/_next/static/chunks/1782-59db1b5aa06df38a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1743.563d3168e95825ef.js → 1852.7f7b53991fcb99ef.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +36 -0
- package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +64 -0
- package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +1 -0
- package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{65ebff95.081daeff622d238e.js → 285adb1a.5654e605dddf86d2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +115 -0
- package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3160-95c96f4d2a21dd26.js +1 -0
- package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +90 -0
- package/apps/pwa/out/_next/static/chunks/328bb3ab-6628a1114fe3fb3b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9917-9e26abc5f7772735.js → 3396-97b97928c49190c9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6196.34d6b229079e9e28.js → 3403.7199205e65124486.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +1 -0
- package/apps/pwa/out/_next/static/chunks/419.736c0d6f426249a7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6def8a8e.c81f9ca41028eccf.js → 425cfc4d.fb91158e3971c39f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{16e57f67.3ea19e893461e611.js → 46bd8bea.2f4b4099172fcdb7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5081.a240b63fad28663a.js → 4759.1f76713aefb87db5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +94 -0
- package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +62 -0
- package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +27 -0
- package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +104 -0
- package/apps/pwa/out/_next/static/chunks/{9974.e77b4ff4884557b3.js → 5591.a35e7a217734a8b9.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +93 -0
- package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5492-e05e26a033ba80d2.js → 6013-2f769370d8b4c2c6.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +24 -0
- package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +2 -0
- package/apps/pwa/out/_next/static/chunks/{5408.377c8c543635b81f.js → 6534.1ab00f370db7b105.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +148 -0
- package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +149 -0
- package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +79 -0
- package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8578.dff22d988cc2b106.js → 6767.1fcfc9b8be83975f.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/6776.06ff1e3b464cc607.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9311.24c8f5ea793253dd.js → 6853.cc5174a9dee59593.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +287 -0
- package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{94.4cfed21c0b781a06.js → 7375.050ea0d72968e49f.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +77 -0
- package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +74 -0
- package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7725-4f83d5541fbdb81b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8332.6f0f49df772e163b.js +23 -0
- package/apps/pwa/out/_next/static/chunks/{7483.ba01c6c209b81bba.js → 8398.73a19b39715eda04.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2846.d6a433b8663819a5.js → 8471.8d2a8c74f09c36ff.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +226 -0
- package/apps/pwa/out/_next/static/chunks/{5785-ea8d2c633b6688e3.js → 8767-2f6a634f5abeaa01.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +32 -0
- package/apps/pwa/out/_next/static/chunks/8795.32573a185af18c7b.js +41 -0
- package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4593.10f5b9bd702d4a6c.js → 9143.ff14585db1d275ff.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4204.a409ab6250c0f6a8.js → 9907.49be0fcadaf214b5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{973cbf1b.3bbcf2b41548eca7.js → a435ad95.577add051b4facb2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-fa46d4588e8442c2.js → page-a5635eba0d73b84e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/{page-66ad46ed0279feb9.js → page-86feb08080261a2f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/{page-646b50f63b6fe732.js → page-8aaa6dedc4c10dfb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/{page-6f131b51193a36f9.js → page-33bf667a5fb297bf.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-29900ed0011b2c83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-9eb56166774eb256.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9f92737b8766009a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{f4dfbfc0.a69fb12f854882aa.js → bc324b7c.02a09dd93f6a399b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +1 -0
- package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +1 -0
- package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +122 -0
- package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.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/graphs/release/release-loop.yaml +6 -2
- package/package.json +1 -1
- package/plugins/agent-team/agents/research.md +1 -0
- package/scripts/ci-typecheck-changed.ts +3 -2
- package/scripts/coord-channel-watch.sh +26 -6
- package/scripts/coord-role-pack.ts +143 -0
- package/scripts/lib/morning-report-options.ts +41 -0
- package/scripts/pr-land-extra-remote-gates.ts +49 -0
- package/scripts/release-loop/gate-batch-safe.ts +23 -0
- package/scripts/release-loop/gate-history.ts +422 -0
- package/scripts/release-loop/gate-node.ts +310 -46
- package/scripts/release-loop/gate-triage-node.ts +190 -0
- package/scripts/release-loop/spawn-lane.ts +68 -0
- package/scripts/release-loop/tui-node-checks.ts +23 -0
- package/scripts/release-loop/version-node.ts +62 -4
- package/scripts/test-deterministic.ts +41 -12
- package/scripts/usage-rollup.ts +11 -3
- package/src/acp/core-turn-bridge.ts +98 -22
- package/src/acp/elanous-extensions.ts +2 -0
- package/src/acp/server.ts +2 -0
- package/src/agent/ref-grounding.ts +18 -0
- package/src/agent-substrate/pr-reviewer.ts +29 -21
- package/src/budget/pty-usage-reemit.ts +7 -0
- package/src/budget/run-usage-rollup.ts +9 -0
- package/src/budget/usage-daily-store.ts +98 -0
- package/src/capture/tui-self-report.ts +22 -4
- package/src/chat/index.ts +31 -10
- package/src/chat/pickers/modal-runtime.ts +1 -0
- package/src/chat/pickers/modals.ts +3 -1
- package/src/chat/turn-typeahead.ts +123 -16
- package/src/cli/dashboard-name-flag.ts +48 -0
- package/src/cli/doctor-cli.ts +80 -0
- package/src/cli/log-event-names.ts +12 -0
- package/src/cli/msg-cli.ts +45 -2
- package/src/cli/pr-cli.ts +382 -105
- package/src/cli/pr-land-heavy-remote.ts +233 -0
- package/src/cli/pr-land-overlap-evidence.ts +104 -5
- package/src/cli/pty-takeover-cli.ts +125 -16
- package/src/cli/release-cli.ts +44 -2
- package/src/cli/remote-resolve.ts +2 -1
- package/src/cli/seat-cli.ts +26 -16
- package/src/cli/tasks-cli.ts +8 -2
- package/src/cli/usage-cli.ts +146 -12
- package/src/cli/usage-daily-cli.ts +84 -0
- package/src/context-bus/context-now.ts +82 -5
- package/src/core-turn/auth-rejected-notice.ts +41 -0
- package/src/core-turn/run-core-turn.ts +13 -2
- package/src/core-turn/run-goal-loop.ts +17 -1
- package/src/core-turn/short-question.ts +45 -12
- package/src/core-turn/types.ts +7 -0
- package/src/dashboard/acp-active-model.ts +40 -0
- package/src/dashboard/auto-compact-runtime.ts +2 -0
- package/src/dashboard/boot-banner.ts +80 -0
- package/src/dashboard/dashboard-status-lines.ts +11 -0
- package/src/dashboard/detail-viewer-runtime.ts +15 -2
- package/src/dashboard/event-loop-stall-monitor.ts +4 -0
- package/src/dashboard/goal-loop-thinking.ts +16 -0
- package/src/dashboard/hitl-boot.ts +9 -4
- package/src/dashboard/index.ts +228 -387
- package/src/dashboard/input/chat-main-entry-runtime.ts +2 -0
- package/src/dashboard/input/chat-main-log-actions.ts +4 -0
- package/src/dashboard/input/chat-main-log-command.ts +12 -1
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +172 -3
- package/src/dashboard/input/chat-main-session.ts +6 -2
- package/src/dashboard/input/chat-main-slash-command.ts +7 -0
- package/src/dashboard/input/chat-main-turn.ts +2 -1
- package/src/dashboard/input/compact-prepass-recovery.ts +97 -0
- package/src/dashboard/input/dashboard-chord-actions.ts +10 -1
- package/src/dashboard/input/dashboard-chord-runtime.ts +2 -0
- package/src/dashboard/input/external-input-host.ts +45 -0
- package/src/dashboard/input/log-fold-binding.ts +18 -0
- package/src/dashboard/input/mouse-wiring.ts +17 -4
- package/src/dashboard/input/turn-steer-bridge.ts +94 -0
- package/src/dashboard/log-click-runtime.ts +5 -3
- package/src/dashboard/running-build-status.ts +74 -0
- package/src/dashboard/seat-boot-preamble.ts +113 -0
- package/src/dashboard/seat-local-instructions.ts +305 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +100 -28
- package/src/dashboard/slash-runtime/model-choices.ts +35 -0
- package/src/dashboard/term-slash-runtime.ts +15 -0
- package/src/dashboard/turn-preamble.ts +30 -2
- package/src/dashboard/turn-session-layers.ts +176 -0
- package/src/dashboard/turn-stream-formatter.ts +14 -6
- package/src/dashboard/turn-stream-presentation-applier.ts +8 -0
- package/src/domains/release-tool.ts +8 -9
- package/src/domains/surface-events.ts +4 -1
- package/src/domains/watch-default-scheduler.ts +8 -9
- package/src/fold-stack.ts +24 -1
- package/src/git-fs/dirty.ts +32 -4
- package/src/git-fs/index.ts +43 -1
- package/src/graph-runner/runner.ts +1 -0
- package/src/harness/harness-gc.ts +32 -5
- package/src/index.ts +14 -1
- package/src/input/external-input-queue.ts +219 -0
- package/src/interactive-terminal-modal.ts +13 -0
- package/src/llm/route-decision.ts +25 -0
- package/src/llm-stream-retry-display.ts +59 -0
- package/src/llm.ts +253 -55
- package/src/log-entry.ts +3 -3
- package/src/log-pane/search.ts +29 -4
- package/src/loops/agent-reply.ts +256 -0
- package/src/loops/budget.ts +37 -7
- package/src/loops/loop-cli.ts +3 -2
- package/src/loops/msg-address.ts +57 -0
- package/src/loops/msg-wake.ts +282 -0
- package/src/loops/orchestrator/inbox.ts +60 -3
- package/src/loops/orchestrator/tick.ts +24 -4
- package/src/loops/registry.ts +42 -4
- package/src/memory.ts +20 -5
- package/src/native-tool-catalog.ts +125 -0
- package/src/nexus/api/http-server.ts +5 -0
- package/src/nexus/api/ops-api.ts +2 -0
- package/src/nexus/api/project-autopsy.ts +127 -0
- package/src/nexus/api/terminals.ts +3 -0
- package/src/nexus/api/workflow-approvals.ts +2 -0
- package/src/nexus/onboarding/first-boot-wizard.ts +56 -2
- package/src/oauth/codex-account-store.ts +15 -3
- package/src/oauth/codex-billing-route.ts +31 -0
- package/src/ops/overview-collect.ts +19 -2
- package/src/panes/log-pane.ts +67 -8
- package/src/persona/presets.ts +44 -0
- package/src/plugins/maker/wizard-generate.ts +6 -4
- package/src/preview/terminal.ts +14 -1
- package/src/prompt-cache/types.ts +2 -0
- package/src/prompt-enhance/enhance.ts +24 -8
- package/src/prompt-library/universal-preamble.ts +273 -56
- package/src/pty-shell/pty-control-ipc.ts +4 -1
- package/src/pty-shell/pty-manifest.ts +77 -5
- package/src/pty-shell/registry.ts +19 -2
- package/src/pty-shell/tui-run-state.ts +253 -0
- package/src/release-loop/light-rc.ts +28 -3
- package/src/release-loop/rehearsal.ts +1 -1
- package/src/render.ts +5 -1
- package/src/seat-loop/seat-report.ts +42 -2
- package/src/self-dev/run-supervisor.ts +71 -5
- package/src/self-dev/shard-aggregate.ts +2 -0
- package/src/self-dev/shard-run.ts +23 -2
- package/src/self-health/signatures.ts +132 -0
- package/src/self-implement/doctor-visit.ts +118 -0
- package/src/self-implement/gate-cli.ts +11 -2
- package/src/self-implement/goal-author-decompose.ts +80 -16
- package/src/self-implement/goal-author.ts +114 -72
- package/src/self-implement/goal-authoring-grounding.ts +1 -1
- package/src/self-implement/goal-file-name.ts +65 -0
- package/src/self-implement/ground-goal.ts +2 -1
- package/src/self-implement/host-regate.ts +14 -0
- package/src/self-implement/review-mustfix-class.ts +115 -0
- package/src/self-implement/run-ledger.ts +111 -7
- package/src/self-implement/running-runs.ts +10 -6
- package/src/self-implement/self-implement-runtime.ts +32 -0
- package/src/session/pending-input.ts +62 -11
- package/src/session-runtime/index.ts +7 -1
- package/src/skills/tools/ops-ledger.ts +707 -0
- package/src/skills/tools/persistent-grounding.ts +47 -7
- package/src/skills/tools/shell.ts +117 -1
- package/src/status/bar.ts +32 -2
- package/src/status/status-provider-info.ts +58 -0
- package/src/task-agent/rejudge-on-head.ts +4 -1
- package/src/task-agent/remote-rejudge-bind.ts +34 -5
- package/src/task-agent/repair-cycle.ts +13 -0
- package/src/task-orchestrator/surfaces/kubectl-transient-retry.ts +51 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +63 -7
- package/src/task-orchestrator/surfaces/pod-install-slots.ts +6 -11
- package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +76 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +107 -33
- package/src/terminal/session-registry.ts +6 -0
- package/src/thinking-line.ts +12 -3
- package/src/tool-runtime/index.ts +4 -0
- package/src/tool-runtime/ops-ledger-runtimes.ts +84 -0
- package/src/tool-runtime/ref-consult-runtime.ts +17 -2
- package/src/tool-runtime/run-shell-runtime.ts +4 -1
- package/src/tool-runtime/self-cognition-runtimes.ts +5 -1
- package/src/tui.ts +5 -0
- package/src/user-config.ts +54 -6
- package/src/ux-sim/fake-llm.ts +29 -0
- package/src/ux-sim/in-process-cli.ts +175 -0
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/1027.a0f04663d24c2779.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1038.676007ae505822e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1113.a37eadf7f740d955.js +0 -1
- package/apps/pwa/out/_next/static/chunks/112-fa7c526c20ce1405.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1144.5fa1fa1d48dbcd12.js +0 -36
- package/apps/pwa/out/_next/static/chunks/1146.80d15ea7c6e6ee95.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1157.f08bf2b70915e176.js +0 -148
- package/apps/pwa/out/_next/static/chunks/119b405e.8fdd0e44d1ff37aa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1296.04560d98e73fbf51.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1314-f604ba013ec535b0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1454-29d1d773d5996a49.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1464.f3209af0d8ae4ff2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1729-d73dd25e564679d4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1843.5924c24295243261.js +0 -27
- package/apps/pwa/out/_next/static/chunks/1987.e28149724b92918b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2066-5ca18ffa5a4be68b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2240.d10a66695155fd93.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2391.e2cbc98d4abbb41a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2528.3868070ef1be69f9.js +0 -24
- package/apps/pwa/out/_next/static/chunks/2566-734cb83bbd405886.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2697.76ca2ac3efef6f3b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/275.0e6bad414729bfa0.js +0 -32
- package/apps/pwa/out/_next/static/chunks/2803-33bdae771855a8d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3143.257997a5f1ed79df.js +0 -34
- package/apps/pwa/out/_next/static/chunks/3259-86f3be56e43eaf6a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3280-e177c33bfbdcfb0a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3294-2b6a6d45a46a6c1c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3309.364573ceedbdfd5f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3522.758840fc5e7fe630.js +0 -287
- package/apps/pwa/out/_next/static/chunks/3525-a7c989c1a661e880.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3694.b1a66387756458c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/370.124f9e678a76fc01.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3797-9643105335e660fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4084.15ecaf4240bd9e77.js +0 -286
- package/apps/pwa/out/_next/static/chunks/4089-b3382b8843114eee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4293.928a8d573c16aab7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4402.f9238a3b18a7bd43.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4490-9b090b0f9427f902.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4548.13502d0ca3b4f862.js +0 -8
- package/apps/pwa/out/_next/static/chunks/4599-548bc96cda44a5a7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4625.206574e33a9e7ae8.js +0 -104
- package/apps/pwa/out/_next/static/chunks/4862-392c9a71f0d8dfb4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5054.2906d1b02542edc5.js +0 -149
- package/apps/pwa/out/_next/static/chunks/5102-c822bbbee5a022a4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5194-8c93f2e7e4b6f717.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5305-bacd7eca0b9a5848.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5311.9071ee3f44fd7ff5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5369.9f34353442daa421.js +0 -1
- package/apps/pwa/out/_next/static/chunks/589-49d730cb8138b397.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5904-264a6412ae3c9028.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5980.728531d5c566535c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/599-56f2c0a5cc4a7295.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6011.f525002e21bef0ac.js +0 -23
- package/apps/pwa/out/_next/static/chunks/6132.4381ab93683f1acf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6149.2e698635e454d8f6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6356-0afafc4230cf9767.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6406.64756073f7df35b8.js +0 -77
- package/apps/pwa/out/_next/static/chunks/6479-16e62aedafa0e310.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6599.b5246b46a2453329.js +0 -64
- package/apps/pwa/out/_next/static/chunks/6610.5c26eec011565acb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/666.37d18474edc1c552.js +0 -2
- package/apps/pwa/out/_next/static/chunks/6904.a0b5b1ed4f2d2c20.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7247-1f4aba94aba50d9f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7274-e71a7c5b7760cd02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7290.1fcaeef3adb5d0d4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7477-2c64e42760f82f33.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7505-47002b76ff1aef6c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7600-11884ca4da68e5d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7607.40d8bb3689697ccb.js +0 -62
- package/apps/pwa/out/_next/static/chunks/7752.5cbdd0b433c54af9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7763.f51fcc19ca1414ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7785.846140c859b1adf6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7807-a0fdac6393e0bf36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7837-20a63b4b7e9342b1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/800.7815414cf280545d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8085-1e5fce59500a2cc2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8100.415f2105faa63e97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8290.701aa42ed13aa767.js +0 -226
- package/apps/pwa/out/_next/static/chunks/83a80514-b897b64df43ce108.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8444.d9c74214a3145a43.js +0 -93
- package/apps/pwa/out/_next/static/chunks/8569.98c915534928c7f9.js +0 -24
- package/apps/pwa/out/_next/static/chunks/8591.b1c7f876e5ec7cfb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8715-f63756021d3ab989.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8879.776c2ec7732aa114.js +0 -115
- package/apps/pwa/out/_next/static/chunks/8881.ddca15b3c82c490c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8946.5da5c87f32a2e1a8.js +0 -41
- package/apps/pwa/out/_next/static/chunks/9117.080b9b75be90e14d.js +0 -74
- package/apps/pwa/out/_next/static/chunks/9167.f3ecb28f367d6e69.js +0 -94
- package/apps/pwa/out/_next/static/chunks/9224.66095370ee28c93b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9238-0682b013c83d6449.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9449.d3ed795da4befb1c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/949.1e7d45ccb71580aa.js +0 -90
- package/apps/pwa/out/_next/static/chunks/9638-d268329f2c6f4f8d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9842-d6644eb53d3dc6bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9863.94ca3263e760696e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9938.b23e4d4dfa0114cd.js +0 -79
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d9babd8795f396a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-5ab1e47978577c5e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-24453f6a302816b4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-6c131d30bb1cf871.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-dc0772b11861af51.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-5159dc8752c6cd29.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-c5a2478861c08b87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-f722a9dec084e08b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-256ffd365d32e100.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-e0de78ae7b99f01c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-cfbdc44b708d9801.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-4c741eb760f2f77c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-e9ba98f5f1440a21.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-d9babd8795f396a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-dafc901bb1b72b5f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-2f6f303fa114ec24.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-1634081c5272006c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-ced0bcfc6542b3fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-bb1f05cd51c38944.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-db069b48a59c8c00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-f736324afa2117c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-435f5e2faf02bc01.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-497e0eedf20e7890.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-a8d28fdf995e16ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-8966452228753c5e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fd5d18656cb432b6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-5663779cb1a37609.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-66a67eb19ebd976b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-3b492aa78cf3c4a6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c71267e7681da982.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-a21d1e1797172692.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-cb249e81ed339318.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-781cfc5114e097da.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-478157214db6a023.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-d9babd8795f396a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-86141f12cf090b7f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-7256c73bb1c36751.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-5c738ca7adef3de5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-0138c8091ec17224.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-cc2f24f16d85e735.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-979d318a534e92da.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-182d394f7e6e096b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-21050928a697ed7a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-44b9d807005a9030.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-601fb77340e63c9a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-75d3fb5d47af0edf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-11bf9e5725a72c22.js +0 -1
- package/apps/pwa/out/_next/static/chunks/dcf24383-2f82e35f2d827393.js +0 -1
- package/apps/pwa/out/_next/static/chunks/e117f801.e92bf10242653497.js +0 -1
- package/apps/pwa/out/_next/static/chunks/e87d89b9.2e71c0ae475d28a1.js +0 -122
- package/apps/pwa/out/_next/static/chunks/framework-bf135b997155e90e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-5571537543bea91c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-25c51c7df7f3a442.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-e3b2c1f5d82abd65.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-083f2e23e9bc3641.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-e94d22b7a028217b.js +0 -1
- package/src/dashboard/bench-slash-runtime.ts +0 -40
- package/src/dashboard/input/search-modal-router.ts +0 -9
- package/src/dashboard/modals/pane-key-router.ts +0 -27
- package/src/dashboard/view-slash-runtime.ts +0 -48
- /package/apps/pwa/out/_next/static/{y1ltt7oCZxVpC6zVPhZ2O → cIpv5nU9AycwYWZI9H589}/_ssgManifest.js +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { realpath } from 'node:fs/promises';
|
|
3
3
|
import { isAbsolute, relative, resolve, sep } from 'node:path';
|
|
4
|
-
import { runGoalLoop, type CoreTurnContext, type CoreTurnDispatchTool, type GoalLoopOptions } from '../../core-turn/index.js';
|
|
4
|
+
import { runGoalLoop, type CoreTurnContext, type CoreTurnDispatchTool, type GoalLoopOptions, type GoalLoopResult } from '../../core-turn/index.js';
|
|
5
5
|
import { debug } from '../../debug/log.js';
|
|
6
|
+
import { selectPlanningLlm } from '../../prompt-enhance/enhance.js';
|
|
6
7
|
import type { LLMMessage, LLMToolSpec } from '../../llm.js';
|
|
7
8
|
import { buildAstGrepTool, dispatchAstGrep, hasAstGrep } from './ast-grep.js';
|
|
8
9
|
import { buildGlobTool, dispatchGlob } from './glob.js';
|
|
@@ -22,6 +23,8 @@ export interface PersistentGroundingDeps {
|
|
|
22
23
|
relativePath?: (from: string, to: string) => string;
|
|
23
24
|
/** Terms generated by an upstream grounding consumer; the loop must prioritize them for code discovery. */
|
|
24
25
|
terms?: string[];
|
|
26
|
+
/** Authoring model selection seam; production follows the planning role, including the Pod relay. */
|
|
27
|
+
planningLlm?: () => Pick<ReturnType<typeof selectPlanningLlm>, 'model' | 'modelSource' | 'fallbackReason' | 'requestedModel' | 'requestedSource'>;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
export interface PersistentGroundingResult {
|
|
@@ -215,7 +218,7 @@ function groundingMessages(goal: string, terms: readonly string[]): LLMMessage[]
|
|
|
215
218
|
function unreadEvidencePaths(evidence: string, readFiles: ReadonlySet<string>): string[] {
|
|
216
219
|
return Array.from(new Set(evidence.split(/\r?\n/)
|
|
217
220
|
.flatMap(repositoryRelativeCodePaths)
|
|
218
|
-
.filter((path) => isCodeRootPath(path) && !readFiles.has(path))))
|
|
221
|
+
.filter((path) => isCodeRootPath(path) && !readFiles.has(path))));
|
|
219
222
|
}
|
|
220
223
|
|
|
221
224
|
function rejectedEvidenceFeedback(evidence: string, readFiles: ReadonlySet<string>): LLMMessage {
|
|
@@ -224,10 +227,11 @@ function rejectedEvidenceFeedback(evidence: string, readFiles: ReadonlySet<strin
|
|
|
224
227
|
return {
|
|
225
228
|
role: 'user',
|
|
226
229
|
content: [
|
|
227
|
-
'Your completion evidence was rejected
|
|
230
|
+
'Your completion evidence was rejected: Glob, Grep, and ListDir prove discovery, but they do not verify a file for completion evidence.',
|
|
228
231
|
`Unverified paths: ${unread.length ? unread.join(', ') : '(none in allowed code roots)'}`,
|
|
229
232
|
`Paths actually Read: ${read.length ? read.join(', ') : '(none)'}`,
|
|
230
|
-
|
|
233
|
+
...(unread.length ? [`Next tool calls: ${unread.map((path) => `Read({"file_path":"${path}"})`).join(' ; ')}`] : []),
|
|
234
|
+
'Before calling update_goal(status="complete"), Read at least one relevant path above and wait for its successful result. Cite only paths that this grounding run actually Read, each with a concrete reason. If a Read fails, omit that path. Finish by calling update_goal; ending with prose alone does not complete this task.',
|
|
231
235
|
].join('\n'),
|
|
232
236
|
};
|
|
233
237
|
}
|
|
@@ -248,7 +252,10 @@ export async function groundPersistently(goal: string, cwd: string, deps: Persis
|
|
|
248
252
|
if (!astGrepAvailable) debug.log('grounding.persistent', 'tool-unavailable', { sessionId, tool: 'AstGrep' }, { level: 'warn' });
|
|
249
253
|
const toolCalls: Record<string, number> = {};
|
|
250
254
|
let completedIterations: number | undefined;
|
|
255
|
+
let resolvedProvider: string | undefined;
|
|
256
|
+
let resolvedModel: string | undefined;
|
|
251
257
|
try {
|
|
258
|
+
const planningLlm = (deps.planningLlm ?? selectPlanningLlm)();
|
|
252
259
|
const loop = deps.runGoalLoop ?? runGoalLoop;
|
|
253
260
|
let completionEvidence = '';
|
|
254
261
|
const readFiles = new Set<string>();
|
|
@@ -259,7 +266,12 @@ export async function groundPersistently(goal: string, cwd: string, deps: Persis
|
|
|
259
266
|
dispatchTool: guardedDispatchTool(cwd, deps.dispatchTool, readFiles, deps.relativePath),
|
|
260
267
|
signal: new AbortController().signal,
|
|
261
268
|
maxToolTurns: 4,
|
|
269
|
+
...(planningLlm.model ? { modelOverride: planningLlm.model } : {}),
|
|
262
270
|
callbacks: {
|
|
271
|
+
onResolvedProvider: (provider, model) => {
|
|
272
|
+
resolvedProvider = provider;
|
|
273
|
+
resolvedModel = model;
|
|
274
|
+
},
|
|
263
275
|
onToolCall: (call) => {
|
|
264
276
|
toolCalls[call.name] = (toolCalls[call.name] ?? 0) + 1;
|
|
265
277
|
if (call.name === 'update_goal' && call.args.status === 'complete' && typeof call.args.evidence === 'string') completionEvidence = call.args.evidence;
|
|
@@ -282,6 +294,8 @@ export async function groundPersistently(goal: string, cwd: string, deps: Persis
|
|
|
282
294
|
let verified = firstVerified;
|
|
283
295
|
let feedbackRetry = false;
|
|
284
296
|
let retryIterations = 0;
|
|
297
|
+
let retryStopReason: GoalLoopResult['stopReason'] | undefined;
|
|
298
|
+
let retryOutcome: 'not-needed' | 'verified' | 'incomplete' | 'evidence-rejected' | 'failed' | 'aborted' | 'auth-rejected' = 'not-needed';
|
|
285
299
|
if (firstVerified.rejection.notRead > 0) {
|
|
286
300
|
feedbackRetry = true;
|
|
287
301
|
const feedback = rejectedEvidenceFeedback(completionEvidence, readFiles);
|
|
@@ -290,6 +304,11 @@ export async function groundPersistently(goal: string, cwd: string, deps: Persis
|
|
|
290
304
|
const retry = await loop({ ...ctx, sessionId: `${sessionId}-evidence-retry`, messages: [...ctx.messages, feedback] },
|
|
291
305
|
{ ...options, maxIterations: 2 });
|
|
292
306
|
retryIterations = retry.iterations;
|
|
307
|
+
retryStopReason = retry.stopReason;
|
|
308
|
+
retryOutcome = retry.goalComplete && retry.stopReason === 'goal_complete' ? 'evidence-rejected'
|
|
309
|
+
: retry.stopReason === 'auth_rejected' ? 'auth-rejected'
|
|
310
|
+
: retry.stopReason === 'aborted' || retry.stopReason === 'soft_stop' ? 'aborted'
|
|
311
|
+
: retry.stopReason === 'error' ? 'failed' : 'incomplete';
|
|
293
312
|
const retryVerified = retry.goalComplete && retry.stopReason === 'goal_complete'
|
|
294
313
|
? verifiedEvidenceFromCompletion(completionEvidence, readFiles)
|
|
295
314
|
: null;
|
|
@@ -300,8 +319,10 @@ export async function groundPersistently(goal: string, cwd: string, deps: Persis
|
|
|
300
319
|
rejection: retryVerified.rejection,
|
|
301
320
|
};
|
|
302
321
|
result = retry;
|
|
322
|
+
if (retryVerified.evidence.length > 0) retryOutcome = 'verified';
|
|
303
323
|
}
|
|
304
324
|
} catch (error) {
|
|
325
|
+
retryOutcome = 'failed';
|
|
305
326
|
try {
|
|
306
327
|
debug.log('grounding.persistent', 'evidence-retry-failed', { sessionId,
|
|
307
328
|
reason: error instanceof Error ? error.message.slice(0, 200) : String(error).slice(0, 200) }, { level: 'warn' });
|
|
@@ -311,22 +332,41 @@ export async function groundPersistently(goal: string, cwd: string, deps: Persis
|
|
|
311
332
|
}
|
|
312
333
|
}
|
|
313
334
|
const totalIterations = first.iterations + retryIterations;
|
|
335
|
+
let stopReason: string = result.stopReason;
|
|
336
|
+
// A verified line remains useful evidence, but it cannot turn an unsuccessful
|
|
337
|
+
// feedback retry into a successful completion of the whole grounding task.
|
|
338
|
+
switch (retryOutcome) {
|
|
339
|
+
case 'incomplete': stopReason = 'evidence_retry_incomplete'; break;
|
|
340
|
+
case 'evidence-rejected': stopReason = 'evidence_retry_rejected'; break;
|
|
341
|
+
case 'failed': stopReason = retryStopReason === 'error' ? 'error' : 'evidence_retry_failed'; break;
|
|
342
|
+
case 'auth-rejected': stopReason = 'auth_rejected'; break;
|
|
343
|
+
case 'aborted': stopReason = retryStopReason === 'soft_stop' ? 'soft_stop' : 'aborted'; break;
|
|
344
|
+
}
|
|
314
345
|
try {
|
|
315
346
|
debug.log('grounding.persistent', 'finished', {
|
|
316
347
|
sessionId,
|
|
317
348
|
maxIterations,
|
|
318
349
|
durationMs: durationMs(),
|
|
319
350
|
iterations: totalIterations,
|
|
320
|
-
stopReason
|
|
351
|
+
stopReason,
|
|
321
352
|
// ⛔ 「끝났다」가 두 뜻이다 — ⓐ 스스로 목표를 끝냈다 ⓑ 턴이 «그냥» 끝났다.
|
|
322
353
|
// 📏 2026-08-11 72차 전수(400건): 후보 0인 finished 가 5건이고 ***다섯 다 end_turn*** 이었다.
|
|
323
354
|
// 그 둘을 한 이름에 두면 「접지는 성공인데 코드가 0」이라는 «없는 수수께끼»가 생긴다.
|
|
324
|
-
outcome: result.goalComplete &&
|
|
355
|
+
outcome: result.goalComplete && stopReason === 'goal_complete' ? 'goal-complete' : 'stopped-without-goal',
|
|
325
356
|
candidates: verified.files,
|
|
326
357
|
candidateCount: verified.files.length,
|
|
327
358
|
evidenceCount: verified.evidence.length,
|
|
328
359
|
evidenceRejection: verified.rejection,
|
|
329
360
|
feedbackRetry,
|
|
361
|
+
retryOutcome,
|
|
362
|
+
retryStopReason: retryStopReason ?? null,
|
|
363
|
+
provider: resolvedProvider ?? null,
|
|
364
|
+
model: resolvedModel ?? null,
|
|
365
|
+
planningModel: planningLlm.model ?? null,
|
|
366
|
+
planningModelSource: planningLlm.modelSource,
|
|
367
|
+
planningFallbackReason: planningLlm.fallbackReason ?? null,
|
|
368
|
+
planningRequestedModel: planningLlm.requestedModel ?? null,
|
|
369
|
+
planningRequestedSource: planningLlm.requestedSource ?? null,
|
|
330
370
|
...(feedbackRetry ? { firstEvidenceRejection: firstVerified.rejection } : {}),
|
|
331
371
|
toolCalls,
|
|
332
372
|
});
|
|
@@ -337,7 +377,7 @@ export async function groundPersistently(goal: string, cwd: string, deps: Persis
|
|
|
337
377
|
files: verified.files,
|
|
338
378
|
evidence: verified.evidence,
|
|
339
379
|
iterations: totalIterations,
|
|
340
|
-
stopReason
|
|
380
|
+
stopReason,
|
|
341
381
|
};
|
|
342
382
|
} catch (error) {
|
|
343
383
|
try {
|
|
@@ -178,6 +178,116 @@ function rejectedCdResult(): RunShellDispatchResult {
|
|
|
178
178
|
};
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
+
// ── ops-ledger CLI steering (RunShell-0 convergence) ────────────────────────
|
|
182
|
+
// The durable mailbox and release-checklist ledgers have in-process native
|
|
183
|
+
// tools (MsgList/MsgPost/MsgAck · ChecklistList/Add/Set/Move —
|
|
184
|
+
// src/skills/tools/ops-ledger.ts, registered for the same skill+tui hosts as
|
|
185
|
+
// RunShell). Shelling out to the `elanous` CLI for exactly those covered ops
|
|
186
|
+
// pays 1.3–2s of process startup for work the host process does in <300ms,
|
|
187
|
+
// and the CLI's human-oriented stdout amplifies TUI screen defects — so the
|
|
188
|
+
// call is steered to the native tool with a structured refusal naming it.
|
|
189
|
+
//
|
|
190
|
+
// Deliberately NOT a blanket elanous-CLI ban: only the seven covered ops are
|
|
191
|
+
// refused, and argv that explicitly scopes another universe (--test /
|
|
192
|
+
// --config-dir / --state-dir) is allowed through because the native tools
|
|
193
|
+
// always serve THIS process's instance.
|
|
194
|
+
const LEDGER_CLI_BIN = /(?:^|[/\\])(?:elanous|elanous\.mjs|elanous\.cjs|eln)$/;
|
|
195
|
+
const LEDGER_ENV_BIN = /(?:^|[/\\])env$/;
|
|
196
|
+
const LEDGER_CLI_NATIVE_TOOL: Readonly<Record<string, string>> = {
|
|
197
|
+
'msg list': 'MsgList',
|
|
198
|
+
'msg post': 'MsgPost',
|
|
199
|
+
'msg ack': 'MsgAck',
|
|
200
|
+
'release checklist list': 'ChecklistList',
|
|
201
|
+
'release checklist add': 'ChecklistAdd',
|
|
202
|
+
'release checklist set': 'ChecklistSet',
|
|
203
|
+
'release checklist move': 'ChecklistMove',
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
/** The covered ops-ledger CLI op in this argv and its exposed native tool,
|
|
207
|
+
* or null when the command should run normally. */
|
|
208
|
+
export function matchLedgerCli(
|
|
209
|
+
command: readonly string[], availableToolNames: readonly string[] = [],
|
|
210
|
+
): { covered: string; tool: string } | null {
|
|
211
|
+
let binIndex = 0;
|
|
212
|
+
// RunShell receives argv, so recognize only argv-preserving env wrappers.
|
|
213
|
+
// An alternate instance must still run its own CLI, never this process's native tool;
|
|
214
|
+
// so must a changed or unset ELANOUS_TRACK — the native tools record THIS process's
|
|
215
|
+
// seat as the actor and route ChecklistMove permissions by it.
|
|
216
|
+
if (LEDGER_ENV_BIN.test(command[0] ?? '')) {
|
|
217
|
+
binIndex = 1;
|
|
218
|
+
while (binIndex < command.length) {
|
|
219
|
+
const arg = command[binIndex]!;
|
|
220
|
+
if (arg === '-i' || arg === '--ignore-environment') return null;
|
|
221
|
+
if (arg === '--') { binIndex += 1; continue; }
|
|
222
|
+
if (arg === '-u' || arg === '--unset') {
|
|
223
|
+
const name = command[binIndex + 1];
|
|
224
|
+
if (!name || /^ELANOUS_(?:STATE_DIR|CONFIG_DIR|TEST_STATE_DIR|TRACK)$/.test(name)) return null;
|
|
225
|
+
binIndex += 2;
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
if (arg.startsWith('--unset=')) {
|
|
229
|
+
if (/^--unset=ELANOUS_(?:STATE_DIR|CONFIG_DIR|TEST_STATE_DIR|TRACK)$/.test(arg)) return null;
|
|
230
|
+
binIndex += 1;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(arg)) {
|
|
234
|
+
if (/^ELANOUS_(?:STATE_DIR|CONFIG_DIR|TEST_STATE_DIR|TRACK)=/.test(arg)) return null;
|
|
235
|
+
binIndex += 1;
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (command[binIndex] === 'bun' || command[binIndex] === 'bunx' || command[binIndex] === 'node' || command[binIndex] === 'npx') {
|
|
242
|
+
binIndex += 1;
|
|
243
|
+
if (command[binIndex] === '--bun') binIndex += 1;
|
|
244
|
+
}
|
|
245
|
+
if (!LEDGER_CLI_BIN.test(command[binIndex] ?? '')) return null;
|
|
246
|
+
const args = command.slice(binIndex + 1);
|
|
247
|
+
if (args.some((arg) => arg === '--test' || arg === '--config-dir' || arg.startsWith('--config-dir=')
|
|
248
|
+
|| arg === '--state-dir' || arg.startsWith('--state-dir=')
|
|
249
|
+
|| arg === '--test-state-dir' || arg.startsWith('--test-state-dir='))) return null;
|
|
250
|
+
let i = 0;
|
|
251
|
+
while (i < args.length && args[i]!.startsWith('-')) i += 1;
|
|
252
|
+
const sub = args[i];
|
|
253
|
+
const covered = sub === 'msg'
|
|
254
|
+
? `msg ${args[i + 1]}`
|
|
255
|
+
: sub === 'release' && args[i + 1] === 'checklist'
|
|
256
|
+
? `release checklist ${args[i + 2]}`
|
|
257
|
+
: '';
|
|
258
|
+
const tool = covered ? LEDGER_CLI_NATIVE_TOOL[covered] : undefined;
|
|
259
|
+
if (!tool || !availableToolNames.includes(tool)) return null;
|
|
260
|
+
return { covered, tool };
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function ledgerCliSteerOutput(shellTool: string, covered: string, tool: string): string {
|
|
264
|
+
const metadata = covered === 'release checklist set' ? ' — for owner/priority/disposition/kind/… use ChecklistEdit, one field per call' : '';
|
|
265
|
+
return `${shellTool} rejected \`${covered}\`: call the native ${tool} tool instead (same ledger, same permissions and audit, no CLI startup)${metadata}.`;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/** Structured refusal steering a covered ops-ledger CLI argv to its native
|
|
269
|
+
* tool, or null when the command should run normally. Exported so tests
|
|
270
|
+
* can exercise the matcher without spawning anything. */
|
|
271
|
+
export function rejectedLedgerCliResult(
|
|
272
|
+
command: readonly string[], availableToolNames: readonly string[] = [],
|
|
273
|
+
): RunShellDispatchResult | null {
|
|
274
|
+
const match = matchLedgerCli(command, availableToolNames);
|
|
275
|
+
if (!match) return null;
|
|
276
|
+
const { covered, tool } = match;
|
|
277
|
+
return {
|
|
278
|
+
output: ledgerCliSteerOutput('RunShell', covered, tool),
|
|
279
|
+
exitCode: null,
|
|
280
|
+
outcome: 'spawn-error',
|
|
281
|
+
elapsedMs: 0,
|
|
282
|
+
stdout: '',
|
|
283
|
+
stderr: `use the native ${tool} tool instead of the ${covered} CLI`,
|
|
284
|
+
truncated: false,
|
|
285
|
+
approvalKey: 'rejected:ops-ledger-cli',
|
|
286
|
+
sandboxed: false,
|
|
287
|
+
sandboxTool: 'none',
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
181
291
|
function logShellDispatch(event: string, data: Record<string, unknown>): void {
|
|
182
292
|
debug.log('shell.dispatch', event, data);
|
|
183
293
|
}
|
|
@@ -240,7 +350,7 @@ export function enqueueShellCompletionNotice(
|
|
|
240
350
|
|
|
241
351
|
export async function dispatchRunShell(
|
|
242
352
|
rawArgs: Record<string, unknown>,
|
|
243
|
-
opts: { signal?: AbortSignal } = {},
|
|
353
|
+
opts: { signal?: AbortSignal; availableToolNames?: readonly string[] } = {},
|
|
244
354
|
): Promise<RunShellDispatchResult> {
|
|
245
355
|
const command = asCommand(rawArgs.command);
|
|
246
356
|
const cwd = typeof rawArgs.cwd === 'string' ? rawArgs.cwd : undefined;
|
|
@@ -255,6 +365,12 @@ export async function dispatchRunShell(
|
|
|
255
365
|
logShellDispatch('cd.rejected', { reason: 'argv-state-does-not-persist' });
|
|
256
366
|
return rejectedCdResult();
|
|
257
367
|
}
|
|
368
|
+
const ledgerCliMatch = matchLedgerCli(command, opts.availableToolNames);
|
|
369
|
+
if (ledgerCliMatch) {
|
|
370
|
+
// covered op ⊕ tool only — the argv can carry a message body.
|
|
371
|
+
logShellDispatch('ledger-cli.steered', { shell: 'run-shell', ...ledgerCliMatch });
|
|
372
|
+
return rejectedLedgerCliResult(command, opts.availableToolNames)!;
|
|
373
|
+
}
|
|
258
374
|
const effectiveCwd = cwd ?? getSessionCwd();
|
|
259
375
|
const cwdSource = cwd === undefined ? 'session' : 'argument';
|
|
260
376
|
const boundaryReject = harnessCommandWriteReject(command, effectiveCwd, 'run-shell');
|
package/src/status/bar.ts
CHANGED
|
@@ -213,6 +213,9 @@ export interface GitSegmentState {
|
|
|
213
213
|
ahead?: number;
|
|
214
214
|
/** Commits behind upstream. Non-zero → peach tone with "-N". */
|
|
215
215
|
behind?: number;
|
|
216
|
+
/** Optional axis label after the glyph (e.g. `트리`) — set when a
|
|
217
|
+
* running-build pill sits next to it so the two SHAs are not confused. */
|
|
218
|
+
label?: string;
|
|
216
219
|
}
|
|
217
220
|
|
|
218
221
|
/** Git state — flat colored text. No pill background.
|
|
@@ -241,7 +244,7 @@ export function gitSegment(
|
|
|
241
244
|
const head = state.branch
|
|
242
245
|
? truncateGitHead(state.branch, 20)
|
|
243
246
|
: `HEAD@${(state.detachedSha ?? '').slice(0, 7)}`;
|
|
244
|
-
const parts: string[] = [`⌥ ${head}`];
|
|
247
|
+
const parts: string[] = [state.label ? `⌥ ${state.label} ${head}` : `⌥ ${head}`];
|
|
245
248
|
const dirty = Math.max(0, state.dirtyTotal ?? 0);
|
|
246
249
|
if (dirty > 0) parts.push(`*${dirty}`);
|
|
247
250
|
if ((state.ahead ?? 0) > 0) parts.push(`+${state.ahead}`);
|
|
@@ -260,6 +263,33 @@ export function gitSegment(
|
|
|
260
263
|
: strongText(parts.join(' '), tone, opts);
|
|
261
264
|
}
|
|
262
265
|
|
|
266
|
+
/** The code this TUI process loaded at boot (not the session tree HEAD). */
|
|
267
|
+
export interface RunningBuildState {
|
|
268
|
+
/** Boot commit (full or short); '' = unknown (rendered as `?`). */
|
|
269
|
+
sha: string;
|
|
270
|
+
/** True when the installed/checkout code moved after boot — a relaunch runs the new build.
|
|
271
|
+
* null = could not compare (not the same as «not stale»). */
|
|
272
|
+
stale: boolean | null;
|
|
273
|
+
/** The commit a relaunch would run, when known. */
|
|
274
|
+
currentSha?: string;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** Running-build pill.
|
|
278
|
+
*
|
|
279
|
+
* ▶ 실행 5c0f98f — boot build matches current code (overlay)
|
|
280
|
+
* ▶ 실행 5c0f98f ⟳ 재기동 필요 → 1a2b3c4 — code moved after boot (yellow, bold)
|
|
281
|
+
* ▶ 실행 5c0f98f ? — could not compare (overlay)
|
|
282
|
+
* ▶ 실행 ? — boot build unknown (overlay) */
|
|
283
|
+
export function runningBuildSegment(state: RunningBuildState | null | undefined, opts: StatusBarRenderOptions = {}): string {
|
|
284
|
+
if (!state) return '';
|
|
285
|
+
if (!state.sha) return text('▶ 실행 ?', 'overlay', opts);
|
|
286
|
+
const label = `▶ 실행 ${state.sha.slice(0, 7)}`;
|
|
287
|
+
if (state.stale === null) return text(`${label} ?`, 'overlay', opts);
|
|
288
|
+
if (!state.stale) return text(label, 'overlay', opts);
|
|
289
|
+
const target = state.currentSha ? ` → ${state.currentSha.slice(0, 7)}` : '';
|
|
290
|
+
return strongText(`${label} ⟳ 재기동 필요${target}`, 'yellow', opts);
|
|
291
|
+
}
|
|
292
|
+
|
|
263
293
|
/** Truncate a model id at the first parameter-size marker (e.g.
|
|
264
294
|
* `qwen3.6-35b-a3b-ud-mlx` → `qwen3.6-35b`). The marker pattern
|
|
265
295
|
* matches one or more digits followed by `b`/`B` (e.g. `7b`, `35b`,
|
|
@@ -289,7 +319,7 @@ function truncateAtParamSize(model: string): string {
|
|
|
289
319
|
* - `local:qwen3.6-35b-a3b-ud-mlx` → `local:qwen3.6-35b`
|
|
290
320
|
* - `node-b:qwen2.5-72b-instruct` → `node-b:qwen2.5-72b`
|
|
291
321
|
* - `claude-opus-4-6` → unchanged (no `\d+b` marker) */
|
|
292
|
-
export function modelSegment(info: ActiveProviderInfo, opts: StatusBarRenderOptions = {}): string {
|
|
322
|
+
export function modelSegment(info: Pick<ActiveProviderInfo, 'provider' | 'model'>, opts: StatusBarRenderOptions = {}): string {
|
|
293
323
|
if (!info.model || info.model === '(none)') {
|
|
294
324
|
return strongText(info.provider, 'pink', opts);
|
|
295
325
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// ── Status-line provider/model reader ──
|
|
2
|
+
//
|
|
3
|
+
// 하단 상태줄은 키 입력마다 다시 그린다. 종전엔 그때마다 `inspectActiveProvider()` 를 불러
|
|
4
|
+
// ① `getUserConfig()` 의 stat ② `decideProviderForConfig()` 의 자격 확인 ③ 상태줄이 «안 쓰는»
|
|
5
|
+
// `authDetail`(codex 면 auth 스토어 readFileSync + JSON.parse) 을 매 렌더 동기로 했다.
|
|
6
|
+
// 📏 실측(10-14 mbp · 운영 HOME · 500회 평균): 렌더 1회 98µs.
|
|
7
|
+
// ⇒ 상태줄이 쓰는 것은 provider·model 둘뿐이라, 그 둘만 짧게 기억한다.
|
|
8
|
+
// ⛔ 기억이 «낡은 값»으로 굳지 않게: runtimeModel 이 바뀌면 즉시, 설정 파일이 바뀌면 TTL(2s) 안에 다시 읽고,
|
|
9
|
+
// 그렇지 않아도 `maxAgeMs` 마다 다시 판정한다(auto 공급자는 자격 유무로 갈리므로). 표시 전용이라 2s 지연은 허용.
|
|
10
|
+
|
|
11
|
+
import { inspectActiveProvider, type ActiveProviderInfo } from '../provider-summary.js';
|
|
12
|
+
import { getUserConfig, type UserConfig } from '../user-config.js';
|
|
13
|
+
|
|
14
|
+
export type StatusProviderInfo = Pick<ActiveProviderInfo, 'provider' | 'model'>;
|
|
15
|
+
|
|
16
|
+
export interface StatusProviderInfoReaderDeps {
|
|
17
|
+
readConfig?: () => UserConfig;
|
|
18
|
+
inspect?: (cfg: UserConfig, runtimeModel?: string) => StatusProviderInfo;
|
|
19
|
+
now?: () => number;
|
|
20
|
+
/** 이 안에서는 설정도 다시 안 읽는다(렌더 경로 0 I/O). */
|
|
21
|
+
ttlMs?: number;
|
|
22
|
+
/** 설정이 그대로여도 이만큼 지나면 다시 판정한다. */
|
|
23
|
+
maxAgeMs?: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function createStatusProviderInfoReader(
|
|
27
|
+
deps: StatusProviderInfoReaderDeps = {},
|
|
28
|
+
): (runtimeModel?: string) => StatusProviderInfo {
|
|
29
|
+
const readConfig = deps.readConfig ?? (() => getUserConfig());
|
|
30
|
+
const inspect = deps.inspect ?? ((cfg, runtimeModel) => inspectActiveProvider(cfg, runtimeModel));
|
|
31
|
+
const now = deps.now ?? Date.now;
|
|
32
|
+
const ttlMs = deps.ttlMs ?? 2_000;
|
|
33
|
+
const maxAgeMs = deps.maxAgeMs ?? 30_000;
|
|
34
|
+
let memo: {
|
|
35
|
+
info: StatusProviderInfo;
|
|
36
|
+
cfg: UserConfig;
|
|
37
|
+
runtimeModel: string | undefined;
|
|
38
|
+
checkedAt: number;
|
|
39
|
+
inspectedAt: number;
|
|
40
|
+
} | null = null;
|
|
41
|
+
|
|
42
|
+
return (runtimeModel?: string): StatusProviderInfo => {
|
|
43
|
+
const t = now();
|
|
44
|
+
// ⛔ 조기 반환에도 최대 수명을 건다 — TTL 만 보면 «29초에 설정 확인 → 30.001초 렌더»가 재판정 없이 지나간다.
|
|
45
|
+
const fresh = memo !== null && t - memo.inspectedAt < maxAgeMs;
|
|
46
|
+
if (memo && fresh && memo.runtimeModel === runtimeModel && t - memo.checkedAt < ttlMs) return memo.info;
|
|
47
|
+
// getUserConfig() 는 파일 mtime 이 같으면 «같은 객체»를, 바뀌면 새 객체를 돌려준다(user-config.ts getUserConfig).
|
|
48
|
+
const cfg = readConfig();
|
|
49
|
+
if (memo && fresh && memo.cfg === cfg && memo.runtimeModel === runtimeModel) {
|
|
50
|
+
memo.checkedAt = t;
|
|
51
|
+
return memo.info;
|
|
52
|
+
}
|
|
53
|
+
const full = inspect(cfg, runtimeModel);
|
|
54
|
+
const info: StatusProviderInfo = { provider: full.provider, model: full.model };
|
|
55
|
+
memo = { info, cfg, runtimeModel, checkedAt: t, inspectedAt: t };
|
|
56
|
+
return info;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -89,6 +89,8 @@ export interface RejudgeDeps {
|
|
|
89
89
|
requestRepair?: (request: RepairLaunchRequest) => Promise<void>;
|
|
90
90
|
applyRepair?: (request: RepairCasRequest) => RepairCasOutcome;
|
|
91
91
|
notifyRepair?: (seat: string, body: string) => void;
|
|
92
|
+
/** Shared new-launch budget for this `tasks rejudge --all` call. */
|
|
93
|
+
repairBudget?: import('./repair-cycle.js').RepairTickBudget;
|
|
92
94
|
/** TA-REJUDGE-REBASE-LOOP — origin/main 을 PR 가지에 3-way merge 하고 일반 push. 시험은 주입한다. */
|
|
93
95
|
catchUpMain?: (request: CatchUpRequest) => Promise<CatchUpResult>;
|
|
94
96
|
log?: (category: string, event: string, data: Record<string, unknown>) => void;
|
|
@@ -533,7 +535,8 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
|
|
|
533
535
|
mustFix: mustFix ?? [], liveMoves: deps.liveMoves, now: now(), readFile: read,
|
|
534
536
|
...(deps.requestRepair ? { request: deps.requestRepair } : {}),
|
|
535
537
|
...(deps.applyRepair ? { apply: deps.applyRepair } : {}),
|
|
536
|
-
...(deps.notifyRepair ? { notify: deps.notifyRepair } : {})
|
|
538
|
+
...(deps.notifyRepair ? { notify: deps.notifyRepair } : {}),
|
|
539
|
+
...(deps.repairBudget ? { repairBudget: deps.repairBudget } : {}) });
|
|
537
540
|
step('repair', result.decision, result.reason, true);
|
|
538
541
|
return outcomes;
|
|
539
542
|
}
|
|
@@ -3,9 +3,23 @@ import { dirname } from 'node:path';
|
|
|
3
3
|
import { debug } from '../debug/log.js';
|
|
4
4
|
import { loadRunLedger } from '../self-implement/run-ledger.js';
|
|
5
5
|
import { bindCardEvidence, podChildRunIds, readCardRunSnapshot, refreshCardRunBinding } from './card-evidence.js';
|
|
6
|
-
import { remoteLedgerMirrorDir } from './parent-host.js';
|
|
6
|
+
import { mirrorRemoteRunLedgers, remoteLedgerMirrorDir } from './parent-host.js';
|
|
7
7
|
import { cardPrNumber, type TaskCard } from './task-hand.js';
|
|
8
8
|
|
|
9
|
+
const RECENT_LAUNCH_MS = 24 * 60 * 60 * 1000;
|
|
10
|
+
|
|
11
|
+
type BindDeps = {
|
|
12
|
+
now?: () => number;
|
|
13
|
+
mirror?: typeof mirrorRemoteRunLedgers;
|
|
14
|
+
onFailure?: (failure: { card: string; runId: string; host: string; reason: string }) => void;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function recentlyLaunched(card: TaskCard, now: number): boolean {
|
|
18
|
+
const launch = [...card.history].reverse().find(event => event.event === 'launch');
|
|
19
|
+
const at = Date.parse(launch?.at ?? card.createdAt);
|
|
20
|
+
return Number.isFinite(at) && at <= now && now - at < RECENT_LAUNCH_MS;
|
|
21
|
+
}
|
|
22
|
+
|
|
9
23
|
/**
|
|
10
24
|
* A remote child PR can appear after the last HQ card refresh. A card without a PR is otherwise absent from
|
|
11
25
|
* `rejudgeCandidates`, so the normal rejudge tick never reaches `mirrorRemoteCardLedger` or the binding replay.
|
|
@@ -14,8 +28,16 @@ import { cardPrNumber, type TaskCard } from './task-hand.js';
|
|
|
14
28
|
*/
|
|
15
29
|
export async function bindMirroredRemoteRejudgeCards(
|
|
16
30
|
tasks: Readonly<Record<string, TaskCard>>, statePath: string,
|
|
31
|
+
deps: BindDeps = {},
|
|
17
32
|
): Promise<{ scanned: number; bound: number; skipped: number }> {
|
|
18
33
|
const root = dirname(statePath);
|
|
34
|
+
const now = (deps.now ?? Date.now)();
|
|
35
|
+
const mirror = deps.mirror ?? mirrorRemoteRunLedgers;
|
|
36
|
+
const reportFailure = (card: TaskCard, reason: string): void => {
|
|
37
|
+
const failure = { card: card.id, runId: card.runId!, host: card.parentHost!.host, reason: reason.slice(0, 300) };
|
|
38
|
+
try { (deps.onFailure ?? ((data) => debug.log('task-agent', 'remote-rejudge-bind-failed', data)))(failure); }
|
|
39
|
+
catch { /* observation must not stop the other cards */ }
|
|
40
|
+
};
|
|
19
41
|
let scanned = 0;
|
|
20
42
|
let bound = 0;
|
|
21
43
|
let skipped = 0;
|
|
@@ -25,6 +47,10 @@ export async function bindMirroredRemoteRejudgeCards(
|
|
|
25
47
|
scanned++;
|
|
26
48
|
const dir = remoteLedgerMirrorDir(root, card.parentHost.host);
|
|
27
49
|
try {
|
|
50
|
+
// This prepass runs before PR-based candidate selection. Pulling here breaks the otherwise circular
|
|
51
|
+
// dependency: cards with a remote PR cannot be selected while their parent/child ledgers are absent locally.
|
|
52
|
+
// Limit fresh remote pulls to recent launches, but keep binding older ledgers already mirrored at HQ.
|
|
53
|
+
if (recentlyLaunched(card, now)) mirror(card.parentHost, card.runId, root);
|
|
28
54
|
const snapshot = await readCardRunSnapshot(card, {
|
|
29
55
|
loadLedger: (id) => loadRunLedger(id, dir),
|
|
30
56
|
podFinishes: () => [],
|
|
@@ -34,9 +60,14 @@ export async function bindMirroredRemoteRejudgeCards(
|
|
|
34
60
|
const childRunId = evidence.childRunId;
|
|
35
61
|
const pr = evidence.pr;
|
|
36
62
|
const child = childRunId ? snapshot.children[childRunId] : null;
|
|
63
|
+
if (snapshot.readErrors?.length) {
|
|
64
|
+
reportFailure(card, snapshot.readErrors.join('; '));
|
|
65
|
+
skipped++;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
37
68
|
// A PR event alone is not a completed remote run. The rejudge candidate must have the same exact
|
|
38
69
|
// child PR and terminal status that remoteBoundRunTerminal will later require.
|
|
39
|
-
if (
|
|
70
|
+
if (!parent || !childRunId || !pr?.url || !child
|
|
40
71
|
|| !podChildRunIds(parent, card.runId).includes(childRunId)
|
|
41
72
|
|| !child.some((entry) => entry.event === 'pr-opened' && entry.data?.number === pr.number
|
|
42
73
|
&& entry.data?.url === pr.url)
|
|
@@ -53,9 +84,7 @@ export async function bindMirroredRemoteRejudgeCards(
|
|
|
53
84
|
else skipped++;
|
|
54
85
|
} catch (error) {
|
|
55
86
|
skipped++;
|
|
56
|
-
|
|
57
|
-
card: card.id, runId: card.runId, host: card.parentHost.host, reason: error instanceof Error ? error.message : String(error),
|
|
58
|
-
}); } catch { /* observation must not stop the other cards */ }
|
|
87
|
+
reportFailure(card, error instanceof Error ? error.message : String(error));
|
|
59
88
|
}
|
|
60
89
|
}
|
|
61
90
|
return { scanned, bound, skipped };
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { spawn } from 'node:child_process';
|
|
3
3
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { dirname, join, resolve, sep } from 'node:path';
|
|
5
|
+
import { debug } from '../debug/log.js';
|
|
5
6
|
import { mintRunId } from '../harness/harness-space.js';
|
|
6
7
|
import { spawnElanousSync } from '../instance/spawn-elanous.js';
|
|
7
8
|
import { passJourneyNode } from '../self-dev/graph-journey-nodes.js';
|
|
@@ -29,8 +30,12 @@ export interface RepairCycleInput {
|
|
|
29
30
|
notify?: (seat: string, body: string) => void;
|
|
30
31
|
observeLaunch?: (move: string, runId: string) => void;
|
|
31
32
|
resolveOwner?: (card: TaskCard) => RepairOwner;
|
|
33
|
+
/** Shared only by one `tasks rejudge --all` invocation; a single-card rejudge has no cap. */
|
|
34
|
+
repairBudget?: RepairTickBudget;
|
|
32
35
|
}
|
|
33
36
|
|
|
37
|
+
export interface RepairTickBudget { max: number; requested: number; capped: number }
|
|
38
|
+
|
|
34
39
|
export type RepairCycleOutcome = { decision: 'would-repair' | 'repair-requested' | 'repair-pending' | 'repair-applied' | 'repair-failed' | 'repair-stopped'; reason: string };
|
|
35
40
|
export type RepairOwner = { seat?: TaskSeat; source: string; reason?: string };
|
|
36
41
|
|
|
@@ -230,6 +235,13 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
|
|
|
230
235
|
? { ...current, status: 'failed', history: [...(current.history ?? []), { at: now.toISOString(), event: 'repair-owner-missing', pr, head, detail: reason }] } : undefined);
|
|
231
236
|
return { decision: 'repair-stopped', reason };
|
|
232
237
|
}
|
|
238
|
+
if (input.repairBudget && input.repairBudget.requested >= input.repairBudget.max) {
|
|
239
|
+
input.repairBudget.capped++;
|
|
240
|
+
const reason = `repairMaxPerTick 상한 ${input.repairBudget.max} · 다음 틱에 재판정`;
|
|
241
|
+
try { debug.log('task-agent', 'repair-tick-cap', { card: card.id, pr, head, max: input.repairBudget.max,
|
|
242
|
+
requested: input.repairBudget.requested, capped: input.repairBudget.capped, move: judged.judgement.move }); } catch { /* fail-soft */ }
|
|
243
|
+
return { decision: 'would-repair', reason };
|
|
244
|
+
}
|
|
233
245
|
const next = attempts.length + 1;
|
|
234
246
|
const runId = mintRunId();
|
|
235
247
|
const { from, to } = alternateRepairModel(card);
|
|
@@ -251,6 +263,7 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
|
|
|
251
263
|
try {
|
|
252
264
|
await (input.request ?? defaultRequestRepair)({ card: card.id, pr, head, repo, resultPath, goalFile,
|
|
253
265
|
runId, model: to, seat: owner.seat });
|
|
266
|
+
if (input.repairBudget) input.repairBudget.requested++;
|
|
254
267
|
} catch (error) {
|
|
255
268
|
const reason = `repair launch failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
256
269
|
updateTaskCard(statePath, card.id, (current) => current?.repairs?.some((entry) => entry.runId === runId && entry.status === 'requested')
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* K3S-SECRET-DB-LOCK-RETRY — kubectl 호출이 «일시 오류»로 거부되면 지수 백오프로 다시 친다.
|
|
3
|
+
*
|
|
4
|
+
* 근거: node-b k3d(k3s · sqlite 저장소)가 Pod Secret 생성 때
|
|
5
|
+
* `Error from server: error when creating "STDIN": rpc error: code = Unknown desc = database is locked`
|
|
6
|
+
* 로 거부했다(10-15 02:11 KST 전후 4건 · TC #4186). sqlite 쓰기 잠금 경합이라 잠시 뒤 같은 apply 는 선다.
|
|
7
|
+
*
|
|
8
|
+
* ⛔ 판정 문구는 «실측 근거가 있는 것»만 둔다 — 짐작으로 늘리면 진짜 거부(권한·스키마)를 백오프 동안 삼킨다.
|
|
9
|
+
* 재시도 소진 시에만 호출부의 기존 실패 경로로 마지막 결과를 그대로 돌려준다.
|
|
10
|
+
*/
|
|
11
|
+
import { debug } from '../../debug/log.js';
|
|
12
|
+
|
|
13
|
+
export type KubectlCallResult = { status: number | null; stdout: string; stderr: string };
|
|
14
|
+
|
|
15
|
+
/** 실측된 일시 오류 문구(stderr 만 · 부분 일치 · 대소문자 무시 — stdout 은 apply 결과라 판정에 안 쓴다). */
|
|
16
|
+
export const KUBECTL_TRANSIENT_PATTERNS: readonly RegExp[] = [/database is locked/i];
|
|
17
|
+
|
|
18
|
+
/** 재시도 사이 대기(ms) — 길이가 곧 재시도 상한(4회 · 합 7.5s). */
|
|
19
|
+
export const KUBECTL_TRANSIENT_BACKOFF_MS: readonly number[] = [500, 1_000, 2_000, 4_000];
|
|
20
|
+
|
|
21
|
+
export function kubectlTransientReason(result: KubectlCallResult): string | null {
|
|
22
|
+
if (result.status === 0) return null;
|
|
23
|
+
const hit = KUBECTL_TRANSIENT_PATTERNS.find((pattern) => pattern.test(result.stderr));
|
|
24
|
+
return hit ? hit.source : null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 첫 결과 `first` 가 일시 오류일 때만 부른다(성공 경로에 await 를 더하지 않으려고 — 호출부의 마이크로태스크 순서를 지킨다).
|
|
29
|
+
* 다시 친 결과가 성공이거나 일시 오류가 아니면 즉시 돌려주고, 백오프를 다 써도 일시 오류면 마지막 결과를 돌려준다.
|
|
30
|
+
*/
|
|
31
|
+
export async function retryKubectlTransient(
|
|
32
|
+
run: () => KubectlCallResult,
|
|
33
|
+
first: KubectlCallResult,
|
|
34
|
+
opts: { sleep: (ms: number) => Promise<void>; category: string; data?: Record<string, unknown>; backoffMs?: readonly number[] },
|
|
35
|
+
): Promise<KubectlCallResult> {
|
|
36
|
+
const backoff = opts.backoffMs ?? KUBECTL_TRANSIENT_BACKOFF_MS;
|
|
37
|
+
let last = first;
|
|
38
|
+
let reason = kubectlTransientReason(last);
|
|
39
|
+
for (let i = 0; i < backoff.length && reason; i++) {
|
|
40
|
+
debug.log(opts.category, 'retry', { ...opts.data, attempt: i + 1, maxAttempts: backoff.length, delayMs: backoff[i], reason });
|
|
41
|
+
await opts.sleep(backoff[i]!);
|
|
42
|
+
last = run();
|
|
43
|
+
reason = kubectlTransientReason(last);
|
|
44
|
+
if (last.status === 0) {
|
|
45
|
+
debug.log(opts.category, 'retry-recovered', { ...opts.data, attempt: i + 1 });
|
|
46
|
+
return last;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (reason) debug.log(opts.category, 'retry-exhausted', { ...opts.data, attempts: backoff.length, reason, stderr: last.stderr.trim().slice(0, 300) }, { level: 'warn' });
|
|
50
|
+
return last;
|
|
51
|
+
}
|