elanous 0.2.29 → 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/{cIpv5nU9AycwYWZI9H589 → LSXfY0u9QtfDbejY0Ukf_}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{058a98ba.7eb28d5e6dc03565.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/{6013-2f769370d8b4c2c6.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/{8332.6f0f49df772e163b.js → 1654.32de4b324981a188.js} +1 -1
- 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/{8795.32573a185af18c7b.js → 1913.7cc6fb6055b1ed3f.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{419.736c0d6f426249a7.js → 2001.6c7e0fd02190886c.js} +1 -1
- 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/{6767.1fcfc9b8be83975f.js → 2213.2ccbada92c33ea0f.js} +16 -16
- 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/{4759.1f76713aefb87db5.js → 2871.0bca6137343b3f76.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6776.06ff1e3b464cc607.js → 2898.fd781bc7cf01a7b7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1782-59db1b5aa06df38a.js → 2940-619bfd8ef337c611.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{8471.8d2a8c74f09c36ff.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/{bc324b7c.02a09dd93f6a399b.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/{7725-4f83d5541fbdb81b.js → 3541-ce3a5424ed5ad7f1.js} +1 -1
- 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/3902.e1e71aaac850a045.js +34 -0
- package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{46bd8bea.2f4b4099172fcdb7.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1142.65d002789ab3af7d.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/4999.c064a4000c2a9e94.js +79 -0
- 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/5304.04d24756f242a094.js +148 -0
- package/apps/pwa/out/_next/static/chunks/5307.60f2209e809bd627.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3396-97b97928c49190c9.js → 5458-16cd7a2b51b74c8c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3403.7199205e65124486.js → 5525.86debf231e181813.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9143.ff14585db1d275ff.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/{8398.73a19b39715eda04.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/{5591.a35e7a217734a8b9.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/6323.8672b4817a306928.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7375.050ea0d72968e49f.js → 6433.fc573af22bbc9ab7.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +90 -0
- 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/6767.ea607cf0c20a25af.js +24 -0
- 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/{1852.7f7b53991fcb99ef.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/{6534.1ab00f370db7b105.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/{285adb1a.5654e605dddf86d2.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +1 -0
- 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/{1516.dfaceff3fd2d0e0d.js → 9138.b6e80031afb1d973.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9907.49be0fcadaf214b5.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/{8767-2f6a634f5abeaa01.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/{3160-95c96f4d2a21dd26.js → 9398-6aed28f0a96d0d6f.js} +1 -1
- 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/{328bb3ab-6628a1114fe3fb3b.js → 997ce8a5-2ad501927003b41b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6853.cc5174a9dee59593.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-a5635eba0d73b84e.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-349f2752d8cd37ad.js +1 -0
- 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-0a07363b130182a1.js +1 -0
- 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-29900ed0011b2c83.js → page-521ee23ac8c0abfa.js} +1 -1
- 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-9f92737b8766009a.js → page-149dc1caba411bb9.js} +1 -1
- 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/{425cfc4d.fb91158e3971c39f.js → b313b242.cb1265eea908db61.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +122 -0
- package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
- package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +1 -0
- 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 +9 -5
- package/graphs/units/recipes.yaml +3 -0
- package/graphs/units/release-gate-recheck.yaml +15 -0
- package/package.json +2 -1
- package/scripts/check-native-tool-wiring.ts +3 -2
- package/scripts/ci-android-unit-tests.ts +16 -0
- package/scripts/ci-typecheck-changed.ts +37 -9
- package/scripts/coord-channel-watch.sh +22 -16
- package/scripts/coord-role-pack.ts +81 -2
- 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/measure-goal-grounding-corpus.ts +2 -1
- 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-closure.ts +12 -8
- package/scripts/release-loop/gate-diff.ts +1 -1
- package/scripts/release-loop/gate-host-mirror.ts +66 -0
- package/scripts/release-loop/gate-node.ts +523 -75
- 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-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 +2 -19
- package/scripts/release-loop/tui-sim-node.ts +3 -2
- package/scripts/release-loop/unattended-release.ts +16 -0
- package/scripts/test-deterministic.ts +5 -61
- 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/src/acp/client.ts +4 -1
- package/src/acp/core-turn-bridge.ts +50 -5
- package/src/ad-pipeline/run.ts +4 -2
- 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 +12 -0
- 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/capture/tui-self-report.ts +15 -0
- package/src/chat/chat-cli.ts +10 -2
- package/src/chat/index.ts +77 -11
- package/src/chat/input-control-key.ts +5 -3
- package/src/chat/tool-interrupt-behavior.ts +38 -0
- package/src/chat/tool-render/dispatch.ts +5 -1
- package/src/chat/turn-typeahead.ts +75 -20
- 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/decisions-cli.ts +80 -6
- package/src/cli/log-event-names.ts +7 -0
- package/src/cli/mcp-login.ts +21 -5
- package/src/cli/msg-cli.ts +88 -0
- package/src/cli/pr-cli.ts +214 -57
- package/src/cli/pr-land-heavy-remote.ts +2 -2
- package/src/cli/pr-land-overlap-evidence.ts +63 -9
- 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/release-cli.ts +80 -14
- package/src/cli/seat-cli.ts +138 -3
- package/src/cli/self-update.ts +5 -2
- package/src/cli/tasks-cli.ts +97 -19
- package/src/context-bus/context-first.ts +13 -0
- package/src/context-bus/context-now.ts +13 -2
- 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/run-core-turn.ts +1 -0
- package/src/core-turn/run-goal-loop.ts +222 -3
- package/src/core-turn/seat-turn-cap.ts +79 -0
- package/src/core-turn/short-question.ts +38 -6
- package/src/core-turn/types.ts +3 -0
- package/src/dashboard/acp-boot.ts +3 -0
- package/src/dashboard/index.ts +224 -615
- package/src/dashboard/input/chat-main-entry-runtime.ts +1 -1
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +4 -1
- package/src/dashboard/input/chat-main-session.ts +8 -1
- package/src/dashboard/input/chat-main-turn.ts +12 -3
- package/src/dashboard/input/compact-prepass-recovery.ts +33 -0
- package/src/dashboard/input/external-input-host.ts +26 -0
- package/src/dashboard/input/internal-turn.ts +261 -0
- package/src/dashboard/input/seat-autowake.ts +318 -0
- package/src/dashboard/input/turn-steer-bridge.ts +70 -0
- package/src/dashboard/loop-scheduler.ts +72 -0
- package/src/dashboard/seat-boot-preamble.ts +18 -0
- package/src/dashboard/skill-runtime.ts +2 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +126 -1181
- package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
- package/src/dashboard/slash-runtime/index.ts +13 -0
- package/src/dashboard/turn-busy-teardown.ts +50 -0
- package/src/decisions/decision-ledger.ts +45 -4
- package/src/discord-self-message.ts +4 -4
- package/src/domains/release-tool.ts +18 -1
- package/src/field-note/transcribe.ts +17 -0
- 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 +1 -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 +2 -1
- 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 +152 -25
- package/src/input/external-input-queue.ts +33 -1
- package/src/intake-plane/slash.ts +14 -3
- package/src/keybindings.ts +4 -1
- package/src/llm/tool-loop-steered-rejection.ts +33 -0
- package/src/llm.ts +138 -19
- package/src/loops/consensus.ts +348 -0
- package/src/loops/msg-wake.ts +206 -4
- package/src/loops/observe.ts +19 -3
- package/src/loops/orchestrator/tick.ts +64 -10
- package/src/loops/orchestrator/traffic.ts +64 -1
- package/src/loops/registry.ts +30 -0
- package/src/market/signed-index.ts +14 -0
- package/src/mcp/mcp-oauth.ts +54 -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/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
- package/src/nexus/api/http-server.ts +54 -15
- package/src/nexus/api/loop-resources.ts +19 -3
- package/src/nexus/api/ops-api.ts +11 -0
- package/src/nexus/daemon-thin-inventory.md +37 -0
- package/src/nexus/index.ts +70 -0
- package/src/nexus/state/state.ts +1 -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/resources.ts +82 -0
- package/src/plugins/maker/connector-maker.ts +41 -0
- package/src/plugins/maker/skill-maker.ts +42 -0
- package/src/pr-tool/census.ts +288 -0
- package/src/prompt-library/chat-conciseness.ts +13 -0
- package/src/prompt-library/universal-preamble.ts +10 -5
- 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 +5 -2
- 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/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/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 +229 -19
- package/src/self-dev/run-types.ts +20 -0
- package/src/self-dev/shard-aggregate.ts +13 -2
- package/src/self-dev/shard-plan.ts +47 -0
- package/src/self-dev/shard-run.ts +112 -10
- package/src/self-dev/spawn-lane-files.ts +19 -0
- package/src/self-implement/app-api-budget.ts +51 -11
- package/src/self-implement/config-gate.ts +2 -1
- 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 +201 -16
- package/src/self-implement/gate-remote.ts +110 -25
- package/src/self-implement/gate-scenario.ts +85 -0
- package/src/self-implement/goal-author.ts +160 -8
- package/src/self-implement/graph-authority.ts +38 -6
- package/src/self-implement/graph-overlay-condition.ts +92 -1
- package/src/self-implement/heal-triage.ts +79 -0
- package/src/self-implement/host-regate.ts +61 -3
- package/src/self-implement/orchestrator.ts +14 -123
- package/src/self-implement/pr-title.ts +123 -0
- package/src/self-implement/run-checkpoint.ts +235 -0
- package/src/self-implement/run-ledger.ts +155 -10
- package/src/self-implement/run-stop.ts +4 -3
- package/src/self-implement/run-ttl.ts +28 -4
- package/src/self-implement/seams.ts +2 -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 +19 -0
- package/src/session/session-start.ts +224 -0
- package/src/session-runtime/parallel-dispatch.ts +22 -5
- package/src/skills/tools/dev-harness.ts +6 -4
- package/src/skills/tools/shell.ts +1 -1
- 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 +89 -12
- package/src/task-agent/remote-rejudge-bind.ts +28 -8
- package/src/task-agent/repair-cycle.ts +45 -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/pod-command-job.ts +88 -28
- 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 +121 -9
- 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 +27 -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 +132 -15
- package/src/telegram.ts +2 -4
- 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 +48 -0
- package/src/user-config/gemini-server-tools.ts +9 -0
- package/src/user-config.ts +53 -16
- 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/headless-tui.ts +72 -0
- package/src/ux-sim/in-process-cli.ts +2 -1
- 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/1015-9cba22a5a4554797.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +0 -8
- package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +0 -34
- package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +0 -286
- package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +0 -24
- package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +0 -36
- package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +0 -64
- package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +0 -1
- package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +0 -115
- package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +0 -1
- package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +0 -90
- package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +0 -94
- package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +0 -62
- package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +0 -27
- package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +0 -104
- package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +0 -93
- package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +0 -24
- package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +0 -2
- package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +0 -148
- package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +0 -149
- package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +0 -79
- package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +0 -287
- package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +0 -77
- package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +0 -74
- package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +0 -226
- package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +0 -32
- package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +0 -1
- package/apps/pwa/out/_next/static/chunks/a435ad95.577add051b4facb2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-8aaa6dedc4c10dfb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-33bf667a5fb297bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-9eb56166774eb256.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +0 -1
- package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +0 -122
- package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +0 -1
- /package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → LSXfY0u9QtfDbejY0Ukf_}/_ssgManifest.js +0 -0
package/src/cli/mcp-login.ts
CHANGED
|
@@ -91,9 +91,8 @@ export async function runMcpLogin(opts: McpLoginOpts): Promise<McpLoginResult> {
|
|
|
91
91
|
const discovered = await discoverMcpOAuth(challenge.resourceMetadata, {
|
|
92
92
|
resourceUrl: spec.url, ...oauthOpts,
|
|
93
93
|
});
|
|
94
|
-
|
|
95
|
-
if (
|
|
96
|
-
if (why) out.log(why);
|
|
94
|
+
const loginWithDevice = async (): Promise<McpLoginResult> => {
|
|
95
|
+
if (server?.listening) await closeServer(server);
|
|
97
96
|
const stored = loadStoredRegistration(discovered.metadata.issuer, oauthOpts);
|
|
98
97
|
const deviceRegistration = await ensureClientRegistration(discovered.metadata, { ...oauthOpts, deviceCode: true });
|
|
99
98
|
const authorizeDevice = (registration: typeof deviceRegistration) => authorizeMcpDevice(discovered.metadata, registration, {
|
|
@@ -119,6 +118,10 @@ export async function runMcpLogin(opts: McpLoginOpts): Promise<McpLoginResult> {
|
|
|
119
118
|
out.log(`✓ credentials saved for '${opts.serverId}' (${discovered.metadata.issuer})`);
|
|
120
119
|
persistLoginDiscovery(opts, discovered.metadata, out);
|
|
121
120
|
return { exitCode: 0 };
|
|
121
|
+
};
|
|
122
|
+
if ((why || !discovered.metadata.authorizationEndpoint) && discovered.metadata.deviceAuthorizationEndpoint) {
|
|
123
|
+
if (why) out.log(why);
|
|
124
|
+
return await loginWithDevice();
|
|
122
125
|
}
|
|
123
126
|
const callbackListener = early ?? await listenForCallback(opts.createListener, 0);
|
|
124
127
|
server = callbackListener.server;
|
|
@@ -170,7 +173,17 @@ export async function runMcpLogin(opts: McpLoginOpts): Promise<McpLoginResult> {
|
|
|
170
173
|
}
|
|
171
174
|
}
|
|
172
175
|
}
|
|
173
|
-
|
|
176
|
+
let callback: Callback;
|
|
177
|
+
try {
|
|
178
|
+
callback = await callbackPromise;
|
|
179
|
+
} catch (error) {
|
|
180
|
+
// A missing browser callback can use the advertised device flow. An explicit
|
|
181
|
+
// denial, mismatched state, or malformed callback must never silently fall back.
|
|
182
|
+
if (!discovered.metadata.deviceAuthorizationEndpoint ||
|
|
183
|
+
!/^authorization callback timed out after \d+ms$/.test(error instanceof Error ? error.message : '')) throw error;
|
|
184
|
+
out.log(`Browser approval did not complete for '${opts.serverId}'; trying device code.`);
|
|
185
|
+
return await loginWithDevice();
|
|
186
|
+
}
|
|
174
187
|
await exchangeAuthorizationCode(authorization.metadata, authorization.request, callback, oauthOpts);
|
|
175
188
|
out.log(`✓ credentials saved for '${opts.serverId}' (${authorization.metadata.issuer})`);
|
|
176
189
|
persistLoginDiscovery(opts, authorization.metadata, out);
|
|
@@ -424,7 +437,10 @@ async function listenForCallback(
|
|
|
424
437
|
}
|
|
425
438
|
settle = resolve;
|
|
426
439
|
reject = rejectWait;
|
|
427
|
-
const timer = setTimeout(() =>
|
|
440
|
+
const timer = setTimeout(() => {
|
|
441
|
+
completed = true;
|
|
442
|
+
settleCallback(new Error(`authorization callback timed out after ${timeoutMs}ms`));
|
|
443
|
+
}, timeoutMs);
|
|
428
444
|
(timer as unknown as { unref?: () => void }).unref?.();
|
|
429
445
|
// ⛔ 성공·실패 어느 쪽으로 끝나든 타이머를 «반드시» 거둔다.
|
|
430
446
|
clearWaitTimer = () => clearTimeout(timer as unknown as ReturnType<typeof setTimeout>);
|
package/src/cli/msg-cli.ts
CHANGED
|
@@ -21,6 +21,14 @@ export interface MsgCliDeps {
|
|
|
21
21
|
registerLogSink?: () => Promise<unknown>;
|
|
22
22
|
/** Wake the recipient after a durable post; never changes the post outcome. */
|
|
23
23
|
wake?: (address: string, msgId: number, message: { from: string; kind?: string }, deps: WakeDeps) => Promise<WakeOutcome>;
|
|
24
|
+
/** Test seams for the existing self-send transport and the selected task-card ledger. */
|
|
25
|
+
readCard?: typeof import('../task-agent/task-hand.js').readTaskCard;
|
|
26
|
+
podFragmentsForRun?: typeof import('../harness/self-send-target.js').listPodFragmentsForRun;
|
|
27
|
+
sendPod?: typeof import('../harness/self-send-target.js').dispatchPodSelfSend;
|
|
28
|
+
runScreen?: typeof import('../self-implement/run-ledger.js').queryRunScreenKey;
|
|
29
|
+
sendMemo?: typeof import('../harness/control-inbox.js').enqueueControlMemo;
|
|
30
|
+
sendStop?: typeof import('../harness/control-inbox.js').enqueueSoftStop;
|
|
31
|
+
screenAlive?: (spaceId: string) => boolean;
|
|
24
32
|
}
|
|
25
33
|
|
|
26
34
|
type CommonOptions = { json?: boolean };
|
|
@@ -59,6 +67,83 @@ export function registerMsgCommands(program: Command, deps: MsgCliDeps = {}): vo
|
|
|
59
67
|
const setExitCode = deps.setExitCode ?? ((code: number) => { process.exitCode = code; });
|
|
60
68
|
const msg = program.command('msg').description('Durable seat-addressed messages');
|
|
61
69
|
|
|
70
|
+
// Called by both msg post and msg ask after their durable TA request is written.
|
|
71
|
+
const handleTaMessage = async (request: Message): Promise<void> => {
|
|
72
|
+
if (request.to !== 'TA' || request.from === 'TA' || request.replyTo !== undefined) return;
|
|
73
|
+
const command = /\b(stop|memo|status)\b/i.exec(request.body);
|
|
74
|
+
const cardId = /\bta-[a-zA-Z0-9][a-zA-Z0-9._-]*\b/.exec(request.body)?.[0]?.replace(/[.,!?]+$/, '');
|
|
75
|
+
if (!command || !cardId) return;
|
|
76
|
+
const { readTaskCard } = await import('../task-agent/task-hand.js');
|
|
77
|
+
const { queryRunScreenKey } = await import('../self-implement/run-ledger.js');
|
|
78
|
+
const { listHarnessScreens } = await import('../harness/harness-screen.js');
|
|
79
|
+
const { normalizeRunId } = await import('../harness/harness-space.js');
|
|
80
|
+
const { dispatchPodSelfSend, listPodFragmentsForRun } = await import('../harness/self-send-target.js');
|
|
81
|
+
const { enqueueControlMemo, enqueueSoftStop } = await import('../harness/control-inbox.js');
|
|
82
|
+
withStore(store => {
|
|
83
|
+
// Reserve one linked reply and pending delivery before touching another store or Pod.
|
|
84
|
+
const pending = store.db.transaction(() => {
|
|
85
|
+
// A concurrent sender may have claimed after an earlier read. Keep this
|
|
86
|
+
// check in the same write transaction as any pending reply change.
|
|
87
|
+
if (store.taDeliveryClaimState(request.id) === 'held') return null;
|
|
88
|
+
const reply = store.listReplies(request.id, 1)[0];
|
|
89
|
+
if (reply && store.taDeliveryStatus(request.id) !== 'pending') return null;
|
|
90
|
+
let delivery: (() => void) | undefined;
|
|
91
|
+
let deliveryReply: string | undefined;
|
|
92
|
+
let answer: string;
|
|
93
|
+
try {
|
|
94
|
+
const card = (deps.readCard ?? readTaskCard)(cardId);
|
|
95
|
+
if (!card) throw new Error(`카드 없음: ${cardId}`);
|
|
96
|
+
if (command[1]!.toLowerCase() === 'status') {
|
|
97
|
+
answer = `${card.id}: ${card.status}${card.runId ? ` · run ${card.runId}` : ''}`;
|
|
98
|
+
} else {
|
|
99
|
+
const runId = card.runId;
|
|
100
|
+
if (!runId || normalizeRunId(runId) !== runId) throw new Error(`${cardId}: 연결된 런 없음`);
|
|
101
|
+
const fragments = (deps.podFragmentsForRun ?? listPodFragmentsForRun)(runId);
|
|
102
|
+
const resolved = fragments.length === 0 ? (deps.runScreen ?? queryRunScreenKey)(runId) : null;
|
|
103
|
+
const screen = resolved?.logStoreStatus === 'read' ? resolved.screenKey : null;
|
|
104
|
+
if (fragments.length > 1 || (fragments.length === 0 && (!screen || !(deps.screenAlive ?? ((id: string) => listHarnessScreens().some(row => row.spaceId === id)))(screen)))) {
|
|
105
|
+
throw new Error(`${cardId}: 실행 중인 단일 런 공간을 찾을 수 없음`);
|
|
106
|
+
}
|
|
107
|
+
const space = fragments[0]?.spaceId ?? screen!;
|
|
108
|
+
const stop = command[1]!.toLowerCase() === 'stop';
|
|
109
|
+
const body = stop ? '' : request.body.replace(command[0], '').replace(cardId, '').trim().replace(/^[,.:;\s-]+/, '');
|
|
110
|
+
if (!stop && (!body || /[\r\n]/.test(body))) throw new Error('memo는 비어 있지 않은 한 줄이어야 한다');
|
|
111
|
+
const memo = { version: 1 as const, kind: 'supervisor', urgency: 'normal' as const, body };
|
|
112
|
+
answer = `${cardId}: run ${runId} 전달 여부 미확인 (${space}) — 자동 재시도 중지; 런 인박스를 확인하세요.`;
|
|
113
|
+
delivery = () => {
|
|
114
|
+
if (fragments.length) {
|
|
115
|
+
if (!(deps.sendPod ?? dispatchPodSelfSend)(space, stop ? { stop: true } : { memo })) throw new Error(`${cardId}: Pod 전달 실패`);
|
|
116
|
+
} else if (stop) (deps.sendStop ?? enqueueSoftStop)(space);
|
|
117
|
+
else (deps.sendMemo ?? enqueueControlMemo)(space, memo);
|
|
118
|
+
};
|
|
119
|
+
deliveryReply = stop ? `${cardId}: run ${runId} soft stop 요청 기록 (${space})`
|
|
120
|
+
: `${cardId}: run ${runId} 감독 메모 기록 (${space})`;
|
|
121
|
+
}
|
|
122
|
+
} catch (error) {
|
|
123
|
+
answer = `${cardId}: ${error instanceof Error ? error.message : String(error)}`;
|
|
124
|
+
}
|
|
125
|
+
if (delivery) store.setTaDeliveryStatus(request.id, 'pending');
|
|
126
|
+
if (reply) store.updateTaReply(request.id, answer);
|
|
127
|
+
else store.post({ from: 'TA', to: request.from, kind: 'reply', body: answer, replyTo: request.id });
|
|
128
|
+
return delivery && deliveryReply ? { delivery, reply: deliveryReply } : null;
|
|
129
|
+
}).immediate();
|
|
130
|
+
if (pending) {
|
|
131
|
+
const claim = store.claimTaDelivery(request.id);
|
|
132
|
+
if (!claim) return;
|
|
133
|
+
try {
|
|
134
|
+
pending.delivery();
|
|
135
|
+
store.settleTaDelivery(request.id, claim, pending.reply, true);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
// A transport error or failed DB settlement may follow a successful publication.
|
|
139
|
+
// Keep the claim and require inspection rather than send the same memo again.
|
|
140
|
+
store.markTaDeliveryUnknown(request.id, claim,
|
|
141
|
+
`${cardId}: 전달 여부 미확인 — 자동 재시도 중지: ${error instanceof Error ? error.message : String(error)}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
|
|
62
147
|
const run = (action: () => void | Promise<void>) => async () => {
|
|
63
148
|
try { await action(); }
|
|
64
149
|
catch (error) {
|
|
@@ -94,6 +179,7 @@ export function registerMsgCommands(program: Command, deps: MsgCliDeps = {}): vo
|
|
|
94
179
|
? store.post(envelope)
|
|
95
180
|
: store.appendWithProvenance(envelope, opts.originKey));
|
|
96
181
|
emit(posted, opts.json, () => out.log(formatMessage(posted)));
|
|
182
|
+
await handleTaMessage(posted); // msg post: process the durable TA request (including pending retry).
|
|
97
183
|
const noBody = noReplyBodyNotice(to);
|
|
98
184
|
if (noBody) out.error(noBody);
|
|
99
185
|
// 저장 «뒤» 한 번 — 읽는 몸이 없다는 안내가 이미 나갔으면 깨움 경고는 겹쳐 내지 않는다.
|
|
@@ -273,6 +359,8 @@ export function registerMsgCommands(program: Command, deps: MsgCliDeps = {}): vo
|
|
|
273
359
|
let store: MsgStore | undefined;
|
|
274
360
|
try {
|
|
275
361
|
const asked = withStore(ledger => ledger.post({ from, to, body: question }));
|
|
362
|
+
// msg ask uses the same saved-message handler before waiting for its linked reply.
|
|
363
|
+
await handleTaMessage(asked);
|
|
276
364
|
const deadline = Date.now() + waitSeconds * 1000;
|
|
277
365
|
let reply: Message | undefined;
|
|
278
366
|
store = open();
|
package/src/cli/pr-cli.ts
CHANGED
|
@@ -58,12 +58,16 @@ import { branchLineageSlug, findSiblingPrs } from './pr-lineage.js';
|
|
|
58
58
|
import { parseReleaseNoteSection } from '../release-loop/release-note.js';
|
|
59
59
|
import { landingFreezeMessage } from '../release-loop/landing-freeze.js';
|
|
60
60
|
import { admitLandingMerge } from '../self-implement/frozen-merges.js';
|
|
61
|
-
import { verifyAncestorAutoPass, verifyOverlapEvidence } from './pr-land-overlap-evidence.js';
|
|
61
|
+
import { verifyAllSameHeadReviews, verifyAncestorAutoPass, verifyOverlapEvidence } from './pr-land-overlap-evidence.js';
|
|
62
|
+
import { verifyVirtualRebasePatch } from './pr-land-virtual-rebase.js';
|
|
62
63
|
import { observePrLandRefusal } from './pr-land-refusal.js';
|
|
63
64
|
import { ensurePrLandHeavyRemote, type HeavyRemoteInput, type HeavyRemoteResult } from './pr-land-heavy-remote.js';
|
|
65
|
+
import { runHeavyOnPodShadow } from './pr-land-pod-shadow.js';
|
|
66
|
+
import type { LandingPodShadowInput, LandingPodShadowVerdict } from './pr-land-pod-shadow-job.js';
|
|
64
67
|
import { taskAgentStatePath } from '../task-agent/task-hand.js';
|
|
65
68
|
import { PR_LABEL_NAMES } from '../github/pr-labels.js';
|
|
66
69
|
import { enqueueL8ShadowQueue, runL8ShadowQueue, shadowPrNumber, statusL8ShadowQueue, type L8ShadowQueueDeps } from '../self-implement/l8-merge-queue.js';
|
|
70
|
+
import { censusOpenPrs, guardNewPr, parseDiffHunks, readOpenPrs, type Seat } from '../pr-tool/census.js';
|
|
67
71
|
|
|
68
72
|
export { branchLineageSlug, findSiblingPrs };
|
|
69
73
|
|
|
@@ -93,6 +97,8 @@ export interface PrLandOpts {
|
|
|
93
97
|
overlapEvidence?: string;
|
|
94
98
|
/** Pinned landing opt-in: run the heavy changed-file gate on node-b at the reviewed head and current main tip. */
|
|
95
99
|
heavyRemote?: boolean;
|
|
100
|
+
/** Opt-in comparison of the heavy remote verdict with a Pod Job; the remote verdict still decides landing. */
|
|
101
|
+
heavyOnPodShadow?: boolean;
|
|
96
102
|
}
|
|
97
103
|
|
|
98
104
|
export interface PrGranularityOpts {
|
|
@@ -146,6 +152,7 @@ export interface PrLandDeps {
|
|
|
146
152
|
runIosGate?: (out: { log: (message: string) => void; error: (message: string) => void }, changedFiles: readonly string[]) => boolean;
|
|
147
153
|
runPwaGate?: (out: { log: (message: string) => void; error: (message: string) => void }, changedFiles: readonly string[]) => boolean;
|
|
148
154
|
runHeavyRemote?: (input: HeavyRemoteInput) => HeavyRemoteResult;
|
|
155
|
+
runLandingPodShadow?: (input: LandingPodShadowInput) => Promise<LandingPodShadowVerdict>;
|
|
149
156
|
isInteractive?: () => boolean;
|
|
150
157
|
/** Clock for the recent-landings window (test seam · default Date.now). */
|
|
151
158
|
now?: () => number;
|
|
@@ -818,13 +825,22 @@ function renderConflictRunIds(runIds: readonly { runId: string; status: string }
|
|
|
818
825
|
return runIds.map(({ runId, status }) => `${runId}) status=${status}`).join(', ');
|
|
819
826
|
}
|
|
820
827
|
|
|
828
|
+
function currentChangePaths(
|
|
829
|
+
run: CmdRunner, cwd: string, staged: PorcelainStatusRecord[] | null, base: string,
|
|
830
|
+
out: { log: (message: string) => void }, strict: true,
|
|
831
|
+
): string[] | null;
|
|
832
|
+
function currentChangePaths(
|
|
833
|
+
run: CmdRunner, cwd: string, staged: PorcelainStatusRecord[] | null, base: string,
|
|
834
|
+
out: { log: (message: string) => void }, strict?: false,
|
|
835
|
+
): string[];
|
|
821
836
|
function currentChangePaths(
|
|
822
837
|
run: CmdRunner,
|
|
823
838
|
cwd: string,
|
|
824
839
|
staged: PorcelainStatusRecord[] | null,
|
|
825
840
|
base: string,
|
|
826
841
|
out: { log: (message: string) => void },
|
|
827
|
-
|
|
842
|
+
strict = false,
|
|
843
|
+
): string[] | null {
|
|
828
844
|
const fromStatus = staged
|
|
829
845
|
? staged.flatMap(({ path, originalPath }) => (originalPath ? [path, originalPath] : [path]))
|
|
830
846
|
: [];
|
|
@@ -847,6 +863,7 @@ function currentChangePaths(
|
|
|
847
863
|
}
|
|
848
864
|
|
|
849
865
|
const diff = run('git', ['diff', '--name-only', '--no-renames', `${comparisonBase}...HEAD`], { cwd });
|
|
866
|
+
if (strict && !diff.ok) return null;
|
|
850
867
|
const fromDiff = diff.ok ? parseNameOnlyList(diff.out) : [];
|
|
851
868
|
return unionPaths(fromStatus, fromDiff);
|
|
852
869
|
}
|
|
@@ -1014,12 +1031,13 @@ function emitLandingOverlapAdvisory(
|
|
|
1014
1031
|
currentFiles: readonly string[],
|
|
1015
1032
|
out: { log: (message: string) => void },
|
|
1016
1033
|
overlappingLandings: string[] = [],
|
|
1034
|
+
resolvedLandings?: NonNullable<ReturnType<typeof collectResolvedBaseLandings>>,
|
|
1017
1035
|
): boolean {
|
|
1018
1036
|
if (currentFiles.length === 0) {
|
|
1019
1037
|
record('overlap', true, { outcome: 'no-changed-files' });
|
|
1020
1038
|
return false;
|
|
1021
1039
|
}
|
|
1022
|
-
const commits = collectResolvedBaseLandings(run, cwd, DEFAULT_GRANULARITY_SINCE, base);
|
|
1040
|
+
const commits = resolvedLandings ?? collectResolvedBaseLandings(run, cwd, DEFAULT_GRANULARITY_SINCE, base);
|
|
1023
1041
|
if (commits === null) {
|
|
1024
1042
|
record('overlap', false, { outcome: 'lookup-failed' });
|
|
1025
1043
|
return false;
|
|
@@ -1041,6 +1059,88 @@ function emitLandingOverlapAdvisory(
|
|
|
1041
1059
|
return false;
|
|
1042
1060
|
}
|
|
1043
1061
|
|
|
1062
|
+
/** The pinned overlap evidence decision is shared by landing and its read-only preview. */
|
|
1063
|
+
function verifyPinnedOverlapDecision(input: {
|
|
1064
|
+
opts: PrLandOpts;
|
|
1065
|
+
deps: PrLandDeps;
|
|
1066
|
+
run: CmdRunner;
|
|
1067
|
+
cwd: string;
|
|
1068
|
+
base: string;
|
|
1069
|
+
readFile: (path: string) => string;
|
|
1070
|
+
overlappingLandings: readonly string[];
|
|
1071
|
+
decision: OverlapLandingDecisionOutcome | undefined;
|
|
1072
|
+
out: { log: (message: string) => void; error: (message: string) => void };
|
|
1073
|
+
refuse: (message: string) => void;
|
|
1074
|
+
}): boolean {
|
|
1075
|
+
const { opts, deps, run, cwd, base, readFile, overlappingLandings, decision, out, refuse } = input;
|
|
1076
|
+
if (decision === undefined || decision === 'user-merge') return true;
|
|
1077
|
+
let accepted = false;
|
|
1078
|
+
let ancestorResyncNeeded = false;
|
|
1079
|
+
if (decision === 'unavailable' && opts.overlapEvidence !== undefined) {
|
|
1080
|
+
const ref = resolveRemoteBranchRef(run, cwd, base);
|
|
1081
|
+
const verdict = verifyOverlapEvidence({
|
|
1082
|
+
evidencePath: opts.overlapEvidence, pr: Number(opts.pr), expectedHead: opts.expectedHead!,
|
|
1083
|
+
remote: ref.remote, branch: ref.branch, cwd, run, readFile,
|
|
1084
|
+
reviewResultsDir: deps.reviewResultsDir ?? join(dirname(taskAgentStatePath()), 'review-results'),
|
|
1085
|
+
listDir: (dir) => readdirSync(dir), reviewMtime: (path) => statSync(path).mtimeMs,
|
|
1086
|
+
reviewRealPath: (path) => realpathSync(path), overlappingLandings,
|
|
1087
|
+
});
|
|
1088
|
+
accepted = verdict.ok;
|
|
1089
|
+
if (verdict.ok) {
|
|
1090
|
+
out.log(verdict.mode === 'already-ancestor'
|
|
1091
|
+
? `✓ overlap-evidence: already-ancestor — 겹친 최근 착지 ${overlappingLandings.length}개가 전부 head ${opts.expectedHead!.slice(0, 12)} 의 조상 · review pass must-fix 0 (${verdict.reviewResult})`
|
|
1092
|
+
: verdict.mode === 'base-advanced-disjoint'
|
|
1093
|
+
? `✓ overlap-evidence: base-advanced-disjoint — gate base ${verdict.gateBase.slice(0, 12)} ⊂ head ${opts.expectedHead!.slice(0, 12)} · ${ref.remote}/${ref.branch} ${verdict.baseTip.slice(0, 12)} 까지 ${verdict.windowCommits}개 커밋이 PR 파일을 안 건드린다 · review pass|warn must-fix 0 (${verdict.reviewResult})`
|
|
1094
|
+
: `✓ overlap-evidence: ${ref.remote}/${ref.branch} ${verdict.baseTip.slice(0, 12)} ⊂ head ${opts.expectedHead!.slice(0, 12)} · gate passed on that base · review pass must-fix 0 (${verdict.reviewResult})`);
|
|
1095
|
+
} else refuse(`✗ overlap-evidence: ${verdict.reason}`);
|
|
1096
|
+
} else if (decision === 'unavailable') {
|
|
1097
|
+
const verdict = verifyAncestorAutoPass({
|
|
1098
|
+
pr: Number(opts.pr), expectedHead: opts.expectedHead!, cwd, run, readFile, overlappingLandings,
|
|
1099
|
+
reviewResultsDir: deps.reviewResultsDir ?? join(dirname(taskAgentStatePath()), 'review-results'),
|
|
1100
|
+
listDir: (dir) => readdirSync(dir),
|
|
1101
|
+
});
|
|
1102
|
+
accepted = verdict.ok;
|
|
1103
|
+
if (verdict.ok) {
|
|
1104
|
+
out.log(`✓ overlap-evidence: already-ancestor-auto — 겹친 최근 착지 ${overlappingLandings.length}개가 전부 head ${opts.expectedHead!.slice(0, 12)} 의 조상 · review pass|warn must-fix 0 (${verdict.reviewResult})`);
|
|
1105
|
+
} else {
|
|
1106
|
+
ancestorResyncNeeded = verdict.reason.startsWith('ancestor-auto-not-ancestor:');
|
|
1107
|
+
if (ancestorResyncNeeded) {
|
|
1108
|
+
const ref = resolveRemoteBranchRef(run, cwd, base);
|
|
1109
|
+
const remote = run('git', ['ls-remote', ref.remote, `refs/heads/${ref.branch}`], { cwd });
|
|
1110
|
+
const baseTip = remote.ok ? remote.out.trim().split(/\s+/u, 1)[0] ?? '' : '';
|
|
1111
|
+
const local = run('git', ['rev-parse', '--verify', `refs/remotes/${ref.remote}/${ref.branch}`], { cwd });
|
|
1112
|
+
const reviews = verifyAllSameHeadReviews({
|
|
1113
|
+
pr: Number(opts.pr), expectedHead: opts.expectedHead!, readFile,
|
|
1114
|
+
reviewResultsDir: deps.reviewResultsDir ?? join(dirname(taskAgentStatePath()), 'review-results'),
|
|
1115
|
+
listDir: (dir) => readdirSync(dir),
|
|
1116
|
+
});
|
|
1117
|
+
const patch = reviews.ok && /^[a-f0-9]{40}$/iu.test(baseTip) && local.ok && local.out.trim() === baseTip
|
|
1118
|
+
? verifyVirtualRebasePatch({ cwd, baseTip, head: opts.expectedHead! })
|
|
1119
|
+
: { ok: false as const, reason: reviews.ok ? 'base-stale-or-unmeasured' : reviews.reason };
|
|
1120
|
+
accepted = patch.ok;
|
|
1121
|
+
ancestorResyncNeeded = !accepted;
|
|
1122
|
+
record('virtual-rebase', patch.ok, {
|
|
1123
|
+
pr: Number(opts.pr), head: opts.expectedHead, baseTip: baseTip || null,
|
|
1124
|
+
reason: patch.ok ? 'same-patch-id' : patch.reason,
|
|
1125
|
+
reviewResult: reviews.ok ? reviews.reviewResult : null,
|
|
1126
|
+
});
|
|
1127
|
+
if (patch.ok) {
|
|
1128
|
+
out.log(`✓ overlap-evidence: virtual-rebase — ${ref.remote}/${ref.branch} ${baseTip.slice(0, 12)} 와 head ${opts.expectedHead!.slice(0, 12)} 충돌 없음 · patch-id ${patch.patchId.slice(0, 12)} 동일 · review pass|warn must-fix 0 (${reviews.reviewResult})`);
|
|
1129
|
+
} else refuse(`✗ virtual-rebase: ${patch.reason} · ${verdict.reason}`);
|
|
1130
|
+
} else refuse(`✗ ancestor-auto: ${verdict.reason}`);
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
if (!accepted) {
|
|
1134
|
+
if (ancestorResyncNeeded && !opts.dryRun) {
|
|
1135
|
+
const marked = run('gh', ['pr', 'edit', String(opts.pr), '--add-label', PR_LABEL_NAMES.needsRebase], { cwd });
|
|
1136
|
+
record('resync-marker', marked.ok, { pr: Number(opts.pr), reason: 'ancestor-auto-not-ancestor' });
|
|
1137
|
+
if (!marked.ok) out.error('⚠ resync-marker: needs-rebase 라벨을 남기지 못했습니다');
|
|
1138
|
+
}
|
|
1139
|
+
out.error('✗ expected-head: overlap merge approval unavailable for the reviewed head');
|
|
1140
|
+
}
|
|
1141
|
+
return accepted;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1044
1144
|
const SOURCE_SPLIT_PR_LIST_LIMIT = 200;
|
|
1045
1145
|
/**
|
|
1046
1146
|
* merged 조회의 «폭주 방지» 절대 상한 — ⛔ 창을 덮는 값이 «아니라» 그 위의 천장이다.
|
|
@@ -1217,6 +1317,10 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1217
1317
|
out.error('✗ heavy-remote: --pr ⊕ --expected-head 머리 고정 착지에서만 쓴다.');
|
|
1218
1318
|
return 1;
|
|
1219
1319
|
}
|
|
1320
|
+
if (opts.heavyOnPodShadow && !opts.heavyRemote) {
|
|
1321
|
+
out.error('✗ heavy-on-pod-shadow: --heavy-remote 머리 고정 착지에서만 쓴다.');
|
|
1322
|
+
return 1;
|
|
1323
|
+
}
|
|
1220
1324
|
|
|
1221
1325
|
const readFile = deps.readFile ?? ((path: string) => readFileSync(path, 'utf8'));
|
|
1222
1326
|
let title = opts.title;
|
|
@@ -1310,8 +1414,8 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1310
1414
|
out.error('✗ dry-run: --hold 는 머리 고정 읽기 전용 예행과 함께 사용할 수 없습니다.');
|
|
1311
1415
|
return 1;
|
|
1312
1416
|
}
|
|
1313
|
-
if (opts.overlapEvidence !== undefined) {
|
|
1314
|
-
out.error('✗
|
|
1417
|
+
if (opts.overlapEvidence !== undefined && !opts.overlapEvidence.trim()) {
|
|
1418
|
+
out.error('✗ overlap-evidence: --overlap-evidence <file> 는 비어 있을 수 없습니다.');
|
|
1315
1419
|
return 1;
|
|
1316
1420
|
}
|
|
1317
1421
|
const inspected = inspectPinnedPr(run, cwd, pr, opts.expectedHead!);
|
|
@@ -1322,8 +1426,55 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1322
1426
|
for (const reason of reasons) out.log(`[dry-run] ✗ preflight: ${reason}`);
|
|
1323
1427
|
if (reasons.includes('PR is draft')) out.log(`[dry-run] 선행: eln gh pr ready ${pr}`);
|
|
1324
1428
|
if (reasons.length === 0) out.log('[dry-run] ✓ preflight: PR OPEN non-draft, matching PR/local HEAD and branch, clean worktree');
|
|
1325
|
-
|
|
1326
|
-
|
|
1429
|
+
if (reasons.length > 0) return 1;
|
|
1430
|
+
// A dry-run may inspect the remote tip but must not update refs, FETCH_HEAD, objects or PR labels.
|
|
1431
|
+
const readOnlyRun: CmdRunner = (command, args, options) => {
|
|
1432
|
+
if ((command === 'git' && /^(fetch|pull|push|merge|commit|checkout|switch|worktree|update-ref|reset|apply|am|rebase)$/u.test(args[0] ?? ''))
|
|
1433
|
+
|| (command === 'gh' && args[0] === 'pr' && /^(edit|ready|merge|create|close|reopen)$/u.test(args[1] ?? ''))) {
|
|
1434
|
+
return { ok: false, out: '', err: 'dry-run forbids mutation' };
|
|
1435
|
+
}
|
|
1436
|
+
return run(command, args, options);
|
|
1437
|
+
};
|
|
1438
|
+
const base = (deps.resolveBase ?? resolveDeliverableBase)(readOnlyRun, cwd, opts.base);
|
|
1439
|
+
if (!base) { out.error('✗ base: 비교 base를 선택하지 못했습니다.'); return 1; }
|
|
1440
|
+
const ref = resolveRemoteBranchRef(readOnlyRun, cwd, base);
|
|
1441
|
+
const measuredBase = `refs/remotes/${ref.remote}/${ref.branch}`;
|
|
1442
|
+
const remoteTip = readOnlyRun('git', ['ls-remote', ref.remote, `refs/heads/${ref.branch}`], { cwd });
|
|
1443
|
+
const tip = remoteTip.ok ? remoteTip.out.trim().split(/\s+/u, 1)[0] : undefined;
|
|
1444
|
+
const localTip = readOnlyRun('git', ['rev-parse', '--verify', measuredBase], { cwd });
|
|
1445
|
+
if (!tip || !/^[a-f0-9]{40}$/iu.test(tip) || !localTip.ok || localTip.out.trim() !== tip) {
|
|
1446
|
+
out.error(`✗ overlap-preflight: ${base} 최신 SHA를 로컬에서 읽지 못했다. 읽기 전용 예행은 ref를 갱신하지 않는다.`);
|
|
1447
|
+
return 1;
|
|
1448
|
+
}
|
|
1449
|
+
const staged = stagedPaths(readOnlyRun, cwd);
|
|
1450
|
+
if (staged === null) {
|
|
1451
|
+
out.error('✗ overlap-preflight: PR 변경 파일을 읽지 못했다. 겹침을 미측정 상태로 둔다.');
|
|
1452
|
+
return 1;
|
|
1453
|
+
}
|
|
1454
|
+
const changed = readOnlyRun('git', ['diff', '--name-only', '--no-renames', `${measuredBase}...HEAD`], { cwd });
|
|
1455
|
+
if (!changed.ok) {
|
|
1456
|
+
out.error('✗ overlap-preflight: PR 변경 파일을 읽지 못했다. 겹침을 미측정 상태로 둔다.');
|
|
1457
|
+
return 1;
|
|
1458
|
+
}
|
|
1459
|
+
const changedPaths = unionPaths(staged.flatMap(({ path, originalPath }) => originalPath ? [path, originalPath] : [path]), parseNameOnlyList(changed.out));
|
|
1460
|
+
const landings = collectResolvedBaseLandings(readOnlyRun, cwd, DEFAULT_GRANULARITY_SINCE, measuredBase);
|
|
1461
|
+
if (landings === null) {
|
|
1462
|
+
out.error('✗ overlap-preflight: 최근 착지 조회가 실패했다. 겹침을 미측정 상태로 둔다.');
|
|
1463
|
+
return 1;
|
|
1464
|
+
}
|
|
1465
|
+
const overlappingLandings: string[] = [];
|
|
1466
|
+
const overlapFound = emitLandingOverlapAdvisory(readOnlyRun, cwd, measuredBase, changedPaths, out, overlappingLandings, landings);
|
|
1467
|
+
emitSiblingPrAdvisory(branch!, deps.listOpenPrs ?? (() => lookupOpenPrs(readOnlyRun, cwd)), out);
|
|
1468
|
+
if (overlapFound && !verifyPinnedOverlapDecision({
|
|
1469
|
+
opts, deps, run: readOnlyRun, cwd, base, readFile, overlappingLandings,
|
|
1470
|
+
decision: 'unavailable', out, refuse: out.error,
|
|
1471
|
+
})) {
|
|
1472
|
+
out.log('[dry-run] Remaining landing gates, freeze and merge: UNMEASURED; no PR or git state changed.');
|
|
1473
|
+
return 1;
|
|
1474
|
+
}
|
|
1475
|
+
out.log(`[dry-run] ✓ overlap: ${overlapFound ? 'evidence accepted' : 'no recent overlapping landing'}`);
|
|
1476
|
+
out.log('[dry-run] Remaining landing gates, freeze and merge: UNMEASURED; no PR or git state changed.');
|
|
1477
|
+
return 0;
|
|
1327
1478
|
}
|
|
1328
1479
|
if (opts.overlapEvidence !== undefined && (!pinned || !opts.overlapEvidence.trim())) {
|
|
1329
1480
|
out.error('✗ overlap-evidence: --overlap-evidence <file> 는 --pr ⊕ --expected-head 머리 고정 착지에서만 쓴다.');
|
|
@@ -1592,7 +1743,12 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1592
1743
|
}
|
|
1593
1744
|
// Pinned landings reject a known non-ancestor before local or remote heavy gates.
|
|
1594
1745
|
// Unpinned landings keep their existing gate and advisory order.
|
|
1595
|
-
|
|
1746
|
+
const initialChangedPaths = pinned ? currentChangePaths(run, cwd, staged, base, out, true) : [];
|
|
1747
|
+
if (initialChangedPaths === null) {
|
|
1748
|
+
out.error('✗ overlap-preflight: PR 변경 파일을 읽지 못했다. 겹침을 미측정 상태로 두고 무거운 게이트를 시작하지 않는다.');
|
|
1749
|
+
return 1;
|
|
1750
|
+
}
|
|
1751
|
+
let changedPaths: string[] = initialChangedPaths;
|
|
1596
1752
|
let hold = !!opts.hold;
|
|
1597
1753
|
const checkOverlap = async (): Promise<number | undefined> => {
|
|
1598
1754
|
const overlappingLandings: string[] = [];
|
|
@@ -1627,54 +1783,7 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1627
1783
|
});
|
|
1628
1784
|
}
|
|
1629
1785
|
hold = !!opts.hold || overlapDecision?.outcome === 'user-hold';
|
|
1630
|
-
|
|
1631
|
-
let overlapEvidenceAccepted = false;
|
|
1632
|
-
let ancestorResyncNeeded = false;
|
|
1633
|
-
if (pinned && overlapDecision?.outcome === 'unavailable' && opts.overlapEvidence !== undefined) {
|
|
1634
|
-
const ref = resolveRemoteBranchRef(run, cwd, base);
|
|
1635
|
-
const verdict = verifyOverlapEvidence({
|
|
1636
|
-
evidencePath: opts.overlapEvidence, pr: Number(opts.pr), expectedHead: opts.expectedHead!,
|
|
1637
|
-
remote: ref.remote, branch: ref.branch, cwd, run, readFile,
|
|
1638
|
-
reviewResultsDir: deps.reviewResultsDir ?? join(dirname(taskAgentStatePath()), 'review-results'),
|
|
1639
|
-
listDir: (dir) => readdirSync(dir), reviewMtime: (path) => statSync(path).mtimeMs,
|
|
1640
|
-
reviewRealPath: (path) => realpathSync(path), overlappingLandings,
|
|
1641
|
-
});
|
|
1642
|
-
overlapEvidenceAccepted = verdict.ok;
|
|
1643
|
-
if (verdict.ok) {
|
|
1644
|
-
out.log(verdict.mode === 'already-ancestor'
|
|
1645
|
-
? `✓ overlap-evidence: already-ancestor — 겹친 최근 착지 ${overlappingLandings.length}개가 전부 head ${opts.expectedHead!.slice(0, 12)} 의 조상 · review pass must-fix 0 (${verdict.reviewResult})`
|
|
1646
|
-
: verdict.mode === 'base-advanced-disjoint'
|
|
1647
|
-
? `✓ overlap-evidence: base-advanced-disjoint — gate base ${verdict.gateBase.slice(0, 12)} ⊂ head ${opts.expectedHead!.slice(0, 12)} · ${ref.remote}/${ref.branch} ${verdict.baseTip.slice(0, 12)} 까지 ${verdict.windowCommits}개 커밋이 PR 파일을 안 건드린다 · review pass|warn must-fix 0 (${verdict.reviewResult})`
|
|
1648
|
-
: `✓ overlap-evidence: ${ref.remote}/${ref.branch} ${verdict.baseTip.slice(0, 12)} ⊂ head ${opts.expectedHead!.slice(0, 12)} · gate passed on that base · review pass must-fix 0 (${verdict.reviewResult})`);
|
|
1649
|
-
}
|
|
1650
|
-
else refuse(`✗ overlap-evidence: ${verdict.reason}`);
|
|
1651
|
-
} else if (pinned && overlapDecision?.outcome === 'unavailable') {
|
|
1652
|
-
// 증거 파일이 없을 때 — 겹친 착지가 전부 머리의 조상이고 표준 자리의 리뷰가 pass|warn ⊕ must-fix 0 이면 통과(아니면 종전 거부).
|
|
1653
|
-
const verdict = verifyAncestorAutoPass({
|
|
1654
|
-
pr: Number(opts.pr), expectedHead: opts.expectedHead!, cwd, run, readFile, overlappingLandings,
|
|
1655
|
-
reviewResultsDir: deps.reviewResultsDir ?? join(dirname(taskAgentStatePath()), 'review-results'),
|
|
1656
|
-
listDir: (dir) => readdirSync(dir),
|
|
1657
|
-
});
|
|
1658
|
-
overlapEvidenceAccepted = verdict.ok;
|
|
1659
|
-
if (verdict.ok) {
|
|
1660
|
-
out.log(`✓ overlap-evidence: already-ancestor-auto — 겹친 최근 착지 ${overlappingLandings.length}개가 전부 head ${opts.expectedHead!.slice(0, 12)} 의 조상 · review pass|warn must-fix 0 (${verdict.reviewResult})`);
|
|
1661
|
-
}
|
|
1662
|
-
else {
|
|
1663
|
-
refuse(`✗ ancestor-auto: ${verdict.reason}`);
|
|
1664
|
-
ancestorResyncNeeded = verdict.reason.startsWith('ancestor-auto-not-ancestor:');
|
|
1665
|
-
}
|
|
1666
|
-
}
|
|
1667
|
-
if (pinned && overlapDecision && overlapDecision.outcome !== 'user-merge' && !overlapEvidenceAccepted) {
|
|
1668
|
-
// A clean GitHub PR can still be behind a recently landed overlapping head. Preserve the cue
|
|
1669
|
-
// across hosts; the current steward tick acts only if it can also prove local run ownership.
|
|
1670
|
-
if (ancestorResyncNeeded && !opts.dryRun) {
|
|
1671
|
-
const marked = run('gh', ['pr', 'edit', String(opts.pr), '--add-label', PR_LABEL_NAMES.needsRebase], { cwd });
|
|
1672
|
-
record('resync-marker', marked.ok, { pr: Number(opts.pr), reason: 'ancestor-auto-not-ancestor' });
|
|
1673
|
-
if (!marked.ok) out.error('⚠ resync-marker: needs-rebase 라벨을 남기지 못했습니다');
|
|
1674
|
-
}
|
|
1675
|
-
out.error('✗ expected-head: overlap merge approval unavailable for the reviewed head');
|
|
1676
|
-
return 1;
|
|
1677
|
-
}
|
|
1786
|
+
if (pinned && !verifyPinnedOverlapDecision({ opts, deps, run, cwd, base, readFile, overlappingLandings, decision: overlapDecision?.outcome, out, refuse })) return 1;
|
|
1678
1787
|
return undefined;
|
|
1679
1788
|
};
|
|
1680
1789
|
if (pinned && (await checkOverlap()) !== undefined) return 1;
|
|
@@ -1724,6 +1833,18 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1724
1833
|
verifiedHeavyBase = main;
|
|
1725
1834
|
out.log(`✓ heavy-remote: host=${verdict.host ?? 'unknown'} head=${opts.expectedHead!.slice(0, 12)} main=${main.slice(0, 12)} source=${verdict.source} elapsed=${verdict.elapsedMs}ms`);
|
|
1726
1835
|
out.log(`✓ typecheck-roots: ${JSON.stringify(verdict.rootPlan ?? { mode: 'not-applicable', roots: null, promoted: false, reason: 'no-root-plan-in-gate-output' })}`);
|
|
1836
|
+
if (opts.heavyOnPodShadow) {
|
|
1837
|
+
await runHeavyOnPodShadow({
|
|
1838
|
+
enabled: true, pr: Number(opts.pr), head: opts.expectedHead!,
|
|
1839
|
+
local: { measured: verdict.rootPlan != null, ok: verdict.ok, rootPlan: verdict.rootPlan ?? null },
|
|
1840
|
+
runPod: async () => {
|
|
1841
|
+
const runPod = deps.runLandingPodShadow ?? (await import('./pr-land-pod-shadow-job.js')).runLandingPodShadowJob;
|
|
1842
|
+
return runPod({ head: opts.expectedHead!, main });
|
|
1843
|
+
},
|
|
1844
|
+
log: (category, event, data) => debug.log(category, event, { ...data, main, phase: 'initial' }),
|
|
1845
|
+
warn: (message) => out.error(`⚠ heavy-on-pod-shadow: ${message}`),
|
|
1846
|
+
});
|
|
1847
|
+
}
|
|
1727
1848
|
}
|
|
1728
1849
|
// Call immediately before the first mergePrOutcome and again before every UNKNOWN retry.
|
|
1729
1850
|
// A move during the wait is the same race as a move during the gate: rerun or fail closed.
|
|
@@ -1751,7 +1872,12 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1751
1872
|
};
|
|
1752
1873
|
const recheckOverlapAtBase = async (currentBase: string): Promise<number | undefined> => {
|
|
1753
1874
|
if (currentBase === overlapCheckedBase) return undefined;
|
|
1754
|
-
|
|
1875
|
+
const refreshedPaths = currentChangePaths(run, cwd, staged, base, out, true);
|
|
1876
|
+
if (refreshedPaths === null) {
|
|
1877
|
+
out.error('✗ overlap-preflight: 움직인 base의 PR 변경 파일을 읽지 못했다. 재게이트하지 않는다.');
|
|
1878
|
+
return 1;
|
|
1879
|
+
}
|
|
1880
|
+
changedPaths = refreshedPaths;
|
|
1755
1881
|
const refused = await checkOverlap();
|
|
1756
1882
|
if (refused !== undefined) return refused;
|
|
1757
1883
|
overlapCheckedBase = currentBase;
|
|
@@ -2294,6 +2420,36 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
2294
2420
|
|
|
2295
2421
|
export function registerPrCommands(program: Command, deps: PrLandDeps = {}, queueDeps: L8ShadowQueueDeps = {}): void {
|
|
2296
2422
|
const pr = program.command('pr').description('PR landing commands');
|
|
2423
|
+
const prToolRun = deps.run ?? defaultCmdRunner;
|
|
2424
|
+
const prToolOut = deps.out ?? liveOut;
|
|
2425
|
+
const prToolExit = deps.setExitCode ?? ((code: number) => { process.exitCode = code; });
|
|
2426
|
+
pr.command('census')
|
|
2427
|
+
.description('열린 PR 전체·골 문서만·2일 무커밋 draft·미닫힌 superseded 집계')
|
|
2428
|
+
.option('--cwd <path>', '저장소 경로')
|
|
2429
|
+
.action((opts: { cwd?: string }) => {
|
|
2430
|
+
const result = censusOpenPrs(readOpenPrs(prToolRun, { cwd: opts.cwd, includeDraftCommitDates: true }));
|
|
2431
|
+
prToolOut.log(JSON.stringify(result));
|
|
2432
|
+
if (result.status === 'unknown') prToolExit(1);
|
|
2433
|
+
});
|
|
2434
|
+
pr.command('open-guard')
|
|
2435
|
+
.description('새 PR 전에 같은 파일 OPEN PR·골 문서만·자리별 상한 검사')
|
|
2436
|
+
.option('--cwd <path>', '작업 트리 경로')
|
|
2437
|
+
.option('--base <ref>', '비교 base ref', 'origin/main')
|
|
2438
|
+
.option('--seat <seat>', 'PR 소유 자리(OP|TC|MK|UX)')
|
|
2439
|
+
.option('--cell <id>', '릴리스 칸 id (같은 칸 OPEN PR 검사)')
|
|
2440
|
+
.option('--seat-cap <number>', '자리별 열린 PR 경고 상한', '30')
|
|
2441
|
+
.action((opts: { cwd?: string; base: string; seat?: string; cell?: string; seatCap: string }) => {
|
|
2442
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
2443
|
+
const diff = prToolRun('git', ['-C', cwd, 'diff', '--name-only', '-z', `${opts.base}...HEAD`]);
|
|
2444
|
+
const files = diff.ok ? diff.out.split('\0').filter(Boolean) : null;
|
|
2445
|
+
const patch = prToolRun('git', ['-C', cwd, 'diff', '--unified=0', `${opts.base}...HEAD`]);
|
|
2446
|
+
const inventory = readOpenPrs(prToolRun, { cwd, ...(files ? { candidateFiles: files } : {}) });
|
|
2447
|
+
const result = guardNewPr({ files: patch.ok ? files : null, seat: opts.seat as Seat | undefined, seatCap: Number(opts.seatCap), cellId: opts.cell, hunks: patch.ok ? parseDiffHunks(patch.out) : undefined }, inventory);
|
|
2448
|
+
// Inspection never spends the three-creation unmeasured allowance.
|
|
2449
|
+
// Only pr-manager records an actual new-PR attempt in that ledger.
|
|
2450
|
+
prToolOut.log(JSON.stringify(result));
|
|
2451
|
+
if (result.status !== 'allow') prToolExit(1);
|
|
2452
|
+
});
|
|
2297
2453
|
const queue = pr.command('queue').description('Shadow merge queue (never lands PRs)');
|
|
2298
2454
|
const queueAction = async (action: () => Promise<unknown>) => {
|
|
2299
2455
|
try {
|
|
@@ -2314,6 +2470,7 @@ export function registerPrCommands(program: Command, deps: PrLandDeps = {}, queu
|
|
|
2314
2470
|
.option('--pr <number>', '기존 PR 번호 고정 (--expected-head 와 함께)')
|
|
2315
2471
|
.option('--expected-head <sha>', '리뷰된 PR 머리 SHA 고정 (--pr 와 함께)')
|
|
2316
2472
|
.option('--heavy-remote', '머리 고정 착지의 무거운 게이트를 node-b·node-c 중 빈 호스트에서 실행; head⊕main 증거가 없거나 실패하면 거부(로컬 폴백 없음)')
|
|
2473
|
+
.option('--heavy-on-pod-shadow', '--heavy-remote 판정을 유지하고 같은 head/main의 Pod 타입·변경 시험 결과를 비교만 한다')
|
|
2317
2474
|
.option('--dry-run', '변경 없이 landing 계획만 출력')
|
|
2318
2475
|
.option('--hold', 'PR을 생성 또는 갱신한 뒤 병합하지 않고 쌓아 둔다')
|
|
2319
2476
|
.option('--title <title>', 'PR title')
|
|
@@ -5,7 +5,7 @@ import { randomBytes } from 'node:crypto';
|
|
|
5
5
|
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
6
6
|
import { getUserConfig } from '../user-config.js';
|
|
7
7
|
import { debug, redactSecretText } from '../debug/log.js';
|
|
8
|
-
import { realGateRemoteRunner, resolveGateRemoteSettings, runOnRemote, type GateRemoteRunner, type RemoteRunOutcome } from '../self-implement/gate-remote.js';
|
|
8
|
+
import { gateRemoteHostCap, realGateRemoteRunner, resolveGateRemoteSettings, runOnRemote, type GateRemoteRunner, type RemoteRunOutcome } from '../self-implement/gate-remote.js';
|
|
9
9
|
|
|
10
10
|
const SHA = /^[0-9a-f]{40}$/i;
|
|
11
11
|
// WSL is excluded until its push permissions and gate environment are proven stable.
|
|
@@ -179,7 +179,7 @@ export function ensurePrLandHeavyRemote(input: HeavyRemoteInput, deps: HeavyRemo
|
|
|
179
179
|
try {
|
|
180
180
|
outcome = (deps.runRemote ?? runOnRemote)({
|
|
181
181
|
repo: input.repo, host, mirror: settings.mirror, commit: input.head,
|
|
182
|
-
refs: [input.main], hostCap: settings
|
|
182
|
+
refs: [input.main], hostCap: gateRemoteHostCap(settings, host), installPwa: true, stableCheckout: true,
|
|
183
183
|
// Test the tree GitHub will merge: scratch-checkout the reviewed head, merge the pinned main tip there,
|
|
184
184
|
// then run typecheck and self gate (changed tests and PWA reach/build) at that exact pair.
|
|
185
185
|
// The detached integration commit stays on the selected host and never changes the PR branch.
|