elanous 0.2.29 → 0.2.32
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 → IVKr3AlRUVLKsw2fh7eXF}/_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-98b64172bc1efe77.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/69-0a2c8209c6d4a158.js +1 -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-9530c03bcc550f02.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-504204b58c82c253.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-a27b1e5a0d1b308f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.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-3dcc1fa411e1f4e0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-32866485913d6a04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-8c66a3b24a745630.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.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-c219f2ed171131be.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-04d00ae9b0890349.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.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/b5d88eba78a3d7bf.css +1 -0
- 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 +26 -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/implement-loop.yaml +5 -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 +63 -10
- 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/measure-si-task-cpu.ts +143 -0
- package/scripts/ratchets/test-interference-patterns.allowlist.txt +255 -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/prepare-node.ts +102 -4
- 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 +65 -8
- package/src/acp/elanous-extensions.ts +3 -0
- package/src/acp/server.ts +3 -0
- package/src/acp/tool-trace.ts +186 -11
- package/src/ad-pipeline/run.ts +4 -2
- package/src/agent/runner.ts +169 -3
- package/src/agent/self-ambient-cache.ts +156 -0
- package/src/agent/self-ambient.ts +8 -1
- package/src/agent/subagent-callable.ts +3 -2
- package/src/agent/task-notification.ts +5 -0
- 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 +14 -0
- package/src/agent-substrate/self-review-cli.ts +30 -4
- package/src/ask-user-question/tool.ts +22 -0
- package/src/autopilot/build/llm-conflict-merge.ts +56 -10
- package/src/autopilot/pr-manager.ts +80 -7
- package/src/briefing/brief-items.ts +24 -22
- package/src/capture/frame-state-detect.ts +39 -0
- package/src/capture/tui-self-report.ts +149 -6
- package/src/chat/chat-cli.ts +10 -2
- package/src/chat/index.ts +138 -26
- package/src/chat/input-control-key.ts +5 -3
- package/src/chat/pickers/modal-runtime.ts +6 -0
- package/src/chat/pickers/modals.ts +8 -2
- 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/ask-bare.ts +1 -0
- package/src/cli/config-audit.ts +123 -0
- package/src/cli/decisions-cli.ts +80 -6
- package/src/cli/import-cli.ts +12 -0
- package/src/cli/log-event-names.ts +17 -0
- package/src/cli/mcp-login.ts +21 -5
- package/src/cli/msg-cli.ts +89 -0
- package/src/cli/pod-cli.ts +14 -3
- package/src/cli/pr-cli.ts +273 -81
- package/src/cli/pr-land-base-read.ts +34 -0
- package/src/cli/pr-land-heavy-remote.ts +82 -26
- package/src/cli/pr-land-overlap-evidence.ts +109 -11
- package/src/cli/pr-land-pod-shadow-job.ts +106 -0
- package/src/cli/pr-land-pod-shadow.ts +16 -3
- package/src/cli/pr-land-refusal.ts +20 -5
- package/src/cli/pr-land-virtual-rebase.ts +108 -0
- package/src/cli/pty-takeover-cli.ts +88 -14
- 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/sim-cli.ts +18 -0
- 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 +79 -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 +2 -0
- package/src/core-turn/run-goal-loop.ts +243 -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 +6 -0
- package/src/dashboard/acp-active-model.ts +42 -1
- package/src/dashboard/acp-boot.ts +3 -0
- package/src/dashboard/background-jobs-status.ts +66 -0
- package/src/dashboard/index.ts +339 -657
- package/src/dashboard/input/agent-wake.ts +242 -0
- package/src/dashboard/input/chat-main-entry-runtime.ts +6 -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 +49 -9
- package/src/dashboard/input/internal-turn.ts +261 -0
- package/src/dashboard/input/mouse-wiring.ts +108 -11
- package/src/dashboard/input/seat-autowake.ts +318 -0
- package/src/dashboard/input/turn-steer-bridge.ts +70 -0
- package/src/dashboard/log-click-runtime.ts +118 -2
- 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/dashboard/turn-preamble.ts +116 -40
- package/src/dashboard/turn-session-layers.ts +4 -2
- package/src/dashboard/turn-start-segments.ts +222 -0
- package/src/decisions/decision-ledger.ts +45 -4
- package/src/discord-self-message.ts +4 -4
- package/src/display/prompt-row-owner.ts +146 -0
- package/src/display/resize-listener.ts +33 -2
- package/src/domains/release-tool.ts +18 -1
- package/src/field-note/transcribe.ts +17 -0
- package/src/fold-stack.ts +4 -2
- package/src/git-fs/index.ts +263 -36
- 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/gate-reserve.ts +87 -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 +70 -20
- package/src/harness/harness-pod-dispatch.ts +87 -10
- package/src/harness/harness-queue.ts +68 -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 +156 -27
- package/src/input/external-input-queue.ts +64 -7
- package/src/intake-plane/slash.ts +14 -3
- package/src/keybindings.ts +4 -1
- package/src/llm/route-decision.ts +36 -0
- package/src/llm/tool-loop-steered-rejection.ts +41 -0
- package/src/llm-request-shape.ts +209 -0
- package/src/llm.ts +301 -283
- 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 +88 -12
- 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/maturity/feature-maturity.ts +1 -1
- 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/mss/logging/render-categories.ts +5 -0
- 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/overview.ts +59 -2
- 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 +303 -0
- package/src/pr-tool/inflight-registry.ts +143 -0
- package/src/prompt-library/chat-conciseness.ts +13 -0
- package/src/prompt-library/universal-preamble.ts +10 -5
- package/src/pty-shell/pty-manifest.ts +12 -3
- package/src/pty-shell/tui-run-state.ts +34 -3
- 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 +5 -1
- package/src/self-dev/ask-launch-flow.ts +37 -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 +267 -33
- 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 +56 -1
- package/src/self-dev/shard-run.ts +207 -12
- 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/elanous-tui-spawn.ts +14 -0
- package/src/self-implement/expose-gate.ts +2 -1
- package/src/self-implement/follow-up-placement.ts +79 -0
- package/src/self-implement/gate-artifacts.ts +416 -0
- package/src/self-implement/gate-baseline.ts +96 -5
- package/src/self-implement/gate-cli.ts +207 -17
- package/src/self-implement/gate-remote.ts +136 -26
- 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 +97 -7
- package/src/self-implement/orchestrator.ts +115 -134
- 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 +162 -15
- 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/index.ts +22 -267
- package/src/session-runtime/parallel-dispatch.ts +22 -5
- package/src/shell-runner/background-surface.ts +15 -5
- package/src/skills/tools/agent.ts +39 -6
- package/src/skills/tools/dev-harness.ts +6 -4
- package/src/skills/tools/list-dir.ts +11 -0
- package/src/skills/tools/schedule-wakeup.ts +408 -0
- package/src/skills/tools/shell.ts +246 -4
- package/src/status/bar.ts +26 -0
- package/src/steward/digest-delivery.ts +118 -0
- package/src/steward/hold-hygiene.ts +120 -0
- package/src/steward/resync-tick.ts +114 -23
- package/src/steward/ta-repair-event-collect.ts +158 -0
- package/src/steward/triage.ts +10 -0
- package/src/surface/shell-runner-boot.ts +5 -2
- 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 +182 -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 +151 -37
- 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 +118 -6
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +1 -1
- 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-pool.ts +3 -1
- package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
- package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +67 -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-pod.ts +525 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runner.ts +90 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +362 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +138 -19
- package/src/telegram.ts +2 -4
- package/src/tui/chat/execution-badge.ts +5 -1
- package/src/tui/input/pickers.ts +732 -0
- package/src/tui/input-lag-probe.ts +230 -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 +52 -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/scenario.ts +255 -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/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/botlab/page-a5635eba0d73b84e.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/chat-ui/page-9f92737b8766009a.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/css/72becfd42807b50d.css +0 -1
- /package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → IVKr3AlRUVLKsw2fh7eXF}/_ssgManifest.js +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isGateSpawnLaneFile } from './spawn-lane-files.js';
|
|
2
|
+
|
|
1
3
|
export interface GateTestShard {
|
|
2
4
|
id: string;
|
|
3
5
|
files: string[];
|
|
@@ -5,6 +7,35 @@ export interface GateTestShard {
|
|
|
5
7
|
plannedSeconds: number;
|
|
6
8
|
}
|
|
7
9
|
|
|
10
|
+
/** A requested shard count cannot hold the measured files; more shards may make the same plan valid. */
|
|
11
|
+
export class GateShardCapacityError extends Error {
|
|
12
|
+
constructor(message: string) { super(message); this.name = 'Error'; }
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Keep real child/PTY tests out of ordinary self-gate shards, within the caller's shard budget. */
|
|
16
|
+
export function planSelfGateSpawnSeparatedShards(
|
|
17
|
+
files: readonly string[],
|
|
18
|
+
rssMb: ReadonlyMap<string, number>,
|
|
19
|
+
seconds: ReadonlyMap<string, number>,
|
|
20
|
+
budgetGiB: number,
|
|
21
|
+
shardCount: number,
|
|
22
|
+
): GateTestShard[] {
|
|
23
|
+
const unique = [...new Set(files)];
|
|
24
|
+
const spawn = unique.filter(isGateSpawnLaneFile);
|
|
25
|
+
const regular = unique.filter((file) => !isGateSpawnLaneFile(file));
|
|
26
|
+
if (!spawn.length || !regular.length) return planGateTestShards(unique, rssMb, seconds, budgetGiB, shardCount);
|
|
27
|
+
if (shardCount < 2) throw new GateShardCapacityError('self gate spawn lane needs at least two shards when regular and spawn tests coexist');
|
|
28
|
+
// Three spawn bundles are the normal lane width, not a memory ceiling. A 5 GiB spawn file cannot share an 8 GiB
|
|
29
|
+
// bundle with another such file; retain lane isolation while allowing the measured plan to grow past three.
|
|
30
|
+
const neededSpawn = planGateTestShards(spawn, rssMb, seconds, budgetGiB).length;
|
|
31
|
+
const spawnCount = Math.min(spawn.length, shardCount - 1, Math.max(3, neededSpawn));
|
|
32
|
+
const planned = [
|
|
33
|
+
...planGateTestShards(regular, rssMb, seconds, budgetGiB, shardCount - spawnCount),
|
|
34
|
+
...planGateTestShards(spawn, rssMb, seconds, budgetGiB, spawnCount),
|
|
35
|
+
];
|
|
36
|
+
return planned.map((shard, index) => ({ ...shard, id: `shard-${index + 1}` }));
|
|
37
|
+
}
|
|
38
|
+
|
|
8
39
|
/** RSS values are the per-file rss_mb observations; the budget is in GiB (1 GiB = 1024 MB here). */
|
|
9
40
|
export function planGateTestShards(
|
|
10
41
|
files: readonly string[],
|
|
@@ -42,7 +73,7 @@ export function planGateTestShards(
|
|
|
42
73
|
if (!shard) {
|
|
43
74
|
const totalRssMb = sorted.reduce((sum, candidate) => sum + rssMb.get(candidate)!, 0);
|
|
44
75
|
const largestRssMb = rssMb.get(sorted[0]!)!;
|
|
45
|
-
throw new
|
|
76
|
+
throw new GateShardCapacityError(`test files exceed ${shardCount} shard memory budgets (files=${unique.length} · totalRssMb=${Math.round(totalRssMb)} · largestRssMb=${Math.round(largestRssMb)} · budgetMb=${capacity} · neededShards≥${Math.ceil(totalRssMb / capacity)})`);
|
|
46
77
|
}
|
|
47
78
|
shard.files.push(file);
|
|
48
79
|
shard.plannedRssMb += rss;
|
|
@@ -50,3 +81,27 @@ export function planGateTestShards(
|
|
|
50
81
|
}
|
|
51
82
|
return shards;
|
|
52
83
|
}
|
|
84
|
+
|
|
85
|
+
/** OP FU (LAND-TRAIN-LIVE side) — opt-in `--fixed-shard-distribution`: no RSS/seconds measurement. Files are deduplicated,
|
|
86
|
+
* sorted by code point (input-order independent) and dealt round-robin into at most `shardCount` shards; real child/PTY
|
|
87
|
+
* tests keep their own lane exactly like the measured planner. Not a memory-safety guarantee — an over-budget shard
|
|
88
|
+
* surfaces as its own run result (signal/exit/incomplete JUnit ⇒ unmeasured), never as a pass. No empty shards. */
|
|
89
|
+
export function planFixedGateTestShards(files: readonly string[], shardCount: number): GateTestShard[] {
|
|
90
|
+
if (!Number.isSafeInteger(shardCount) || shardCount < 1) throw new Error('invalid shard count');
|
|
91
|
+
const sorted = [...new Set(files)].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
92
|
+
const deal = (subset: readonly string[], count: number): string[][] => {
|
|
93
|
+
const buckets: string[][] = Array.from({ length: Math.min(count, subset.length) }, () => []);
|
|
94
|
+
subset.forEach((file, index) => buckets[index % buckets.length]!.push(file));
|
|
95
|
+
return buckets;
|
|
96
|
+
};
|
|
97
|
+
const spawn = sorted.filter(isGateSpawnLaneFile);
|
|
98
|
+
const regular = sorted.filter((file) => !isGateSpawnLaneFile(file));
|
|
99
|
+
let groups: string[][];
|
|
100
|
+
if (!spawn.length || !regular.length) groups = deal(sorted, shardCount);
|
|
101
|
+
else {
|
|
102
|
+
if (shardCount < 2) throw new Error('self gate spawn lane needs at least two shards when regular and spawn tests coexist');
|
|
103
|
+
const spawnCount = Math.min(3, spawn.length, shardCount - 1);
|
|
104
|
+
groups = [...deal(regular, shardCount - spawnCount), ...deal(spawn, spawnCount)];
|
|
105
|
+
}
|
|
106
|
+
return groups.map((group, index) => ({ id: `shard-${index + 1}`, files: group, plannedRssMb: 0, plannedSeconds: 0 }));
|
|
107
|
+
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { existsSync, mkdtempSync, readFileSync, rmSync, statSync } from 'node:fs';
|
|
2
|
-
import { tmpdir } from 'node:os';
|
|
1
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statfsSync, statSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { availableParallelism, freemem, tmpdir } from 'node:os';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { debug, redactSecretText } from '../debug/log.js';
|
|
5
5
|
import { prepareDeterministicChildEnvironment } from '../../scripts/lib/deterministic-env.js';
|
|
6
|
+
import { withGateTestEnv } from '../../scripts/lib/gate-test-env.js';
|
|
6
7
|
import { withBaselineWorktree } from '../self-implement/gate-baseline.js';
|
|
7
8
|
import { aggregateGateTestShards, type GateShardAttempt, type GateShardAggregate } from './shard-aggregate.js';
|
|
8
|
-
import {
|
|
9
|
+
import { GateShardCapacityError, planFixedGateTestShards, planSelfGateSpawnSeparatedShards, type GateTestShard } from './shard-plan.js';
|
|
10
|
+
import { isGateSpawnLaneFile } from './spawn-lane-files.js';
|
|
9
11
|
|
|
10
12
|
export interface ShardRunResult {
|
|
11
13
|
aggregate: GateShardAggregate;
|
|
@@ -13,6 +15,70 @@ export interface ShardRunResult {
|
|
|
13
15
|
attempts: GateShardAttempt[];
|
|
14
16
|
reason?: string;
|
|
15
17
|
measurementFailures?: number;
|
|
18
|
+
/** The measured RSS plan needed more bundles than the requested count. */
|
|
19
|
+
expandedFrom?: number;
|
|
20
|
+
/** A fixed plan selected explicitly, or after the measured plan exceeds host expansion capacity. */
|
|
21
|
+
distribution?: 'fixed' | 'fixed-cap-fallback';
|
|
22
|
+
fallbackReason?: string;
|
|
23
|
+
/** OP FU (MK #8178 shard-9) — raw evidence of every failed shard process (exit≠0 · signal · no JUnit). Observation only:
|
|
24
|
+
* the aggregate never reads it. Absent = no shard process reported failure output. */
|
|
25
|
+
failureEvidence?: ShardFailureEvidence[];
|
|
26
|
+
/** Latest failed attempt's reason for each incomplete shard; copied into the gate artifact summary. */
|
|
27
|
+
unmeasuredByShard?: Record<string, string>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** What a failed shard process leaves behind so «test failure vs runner error» can be told apart after the fact. */
|
|
31
|
+
export interface ShardFailureOutput {
|
|
32
|
+
durationMs: number;
|
|
33
|
+
/** Last 64KB of the child's stdout/stderr (redacted). */
|
|
34
|
+
stdoutTail: string;
|
|
35
|
+
stderrTail: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ShardFailureEvidence extends ShardFailureOutput {
|
|
39
|
+
shardId: string;
|
|
40
|
+
side: 'current' | 'baseline';
|
|
41
|
+
attempt: number;
|
|
42
|
+
files: string[];
|
|
43
|
+
exitCode: number | null;
|
|
44
|
+
signal: string | null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface ShardRunMode {
|
|
48
|
+
/** OP FU — sorted round-robin into `count` shards, zero pre-measurement runs. Default off: the measured planner. */
|
|
49
|
+
fixedDistribution?: boolean;
|
|
50
|
+
/** Measured on the executing host; override only for deterministic planning tests. */
|
|
51
|
+
hostResources?: { cores: number; freeMemoryGiB: number; freeTmpGiB: number };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function hostResources(): ShardRunMode['hostResources'] | undefined {
|
|
55
|
+
try {
|
|
56
|
+
const tmp = statfsSync(tmpdir());
|
|
57
|
+
// Linux page cache is reclaimable. `freemem()` alone saw only ~10 GiB on a WSL host
|
|
58
|
+
// with 24 GiB MemAvailable and would incorrectly cap a two-shard plan at one.
|
|
59
|
+
let freeMemoryGiB = freemem() / (1024 ** 3);
|
|
60
|
+
if (process.platform === 'linux') {
|
|
61
|
+
const availableKiB = /^MemAvailable:\s+(\d+)\s+kB/m.exec(readFileSync('/proc/meminfo', 'utf8'))?.[1];
|
|
62
|
+
if (availableKiB) freeMemoryGiB = Number(availableKiB) / (1024 ** 2);
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
cores: availableParallelism(),
|
|
66
|
+
freeMemoryGiB,
|
|
67
|
+
freeTmpGiB: Number(tmp.bavail) * Number(tmp.bsize) / (1024 ** 3),
|
|
68
|
+
};
|
|
69
|
+
} catch { return undefined; }
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** One expansion slot needs one CPU, one shard memory budget, and 1 GiB of free tmp space.
|
|
73
|
+
* Explicitly requested shards remain the caller's choice; this only limits automatic growth. */
|
|
74
|
+
export function maxAutomaticShardCount(requested: number, budgetGiB: number, resources: ShardRunMode['hostResources']): number {
|
|
75
|
+
if (!resources || !Number.isFinite(budgetGiB) || budgetGiB <= 0) return requested;
|
|
76
|
+
const limit = Math.min(
|
|
77
|
+
Math.floor(resources.cores),
|
|
78
|
+
Math.floor(resources.freeMemoryGiB / budgetGiB),
|
|
79
|
+
Math.floor(resources.freeTmpGiB),
|
|
80
|
+
);
|
|
81
|
+
return Math.max(requested, Number.isFinite(limit) ? limit : requested);
|
|
16
82
|
}
|
|
17
83
|
|
|
18
84
|
export type ShardProcess = (cwd: string, files: readonly string[]) => {
|
|
@@ -23,8 +89,37 @@ export type ShardProcess = (cwd: string, files: readonly string[]) => {
|
|
|
23
89
|
seconds?: number;
|
|
24
90
|
/** Bounded, redacted process output for an abnormal exit before JUnit exists. */
|
|
25
91
|
diagnostic?: string;
|
|
92
|
+
/** Present only when the process failed (exit≠0 · signal · no JUnit) — observation only, never part of the verdict. */
|
|
93
|
+
failure?: ShardFailureOutput;
|
|
26
94
|
};
|
|
27
95
|
|
|
96
|
+
export const SHARD_FAILURE_TAIL_BYTES = 64 * 1024;
|
|
97
|
+
|
|
98
|
+
function outputTail(bytes: Uint8Array | undefined): string {
|
|
99
|
+
if (!bytes?.length) return '';
|
|
100
|
+
const tail = bytes.length > SHARD_FAILURE_TAIL_BYTES ? bytes.subarray(bytes.length - SHARD_FAILURE_TAIL_BYTES) : bytes;
|
|
101
|
+
return redactSecretText(Buffer.from(tail).toString('utf8'));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** `<shardId>.failure.json` per failed shard (shard ids are already `shard-<n>`). Top level = the latest current-side
|
|
105
|
+
* failure (else the latest baseline one); `failures` keeps every failed side/attempt. Returns the written paths. */
|
|
106
|
+
export function writeShardFailureEvidence(dir: string, evidence: readonly ShardFailureEvidence[]): string[] {
|
|
107
|
+
if (!evidence.length) return [];
|
|
108
|
+
mkdirSync(dir, { recursive: true });
|
|
109
|
+
const byShard = new Map<string, ShardFailureEvidence[]>();
|
|
110
|
+
for (const item of evidence) byShard.set(item.shardId, [...(byShard.get(item.shardId) ?? []), item]);
|
|
111
|
+
const written: string[] = [];
|
|
112
|
+
for (const [shardId, failures] of byShard) {
|
|
113
|
+
const primary = [...failures].reverse().find((item) => item.side === 'current') ?? failures[failures.length - 1]!;
|
|
114
|
+
const path = join(dir, `${shardId.replace(/[^A-Za-z0-9._-]/g, '_')}.failure.json`);
|
|
115
|
+
const { side, attempt, ...fields } = primary;
|
|
116
|
+
writeFileSync(path, `${JSON.stringify({ ...fields, side, attempt, failures }, null, 2)}\n`);
|
|
117
|
+
debug.log('self-dev.shard', 'failure-evidence', { shardId, path, failures: failures.length, exitCode: primary.exitCode, signal: primary.signal });
|
|
118
|
+
written.push(path);
|
|
119
|
+
}
|
|
120
|
+
return written;
|
|
121
|
+
}
|
|
122
|
+
|
|
28
123
|
const DIAGNOSTIC_STREAM_LIMIT = 240;
|
|
29
124
|
|
|
30
125
|
function boundedDiagnostic(stdout: Uint8Array, stderr: Uint8Array): string | undefined {
|
|
@@ -56,8 +151,17 @@ export function runShardedGateTests(
|
|
|
56
151
|
run: ShardProcess = runBunShard,
|
|
57
152
|
baselineWorktree: typeof withBaselineWorktree = withBaselineWorktree,
|
|
58
153
|
budgetGiB = 8,
|
|
154
|
+
mode: ShardRunMode = {},
|
|
59
155
|
): ShardRunResult {
|
|
60
156
|
if (!Number.isSafeInteger(count) || count < 1) throw new Error('invalid --shards count');
|
|
157
|
+
if (mode.fixedDistribution) {
|
|
158
|
+
// Opt-in: no per-file pre-measurement at all — the shard runs themselves (JUnit · rc · signal · baseline) decide.
|
|
159
|
+
let fixed: GateTestShard[];
|
|
160
|
+
try { fixed = planFixedGateTestShards(files, count); }
|
|
161
|
+
catch (error) { return { aggregate: { status: 'unmeasured', retryShardIds: [] }, shards: [], attempts: [], reason: String(error), distribution: 'fixed' }; }
|
|
162
|
+
debug.log('self-dev.shard', 'fixed-distribution', { shards: fixed.length, files: fixed.reduce((sum, shard) => sum + shard.files.length, 0) });
|
|
163
|
+
return { ...runPlannedShards(cwd, fixed, baseRef, run, baselineWorktree), distribution: 'fixed' };
|
|
164
|
+
}
|
|
61
165
|
const rss = new Map<string, number>();
|
|
62
166
|
const seconds = new Map<string, number>();
|
|
63
167
|
const failedMeasurements: string[] = [];
|
|
@@ -88,13 +192,61 @@ export function runShardedGateTests(
|
|
|
88
192
|
}
|
|
89
193
|
}
|
|
90
194
|
const measurementFailures = failedMeasurements.length || undefined;
|
|
91
|
-
|
|
195
|
+
const fixedAtHostCap = (maxCount: number, reason: string): ShardRunResult => {
|
|
196
|
+
try {
|
|
197
|
+
const fixed = planFixedGateTestShards(files, maxCount);
|
|
198
|
+
debug.log('self-dev.shard', 'host-cap-fixed-fallback', { requested: count, cap: maxCount,
|
|
199
|
+
files: new Set(files).size, reason, measurementFailures: measurementFailures ?? 0 });
|
|
200
|
+
return { ...runPlannedShards(cwd, fixed, baseRef, run, baselineWorktree), distribution: 'fixed-cap-fallback',
|
|
201
|
+
fallbackReason: reason, ...(measurementFailures ? { measurementFailures } : {}) };
|
|
202
|
+
} catch (error) {
|
|
203
|
+
return { aggregate: { status: 'unmeasured', retryShardIds: [] }, shards: [], attempts: [],
|
|
204
|
+
reason: `host-cap fixed fallback failed: ${String(error)}; measured plan: ${reason}`,
|
|
205
|
+
...(measurementFailures ? { measurementFailures } : {}) };
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
let shards: GateTestShard[] | undefined;
|
|
209
|
+
let plannedCount = count;
|
|
92
210
|
try {
|
|
93
|
-
|
|
211
|
+
const fileCount = new Set(files).size;
|
|
212
|
+
const totalRss = [...rss.values()].reduce((sum, value) => sum + value, 0);
|
|
213
|
+
const lowerBound = Number.isFinite(budgetGiB) && budgetGiB > 0 ? Math.ceil(totalRss / (budgetGiB * 1024)) : count;
|
|
214
|
+
plannedCount = Math.max(count, Math.min(fileCount, lowerBound));
|
|
215
|
+
// The requested count may exceed the number of files. Only expansion is bounded by file count.
|
|
216
|
+
const maxCount = Math.max(count, Math.min(fileCount, maxAutomaticShardCount(count, budgetGiB, mode.hostResources ?? hostResources())));
|
|
217
|
+
if (plannedCount > maxCount) return fixedAtHostCap(maxCount, `host shard expansion cap ${maxCount} < needed ${plannedCount} (requested ${count}, measured RSS sum ${Math.round(totalRss)} MiB, budget ${budgetGiB} GiB)`);
|
|
218
|
+
for (; plannedCount <= maxCount; plannedCount++) {
|
|
219
|
+
try { shards = planSelfGateSpawnSeparatedShards(files, rss, seconds, budgetGiB, plannedCount); break; }
|
|
220
|
+
catch (error) {
|
|
221
|
+
if (!(error instanceof GateShardCapacityError)) throw error;
|
|
222
|
+
if (plannedCount === maxCount) return fixedAtHostCap(maxCount, `host shard expansion cap ${maxCount} < needed ≥${maxCount + 1} (requested ${count}, ${error.message})`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
94
225
|
} catch (error) {
|
|
95
226
|
return { aggregate: { status: 'unmeasured', retryShardIds: [] }, shards: [], attempts: [], reason: String(error), ...(measurementFailures ? { measurementFailures } : {}) };
|
|
96
227
|
}
|
|
228
|
+
if (!shards) return { aggregate: { status: 'unmeasured', retryShardIds: [] }, shards: [], attempts: [], reason: 'shard planning produced no result' };
|
|
229
|
+
if (plannedCount > count) debug.log('self-dev.shard', 'plan-expanded', {
|
|
230
|
+
requested: count, planned: shards.length, files: new Set(files).size, budgetGiB,
|
|
231
|
+
measurementFailures: measurementFailures ?? 0,
|
|
232
|
+
});
|
|
233
|
+
return { ...runPlannedShards(cwd, shards, baseRef, run, baselineWorktree), ...(plannedCount > count ? { expandedFrom: count } : {}), ...(measurementFailures ? { measurementFailures } : {}) };
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** Shared by the measured and the fixed planner: current + baseline per shard, one retry round, one aggregate. */
|
|
237
|
+
function runPlannedShards(
|
|
238
|
+
cwd: string,
|
|
239
|
+
shards: GateTestShard[],
|
|
240
|
+
baseRef: string,
|
|
241
|
+
run: ShardProcess,
|
|
242
|
+
baselineWorktree: typeof withBaselineWorktree,
|
|
243
|
+
): ShardRunResult {
|
|
97
244
|
const attempts: GateShardAttempt[] = [];
|
|
245
|
+
const failureEvidence: ShardFailureEvidence[] = [];
|
|
246
|
+
const keepFailure = (shardId: string, side: ShardFailureEvidence['side'], attempt: number, files: readonly string[], result: ReturnType<ShardProcess>) => {
|
|
247
|
+
if (!result.failure) return;
|
|
248
|
+
failureEvidence.push({ shardId, side, attempt, files: [...files], exitCode: result.exitCode, signal: result.signal ?? null, ...result.failure });
|
|
249
|
+
};
|
|
98
250
|
const baseline = baselineWorktree(cwd, baseRef, (dir) => {
|
|
99
251
|
// LIGHT-RC-MEASURE ① — bun silently skips a path that is not in the baseline tree (exit 0), so a shard holding a
|
|
100
252
|
// new test file could never yield a complete baseline JUnit. Run the baseline side on the files the base has; an
|
|
@@ -114,6 +266,8 @@ export function runShardedGateTests(
|
|
|
114
266
|
}
|
|
115
267
|
const current = runSafely(cwd, shard.files);
|
|
116
268
|
const base = baselineFiles.length ? runSafely(dir, baselineFiles) : { exitCode: 0 };
|
|
269
|
+
keepFailure(shard.id, 'current', round, shard.files, current);
|
|
270
|
+
keepFailure(shard.id, 'baseline', round, baselineFiles, base);
|
|
117
271
|
attempts.push({
|
|
118
272
|
shardId: shard.id, attempt: round,
|
|
119
273
|
currentJUnit: current.junit, baselineJUnit: base.junit,
|
|
@@ -128,22 +282,62 @@ export function runShardedGateTests(
|
|
|
128
282
|
}
|
|
129
283
|
return aggregateGateTestShards(shards, attempts);
|
|
130
284
|
});
|
|
131
|
-
|
|
132
|
-
|
|
285
|
+
const evidence = failureEvidence.length ? { failureEvidence } : {};
|
|
286
|
+
if ('retryShardIds' in baseline) return {
|
|
287
|
+
aggregate: baseline, shards, attempts, ...evidence,
|
|
288
|
+
...(baseline.retryShardIds.length ? { unmeasuredByShard: incompleteShardReasons(baseline.retryShardIds, attempts) } : {}),
|
|
289
|
+
};
|
|
290
|
+
const retryShardIds = shards.map((shard) => shard.id);
|
|
291
|
+
return {
|
|
292
|
+
aggregate: { status: 'unmeasured', retryShardIds }, shards, attempts, reason: baseline.log, ...evidence,
|
|
293
|
+
unmeasuredByShard: Object.fromEntries(retryShardIds.map((id) => [id, `baseline worktree: ${redactSecretText(baseline.log).replace(/[\r\n\t\x00-\x1f\x7f]+/g, ' ').slice(0, 500)}`])),
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function incompleteShardReasons(shardIds: readonly string[], attempts: readonly GateShardAttempt[]): Record<string, string> {
|
|
298
|
+
return Object.fromEntries(shardIds.map((id) => {
|
|
299
|
+
const latest = attempts.filter((attempt) => attempt.shardId === id).at(-1);
|
|
300
|
+
if (!latest) return [id, 'no shard attempt recorded'];
|
|
301
|
+
const side = (name: string, rc: number | null, signal: string | null | undefined, junit: string | undefined, diagnostic: string | undefined): string => {
|
|
302
|
+
const safeDiagnostic = diagnostic ? redactSecretText(diagnostic).replace(/[\r\n\t\x00-\x1f\x7f]+/g, ' ').slice(0, 500) : undefined;
|
|
303
|
+
return `${name}: exit ${rc ?? 'unavailable'}, signal ${signal ?? 'none'}, JUnit ${junit === undefined ? 'missing' : 'present'}`
|
|
304
|
+
+ (safeDiagnostic ? `; ${safeDiagnostic}` : '');
|
|
305
|
+
};
|
|
306
|
+
const statuses = [
|
|
307
|
+
side('current', latest.currentExitCode, latest.currentSignal, latest.currentJUnit, latest.currentDiagnostic),
|
|
308
|
+
...(latest.baselineFiles?.length === 0 ? [] : [side('baseline', latest.baselineExitCode, latest.baselineSignal, latest.baselineJUnit, latest.baselineDiagnostic)]),
|
|
309
|
+
];
|
|
310
|
+
return [id, `${statuses.join(' · ')} · aggregate rejected (incomplete, malformed JUnit, or exit/JUnit mismatch)`];
|
|
311
|
+
}));
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export function selfGateShardTimeoutMs(files: readonly string[]): number {
|
|
315
|
+
const spawnFiles = files.filter(isGateSpawnLaneFile);
|
|
316
|
+
if (spawnFiles.length && spawnFiles.length !== files.length) throw new Error('self gate spawn lane mixed with regular tests');
|
|
317
|
+
return spawnFiles.length ? 120_000 : 300_000;
|
|
133
318
|
}
|
|
134
319
|
|
|
135
320
|
export function runBunShard(cwd: string, files: readonly string[]): ReturnType<ShardProcess> {
|
|
321
|
+
return runBunShardWithSpawn(cwd, files, Bun.spawnSync);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/** Child launch seam for verifying the actual command and process timeout. */
|
|
325
|
+
export function runBunShardWithSpawn(cwd: string, files: readonly string[], spawn: typeof Bun.spawnSync): ReturnType<ShardProcess> {
|
|
326
|
+
const timeout = selfGateShardTimeoutMs(files);
|
|
327
|
+
const spawnLane = timeout === 120_000;
|
|
136
328
|
const dir = mkdtempSync(join(tmpdir(), 'elanous-shard-junit-'));
|
|
137
329
|
const report = join(dir, 'result.xml');
|
|
138
|
-
const isolated = prepareDeterministicChildEnvironment('elanous-shard-test-env-');
|
|
330
|
+
const isolated = prepareDeterministicChildEnvironment('elanous-shard-test-env-', { env: withGateTestEnv(process.env) });
|
|
139
331
|
try {
|
|
140
332
|
const measured = files.length === 1;
|
|
141
|
-
const args = ['test', '--reporter=junit', `--reporter-outfile=${report}`, ...files];
|
|
333
|
+
const args = ['test', ...(spawnLane ? ['--timeout=120000'] : []), '--reporter=junit', `--reporter-outfile=${report}`, ...files];
|
|
142
334
|
const started = performance.now();
|
|
143
|
-
const result =
|
|
144
|
-
cwd, env: isolated.env, stdout: 'pipe', stderr: 'pipe', timeout
|
|
335
|
+
const result = spawn(['bun', ...args], {
|
|
336
|
+
cwd, env: isolated.env, stdout: 'pipe', stderr: 'pipe', timeout,
|
|
145
337
|
});
|
|
338
|
+
const durationMs = performance.now() - started;
|
|
146
339
|
const junit = existsSync(report) ? readFileSync(report, 'utf8') : undefined;
|
|
340
|
+
const failed = result.exitCode !== 0 || !!result.signalCode || junit === undefined;
|
|
147
341
|
return {
|
|
148
342
|
exitCode: result.exitCode,
|
|
149
343
|
signal: result.signalCode ? String(result.signalCode) : undefined,
|
|
@@ -151,7 +345,8 @@ export function runBunShard(cwd: string, files: readonly string[]): ReturnType<S
|
|
|
151
345
|
...(junit === undefined && (result.exitCode !== 0 || result.signalCode)
|
|
152
346
|
? { diagnostic: boundedDiagnostic(result.stdout, result.stderr) } : {}),
|
|
153
347
|
rssMb: measured ? result.resourceUsage.maxRSS / (1024 * 1024) : undefined,
|
|
154
|
-
seconds: measured ?
|
|
348
|
+
seconds: measured ? durationMs / 1000 : undefined,
|
|
349
|
+
...(failed ? { failure: { durationMs: Math.round(durationMs), stdoutTail: outputTail(result.stdout), stderrTail: outputTail(result.stderr) } } : {}),
|
|
155
350
|
};
|
|
156
351
|
} finally {
|
|
157
352
|
isolated.cleanup();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Real child/PTY test files. This list is shared by release and self gates. */
|
|
2
|
+
export const GATE_SPAWN_LANE_FILES = [
|
|
3
|
+
'scripts/lib/tui-runshell-group-e2e.test.ts',
|
|
4
|
+
'scripts/lib/tui-streaming-e2e.test.ts',
|
|
5
|
+
'src/agent-mission/doc-guided-install.test.ts',
|
|
6
|
+
'src/dashboard/first-screen-band-wiring.test.ts',
|
|
7
|
+
'src/git-fs/spawn-discipline.test.ts',
|
|
8
|
+
'src/self-implement/run-ledger.test.ts',
|
|
9
|
+
'src/video-pipeline/recipes/reframe.test.ts',
|
|
10
|
+
'test/ch5730-watch-delivery.test.ts',
|
|
11
|
+
'test/cli-dev-command.test.ts',
|
|
12
|
+
'test/preview-terminal.test.ts',
|
|
13
|
+
] as const;
|
|
14
|
+
|
|
15
|
+
const SPAWN_FILES: ReadonlySet<string> = new Set(GATE_SPAWN_LANE_FILES);
|
|
16
|
+
|
|
17
|
+
export function isGateSpawnLaneFile(file: string): boolean {
|
|
18
|
+
return SPAWN_FILES.has(file);
|
|
19
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { execFile as execFileCb } from 'node:child_process';
|
|
2
2
|
import { promisify } from 'node:util';
|
|
3
3
|
import { debug } from '../debug/log.js';
|
|
4
|
+
import { runGithubRemoteCall } from '../github/remote-call.js';
|
|
4
5
|
import { releaseGitDiffPaths, releasePrFilePaths } from '../self-dev/release-path-guard.js';
|
|
5
6
|
|
|
6
7
|
const defaultExecFile = promisify(execFileCb);
|
|
@@ -33,6 +34,25 @@ const GH_APP_CALLERS = {
|
|
|
33
34
|
|
|
34
35
|
export type GhAppCaller = keyof typeof GH_APP_CALLERS;
|
|
35
36
|
|
|
37
|
+
/** Fixed routes keep `--body`, `-f body=…`, labels, and tokens out of both log categories. */
|
|
38
|
+
const GH_APP_ROUTES: Record<GhAppCaller, string> = {
|
|
39
|
+
'post-pr-comment-history': 'repos/{owner}/{repo}/issues/:number/comments',
|
|
40
|
+
'post-pr-comment': 'pr/:number/comment',
|
|
41
|
+
'find-pr-comment': 'repos/{owner}/{repo}/issues/:number/comments',
|
|
42
|
+
'edit-pr-comment': 'repos/{owner}/{repo}/issues/comments/:id',
|
|
43
|
+
'add-pr-label-list': 'label/list',
|
|
44
|
+
'add-pr-label-create': 'label/create',
|
|
45
|
+
'add-pr-label': 'pr/:number/edit',
|
|
46
|
+
'read-pr-files': 'repos/{owner}/{repo}/pulls/:number/files',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
function observedGhMethod(args: readonly string[]): string | undefined {
|
|
50
|
+
if (args[0] !== 'api') return undefined; // gh pr/label may choose REST or GraphQL internally
|
|
51
|
+
const at = args.indexOf('--method');
|
|
52
|
+
const value = at >= 0 ? args[at + 1] : undefined;
|
|
53
|
+
return value && /^(GET|POST|PUT|PATCH|DELETE)$/.test(value) ? value : undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
36
56
|
export const APP_API_RATE_LIMIT_RETRY_CAP_MS = 15 * 60_000;
|
|
37
57
|
|
|
38
58
|
export class AppApiRateLimitError extends Error {
|
|
@@ -83,14 +103,32 @@ export async function waitForAppApiRateLimitReset(
|
|
|
83
103
|
export async function runGhApp(
|
|
84
104
|
caller: GhAppCaller,
|
|
85
105
|
args: readonly string[],
|
|
86
|
-
opts: { cwd: string; encoding: 'utf8'; timeout: number; maxBuffer?: number; env: NodeJS.ProcessEnv },
|
|
106
|
+
opts: { cwd: string; encoding: 'utf8'; timeout: number; maxBuffer?: number; env: NodeJS.ProcessEnv; retry?: number },
|
|
87
107
|
): Promise<{ stdout: string; stderr: string }> {
|
|
108
|
+
const { retry, ...execOpts } = opts;
|
|
88
109
|
let stdout = '';
|
|
89
110
|
let stderr = '';
|
|
90
111
|
let status: number | undefined;
|
|
91
112
|
let error: unknown;
|
|
92
113
|
try {
|
|
93
|
-
const result = await
|
|
114
|
+
const result = await runGithubRemoteCall({
|
|
115
|
+
kind: args[0] === 'api' ? 'rest' : 'gh-command',
|
|
116
|
+
caller: GH_APP_CALLERS[caller],
|
|
117
|
+
route: GH_APP_ROUTES[caller],
|
|
118
|
+
method: observedGhMethod(args),
|
|
119
|
+
host: 'unmeasured', // gh may select the repo host even when GH_HOST is set
|
|
120
|
+
runId: opts.env.ELANOUS_RUN_ID,
|
|
121
|
+
retry,
|
|
122
|
+
}, () => execFileImpl('gh', args, execOpts), {
|
|
123
|
+
status: ({ failed, error: callError }) => {
|
|
124
|
+
if (!failed) return undefined; // gh exit 0 is not an observed HTTP 200
|
|
125
|
+
const raw = (callError as { stderr?: unknown })?.stderr;
|
|
126
|
+
const failureStderr = typeof raw === 'string' ? raw : '';
|
|
127
|
+
const header = ghHeader(failureStderr, 'HTTP') ?? ghHeader(failureStderr, 'status');
|
|
128
|
+
const code = header ? Number.parseInt(header, 10) : NaN;
|
|
129
|
+
return Number.isFinite(code) ? code : undefined;
|
|
130
|
+
},
|
|
131
|
+
});
|
|
94
132
|
stdout = result.stdout;
|
|
95
133
|
stderr = result.stderr ?? '';
|
|
96
134
|
status = 200;
|
|
@@ -102,12 +140,14 @@ export async function runGhApp(
|
|
|
102
140
|
status = ghStatusCode(stderr, caught);
|
|
103
141
|
}
|
|
104
142
|
const remaining = ghHeader(stderr, 'X-RateLimit-Remaining');
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
143
|
+
try {
|
|
144
|
+
debug.log('github.app-api', 'call', {
|
|
145
|
+
caller: GH_APP_CALLERS[caller],
|
|
146
|
+
endpoint: GH_APP_ROUTES[caller],
|
|
147
|
+
status: status ?? 0,
|
|
148
|
+
remaining: remaining ?? '',
|
|
149
|
+
});
|
|
150
|
+
} catch { /* observation cannot replace the gh result or its original error */ }
|
|
111
151
|
if (error) {
|
|
112
152
|
const text = `${stderr}\n${error instanceof Error ? error.message : String(error)}`;
|
|
113
153
|
if (isAppApiRateLimitFailure(status, text, remaining)) {
|
|
@@ -138,7 +178,7 @@ export async function readPrFilesWithRateLimitFallback(input: {
|
|
|
138
178
|
`repos/{owner}/{repo}/pulls/${input.number}/files`,
|
|
139
179
|
];
|
|
140
180
|
const ghOpts = { cwd: input.cwd, encoding: 'utf8' as const, timeout: GIT_TIMEOUT, maxBuffer: 64 * 1024 * 1024, env };
|
|
141
|
-
const fromApi = async () => releasePrFilePaths(JSON.parse((await runGhApp('read-pr-files', endpoint, ghOpts)).stdout));
|
|
181
|
+
const fromApi = async (retry: number) => releasePrFilePaths(JSON.parse((await runGhApp('read-pr-files', endpoint, { ...ghOpts, retry })).stdout));
|
|
142
182
|
const fromGit = async (): Promise<string[]> => {
|
|
143
183
|
const base = input.base ?? 'origin/main';
|
|
144
184
|
const { stdout } = await execFileImpl('git', ['diff', '--find-renames', '--name-status', '-z', `${base}...HEAD`], {
|
|
@@ -147,7 +187,7 @@ export async function readPrFilesWithRateLimitFallback(input: {
|
|
|
147
187
|
return releaseGitDiffPaths(stdout);
|
|
148
188
|
};
|
|
149
189
|
try {
|
|
150
|
-
return await fromApi();
|
|
190
|
+
return await fromApi(0);
|
|
151
191
|
} catch (error) {
|
|
152
192
|
if (!(error instanceof AppApiRateLimitError)) throw error;
|
|
153
193
|
try {
|
|
@@ -156,7 +196,7 @@ export async function readPrFilesWithRateLimitFallback(input: {
|
|
|
156
196
|
const waited = await waitForAppApiRateLimitReset(error.resetAtMs, input.now?.() ?? Date.now(), input.sleep);
|
|
157
197
|
if (!waited) throw error;
|
|
158
198
|
try {
|
|
159
|
-
return await fromApi();
|
|
199
|
+
return await fromApi(1);
|
|
160
200
|
} catch (retryError) {
|
|
161
201
|
if (retryError instanceof AppApiRateLimitError) throw retryError;
|
|
162
202
|
throw gitError;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
// 셸 검사는 `zsh -n`/`bash -n`(구문만·미실행). JSON/TOML 은 인-프로세스 파싱(외부 프로세스 불필요).
|
|
9
9
|
|
|
10
10
|
import { spawnSync } from 'node:child_process';
|
|
11
|
+
import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
|
|
11
12
|
import { readFileSync } from 'node:fs';
|
|
12
13
|
import { basename } from 'node:path';
|
|
13
14
|
|
|
@@ -32,7 +33,7 @@ export function runConfigSyntaxGate(filePath: string): ConfigGateResult {
|
|
|
32
33
|
const isBash = /(^|\.)(bashrc|bash_profile|bash_login|profile|bash_aliases)$/.test(name) || name.endsWith('.bash') || name.endsWith('.sh');
|
|
33
34
|
if (isZsh || isBash) {
|
|
34
35
|
const shell = isZsh ? 'zsh' : 'bash';
|
|
35
|
-
const r = spawnSync(shell, ['-n', filePath], { encoding: 'utf8', timeout: SHELL_TIMEOUT_MS });
|
|
36
|
+
const r = spawnSync(shell, ['-n', filePath], { encoding: 'utf8', timeout: SHELL_TIMEOUT_MS, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
|
|
36
37
|
// 셸 미설치(status=null·ENOENT) → 검사 불가로 skip(차단 아님·HITL diff 로 검증).
|
|
37
38
|
if (r.error || r.status === null) return { passed: true, checked: false, label: `${shell} -n (미설치)`, log: String(r.error?.message ?? 'shell 없음') };
|
|
38
39
|
return { passed: r.status === 0, checked: true, label: `${shell} -n`, log: `${r.stdout ?? ''}${r.stderr ?? ''}`.slice(-2000) };
|
|
@@ -13,6 +13,10 @@ import { selfDevRunsDir } from '../self-dev/run-store.js';
|
|
|
13
13
|
import { syncTestConfig } from '../cli/config-test-sync.js';
|
|
14
14
|
import { debug } from '../debug/log.js';
|
|
15
15
|
|
|
16
|
+
/** = `PREAMBLE_SYNC_BLOCK_ENV`(dashboard/turn-preamble.ts). 그 모듈을 끌어오지 않으려 이름만 둔다 —
|
|
17
|
+
* 같은 값인지는 elanous-tui-spawn-identity.test.ts 가 잡는다. */
|
|
18
|
+
export const PREAMBLE_SYNC_BLOCK_ENV = 'ELANOUS_TEST_PREAMBLE_SYNC_BLOCK_MS';
|
|
19
|
+
|
|
16
20
|
export interface ElanousTuiSpawnOptions {
|
|
17
21
|
readonly repoRoot: string;
|
|
18
22
|
readonly cwd: string;
|
|
@@ -138,6 +142,13 @@ export function elanousTuiSpawnOptions(opts: ElanousTuiSpawnOptions): StartOpts
|
|
|
138
142
|
}
|
|
139
143
|
const { runId } = resolveRunIdentity({ explicit: opts.runId, inherited: opts.space.runId });
|
|
140
144
|
const debugLevel = process.env.ELANOUS_DEBUG_LEVEL;
|
|
145
|
+
// ⭐ PTY 는 기동 때 잡은 로그인 셸 env 위에 «여기 적은 키만» 얹는다(registry `buildPtyEnv`) —
|
|
146
|
+
// 부모에 건 시험 seam env 는 적어 주지 않으면 자식에 안 닿는다(run-fbe85b7c · 자식 env 실측).
|
|
147
|
+
// 격리 자식에만 넘긴다. 자식도 운영 우주면 무시한다(`preambleSyncBlockMs`).
|
|
148
|
+
const preambleSyncBlock = isolated ? process.env[PREAMBLE_SYNC_BLOCK_ENV]?.trim() : undefined;
|
|
149
|
+
if (preambleSyncBlock) {
|
|
150
|
+
debug.log('self-implement.elanous-tui-spawn', 'test-seam-env', { name: PREAMBLE_SYNC_BLOCK_ENV, value: preambleSyncBlock });
|
|
151
|
+
}
|
|
141
152
|
const controller = opts.controller ?? deriveChildController(process.env, process.pid);
|
|
142
153
|
const channels = 'pty,inbox';
|
|
143
154
|
debug.log('self-implement.elanous-tui-spawn', 'controller', { controller, channels });
|
|
@@ -149,6 +160,8 @@ export function elanousTuiSpawnOptions(opts: ElanousTuiSpawnOptions): StartOpts
|
|
|
149
160
|
],
|
|
150
161
|
accessMode: 'auto',
|
|
151
162
|
transitionPolicy: 'open',
|
|
163
|
+
// 안 넘길 때는 로그인 셸 캡처본에 그 변수가 있어도 지운다 — 비격리 자식에 seam 이 새지 않게.
|
|
164
|
+
...(preambleSyncBlock ? {} : { unsetEnv: [PREAMBLE_SYNC_BLOCK_ENV] }),
|
|
152
165
|
// ⭐ 대표 2026-08-02 — 자식 화면 기본 **160×40**. 가상 PTY라 사람 터미널과 무관하고,
|
|
153
166
|
// 좁으면 렌더 블록이 화면을 넘어 **관측이 잘린다**(그 실측이 `--cols/--rows` 를 열게 했다).
|
|
154
167
|
cols: opts.cols ?? 160,
|
|
@@ -164,6 +177,7 @@ export function elanousTuiSpawnOptions(opts: ElanousTuiSpawnOptions): StartOpts
|
|
|
164
177
|
ELANOUS_CONTROL_CHANNELS: channels,
|
|
165
178
|
...observeOnlyFlagEnv(opts.observeOnly),
|
|
166
179
|
...(debugLevel === undefined ? {} : { ELANOUS_DEBUG_LEVEL: debugLevel }),
|
|
180
|
+
...(preambleSyncBlock ? { [PREAMBLE_SYNC_BLOCK_ENV]: preambleSyncBlock } : {}),
|
|
167
181
|
...childRunContextEnv('self-build'),
|
|
168
182
|
...childNestEnv(),
|
|
169
183
|
...harnessSpaceEnv(opts.space.kind, opts.space.id, runId),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
|
|
2
3
|
import { debug } from '../debug/log.js';
|
|
3
4
|
|
|
4
5
|
type ExposeMode = 'warn' | 'strict';
|
|
@@ -15,7 +16,7 @@ export function runExposeGate(
|
|
|
15
16
|
changed: readonly string[],
|
|
16
17
|
mode: ExposeMode,
|
|
17
18
|
run: (command: string, args: string[], cwd: string) => ProcessResult = (command, args, dir) => {
|
|
18
|
-
const result = spawnSync(command, args, { cwd: dir, encoding: 'utf8', timeout: 300_000 });
|
|
19
|
+
const result = spawnSync(command, args, { cwd: dir, encoding: 'utf8', timeout: 300_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
|
|
19
20
|
return { status: result.status, stdout: result.stdout ?? '', stderr: result.stderr ?? '', error: result.error };
|
|
20
21
|
},
|
|
21
22
|
): ExposeResult {
|