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
|
@@ -11,6 +11,7 @@ import { runSelfGateCli, type SelfGateCliOptions, type SelfGateCliResult } from
|
|
|
11
11
|
import { dispatchHeavyCheck, isValidGateHost, type DispatchDeps, type DispatchOptions } from '../self-implement/gate-remote.js';
|
|
12
12
|
import { latestPublishedPreviousVersion } from '../../scripts/release-loop/unattended-release.js';
|
|
13
13
|
import { baseVersion, isReleaseVersion } from '../../scripts/release-loop/release-version.js';
|
|
14
|
+
import { executeTuiNodeCheck, type ExecutedTuiCheck } from '../../scripts/release-loop/tui-node-checks.js';
|
|
14
15
|
|
|
15
16
|
export const LIGHT_RC_ALWAYS_FILE = 'release/light-rc-always.txt';
|
|
16
17
|
export const LIGHT_RC_DEFAULT_SHARDS = 4;
|
|
@@ -28,9 +29,14 @@ export interface LightRcOptions {
|
|
|
28
29
|
/** Run on this machine (the remote child is re-invoked with it). */
|
|
29
30
|
local?: boolean;
|
|
30
31
|
shards?: number;
|
|
32
|
+
/** OP FU — pass `--fixed-shard-distribution` to self gate (sorted round-robin into `shards`, no RSS pre-measurement).
|
|
33
|
+
* Opt-in; absent = the measured planner, unchanged. Also carried to the remote child. */
|
|
34
|
+
fixedShardDistribution?: boolean;
|
|
31
35
|
/** Release ledger root for the previous-version lookup (release run's deps.ledgerRoot). */
|
|
32
36
|
ledgerRoot?: string;
|
|
33
37
|
log?: (line: string) => void;
|
|
38
|
+
/** Rehearsal-only TUI screen check; other light-rc callers keep their current defaults. */
|
|
39
|
+
rehearsalTui?: boolean;
|
|
34
40
|
}
|
|
35
41
|
|
|
36
42
|
export interface LightRcResult {
|
|
@@ -57,6 +63,7 @@ export interface LightRcResult {
|
|
|
57
63
|
/** LIGHT-RC-MEASURE ③ — why the gate produced no measurement (e.g. `shard-2`); null = it measured. Carried in the
|
|
58
64
|
* JSON so the reason reaches the caller even when the remote child's human lines (stderr) do not. */
|
|
59
65
|
unmeasured: string | null;
|
|
66
|
+
rehearsalTui?: ExecutedTuiCheck;
|
|
60
67
|
}
|
|
61
68
|
|
|
62
69
|
export interface LightRcDeps {
|
|
@@ -68,6 +75,7 @@ export interface LightRcDeps {
|
|
|
68
75
|
dispatch?: (opts: DispatchOptions, deps?: DispatchDeps) => Promise<number>;
|
|
69
76
|
/** Extra dispatch deps (runner · settings) — tests drive the real dispatch with a fake host. */
|
|
70
77
|
dispatchDeps?: Omit<DispatchDeps, 'write'>;
|
|
78
|
+
tuiCheck?: typeof executeTuiNodeCheck;
|
|
71
79
|
/** Detached checkout of `sha` for a local run whose tree is not at the measured commit (default: git worktree add
|
|
72
80
|
* --detach in a temp dir ⊕ bun install); `cleanup` removes it. */
|
|
73
81
|
checkout?: (sha: string, repo: string, log: (line: string) => void) => { dir: string; cleanup: () => void };
|
|
@@ -180,13 +188,21 @@ export async function runLightRc(version: string, opts: LightRcOptions = {}, dep
|
|
|
180
188
|
let alwaysInclude = readList(cwd);
|
|
181
189
|
|
|
182
190
|
let local: SelfGateCliResult | undefined;
|
|
183
|
-
|
|
191
|
+
let localTui: ExecutedTuiCheck | undefined;
|
|
192
|
+
const runLocal = async () => {
|
|
184
193
|
// ① The gate scopes by its tree's HEAD — so a tree that is not at the measured commit runs in a detached checkout of it.
|
|
185
194
|
const checkout = worktreeHead === measuredCommit ? undefined : (deps.checkout ?? defaultCheckout)(measuredCommit, cwd, log);
|
|
186
195
|
try {
|
|
187
196
|
const dir = checkout?.dir ?? cwd;
|
|
188
197
|
if (checkout) alwaysInclude = readList(dir);
|
|
189
|
-
local = (deps.runGate ?? runSelfGateCli)(dir, { base, shards, alwaysInclude, includeImporterTests: true });
|
|
198
|
+
local = (deps.runGate ?? runSelfGateCli)(dir, { base, shards, ...(opts.fixedShardDistribution ? { fixedShardDistribution: true } : {}), alwaysInclude, includeImporterTests: true });
|
|
199
|
+
if (opts.rehearsalTui) {
|
|
200
|
+
const command = async (cmd: string, args: string[], tree: string, limitMs?: number) => {
|
|
201
|
+
const run = spawnSync(cmd, args, { cwd: tree, encoding: 'utf8', timeout: limitMs });
|
|
202
|
+
return { rc: run.status ?? 2, output: `${run.stdout ?? ''}\n${run.stderr ?? ''}` };
|
|
203
|
+
};
|
|
204
|
+
localTui = await (deps.tuiCheck ?? executeTuiNodeCheck)(measuredCommit, dir, command);
|
|
205
|
+
}
|
|
190
206
|
} finally { checkout?.cleanup(); }
|
|
191
207
|
for (const line of local.lines) log(line);
|
|
192
208
|
return local.exitCode;
|
|
@@ -195,7 +211,7 @@ export async function runLightRc(version: string, opts: LightRcOptions = {}, dep
|
|
|
195
211
|
const rc = await (deps.dispatch ?? dispatchHeavyCheck)({
|
|
196
212
|
tool: 'self-gate', repo: cwd, installPwa: true, refs: [base], json: true, commit: measuredCommit,
|
|
197
213
|
// The host re-runs this command with --local (and ELANOUS_GATE_REMOTE_CHILD=1), so it never recurses.
|
|
198
|
-
remoteArgv: (sha) => ['bun', 'bin/elanous.mjs', 'release', 'light-rc', '--version', version, '--base', sha(base), '--head', measuredCommit, '--shards', String(shards), '--local', '--json'],
|
|
214
|
+
remoteArgv: (sha) => ['bun', 'bin/elanous.mjs', 'release', 'light-rc', '--version', version, '--base', sha(base), '--head', measuredCommit, '--shards', String(shards), ...(opts.fixedShardDistribution ? ['--fixed-shard-distribution'] : []), '--local', '--json', ...(opts.rehearsalTui ? ['--rehearsal-tui'] : [])],
|
|
199
215
|
flags: { remote: opts.local ? undefined : opts.remote ?? true, local: !!opts.local },
|
|
200
216
|
runLocal,
|
|
201
217
|
}, {
|
|
@@ -236,11 +252,22 @@ export async function runLightRc(version: string, opts: LightRcOptions = {}, dep
|
|
|
236
252
|
unmeasured: typeof remote.unmeasured === 'string' && remote.unmeasured
|
|
237
253
|
? remote.unmeasured
|
|
238
254
|
: typeof remote.introduced === 'number' ? null : LIGHT_RC_REASON_NOT_REPORTED,
|
|
255
|
+
...(remote.rehearsalTui ? { rehearsalTui: remote.rehearsalTui } : {}),
|
|
239
256
|
};
|
|
240
257
|
}
|
|
241
258
|
// Unmeasured (null) or unclassified failures are never green; policy-gate findings in the gate output are reported
|
|
242
259
|
// (gate rc), not a regression.
|
|
243
|
-
|
|
260
|
+
if (opts.rehearsalTui) {
|
|
261
|
+
if (local) {
|
|
262
|
+
result.rehearsalTui = localTui ?? { outcome: 'unmeasured', detail: 'local TUI screen result missing' };
|
|
263
|
+
} else {
|
|
264
|
+
const tui = result.rehearsalTui;
|
|
265
|
+
result.rehearsalTui = tui && ['ok', 'fail', 'unmeasured'].includes(tui.outcome) && typeof tui.detail === 'string' && tui.detail.length > 0
|
|
266
|
+
? tui : { outcome: 'unmeasured', detail: 'remote TUI screen result missing' };
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
result.ok = result.introduced === 0 && result.unclassified === 0 && result.unmeasured === null
|
|
270
|
+
&& (!opts.rehearsalTui || result.rehearsalTui?.outcome === 'ok');
|
|
244
271
|
debug.log('release.light-rc', 'done', { version, base, measuredCommit, worktreeHead, importerTests: result.importerTests, introduced: result.introduced, preexisting: result.preexisting, unclassified: result.unclassified, shards, remote: result.remote, unmeasured: result.unmeasured });
|
|
245
272
|
return result;
|
|
246
273
|
}
|
|
@@ -250,5 +277,6 @@ export function formatLightRc(result: LightRcResult): string[] {
|
|
|
250
277
|
`${result.ok ? '✅' : '⛔'} light-rc ${result.version} · base ${result.base.slice(0, 12)} · measured ${result.measuredCommit.slice(0, 12)} · ${result.remote ? `host ${result.remote}` : 'local'} · shards ${result.shards}`,
|
|
251
278
|
` introduced ${result.introduced ?? '못 쟀다'} · preexisting ${result.preexisting ?? '못 쟀다'} · unclassified ${result.unclassified ?? '못 쟀다'} · importer tests ${result.importerTests ?? '못 쟀다'} · always-include ${result.alwaysInclude}${result.alwaysIncludeMissing.length ? ` (missing: ${result.alwaysIncludeMissing.join(', ')})` : ''} · gate rc ${result.gateExitCode}`,
|
|
252
279
|
...(result.unmeasured !== null ? [` shards: unmeasured (${result.unmeasured})`] : []),
|
|
280
|
+
...(result.rehearsalTui ? [` TUI screens: ${result.rehearsalTui.outcome} (${result.rehearsalTui.detail})`] : []),
|
|
253
281
|
];
|
|
254
282
|
}
|
|
@@ -6,7 +6,7 @@ import { resolveRepositoryName } from '../harness/repository-name.js';
|
|
|
6
6
|
import { getElanousConfigDirOverride } from '../elanous-config-dir.js';
|
|
7
7
|
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
8
8
|
import { userConfigPath } from '../user-config.js';
|
|
9
|
-
import { addItem, checklistHistory, listChecklist, ownerMatches, parseOwner, setItem, validateCeoLoad, type ChecklistItem } from './checklist.js';
|
|
9
|
+
import { addItem, checklistHistory, inspectChecklistTargetPaths, listChecklist, ownerMatches, parseOwner, setItem, validateCeoLoad, type ChecklistItem } from './checklist.js';
|
|
10
10
|
import { assignedVersions, move, releasedVersion } from './feature-store.js';
|
|
11
11
|
import { debug } from '../debug/log.js';
|
|
12
12
|
import { kstDay, listSchedules, type ReleaseSchedule } from './release-schedule.js';
|
|
@@ -110,6 +110,12 @@ function validCeoCap(cap: number): number {
|
|
|
110
110
|
|
|
111
111
|
export function placementCeoDailyCap(): number { return validCeoCap(placementConfig().ceoDailyCap ?? 30); }
|
|
112
112
|
|
|
113
|
+
/** One configuration snapshot for the read-only pull-forward caller. */
|
|
114
|
+
export function pullForwardPlacementConfig(): { seatCap: Record<string, number>; ceoDailyCap: number; ceoCalendar: CeoCalendar } {
|
|
115
|
+
const config = placementConfig();
|
|
116
|
+
return { seatCap: config.seatCap ?? {}, ceoDailyCap: validCeoCap(config.ceoDailyCap ?? 30), ceoCalendar: config.ceoCalendar ?? {} };
|
|
117
|
+
}
|
|
118
|
+
|
|
113
119
|
function validDay(day: string): boolean {
|
|
114
120
|
return typeof day === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(day) && Number.isFinite(Date.parse(`${day}T00:00:00Z`))
|
|
115
121
|
&& new Date(`${day}T00:00:00Z`).toISOString().slice(0, 10) === day;
|
|
@@ -406,6 +412,91 @@ export function rebalance(version: string, deps: PlacementDeps = {}): RebalanceR
|
|
|
406
412
|
return result;
|
|
407
413
|
}
|
|
408
414
|
|
|
415
|
+
export interface PullForwardDeps {
|
|
416
|
+
now: Date;
|
|
417
|
+
schedules: readonly ReleaseSchedule[];
|
|
418
|
+
checklists: ReadonlyMap<string, readonly ChecklistItem[]>;
|
|
419
|
+
released: string;
|
|
420
|
+
merged24h: number;
|
|
421
|
+
seatCap: Record<string, number>;
|
|
422
|
+
ceoDailyCap: number;
|
|
423
|
+
ceoCalendar: CeoCalendar;
|
|
424
|
+
signal: { order?: readonly string[]; hold?: readonly string[] };
|
|
425
|
+
targetPathExists: (path: string) => boolean;
|
|
426
|
+
backlog?: readonly string[];
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/** Read-only plan: every operational input is supplied by the caller. */
|
|
430
|
+
export function planPullForward(deps: PullForwardDeps): RebalanceResult {
|
|
431
|
+
if (typeof deps.targetPathExists !== 'function') throw new CliUserError('대상 저장소 경로 판정기가 필요하다');
|
|
432
|
+
const rows = [...deps.schedules].sort((a, b) => versionOrder(a.version, b.version));
|
|
433
|
+
const now = deps.now.getTime();
|
|
434
|
+
const backlog = deps.backlog ?? BACKLOG_VERSIONS;
|
|
435
|
+
const released = deps.released;
|
|
436
|
+
const open = rows.filter((row) => (!released || versionOrder(row.version, released) > 0) && available(row, now, backlog));
|
|
437
|
+
const target = open[0];
|
|
438
|
+
if (!target) throw new CliUserError('당겨올 판이 없다 — 착지 마감이 안 지난 판이 필요하다');
|
|
439
|
+
const result: RebalanceResult = { decisions: [], blocked: [] };
|
|
440
|
+
const source = rows.find((row) => versionOrder(row.version, target.version) > 0 && !backlog.includes(row.version));
|
|
441
|
+
if (!source || !available(source, now, backlog)) return result;
|
|
442
|
+
const sources = [...new Set([...rows.map((row) => row.version), ...deps.checklists.keys(), ...backlog])];
|
|
443
|
+
const snapshots = new Map(sources.map((version) => [version, [...(deps.checklists.get(version) ?? [])]]));
|
|
444
|
+
const remainingP0 = snapshots.get(target.version)!.filter((item) => item.priority === 'P0' && item.status !== 'green' && item.status !== 'done').length;
|
|
445
|
+
const hold = new Set(deps.signal?.hold ?? []);
|
|
446
|
+
const rank = new Map<string, number>();
|
|
447
|
+
for (const [index, id] of (deps.signal?.order ?? []).entries()) if (!rank.has(id)) rank.set(id, index);
|
|
448
|
+
// Untyped legacy cells are fail-closed on human-action words in either language. These
|
|
449
|
+
// conservative markers may exclude code about approvals, but must never move a manual gate.
|
|
450
|
+
const human = /\uD83D\uDC51|실기기|실기 |사람|대표|손|라이브 1회|녹화|세미나|수동|승인|검토|결정|HITL|manual|human|approval|sign.off|review|operator|ceo/i;
|
|
451
|
+
const complete = new Set<string>();
|
|
452
|
+
const incomplete = new Set<string>();
|
|
453
|
+
for (const items of snapshots.values()) for (const item of items) {
|
|
454
|
+
if (item.status === 'green' || item.status === 'done') complete.add(item.id);
|
|
455
|
+
else incomplete.add(item.id);
|
|
456
|
+
}
|
|
457
|
+
const targetPathsReady = (title: string): boolean => {
|
|
458
|
+
const check = inspectChecklistTargetPaths({ title }, { existsAtMain: deps.targetPathExists });
|
|
459
|
+
return check.targets.length > 0 && check.warnings.length === 0;
|
|
460
|
+
};
|
|
461
|
+
const candidates = snapshots.get(source.version)!.filter((item) =>
|
|
462
|
+
(item.priority === 'P0' || item.priority === 'P1') && item.status !== 'green' && item.status !== 'done'
|
|
463
|
+
&& !hold.has(item.id) && !human.test(item.title) && (!item.dispatchKind || item.dispatchKind === 'code')
|
|
464
|
+
&& (item.ceoMinutes === undefined || item.ceoMinutes === 0)
|
|
465
|
+
&& targetPathsReady(item.title)
|
|
466
|
+
&& (item.predecessors ?? []).every((id) => complete.has(id) && !incomplete.has(id)))
|
|
467
|
+
.map((item, index) => ({ item, index }))
|
|
468
|
+
.sort((a, b) => (rank.get(a.item.id) ?? Infinity) - (rank.get(b.item.id) ?? Infinity)
|
|
469
|
+
|| (a.item.priority === 'P0' ? 0 : 1) - (b.item.priority === 'P0' ? 0 : 1) || a.index - b.index);
|
|
470
|
+
if (!candidates.length) return result;
|
|
471
|
+
if (Date.parse(target.landBy ?? target.cutAt) - now < 4 * 60 * 60 * 1000) {
|
|
472
|
+
for (const { item } of candidates)
|
|
473
|
+
result.blocked.push({ id: item.id, from: source.version, to: target.version, reason: `지금 판 ${target.version} 착지 마감까지 4시간 미만 — 당겨오기 보류` });
|
|
474
|
+
return result;
|
|
475
|
+
}
|
|
476
|
+
if (remainingP0 > 3) {
|
|
477
|
+
for (const { item } of candidates)
|
|
478
|
+
result.blocked.push({ id: item.id, from: source.version, to: target.version, reason: `지금 판 ${target.version} 남은 P0 ${remainingP0} > 3 — 당겨오기 보류` });
|
|
479
|
+
return result;
|
|
480
|
+
}
|
|
481
|
+
const rate = deps.merged24h;
|
|
482
|
+
if (!Number.isInteger(rate) || rate < 0) throw new CliUserError('24시간 병합 PR 수가 잘못됐다');
|
|
483
|
+
const caps = deps.seatCap;
|
|
484
|
+
const ceoCap = validCeoCap(deps.ceoDailyCap);
|
|
485
|
+
const calendar = deps.ceoCalendar;
|
|
486
|
+
for (const { item } of candidates) {
|
|
487
|
+
if (result.decisions.length >= 5) break;
|
|
488
|
+
const from = source.version;
|
|
489
|
+
// The pull-forward contract uses the schedule's cutAt only when landBy is absent.
|
|
490
|
+
const destination = { ...target, landBy: target.landBy ?? target.cutAt };
|
|
491
|
+
const violation = moveConstraint(item, destination, backlog, snapshots, now, rate, caps, rows, ceoCap, calendar, released);
|
|
492
|
+
if (violation) { result.blocked.push({ id: item.id, from, to: target.version, reason: violation }); continue; }
|
|
493
|
+
result.decisions.push({ id: item.id, from, version: target.version, reason: `다음 판 ${from} → 지금 판 ${target.version} 당겨오기 · 남은 P0 ${remainingP0} ≤ 3 · 착지 마감 ≥ 4h`, displaced: [] });
|
|
494
|
+
snapshots.set(from, snapshots.get(from)!.filter((cell) => cell.id !== item.id));
|
|
495
|
+
snapshots.get(target.version)!.push(item);
|
|
496
|
+
}
|
|
497
|
+
return result;
|
|
498
|
+
}
|
|
499
|
+
|
|
409
500
|
/** Reasons that justify a second forward rollover of the same cell (대표 10-10 «계속 이월되지 않게»). */
|
|
410
501
|
const SECOND_ROLLOVER_REASON_PREFIXES: readonly string[] = ['쪼개기:', '닫기:', '\u{1F451}:'];
|
|
411
502
|
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { availableParallelism, cpus as hostCpus, freemem, totalmem } from 'node:os';
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { selectGateTestFiles } from '../self-implement/gate-cli.js';
|
|
6
|
+
import { readFileMemory } from '../../scripts/release-loop/shard-plan.js';
|
|
7
|
+
import { gateShardsPath, readGateShards } from './gate-shards.js';
|
|
8
|
+
import { LIGHT_RC_ALWAYS_FILE, LIGHT_RC_DEFAULT_SHARDS, parseAlwaysIncludeList, previousCutBase } from './light-rc.js';
|
|
9
|
+
|
|
10
|
+
const FILE_MEMORY_SOURCE = 'docs/measurements/td1-whole-gate-mechanical-2026-10-01.tsv';
|
|
11
|
+
|
|
12
|
+
export interface RehearsalShardPlan {
|
|
13
|
+
shards: number;
|
|
14
|
+
testFiles: number | null;
|
|
15
|
+
/** Observed on the tick host, not necessarily the remote gate host. */
|
|
16
|
+
resources: { cpus: number; freeBytes: number; totalBytes: number };
|
|
17
|
+
gatePlanShards: number | null;
|
|
18
|
+
/** Local preflight budget, not a measured remote peak-RSS or a workload-specific guarantee. */
|
|
19
|
+
capacity?: { reserveBytes: number; bytesPerShard: number; memoryShards: number | null; requiredBytes: number; measuredFiles: number; peakFileBytes: number | null };
|
|
20
|
+
unmeasured: string | null;
|
|
21
|
+
/** The remote host's capacity is checked by the actual RC, after this preflight. */
|
|
22
|
+
remoteCapacityPending?: boolean;
|
|
23
|
+
rssRevisionPending?: boolean;
|
|
24
|
+
planningGaps?: string[];
|
|
25
|
+
remoteCapacityVerifiedBy?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface RehearsalShardPlanDeps {
|
|
29
|
+
/** Rehearsal light RC dispatches remotely; local CPU/memory is evidence only, not a gate-host limit. */
|
|
30
|
+
remoteGate?: boolean;
|
|
31
|
+
select?: (checkout: string, options: { base: string; alwaysInclude: string[]; includeImporterTests: true }) => { testFiles: string[]; alwaysIncludeMissing?: readonly string[]; lookupFailed?: string | null; unrunImporterTotal?: number | null; skipTestStep?: boolean; routeLookupFailures?: readonly unknown[]; unverified?: readonly string[]; callerTestsOverflow?: readonly unknown[] };
|
|
32
|
+
resources?: () => RehearsalShardPlan['resources'];
|
|
33
|
+
board?: typeof readGateShards;
|
|
34
|
+
readAlways?: (path: string) => string;
|
|
35
|
+
resolveBase?: (version: string, checkout: string, root: string) => string;
|
|
36
|
+
fileMemory?: (path: string) => Map<string, number>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Preflight only: the gate still performs its own selection at execution time. The local budget uses measured
|
|
40
|
+
* selected-file peak RSS with a 2 GiB floor per shard and reserves 1 GiB for the host. The RC result is the
|
|
41
|
+
* authority for whether execution on its actual gate host succeeded. */
|
|
42
|
+
const GIB = 1024 ** 3;
|
|
43
|
+
const RESERVE_BYTES = GIB;
|
|
44
|
+
const BYTES_PER_SHARD = 2 * GIB;
|
|
45
|
+
|
|
46
|
+
/** The dated TSV has no dependency graph/revision. Require the whole checkout to match its source commit;
|
|
47
|
+
* otherwise RSS is provisional until a completed RC measures this actual checkout on its gate host. */
|
|
48
|
+
function measurementMatchesCheckout(checkout: string): boolean {
|
|
49
|
+
const source = spawnSync('git', ['log', '-1', '--format=%H', '--', FILE_MEMORY_SOURCE], { cwd: checkout, encoding: 'utf8' });
|
|
50
|
+
const commit = source.stdout?.trim();
|
|
51
|
+
if (source.status !== 0 || !/^[0-9a-f]{40}$/.test(commit ?? '')) return false;
|
|
52
|
+
const diff = spawnSync('git', ['diff', '--quiet', commit!, 'HEAD', '--', '.'], { cwd: checkout, encoding: 'utf8' });
|
|
53
|
+
if (diff.status !== 0) return false;
|
|
54
|
+
const working = spawnSync('git', ['status', '--porcelain', '--untracked-files=all'], { cwd: checkout, encoding: 'utf8' });
|
|
55
|
+
return working.status === 0 && !working.stdout?.trim();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** OS free memory can describe the entire host rather than the tick's container; bound it by cgroup headroom. */
|
|
59
|
+
export function rehearsalHostResources(read: (path: string) => string = (path) => readFileSync(path, 'utf8')): RehearsalShardPlan['resources'] {
|
|
60
|
+
const cpus = Math.max(1, Number(availableParallelism?.() ?? hostCpus()?.length ?? 1) || 1);
|
|
61
|
+
let freeBytes = freemem(), totalBytes = totalmem();
|
|
62
|
+
for (const [limitPath, usagePath] of [
|
|
63
|
+
['/sys/fs/cgroup/memory.max', '/sys/fs/cgroup/memory.current'],
|
|
64
|
+
['/sys/fs/cgroup/memory/memory.limit_in_bytes', '/sys/fs/cgroup/memory/memory.usage_in_bytes'],
|
|
65
|
+
]) {
|
|
66
|
+
try {
|
|
67
|
+
const limit = Number(read(limitPath).trim()), usage = Number(read(usagePath).trim());
|
|
68
|
+
if (Number.isSafeInteger(limit) && limit > 0 && limit < totalBytes && Number.isSafeInteger(usage) && usage >= 0) {
|
|
69
|
+
totalBytes = limit;
|
|
70
|
+
freeBytes = Math.min(freeBytes, Math.max(0, limit - usage));
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
} catch { /* not running inside this cgroup version */ }
|
|
74
|
+
}
|
|
75
|
+
return { cpus, freeBytes, totalBytes };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function planRehearsalShards(version: string, root: string, checkout: string, deps: RehearsalShardPlanDeps = {}): RehearsalShardPlan {
|
|
79
|
+
const reasons: string[] = [];
|
|
80
|
+
let rssRevisionPending = false;
|
|
81
|
+
let resources: RehearsalShardPlan['resources'];
|
|
82
|
+
try { resources = (deps.resources ?? rehearsalHostResources)(); }
|
|
83
|
+
catch (error) {
|
|
84
|
+
resources = { cpus: 0, freeBytes: 0, totalBytes: 0 };
|
|
85
|
+
reasons.push(`host resource probe failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
86
|
+
}
|
|
87
|
+
let gatePlanShards: number | null = null;
|
|
88
|
+
try {
|
|
89
|
+
const board = (deps.board ?? readGateShards)(gateShardsPath(version, root));
|
|
90
|
+
gatePlanShards = board?.version === version && board.shards.length && new Set(board.shards.map(shard => shard.id)).size === board.shards.length ? board.shards.length : null;
|
|
91
|
+
} catch (error) { reasons.push(`persisted gate shard plan unreadable: ${error instanceof Error ? error.message : String(error)}`); }
|
|
92
|
+
let testFiles: number | null = null;
|
|
93
|
+
let measuredFiles = 0;
|
|
94
|
+
let peakFileBytes: number | null = null;
|
|
95
|
+
try {
|
|
96
|
+
const path = join(checkout, LIGHT_RC_ALWAYS_FILE);
|
|
97
|
+
const text = deps.readAlways ? deps.readAlways(path) : existsSync(path) ? readFileSync(path, 'utf8') : undefined;
|
|
98
|
+
if (text === undefined) throw new Error(`${LIGHT_RC_ALWAYS_FILE} missing`);
|
|
99
|
+
const base = (deps.resolveBase ?? ((v, cwd, ledgerRoot) => previousCutBase(v, { cwd, ledgerRoot })))(version, checkout, root);
|
|
100
|
+
const selection = (deps.select ?? ((cwd, opts) => selectGateTestFiles(cwd, opts)))(checkout, { base, alwaysInclude: parseAlwaysIncludeList(text), includeImporterTests: true });
|
|
101
|
+
const files = [...new Set(selection.testFiles)];
|
|
102
|
+
testFiles = files.length;
|
|
103
|
+
try {
|
|
104
|
+
const memory = (deps.fileMemory ?? readFileMemory)(join(checkout, FILE_MEMORY_SOURCE));
|
|
105
|
+
const peaks = files.map(file => memory.get(file)).filter((value): value is number => value !== undefined && Number.isFinite(value) && value > 0);
|
|
106
|
+
measuredFiles = peaks.length;
|
|
107
|
+
if (peaks.length) peakFileBytes = Math.ceil(peaks.reduce((largest, value) => Math.max(largest, value), 0) * 1_000_000);
|
|
108
|
+
if (measuredFiles !== testFiles) reasons.push(`selected file memory not measured: ${testFiles - measuredFiles}/${testFiles}`);
|
|
109
|
+
if (!deps.fileMemory && files.length && !measurementMatchesCheckout(checkout)) {
|
|
110
|
+
if (deps.remoteGate) rssRevisionPending = true;
|
|
111
|
+
else reasons.push('selected file RSS measurement revision not verified against checkout');
|
|
112
|
+
}
|
|
113
|
+
} catch (error) { reasons.push(`selected file memory unavailable: ${error instanceof Error ? error.message : String(error)}`); }
|
|
114
|
+
if (selection.alwaysIncludeMissing?.length) reasons.push(`always-include missing: ${selection.alwaysIncludeMissing.join(', ')}`);
|
|
115
|
+
if (selection.lookupFailed) reasons.push(`importer lookup failed: ${selection.lookupFailed}`);
|
|
116
|
+
if (selection.unrunImporterTotal === undefined) reasons.push('importer coverage not reported');
|
|
117
|
+
if (selection.unrunImporterTotal === null || (selection.unrunImporterTotal ?? 0) > 0) reasons.push(`importer tests not run: ${selection.unrunImporterTotal ?? 'unknown'}`);
|
|
118
|
+
if (selection.routeLookupFailures?.length) reasons.push(`route lookup failed: ${selection.routeLookupFailures.length}`);
|
|
119
|
+
if (selection.unverified?.length) reasons.push(`unverified scope: ${selection.unverified.length}`);
|
|
120
|
+
if (selection.callerTestsOverflow?.length) reasons.push(`caller tests overflow: ${selection.callerTestsOverflow.length}`);
|
|
121
|
+
if (selection.skipTestStep) reasons.push('gate test step skipped');
|
|
122
|
+
if (!testFiles) reasons.push('selected test files empty');
|
|
123
|
+
} catch (error) { reasons.push(`test selection unavailable: ${error instanceof Error ? error.message : String(error)}`); }
|
|
124
|
+
if (gatePlanShards === null) reasons.push('persisted gate shard plan unavailable');
|
|
125
|
+
const cpuValid = Number.isSafeInteger(resources.cpus) && resources.cpus > 0;
|
|
126
|
+
const memoryValid = Number.isFinite(resources.freeBytes) && resources.freeBytes >= 0 && Number.isFinite(resources.totalBytes) && resources.totalBytes > 0 && resources.freeBytes <= resources.totalBytes;
|
|
127
|
+
if (!deps.remoteGate && (!cpuValid || !memoryValid)) reasons.push('host resources unavailable');
|
|
128
|
+
const bytesPerShard = Math.max(BYTES_PER_SHARD, peakFileBytes ?? 0);
|
|
129
|
+
const memoryShards = memoryValid ? Math.max(0, Math.floor((resources.freeBytes - RESERVE_BYTES) / bytesPerShard)) : null;
|
|
130
|
+
const candidate = Math.max(1, Math.min(gatePlanShards ?? LIGHT_RC_DEFAULT_SHARDS, testFiles ?? LIGHT_RC_DEFAULT_SHARDS, deps.remoteGate ? Number.MAX_SAFE_INTEGER : cpuValid ? resources.cpus : LIGHT_RC_DEFAULT_SHARDS));
|
|
131
|
+
if (!deps.remoteGate && peakFileBytes !== null && memoryValid && resources.freeBytes < RESERVE_BYTES + peakFileBytes) {
|
|
132
|
+
reasons.push(`selected file peak exceeds host memory: peak ${peakFileBytes}, free ${resources.freeBytes}, reserve ${RESERVE_BYTES} bytes`);
|
|
133
|
+
}
|
|
134
|
+
// Never treat a 0-slot host as sufficient for one shard. The caller must leave an unrun step retryable.
|
|
135
|
+
const shards = deps.remoteGate || memoryShards === null ? candidate : Math.max(1, Math.min(candidate, memoryShards));
|
|
136
|
+
const capacity = { reserveBytes: RESERVE_BYTES, bytesPerShard, memoryShards, requiredBytes: RESERVE_BYTES + shards * bytesPerShard, measuredFiles, peakFileBytes };
|
|
137
|
+
if (!deps.remoteGate && memoryShards === 0) reasons.push(`host memory insufficient: free ${resources.freeBytes} < required ${capacity.requiredBytes} bytes for 1 shard`);
|
|
138
|
+
// The exported local planner has no local RC caller to validate aggregate workload capacity. A prior board's
|
|
139
|
+
// shard count and individual file peaks cannot prove that hundreds of tests fit one shard.
|
|
140
|
+
if (!deps.remoteGate) reasons.push('local gate shard workload sufficiency not measured');
|
|
141
|
+
// A complete selected-file measurement plus the persisted shard count and a valid host budget is enough to
|
|
142
|
+
// select a candidate. Execution on another host is judged by the RC result, not by a permanent preflight warning.
|
|
143
|
+
const remoteCapacityReason = 'remote gate host resources unmeasured before RC';
|
|
144
|
+
const rssRevisionReason = 'selected file RSS measurement revision not verified before RC';
|
|
145
|
+
return { shards, testFiles, resources, gatePlanShards, capacity,
|
|
146
|
+
...(deps.remoteGate ? { remoteCapacityPending: true, rssRevisionPending, planningGaps: reasons } : {}),
|
|
147
|
+
unmeasured: reasons.length || deps.remoteGate ? [...reasons, ...(rssRevisionPending ? [rssRevisionReason] : []), ...(deps.remoteGate ? [remoteCapacityReason] : [])].join('; ') : null,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
|
-
import { existsSync, linkSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { existsSync, linkSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
4
5
|
import { dirname, join } from 'node:path';
|
|
5
6
|
import { debug } from '../debug/log.js';
|
|
6
7
|
import { sendOutbound } from '../domains/outbound-alert.js';
|
|
7
8
|
import { releaseLedgerRoot } from '../instance/resolve.js';
|
|
8
|
-
import {
|
|
9
|
+
import { isValidGateHost } from '../self-implement/gate-remote.js';
|
|
10
|
+
import { LIGHT_RC_UNKNOWN_HOST, runLightRc, type LightRcResult } from './light-rc.js';
|
|
11
|
+
import { planRehearsalShards, type RehearsalShardPlan, type RehearsalShardPlanDeps } from './rehearsal-shard-plan.js';
|
|
9
12
|
import { listSchedules, type ReleaseSchedule } from './release-schedule.js';
|
|
10
13
|
|
|
11
14
|
export type StepId = 'rc-7h' | 'rc-150m';
|
|
@@ -50,6 +53,9 @@ export interface RehearsalStamp {
|
|
|
50
53
|
summary?: string;
|
|
51
54
|
regressionFiles?: string[];
|
|
52
55
|
result?: LightRcResult;
|
|
56
|
+
shardPlan?: RehearsalShardPlan;
|
|
57
|
+
leakCheck?: { outcome: 'ok' | 'fail'; sha: string; exitCode: number | null };
|
|
58
|
+
selection?: { shards?: number; remote?: string };
|
|
53
59
|
notifiedAt?: string;
|
|
54
60
|
ownerPid?: number;
|
|
55
61
|
}
|
|
@@ -58,14 +64,19 @@ export interface RehearsalOptions {
|
|
|
58
64
|
apply?: boolean;
|
|
59
65
|
checkout?: string;
|
|
60
66
|
ledgerRoot?: string;
|
|
67
|
+
shards?: number;
|
|
68
|
+
remote?: string;
|
|
61
69
|
}
|
|
62
70
|
|
|
63
71
|
export interface RehearsalDeps {
|
|
64
72
|
now?: () => Date;
|
|
65
73
|
schedules?: (root: string) => ReleaseSchedule[];
|
|
66
|
-
lightRc?: (version: string, checkout: string) => Promise<LightRcResult>;
|
|
74
|
+
lightRc?: (version: string, checkout: string, selection: { shards?: number; remote?: string }) => Promise<LightRcResult>;
|
|
75
|
+
shardPlan?: typeof planRehearsalShards;
|
|
76
|
+
shardPlanDeps?: RehearsalShardPlanDeps;
|
|
67
77
|
notify?: (text: string) => void | boolean | Promise<void | boolean>;
|
|
68
78
|
git?: (args: string[], cwd: string) => { rc: number | null; stdout: string; stderr?: string };
|
|
79
|
+
leakCheck?: (checkout: string) => { status: number | null };
|
|
69
80
|
}
|
|
70
81
|
|
|
71
82
|
export type RehearsalTickResult = RehearsalPlan & { applied?: boolean; stamps?: RehearsalStamp[]; notificationFailures?: number };
|
|
@@ -86,6 +97,17 @@ function gitResult(git: NonNullable<RehearsalDeps['git']>, args: string[], check
|
|
|
86
97
|
return result.stdout.trim();
|
|
87
98
|
}
|
|
88
99
|
|
|
100
|
+
/** Public export checks the pinned rehearsal checkout before any remote RC work. Its output is private and ephemeral. */
|
|
101
|
+
function runRehearsalLeakCheck(checkout: string): { status: number | null } {
|
|
102
|
+
const out = mkdtempSync(join(tmpdir(), 'elanous-rehearsal-export-'));
|
|
103
|
+
try {
|
|
104
|
+
const result = spawnSync('bun', ['scripts/public-export.ts', '--out', join(out, 'export')], {
|
|
105
|
+
cwd: checkout, encoding: 'utf8', timeout: 1_800_000, maxBuffer: 64 * 1024 * 1024,
|
|
106
|
+
});
|
|
107
|
+
return { status: result.status };
|
|
108
|
+
} finally { rmSync(out, { recursive: true, force: true }); }
|
|
109
|
+
}
|
|
110
|
+
|
|
89
111
|
function oneLine(text: string): string { return text.replace(/\s+/g, ' ').trim(); }
|
|
90
112
|
|
|
91
113
|
function outcomeLine(stamp: RehearsalStamp): string {
|
|
@@ -95,7 +117,11 @@ function outcomeLine(stamp: RehearsalStamp): string {
|
|
|
95
117
|
if (!stamp.result) return `${head}${stamp.summary ? ` · ${stamp.summary}` : ''}`;
|
|
96
118
|
const result = stamp.result;
|
|
97
119
|
const duration = Math.max(0, Math.round((Date.parse(stamp.endedAt!) - Date.parse(stamp.startedAt)) / minute));
|
|
98
|
-
|
|
120
|
+
const planningGap = stamp.shardPlan?.unmeasured
|
|
121
|
+
|| (stamp.selection?.shards !== undefined && result.shards !== stamp.selection.shards)
|
|
122
|
+
|| (stamp.selection?.remote !== undefined && result.remote !== stamp.selection.remote);
|
|
123
|
+
const detail = stamp.summary && (stamp.outcome === 'unmeasured' || stamp.outcome === 'error' && planningGap) ? ` · ${stamp.summary}` : '';
|
|
124
|
+
return `${head} · 새 회귀 ${result.introduced ?? '못 쟀다'} · 기존 ${result.preexisting ?? '못 쟀다'} · 미분류 ${result.unclassified ?? '못 쟀다'} · ${result.remote ?? 'local'} · ${duration}분${stamp.outcome === 'error' ? ` · gate rc ${result.gateExitCode}${!result.ok ? ' · RC 실패' : ''}` : ''}${stamp.regressionFiles?.length ? ` · 파일 ${stamp.regressionFiles.slice(0, 3).join(', ')}` : ''}${detail}`;
|
|
99
125
|
}
|
|
100
126
|
|
|
101
127
|
function persistStamp(path: string, stamp: RehearsalStamp): void {
|
|
@@ -207,6 +233,12 @@ function interruptStamp(path: string, saved: RehearsalStamp, now: Date): Rehears
|
|
|
207
233
|
|
|
208
234
|
/** wx claim is permanent per version/step; a crashed run is reported as interrupted without running RC twice. */
|
|
209
235
|
export async function runRehearsalTick(opts: RehearsalOptions = {}, deps: RehearsalDeps = {}): Promise<RehearsalTickResult> {
|
|
236
|
+
if (opts.shards !== undefined && (!Number.isSafeInteger(opts.shards) || opts.shards < 1)) {
|
|
237
|
+
throw new Error(`release rehearsal tick: invalid --shards count: ${opts.shards}`);
|
|
238
|
+
}
|
|
239
|
+
if (opts.remote !== undefined && !isValidGateHost(opts.remote)) {
|
|
240
|
+
throw new Error(`release rehearsal tick: invalid --remote host: ${opts.remote}`);
|
|
241
|
+
}
|
|
210
242
|
const root = opts.ledgerRoot ?? releaseLedgerRoot();
|
|
211
243
|
const now = (deps.now ?? (() => new Date()))();
|
|
212
244
|
const schedules = (deps.schedules ?? listSchedules)(root);
|
|
@@ -289,26 +321,50 @@ export async function runRehearsalTick(opts: RehearsalOptions = {}, deps: Rehear
|
|
|
289
321
|
gitResult(git, ['checkout', '-q', '--detach', 'origin/main'], checkout);
|
|
290
322
|
stamp.sha = gitResult(git, ['rev-parse', 'HEAD'], checkout);
|
|
291
323
|
if (!stamp.sha) throw new Error('git rev-parse HEAD returned no sha');
|
|
324
|
+
const leak = (deps.leakCheck ?? runRehearsalLeakCheck)(checkout);
|
|
325
|
+
stamp.leakCheck = { outcome: leak.status === 0 ? 'ok' : 'fail', sha: stamp.sha, exitCode: leak.status };
|
|
326
|
+
if (leak.status !== 0) throw new Error(`public export leak-check failed (rc=${leak.status ?? 'spawn'})`);
|
|
292
327
|
const regressionFiles: string[] = [];
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
328
|
+
const shardPlan = opts.shards === undefined ? (deps.shardPlan ?? planRehearsalShards)(plan.version, root, checkout, { ...deps.shardPlanDeps, remoteGate: true }) : undefined;
|
|
329
|
+
if (shardPlan) stamp.shardPlan = shardPlan;
|
|
330
|
+
const selection = { shards: opts.shards ?? shardPlan?.shards, remote: opts.remote };
|
|
331
|
+
stamp.selection = selection;
|
|
332
|
+
const result = await (deps.lightRc ?? ((version, cwd) => runLightRc(version, { ledgerRoot: root, head: stamp.sha, ...selection, rehearsalTui: true, log: (line) => {
|
|
333
|
+
for (const entry of line.split(/\r?\n/)) {
|
|
334
|
+
const file = /^- introduced: (.+?)(?: > |$)/.exec(entry)?.[1];
|
|
335
|
+
if (file && regressionFiles.length < 3) regressionFiles.push(file);
|
|
336
|
+
}
|
|
337
|
+
console.error(line);
|
|
338
|
+
} }, { cwd })))(plan.version, checkout, selection);
|
|
300
339
|
stamp.result = result;
|
|
301
340
|
if (regressionFiles.length) stamp.regressionFiles = regressionFiles;
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
341
|
+
const shardMismatch = selection.shards !== undefined && result.shards !== selection.shards
|
|
342
|
+
? `selected shards ${selection.shards} but RC reported ${result.shards}` : null;
|
|
343
|
+
const remoteMismatch = opts.remote && result.remote !== opts.remote
|
|
344
|
+
? `requested remote ${opts.remote} but RC reported ${result.remote ?? 'local'}` : null;
|
|
345
|
+
if (shardPlan?.remoteCapacityPending && result.remote && result.remote !== LIGHT_RC_UNKNOWN_HOST
|
|
346
|
+
&& !remoteMismatch && result.unmeasured === null
|
|
347
|
+
&& result.introduced !== null && result.unclassified === 0 && result.ok
|
|
348
|
+
&& result.gateExitCode === 0 && !shardMismatch) {
|
|
349
|
+
// Only the completed RC can validate capacity of the actual remote host. Keep independent
|
|
350
|
+
// selection/RSS gaps; clear just the provisional remote-capacity gap.
|
|
351
|
+
stamp.shardPlan = { ...shardPlan, remoteCapacityPending: false, rssRevisionPending: false,
|
|
352
|
+
remoteCapacityVerifiedBy: result.remote,
|
|
353
|
+
unmeasured: shardPlan.planningGaps?.length ? shardPlan.planningGaps.join('; ') : null };
|
|
354
|
+
}
|
|
355
|
+
const planningGap = stamp.shardPlan?.unmeasured || shardMismatch || remoteMismatch;
|
|
356
|
+
const missingEvidence = result.introduced === null || result.unclassified === null
|
|
357
|
+
|| result.unmeasured !== null || result.unclassified > 0 || !!planningGap;
|
|
358
|
+
stamp.outcome = result.introduced !== null && result.introduced > 0 ? missingEvidence ? 'unmeasured' : 'regression'
|
|
359
|
+
: result.introduced === null || result.unclassified === null || result.unmeasured !== null || result.unclassified > 0 ? 'unmeasured'
|
|
360
|
+
: result.unmeasured === null && (!result.ok || result.gateExitCode !== 0) ? 'error'
|
|
361
|
+
: planningGap ? 'unmeasured' : 'ok';
|
|
362
|
+
stamp.summary = oneLine(`introduced ${result.introduced} · preexisting ${result.preexisting ?? 'unmeasured'} · unclassified ${result.unclassified} · ${result.remote ?? 'local'} · gate rc ${result.gateExitCode}${!result.ok ? ' · RC 실패' : ''}${result.unmeasured !== null ? ` · unmeasured: ${result.unmeasured || 'RC reason empty'}` : ''}${stamp.shardPlan?.unmeasured ? ` · unmeasured: ${stamp.shardPlan.unmeasured}` : ''}${shardMismatch ? ` · unmeasured: ${shardMismatch}` : ''}${remoteMismatch ? ` · unmeasured: ${remoteMismatch}` : ''}`);
|
|
307
363
|
}
|
|
308
364
|
}
|
|
309
365
|
} catch (error) {
|
|
310
366
|
stamp.outcome = 'error';
|
|
311
|
-
stamp.summary = oneLine(String(error instanceof Error ? error.message : error).split(/\r?\n/, 1)[0] ?? 'unknown error');
|
|
367
|
+
stamp.summary = oneLine(`${String(error instanceof Error ? error.message : error).split(/\r?\n/, 1)[0] ?? 'unknown error'}${stamp.shardPlan?.unmeasured ? ` · unmeasured: ${stamp.shardPlan.unmeasured}` : ''}`);
|
|
312
368
|
}
|
|
313
369
|
await finish(path, stamp);
|
|
314
370
|
}
|
package/src/render.ts
CHANGED
|
@@ -572,6 +572,10 @@ function parseAndRenderTable(lines: string[]): string {
|
|
|
572
572
|
* Render a tool call header like Claude Code:
|
|
573
573
|
* ⏺ ToolName(description)
|
|
574
574
|
*/
|
|
575
|
+
export function singleLineToolHeaderText(text: string): string {
|
|
576
|
+
return text.replace(/[ \t]*(?:\r\n|\r|\n|\u2028|\u2029)[ \t]*/g, ' ↵ ');
|
|
577
|
+
}
|
|
578
|
+
|
|
575
579
|
export function toolHeader(
|
|
576
580
|
toolName: string,
|
|
577
581
|
description: string,
|
|
@@ -585,7 +589,7 @@ export function toolHeader(
|
|
|
585
589
|
case 'error': icon = applyColor(circle, 'error'); break;
|
|
586
590
|
}
|
|
587
591
|
const name = chalk.bold(toolName);
|
|
588
|
-
const desc = description ? chalk.dim(`(${description})`) : '';
|
|
592
|
+
const desc = description ? chalk.dim(`(${singleLineToolHeaderText(description)})`) : '';
|
|
589
593
|
return `${icon} ${name}${desc}`;
|
|
590
594
|
}
|
|
591
595
|
|
package/src/repl/index.ts
CHANGED
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
import {
|
|
31
31
|
resolveSessionId,
|
|
32
32
|
loadSession,
|
|
33
|
+
listSessions,
|
|
33
34
|
setActiveSessionId,
|
|
34
35
|
getActiveSessionId,
|
|
35
36
|
} from '../session/index.js';
|
|
@@ -41,6 +42,7 @@ import {
|
|
|
41
42
|
} from '../user-config.js';
|
|
42
43
|
import { setAmbientSessionId, debug } from '../debug/log.js';
|
|
43
44
|
import { decideSigintAction } from './sigint.js';
|
|
45
|
+
import { decideSessionStart, observeSessionStart } from '../session/session-start.js';
|
|
44
46
|
import { buildReplayTurnsFromSession } from './replay.js';
|
|
45
47
|
import type { LLMToolSpec, ContentBlock } from '../llm.js';
|
|
46
48
|
import { inspectActiveProvider } from '../provider-summary.js';
|
|
@@ -58,6 +60,8 @@ export interface ReplOpts {
|
|
|
58
60
|
initialSessionId: string | undefined;
|
|
59
61
|
/** Force a fresh session even if active marker exists. */
|
|
60
62
|
forceNew: boolean;
|
|
63
|
+
/** `--continue`/`--resume` — 활성 세션 이어하기(명시). 대표 #73: 기본은 새 세션. */
|
|
64
|
+
continueActive?: boolean;
|
|
61
65
|
/** Enable the tool loop (Read/Grep/Bash/...). Default true — REPL
|
|
62
66
|
* is the agent surface; users opt out with --no-tools. */
|
|
63
67
|
enableTools: boolean;
|
|
@@ -445,11 +449,25 @@ export async function runRepl(opts: ReplOpts): Promise<number> {
|
|
|
445
449
|
return 1;
|
|
446
450
|
}
|
|
447
451
|
initialId = id;
|
|
448
|
-
} else if (!opts.forceNew) {
|
|
449
|
-
initialId = getActiveSessionId() ?? undefined;
|
|
450
452
|
}
|
|
453
|
+
const startDecision = decideSessionStart({
|
|
454
|
+
...(initialId ? { explicitSessionId: initialId } : {}),
|
|
455
|
+
continueActive: opts.continueActive === true,
|
|
456
|
+
forceNew: opts.forceNew,
|
|
457
|
+
activeSessionId: () => getActiveSessionId(),
|
|
458
|
+
// TUI-H8-FOLLOW ① — 활성 표지가 사라진 세션이면 최신 세션으로.
|
|
459
|
+
sessionExists: (id) => loadSession(id) !== null,
|
|
460
|
+
latestSessionId: () => listSessions({ limit: 1 })[0]?.id ?? null,
|
|
461
|
+
});
|
|
462
|
+
initialId = startDecision.sessionIdHint;
|
|
451
463
|
const session = ensureCliSession(cfg, initialId);
|
|
452
464
|
setActiveSessionId(session.id);
|
|
465
|
+
observeSessionStart({
|
|
466
|
+
surface: 'repl',
|
|
467
|
+
origin: initialId && session.id === initialId ? startDecision.origin : 'new',
|
|
468
|
+
reason: initialId && session.id !== initialId ? 'resume-target-missing' : startDecision.reason,
|
|
469
|
+
sessionId: session.id,
|
|
470
|
+
});
|
|
453
471
|
setAmbientSessionId(session.id);
|
|
454
472
|
if (!opts.jsonOutput && (!initialId || session.id !== initialId)) {
|
|
455
473
|
try {
|