elanous 0.2.28 → 0.2.31
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 → LSXfY0u9QtfDbejY0Ukf_}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{ab4d57c2.e90bc2cb31949045.js → 0bb0ff36.b8d418980951e5ba.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +27 -0
- package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +287 -0
- package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +62 -0
- package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5492-e05e26a033ba80d2.js → 1335-6731f392c35216eb.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1654.32de4b324981a188.js +23 -0
- package/apps/pwa/out/_next/static/chunks/1834-50625904996a8fa8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +149 -0
- package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +41 -0
- package/apps/pwa/out/_next/static/chunks/2001.6c7e0fd02190886c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8578.dff22d988cc2b106.js → 2213.2ccbada92c33ea0f.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5081.a240b63fad28663a.js → 2871.0bca6137343b3f76.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2898.fd781bc7cf01a7b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2940-619bfd8ef337c611.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2846.d6a433b8663819a5.js → 2985.39ccdecd36848b12.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +115 -0
- package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +64 -0
- package/apps/pwa/out/_next/static/chunks/{f4dfbfc0.a69fb12f854882aa.js → 3267c0e6.d34854e7b3984a6e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3278.2e5d15b53a4091c8.js +2 -0
- package/apps/pwa/out/_next/static/chunks/3541-ce3a5424ed5ad7f1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3143.257997a5f1ed79df.js → 3902.e1e71aaac850a045.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{16e57f67.3ea19e893461e611.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1146.80d15ea7c6e6ee95.js → 4111.2bfedbb233ad206b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1516.83dd2c1b86b4e507.js → 4174.92ed04922709ac9e.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +36 -0
- package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +286 -0
- package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +77 -0
- package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +226 -0
- package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9938.b23e4d4dfa0114cd.js → 4999.c064a4000c2a9e94.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/5173-233188df2f42c626.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1157.f08bf2b70915e176.js → 5304.04d24756f242a094.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{7752.5cbdd0b433c54af9.js → 5307.60f2209e809bd627.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9917-9e26abc5f7772735.js → 5458-16cd7a2b51b74c8c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6196.34d6b229079e9e28.js → 5525.86debf231e181813.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4593.10f5b9bd702d4a6c.js → 5543.a438b8ab5a13ea47.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +74 -0
- package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +94 -0
- package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7483.ba01c6c209b81bba.js → 6092.a7f99e68b188ca66.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9974.e77b4ff4884557b3.js → 6157.0c9af021de4fb31b.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3309.364573ceedbdfd5f.js → 6323.8672b4817a306928.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{94.4cfed21c0b781a06.js → 6433.fc573af22bbc9ab7.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{949.1e7d45ccb71580aa.js → 6517.4147878ac06d584d.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +32 -0
- package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +104 -0
- package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2528.3868070ef1be69f9.js → 6767.ea607cf0c20a25af.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +93 -0
- package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1743.563d3168e95825ef.js → 7502.ccd5b8065545edd0.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +8 -0
- package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5408.377c8c543635b81f.js → 7862.30a8d6482bb238eb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{65ebff95.081daeff622d238e.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2697.76ca2ac3efef6f3b.js → 8018.a32663f04a6fc5f9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8097-92f87bd108322f66.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +1 -0
- package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +24 -0
- package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9138.b6e80031afb1d973.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4204.a409ab6250c0f6a8.js → 9221.7d22eaf353a2d4e7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5785-ea8d2c633b6688e3.js → 9279-d28c5b7754d010ae.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9398-6aed28f0a96d0d6f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/997ce8a5-2ad501927003b41b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9311.24c8f5ea793253dd.js → 9989.3694300e5f000b14.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-bf3634a117322df7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-3535a4a69f1fafaa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-b9f51447f757fbf2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-fa46d4588e8442c2.js → page-2ebb8fd59b9461f9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-a2fc4e49a4fa4ba8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-5a503541353e60a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-6025101384e361a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-f4b630cc8b5273cd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-a645f00a06483e9a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-61ac22cbab1ee4ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-e9bab7413b028b28.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-c992eafe028b642e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-e547e6ce55f1fb33.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-d27e1b9850fd54bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-805ac2e137b7a121.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-0fec29c7ba01894b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-339a07410cd6f36b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/{page-ced0bcfc6542b3fc.js → page-349f2752d8cd37ad.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-d5c6dcf31c25cecc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-2fd93ed8c9f16580.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-9b564dbff0fefc35.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-62f4475d3c38fb9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-814ba51385225776.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-397d479626e5a459.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-af1bba4e3251b728.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ad3be5e7d3fdce9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-f219ccdbc0bf27df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4da93ad35d4a8d28.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-456666766e5ce6fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-7404e377e8adb8c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-14456240ed2a36ad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-3a658d5fa6d16a25.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-0157de6e85f8bb6b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-cb249e81ed339318.js → page-0a07363b130182a1.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-841d73d4ac44ed49.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6f43a3d1146e6377.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-521ee23ac8c0abfa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-a9992ee285efaa83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-3d48e85fa89ec04f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-d2ced71132fac9b2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-f08358bdf251adb9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-233c71cd5f68f0d7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-70151d78de2f375e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-dcac33a3e2cb72c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-149dc1caba411bb9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-0448145ccd5c45c1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-9cb0c444903da65d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-17e504c396e0e389.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6def8a8e.c81f9ca41028eccf.js → b313b242.cb1265eea908db61.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{e87d89b9.2e71c0ae475d28a1.js → e5012ffe.f727e23c231f4342.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{e117f801.e92bf10242653497.js → ebc7d829.264a0bcb6c750b50.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +1 -0
- package/apps/pwa/out/_next/static/css/{72becfd42807b50d.css → 3f5fc6f96e2cf7b2.css} +1 -1
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +23 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +22 -22
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +23 -23
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/bin/elanous.mjs +7 -3
- package/graphs/context/nightly-condense.yaml +1 -0
- package/graphs/intake/intake-daily.yaml +8 -1
- package/graphs/intake/recipes.yaml +5 -0
- package/graphs/lecture/lecture-note.yaml +2 -2
- package/graphs/ops/harness-gc.yaml +1 -0
- package/graphs/release/recipes.yaml +3 -0
- package/graphs/release/release-loop.yaml +15 -7
- package/graphs/units/recipes.yaml +3 -0
- package/graphs/units/release-gate-recheck.yaml +15 -0
- package/package.json +2 -1
- package/plugins/agent-team/agents/research.md +1 -0
- package/scripts/check-native-tool-wiring.ts +3 -2
- package/scripts/ci-android-unit-tests.ts +16 -0
- package/scripts/ci-typecheck-changed.ts +40 -11
- package/scripts/coord-channel-watch.sh +45 -19
- package/scripts/coord-role-pack.ts +222 -0
- package/scripts/cron-run.ts +96 -3
- package/scripts/detect-test-interference.ts +38 -5
- package/scripts/gate-pr-cache.ts +65 -0
- package/scripts/gh-surface/capture.ts +126 -0
- package/scripts/gh-surface/gh +40 -0
- package/scripts/import-graph-scc.ts +38 -0
- package/scripts/install.ps1 +19 -0
- package/scripts/intake-social.ts +181 -0
- package/scripts/lecture-note/node.ts +71 -4
- package/scripts/lib/android-toolchain.ts +32 -0
- package/scripts/lib/deterministic-env.ts +62 -0
- package/scripts/lib/gate-test-env.ts +19 -0
- package/scripts/lib/morning-report-options.ts +41 -0
- package/scripts/measure-goal-grounding-corpus.ts +2 -1
- package/scripts/pr-land-extra-remote-gates.ts +49 -0
- package/scripts/ratchets/test-interference-patterns.allowlist.txt +257 -0
- package/scripts/ratchets/test-interference-patterns.ts +367 -0
- package/scripts/release-loop/cut-branch.ts +4 -3
- package/scripts/release-loop/export-check-node.ts +0 -1
- package/scripts/release-loop/fixtures/warm-failure-assertion/sample.junit.xml +8 -0
- package/scripts/release-loop/fixtures/warm-job-029/sample.json +1 -0
- package/scripts/release-loop/fixtures/warm-job-029/sample.junit.xml +10 -0
- package/scripts/release-loop/gate-batch-safe.ts +23 -0
- package/scripts/release-loop/gate-closure.ts +12 -8
- package/scripts/release-loop/gate-diff.ts +1 -1
- package/scripts/release-loop/gate-history.ts +422 -0
- package/scripts/release-loop/gate-host-mirror.ts +66 -0
- package/scripts/release-loop/gate-node.ts +806 -94
- package/scripts/release-loop/gate-partial.ts +106 -9
- package/scripts/release-loop/gate-pr-cache.ts +66 -0
- package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
- package/scripts/release-loop/gate-r2-verdict.ts +189 -0
- package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
- package/scripts/release-loop/gate-triage-node.ts +190 -0
- package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
- package/scripts/release-loop/import-graph-scc-run.ts +54 -0
- package/scripts/release-loop/import-graph-scc.ts +215 -0
- package/scripts/release-loop/node-verdict.ts +2 -0
- package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
- package/scripts/release-loop/resume-release.ts +33 -4
- package/scripts/release-loop/resume.ts +13 -5
- package/scripts/release-loop/spawn-lane.ts +51 -0
- package/scripts/release-loop/tui-node-checks.ts +23 -0
- package/scripts/release-loop/tui-sim-node.ts +3 -2
- package/scripts/release-loop/unattended-release.ts +16 -0
- package/scripts/release-loop/version-node.ts +62 -4
- package/scripts/test-deterministic.ts +46 -73
- package/scripts/train-reach-grouping.ts +48 -0
- package/scripts/tsc-incremental-cache.ts +86 -0
- package/scripts/tsc-incremental-diagnostics.ts +76 -0
- package/scripts/tsc-main-safety-net.ts +2 -2
- package/scripts/usage-rollup.ts +11 -3
- package/src/acp/client.ts +4 -1
- package/src/acp/core-turn-bridge.ts +145 -24
- package/src/acp/elanous-extensions.ts +2 -0
- package/src/acp/server.ts +2 -0
- package/src/ad-pipeline/run.ts +4 -2
- package/src/agent/ref-grounding.ts +18 -0
- package/src/agent/runner.ts +169 -3
- package/src/agent/subagent-callable.ts +3 -2
- package/src/agent-mission/review-loop.ts +6 -3
- package/src/agent-substrate/acp-implementer.ts +14 -2
- package/src/agent-substrate/pr-reviewer.ts +41 -21
- package/src/agent-substrate/self-review-cli.ts +30 -4
- package/src/autopilot/pr-manager.ts +62 -7
- package/src/briefing/brief-items.ts +24 -22
- 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 +37 -4
- package/src/chat/chat-cli.ts +10 -2
- package/src/chat/index.ts +107 -20
- package/src/chat/input-control-key.ts +5 -3
- package/src/chat/pickers/modal-runtime.ts +1 -0
- package/src/chat/pickers/modals.ts +3 -1
- package/src/chat/tool-interrupt-behavior.ts +38 -0
- package/src/chat/tool-render/dispatch.ts +5 -1
- package/src/chat/turn-typeahead.ts +191 -29
- package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
- package/src/cli/agent-cli.ts +41 -13
- package/src/cli/config-audit.ts +123 -0
- package/src/cli/dashboard-name-flag.ts +48 -0
- package/src/cli/decisions-cli.ts +80 -6
- package/src/cli/doctor-cli.ts +80 -0
- package/src/cli/log-event-names.ts +19 -0
- package/src/cli/mcp-login.ts +21 -5
- package/src/cli/msg-cli.ts +133 -2
- package/src/cli/pr-cli.ts +546 -112
- package/src/cli/pr-land-heavy-remote.ts +233 -0
- package/src/cli/pr-land-overlap-evidence.ts +167 -14
- package/src/cli/pr-land-pod-shadow-job.ts +83 -0
- package/src/cli/pr-land-pod-shadow.ts +16 -3
- package/src/cli/pr-land-virtual-rebase.ts +108 -0
- package/src/cli/pty-takeover-cli.ts +125 -16
- package/src/cli/release-cli.ts +122 -14
- package/src/cli/remote-resolve.ts +2 -1
- package/src/cli/seat-cli.ts +164 -19
- package/src/cli/self-update.ts +5 -2
- package/src/cli/tasks-cli.ts +105 -21
- package/src/cli/usage-cli.ts +146 -12
- package/src/cli/usage-daily-cli.ts +84 -0
- package/src/context-bus/context-first.ts +13 -0
- package/src/context-bus/context-now.ts +95 -7
- package/src/context-bus/ops-events.ts +75 -0
- package/src/control-plane/lease-holder.ts +12 -8
- package/src/control-plane/ledger.ts +163 -4
- package/src/control-plane/server.ts +91 -11
- package/src/core-turn/auth-rejected-notice.ts +41 -0
- package/src/core-turn/run-core-turn.ts +14 -2
- package/src/core-turn/run-goal-loop.ts +239 -4
- package/src/core-turn/seat-turn-cap.ts +79 -0
- package/src/core-turn/short-question.ts +78 -13
- package/src/core-turn/types.ts +10 -0
- package/src/dashboard/acp-active-model.ts +40 -0
- package/src/dashboard/acp-boot.ts +3 -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 +448 -998
- 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 +176 -4
- package/src/dashboard/input/chat-main-session.ts +14 -3
- package/src/dashboard/input/chat-main-slash-command.ts +7 -0
- package/src/dashboard/input/chat-main-turn.ts +14 -4
- package/src/dashboard/input/compact-prepass-recovery.ts +130 -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 +71 -0
- package/src/dashboard/input/internal-turn.ts +261 -0
- package/src/dashboard/input/log-fold-binding.ts +18 -0
- package/src/dashboard/input/mouse-wiring.ts +17 -4
- package/src/dashboard/input/seat-autowake.ts +318 -0
- package/src/dashboard/input/turn-steer-bridge.ts +164 -0
- package/src/dashboard/log-click-runtime.ts +5 -3
- package/src/dashboard/loop-scheduler.ts +72 -0
- package/src/dashboard/running-build-status.ts +74 -0
- package/src/dashboard/seat-boot-preamble.ts +131 -0
- package/src/dashboard/seat-local-instructions.ts +305 -0
- package/src/dashboard/skill-runtime.ts +2 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +220 -1203
- package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
- package/src/dashboard/slash-runtime/index.ts +13 -0
- package/src/dashboard/slash-runtime/model-choices.ts +35 -0
- package/src/dashboard/term-slash-runtime.ts +15 -0
- package/src/dashboard/turn-busy-teardown.ts +50 -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/decisions/decision-ledger.ts +45 -4
- package/src/discord-self-message.ts +4 -4
- package/src/domains/release-tool.ts +26 -10
- package/src/domains/surface-events.ts +4 -1
- package/src/domains/watch-default-scheduler.ts +8 -9
- package/src/field-note/transcribe.ts +17 -0
- 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/github/remote-call.ts +81 -0
- package/src/goals/registry.ts +46 -6
- package/src/goals/types.ts +7 -1
- package/src/graph-runner/runner.ts +2 -0
- package/src/grok/credential.ts +26 -0
- package/src/harness/harness-clean.ts +2 -1
- package/src/harness/harness-cli-command.ts +52 -5
- package/src/harness/harness-gc.ts +34 -6
- package/src/harness/harness-incidents.ts +57 -20
- package/src/harness/harness-pod-dispatch.ts +87 -10
- package/src/harness/harness-queue.ts +53 -4
- package/src/harness/harness-stop.ts +4 -3
- package/src/harness/harness-substrate-default.ts +78 -7
- package/src/harness/harness-worktree-auto.ts +2 -1
- package/src/harness/harness-worktrees.ts +3 -2
- package/src/hooks/dispatch.ts +2 -1
- package/src/index.ts +166 -26
- package/src/input/external-input-queue.ts +251 -0
- package/src/intake-plane/slash.ts +14 -3
- package/src/interactive-terminal-modal.ts +13 -0
- package/src/keybindings.ts +4 -1
- package/src/llm/route-decision.ts +25 -0
- package/src/llm/tool-loop-steered-rejection.ts +33 -0
- package/src/llm-stream-retry-display.ts +59 -0
- package/src/llm.ts +391 -74
- 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/consensus.ts +348 -0
- package/src/loops/loop-cli.ts +3 -2
- package/src/loops/msg-address.ts +57 -0
- package/src/loops/msg-wake.ts +484 -0
- package/src/loops/observe.ts +19 -3
- package/src/loops/orchestrator/inbox.ts +60 -3
- package/src/loops/orchestrator/tick.ts +80 -6
- package/src/loops/orchestrator/traffic.ts +64 -1
- package/src/loops/registry.ts +72 -4
- package/src/market/signed-index.ts +14 -0
- package/src/mcp/mcp-oauth.ts +54 -5
- package/src/memory.ts +20 -5
- package/src/models/prompts.ts +28 -0
- package/src/msg/msg-sse-client.ts +223 -0
- package/src/msg/msg-store.ts +86 -2
- package/src/mss/logging/log-store.ts +225 -1
- package/src/native-tool-catalog.ts +125 -0
- package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
- package/src/nexus/api/http-server.ts +59 -15
- package/src/nexus/api/loop-resources.ts +19 -3
- package/src/nexus/api/ops-api.ts +13 -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/daemon-thin-inventory.md +37 -0
- package/src/nexus/index.ts +70 -0
- package/src/nexus/onboarding/first-boot-wizard.ts +56 -2
- package/src/nexus/state/state.ts +1 -0
- package/src/oauth/codex-account-store.ts +15 -3
- package/src/oauth/codex-billing-route.ts +31 -0
- package/src/oauth/store.ts +32 -7
- package/src/onboarding/first-run.ts +28 -3
- package/src/ops/overview-cache.ts +16 -4
- package/src/ops/overview-collect.ts +19 -2
- package/src/ops/resources.ts +82 -0
- package/src/panes/log-pane.ts +67 -8
- package/src/persona/presets.ts +44 -0
- package/src/plugins/maker/connector-maker.ts +41 -0
- package/src/plugins/maker/skill-maker.ts +42 -0
- package/src/plugins/maker/wizard-generate.ts +6 -4
- package/src/pr-tool/census.ts +288 -0
- 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/chat-conciseness.ts +13 -0
- package/src/prompt-library/universal-preamble.ts +283 -61
- 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/gate-host-reservation.ts +97 -0
- package/src/release-loop/landing-freeze.ts +5 -0
- package/src/release-loop/light-rc.ts +32 -4
- package/src/release-loop/placement.ts +92 -1
- package/src/release-loop/rehearsal-shard-plan.ts +149 -0
- package/src/release-loop/rehearsal.ts +73 -17
- package/src/render.ts +5 -1
- package/src/repl/index.ts +20 -2
- package/src/seat-loop/seat-knowhow.ts +282 -0
- package/src/seat-loop/seat-loop.ts +41 -2
- package/src/seat-loop/seat-report.ts +42 -2
- package/src/seat-loop/traffic-signal.ts +3 -0
- package/src/self-dev/ask-launch-flow.ts +24 -3
- package/src/self-dev/decompose-compose-graph.ts +28 -27
- package/src/self-dev/decompose-proposal.ts +53 -38
- package/src/self-dev/decompose.ts +17 -0
- package/src/self-dev/dev-pipeline.ts +31 -2
- package/src/self-dev/draft-residue.ts +24 -9
- package/src/self-dev/draft-sweep.ts +59 -4
- package/src/self-dev/external-call-zero.ts +77 -0
- package/src/self-dev/launch-preflight-text.ts +6 -0
- package/src/self-dev/launch-preflight.ts +25 -3
- package/src/self-dev/local-supervisor-judge.ts +185 -0
- package/src/self-dev/run-supervisor.ts +300 -24
- package/src/self-dev/run-types.ts +20 -0
- package/src/self-dev/shard-aggregate.ts +15 -2
- package/src/self-dev/shard-plan.ts +47 -0
- package/src/self-dev/shard-run.ts +135 -12
- package/src/self-dev/spawn-lane-files.ts +19 -0
- package/src/self-health/signatures.ts +132 -0
- package/src/self-implement/app-api-budget.ts +51 -11
- package/src/self-implement/config-gate.ts +2 -1
- package/src/self-implement/doctor-visit.ts +118 -0
- package/src/self-implement/expose-gate.ts +2 -1
- package/src/self-implement/gate-artifacts.ts +405 -0
- package/src/self-implement/gate-cli.ts +212 -18
- package/src/self-implement/gate-remote.ts +110 -25
- package/src/self-implement/gate-scenario.ts +85 -0
- package/src/self-implement/goal-author-decompose.ts +80 -16
- package/src/self-implement/goal-author.ts +270 -76
- package/src/self-implement/goal-authoring-grounding.ts +1 -1
- package/src/self-implement/goal-file-name.ts +65 -0
- package/src/self-implement/graph-authority.ts +38 -6
- package/src/self-implement/graph-overlay-condition.ts +92 -1
- package/src/self-implement/ground-goal.ts +2 -1
- package/src/self-implement/heal-triage.ts +79 -0
- package/src/self-implement/host-regate.ts +74 -2
- package/src/self-implement/orchestrator.ts +14 -123
- package/src/self-implement/pr-title.ts +123 -0
- package/src/self-implement/review-mustfix-class.ts +115 -0
- package/src/self-implement/run-checkpoint.ts +235 -0
- package/src/self-implement/run-ledger.ts +266 -17
- package/src/self-implement/run-stop.ts +4 -3
- package/src/self-implement/run-ttl.ts +28 -4
- package/src/self-implement/running-runs.ts +10 -6
- package/src/self-implement/seams.ts +2 -0
- package/src/self-implement/self-implement-runtime.ts +32 -0
- package/src/self-implement/shadow-stage.ts +7 -6
- package/src/self-implement/stop-autoheal.ts +2 -1
- package/src/self-implement/train-gate-remote.ts +37 -8
- package/src/self-implement/train-reach-grouping.ts +157 -0
- package/src/self-implement/train-scenario-layers.ts +133 -0
- package/src/self-implement/uncommitted-work.ts +2 -0
- package/src/session/pending-input.ts +81 -11
- package/src/session/session-start.ts +224 -0
- package/src/session-runtime/index.ts +7 -1
- package/src/session-runtime/parallel-dispatch.ts +22 -5
- package/src/skills/tools/dev-harness.ts +6 -4
- 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/steward/resync-tick.ts +114 -23
- package/src/steward/ta-repair-event-collect.ts +158 -0
- package/src/task-agent/card-evidence.ts +25 -1
- package/src/task-agent/green-sweep.ts +8 -3
- package/src/task-agent/judge.ts +76 -0
- package/src/task-agent/land-queue.ts +79 -0
- package/src/task-agent/live-moves.ts +30 -9
- package/src/task-agent/postland-card.ts +5 -0
- package/src/task-agent/prelaunch-already-done.ts +98 -0
- package/src/task-agent/real-launch-guard.ts +37 -0
- package/src/task-agent/rejudge-on-head.ts +93 -13
- package/src/task-agent/remote-rejudge-bind.ts +62 -13
- package/src/task-agent/repair-cycle.ts +58 -7
- package/src/task-agent/repair-worker.ts +7 -0
- package/src/task-agent/run-identity.ts +200 -0
- package/src/task-agent/shadow.ts +50 -3
- package/src/task-agent/task-hand.ts +158 -5
- package/src/task-agent/train-landing.ts +77 -0
- package/src/task-agent/work-order.ts +104 -0
- package/src/task-orchestrator/surfaces/kubectl-transient-retry.ts +51 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +138 -22
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
- package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
- package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
- package/src/task-orchestrator/surfaces/pod-install-slots.ts +122 -15
- package/src/task-orchestrator/surfaces/pod-lease.ts +20 -6
- package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
- package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +103 -0
- package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
- package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +63 -0
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +19 -3
- package/src/task-orchestrator/surfaces/pod-warm-switch.ts +141 -0
- package/src/task-orchestrator/surfaces/pod-warm-ta-shadow.ts +85 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +208 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +237 -46
- package/src/telegram.ts +2 -4
- 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/input/pickers.ts +732 -0
- package/src/tui/slash/mission.ts +492 -0
- package/src/tui/slash/term.ts +877 -0
- package/src/tui-client/dashboard-session.ts +9 -0
- package/src/tui.ts +53 -0
- package/src/user-config/gemini-server-tools.ts +9 -0
- package/src/user-config.ts +106 -21
- package/src/util/spawn-sync-output.ts +7 -0
- package/src/ux-sim/fake-bin.ts +154 -0
- package/src/ux-sim/fake-clock.ts +36 -0
- package/src/ux-sim/fake-llm.ts +29 -0
- package/src/ux-sim/headless-tui.ts +72 -0
- package/src/ux-sim/in-process-cli.ts +176 -0
- package/src/ux-sim/temp-git-remote.ts +82 -0
- package/src/version/packed-revision.json +1 -1
- package/src/video-pipeline/recipes/vlog.ts +25 -7
- 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/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/2566-734cb83bbd405886.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/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/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/4565-67e4c620597965c8.js +0 -1
- 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/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/9638-d268329f2c6f4f8d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/973cbf1b.3bbcf2b41548eca7.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/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/ceo/page-66ad46ed0279feb9.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-run/page-bb1f05cd51c38944.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-646b50f63b6fe732.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/morning/page-6f131b51193a36f9.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/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/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 → LSXfY0u9QtfDbejY0Ukf_}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/** Immediate TA repair collection. The card and atomic worker result remain authoritative. */
|
|
2
|
+
import { mkdirSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, join, resolve } from 'node:path';
|
|
4
|
+
import { debug } from '../debug/log.js';
|
|
5
|
+
import { spawnElanous } from '../instance/spawn-elanous.js';
|
|
6
|
+
import { acquireLockSync } from '../storage/file-lock.js';
|
|
7
|
+
import { subscribeInsideEvent, type InsideLiveEvent } from '../nexus/api/inside-events.js';
|
|
8
|
+
import type { NexusEventBus } from '../nexus/api/event-bus.js';
|
|
9
|
+
import { parseRepairWorkerResult } from '../task-agent/repair-worker.js';
|
|
10
|
+
import { readTaskCard, taskAgentStatePath } from '../task-agent/task-hand.js';
|
|
11
|
+
|
|
12
|
+
const SHA40 = /^[0-9a-f]{40}$/i;
|
|
13
|
+
const CARD = /^ta-[a-z0-9-]{1,80}$/;
|
|
14
|
+
const TIMEOUT_MS = 10 * 60_000;
|
|
15
|
+
const OUTPUT_LIMIT = 1024 * 1024;
|
|
16
|
+
|
|
17
|
+
export interface TaRepairCompleted {
|
|
18
|
+
kind: 'ta.repair.completed'; schema: 1; card: string; pr: number; head: string;
|
|
19
|
+
runId: string; resultPath: string; completedAt: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function parseTaRepairCompleted(value: unknown): TaRepairCompleted | null {
|
|
23
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return null;
|
|
24
|
+
const v = value as Record<string, unknown>;
|
|
25
|
+
if (v.kind !== 'ta.repair.completed' || v.schema !== 1 || typeof v.card !== 'string' || !CARD.test(v.card)
|
|
26
|
+
|| !Number.isSafeInteger(v.pr) || Number(v.pr) < 1 || typeof v.head !== 'string' || !SHA40.test(v.head)
|
|
27
|
+
|| typeof v.runId !== 'string' || !/^run-[a-z0-9-]{1,100}$/i.test(v.runId)
|
|
28
|
+
|| typeof v.resultPath !== 'string' || !v.resultPath.startsWith('/')
|
|
29
|
+
|| typeof v.completedAt !== 'string' || !Number.isFinite(Date.parse(v.completedAt))) return null;
|
|
30
|
+
return v as unknown as TaRepairCompleted;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface TaRepairCollectDeps {
|
|
34
|
+
statePath?: string;
|
|
35
|
+
/** Test entry for a child that runs the real tasks CLI with isolated dependencies. */
|
|
36
|
+
cliBin?: string;
|
|
37
|
+
read?: (path: string) => string;
|
|
38
|
+
run?: (card: string) => Promise<{ code: number | null; output: string; truncated?: boolean }>;
|
|
39
|
+
now?: () => Date;
|
|
40
|
+
log?: (data: Record<string, unknown>) => void;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function defaultRun(card: string, statePath: string, cliBin?: string): Promise<{ code: number | null; output: string; truncated?: boolean }> {
|
|
44
|
+
return new Promise(done => {
|
|
45
|
+
const child = spawnElanous(['tasks', 'rejudge', card, '--json'], { stateDir: dirname(statePath),
|
|
46
|
+
...(cliBin ? { bin: cliBin } : {}), stdio: ['ignore', 'pipe', 'pipe'] });
|
|
47
|
+
let output = '';
|
|
48
|
+
let truncated = false;
|
|
49
|
+
let settled = false;
|
|
50
|
+
let force: ReturnType<typeof setTimeout> | undefined;
|
|
51
|
+
const finish = (code: number | null) => {
|
|
52
|
+
if (settled) return;
|
|
53
|
+
settled = true;
|
|
54
|
+
clearTimeout(timer);
|
|
55
|
+
if (force) clearTimeout(force);
|
|
56
|
+
done({ code, output, truncated });
|
|
57
|
+
};
|
|
58
|
+
const timer = setTimeout(() => {
|
|
59
|
+
child.kill('SIGTERM');
|
|
60
|
+
// Keep the card lock until close confirms the child has stopped writing the card.
|
|
61
|
+
force = setTimeout(() => { child.kill('SIGKILL'); }, 5000);
|
|
62
|
+
}, TIMEOUT_MS);
|
|
63
|
+
const append = (chunk: unknown) => {
|
|
64
|
+
const next = output + String(chunk);
|
|
65
|
+
if (next.length > OUTPUT_LIMIT) { truncated = true; output = next.slice(-OUTPUT_LIMIT); }
|
|
66
|
+
else output = next;
|
|
67
|
+
};
|
|
68
|
+
child.stdout?.on('data', append);
|
|
69
|
+
child.stderr?.on('data', append);
|
|
70
|
+
// Node emits close after error, including spawn failure. An error can also
|
|
71
|
+
// describe a failed kill while the child is still alive: keep the lock.
|
|
72
|
+
child.once('error', (error) => { append(`\nchild error: ${String(error)}`); });
|
|
73
|
+
child.once('close', finish);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function childConsumedRepair(output: string, event: TaRepairCompleted): boolean {
|
|
78
|
+
for (const line of output.split(/\r?\n/).reverse()) {
|
|
79
|
+
if (!line.trimStart().startsWith('[')) continue;
|
|
80
|
+
try {
|
|
81
|
+
const rows: unknown = JSON.parse(line);
|
|
82
|
+
if (Array.isArray(rows) && rows.some(row => row && typeof row === 'object' && row.card === event.card
|
|
83
|
+
&& row.pr === event.pr && row.repairRunId === event.runId && row.repairHead === event.head
|
|
84
|
+
&& row.step === 'repair' && (row.decision === 'repair-applied' || row.decision === 'repair-failed'))) return true;
|
|
85
|
+
} catch { /* not a JSON result line */ }
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** One event may start one card rejudge. A periodic rejudge can race; its existing card CAS still owns side effects. */
|
|
91
|
+
export async function collectTaRepairCompleted(input: unknown, deps: TaRepairCollectDeps = {}): Promise<'invalid' | 'duplicate' | 'deferred' | 'collected'> {
|
|
92
|
+
const event = parseTaRepairCompleted(input);
|
|
93
|
+
if (!event) return 'invalid';
|
|
94
|
+
const statePath = deps.statePath ?? taskAgentStatePath();
|
|
95
|
+
const emit = (outcome: string, extra: Record<string, unknown> = {}) => {
|
|
96
|
+
const collectedAt = (deps.now?.() ?? new Date()).toISOString();
|
|
97
|
+
const data = { card: event.card, pr: event.pr, runId: event.runId, completedAt: event.completedAt,
|
|
98
|
+
collectedAt, ...(outcome === 'collected' ? { latencyMs: Date.parse(collectedAt) - Date.parse(event.completedAt) } : {}),
|
|
99
|
+
delivery: 'event', outcome, ...extra };
|
|
100
|
+
try { (deps.log ?? ((d) => debug.log('task-agent', 'ta.repair.collected', d)))(data); } catch { /* observability cannot change the result */ }
|
|
101
|
+
};
|
|
102
|
+
let card;
|
|
103
|
+
try { card = readTaskCard(event.card, statePath); } catch { emit('deferred', { reason: 'card unreadable' }); return 'deferred'; }
|
|
104
|
+
const repair = Array.isArray(card?.repairs) ? card.repairs.find(entry => entry && typeof entry === 'object' && entry.runId === event.runId) : undefined;
|
|
105
|
+
if (!repair || repair.pr !== event.pr || typeof repair.head !== 'string' || repair.head.toLowerCase() !== event.head.toLowerCase()
|
|
106
|
+
|| typeof repair.resultPath !== 'string' || !repair.resultPath.startsWith('/')
|
|
107
|
+
|| resolve(repair.resultPath) !== resolve(event.resultPath)) { emit('invalid', { reason: 'event differs from card binding' }); return 'invalid'; }
|
|
108
|
+
if (repair.status !== 'requested') { emit('duplicate', { reason: `repair ${repair.status}` }); return 'duplicate'; }
|
|
109
|
+
let result;
|
|
110
|
+
try { result = parseRepairWorkerResult((deps.read ?? ((path) => readFileSync(path, 'utf8')))(repair.resultPath), event.pr, event.head, event.runId); }
|
|
111
|
+
catch { /* periodic tick can recover a missing result */ }
|
|
112
|
+
if (!result) { emit('deferred', { reason: 'worker result missing or invalid' }); return 'deferred'; }
|
|
113
|
+
|
|
114
|
+
// Existing PID-aware lock recovers a dead daemon without making later events wait forever.
|
|
115
|
+
// A live holder keeps the lock through the child process; the card CAS covers periodic-tick races.
|
|
116
|
+
const lock = join(dirname(statePath), 'steward', 'ta-repair-collect', `${event.card}.lock`);
|
|
117
|
+
let release: () => void;
|
|
118
|
+
try {
|
|
119
|
+
mkdirSync(dirname(lock), { recursive: true });
|
|
120
|
+
release = acquireLockSync(lock, { breakDeadHolder: true, staleMs: TIMEOUT_MS + 60_000, maxTries: 2 });
|
|
121
|
+
}
|
|
122
|
+
catch { emit('deferred', { reason: 'collector busy; periodic fallback remains' }); return 'deferred'; }
|
|
123
|
+
try {
|
|
124
|
+
// Recheck after claiming: another collector or the periodic tick may have consumed the file.
|
|
125
|
+
const current = readTaskCard(event.card, statePath);
|
|
126
|
+
const latest = Array.isArray(current?.repairs) ? current.repairs.find(entry => entry && typeof entry === 'object' && entry.runId === event.runId) : undefined;
|
|
127
|
+
if (!latest || latest.status !== 'requested' || latest.pr !== event.pr || typeof latest.head !== 'string'
|
|
128
|
+
|| latest.head.toLowerCase() !== event.head.toLowerCase() || typeof latest.resultPath !== 'string'
|
|
129
|
+
|| !latest.resultPath.startsWith('/') || resolve(latest.resultPath) !== resolve(event.resultPath)) { emit('duplicate'); return 'duplicate'; }
|
|
130
|
+
const child = await (deps.run ?? ((card) => defaultRun(card, statePath, deps.cliBin)))(event.card);
|
|
131
|
+
const after = readTaskCard(event.card, statePath)?.repairs?.find(entry => entry.runId === event.runId);
|
|
132
|
+
const consumed = child.code === 0 && !child.truncated && after?.status !== 'requested' && after !== undefined
|
|
133
|
+
&& childConsumedRepair(child.output, event);
|
|
134
|
+
const outcome = consumed ? 'collected' : child.truncated ? 'deferred' : after && after.status !== 'requested' ? 'duplicate' : 'deferred';
|
|
135
|
+
emit(outcome, { rc: child.code, repairStatus: after?.status,
|
|
136
|
+
...(child.truncated ? { reason: 'rejudge output exceeded 1 MiB; event attribution unmeasured' } : {}),
|
|
137
|
+
detail: child.output.slice(-300) });
|
|
138
|
+
return consumed ? 'collected' : outcome === 'duplicate' ? 'duplicate' : 'deferred';
|
|
139
|
+
} catch (error) {
|
|
140
|
+
emit('deferred', { reason: String(error).slice(-300) });
|
|
141
|
+
return 'deferred';
|
|
142
|
+
} finally { release(); }
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Bridge child-process inside events to Nexus pub/sub; keep the handler nonblocking. */
|
|
146
|
+
export function startTaRepairEventCollector(bus: NexusEventBus, deps: TaRepairCollectDeps = {}): () => void {
|
|
147
|
+
const unsubscribeBus = bus.subscribe(event => {
|
|
148
|
+
void collectTaRepairCompleted(event.detail, deps).catch(error => {
|
|
149
|
+
try { debug.log('task-agent', 'ta.repair.collect-error', { reason: String(error).slice(-300) }, { level: 'warn' }); }
|
|
150
|
+
catch { /* observer failure cannot reject the Nexus callback */ }
|
|
151
|
+
});
|
|
152
|
+
}, ['ta.repair.completed']);
|
|
153
|
+
const unsubscribeInside = subscribeInsideEvent((event: InsideLiveEvent) => {
|
|
154
|
+
if (event.kind !== 'ta.repair.completed') return;
|
|
155
|
+
bus.publish({ kind: 'ta.repair.completed', ts: Date.now(), detail: event as unknown as Record<string, unknown> });
|
|
156
|
+
});
|
|
157
|
+
return () => { unsubscribeInside(); unsubscribeBus(); };
|
|
158
|
+
}
|
|
@@ -76,7 +76,27 @@ export function podChildRunIds(host: readonly RunLedgerEntry[] | null, runId?: s
|
|
|
76
76
|
&& RUN_ID.test(entry.data.childRunId) && entry.data.childRunId !== runId).map((entry) => entry.data.childRunId as string))];
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
/**
|
|
79
|
+
/**
|
|
80
|
+
* TA-BIND-PR-TERMINAL — 부모(호스트) 원장의 `pr-terminal{childRunId, prNumber, prUrl}`(draft-residue `applyPodTerminal`).
|
|
81
|
+
* gate-failed draft 자식은 `pr-opened` 없이 `rework-blocked-draft-pr`·`pr.comment.mode` 만 남겨서, PR 근거는 부모의 이 줄뿐이다.
|
|
82
|
+
* 자식은 부모의 `pod-child-run` 자식이어야 하고, url 은 같은 번호의 PR 주소여야 한다. 나중 줄이 먼저다.
|
|
83
|
+
*/
|
|
84
|
+
export function podTerminalPr(host: readonly RunLedgerEntry[] | null, childRunIds: readonly string[]): { number: number; url: string; childRunId: string } | undefined {
|
|
85
|
+
const children = new Set(childRunIds);
|
|
86
|
+
for (let at = (host?.length ?? 0) - 1; at >= 0; at--) {
|
|
87
|
+
const entry = host![at]!;
|
|
88
|
+
if (entry.event !== 'pr-terminal') continue;
|
|
89
|
+
const childRunId = entry.data?.childRunId;
|
|
90
|
+
const number = entry.data?.prNumber;
|
|
91
|
+
const url = entry.data?.prUrl;
|
|
92
|
+
if (typeof childRunId !== 'string' || !children.has(childRunId) || !Number.isSafeInteger(number) || (number as number) <= 0
|
|
93
|
+
|| typeof url !== 'string' || PR_URL.exec(url)?.[1] !== String(number)) continue;
|
|
94
|
+
return { number: number as number, url, childRunId };
|
|
95
|
+
}
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** 순수 — 카드 런의 골 id · PR. PR 은 호스트 → 자식(나중 자식 먼저) → 호스트 `pr-terminal` → job-finished 순으로 처음 찾은 것. */
|
|
80
100
|
export function bindCardEvidence(card: Pick<TaskCard, 'runId'>, snapshot: CardRunSnapshot): CardRunEvidence {
|
|
81
101
|
if (!card.runId || !snapshot.host) return { ledgerFound: false };
|
|
82
102
|
const children = podChildRunIds(snapshot.host, card.runId).reverse();
|
|
@@ -88,6 +108,10 @@ export function bindCardEvidence(card: Pick<TaskCard, 'runId'>, snapshot: CardRu
|
|
|
88
108
|
const found = entries ? lastPr(entries) : undefined;
|
|
89
109
|
if (found) { pr = found; childRunId = id; }
|
|
90
110
|
}
|
|
111
|
+
if (!pr) {
|
|
112
|
+
const terminal = podTerminalPr(snapshot.host, children);
|
|
113
|
+
if (terminal) { pr = { number: terminal.number, url: terminal.url }; childRunId = terminal.childRunId; }
|
|
114
|
+
}
|
|
91
115
|
for (const id of children) {
|
|
92
116
|
if (pr) break;
|
|
93
117
|
const finish = [...(snapshot.podFinishes ?? [])].reverse().find((row) => row.childRunId === id && PR_URL.test(row.prUrl));
|
|
@@ -19,6 +19,7 @@ export interface GreenSweepPr {
|
|
|
19
19
|
state: string;
|
|
20
20
|
mergeSha?: string;
|
|
21
21
|
url?: string;
|
|
22
|
+
viaTrain?: { integrationPr: number };
|
|
22
23
|
}
|
|
23
24
|
export interface GreenSweepDecision {
|
|
24
25
|
cell: string;
|
|
@@ -112,7 +113,8 @@ export function decideGreenSweep(input: {
|
|
|
112
113
|
const { item, candidate, pr } = input;
|
|
113
114
|
const mergeSha = pr?.mergeSha && /^[a-f0-9]{40}$/i.test(pr.mergeSha) ? pr.mergeSha : null;
|
|
114
115
|
const result = (verdict: GreenSweepVerdict, reason: string): GreenSweepDecision => {
|
|
115
|
-
const
|
|
116
|
+
const landing = pr?.viaTrain ? ` via train #${pr.viaTrain.integrationPr}` : '';
|
|
117
|
+
const evidence = `GREEN-FROM-LEDGER: PR #${candidate.pr}${landing}${mergeSha ? ` merged ${mergeSha}` : ''} · ${verdict} · ${reason}`;
|
|
116
118
|
return { cell: item.id, pr: candidate.pr, mergeSha, source: candidate.source, verdict, reason,
|
|
117
119
|
evidence, existingEvidence: item.evidence ?? '', plannedEvidence: appendGreenSweepEvidence(item.evidence, evidence) };
|
|
118
120
|
};
|
|
@@ -122,6 +124,9 @@ export function decideGreenSweep(input: {
|
|
|
122
124
|
if (input.repositoryMatches === false) return result('skip', 'repository-mismatch');
|
|
123
125
|
if (input.repositoryMatches !== true) return result('record-only', 'repository-unreadable');
|
|
124
126
|
if (pr.state !== 'MERGED') return result('skip', `pr-${pr.state.toLowerCase()}`);
|
|
127
|
+
if (pr.viaTrain && (candidate.card?.trainLanding?.componentPr !== candidate.pr
|
|
128
|
+
|| candidate.card.trainLanding.integrationPr !== pr.viaTrain.integrationPr
|
|
129
|
+
|| candidate.card.trainLanding.mergeSha !== pr.mergeSha)) return result('skip', 'train-binding-mismatch');
|
|
125
130
|
if (!mergeSha) return result('skip', 'merge-sha-unreadable');
|
|
126
131
|
if (input.ancestor === null) return result('record-only', 'origin-main-ref-unverified');
|
|
127
132
|
if (!input.ancestor) return result('skip', 'merge-sha-not-on-origin-main');
|
|
@@ -159,8 +164,8 @@ export function decideGreenSweep(input: {
|
|
|
159
164
|
if (typeof card.pr === 'object' && pr.url && card.pr.url
|
|
160
165
|
&& card.pr.url.replace(/\/+$/, '') !== pr.url.replace(/\/+$/, ''))
|
|
161
166
|
return result('record-only', 'card-pr-url-mismatch');
|
|
162
|
-
if (card.prTerminal?.state === 'CLOSED') return result('record-only', 'card-terminal-conflict');
|
|
163
|
-
return result('green', card.postLand?.outcome === 'complete' ? 'bound-card-complete' : 'bound-card-merged');
|
|
167
|
+
if (card.prTerminal?.state === 'CLOSED' && !pr.viaTrain) return result('record-only', 'card-terminal-conflict');
|
|
168
|
+
return result('green', card.postLand?.outcome === 'complete' ? 'bound-card-complete' : pr.viaTrain ? 'bound-card-train-merged' : 'bound-card-merged');
|
|
164
169
|
}
|
|
165
170
|
|
|
166
171
|
/** Every candidate emits one structured decision, including refusals. */
|
package/src/task-agent/judge.ts
CHANGED
|
@@ -24,6 +24,8 @@ export interface TaskJudgeInput {
|
|
|
24
24
|
stopReason?: SupervisorStopReason;
|
|
25
25
|
prState?: 'OPEN' | 'MERGED' | 'CLOSED';
|
|
26
26
|
pr?: string | number;
|
|
27
|
+
/** Complete PR target paths when measured. Unknown is omitted, never treated as zero code diff. */
|
|
28
|
+
prTargetPaths?: readonly string[];
|
|
27
29
|
/** `self review --json` 판정. 관측 못 했으면 비운다(«통과»로 읽지 않는다). */
|
|
28
30
|
review?: 'pass' | 'fail';
|
|
29
31
|
mustFix?: readonly string[];
|
|
@@ -36,6 +38,42 @@ export interface TaskJudgeInput {
|
|
|
36
38
|
evidence?: { ok: boolean; ref: string };
|
|
37
39
|
/** Only classified terminal evidence; an absent input preserves the existing stop-reason table. */
|
|
38
40
|
terminalRun?: { kind: typeof STOP_CLASS_POD_FAILURE | typeof STOP_CLASS_NO_LAUNCH; reason: string; hasPr: boolean; hasHarvestBranch: boolean };
|
|
41
|
+
/**
|
|
42
|
+
* 같은 칸(checklistId)의 앞 런들 — 재발사 계열 수를 고르기 «전»에 받는 «선례»(RFC adaptive-graph-ops §9.10).
|
|
43
|
+
* 없으면 지금 표 그대로(입력이 비어도 동작한다 — RUN-TAG-REWORK 가 원장에 서명을 달면 여기 입력이 된다).
|
|
44
|
+
*/
|
|
45
|
+
precedents?: readonly TaskPrecedent[];
|
|
46
|
+
/** 판정 관측 훅 — `task-agent.judge` 이벤트에 precedent {matched, priorRunId, signature} 를 싣는다. 없으면 관측 없이 종전 동작. */
|
|
47
|
+
observe?: (event: 'task-agent.judge', data: { precedent: { matched: boolean; priorRunId?: string; signature?: string } }) => void;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** 같은 칸의 앞 런 한 건 — 결말(outcome)과 must-fix 서명. `outcome: 'alternative-failed'` 는 «대안도 같은 서명으로 실패했다»는 예약 결말이다. */
|
|
51
|
+
export interface TaskPrecedent {
|
|
52
|
+
runId: string;
|
|
53
|
+
outcome: string;
|
|
54
|
+
signature: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** must-fix 서명의 분류 축(남은 must-fix 의 성격) — 해시에 함께 박는다. */
|
|
58
|
+
export const MUST_FIX_CLASSIFICATION = 'implementation-deficit';
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* 남은 must-fix 원문을 정규화(공백 접기·trim·정렬)한 해시 ⊕ 분류 — 같은 칸의 앞 런과 비교하는 «서명».
|
|
62
|
+
* must-fix 가 비면 서명도 없다(선례 비교 없음).
|
|
63
|
+
*/
|
|
64
|
+
export function mustFixSignature(mustFix?: readonly string[]): string | undefined {
|
|
65
|
+
const normalized = [...(mustFix ?? [])]
|
|
66
|
+
.map(fix => (typeof fix === 'string' ? fix.trim().replace(/\s+/gu, ' ') : ''))
|
|
67
|
+
.filter(Boolean)
|
|
68
|
+
.sort();
|
|
69
|
+
if (!normalized.length) return undefined;
|
|
70
|
+
let hash = 0x811c9dc5;
|
|
71
|
+
const text = `${MUST_FIX_CLASSIFICATION}:${JSON.stringify(normalized)}`;
|
|
72
|
+
for (let i = 0; i < text.length; i++) {
|
|
73
|
+
hash ^= text.charCodeAt(i);
|
|
74
|
+
hash = Math.imul(hash, 0x01000193) >>> 0;
|
|
75
|
+
}
|
|
76
|
+
return `fnv1a-${hash.toString(16).padStart(8, '0')}`;
|
|
39
77
|
}
|
|
40
78
|
|
|
41
79
|
export interface TaskJudgement {
|
|
@@ -83,12 +121,22 @@ const RETRY_MOVE_OF_VARIANT: Record<RetryVariant, LiveRetryMove> = {
|
|
|
83
121
|
alternative: 'alternative',
|
|
84
122
|
};
|
|
85
123
|
|
|
124
|
+
/** Only a measured complete file list can establish zero implementation target diff. */
|
|
125
|
+
export function isGoalOnlyPr(paths: readonly string[] | undefined): boolean {
|
|
126
|
+
return paths !== undefined && paths.every((path) => /^docs\/goals\/[^/]+(?:\/.*)?$/.test(path));
|
|
127
|
+
}
|
|
128
|
+
|
|
86
129
|
/** 실행부 `retry` 가 어느 수인가 — 갈래 없는 재발사(리뷰 fail 의 must-fix 재발사)는 «좁혀 재발사»다. */
|
|
87
130
|
export function retryMoveOf(variant?: RetryVariant): LiveRetryMove {
|
|
88
131
|
return RETRY_MOVE_OF_VARIANT[variant ?? 'narrow'];
|
|
89
132
|
}
|
|
90
133
|
|
|
91
134
|
function base(input: TaskJudgeInput): Omit<TaskJudgement, 'executorKind'> {
|
|
135
|
+
// A goal document is a launch artifact. Its PR cannot prove implementation progress,
|
|
136
|
+
// even when the PR has merged. Waiting also prevents the same goal's live retry.
|
|
137
|
+
if (input.pr && isGoalOnlyPr(input.prTargetPaths)) {
|
|
138
|
+
return { move: 'wait', stage: 'escalated', reason: `goal-only-pr — PR ${input.pr} target diff 0; 같은 골 재큐 중지·구현 근거 필요` };
|
|
139
|
+
}
|
|
92
140
|
if (input.deliveryEvidence) return input.deliveryEvidence.ok
|
|
93
141
|
? { move: 'propose-green', stage: 'closing', reason: `전달 근거 확인: ${input.deliveryEvidence.files.join(', ')}` }
|
|
94
142
|
: { move: 'wait', stage: 'waiting', reason: input.deliveryEvidence.reason };
|
|
@@ -139,16 +187,34 @@ function base(input: TaskJudgeInput): Omit<TaskJudgement, 'executorKind'> {
|
|
|
139
187
|
/** 재발사 계열 — 대안(alternative)이 실패한 «같은 실패 흐름»에 속하는 수. */
|
|
140
188
|
const RETRY_FAMILY: ReadonlySet<TaskMove> = new Set<TaskMove>(['narrow-relaunch', 'wait-retry', 'salvage-relaunch']);
|
|
141
189
|
|
|
190
|
+
/**
|
|
191
|
+
* 선례가 «같은 수로 재발사»를 막는 수 — narrow·salvage·그 자신(alternative).
|
|
192
|
+
* 대기 후 재시도(wait-retry)는 «같은 수로 재발사»가 아니므로 선례 승격에서는 제외.
|
|
193
|
+
*/
|
|
194
|
+
const PRECEDENT_RELAUNCH_FAMILY: ReadonlySet<TaskMove> = new Set<TaskMove>(['narrow-relaunch', 'salvage-relaunch']);
|
|
195
|
+
|
|
142
196
|
/**
|
|
143
197
|
* 종료 어휘·관측에서 다음 한 수를 고른다. 같은 수 2회 실패 → 다른 수 → 그것도 실패 → 결정 카드.
|
|
144
198
|
*
|
|
145
199
|
* ⭐ 새 관측이 이긴다(사후 리뷰 must-fix · #24453): 병합된 PR(propose-green)·종료 미관측(wait)·표 밖 어휘(decision-card)는
|
|
146
200
|
* 실패 셈과 무관하게 그대로 간다. 「대안도 실패 → 결정 카드」 승격은 지금 수가 같은 실패 흐름일 때만 —
|
|
147
201
|
* 재발사 계열이거나, 그 수 자신이 이미 같은 수 한도만큼 실패했을 때다.
|
|
202
|
+
*
|
|
203
|
+
* ⭐ 선례(RFC adaptive-graph-ops §9.10): 이번 런의 must-fix 서명이 앞 런 서명과 같으면 같은 수로 재발사하지 않는다 —
|
|
204
|
+
* narrow/salvage → alternative, alternative 자신(또는 선례 결말이 `alternative-failed`)이면 결정 카드.
|
|
205
|
+
* 선례가 없으면 지금 표 그대로.
|
|
148
206
|
*/
|
|
149
207
|
export function judgeNextMove(input: TaskJudgeInput): TaskJudgement {
|
|
150
208
|
const failures = input.failures ?? {};
|
|
151
209
|
let judged = base(input);
|
|
210
|
+
const signature = mustFixSignature(input.mustFix);
|
|
211
|
+
// 같은 서명 일치 «전체»를 스캔한다 — `alternative-failed` 유무는 목록 어느 위치에 있든 먼저 판정한다(anyMatch 우선, 순서 무관).
|
|
212
|
+
const sameSignature = signature !== undefined
|
|
213
|
+
? (input.precedents ?? []).filter(prec => typeof prec?.signature === 'string' && prec.signature === signature
|
|
214
|
+
&& typeof prec?.runId === 'string' && prec.runId !== '')
|
|
215
|
+
: [];
|
|
216
|
+
const matched = sameSignature[0];
|
|
217
|
+
input.observe?.('task-agent.judge', { precedent: { matched: matched !== undefined, priorRunId: matched?.runId, signature } });
|
|
152
218
|
const escalatable = judged.move !== 'wait' && judged.move !== 'decision-card' && judged.move !== 'propose-green';
|
|
153
219
|
const exhausted = escalatable && (failures[judged.move] ?? 0) >= SAME_MOVE_FAILURE_LIMIT;
|
|
154
220
|
const inFailingFlow = RETRY_FAMILY.has(judged.move) || exhausted;
|
|
@@ -157,6 +223,16 @@ export function judgeNextMove(input: TaskJudgeInput): TaskJudgement {
|
|
|
157
223
|
} else if (exhausted) {
|
|
158
224
|
judged = { move: 'alternative', stage: 'repairing', reason: `같은 수 ${SAME_MOVE_FAILURE_LIMIT}회 실패 — 다른 수 선택 (${judged.move})` };
|
|
159
225
|
}
|
|
226
|
+
// 선례 승격 — 실패 승격 다음: 이번 수가 같은 서명 앞 런의 수와 겹치지 않게 한다(같은 수로 재발사 차단).
|
|
227
|
+
if (matched !== undefined && (PRECEDENT_RELAUNCH_FAMILY.has(judged.move) || judged.move === 'alternative')) {
|
|
228
|
+
if (judged.move === 'alternative' || sameSignature.some(prec => prec.outcome === 'alternative-failed')) {
|
|
229
|
+
judged = { move: 'decision-card', stage: 'escalated',
|
|
230
|
+
reason: `같은 must-fix 서명 선례 ${matched.runId} — 대안도 같은 서명으로 실패 — 사람 결정 (서명 ${signature})` };
|
|
231
|
+
} else {
|
|
232
|
+
judged = { move: 'alternative', stage: 'repairing',
|
|
233
|
+
reason: `같은 must-fix 서명 선례 ${matched.runId} — 같은 수로 재발사하지 않고 다른 수 선택 (서명 ${signature})` };
|
|
234
|
+
}
|
|
235
|
+
}
|
|
160
236
|
const executorKind = EXECUTOR_KIND[judged.move];
|
|
161
237
|
const executorVariant = EXECUTOR_VARIANT[judged.move];
|
|
162
238
|
if (!executorKind) return judged;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/** TA-LAND-AFTER-REVIEW: a configured queue adapter after exact-head review and remote changed gate. */
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { mkdirSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { dirname, isAbsolute, join } from 'node:path';
|
|
5
|
+
import { randomUUID } from 'node:crypto';
|
|
6
|
+
import { parseReviewResultOutput } from './review-result-capture.js';
|
|
7
|
+
|
|
8
|
+
type CommandResult = { status: number; stdout: string; stderr: string };
|
|
9
|
+
export interface QueueLandingInput {
|
|
10
|
+
card: string; pr: number; head: string; cwd: string; statePath: string; reviewResult: string;
|
|
11
|
+
command: string; remote: string; entry: string; configDir: string;
|
|
12
|
+
}
|
|
13
|
+
export interface QueueLandingDeps {
|
|
14
|
+
run?: (command: string, args: string[], cwd: string, env?: NodeJS.ProcessEnv) => Promise<CommandResult>;
|
|
15
|
+
read?: (path: string) => string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function run(command: string, args: string[], cwd: string, env?: NodeJS.ProcessEnv): Promise<CommandResult> {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
const child = spawn(command, args, { cwd, env: env ?? process.env, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
21
|
+
let stdout = ''; let stderr = '';
|
|
22
|
+
child.stdout.on('data', (chunk: Buffer) => { stdout = (stdout + chunk.toString()).slice(-4000); });
|
|
23
|
+
child.stderr.on('data', (chunk: Buffer) => { stderr = (stderr + chunk.toString()).slice(-4000); });
|
|
24
|
+
child.once('error', reject);
|
|
25
|
+
child.once('close', (code) => resolve({ status: code ?? 1, stdout, stderr }));
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** The adapter owns no merge authority. Its only successful result is a confirmed queue row. */
|
|
30
|
+
export async function runQueuedLanding(input: QueueLandingInput, deps: QueueLandingDeps = {}): Promise<CommandResult> {
|
|
31
|
+
const invoke = deps.run ?? run;
|
|
32
|
+
const read = deps.read ?? ((path: string) => readFileSync(path, 'utf8'));
|
|
33
|
+
const fail = (stage: string, reason: string): CommandResult => ({ status: 1, stdout: '', stderr: `${stage}: ${reason.slice(-500)}` });
|
|
34
|
+
if (!/^[a-f0-9]{40}$/i.test(input.head) || !Number.isSafeInteger(input.pr) || input.pr < 1) return fail('input', 'invalid PR/head');
|
|
35
|
+
if (!isAbsolute(input.command) || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(input.remote)) return fail('config', 'land queue command/remote invalid');
|
|
36
|
+
let review: ReturnType<typeof parseReviewResultOutput>;
|
|
37
|
+
try { review = parseReviewResultOutput(read(input.reviewResult)); }
|
|
38
|
+
catch (error) { return fail('review', String(error)); }
|
|
39
|
+
if (!review || review.pr !== input.pr || review.head?.toLowerCase() !== input.head.toLowerCase()
|
|
40
|
+
|| review.reviewed !== true || !['pass', 'warn'].includes(review.verdict ?? '') || review.mustFix !== 0 || review.error) {
|
|
41
|
+
return fail('review', `exact head #${input.pr} ${input.head.slice(0, 12)} PASS/WARN mf0 not proven`);
|
|
42
|
+
}
|
|
43
|
+
const git = async (args: string[]) => invoke(process.execPath, [input.entry, '--config-dir', input.configDir, 'git', ...args], input.cwd);
|
|
44
|
+
const fetched = await git(['fetch', '--quiet', 'origin', 'main']);
|
|
45
|
+
if (fetched.status !== 0) return fail('base-fetch', fetched.stderr || fetched.stdout || `exit ${fetched.status}`);
|
|
46
|
+
const base = await git(['rev-parse', '--verify', 'origin/main']);
|
|
47
|
+
const baseHead = base.stdout.trim().split(/\s+/)[0];
|
|
48
|
+
if (base.status !== 0 || !/^[a-f0-9]{40}$/i.test(baseHead ?? '')) return fail('base', 'origin/main commit unmeasured');
|
|
49
|
+
const local = await git(['rev-parse', '--verify', 'HEAD']);
|
|
50
|
+
if (local.status !== 0 || local.stdout.trim().split(/\s+/)[0]?.toLowerCase() !== input.head.toLowerCase()) return fail('head', 'queue worktree HEAD differs from PR head');
|
|
51
|
+
const safeCard = input.card.replace(/[^A-Za-z0-9._-]/g, '_');
|
|
52
|
+
const artifact = join(dirname(input.statePath), 'land-queue-gates', `${safeCard}-${input.pr}-${input.head.slice(0, 12)}-${randomUUID()}`);
|
|
53
|
+
mkdirSync(artifact, { recursive: true });
|
|
54
|
+
const gate = await invoke(process.execPath, [input.entry, '--config-dir', input.configDir,
|
|
55
|
+
'self', 'gate', '--changed', '--base', baseHead!, '--remote', input.remote, '--shards', '4', '--artifact-dir', artifact], input.cwd);
|
|
56
|
+
if (gate.status !== 0) return fail('remote-changed-gate', gate.stderr || gate.stdout || `exit ${gate.status}`);
|
|
57
|
+
let summary: Record<string, unknown>;
|
|
58
|
+
try { summary = JSON.parse(read(join(artifact, 'summary.json'))) as Record<string, unknown>; }
|
|
59
|
+
catch (error) { return fail('remote-changed-gate', `summary unreadable: ${String(error)}`); }
|
|
60
|
+
if (summary.head40 !== input.head || summary.base40 !== baseHead || summary.remoteHost !== input.remote
|
|
61
|
+
|| summary.verdict !== 'passed' || summary.exitCode !== 0 || summary.introduced !== 0
|
|
62
|
+
|| summary.unknown !== 0 || summary.preconditionUnmet !== 0) {
|
|
63
|
+
return fail('remote-changed-gate', 'summary does not prove this head/base/remote passed with zero unknown');
|
|
64
|
+
}
|
|
65
|
+
const fresh = await invoke('gh', ['pr', 'view', String(input.pr), '--json', 'headRefOid,state,isDraft'], input.cwd);
|
|
66
|
+
let latest: { headRefOid?: unknown; state?: unknown; isDraft?: unknown };
|
|
67
|
+
try { latest = JSON.parse(fresh.stdout) as typeof latest; }
|
|
68
|
+
catch { return fail('pr-head', `current PR state unreadable: ${fresh.stderr || fresh.stdout || fresh.status}`); }
|
|
69
|
+
if (fresh.status !== 0 || latest.state !== 'OPEN' || latest.isDraft !== false
|
|
70
|
+
|| typeof latest.headRefOid !== 'string' || latest.headRefOid.toLowerCase() !== input.head.toLowerCase()) {
|
|
71
|
+
return fail('pr-head', `PR #${input.pr} changed after gate or is not ready`);
|
|
72
|
+
}
|
|
73
|
+
const enrolled = await invoke(input.command, [String(input.pr), input.cwd, '--review', input.reviewResult, '--expected-head', input.head], input.cwd,
|
|
74
|
+
{ ...process.env, LAND_RR_DIR: dirname(input.reviewResult) });
|
|
75
|
+
if (enrolled.status !== 0 || !new RegExp(`^OK #${input.pr} head=${input.head.slice(0, 12)}(?:\\s|$)`, 'm').test(enrolled.stdout)) {
|
|
76
|
+
return fail('land-enqueue-refused', enrolled.stdout || enrolled.stderr || `exit ${enrolled.status}`);
|
|
77
|
+
}
|
|
78
|
+
return { status: 0, stdout: `queued #${input.pr} head ${input.head.slice(0, 12)} gate ${artifact} · ${enrolled.stdout.slice(-250)}`, stderr: '' };
|
|
79
|
+
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* TA-REVIEW-RESULT-CAPTURE — 자식 stdout(`--json`)은 결과 파일로 받고, 자식 완료 뒤 해당 카드만 회수·재판정한다.
|
|
7
7
|
* 회수한 pass 는 그 틱의 판단부·land 관문 입력(`selfReview`)이 될 뿐 land 판정 로직은 그대로다.
|
|
8
8
|
* - `propose-green`: 카드에 green «제안»(`greenProposal`)만 적는다 — 체크리스트는 손대지 않는다.
|
|
9
|
-
* - `propose-land`: 카드·현재 머리의 self review 통과(pass «또는» warn ⊕ must-fix 0 · TA-LAND-WARN-MUSTFIX0)·non-draft 를
|
|
9
|
+
* - `propose-land`: 카드·현재 머리의 self review 통과(pass «또는» warn ⊕ must-fix 0 · TA-LAND-WARN-MUSTFIX0)·non-draft 를 확인한다. 큐 설정이 있으면 원격 changed gate 뒤 착지 줄에 등록하고, 없으면 기존 `pr land` 를 머리 고정으로 한 번 부른다.
|
|
10
10
|
* - 사다리 R4: `narrow-relaunch` · `wait-retry` · `salvage-relaunch` · `alternative` 도 허용 목록 어휘다 — 실제 발사는 실행부
|
|
11
11
|
* `executeNextAction`(`actions.ts`)이 «목록 ⊕ 같은 수 2회 상한 ⊕ 회당 1건 ⊕ 부하 관문»을 모두 넘을 때만 한다.
|
|
12
12
|
* - `decision-card`: 막힌 과제를 «근거(서명 · 화면 · must-fix)» 붙은 결정 카드로 올린다 — 근거가 하나도 없으면 카드를 올리지 않는다.
|
|
@@ -28,6 +28,7 @@ import { decisionCardGrounds, decisionRaiseArgs, type DecisionCardEvidence, type
|
|
|
28
28
|
import { pendingReviewResults, reviewResultPath, TA_REVIEW_COMPLETION_CARD_ENV, TA_REVIEW_COMPLETION_RESULT_ENV, TA_REVIEW_COMPLETION_STATE_ENV } from './review-result-capture.js';
|
|
29
29
|
import { buildPriorFixContext, PRIOR_FIX_SCOPE_LINE, priorFixBlock, priorFixObservation, type PriorDiffReader, type PriorFixContext } from './review-prior-fix.js';
|
|
30
30
|
import { createLandWorktree, localBranch, localHead, observeLandWorktree, type LandWorktree, type LandWorktreeFailure, type LandWorktreeInput, type LandWorktreeRemoval } from './land-worktree.js';
|
|
31
|
+
import { runQueuedLanding, type QueueLandingInput } from './land-queue.js';
|
|
31
32
|
|
|
32
33
|
export const TASK_AGENT_LIVE_MOVES = ['review', 'propose-green', 'propose-land', 'decision-card', ...LIVE_RETRY_MOVES] as const;
|
|
33
34
|
export type TaskAgentLiveMove = typeof TASK_AGENT_LIVE_MOVES[number];
|
|
@@ -90,6 +91,9 @@ export interface LiveMoveDeps {
|
|
|
90
91
|
log?: (category: string, event: string, data: Record<string, unknown>) => void;
|
|
91
92
|
/** TA-LAND-WORKTREE — cwd HEAD 읽기 · PR 머리 임시 워크트리 만들기(시험 주입 · 기본 = git). */
|
|
92
93
|
landWorktree?: { localHead?: (cwd: string) => string | null; localBranch?: (cwd: string) => string | null; create?: (input: LandWorktreeInput) => Promise<LandWorktree | LandWorktreeFailure> };
|
|
94
|
+
/** TA-LAND-AFTER-REVIEW — injected queue adapter; absent uses configured command after a remote changed gate. */
|
|
95
|
+
queueLanding?: (input: QueueLandingInput) => Promise<{ status: number; stdout: string; stderr?: string }>;
|
|
96
|
+
landQueueConfig?: { command: string; remote: string } | null;
|
|
93
97
|
}
|
|
94
98
|
|
|
95
99
|
/** `executed` = 부작용을 실제로 냈다(리뷰를 띄웠다 · 제안을 적었다). ok 이지만 이미 한 수(같은 머리·이미 제안)면 false. */
|
|
@@ -101,6 +105,8 @@ export interface LiveMoveResult {
|
|
|
101
105
|
resultPath?: string;
|
|
102
106
|
/** TA-LAND-RETRY-ON-INFRA — 실행한 land 의 그 머리 몇 번째 시도인가 · 실패면 갈래(infra|judgement|base-stale)·사유·재시도 가능 여부. */
|
|
103
107
|
landAttempt?: { attempt: number; class?: LandFailureClass; reason?: string; retryAllowed?: boolean };
|
|
108
|
+
/** A queue accepted this head. Merge confirmation belongs to the later train receipt. */
|
|
109
|
+
queued?: boolean;
|
|
104
110
|
}
|
|
105
111
|
|
|
106
112
|
export interface PrHeadView { head: string; state: string; branch?: string; url?: string }
|
|
@@ -543,10 +549,11 @@ export const LAND_RETRY_ON_INFRA_EVENT = 'land-retry-on-infra';
|
|
|
543
549
|
|
|
544
550
|
const landedCycles = new Set<string>();
|
|
545
551
|
|
|
546
|
-
/** `propose-land` — only a passing self review (pass or warn, with must-fix 0) of this exact OPEN, non-draft head may invoke pr land. */
|
|
552
|
+
/** `propose-land` — only a passing self review (pass or warn, with must-fix 0) of this exact OPEN, non-draft head may enqueue or invoke pr land. */
|
|
547
553
|
export async function executeLiveLand(
|
|
548
554
|
card: TaskCard | undefined, pr: number | undefined,
|
|
549
555
|
ctx: { runId?: string | null; cycleId?: string; cwd?: string; produced?: { headCommit?: string; branch?: string; prUrl?: string }; review?: { verdict: 'pass' | 'warn' | 'fail'; head: string; /** TA-LAND-WARN-MUSTFIX0 — `false` 면 리뷰가 실제로 안 돌았다 → land 거부. 슈퍼바이저 입력은 reviewed 리뷰로만 만들어져 칸이 없다. */ reviewed?: boolean };
|
|
556
|
+
/** Exact bytes consumed by the queue's own review check; no path means queue mode cannot proceed. */ reviewResultPath?: string;
|
|
550
557
|
/** TA-REJUDGE-ON-HEAD — 겹침 증거 파일(있으면 land 에 넘길 뿐 · 판정은 그대로). */ overlapEvidence?: string;
|
|
551
558
|
/** REJUDGE base-stale — 증거의 재게이트를 요청한 시각 · 그 앞의 base-stale 시도는 소비됨(`openLandAttempts`). */ gateAt?: string },
|
|
552
559
|
deps: LiveMoveDeps = {},
|
|
@@ -584,6 +591,10 @@ export async function executeLiveLand(
|
|
|
584
591
|
const mustFixCount = (ctx.review as { mustFixCount?: unknown }).mustFixCount;
|
|
585
592
|
if (typeof mustFixCount !== 'number' || !Number.isSafeInteger(mustFixCount) || mustFixCount < 0) return reject(card.id, `PR #${pr} review-must-fix-unknown`, reviewRepo);
|
|
586
593
|
if (mustFixCount > 0) return reject(card.id, `PR #${pr} review-warn-with-must-fix: pass carries ${mustFixCount} must-fix`, reviewRepo);
|
|
594
|
+
const queueConfig = deps.landQueueConfig === undefined ? getUserConfig().taskAgent?.landQueue : deps.landQueueConfig;
|
|
595
|
+
if (queueConfig && (!isAbsolute(queueConfig.command) || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(queueConfig.remote)))
|
|
596
|
+
return reject(card.id, `PR #${pr} land queue command/remote invalid`, reviewRepo);
|
|
597
|
+
if (queueConfig && !ctx.reviewResultPath) return reject(card.id, `PR #${pr} queue review result path missing`, reviewRepo);
|
|
587
598
|
const cycle = ctx.cycleId ?? ctx.runId;
|
|
588
599
|
if (cycle && landedCycles.has(cycle)) return reject(card.id, `cycle ${cycle} already landed — stays shadow`, reviewRepo);
|
|
589
600
|
const path = deps.statePath ?? taskAgentStatePath();
|
|
@@ -695,11 +706,16 @@ export async function executeLiveLand(
|
|
|
695
706
|
let failure: LandFailureClassification | undefined;
|
|
696
707
|
try {
|
|
697
708
|
// The CLI rechecks the pinned PR/head immediately before merge, after its own gates and freeze admission.
|
|
698
|
-
const outcome =
|
|
699
|
-
? await (deps.
|
|
700
|
-
|
|
709
|
+
const outcome = queueConfig
|
|
710
|
+
? await (deps.queueLanding ?? runQueuedLanding)({ card: card.id, pr, head: view.head, cwd: landCwd, statePath: path,
|
|
711
|
+
reviewResult: ctx.reviewResultPath!, command: queueConfig.command, remote: queueConfig.remote,
|
|
712
|
+
entry: (await import('../cli/tasks-cli.js')).ELANOUS_CLI_ENTRY,
|
|
713
|
+
configDir: (await import('../elanous-config-dir.js')).getElanousConfigDirOverride() ?? (await import('../instance/resolve.js')).effectiveInstanceRoot() })
|
|
714
|
+
: overlapEvidence
|
|
715
|
+
? await (deps.land ?? defaultLand)(pr, view.head, landCwd, { overlapEvidence })
|
|
716
|
+
: await (deps.land ?? defaultLand)(pr, view.head, landCwd);
|
|
701
717
|
ok = outcome.status === 0;
|
|
702
|
-
detail = (ok ? outcome.stdout ||
|
|
718
|
+
detail = (ok ? outcome.stdout || `${queueConfig ? 'queued' : 'land merged'} #${pr} head ${view.head.slice(0, 12)}` : outcome.stderr || outcome.stdout || `exit ${outcome.status}`).slice(-300);
|
|
703
719
|
if (!ok) failure = classifyLandFailure(outcome);
|
|
704
720
|
} catch (error) {
|
|
705
721
|
detail = (error instanceof Error ? error.message : String(error)).slice(-300);
|
|
@@ -708,8 +724,13 @@ export async function executeLiveLand(
|
|
|
708
724
|
const retryAllowed = failure?.class === 'infra' && attempt < LAND_ATTEMPTS_PER_HEAD_ON_INFRA;
|
|
709
725
|
// 인프라 실패로 재시도가 남으면 주기 표시도 푼다 — 같은 주기 id(재판정 틱의 `rejudge:<card>:<head>`)가 그 한 번을 막지 않게.
|
|
710
726
|
if (retryAllowed && cycle) landedCycles.delete(cycle);
|
|
711
|
-
if (worktree) {
|
|
712
|
-
//
|
|
727
|
+
if (worktree && queueConfig && ok) {
|
|
728
|
+
// The queue row pins this exact path until the train consumes it. Removing it here
|
|
729
|
+
// would turn a successful enqueue into a guaranteed missing-tree landing failure.
|
|
730
|
+
observeLandWorktree({ card: card.id, pr, head: view.head, created: worktree.created ?? null,
|
|
731
|
+
removed: false, reason: 'queued — train owns this exact-head worktree until its receipt' }, deps.log);
|
|
732
|
+
} else if (worktree) {
|
|
733
|
+
// Direct land and rejected queue attempts no longer need the temporary checkout.
|
|
713
734
|
let removal: LandWorktreeRemoval;
|
|
714
735
|
try { removal = worktree.cleanup(); } catch (error) { removal = { removed: false, reason: String(error).slice(-200) }; }
|
|
715
736
|
observeLandWorktree({ card: card.id, pr, head: view.head, created: worktree.created ?? null, removed: removal.removed, ...(removal.branchRemoved !== undefined ? { branchRemoved: removal.branchRemoved } : {}),
|
|
@@ -746,7 +767,7 @@ export async function executeLiveLand(
|
|
|
746
767
|
return observe(deps, withRepo({ kind, card: card.id, ok: false, executed: true, landAttempt,
|
|
747
768
|
detail: `land ${ok ? 'succeeded' : 'failed'} but card update failed: ${String(error).slice(-230)}` }));
|
|
748
769
|
}
|
|
749
|
-
return observe(deps, withRepo({ kind, card: card.id, ok, executed: true, detail, landAttempt }));
|
|
770
|
+
return observe(deps, withRepo({ kind, card: card.id, ok, executed: true, detail, landAttempt, ...(queueConfig && ok ? { queued: true } : {}) }));
|
|
750
771
|
}
|
|
751
772
|
|
|
752
773
|
/** `propose-green` — 비지 않은 근거가 있을 때만 카드에 제안을 적는다(한 번). 체크리스트는 쓰지 않는다. */
|
|
@@ -2,6 +2,7 @@ import { debug } from '../debug/log.js';
|
|
|
2
2
|
import { listChecklist, setItemIfSnapshot, type Checklist } from '../release-loop/checklist.js';
|
|
3
3
|
import { judgeLandedCell, parseJudgeSignals, type GreenVerdict } from '../release-loop/landed-to-green.js';
|
|
4
4
|
import { cardPrNumber, readTaskAgentState, taskAgentStatePath, updateTaskCard, type TaskCard } from './task-hand.js';
|
|
5
|
+
import { isGoalOnlyPr } from './judge.js';
|
|
5
6
|
|
|
6
7
|
export interface LandedTaskPr { number: number; url: string; headRefOid: string; state: string; baseRefName: string; mergedAt: string; files?: Array<{ path: string }> }
|
|
7
8
|
export interface PostlandDeps {
|
|
@@ -32,6 +33,10 @@ export function candidateMergedTaskCells(number: number, statePath = taskAgentSt
|
|
|
32
33
|
export function closeMergedTaskCard(pr: LandedTaskPr, cwd: string, deps: PostlandDeps): string | null {
|
|
33
34
|
const log = deps.log ?? debug.log.bind(debug);
|
|
34
35
|
if (pr.state !== 'MERGED' || pr.baseRefName !== 'main' || !/^[a-f0-9]{40}$/i.test(pr.headRefOid) || !pr.url) return null;
|
|
36
|
+
if (isGoalOnlyPr(pr.files?.map((file) => file.path))) {
|
|
37
|
+
log('task-agent', 'postland-card-skipped', { pr: pr.number, reason: 'goal-only-pr', targetDiff: 0 });
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
35
40
|
const path = deps.statePath ?? taskAgentStatePath();
|
|
36
41
|
const tasks = readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(path).tasks ?? {};
|
|
37
42
|
const cards = Object.values(tasks).filter((card) => card.taLand && card.checklistId && cardPrNumber(card) === pr.number
|