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
|
@@ -5,7 +5,7 @@ import { CardStore, taskCardsDir, type TaskCard } from '../../task-cards/card-st
|
|
|
5
5
|
import { Database } from 'bun:sqlite';
|
|
6
6
|
import { type ChecklistItem } from '../../release-loop/checklist.js';
|
|
7
7
|
import { effectiveInstanceRoot } from '../../instance/resolve.js';
|
|
8
|
-
import { getUserConfig, type OrchestratorLoopConfig } from '../../user-config.js';
|
|
8
|
+
import { getUserConfig, ORCHESTRATOR_DEFAULTS, resolveConfiguredAgentRoleLlm, type OrchestratorLoopConfig } from '../../user-config.js';
|
|
9
9
|
import { rubricPriority } from '../../release-loop/rubric.js';
|
|
10
10
|
import { debug } from '../../debug/log.js';
|
|
11
11
|
import { emitLoopHeartbeat } from '../neighbor-runtime.js';
|
|
@@ -15,8 +15,15 @@ import { addHarnessQueue, harnessQueueOutcome, setQueuedPoolHint } from '../../h
|
|
|
15
15
|
import { placeOnGrid, type GridHost } from './grid-place.js';
|
|
16
16
|
import { checkPodPool, parsePodPool, resolvePodPoolSpec } from '../../task-orchestrator/surfaces/pod-pool.js';
|
|
17
17
|
import { leaseKubectl } from '../../task-orchestrator/surfaces/pod-lease.js';
|
|
18
|
+
import { isLaunchEligible, isTrafficLaunch, recordDispatchCycle, seatOfTree, type TrafficProcess } from './traffic.js';
|
|
19
|
+
import { defaultListHarnessProcesses } from '../../harness/harness-cli-command.js';
|
|
20
|
+
import * as testGuard from '../../instance/test-write-guard.js';
|
|
21
|
+
import { seatCapDetails } from '../budget.js';
|
|
22
|
+
export { isLaunchEligible } from './traffic.js';
|
|
18
23
|
import { readTaskAgentState, TASK_SEATS, type HandTaskOptions, type TaskCard as TaskAgentCard, type HandTaskResult, type TaskLauncher, type TaskSeat } from '../../task-agent/task-hand.js';
|
|
19
|
-
import { runCoordinatorInbox } from './inbox.js';
|
|
24
|
+
import { runCoordinatorAgentInbox, runCoordinatorInbox, type CoordinatorInboxResult } from './inbox.js';
|
|
25
|
+
import { loadAgentRolePack, type AgentReplyInput } from '../agent-reply.js';
|
|
26
|
+
import type { LLMProvider } from '../../llm.js';
|
|
20
27
|
|
|
21
28
|
export type Window = '08' | '12' | '18';
|
|
22
29
|
export type Node = 'intake' | 'split' | 'place' | 'delegate' | 'launch' | 'reconcile' | 'report';
|
|
@@ -61,6 +68,8 @@ export interface TickDeps {
|
|
|
61
68
|
gridHosts?: readonly GridHost[];
|
|
62
69
|
seatTurn?: (seat: string, root: string, host?: string, options?: Pick<SeatDeps, 'enqueue'>) => Promise<{ status: string; queueId?: string; runId?: string; item?: { source: string; id: string } }>;
|
|
63
70
|
queueOutcome?: (queueId: string, root: string) => 'pending' | 'unknown' | 'retryable' | 'succeeded';
|
|
71
|
+
/** Snapshot of running harness processes for launch-cap decisions; an unreadable snapshot blocks launches. */
|
|
72
|
+
launchProcesses?: () => { status: 'ok'; records: readonly TrafficProcess[] } | { status: 'incomplete' };
|
|
64
73
|
/** 발사 전 대기열 항목의 풀 힌트 갱신(주입 안 하면 harness-queue `setQueuedPoolHint`). */
|
|
65
74
|
setPoolHint?: (queueId: string, poolHint: string | undefined, root: string) => Promise<boolean>;
|
|
66
75
|
loadAdapter?: (path: string, name: string) => Promise<unknown>;
|
|
@@ -73,7 +82,10 @@ export interface TickDeps {
|
|
|
73
82
|
handTask?: (opts: HandTaskOptions) => Promise<HandTaskResult>;
|
|
74
83
|
taskLauncher?: TaskLauncher;
|
|
75
84
|
/** Coordinator inbox seam; the real intake reads and replies on the durable message bus. */
|
|
76
|
-
coordinatorInbox?: () =>
|
|
85
|
+
coordinatorInbox?: () => CoordinatorInboxResult | Promise<CoordinatorInboxResult>;
|
|
86
|
+
/** Production still uses the restricted turn; tests can supply a deterministic turn. */
|
|
87
|
+
coordinatorAgentRun?: AgentReplyInput['runAgent'];
|
|
88
|
+
coordinatorAgentProvider?: LLMProvider;
|
|
77
89
|
}
|
|
78
90
|
|
|
79
91
|
/** ORCH-TA-HAND ledger — one row per handed `orch:<card>:<cell>` key so a cell is handed once across ticks and processes. */
|
|
@@ -475,7 +487,15 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
|
|
|
475
487
|
// A graph node may be replayed with the same runId, and 12/18 skip intake.
|
|
476
488
|
// Drain the bus on every tick command; the message transaction prevents duplicate answers.
|
|
477
489
|
if (mode !== 'off') {
|
|
478
|
-
const
|
|
490
|
+
const inboxPath = join(root, 'msg', 'messages.db');
|
|
491
|
+
const inbox = await (deps.coordinatorInbox ?? (() => {
|
|
492
|
+
const role = resolveConfiguredAgentRoleLlm('coordinator');
|
|
493
|
+
return role
|
|
494
|
+
? runCoordinatorAgentInbox({ role, pack: loadAgentRolePack('coordinator'), path: inboxPath, root,
|
|
495
|
+
...(deps.coordinatorAgentRun ? { runAgent: deps.coordinatorAgentRun } : {}),
|
|
496
|
+
...(deps.coordinatorAgentProvider ? { provider: deps.coordinatorAgentProvider } : {}) })
|
|
497
|
+
: runCoordinatorInbox(undefined, 100, inboxPath);
|
|
498
|
+
}))();
|
|
479
499
|
if (inbox.replied || inbox.acknowledged) {
|
|
480
500
|
observe('exchange', 'coordinator-inbox-replied', inbox.replied);
|
|
481
501
|
observe('exchange', 'coordinator-inbox-acknowledged', inbox.acknowledged);
|
|
@@ -730,8 +750,55 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
|
|
|
730
750
|
&& (orchestratorConfig?.maxDelegatePerTick === undefined || state.delegatedKeys?.includes(`orch:${cell.cardId}:${cell.id}`)
|
|
731
751
|
|| (mode === 'live' && latestRequests.has(`orch:${cell.cardId}:${cell.id}`))));
|
|
732
752
|
const seats = [...new Set(eligible.map(cell => cell.seat!))];
|
|
753
|
+
const supplied = state.cells.filter(cell => cell.origin === 'flow1a' && cell.seat && SEAT_LOOP_IDS[cell.seat]);
|
|
754
|
+
const eligibleKeys = new Set(eligible.map(cell => `orch:${cell.cardId}:${cell.id}`));
|
|
755
|
+
const deferredKeys = new Set((state.deferredCells ?? []).map(cell => `orch:${cell.cardId}:${cell.id}`));
|
|
756
|
+
const skipped: Record<string, number> = {};
|
|
757
|
+
for (const cell of supplied) {
|
|
758
|
+
const key = `orch:${cell.cardId}:${cell.id}`;
|
|
759
|
+
if (eligibleKeys.has(key)) continue;
|
|
760
|
+
const reason = state.degradation?.level === 2 ? 'degraded-skip'
|
|
761
|
+
: deferredKeys.has(key) ? 'cap-deferred' : 'not-queued';
|
|
762
|
+
skipped[reason] = (skipped[reason] ?? 0) + 1;
|
|
763
|
+
}
|
|
764
|
+
if (!supplied.length) skipped['no-supply'] = 1;
|
|
765
|
+
// Use the same process inventory and seat mapping as traffic for production live launches.
|
|
766
|
+
// A shadow/test tick must not synchronously scan host processes (up to 2.5s per tick).
|
|
767
|
+
const observed = seats.length ? deps.launchProcesses?.() ?? (() => {
|
|
768
|
+
if (mode === 'shadow' || testGuard.testProcessSignal()) {
|
|
769
|
+
observe('launch-inventory-skipped', mode === 'shadow' ? 'shadow' : 'test', 1);
|
|
770
|
+
return { status: 'ok' as const, records: [] };
|
|
771
|
+
}
|
|
772
|
+
const snapshot = defaultListHarnessProcesses({ include: record => isTrafficLaunch(record.command), cwdOnly: true, deadlineMs: 2_500 });
|
|
773
|
+
// The inventory itself must be complete; an unreadable cwd is handled as one reserved slot below.
|
|
774
|
+
return snapshot.status === 'ok' ? snapshot : { status: 'incomplete' as const };
|
|
775
|
+
})() : { status: 'ok' as const, records: [] };
|
|
776
|
+
const processes = observed.status === 'ok' ? observed.records : null;
|
|
777
|
+
const identified = (processes ?? []).filter(process => isTrafficLaunch(process.command)).map(process =>
|
|
778
|
+
'seat' in process ? process.seat : seatOfTree(process.cwd, orchestratorConfig ?? ORCHESTRATOR_DEFAULTS));
|
|
779
|
+
const unknown = identified.filter(seat => !seat).length;
|
|
780
|
+
// OP policy: unknown launches together reserve one conservative slot per seat, rather than
|
|
781
|
+
// closing every seat. An incomplete process inventory still fails closed.
|
|
782
|
+
identified.forEach((seat, index) => { if (!seat) observe('launch-unknown-seat', `cwd-unknown:${index}`, 1); });
|
|
783
|
+
const reserve = unknown ? 1 : 0;
|
|
784
|
+
const running = (seat: string): number => identified.filter(value => value === seat).length;
|
|
785
|
+
const free = (seat: string): number => Math.max(0, seatCapDetails({ seat: seat as keyof typeof ORCHESTRATOR_DEFAULTS.seatCaps,
|
|
786
|
+
caps: orchestratorConfig?.seatCaps, gate: orchestratorConfig?.releaseGate }).cap - running(seat) - reserve);
|
|
787
|
+
const launchSeats = seats.filter(seat => {
|
|
788
|
+
const cell = eligible.find(row => row.seat === seat)!;
|
|
789
|
+
const cap = free(seat);
|
|
790
|
+
if (processes === null || !isLaunchEligible({ nextCell: { id: cell.id, title: cell.title, owner: seat, status: 'yellow' },
|
|
791
|
+
running: 0, launchCap: cap })) {
|
|
792
|
+
// Every eligible cell of this seat stays unlaunched, not just one — count them all per reason.
|
|
793
|
+
skipped['capacity'] = (skipped['capacity'] ?? 0) + eligible.filter(row => row.seat === seat).length;
|
|
794
|
+
return false;
|
|
795
|
+
}
|
|
796
|
+
const leftovers = eligible.filter(row => row.seat === seat).length - 1;
|
|
797
|
+
if (leftovers > 0) skipped['seat-occupied'] = (skipped['seat-occupied'] ?? 0) + leftovers;
|
|
798
|
+
return true;
|
|
799
|
+
});
|
|
733
800
|
state.launched = [];
|
|
734
|
-
for (const seat of
|
|
801
|
+
for (const seat of launchSeats) {
|
|
735
802
|
if (mode === 'shadow') {
|
|
736
803
|
const cell = eligible.find(row => row.seat === seat)!;
|
|
737
804
|
const item: SeatItem = { source: 'request', id: `orch:${cell.cardId}:${cell.id}`, title: cell.title, text: cell.title };
|
|
@@ -754,7 +821,7 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
|
|
|
754
821
|
: undefined;
|
|
755
822
|
const options = enqueue ? { enqueue } : undefined;
|
|
756
823
|
const turn = await (deps.seatTurn ?? ((assigned: string, stateRoot: string, _preferred?: string, overrides?: Pick<SeatDeps, 'enqueue'>) =>
|
|
757
|
-
runSeatLoopOnce(assigned, { root: stateRoot,
|
|
824
|
+
runSeatLoopOnce(assigned, { root: stateRoot, needsOwnerGate: true, // autonomous launch: needs-owner hold on
|
|
758
825
|
config: { ...getUserConfig().loops?.seat, mode: 'live-safe', seats: [assigned] }, ...overrides })))(seat, root, host, options);
|
|
759
826
|
// 자리 턴이 «이 틱이 넣은 의뢰»를 처리했을 때만 칸에 잇는다 — 대기열의 다른 의뢰는 이 카드의 발사가 아니다.
|
|
760
827
|
const targets = new Set(eligible.filter(row => row.seat === seat).map(row => `orch:${row.cardId}:${row.id}`));
|
|
@@ -767,6 +834,13 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
|
|
|
767
834
|
observe('exchange', `seat-turn:${seat}:${turn.status}`, 1, SEAT_LOOP_IDS[seat]);
|
|
768
835
|
}
|
|
769
836
|
}
|
|
837
|
+
// `dispatch` (podTarget · localLane, RFC A3) is record-only at this stage: it is copied from config into the
|
|
838
|
+
// dispatch ledger and does not change launch or capacity decisions — seatCaps · running · isLaunchEligible decide those.
|
|
839
|
+
recordDispatchCycle(root, { at: now.toISOString(), source: 'tick', mode, runId,
|
|
840
|
+
supply: supplied.length, capacity: processes === null ? 0 : seats.reduce((total, seat) => total + free(seat), 0),
|
|
841
|
+
eligible: launchSeats.length, skipped,
|
|
842
|
+
dispatch: orchestratorConfig?.dispatch ?? ORCHESTRATOR_DEFAULTS.dispatch,
|
|
843
|
+
});
|
|
770
844
|
} else if (node === 'reconcile') {
|
|
771
845
|
if (window !== '08') {
|
|
772
846
|
// 새 카드가 있어도 앞 틱의 의뢰·발사를 같이 대조한다 — 지금 틱 것이 같은 키를 이긴다.
|
|
@@ -17,6 +17,51 @@ export type TrafficProcess = Pick<HarnessProcessRecord, 'command' | 'elapsedSeco
|
|
|
17
17
|
export type TrafficSeatRow = { seat: OrchestratorSeat; running: number; cap: number; baseShare: number | null; borrowed: number; lent: number; launchCap: number; idleFor: number | null; idle: boolean; nextCell: TrafficCell | null };
|
|
18
18
|
export type TrafficResult = { seats: TrafficSeatRow[]; unassigned: number; now: Date; idleMinutes: number; finish?: { metrics: FinishMetrics; advice: FinishAdvice } };
|
|
19
19
|
|
|
20
|
+
/** A reason from a previous turn never blocks recovered supply; only active holds do. */
|
|
21
|
+
export function isLaunchEligible(row: Pick<TrafficSeatRow, 'nextCell' | 'running' | 'launchCap'>,
|
|
22
|
+
skipReason?: string): boolean {
|
|
23
|
+
return row.nextCell !== null && row.running < row.launchCap &&
|
|
24
|
+
skipReason !== 'degraded-skip' && skipReason !== 'cap-deferred';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type DispatchCycle = {
|
|
28
|
+
at: string; source: 'traffic' | 'tick'; mode: 'shadow' | 'live'; runId: string;
|
|
29
|
+
supply: number; capacity: number; eligible: number; skipped: Record<string, number>;
|
|
30
|
+
dispatch: OrchestratorLoopConfig['dispatch'];
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/** Separate journal: never extend or reinterpret seat-requests or per-run state rows. */
|
|
34
|
+
export function recordDispatchCycle(root: string, cycle: DispatchCycle,
|
|
35
|
+
log: (category: string, event: string, data: Record<string, unknown>) => void = debug.log.bind(debug)): void {
|
|
36
|
+
const path = join(root, 'orchestrator', 'dispatch-ledger.jsonl');
|
|
37
|
+
try {
|
|
38
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
39
|
+
const appended = withFileLockSync(`${path}.lock`, () => {
|
|
40
|
+
const previous = existsSync(path) ? readFileSync(path, 'utf8') : '';
|
|
41
|
+
if (previous.split('\n').some(line => {
|
|
42
|
+
if (!line) return false;
|
|
43
|
+
let row: Partial<DispatchCycle>;
|
|
44
|
+
try { row = JSON.parse(line) as Partial<DispatchCycle>; }
|
|
45
|
+
catch {
|
|
46
|
+
// A torn append must not permanently stop later cycles. Keep the line for forensic inspection.
|
|
47
|
+
try { log('loop.orchestrator', 'dispatch-cycle-malformed', { path }); }
|
|
48
|
+
catch { /* Observation must not stop a valid append. */ }
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
return row && row.source === cycle.source && row.runId === cycle.runId && row.mode === cycle.mode;
|
|
52
|
+
})) return false;
|
|
53
|
+
// A torn final line has no newline; separate it from the next valid JSONL row.
|
|
54
|
+
appendFileSync(path, `${previous && !previous.endsWith('\n') ? '\n' : ''}${JSON.stringify(cycle)}\n`);
|
|
55
|
+
return true;
|
|
56
|
+
});
|
|
57
|
+
if (appended) try { log('loop.orchestrator', 'dispatch-cycle', cycle); }
|
|
58
|
+
catch { /* Observation cannot change a recorded decision. */ }
|
|
59
|
+
} catch (error) {
|
|
60
|
+
try { debug.log('loop.orchestrator', 'dispatch-cycle-failed', { error: String(error).slice(0, 200) }, { level: 'warn' }); }
|
|
61
|
+
catch { /* Observation cannot change a recorded decision. */ }
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
20
65
|
/** Same bounded walk as the CTX1 hook: a marker at the git root is checked before stopping. */
|
|
21
66
|
export function seatOfTree(cwd: string | undefined, cfg: Pick<OrchestratorLoopConfig, 'seatTrees'>): OrchestratorSeat | null {
|
|
22
67
|
if (!cwd || !isAbsolute(cwd)) return null;
|
|
@@ -144,7 +189,24 @@ export function runTrafficTick({ processes, now, caps, openCells, nextRound, tot
|
|
|
144
189
|
const advice = finishAdvice(metrics, TRAFFIC_SEATS.reduce((sum, seat) => sum + caps[seat], 0));
|
|
145
190
|
const result = { ...trafficTick({ processes, now, caps, openCells, nextRound, totalSlots: totalSlots ?? advice.launchSlots }),
|
|
146
191
|
finish: { metrics, advice } };
|
|
147
|
-
const
|
|
192
|
+
const root = applyDeps?.root ?? effectiveInstanceRoot();
|
|
193
|
+
const queued = applyTraffic(result, { ...applyDeps, root, mode });
|
|
194
|
+
{
|
|
195
|
+
const skipped: Record<string, number> = {};
|
|
196
|
+
const suppliedSeats = new Set(openCells.filter(cell => cell.status !== 'done').map(cell => cell.owner?.split('/')[0]));
|
|
197
|
+
for (const row of result.seats) {
|
|
198
|
+
const reason = !suppliedSeats.has(row.seat) ? 'no-supply' : row.running >= row.launchCap ? 'capacity'
|
|
199
|
+
: !row.idle ? 'not-idle' : undefined;
|
|
200
|
+
if (reason) skipped[reason] = (skipped[reason] ?? 0) + 1;
|
|
201
|
+
}
|
|
202
|
+
recordDispatchCycle(root, {
|
|
203
|
+
at: now.toISOString(), source: 'traffic', mode, runId: now.toISOString(),
|
|
204
|
+
supply: result.seats.filter(row => suppliedSeats.has(row.seat)).length,
|
|
205
|
+
capacity: result.seats.reduce((sum, row) => sum + Math.max(0, row.launchCap - row.running), 0),
|
|
206
|
+
eligible: result.seats.filter(row => row.idle && isLaunchEligible(row)).length,
|
|
207
|
+
skipped, dispatch: getUserConfig().loops?.orchestrator?.dispatch ?? ORCHESTRATOR_DEFAULTS.dispatch,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
148
210
|
let authorShadow: AuthorShadow | null = null;
|
|
149
211
|
let shadowFailure: Record<string, unknown> | null = null;
|
|
150
212
|
try {
|
|
@@ -187,6 +249,7 @@ if (import.meta.main) {
|
|
|
187
249
|
const { result, queued, authorShadow } = runTrafficTick({
|
|
188
250
|
processes, now, caps: cfg.seatCaps, openCells: listChecklist(version).items,
|
|
189
251
|
...(nextVersion ? { nextRound: listChecklist(nextVersion).items } : {}), mode: cfg.trafficMode,
|
|
252
|
+
applyDeps: { root: effectiveInstanceRoot() },
|
|
190
253
|
});
|
|
191
254
|
if (args.includes('--json')) console.log(JSON.stringify({ ...result, mode: cfg.trafficMode, queued, version, authorShadow }));
|
|
192
255
|
else console.log(trafficLine(result, cfg.trafficMode));
|
package/src/loops/registry.ts
CHANGED
|
@@ -14,6 +14,9 @@ import { getUserConfig, type UserConfig } from '../user-config.js';
|
|
|
14
14
|
import { runGraph, type GraphRunState } from '../graph-runner/runner.js';
|
|
15
15
|
import { FENCE_ROLES } from '../hq/hq.js';
|
|
16
16
|
import { dueBefore, type CheckEntry } from './checker.js';
|
|
17
|
+
import { readUnreadCount } from '../msg/msg-store.js';
|
|
18
|
+
import { loopMessageRoute, SEAT_MESSAGE_ROUTES, type LoopReplyBody, type MessageWake } from './msg-address.js';
|
|
19
|
+
import { resolveWake, type WakeDeps, type WakeResolution } from './msg-wake.js';
|
|
17
20
|
|
|
18
21
|
export interface LoopRun {
|
|
19
22
|
at: string;
|
|
@@ -23,8 +26,22 @@ export interface LoopRun {
|
|
|
23
26
|
failedNodes: string[];
|
|
24
27
|
durationMs: number | null;
|
|
25
28
|
}
|
|
29
|
+
export type LoopRoot = '조율자' | '수호자';
|
|
30
|
+
export type LoopStage = 'proposed' | 'shadow' | 'live' | 'retiring' | 'retired';
|
|
31
|
+
const LOOP_STAGES: readonly LoopStage[] = ['proposed', 'shadow', 'live', 'retiring', 'retired'];
|
|
32
|
+
|
|
26
33
|
export interface LoopEntry {
|
|
27
34
|
id: string;
|
|
35
|
+
parent?: string | null;
|
|
36
|
+
root?: LoopRoot | null;
|
|
37
|
+
purpose?: string | null;
|
|
38
|
+
stage?: LoopStage | null;
|
|
39
|
+
msgAddress?: string | null;
|
|
40
|
+
replyBody?: LoopReplyBody;
|
|
41
|
+
wake?: MessageWake;
|
|
42
|
+
/** Where `wake` came from — `unresolved` is «모름», not a measured absence. */
|
|
43
|
+
wakeSource?: WakeResolution['source'];
|
|
44
|
+
unreadCount?: number | null;
|
|
28
45
|
title: string;
|
|
29
46
|
description: string | null;
|
|
30
47
|
owner?: string | null;
|
|
@@ -48,6 +65,20 @@ export interface LoopRegistryOptions {
|
|
|
48
65
|
scheduleAction?: (action: 'create' | 'enable' | 'disable', args: Record<string, unknown>) => Promise<unknown>;
|
|
49
66
|
/** Home used to expand `~`/`$HOME` in cron redirects; tests inject a temp dir instead of writing the real HOME. */
|
|
50
67
|
home?: string;
|
|
68
|
+
/** Seat wake resolution (pty manifest ⊕ seat folders); tests inject fixed rows. */
|
|
69
|
+
wakeDeps?: WakeDeps;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function messageFields(id: string, stateRoot: string): { msgAddress: string | null; replyBody: LoopReplyBody; wake: MessageWake; wakeSource?: WakeResolution['source']; unreadCount: number | null } {
|
|
73
|
+
const route = loopMessageRoute(id);
|
|
74
|
+
return { ...route, ...(route.msgAddress ? { wakeSource: 'loop-table' as const } : {}), unreadCount: route.msgAddress ? readUnreadCount(route.msgAddress, join(stateRoot, 'msg', 'messages.db')) : null };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** A seat row is addressed by its seat; its wake path is resolved on this host (pty name → herdr pane → 모름). */
|
|
78
|
+
function seatMessageFields(seat: string, stateRoot: string, wakeDeps?: WakeDeps): { msgAddress: string; replyBody: LoopReplyBody; wake: MessageWake; wakeSource: WakeResolution['source']; unreadCount: number | null } {
|
|
79
|
+
const wake = resolveWake(seat, wakeDeps);
|
|
80
|
+
return { msgAddress: seat, replyBody: 'agent', wake: wake.wake, wakeSource: wake.source,
|
|
81
|
+
unreadCount: readUnreadCount(seat, join(stateRoot, 'msg', 'messages.db')) };
|
|
51
82
|
}
|
|
52
83
|
|
|
53
84
|
function graphFiles(dir: string): string[] {
|
|
@@ -186,6 +217,8 @@ export function defaultLoopRoot(): string {
|
|
|
186
217
|
return installedCronRoot() ?? repoRoot();
|
|
187
218
|
}
|
|
188
219
|
|
|
220
|
+
const warnedLegacyRoots = new Set<string>();
|
|
221
|
+
|
|
189
222
|
export function listLoops(opts: LoopRegistryOptions = {}): LoopEntry[] {
|
|
190
223
|
const root = resolve(opts.root ?? defaultLoopRoot());
|
|
191
224
|
const stateRoot = opts.stateRoot ?? effectiveInstanceRoot();
|
|
@@ -211,13 +244,25 @@ export function listLoops(opts: LoopRegistryOptions = {}): LoopEntry[] {
|
|
|
211
244
|
if (!declaredCron && !events.length && !matched.length) continue;
|
|
212
245
|
if (!/^[a-zA-Z0-9][\w.-]*$/.test(doc.graph_id)) throw new Error(`unsafe loop graph_id: ${doc.graph_id}`);
|
|
213
246
|
if (loops.some(loop => loop.id === doc.graph_id)) throw new Error(`duplicate loop graph_id: ${doc.graph_id}`);
|
|
247
|
+
if (header?.root != null && header.root !== '조율자' && header.root !== '수호자')
|
|
248
|
+
throw new Error(`invalid loop root for ${doc.graph_id}: ${String(header.root)}`);
|
|
249
|
+
if (header?.stage !== undefined && (typeof header.stage !== 'string' || !LOOP_STAGES.includes(header.stage as LoopStage)))
|
|
250
|
+
throw new Error(`invalid loop stage for ${doc.graph_id}: ${String(header.stage)}`);
|
|
251
|
+
if (header?.root == null && !warnedLegacyRoots.has(file)) {
|
|
252
|
+
warnedLegacyRoots.add(file);
|
|
253
|
+
debug.log('loops.registry', 'legacy-root-missing', { id: doc.graph_id, file });
|
|
254
|
+
}
|
|
214
255
|
const jobs = matched.map(row => ({ id: row.id, cron: row.cron, enabled: !!row.enabled,
|
|
215
256
|
...(entryRows.includes(row) ? { entryScript: true } : {}) }));
|
|
216
257
|
const active = matched.filter(row => !!row.enabled && !!row.cron);
|
|
217
258
|
const next = active.map(row => nextLoopFire(row.cron!, opts.now ?? new Date())).filter((v): v is string => v !== null).sort()[0] ?? null;
|
|
218
259
|
const title = typeof header?.title === 'string' ? header.title : doc.graph_id;
|
|
219
|
-
const entry: LoopEntry = { id: doc.graph_id, title,
|
|
260
|
+
const entry: LoopEntry = { id: doc.graph_id, title, ...messageFields(doc.graph_id, stateRoot),
|
|
220
261
|
description: typeof header?.description === 'string' ? header.description : null,
|
|
262
|
+
...(typeof header?.parent === 'string' ? { parent: header.parent } : {}),
|
|
263
|
+
...(header?.root === '조율자' || header?.root === '수호자' ? { root: header.root } : {}),
|
|
264
|
+
...(typeof header?.purpose === 'string' ? { purpose: header.purpose } : {}),
|
|
265
|
+
...(typeof header?.stage === 'string' ? { stage: header.stage as LoopStage } : {}),
|
|
221
266
|
...resolveOwner(doc.graph_id, title, config, header?.owner),
|
|
222
267
|
mode: typeof header?.mode === 'string' ? header.mode : null, file: relative(root, file),
|
|
223
268
|
trigger: { cron: declaredCron, events }, jobs, enabled: matched.some(row => !!row.enabled),
|
|
@@ -229,6 +274,16 @@ export function listLoops(opts: LoopRegistryOptions = {}): LoopEntry[] {
|
|
|
229
274
|
}
|
|
230
275
|
|
|
231
276
|
export interface AllLoopEntry extends CheckEntry {
|
|
277
|
+
parent?: LoopEntry['parent'];
|
|
278
|
+
root?: LoopEntry['root'];
|
|
279
|
+
purpose?: LoopEntry['purpose'];
|
|
280
|
+
stage?: LoopEntry['stage'];
|
|
281
|
+
msgAddress?: string | null;
|
|
282
|
+
replyBody?: LoopReplyBody;
|
|
283
|
+
wake?: MessageWake;
|
|
284
|
+
/** Where `wake` came from — `unresolved` is «모름», not a measured absence. */
|
|
285
|
+
wakeSource?: WakeResolution['source'];
|
|
286
|
+
unreadCount?: number | null;
|
|
232
287
|
kind: 'graph' | 'seat' | 'cron-shell' | 'orchestrator' | 'unregistered';
|
|
233
288
|
title: string;
|
|
234
289
|
cron?: string;
|
|
@@ -589,6 +644,9 @@ export function listAllLoops(opts: LoopRegistryOptions = {}): AllLoopEntry[] {
|
|
|
589
644
|
const declaredHost = typeof header.host === 'string' && header.host ? header.host : undefined;
|
|
590
645
|
const declaredCategory = typeof header.observationCategory === 'string' && header.observationCategory ? header.observationCategory : undefined;
|
|
591
646
|
return { kind: 'graph', id: loop.id, title: loop.title, owner: loop.owner ?? undefined, ownerSource: loop.ownerSource,
|
|
647
|
+
...(loop.parent ? { parent: loop.parent } : {}), ...(loop.root ? { root: loop.root } : {}),
|
|
648
|
+
...(loop.purpose ? { purpose: loop.purpose } : {}), ...(loop.stage ? { stage: loop.stage } : {}),
|
|
649
|
+
msgAddress: loop.msgAddress, replyBody: loop.replyBody, wake: loop.wake, ...(loop.wakeSource ? { wakeSource: loop.wakeSource } : {}), unreadCount: loop.unreadCount,
|
|
592
650
|
...(declaredHost || installed.length ? { host: declaredHost ?? hostname() } : {}),
|
|
593
651
|
observationCategory: declaredCategory ?? 'graph.runner',
|
|
594
652
|
...(fenceRole ? { fenceRole } : {}),
|
|
@@ -599,6 +657,7 @@ export function listAllLoops(opts: LoopRegistryOptions = {}): AllLoopEntry[] {
|
|
|
599
657
|
recentStatuses: runs.map(run => run.status) };
|
|
600
658
|
});
|
|
601
659
|
const namedIds = namedCronIds(rows, claimed);
|
|
660
|
+
const seatOf = new Map<AllLoopEntry, string>();
|
|
602
661
|
for (const row of rows) {
|
|
603
662
|
if (claimed.has(row.id)) continue;
|
|
604
663
|
const command = row.command ?? '';
|
|
@@ -622,7 +681,7 @@ export function listAllLoops(opts: LoopRegistryOptions = {}): AllLoopEntry[] {
|
|
|
622
681
|
const picked = logMtime && (!recorded || Date.parse(logMtime) >= Date.parse(recorded)) ? 'log-mtime'
|
|
623
682
|
: recorded ? 'registry' : 'none';
|
|
624
683
|
debug.log('loops.registry', 'cron-last-run', { id, targets, picked });
|
|
625
|
-
|
|
684
|
+
const pushed: AllLoopEntry = { kind, id, title,
|
|
626
685
|
...resolveOwner(id, title, config, undefined, seatArg ?? seat, seatArg ? 'seat-arg' : 'seat'), ...(fenceRole ? { fenceRole } : {}),
|
|
627
686
|
host: hostname(), observationCategory: row.category,
|
|
628
687
|
enabled: !!row.enabled, registered: true,
|
|
@@ -632,7 +691,11 @@ export function listAllLoops(opts: LoopRegistryOptions = {}): AllLoopEntry[] {
|
|
|
632
691
|
...(picked === 'log-mtime' ? { lastRunAt: logMtime, evidence: picked }
|
|
633
692
|
: picked === 'registry' ? { lastRunAt: recorded, evidence: picked } : {}),
|
|
634
693
|
...(row.last_status ? { lastStatus: row.last_status } : {}),
|
|
635
|
-
recentStatuses: row.last_status ? [row.last_status] : [] }
|
|
694
|
+
recentStatuses: row.last_status ? [row.last_status] : [] };
|
|
695
|
+
all.push(pushed);
|
|
696
|
+
const seatName = (seatArg ?? seat)?.toUpperCase();
|
|
697
|
+
// 선언된 자리 줄만 자리 주소로 공개한다 — 모르는 `--seat FOO` 는 종전처럼 주소 없음.
|
|
698
|
+
if (kind === 'seat' && seatName && Object.hasOwn(SEAT_MESSAGE_ROUTES, seatName)) seatOf.set(pushed, seatName);
|
|
636
699
|
}
|
|
637
700
|
const warnings = unregisteredCronLoops(all, graphOpts);
|
|
638
701
|
for (const row of warnings) {
|
|
@@ -647,7 +710,10 @@ export function listAllLoops(opts: LoopRegistryOptions = {}): AllLoopEntry[] {
|
|
|
647
710
|
for (const loop of all) bySource[loop.ownerSource!]++;
|
|
648
711
|
debug.log('loop.check', 'ownership', { total: all.length, bySource });
|
|
649
712
|
debug.log('loops.registry', 'list-all', { count: all.length });
|
|
650
|
-
|
|
713
|
+
const stateRoot = opts.stateRoot ?? effectiveInstanceRoot();
|
|
714
|
+
return all.map(entry => entry.kind === 'graph' ? entry
|
|
715
|
+
: seatOf.has(entry) ? { ...entry, ...seatMessageFields(seatOf.get(entry)!, stateRoot, opts.wakeDeps) }
|
|
716
|
+
: { ...entry, ...messageFields(entry.id, stateRoot) });
|
|
651
717
|
}
|
|
652
718
|
|
|
653
719
|
/** An unclaimed cron line with any elanous marker must surface as an unregistered warning. */
|
|
@@ -711,6 +777,8 @@ export async function setLoopEnabled(id: string, enabled: boolean, yes = false,
|
|
|
711
777
|
const loop = loopStatus(id, opts);
|
|
712
778
|
const action = enabled ? 'start' : 'stop';
|
|
713
779
|
if (!loop.jobs.length && (!enabled || !loop.trigger.cron)) throw new Error(`loop ${id} has no cron job to ${action}`);
|
|
780
|
+
// Registration creates a new cron; toggling an already installed legacy cron remains supported.
|
|
781
|
+
if (enabled && !loop.jobs.length && !loop.root) throw new Error(`loop ${id} requires root (조율자|수호자) for new registration`);
|
|
714
782
|
const pending = loop.jobs.filter(job => job.enabled !== enabled);
|
|
715
783
|
const entryScript = loop.jobs.some(job => job.entryScript);
|
|
716
784
|
const entryLabel = entryScript ? { entryScript: true } : {};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createHash, createPublicKey, generateKeyPairSync, sign, verify } from 'node:crypto';
|
|
2
2
|
|
|
3
|
+
import { scanPackInternalRefs } from './pack-internal-refs';
|
|
4
|
+
|
|
3
5
|
export interface MarketplaceArtifact {
|
|
4
6
|
sha256: string;
|
|
5
7
|
bytes: number;
|
|
@@ -96,6 +98,18 @@ function invalidIndex(value: unknown): string | null {
|
|
|
96
98
|
if (!Number.isSafeInteger(entry.artifact.bytes) || (entry.artifact.bytes as number) < 0) return field('artifact.bytes: expected non-negative integer');
|
|
97
99
|
if (!string(entry.artifact.key) || !entry.artifact.key.trim()) return field('artifact.key: expected non-empty string');
|
|
98
100
|
if (collection === 'loopBundles' && entry.graphs !== undefined && !stringArray(entry.graphs)) return field('graphs: expected string array');
|
|
101
|
+
if (entry.visibility === 'public') {
|
|
102
|
+
const texts: Array<[string, string | undefined]> = [
|
|
103
|
+
['name', string(entry.name) ? entry.name : undefined],
|
|
104
|
+
['version', string(entry.version) ? entry.version : undefined],
|
|
105
|
+
['description', string(entry.description) ? entry.description : undefined],
|
|
106
|
+
['artifact.key', string(entry.artifact.key) ? entry.artifact.key : undefined],
|
|
107
|
+
];
|
|
108
|
+
const graphs = collection === 'loopBundles' && stringArray(entry.graphs) ? entry.graphs : undefined;
|
|
109
|
+
if (graphs !== undefined) texts.push(['graphs', graphs.join('\n')]);
|
|
110
|
+
const hit = scanPackInternalRefs(texts.filter((pair): pair is [string, string] => pair[1] !== undefined).map(([path, text]) => ({ path, text })))[0];
|
|
111
|
+
if (hit) return field(`${hit.file}: expected no internal reference (${hit.marker})`);
|
|
112
|
+
}
|
|
99
113
|
}
|
|
100
114
|
}
|
|
101
115
|
|
package/src/mcp/mcp-oauth.ts
CHANGED
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
// 인가 서버가 RFC 8628 을 광고할 때는 장치 코드로 자격을 얻는다.
|
|
10
10
|
// 경계: 새 CLI 하위 명령은 더하지 않는다.
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import { chmodSync, closeSync, fchmodSync, mkdirSync, openSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
13
|
+
import { randomUUID } from 'node:crypto';
|
|
14
|
+
import { dirname, join } from 'node:path';
|
|
13
15
|
import { generatePkcePair } from '../oauth/pkce.js';
|
|
14
16
|
import {
|
|
15
17
|
authStorePath,
|
|
@@ -19,6 +21,7 @@ import {
|
|
|
19
21
|
saveTokens,
|
|
20
22
|
type OAuthTokens,
|
|
21
23
|
type ProviderAuthState,
|
|
24
|
+
type WriteTokensOpts,
|
|
22
25
|
} from '../oauth/store.js';
|
|
23
26
|
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
24
27
|
import { debug } from '../debug/log.js';
|
|
@@ -175,7 +178,7 @@ function loadIssuerState(
|
|
|
175
178
|
if (legacy === path) return null;
|
|
176
179
|
const stranded = loadTokens(issuer, legacy);
|
|
177
180
|
if (!stranded || stranded.authMode !== AUTH_MODE) return null;
|
|
178
|
-
|
|
181
|
+
saveMcpTokens(
|
|
179
182
|
issuer,
|
|
180
183
|
stranded.tokens,
|
|
181
184
|
{
|
|
@@ -424,6 +427,15 @@ function registrationFromState(state: ProviderAuthState | null): ClientRegistrat
|
|
|
424
427
|
};
|
|
425
428
|
}
|
|
426
429
|
|
|
430
|
+
function saveMcpTokens(issuer: string, tokens: OAuthTokens, opts: WriteTokensOpts, path: string): void {
|
|
431
|
+
// The shared store creates path.tmp with default permissions and chmods only
|
|
432
|
+
// after rename. Restrict the temporary file before this MCP credential write.
|
|
433
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
434
|
+
writeFileSync(`${path}.tmp`, '', { mode: 0o600, flag: 'w' });
|
|
435
|
+
chmodSync(`${path}.tmp`, 0o600);
|
|
436
|
+
saveTokens(issuer, tokens, opts, path);
|
|
437
|
+
}
|
|
438
|
+
|
|
427
439
|
function persistRegistration(
|
|
428
440
|
issuer: string,
|
|
429
441
|
registration: ClientRegistration,
|
|
@@ -431,7 +443,7 @@ function persistRegistration(
|
|
|
431
443
|
tokens?: OAuthTokens,
|
|
432
444
|
): void {
|
|
433
445
|
const existing = loadTokens(issuer, path);
|
|
434
|
-
|
|
446
|
+
saveMcpTokens(
|
|
435
447
|
issuer,
|
|
436
448
|
tokens ?? existing?.tokens ?? { accessToken: '', refreshToken: '', expiresAt: null },
|
|
437
449
|
{
|
|
@@ -685,8 +697,45 @@ function persistTokens(
|
|
|
685
697
|
): void {
|
|
686
698
|
const existing = loadTokens(issuer, path);
|
|
687
699
|
const clientId = registration?.clientId ?? existing?.accountUuid;
|
|
688
|
-
const
|
|
689
|
-
|
|
700
|
+
const switchingClient = registration !== null && existing !== null && registration.clientId !== existing.accountUuid;
|
|
701
|
+
const clientSecret = registration?.clientSecret ?? (switchingClient ? undefined : existing?.organizationUuid);
|
|
702
|
+
if (switchingClient) {
|
|
703
|
+
// Build the complete replacement in memory. A failed temporary write or rename
|
|
704
|
+
// must leave the old client's registration AND refresh token together on disk.
|
|
705
|
+
const store = JSON.parse(readFileSync(path, 'utf8')) as { providers: Record<string, ProviderAuthState> };
|
|
706
|
+
const previous = store.providers[issuer];
|
|
707
|
+
if (!previous || previous.accountUuid !== existing?.accountUuid) {
|
|
708
|
+
throw new McpOAuthError('token', 'stored client registration changed during token exchange');
|
|
709
|
+
}
|
|
710
|
+
const replacement: ProviderAuthState = {
|
|
711
|
+
...previous,
|
|
712
|
+
tokens,
|
|
713
|
+
lastRefresh: new Date().toISOString(),
|
|
714
|
+
authMode: AUTH_MODE,
|
|
715
|
+
accountUuid: registration.clientId,
|
|
716
|
+
};
|
|
717
|
+
delete replacement.redirectUri;
|
|
718
|
+
delete replacement.organizationUuid;
|
|
719
|
+
if (clientSecret) replacement.organizationUuid = clientSecret;
|
|
720
|
+
if (registration.redirectUri) replacement.redirectUri = registration.redirectUri;
|
|
721
|
+
store.providers[issuer] = replacement;
|
|
722
|
+
// A stale path.tmp may be 0644. Never write new tokens into it, even briefly.
|
|
723
|
+
// The unique sibling is created exclusively and private before any token bytes are written.
|
|
724
|
+
const tmp = `${path}.${randomUUID()}.tmp`;
|
|
725
|
+
const fd = openSync(tmp, 'wx', 0o600);
|
|
726
|
+
try {
|
|
727
|
+
fchmodSync(fd, 0o600);
|
|
728
|
+
writeFileSync(fd, `${JSON.stringify(store, null, 2)}\n`, 'utf8');
|
|
729
|
+
closeSync(fd);
|
|
730
|
+
renameSync(tmp, path);
|
|
731
|
+
} catch (error) {
|
|
732
|
+
try { closeSync(fd); } catch { /* already closed */ }
|
|
733
|
+
try { unlinkSync(tmp); } catch { /* already renamed */ }
|
|
734
|
+
throw error;
|
|
735
|
+
}
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
saveMcpTokens(
|
|
690
739
|
issuer,
|
|
691
740
|
tokens,
|
|
692
741
|
{
|
package/src/memory.ts
CHANGED
|
@@ -444,7 +444,12 @@ const INDEX_MAX_LINES = 200;
|
|
|
444
444
|
*/
|
|
445
445
|
export function rebuildIndex(root: string = memoryRoot()): void {
|
|
446
446
|
ensureRoot(root);
|
|
447
|
-
|
|
447
|
+
writeFileDurable(memoryIndexPath(root), renderMemoryIndex(listMemories({}, root)));
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/** The MEMORY.md text for a set of entries — rebuildIndex writes it for the whole store,
|
|
451
|
+
* a scoped injection renders it for the entries its filter keeps. */
|
|
452
|
+
export function renderMemoryIndex(entries: readonly MemoryEntry[]): string {
|
|
448
453
|
const byType: Record<MemoryType, MemoryEntry[]> = {
|
|
449
454
|
user: [], feedback: [], project: [], reference: [],
|
|
450
455
|
};
|
|
@@ -468,7 +473,7 @@ export function rebuildIndex(root: string = memoryRoot()): void {
|
|
|
468
473
|
}
|
|
469
474
|
lines.push('');
|
|
470
475
|
}
|
|
471
|
-
|
|
476
|
+
return lines.join('\n');
|
|
472
477
|
}
|
|
473
478
|
|
|
474
479
|
/** Read the MEMORY.md index verbatim. Returns '' when missing (e.g.
|
|
@@ -512,6 +517,11 @@ export interface InjectOpts {
|
|
|
512
517
|
minScore?: number;
|
|
513
518
|
/** Always include the MEMORY.md index even if no keyword hits. */
|
|
514
519
|
alwaysIncludeIndex?: boolean;
|
|
520
|
+
/** Scope filter. When set, only kept entries are injected and the index is rendered from
|
|
521
|
+
* them instead of read from MEMORY.md (which lists every entry, other seats' cards included). */
|
|
522
|
+
filter?: (entry: MemoryEntry) => boolean;
|
|
523
|
+
/** Inject these bodies like pinned ones (e.g. the current seat's context cards). */
|
|
524
|
+
alwaysInject?: (entry: MemoryEntry) => boolean;
|
|
515
525
|
}
|
|
516
526
|
|
|
517
527
|
/** Build the memory-injection block for a user turn. Always prepends
|
|
@@ -531,7 +541,9 @@ export function buildMemoryInjection(
|
|
|
531
541
|
const minScore = opts.minScore ?? 2;
|
|
532
542
|
const alwaysIdx = opts.alwaysIncludeIndex !== false;
|
|
533
543
|
|
|
534
|
-
const
|
|
544
|
+
const filter = opts.filter;
|
|
545
|
+
const scoped = filter ? listMemories({}, root).filter(m => m.contextCard?.status !== 'retired' && filter(m)) : null;
|
|
546
|
+
const index = scoped ? (scoped.length > 0 ? renderMemoryIndex(scoped) : '') : readIndex(root);
|
|
535
547
|
if (!index) return { block: '', tokens: 0, injectedIds: [] };
|
|
536
548
|
|
|
537
549
|
const parts: string[] = [];
|
|
@@ -548,7 +560,10 @@ export function buildMemoryInjection(
|
|
|
548
560
|
|
|
549
561
|
// 📌 pinned 기억 — 키워드 무관 항상 주입(relevance gate bypass · Letta pinned block /
|
|
550
562
|
// claude-code MEMORY.md tier 동형). priority 높은 순. core/safety/ref-location 사실용.
|
|
551
|
-
const
|
|
563
|
+
const alwaysInject = opts.alwaysInject;
|
|
564
|
+
const pinnedMems = (scoped ?? listMemories({}, root))
|
|
565
|
+
.filter(m => (m.pinned || alwaysInject?.(m) === true) && m.contextCard?.status !== 'retired')
|
|
566
|
+
.sort((a, b) => b.priority - a.priority);
|
|
552
567
|
const pinnedParts: string[] = [];
|
|
553
568
|
for (const e of pinnedMems) {
|
|
554
569
|
const chunk = pinnedChunk(e);
|
|
@@ -566,7 +581,7 @@ export function buildMemoryInjection(
|
|
|
566
581
|
const hits = lowContext
|
|
567
582
|
? []
|
|
568
583
|
: searchMemories(userText, { limit: maxHits + pinnedParts.length }, root)
|
|
569
|
-
.filter(h => h.score >= minScore && !injected.includes(h.entry.id))
|
|
584
|
+
.filter(h => h.score >= minScore && !injected.includes(h.entry.id) && (!filter || filter(h.entry)))
|
|
570
585
|
.slice(0, maxHits);
|
|
571
586
|
const bodyParts: string[] = [];
|
|
572
587
|
for (const hit of hits) {
|
package/src/models/prompts.ts
CHANGED
|
@@ -70,6 +70,34 @@ export function getModelFamily(modelId: string | undefined): ModelFamily {
|
|
|
70
70
|
return 'other';
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
/** gpt-6 세대 모델인가 — 직결 id(`gpt-6-sol` · `gpt-6-luna` · `gpt-6-astra` …)와 OpenRouter 게이트웨이 id
|
|
74
|
+
* (`openrouter/openai/gpt-6-*`) 둘 다. 판정은 «모델 이름»만 본다(구동기 무관): 아래 가드는 모델의 도구 호출
|
|
75
|
+
* «행동»에 묶인 것이라 같은 모델이면 어느 경로로 오든 같아야 한다. 맨 `openai/...` id 는 getModelFamily 와 같은
|
|
76
|
+
* 이유(LM Studio 이름 꼴)로 건드리지 않는다. */
|
|
77
|
+
export function isGpt6GenerationModel(modelId: string | undefined): boolean {
|
|
78
|
+
if (!modelId) return false;
|
|
79
|
+
let m = modelId.toLowerCase();
|
|
80
|
+
if (m.startsWith(OPENROUTER_OPENAI_PREFIX)) m = m.slice(OPENROUTER_OPENAI_PREFIX.length);
|
|
81
|
+
return m.startsWith('gpt-6');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** TUI-GPT6-GUARD-PARITY (2026-10-16) — codex 계열 «모델 행동» 도구 루프 가드를 켤 모델인가. 단일 원천.
|
|
85
|
+
*
|
|
86
|
+
* 🩸 계기(tui-op-issues #61): getModelFamily 는 `gpt-5*`·이름에 `codex` 만 'codex' 로 보내서 운영 기본
|
|
87
|
+
* `gpt-6-sol`(·luna)이 'gpt' 로 떨어졌고, llm.ts 의 `modelFamily === 'codex'` 가드가 전부 꺼져 있었다.
|
|
88
|
+
* ⛔ getModelFamily 자체를 바꾸지 않는다 — gpt-6 은 'gpt' 칸으로 전용 프롬프트(gpt6-family-addendum ·
|
|
89
|
+
* GPT_CHAT_VARIANT · tool-hint 상한)를 받고 있고, 'codex' 로 옮기면 그것을 잃고 codex 프롬프트·도구 모양·
|
|
90
|
+
* 예산 칸까지 딸려 간다. 그래서 «가드만» 이 술어로 넓힌다.
|
|
91
|
+
*
|
|
92
|
+
* 이 술어로 가는 자리(모델 행동 · 넓힘): llm.ts 탐색 리다이렉트 묶음(W4-anchor · W6-A · W4-A · W5-D · W5-A)
|
|
93
|
+
* ⊕ 그 Read 계수 ⊕ hard-stop 강제 종합(W5-E) ⊕ 예산 소진 강제 종합(W5-F).
|
|
94
|
+
* 일부러 안 넓힌 자리(`modelFamily === 'codex'` 유지 · 근거 없음/정책/구동기 축)는 PR 본문 표 참조:
|
|
95
|
+
* 즉시 hard-stop 셋 · auto-narrow/inspect 예산 · narrowing 문턱 · W5-G 조기 종합 · 최대 턴 예산 칸 ·
|
|
96
|
+
* 탐색 면제 · 유휴 감시(구동기 축이 이미 덮음) · codex 도구 모양(eval) · 프롬프트 변형. */
|
|
97
|
+
export function usesCodexBehaviorGuards(modelId: string | undefined): boolean {
|
|
98
|
+
return getModelFamily(modelId) === 'codex' || isGpt6GenerationModel(modelId);
|
|
99
|
+
}
|
|
100
|
+
|
|
73
101
|
// ── Model tier (session 21) ─────────────────────────────────────────
|
|
74
102
|
//
|
|
75
103
|
// Coarse 3-tier classification used by the skill router to decide if
|