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
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
// Core really can run headless.
|
|
36
36
|
|
|
37
37
|
import type { LLMMessage, LLMToolSpec, ContentBlock } from '../llm.js';
|
|
38
|
-
import { debug } from '../debug/log.js';
|
|
38
|
+
import { debug, redactSecretText } from '../debug/log.js';
|
|
39
|
+
import { CoreTurnAuthRejectedError } from '../core-turn/auth-rejected-notice.js';
|
|
39
40
|
import {
|
|
40
41
|
runCoreTurn,
|
|
41
42
|
runGoalLoop,
|
|
@@ -49,20 +50,25 @@ import type { AcpServerOptions, AcpTurnContext } from './server.js';
|
|
|
49
50
|
import { acpToolDenialResult } from './tool-approval.js';
|
|
50
51
|
import { readOriginSessionMeta } from './origin-session-meta.js';
|
|
51
52
|
import { isFactQuestion } from './fact-question.js';
|
|
52
|
-
import { classifyTuiChatIntent, type TuiChatRoute } from '../core-turn/short-question.js';
|
|
53
|
+
import { classifyTuiChatIntent, formatTuiRouteLine, type TuiChatRoute } from '../core-turn/short-question.js';
|
|
53
54
|
import { HARNESS_ROLE_ENV } from '../harness/harness-space.js';
|
|
54
55
|
|
|
55
56
|
const FACT_QUESTION_INSTRUCTION = '사실·최신 정보 질문이다. WebSearch 를 1~2회 쓰고 검색 결과(제목·스니펫·URL)로 답하라. 출처 링크를 붙여라. 셸·브라우저·파일 도구는 검색 결과로 부족할 때만. 도구 예산에 닿으면 지금까지 근거로 답하고 끝에 «더 찾아볼까요?»를 붙여라.';
|
|
56
57
|
|
|
58
|
+
// 읽기·분석 keeps every tool (it reads files and state) and only leaves the goal loop.
|
|
59
|
+
type QuickTuiRoute = Exclude<TuiChatRoute, '코딩·구현' | '읽기·분석'>;
|
|
60
|
+
|
|
57
61
|
// An allowlist, not a denylist: a new repository writer cannot slip into a quick turn.
|
|
58
|
-
|
|
62
|
+
// memory_recall is read-only and on every quick route: the self-access discipline (agent/self-ambient.ts) tells
|
|
63
|
+
// every turn to recall before judging, so a route without it asked for a tool it could not call (TUI-SEAT-MEMORY-SCOPE).
|
|
64
|
+
const QUICK_TOOLS: Record<QuickTuiRoute, readonly string[]> = {
|
|
59
65
|
'조회': ['decisions_pending', 'ops_seats', 'ops_status', 'release_status', 'logs_query', 'context_now', 'memory_recall', 'Read'],
|
|
60
|
-
'설정 변경': ['DashboardConfigGet', 'DashboardConfigSet', 'LlmListAvailableModels', 'prompt_getRuntimeConfig', 'prompt_setRuntimeConfig', 'view_getConfig', 'view_applyRuntimeConfig', 'view_saveConfig'],
|
|
61
|
-
'조사': ['WebSearch', 'OmniSearch', 'Grep', 'Glob', 'Read', 'fact_check'],
|
|
62
|
-
'상시 일': ['schedule_manage', 'schedule_list', 'schedule_create', 'schedule_update', 'session_manage', 'ops_status'],
|
|
66
|
+
'설정 변경': ['DashboardConfigGet', 'DashboardConfigSet', 'LlmListAvailableModels', 'prompt_getRuntimeConfig', 'prompt_setRuntimeConfig', 'view_getConfig', 'view_applyRuntimeConfig', 'view_saveConfig', 'memory_recall'],
|
|
67
|
+
'조사': ['WebSearch', 'OmniSearch', 'Grep', 'Glob', 'Read', 'fact_check', 'memory_recall'],
|
|
68
|
+
'상시 일': ['schedule_manage', 'schedule_list', 'schedule_create', 'schedule_update', 'session_manage', 'ops_status', 'memory_recall'],
|
|
63
69
|
};
|
|
64
70
|
|
|
65
|
-
export function toolsForTuiRoute(tools: readonly LLMToolSpec[], route:
|
|
71
|
+
export function toolsForTuiRoute(tools: readonly LLMToolSpec[], route: QuickTuiRoute): LLMToolSpec[] {
|
|
66
72
|
const preferred = QUICK_TOOLS[route];
|
|
67
73
|
return preferred.flatMap((name) => tools.filter((tool) => tool.name === name));
|
|
68
74
|
}
|
|
@@ -155,6 +161,10 @@ export function acpApprovalGatedDispatch(
|
|
|
155
161
|
};
|
|
156
162
|
}
|
|
157
163
|
|
|
164
|
+
/** 사용자 답에서 뺀 검증 보충을 로그에 남길 때 한 조각의 글자 수 — 로그 저장의 문자열 상한
|
|
165
|
+
* (`compactForLog` stringMax 256)보다 작아야 조각이 저장 중에 안 잘린다(리뷰 r4). */
|
|
166
|
+
const FINAL_SUPPLEMENT_LOG_CHUNK = 240;
|
|
167
|
+
|
|
158
168
|
/** Extract the trailing assistant message text from runCoreTurn's
|
|
159
169
|
* `newMessages` array. emitTurnComplete (src/llm.ts:3835) appends
|
|
160
170
|
* `{role:'assistant', content:[{type:'text', text:finalAssistantText}]}`
|
|
@@ -223,7 +233,7 @@ export function bridgeCoreTurnToAcp(
|
|
|
223
233
|
hasAttachments: turnCtx.promptBlocks?.some((block) => block.type !== 'text') ?? false,
|
|
224
234
|
})
|
|
225
235
|
: { route: '코딩·구현' as const, reason: harness ? 'harness' : 'legacy', goalLoop: true };
|
|
226
|
-
const tools = !route.goalLoop && route.route !== '코딩·구현'
|
|
236
|
+
const tools = !route.goalLoop && route.route !== '코딩·구현' && route.route !== '읽기·분석'
|
|
227
237
|
? toolsForTuiRoute(availableTools, route.route)
|
|
228
238
|
: availableTools;
|
|
229
239
|
if (deps.tuiRouting) {
|
|
@@ -231,12 +241,27 @@ export function bridgeCoreTurnToAcp(
|
|
|
231
241
|
// Only a quick route is announced: a coding turn's transcript stays exactly as before (preservation).
|
|
232
242
|
// Awaited so the route line precedes the answer; a failed write is observed, not fatal to the turn.
|
|
233
243
|
if (!route.goalLoop) {
|
|
234
|
-
try { await turnCtx.push(
|
|
244
|
+
try { await turnCtx.push(formatTuiRouteLine(route.route)); }
|
|
235
245
|
catch (error) { debug.log('chat.route', 'push-failed', { route: route.route, error: String(error) }); }
|
|
236
246
|
}
|
|
237
247
|
}
|
|
238
248
|
const modelOverride = deps.resolveModel?.({ sessionId: turnCtx.sessionId, userText: turnCtx.userText });
|
|
239
|
-
|
|
249
|
+
// Tier 2 arming(config-gated·2026-07-19 goal-exec → 아크4 전-family) — llm.goalLoop.enabled
|
|
250
|
+
// 면 across-turn goal loop(runGoalLoop)로 감싸 목표 완료(update_goal 증거게이트)까지 지속·
|
|
251
|
+
// continuation 재주입. **family 무관**(runGoalLoop 프롬프트·update_goal 툴 전부 provider-generic·
|
|
252
|
+
// 백스톱=max-iter·spin·blocked-3strike·context-pressure). 그 외엔 단일 turn(runCoreTurn).
|
|
253
|
+
// 하드코딩 기본 ON 아님 — config 로 아밍(안전).
|
|
254
|
+
const goalLoopCfg = getUserConfig().llm.goalLoop;
|
|
255
|
+
const armGoalLoop = goalLoopCfg?.enabled === true && route.goalLoop;
|
|
256
|
+
// 사실 질문 예산은 «단일 턴» 전용이다 — goal loop 와 겹치면 예산을 다 쓴 뒤에도 루프가 계속 재촉해
|
|
257
|
+
// 매 continuation 이 «Tool budget reached» 로 거부되고, 모델은 그것을 도구 장애로 읽어 blocked 를 남긴다
|
|
258
|
+
// (10-14 13:48 운영 TUI OP: route short-question·goalLoop ⊕ factQuestion → 소진 뒤 헛호출 7회).
|
|
259
|
+
const factShaped = isFactQuestion(turnCtx.userText);
|
|
260
|
+
const factQuestion = factShaped && !armGoalLoop;
|
|
261
|
+
if (factShaped && armGoalLoop) {
|
|
262
|
+
try { debug.log('chat.turn', 'fact-budget-skipped', { reason: 'goal-loop-armed', route: route.route }); }
|
|
263
|
+
catch { /* observation cannot interrupt a turn */ }
|
|
264
|
+
}
|
|
240
265
|
const explicitMaxToolTurns = deps.resolveMaxToolTurns?.({ sessionId: turnCtx.sessionId });
|
|
241
266
|
const maxToolTurns = explicitMaxToolTurns ?? (factQuestion ? getUserConfig().chat.factQuestion.maxToolTurns : undefined);
|
|
242
267
|
const turnMessages: LLMMessage[] = factQuestion
|
|
@@ -262,15 +287,12 @@ export function bridgeCoreTurnToAcp(
|
|
|
262
287
|
// `delta=''` (synthesizedText lost to ACP). The dashboard never
|
|
263
288
|
// saw the substantive answer — only the streamed narration.
|
|
264
289
|
let streamedTextSum = '';
|
|
265
|
-
//
|
|
266
|
-
//
|
|
267
|
-
|
|
268
|
-
//
|
|
269
|
-
// 하드코딩 기본 ON 아님 — config 로 아밍(안전). turnFamily 는 관측용으로만 유지.
|
|
270
|
-
const goalLoopCfg = getUserConfig().llm.goalLoop;
|
|
290
|
+
// 런타임이 최종 답 꼬리에 붙인 검증 보충(변경 파일·검증 최신성·루프 마감 상태 — goal loop 내부 판정).
|
|
291
|
+
// 사용자 답에서는 빼고 로그로 보낸다(TUI 결함 #25). 코어 턴이 끝날 때마다(goal loop 반복 경계) 비운다.
|
|
292
|
+
let finalSupplement: { answer: string; supplement: string; finalText: string } | null = null;
|
|
293
|
+
// turnFamily 는 관측용으로만 유지(goal loop 아밍 판정은 위 사실 질문 판정 앞에서 한다).
|
|
271
294
|
const turnModel = modelOverride ?? getUserConfig().llm.model;
|
|
272
295
|
const turnFamily = getModelFamily(turnModel);
|
|
273
|
-
const armGoalLoop = goalLoopCfg?.enabled === true && route.goalLoop;
|
|
274
296
|
if (armGoalLoop) {
|
|
275
297
|
// 관측 — 어느 family/모델에서 across-turn goal-loop 가 아밍됐나(전-family 개방 검증).
|
|
276
298
|
debug.log('goal.loop', 'arm', { family: turnFamily, model: turnModel });
|
|
@@ -326,7 +348,7 @@ export function bridgeCoreTurnToAcp(
|
|
|
326
348
|
return approvedDispatch(name, args, dispatchCtx);
|
|
327
349
|
}
|
|
328
350
|
: approvedDispatch;
|
|
329
|
-
await runTurnDispatch({
|
|
351
|
+
const dispatchResult = await runTurnDispatch({
|
|
330
352
|
sessionId: turnCtx.sessionId,
|
|
331
353
|
...(originSessionId ? { originSessionId } : {}),
|
|
332
354
|
...(turnCtx.userText ? { userText: turnCtx.userText } : {}),
|
|
@@ -338,7 +360,11 @@ export function bridgeCoreTurnToAcp(
|
|
|
338
360
|
...(maxToolTurns !== undefined ? { maxToolTurns } : {}),
|
|
339
361
|
...((!factQuestion || explicitMaxToolTurns !== undefined) && deps.budgetGrant !== undefined ? { budgetGrant: deps.budgetGrant } : {}),
|
|
340
362
|
callbacks: {
|
|
341
|
-
onText: (delta) => {
|
|
363
|
+
onText: (delta, full) => {
|
|
364
|
+
// ⛔ 검증 보충이 붙은 최종 답의 재방출(`onText('', 답+보충)`)은 흘리지 않는다 — 빈 청크를 TUI 는
|
|
365
|
+
// «확정(commit)»으로 읽어 이미 그린 답을 굳히고, 아래 onTurnComplete 재표면화가 같은 답을
|
|
366
|
+
// «한 번 더» 그렸다(TUI 결함 #25 · 10-14 18:36 OPT). 답 표시는 onTurnComplete 가 정한다.
|
|
367
|
+
if (delta === '' && finalSupplement !== null && full === finalSupplement.finalText) return;
|
|
342
368
|
// Fire-and-forget: ACP `push` is async but the core-turn
|
|
343
369
|
// contract is synchronous onText. Chunks are delivered in
|
|
344
370
|
// order because `sessionUpdate` is serialized per-
|
|
@@ -353,6 +379,7 @@ export function bridgeCoreTurnToAcp(
|
|
|
353
379
|
// callers see today. Fire-and-forget for the same reason
|
|
354
380
|
// onText is: callbacks are synchronous, `turnCtx.push*` is
|
|
355
381
|
// async, ordering is preserved by the SDK.
|
|
382
|
+
onFinalAnswerSupplement: (info) => { finalSupplement = info; },
|
|
356
383
|
onToolCall: (call) => {
|
|
357
384
|
if (!factQuestion || maxToolTurns === undefined || maxToolTurns <= 0) {
|
|
358
385
|
toolCallCount += 1;
|
|
@@ -362,7 +389,8 @@ export function bridgeCoreTurnToAcp(
|
|
|
362
389
|
void turnCtx.pushToolCall(call);
|
|
363
390
|
},
|
|
364
391
|
onToolResult: (call) => { void turnCtx.pushToolResult(call); },
|
|
365
|
-
|
|
392
|
+
// 턴 모델(라우팅 결과)을 실어 보낸다 — 대시보드 턴 지표가 설정 모델로 ctx·단가를 잡지 않게.
|
|
393
|
+
onUsage: (usage) => { void turnCtx.pushUsage({ ...usage, model: usage.model ?? turnModel }); },
|
|
366
394
|
// Codex Responses API reasoning summary stream. Currently
|
|
367
395
|
// surfaced via forensic only (debug.log) — acts as the
|
|
368
396
|
// "did the model actually emit reasoning?" verification
|
|
@@ -438,8 +466,15 @@ export function bridgeCoreTurnToAcp(
|
|
|
438
466
|
visibleFinalText !== null
|
|
439
467
|
&& visibleFinalText.length > 0
|
|
440
468
|
&& streamedTextSum.endsWith(visibleFinalText);
|
|
469
|
+
// ⭐ 최종 답 = 모델 답 ⊕ 런타임 검증 보충이면 사용자에겐 «모델 답»만 보인다 — 보충은 로그로(#25).
|
|
470
|
+
// 대화 이력(completedMessages)엔 그대로 남아 다음 턴 맥락은 바뀌지 않는다.
|
|
471
|
+
const supplement = finalSupplement !== null && finalAssistantText === finalSupplement.finalText
|
|
472
|
+
? finalSupplement
|
|
473
|
+
: null;
|
|
474
|
+
finalSupplement = null;
|
|
441
475
|
const needsReSurface =
|
|
442
|
-
|
|
476
|
+
supplement === null
|
|
477
|
+
&& visibleFinalText !== null
|
|
443
478
|
&& visibleFinalText !== streamedTextSum
|
|
444
479
|
&& !synthesisAlreadyStreamed
|
|
445
480
|
&& !originalFinalStreamed;
|
|
@@ -452,9 +487,34 @@ export function bridgeCoreTurnToAcp(
|
|
|
452
487
|
&& visibleFinalText.startsWith(streamedTextSum),
|
|
453
488
|
endsWithStreamedTail: synthesisAlreadyStreamed,
|
|
454
489
|
needsReSurface,
|
|
490
|
+
supplementChars: supplement?.supplement.length ?? 0,
|
|
455
491
|
});
|
|
456
492
|
}
|
|
457
|
-
if (
|
|
493
|
+
if (supplement !== null) {
|
|
494
|
+
const answerStreamed = supplement.answer.length > 0 && streamedTextSum.trimEnd().endsWith(supplement.answer);
|
|
495
|
+
try {
|
|
496
|
+
// 보충 «전체»를 남긴다 — 한 행이 저장 전에 잘리지 않게 조각(part/parts)으로 나눈다(리뷰 r3·r4).
|
|
497
|
+
const redacted = redactSecretText(supplement.supplement);
|
|
498
|
+
const parts = Math.max(1, Math.ceil(redacted.length / FINAL_SUPPLEMENT_LOG_CHUNK));
|
|
499
|
+
for (let part = 0; part < parts; part += 1) {
|
|
500
|
+
debug.log('acp.turn', 'final-supplement-withheld', {
|
|
501
|
+
sessionId: turnCtx.sessionId,
|
|
502
|
+
answerChars: supplement.answer.length,
|
|
503
|
+
answerStreamed,
|
|
504
|
+
supplementChars: supplement.supplement.length,
|
|
505
|
+
part: part + 1,
|
|
506
|
+
parts,
|
|
507
|
+
supplement: redacted.slice(part * FINAL_SUPPLEMENT_LOG_CHUNK, (part + 1) * FINAL_SUPPLEMENT_LOG_CHUNK),
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
} catch { /* observation cannot interrupt a turn */ }
|
|
511
|
+
if (!answerStreamed && supplement.answer.length > 0) {
|
|
512
|
+
void turnCtx.push('');
|
|
513
|
+
void turnCtx.push(needsFollowup ? `${supplement.answer}${followupSuffix}` : supplement.answer);
|
|
514
|
+
} else if (needsFollowup) {
|
|
515
|
+
void turnCtx.push(followupSuffix);
|
|
516
|
+
}
|
|
517
|
+
} else if (originalFinalStreamed) {
|
|
458
518
|
void turnCtx.push(followupSuffix);
|
|
459
519
|
} else if (needsReSurface) {
|
|
460
520
|
// Emit a clear-then-replace pair so clients that follow
|
|
@@ -476,6 +536,22 @@ export function bridgeCoreTurnToAcp(
|
|
|
476
536
|
},
|
|
477
537
|
},
|
|
478
538
|
});
|
|
539
|
+
// ⭐ 인증 거절은 코어 턴이 «던지지 않고» 돌려준다 — 여기서 안 읽으면 서버는 end_turn 을 내고
|
|
540
|
+
// TUI 엔 «✔ 완료»만 남는다(TUI 결함 #22). 던져서 실패 경로(prompt-failed · 오류 줄)로 보낸다.
|
|
541
|
+
const stopReason = (dispatchResult as { stopReason?: unknown } | null | undefined)?.stopReason;
|
|
542
|
+
if (stopReason === 'auth_rejected') {
|
|
543
|
+
const rawError = (dispatchResult as { errorMessage?: unknown }).errorMessage;
|
|
544
|
+
const error = new CoreTurnAuthRejectedError(typeof rawError === 'string' ? rawError : undefined);
|
|
545
|
+
try {
|
|
546
|
+
debug.log('acp.turn', 'auth-rejected', {
|
|
547
|
+
sessionId: turnCtx.sessionId,
|
|
548
|
+
model: turnModel,
|
|
549
|
+
goalLoop: armGoalLoop,
|
|
550
|
+
error: error.rawMessage.slice(0, 300),
|
|
551
|
+
}, { level: 'warn' });
|
|
552
|
+
} catch { /* observation cannot interrupt a turn */ }
|
|
553
|
+
throw error;
|
|
554
|
+
}
|
|
479
555
|
} finally {
|
|
480
556
|
clearInterval(poll);
|
|
481
557
|
}
|
|
@@ -79,6 +79,8 @@ export interface ElanousUiUsagePayload {
|
|
|
79
79
|
/** Opaque correlation id. Dashboard uses `turn:<epoch>` per turn. */
|
|
80
80
|
id: string;
|
|
81
81
|
provider?: 'anthropic' | 'openai';
|
|
82
|
+
/** 그 턴이 실제로 요청한 모델(라우팅 결과 — 설정 모델과 다를 수 있다). */
|
|
83
|
+
model?: string;
|
|
82
84
|
inputTokens?: number;
|
|
83
85
|
outputTokens?: number;
|
|
84
86
|
cacheReadInputTokens?: number;
|
package/src/acp/server.ts
CHANGED
|
@@ -837,6 +837,7 @@ export interface AcpTurnContext {
|
|
|
837
837
|
* didn't advertise `elanous.ui.usage` in its ClientCapabilities. */
|
|
838
838
|
pushUsage: (usage: {
|
|
839
839
|
provider?: 'anthropic' | 'openai';
|
|
840
|
+
model?: string;
|
|
840
841
|
inputTokens?: number;
|
|
841
842
|
outputTokens?: number;
|
|
842
843
|
cacheReadInputTokens?: number;
|
|
@@ -1837,6 +1838,7 @@ function wireAcpConnection(
|
|
|
1837
1838
|
const payload: ElanousUiUsagePayload = {
|
|
1838
1839
|
id: `turn:${Date.now()}`,
|
|
1839
1840
|
...(usage.provider !== undefined ? { provider: usage.provider } : {}),
|
|
1841
|
+
...(usage.model !== undefined ? { model: usage.model } : {}),
|
|
1840
1842
|
...(usage.inputTokens !== undefined ? { inputTokens: usage.inputTokens } : {}),
|
|
1841
1843
|
...(usage.outputTokens !== undefined ? { outputTokens: usage.outputTokens } : {}),
|
|
1842
1844
|
...(usage.cacheReadInputTokens !== undefined
|
|
@@ -18,6 +18,23 @@ import { debug } from '../debug/log.js';
|
|
|
18
18
|
/** 로컬 참조 루트(기본 ~/source/ref). 다른 환경엔 없으면 무동작(graceful). */
|
|
19
19
|
export const DEFAULT_REFERENCE_ROOTS = [join(homedir(), 'source', 'ref')];
|
|
20
20
|
|
|
21
|
+
// 대표 2026-10-14 — 비공개 소스(Claude Code 사본) 통로 차단. Claude Code 는 공개 계약(code.claude.com)만 본다.
|
|
22
|
+
// ref 루트 아래 디렉터리가 실존해도 이 이름이면 그라운딩·조회 대상에서 뺀다(대소문자·`_`/`-` 변형 포함).
|
|
23
|
+
const NON_PUBLIC_REFERENCE_PATTERN = /^claude[-_]?code[-_]?(?:fork|src|source|leak|leaked)$/i;
|
|
24
|
+
|
|
25
|
+
/** 공개 계약이 아닌 참조 사본 이름인가. `owner/repo` 꼴이면 마지막 칸으로 본다. */
|
|
26
|
+
export function isNonPublicReferenceName(name: string): boolean {
|
|
27
|
+
const last = name.trim().replace(/\/+$/, '').split('/').pop() ?? '';
|
|
28
|
+
return NON_PUBLIC_REFERENCE_PATTERN.test(last);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** 거부 판정 ⊕ 관측 한 줄. 거부면 true. */
|
|
32
|
+
export function denyNonPublicReference(name: string): boolean {
|
|
33
|
+
if (!isNonPublicReferenceName(name)) return false;
|
|
34
|
+
try { debug.log('ref.grounding', 'denied', { name, reason: 'non-public-source' }); } catch { /* fail-soft */ }
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
|
|
21
38
|
function expandTilde(p: string): string {
|
|
22
39
|
return p.startsWith('~') ? join(homedir(), p.slice(1)) : p;
|
|
23
40
|
}
|
|
@@ -91,6 +108,7 @@ export function localRefGroundingDigest(taskText: string, roots: string[] = DEFA
|
|
|
91
108
|
if (!existsSync(root)) continue;
|
|
92
109
|
for (const token of tokens) {
|
|
93
110
|
if (seen.has(token)) continue;
|
|
111
|
+
if (denyNonPublicReference(token)) { seen.add(token); continue; }
|
|
94
112
|
try {
|
|
95
113
|
const path = join(root, token);
|
|
96
114
|
if (statSync(path).isDirectory()) { found.push({ path, root, token }); seen.add(token); }
|
|
@@ -652,6 +652,9 @@ export function buildReviewPrompt(
|
|
|
652
652
|
* `none of the tests …`. 표지 낱말로 시작하는 실제 블로커를 지우면 PASS/WARN 리뷰에서 블로커가 사라진다. */
|
|
653
653
|
const NONE_WORD = String.raw`(?:없음|해당\s*없음|n\/a|none|nothing)`;
|
|
654
654
|
const BARE_SENTINEL = new RegExp(String.raw`^${NONE_WORD}\s*[.。]?$`, 'i');
|
|
655
|
+
const DASH_ONLY_SENTINEL = /^[([(【]\s*[-—–]\s*[)\])】]$/;
|
|
656
|
+
// 목록 항목의 바깥 `- `와 별개로, 리뷰어가 괄호 안에도 장식 대시를 둘 수 있다: `- (- 없음 -)`.
|
|
657
|
+
const DASH_WRAPPED_BRACKETED_SENTINEL = new RegExp(String.raw`^[([(【]\s*(?:[-—–]+\s*)?${NONE_WORD}\s*(?:[-—–]+\s*)?[)\])】]$`, 'i');
|
|
655
658
|
const BRACKETED_SENTINEL = new RegExp(String.raw`^[([(【]\s*${NONE_WORD}(?:\s*[—–\-:.,;·]\s*([^)\])】]*))?\s*[)\])】]$`, 'i');
|
|
656
659
|
// ⭐ 설명 «전체»가 「지적 없음」 한 문장일 때만 — 일부만 맞아도 접으면 `(none: no blockers are checked because …)` 같은 지적이 사라진다.
|
|
657
660
|
const NO_FINDING_REMARK = new RegExp([
|
|
@@ -662,41 +665,38 @@ const NO_FINDING_REMARK = new RegExp([
|
|
|
662
665
|
String.raw`^수용\s*기준(?:을|이)?\s*(?:(?:모두|전부)\s*)?충족(?:함|됨|했다|합니다)?[.。]?$`,
|
|
663
666
|
String.raw`^(?:all\s+)?acceptance\s+criteria\s+(?:are\s+)?(?:all\s+)?met\.?$`,
|
|
664
667
|
].join('|'), 'i');
|
|
665
|
-
//
|
|
666
|
-
//
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
String.raw`must-?fix\s*(?:항목)?(?:은|는|이|가)?\s*(?:없(?:음|다|습니다)|0\s*건)`,
|
|
674
|
-
String.raw`(?:no|zero)\s+(?:blocking\s+)?(?:blockers?|must-?fix(?:es)?)(?:\s+found)?`,
|
|
675
|
-
String.raw`(?:(?:블로커|차단)\s*)?(?:수준의?\s*)?(?:결함|블로커)(?:은|는|이|가)?\s*(?:발견되지\s*않(?:음|았(?:다|습니다)?)|없(?:음|다|습니다))`,
|
|
676
|
-
].join('|') + String.raw`)\s*(?:[::—–\-·,;.。(]|$)`, 'i');
|
|
677
|
-
const LONG_REMARK_DISSENT = /하지만|그러나|다만|(?<![가-힣])단(?:,|\s)|미\s*충족|불\s*충족|충족하지|충족되지|\bbut\b|\bhowever\b|\bexcept\b|\balthough\b|\bnot\s+(?:yet\s+)?met\b|\bunmet\b/i;
|
|
678
|
-
/** 괄호 안이 «없음 + 구분자 + 무소견 머리 …» 인가 — 길이 무관(근거 안 괄호도 허용). `isNoneSentinelFinding` 의 갈래. */
|
|
668
|
+
// OP #3173 — 설명은 의미 추정하지 않는다. 실측으로 무소견임을 확인한 문장만 등록한다.
|
|
669
|
+
// 문법 밖 `없음 — 설명`은 실제 결함일 수 있으므로 mustFix에 남긴다.
|
|
670
|
+
const LONG_BRACKETED_SENTINEL = new RegExp(String.raw`^[([(【]\s*(?:[-—–]+\s*)?${NONE_WORD}\s*[—–\-:·]\s*([\s\S]+?)\s*[)\])】]$`, 'i');
|
|
671
|
+
const KNOWN_NO_FINDING_REMARKS = new Set([
|
|
672
|
+
// #27349 저장 JSON의 실제 무소견 문구.
|
|
673
|
+
'문서 전용 변경이고 의도된 산출물이 실제로 존재하며 배선 누락·죽은 코드·Goodhart 해당 없음',
|
|
674
|
+
]);
|
|
675
|
+
/** 괄호 안 `없음` 뒤 설명이 닫힌 무소견 문법에 정확히 들어가는가. */
|
|
679
676
|
function isLongNoFindingBracket(text: string): boolean {
|
|
680
677
|
const m = LONG_BRACKETED_SENTINEL.exec(text.trim());
|
|
681
678
|
if (!m) return false;
|
|
682
679
|
const remark = m[1]!.trim();
|
|
683
|
-
|
|
680
|
+
const bareRemark = remark.replace(/\s*[-—–]+\s*$/, '').trim();
|
|
681
|
+
return NO_FINDING_REMARK.test(bareRemark) || KNOWN_NO_FINDING_REMARKS.has(bareRemark);
|
|
684
682
|
}
|
|
685
683
|
/** must-fix 항목이 «지적 없음» 표지인가 — must-fix 를 세는 자리는 전부 `parseReviewResult` 를 거친다
|
|
686
684
|
* (`self review --json` 의 `mustFix` → TA `parseReviewResultOutput` → `pr land --overlap-evidence` 의 `review-must-fix-N`).
|
|
687
685
|
* ⭐ export — `parseReviewResultOutput` 가 «같은» 판정으로 저장된 결과의 표지 줄을 다시 접는다(PR-LAND-MUSTFIX-NONE · 복제 금지). */
|
|
688
686
|
export function isNoneSentinelFinding(finding: string): boolean {
|
|
689
687
|
const text = finding.trim();
|
|
690
|
-
if (
|
|
691
|
-
const
|
|
688
|
+
if (/^[-—–]+$/.test(text)) return true;
|
|
689
|
+
const markerText = text.replace(/^[—–-]+\s*|\s*[—–-]+$/g, '').trim();
|
|
690
|
+
if (markerText && (BARE_SENTINEL.test(markerText) || DASH_ONLY_SENTINEL.test(markerText) || DASH_WRAPPED_BRACKETED_SENTINEL.test(markerText))) return true;
|
|
691
|
+
const bracketed = BRACKETED_SENTINEL.exec(markerText);
|
|
692
692
|
if (bracketed) {
|
|
693
693
|
const remark = bracketed[1]?.trim();
|
|
694
694
|
if (!remark || NO_FINDING_REMARK.test(remark)) return true;
|
|
695
695
|
}
|
|
696
|
-
return isLongNoFindingBracket(
|
|
696
|
+
return isLongNoFindingBracket(markerText);
|
|
697
697
|
}
|
|
698
698
|
|
|
699
|
-
/** critic 응답 파싱 → ReviewResult.
|
|
699
|
+
/** critic 응답 파싱 → ReviewResult. VERDICT + MUST-FIX/SHOULD-FIX/REQUIREMENTS 섹션 분해.
|
|
700
700
|
* verdict=FAIL 인데 must-fix 미기재면 첫 finding 을 must 로 승격(블로커 근거 보존). */
|
|
701
701
|
/** ⭐ `VERDICT: PASS|WARN|FAIL` 판정 줄 — `parseReviewResult` 와 `reviewedResultFromRaw` 가 «같은» 정규식을 쓴다(존재 판정이 갈리면 안 된다). */
|
|
702
702
|
const VERDICT_LINE = /VERDICT:\s*(PASS|WARN|FAIL)/i;
|
|
@@ -709,6 +709,7 @@ export function parseReviewResult(text: string): ReviewResult {
|
|
|
709
709
|
const shouldFix: string[] = [];
|
|
710
710
|
const requirements: string[] = [];
|
|
711
711
|
let fallbackFinding: string | undefined;
|
|
712
|
+
let droppedNonePlaceholders = 0;
|
|
712
713
|
let section: 'must' | 'should' | 'requirements' | null = null;
|
|
713
714
|
for (const l of lines) {
|
|
714
715
|
if (/^MUST-?FIX/i.test(l)) { section = 'must'; continue; }
|
|
@@ -718,12 +719,19 @@ export function parseReviewResult(text: string): ReviewResult {
|
|
|
718
719
|
if (l.startsWith('- ')) {
|
|
719
720
|
const f = l.slice(2).trim();
|
|
720
721
|
if (!f) continue;
|
|
721
|
-
if (section === 'must') {
|
|
722
|
-
|
|
722
|
+
if (section === 'must') {
|
|
723
|
+
if (isNoneSentinelFinding(f)) droppedNonePlaceholders++;
|
|
724
|
+
else mustFix.push(f);
|
|
725
|
+
} else if (section === 'should') shouldFix.push(f);
|
|
723
726
|
else if (section === 'requirements') requirements.push(f);
|
|
724
727
|
else fallbackFinding ??= f;
|
|
725
728
|
}
|
|
726
729
|
}
|
|
730
|
+
if (droppedNonePlaceholders > 0) {
|
|
731
|
+
try {
|
|
732
|
+
debug.log('review.parse', 'none-placeholder-dropped', { count: droppedNonePlaceholders });
|
|
733
|
+
} catch { /* observation must not change parsed review data */ }
|
|
734
|
+
}
|
|
727
735
|
if (verdict === 'fail' && mustFix.length === 0) {
|
|
728
736
|
const first = shouldFix.shift() ?? fallbackFinding;
|
|
729
737
|
mustFix.push(first ?? 'PR 리뷰 FAIL — 재작업 필요(구체 지적 미파싱).');
|
|
@@ -12,6 +12,10 @@ export interface PtyUsageReemitOpts {
|
|
|
12
12
|
readonly workdir: string;
|
|
13
13
|
/** Codex session UUID observed from this child PTY; empty when unavailable (emit nothing). */
|
|
14
14
|
readonly sessionId: string;
|
|
15
|
+
/** Caller-observed metadata only. Never infer a Codex account from CODEX_HOME. */
|
|
16
|
+
readonly role?: string;
|
|
17
|
+
readonly stage?: string;
|
|
18
|
+
readonly account?: string;
|
|
15
19
|
/** Child start time: do not attribute older sessions in a shared CODEX_HOME to this child. */
|
|
16
20
|
readonly sinceMs?: number;
|
|
17
21
|
/** Override the dedup ledger location in isolated tests. */
|
|
@@ -40,6 +44,9 @@ export function reemitPtyUsage(opts: PtyUsageReemitOpts): number {
|
|
|
40
44
|
if (Number(insert.run(home, turn.turnId).changes) === 0) continue;
|
|
41
45
|
debug.log('llm.usage', 'llm-usage', {
|
|
42
46
|
runId: opts.runId,
|
|
47
|
+
...(opts.role !== undefined ? { role: opts.role } : {}),
|
|
48
|
+
...(opts.stage !== undefined ? { stage: opts.stage } : {}),
|
|
49
|
+
...(opts.account !== undefined ? { account: opts.account } : {}),
|
|
43
50
|
substrate: 'pty',
|
|
44
51
|
site: 'pty-rollup:codex',
|
|
45
52
|
turnId: turn.turnId,
|
|
@@ -16,6 +16,15 @@ export interface RunUsageInput {
|
|
|
16
16
|
cost?: { kind?: string; usd?: number; apiEquivalentUsd?: number } | null;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
/** A returned Pod raw usage row is covered only by a measured rollup from the same Job. */
|
|
20
|
+
export function excludeCoveredPodRawRows<T extends { origin?: unknown; podJob?: unknown; job?: unknown; site?: unknown; measured?: unknown }>(rows: readonly T[]): T[] {
|
|
21
|
+
const rolledUpJobs = new Set(rows.flatMap((row) =>
|
|
22
|
+
typeof row.job === 'string' && row.job.length > 0
|
|
23
|
+
&& typeof row.site === 'string' && row.site.startsWith('pod-rollup:')
|
|
24
|
+
&& row.site !== 'pod-rollup:missing' && row.measured !== false ? [row.job] : []));
|
|
25
|
+
return rows.filter((row) => row.origin !== 'pod' || typeof row.podJob !== 'string' || !rolledUpJobs.has(row.podJob));
|
|
26
|
+
}
|
|
27
|
+
|
|
19
28
|
export interface RunUsageRow {
|
|
20
29
|
runId: string;
|
|
21
30
|
role?: string;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/** Read-only UTC usage buckets from the portion of logs.db still retained. */
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { LogStore, logsDbPath, type LogStoreRow } from '../mss/logging/log-store.js';
|
|
4
|
+
|
|
5
|
+
type Metrics = {
|
|
6
|
+
calls: number; inputTokens: number; outputTokens: number; cacheReadInputTokens: number;
|
|
7
|
+
cacheCreationInputTokens: number; reasoningOutputTokens: number; usdKnown: number;
|
|
8
|
+
unknownCostCalls: number; includedCalls: number; apiEquivalentUsd: number;
|
|
9
|
+
};
|
|
10
|
+
const ZERO: Metrics = { calls: 0, inputTokens: 0, outputTokens: 0, cacheReadInputTokens: 0,
|
|
11
|
+
cacheCreationInputTokens: 0, reasoningOutputTokens: 0, usdKnown: 0, unknownCostCalls: 0,
|
|
12
|
+
includedCalls: 0, apiEquivalentUsd: 0 };
|
|
13
|
+
const FIELDS = Object.keys(ZERO) as Array<keyof Metrics>;
|
|
14
|
+
const finite = (value: unknown): number => typeof value === 'number' && Number.isFinite(value) ? value : 0;
|
|
15
|
+
const nonnegativeOr = (value: unknown, fallback: number): number =>
|
|
16
|
+
typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : fallback;
|
|
17
|
+
const label = (value: unknown): string => typeof value === 'string' && value.length > 0 ? value : '(none)';
|
|
18
|
+
const obj = (value: unknown): Record<string, unknown> | null => value && typeof value === 'object' && !Array.isArray(value)
|
|
19
|
+
? value as Record<string, unknown> : null;
|
|
20
|
+
|
|
21
|
+
function metrics(data: Record<string, unknown>): Metrics {
|
|
22
|
+
const cost = obj(data.cost);
|
|
23
|
+
const calls = nonnegativeOr(data.calls, 1);
|
|
24
|
+
const kind = cost?.kind;
|
|
25
|
+
return {
|
|
26
|
+
calls, inputTokens: finite(data.inputTokens), outputTokens: finite(data.outputTokens),
|
|
27
|
+
cacheReadInputTokens: finite(data.cacheReadInputTokens), cacheCreationInputTokens: finite(data.cacheCreationInputTokens),
|
|
28
|
+
reasoningOutputTokens: finite(data.reasoningOutputTokens),
|
|
29
|
+
usdKnown: kind === 'known' || kind === 'actual' || kind === 'partial' ? finite(cost?.usd) : 0,
|
|
30
|
+
unknownCostCalls: kind === 'unknown' || kind === 'partial' ? nonnegativeOr(cost?.unknownCostCalls, calls)
|
|
31
|
+
: kind === 'known' || kind === 'actual' || kind === 'included' ? 0 : calls,
|
|
32
|
+
includedCalls: kind === 'included' ? nonnegativeOr(cost?.includedCalls, calls) : finite(cost?.includedCalls),
|
|
33
|
+
apiEquivalentUsd: finite(cost?.apiEquivalentUsd),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function classify(row: LogStoreRow): { kind: 'host'; data: Record<string, unknown> } | { kind: 'pod' } | { kind: 'unclassified' } {
|
|
38
|
+
let data: Record<string, unknown> | null = null;
|
|
39
|
+
try { data = obj(JSON.parse(row.data ?? '')); } catch { /* unreadable payload stays unmeasured */ }
|
|
40
|
+
if (!data) return { kind: 'unclassified' };
|
|
41
|
+
if (data.origin === 'pod' || typeof data.podJob === 'string' || data.substrate === 'pod'
|
|
42
|
+
|| typeof data.site === 'string' && data.site.startsWith('pod-rollup:')) return { kind: 'pod' };
|
|
43
|
+
if (data.measured === false) return { kind: 'unclassified' };
|
|
44
|
+
return { kind: 'host', data };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface DailyUsageRow extends Metrics {
|
|
48
|
+
day: string; hour: string; role: string; stage: string; account: string; model: string;
|
|
49
|
+
billingProvider: string; billing: string; site: string; hostId: string;
|
|
50
|
+
}
|
|
51
|
+
export interface UsageDailyRead {
|
|
52
|
+
rows: DailyUsageRow[];
|
|
53
|
+
podObservedRows: number;
|
|
54
|
+
unclassifiedRows: number;
|
|
55
|
+
sourceMaxId: number;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Query every llm.usage event in bounded pages. No database or retention writes occur. */
|
|
59
|
+
export function readUsageDaily(path = logsDbPath(), sinceDay?: string): UsageDailyRead | null {
|
|
60
|
+
if (!existsSync(path)) return null;
|
|
61
|
+
const logs = LogStore.openReadOnly(path);
|
|
62
|
+
try {
|
|
63
|
+
const upper = logs.maxId();
|
|
64
|
+
const groups = new Map<string, DailyUsageRow>();
|
|
65
|
+
let afterId = 0;
|
|
66
|
+
let podObservedRows = 0;
|
|
67
|
+
let unclassifiedRows = 0;
|
|
68
|
+
const sinceMs = sinceDay === undefined ? undefined : Date.parse(`${sinceDay}T00:00:00Z`);
|
|
69
|
+
while (afterId < upper) {
|
|
70
|
+
const page = logs.query({ exactCategories: ['llm.usage'], sinceMs, afterId, limit: 1000 });
|
|
71
|
+
if (!page.length) break;
|
|
72
|
+
for (const row of page) {
|
|
73
|
+
if (row.id > upper) break;
|
|
74
|
+
const classified = classify(row);
|
|
75
|
+
if (classified.kind === 'pod') { podObservedRows++; continue; }
|
|
76
|
+
if (classified.kind === 'unclassified') { unclassifiedRows++; continue; }
|
|
77
|
+
const { data } = classified;
|
|
78
|
+
const hour = new Date(row.ts_ms).toISOString().slice(0, 13);
|
|
79
|
+
const day = hour.slice(0, 10);
|
|
80
|
+
const dimensions = [label(data.role), label(data.stage), label(data.account), label(data.model),
|
|
81
|
+
label(data.billingProvider ?? data.provider), label(data.billing), label(data.site), label(data.hostId ?? row.host_id)];
|
|
82
|
+
const key = JSON.stringify([hour, ...dimensions]);
|
|
83
|
+
let value = groups.get(key);
|
|
84
|
+
if (!value) {
|
|
85
|
+
const [role, stage, account, model, billingProvider, billing, site, hostId] = dimensions;
|
|
86
|
+
value = { day, hour, role: role!, stage: stage!, account: account!, model: model!, billingProvider: billingProvider!,
|
|
87
|
+
billing: billing!, site: site!, hostId: hostId!, ...ZERO };
|
|
88
|
+
groups.set(key, value);
|
|
89
|
+
}
|
|
90
|
+
const delta = metrics(data);
|
|
91
|
+
for (const field of FIELDS) value[field] += delta[field];
|
|
92
|
+
}
|
|
93
|
+
afterId = page.at(-1)!.id;
|
|
94
|
+
}
|
|
95
|
+
return { rows: [...groups.values()].sort((a, b) => a.hour.localeCompare(b.hour)),
|
|
96
|
+
podObservedRows, unclassifiedRows, sourceMaxId: upper };
|
|
97
|
+
} finally { logs.close(); }
|
|
98
|
+
}
|
|
@@ -42,7 +42,9 @@ import {
|
|
|
42
42
|
upsertPtyManifest, updatePtyManifestFrame, touchLivePtyManifest, markPtyManifestClosed, removePtyManifest,
|
|
43
43
|
} from '../pty-shell/pty-manifest.js';
|
|
44
44
|
import { writeHarnessScreen } from '../harness/harness-screen.js';
|
|
45
|
+
import { startTuiRunStateRecorder } from '../pty-shell/tui-run-state.js';
|
|
45
46
|
import { debug } from '../debug/log.js';
|
|
47
|
+
import { routeExternalInput, type ExternalInputRoute } from '../input/external-input-queue.js';
|
|
46
48
|
|
|
47
49
|
export interface TuiFrameObserverCfg {
|
|
48
50
|
surfaceId: string;
|
|
@@ -99,6 +101,8 @@ export interface TuiControlTargetDeps {
|
|
|
99
101
|
splitKeys?: (input: string) => Key[];
|
|
100
102
|
/** The foreground terminal's real size; `undefined` when it cannot be known (stdout is not a TTY). */
|
|
101
103
|
dims?: () => { readonly cols: number; readonly rows: number } | undefined;
|
|
104
|
+
/** 외부 주입 라우터 — 글 한 줄을 사용자 버퍼에 섞지 않고 별도 대기열로 돌린다(`input/external-input-queue`). */
|
|
105
|
+
routeExternal?: (chars: string) => ExternalInputRoute;
|
|
102
106
|
}
|
|
103
107
|
|
|
104
108
|
function stdoutDims(): { cols: number; rows: number } | undefined {
|
|
@@ -116,6 +120,7 @@ export function createTuiControlTarget(surfaceId: string, deps: TuiControlTarget
|
|
|
116
120
|
const inject = deps.injectKey ?? injectKey;
|
|
117
121
|
const parse = deps.splitKeys ?? splitKeys;
|
|
118
122
|
const dims = deps.dims ?? stdoutDims;
|
|
123
|
+
const routeExternal = deps.routeExternal ?? routeExternalInput;
|
|
119
124
|
let alive = true;
|
|
120
125
|
let accessMode: PtyAccessMode = 'write';
|
|
121
126
|
let transitionPolicy: PtyTransitionPolicy = 'open';
|
|
@@ -135,6 +140,8 @@ export function createTuiControlTarget(surfaceId: string, deps: TuiControlTarget
|
|
|
135
140
|
isAlive: () => alive,
|
|
136
141
|
canWrite: (actor: PtyWriteActor = 'human') => resolveWriteDecision(accessMode, actor).allow,
|
|
137
142
|
write(chars: string): void {
|
|
143
|
+
// ⭐ 이 write 는 «바깥»(제어 IPC)에서만 온다 — 키보드와 섞이기 전에 라우터가 먼저 가른다.
|
|
144
|
+
if (routeExternal(chars) !== 'passthrough') return;
|
|
138
145
|
const keys = parse(chars);
|
|
139
146
|
if (!keys.length || !keys.every(inject)) throw new Error('tui-input-undelivered');
|
|
140
147
|
},
|
|
@@ -145,11 +152,13 @@ export function createTuiControlTarget(surfaceId: string, deps: TuiControlTarget
|
|
|
145
152
|
|
|
146
153
|
export interface TuiSelfReportDeps {
|
|
147
154
|
surfaceId?: string;
|
|
155
|
+
/** `elanous --name <name>` — 자기 manifest 행 별명. `pty list`·`pty snapshot <name>` 이 이것으로 부른다. */
|
|
156
|
+
nickname?: string;
|
|
148
157
|
throttleMs?: number;
|
|
149
158
|
now?: () => number;
|
|
150
159
|
register?: (fn: ((lines: readonly string[], dims: { rows: number; cols: number }) => void) | null) => void;
|
|
151
160
|
publishFrame?: (frame: SelfReportFrame) => void;
|
|
152
|
-
registerRow?: (surfaceId: string, now: number) => void;
|
|
161
|
+
registerRow?: (surfaceId: string, now: number, nickname?: string) => void;
|
|
153
162
|
writeFrame?: (surfaceId: string, text: string, now: number) => void;
|
|
154
163
|
/** B(harness-screens 파일) sink — `elanous self screen` 이 읽는 substrate.
|
|
155
164
|
* 자식 harness 발행과 대칭(tmux 없이 L2 대시보드 자기 화면 관측). */
|
|
@@ -174,6 +183,8 @@ export interface TuiSelfReportDeps {
|
|
|
174
183
|
startControlPoller?: () => (() => void);
|
|
175
184
|
reportControlInitFailure?: (stage: TuiControlInitStage, error: unknown) => void;
|
|
176
185
|
reportControlCleanupFailure?: (stage: TuiControlCleanupStage, error: unknown) => void;
|
|
186
|
+
/** 행 등록 직후 실행 판 ⊕ 턴(idle) 기록을 연다 — `elanous pty state` 가 읽는다. 반환 = 정리. */
|
|
187
|
+
startRunState?: (surfaceId: string) => (() => void);
|
|
177
188
|
}
|
|
178
189
|
|
|
179
190
|
export type TuiControlInitStage = 'create-target' | 'register-target' | 'start-poller' | 'publish-manifest';
|
|
@@ -235,7 +246,9 @@ export function startTuiSelfReport(deps: TuiSelfReportDeps = {}): () => void {
|
|
|
235
246
|
initDisposers.push({ stage: 'stop-poller', dispose: stopControlPoller });
|
|
236
247
|
controlInitStage = 'publish-manifest';
|
|
237
248
|
initDisposers.push({ stage: 'rollback-manifest', dispose: () => rollbackRow(surfaceId) });
|
|
238
|
-
|
|
249
|
+
const nickname = deps.nickname?.trim() || undefined;
|
|
250
|
+
registerRow(surfaceId, now(), nickname);
|
|
251
|
+
if (nickname) debug.log('pty.rename', 'tui-launch-name', { ptyId: surfaceId, nickname });
|
|
239
252
|
} catch (error) {
|
|
240
253
|
for (let disposer = initDisposers.pop(); disposer; disposer = initDisposers.pop()) {
|
|
241
254
|
try { disposer.dispose(); } catch (cleanupError) {
|
|
@@ -246,6 +259,10 @@ export function startTuiSelfReport(deps: TuiSelfReportDeps = {}): () => void {
|
|
|
246
259
|
return () => {};
|
|
247
260
|
}
|
|
248
261
|
const activeControlTarget = controlTarget;
|
|
262
|
+
let stopRunState: () => void = () => {};
|
|
263
|
+
// 행 등록을 갈아 끼운 호출자(시험)는 실 manifest 를 안 건드린다 — 기본 녹음기는 기본 행 등록과 짝일 때만.
|
|
264
|
+
const startRunState = deps.startRunState ?? (deps.registerRow ? () => () => {} : startTuiRunStateRecorder);
|
|
265
|
+
try { stopRunState = startRunState(surfaceId); } catch { /* fail-soft — recorder logs its own write failures */ }
|
|
249
266
|
const driveTicks = deps.driveTicks ?? ((tick, ms) => {
|
|
250
267
|
const t = setInterval(tick, ms);
|
|
251
268
|
(t as { unref?: () => void }).unref?.();
|
|
@@ -320,6 +337,7 @@ export function startTuiSelfReport(deps: TuiSelfReportDeps = {}): () => void {
|
|
|
320
337
|
try { stopSource(); } catch { /* fail-soft — unregisters observer / clears tick timer */ }
|
|
321
338
|
try { mirror?.stop(); } catch { /* fail-soft — restores stdout.write */ }
|
|
322
339
|
clearInterval(hb);
|
|
340
|
+
try { stopRunState(); } catch { /* fail-soft */ }
|
|
323
341
|
try { markClosed(surfaceId, now()); } catch { /* fail-soft */ }
|
|
324
342
|
try { activeControlTarget?.deactivate(); } catch { /* fail-soft */ }
|
|
325
343
|
try { stopControlPoller(); } catch { /* fail-soft */ }
|
|
@@ -357,8 +375,8 @@ function defaultPublishFrame(frame: SelfReportFrame): void {
|
|
|
357
375
|
publishSelfReportFrame(getChannelBus(), frame);
|
|
358
376
|
}
|
|
359
377
|
|
|
360
|
-
function defaultRegisterRow(surfaceId: string, now: number): void {
|
|
361
|
-
upsertPtyManifest({ id: surfaceId, kind: 'tui', cmd: 'elanous', startedAt: now, now });
|
|
378
|
+
function defaultRegisterRow(surfaceId: string, now: number, nickname?: string): void {
|
|
379
|
+
upsertPtyManifest({ id: surfaceId, kind: 'tui', ...(nickname ? { nickname } : {}), cmd: 'elanous', startedAt: now, now });
|
|
362
380
|
}
|
|
363
381
|
|
|
364
382
|
function defaultWriteFrame(surfaceId: string, text: string, now: number): void {
|