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
|
@@ -201,6 +201,7 @@ export class DashboardSession {
|
|
|
201
201
|
dispatchTool: opts.dispatchTool,
|
|
202
202
|
...(opts.onTurnComplete ? { onTurnComplete: opts.onTurnComplete } : {}),
|
|
203
203
|
...(opts.resolveModel ? { resolveModel: opts.resolveModel } : {}),
|
|
204
|
+
...(opts.resolveSeat ? { resolveSeat: opts.resolveSeat } : {}),
|
|
204
205
|
...(opts.resolveMaxToolTurns
|
|
205
206
|
? { resolveMaxToolTurns: opts.resolveMaxToolTurns }
|
|
206
207
|
: {}),
|
|
@@ -467,6 +468,14 @@ export class DashboardSession {
|
|
|
467
468
|
this.sessionId = newSessionId;
|
|
468
469
|
}
|
|
469
470
|
|
|
471
|
+
/** TUI-H8 ② — `/session new` 이 백엔드(ACP) 세션까지 새로 받는다. 같은 연결에서 `session/new` 를 다시 불러
|
|
472
|
+
* 새 id 로 갈아탄다(종전엔 TUI 기록만 비우고 ACP sessionId 가 그대로였다 · #69). 새 id 를 돌려준다. */
|
|
473
|
+
async renew(cwd: string): Promise<string> {
|
|
474
|
+
const { sessionId } = await this.client.newSession({ cwd, mcpServers: [] });
|
|
475
|
+
this.sessionId = sessionId;
|
|
476
|
+
return sessionId;
|
|
477
|
+
}
|
|
478
|
+
|
|
470
479
|
/** Send a single user prompt and await the turn's stopReason.
|
|
471
480
|
* Streaming text deltas and tool / usage events are delivered via
|
|
472
481
|
* the optional callbacks on `req`. */
|
package/src/tui.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import chalk from 'chalk';
|
|
6
6
|
import { StringDecoder } from 'node:string_decoder';
|
|
7
7
|
import { perf } from './perf-counters.js';
|
|
8
|
+
import { noteInputLagKey, noteInputLagPaint } from './tui/input-lag-probe.js';
|
|
8
9
|
import { debug } from './debug/log.js';
|
|
9
10
|
|
|
10
11
|
// ── ANSI escape sequences ──
|
|
@@ -523,6 +524,12 @@ const _keyQueue: Key[] = [];
|
|
|
523
524
|
export type KeyTraceSource = 'main' | 'stream' | 'input';
|
|
524
525
|
|
|
525
526
|
let _keyTracer: ((key: Key, source: KeyTraceSource) => void) | null = null;
|
|
527
|
+
let _lastHumanKeyAt = 0;
|
|
528
|
+
|
|
529
|
+
/** 마지막으로 배달된 사람 키 시각(ms · 0 = 아직 없음) — 내부 턴 문(H2)의 조용창 판정에 쓴다. */
|
|
530
|
+
export function lastHumanKeyAt(): number {
|
|
531
|
+
return _lastHumanKeyAt;
|
|
532
|
+
}
|
|
526
533
|
|
|
527
534
|
/** Install a tracer invoked with every dispatched Key. Set to null to
|
|
528
535
|
* detach. Exceptions thrown by the tracer are swallowed so a broken
|
|
@@ -534,6 +541,8 @@ export function setKeyTracer(fn: ((key: Key, source: KeyTraceSource) => void) |
|
|
|
534
541
|
/** Call the installed tracer, if any. Safe to invoke unconditionally —
|
|
535
542
|
* becomes a noop when no tracer is registered. */
|
|
536
543
|
export function traceKey(key: Key, source: KeyTraceSource): void {
|
|
544
|
+
// H2 내부 턴 문 — «마지막 사람 키» 시각. 빈 이름(readKey 취소·빈 깨움)·리스너 표지는 사람 키가 아니다.
|
|
545
|
+
if (key.name && !key.name.startsWith('listener-')) _lastHumanKeyAt = Date.now();
|
|
537
546
|
if (!_keyTracer) return;
|
|
538
547
|
try { _keyTracer(key, source); } catch { /* swallow — never break input */ }
|
|
539
548
|
}
|
|
@@ -903,6 +912,7 @@ export function readKey(source: KeyTraceSource = 'main'): Promise<Key> {
|
|
|
903
912
|
// split across chunk boundaries need a pending buffer that belongs
|
|
904
913
|
// to this stream alone.
|
|
905
914
|
const keys = _stdinParser.push(data);
|
|
915
|
+
if (keys.length > 0) noteInputLagKey(keys.length);
|
|
906
916
|
|
|
907
917
|
// 2026-04-30 — also drain `_keyQueue` here so an `injectKey`
|
|
908
918
|
// call that happened while `readKey` was already awaiting on
|
|
@@ -955,7 +965,9 @@ export function readKey(source: KeyTraceSource = 'main'): Promise<Key> {
|
|
|
955
965
|
* §8.6 — "(A) auto-Enter via injectKey" approach. */
|
|
956
966
|
export function injectKey(key: Key): boolean {
|
|
957
967
|
if (!_raw) return false;
|
|
968
|
+
noteInputLagKey();
|
|
958
969
|
_keyQueue.push(key);
|
|
970
|
+
_injectedKeys.add(key);
|
|
959
971
|
// Wake any in-flight readKey awaiting on stdin by emitting an empty
|
|
960
972
|
// chunk. The handler's queue-drain branch picks up the injected key
|
|
961
973
|
// immediately.
|
|
@@ -965,6 +977,38 @@ export function injectKey(key: Key): boolean {
|
|
|
965
977
|
return true;
|
|
966
978
|
}
|
|
967
979
|
|
|
980
|
+
/** `injectKey` 로 들어온 키 표지 — `takeInjectedKeys` 가 stdin 잔여 키(readKey 몫)는 두고 주입 키만 꺼낸다. */
|
|
981
|
+
const _injectedKeys = new WeakSet<Key>();
|
|
982
|
+
|
|
983
|
+
/** ⭐ TUI-ESC-ABORT-TOOLS (2026-10-15) — 턴 중 스트리밍 리스너(`attachStreamingKeys`)가
|
|
984
|
+
* 바깥에서 주입된 키(`pty key` · 제어 IPC input-key → `injectKey`)를 받게 큐에서 꺼낸다.
|
|
985
|
+
* ⛔ readKey 가 걸려 있으면(`_cancelReadKey`) 큐는 그 readKey 의 몫이다 — 빈 배열을 돌려준다.
|
|
986
|
+
* ⛔ stdin 청크 잔여 키(readKey 가 넣은 것)는 건드리지 않는다. readKey 의 drain 동작은 그대로다. */
|
|
987
|
+
export function takeInjectedKeys(): Key[] {
|
|
988
|
+
if (_cancelReadKey || _keyQueue.length === 0) return [];
|
|
989
|
+
const taken: Key[] = [];
|
|
990
|
+
for (let i = 0; i < _keyQueue.length; ) {
|
|
991
|
+
const k = _keyQueue[i]!;
|
|
992
|
+
if (_injectedKeys.has(k)) {
|
|
993
|
+
taken.push(k);
|
|
994
|
+
_keyQueue.splice(i, 1);
|
|
995
|
+
} else {
|
|
996
|
+
i += 1;
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
// 같은 Key 객체가 두 번 주입될 수 있으므로 표지는 다 꺼낸 «뒤에» 지운다.
|
|
1000
|
+
for (const k of taken) _injectedKeys.delete(k);
|
|
1001
|
+
return taken;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/** ⭐ H2 내부 턴 문 — 걸려 있는 readKey 를 «빈 키»로 깨운다(키를 만들지도 큐에 넣지도 않는다).
|
|
1005
|
+
* stdin 에 남은 바이트는 그대로 다음 readKey 몫이다. 걸린 readKey 가 없으면 false. */
|
|
1006
|
+
export function cancelPendingReadKey(): boolean {
|
|
1007
|
+
if (!_cancelReadKey) return false;
|
|
1008
|
+
_cancelReadKey();
|
|
1009
|
+
return true;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
968
1012
|
/** 아직 readKey 가 소비하지 않은 키 수 — 외부 입력 대기열이 «사용자 키보다 앞서» 끼어들지 않게 본다. */
|
|
969
1013
|
export function pendingKeyCount(): number {
|
|
970
1014
|
return _keyQueue.length;
|
|
@@ -997,6 +1041,13 @@ export function resetRenderCache(): void {
|
|
|
997
1041
|
_lastFrameCols = 0;
|
|
998
1042
|
}
|
|
999
1043
|
|
|
1044
|
+
/** True when the frame cache says `row` (0-based) currently shows
|
|
1045
|
+
* exactly `text` — a direct writer can skip repainting it. Invalidated
|
|
1046
|
+
* rows hold a sentinel that never matches. */
|
|
1047
|
+
export function renderCacheRowIs(row: number, text: string): boolean {
|
|
1048
|
+
return row >= 0 && row < _lastFrameLines.length && _lastFrameLines[row] === text;
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1000
1051
|
/** Invalidate a specific row in the frame cache without nuking the
|
|
1001
1052
|
* whole thing. Callers that do direct stdout writes to a narrow
|
|
1002
1053
|
* band (input prompt, cursor moves) use this instead of
|
|
@@ -1061,6 +1112,7 @@ export function render(lines: string[], opts: RenderOptions = {}): void {
|
|
|
1061
1112
|
}
|
|
1062
1113
|
perf.recordStdoutWrite(buf.length, true);
|
|
1063
1114
|
perf.markDrawEnd();
|
|
1115
|
+
noteInputLagPaint();
|
|
1064
1116
|
|
|
1065
1117
|
_lastFrameLines = lines.slice(0, lineCount);
|
|
1066
1118
|
_lastFrameRows = rows;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function parseGeminiServerTools(raw: unknown): { googleSearch?: boolean; codeExecution?: boolean; urlContext?: boolean } | undefined {
|
|
2
|
+
if (!raw || typeof raw !== 'object') return undefined;
|
|
3
|
+
const obj = raw as Record<string, unknown>;
|
|
4
|
+
const out: { googleSearch?: boolean; codeExecution?: boolean; urlContext?: boolean } = {};
|
|
5
|
+
if (obj.googleSearch === true) out.googleSearch = true;
|
|
6
|
+
if (obj.codeExecution === true) out.codeExecution = true;
|
|
7
|
+
if (obj.urlContext === true) out.urlContext = true;
|
|
8
|
+
return (Object.keys(out).length > 0) ? out : undefined;
|
|
9
|
+
}
|
package/src/user-config.ts
CHANGED
|
@@ -71,6 +71,7 @@ import { migrateLegacyXdgUserConfig } from './storage/legacy-elanous-config-migr
|
|
|
71
71
|
import { withFileLockSync } from './storage/file-lock.js';
|
|
72
72
|
import { debug } from './debug/log.js';
|
|
73
73
|
import { setConfigTimeZoneSource } from './time/format.js';
|
|
74
|
+
import { parseGeminiServerTools } from './user-config/gemini-server-tools.js';
|
|
74
75
|
import type { FoldMode } from './log-entry.js';
|
|
75
76
|
import {
|
|
76
77
|
CLAUDE_PACKAGE_MISSING,
|
|
@@ -85,6 +86,7 @@ import {
|
|
|
85
86
|
parseGroundingSources,
|
|
86
87
|
type GroundingConfig,
|
|
87
88
|
} from './grounding/sources.js';
|
|
89
|
+
import { parseSeatTurnCapConfig, type SeatTurnCapConfig } from './core-turn/seat-turn-cap.js';
|
|
88
90
|
|
|
89
91
|
// ── SkillRouter (existing) ───────────────────────────────────────────
|
|
90
92
|
|
|
@@ -1544,6 +1546,8 @@ export function parseErrorReportsConfig(raw: unknown): ErrorReportsConfig | unde
|
|
|
1544
1546
|
|
|
1545
1547
|
export interface ChatConfig {
|
|
1546
1548
|
factQuestion: { maxToolTurns: number };
|
|
1549
|
+
/** TUI-SEAT-TURN-CAP — 자리 TUI goal loop 한정 core 턴 상한 덮어쓰기(기본값 = core-turn/seat-turn-cap.ts). 설정했을 때만 있다. */
|
|
1550
|
+
seatTurnCap?: Partial<SeatTurnCapConfig>;
|
|
1547
1551
|
/** Short questions may receive a tool-free first reply. Default true. */
|
|
1548
1552
|
fastPath: boolean;
|
|
1549
1553
|
conciseness: ChatConcisenessConfig;
|
|
@@ -3656,6 +3660,8 @@ export interface OrchestratorLoopConfig {
|
|
|
3656
3660
|
seatCaps: Record<OrchestratorSeat, number>;
|
|
3657
3661
|
/** Max new delegations per tick; absent means no limit. */
|
|
3658
3662
|
maxDelegatePerTick?: number;
|
|
3663
|
+
/** Dispatch placement preference and local concurrency lane. Defaults preserve the existing Pod preference and one local lane. */
|
|
3664
|
+
dispatch: { podTarget: number; localLane: number };
|
|
3659
3665
|
/** Per-seat release gate; absent seats retain the spawn-budget default. */
|
|
3660
3666
|
releaseGate?: Partial<Record<OrchestratorSeat, number>>;
|
|
3661
3667
|
trafficMode: 'shadow' | 'live';
|
|
@@ -3673,7 +3679,7 @@ export interface OrchestratorLoopConfig {
|
|
|
3673
3679
|
}
|
|
3674
3680
|
|
|
3675
3681
|
export const ORCHESTRATOR_DEFAULTS: OrchestratorLoopConfig = {
|
|
3676
|
-
mode: 'shadow', seatTrees: {}, seatCaps: { TC: 8, UX: 6, MK: 6, OP: 4 }, trafficMode: 'shadow', idleRequest: 'shadow', finishGate: 'shadow',
|
|
3682
|
+
mode: 'shadow', seatTrees: {}, seatCaps: { TC: 8, UX: 6, MK: 6, OP: 4 }, dispatch: { podTarget: 18, localLane: 1 }, trafficMode: 'shadow', idleRequest: 'shadow', finishGate: 'shadow',
|
|
3677
3683
|
};
|
|
3678
3684
|
|
|
3679
3685
|
export function parseOrchestratorLoopConfig(raw: unknown): OrchestratorLoopConfig {
|
|
@@ -3696,7 +3702,14 @@ export function parseOrchestratorLoopConfig(raw: unknown): OrchestratorLoopConfi
|
|
|
3696
3702
|
}
|
|
3697
3703
|
const mode = value.mode === 'off' || value.mode === 'live' ? value.mode : 'shadow';
|
|
3698
3704
|
const maxDelegatePerTick = value.maxDelegatePerTick;
|
|
3699
|
-
|
|
3705
|
+
const rawDispatch = value.dispatch && typeof value.dispatch === 'object' && !Array.isArray(value.dispatch)
|
|
3706
|
+
? value.dispatch as Record<string, unknown> : {};
|
|
3707
|
+
const dispatch = { ...ORCHESTRATOR_DEFAULTS.dispatch };
|
|
3708
|
+
for (const field of ['podTarget', 'localLane'] as const) {
|
|
3709
|
+
const setting = rawDispatch[field];
|
|
3710
|
+
if (typeof setting === 'number' && Number.isSafeInteger(setting) && setting >= 0) dispatch[field] = setting;
|
|
3711
|
+
}
|
|
3712
|
+
return { mode, seatTrees, seatCaps, dispatch,
|
|
3700
3713
|
...(typeof maxDelegatePerTick === 'number' && Number.isSafeInteger(maxDelegatePerTick) && maxDelegatePerTick >= 0 ? { maxDelegatePerTick } : {}),
|
|
3701
3714
|
...(Object.keys(releaseGate).length ? { releaseGate } : {}),
|
|
3702
3715
|
trafficMode: value.trafficMode === 'live' ? 'live' : 'shadow',
|
|
@@ -3792,8 +3805,10 @@ export interface GateRemoteConfig {
|
|
|
3792
3805
|
host?: string;
|
|
3793
3806
|
/** Local 1-min load average above which checks go remote (default 20). */
|
|
3794
3807
|
loadThreshold?: number;
|
|
3795
|
-
/**
|
|
3808
|
+
/** Legacy default cap for hosts without an entry in hostCaps (1..2, default 2). */
|
|
3796
3809
|
hostCap?: number;
|
|
3810
|
+
/** Per SSH host concurrent heavy-check slots (1..8); overrides hostCap for that host. */
|
|
3811
|
+
hostCaps?: Record<string, number>;
|
|
3797
3812
|
/** Bare mirror on the host (default ~/mirror/elanous-agent.git — shared with the release gate). */
|
|
3798
3813
|
mirror?: string;
|
|
3799
3814
|
/** Seconds to wait for a free host slot before running locally (default 600). */
|
|
@@ -3811,6 +3826,12 @@ export function parseGateRemoteConfig(raw: unknown): GateRemoteConfig | undefine
|
|
|
3811
3826
|
if (typeof v === 'number' && Number.isFinite(v) && v >= 0) out[key] = v;
|
|
3812
3827
|
}
|
|
3813
3828
|
if (typeof r.hostCap === 'number' && Number.isSafeInteger(r.hostCap) && r.hostCap > 0 && r.hostCap <= 2) out.hostCap = r.hostCap;
|
|
3829
|
+
if (r.hostCaps && typeof r.hostCaps === 'object' && !Array.isArray(r.hostCaps)) {
|
|
3830
|
+
const caps = Object.fromEntries(Object.entries(r.hostCaps).filter(([host, cap]) =>
|
|
3831
|
+
/^(?:[\w.-]+@)?[\w.-]+$/.test(host) && !host.startsWith('-') &&
|
|
3832
|
+
typeof cap === 'number' && Number.isSafeInteger(cap) && cap >= 1 && cap <= 8)) as Record<string, number>;
|
|
3833
|
+
if (Object.keys(caps).length) out.hostCaps = caps;
|
|
3834
|
+
}
|
|
3814
3835
|
return Object.keys(out).length ? out : undefined;
|
|
3815
3836
|
}
|
|
3816
3837
|
|
|
@@ -3871,7 +3892,7 @@ export interface UserConfig {
|
|
|
3871
3892
|
guardian?: { mode?: 'shadow' | 'live'; /** Orphan CLI GC on the guardian tick: off = no ps collection, shadow (default) = evidence only, on = evidence then SIGTERM. */ orphanGc?: 'off' | 'shadow' | 'on' };
|
|
3872
3893
|
/** Task-agent live move allow-list (`src/task-agent/live-moves.ts` validates its vocabulary).
|
|
3873
3894
|
* Absent = env ELANOUS_TASK_AGENT_LIVE_MOVES, else none (pure shadow). */
|
|
3874
|
-
taskAgent?: { liveMoves?: string[]; /** TA-REJUDGE-PERIODIC — steward tick runs `tasks rejudge --all` every N minutes (absent/0 = off). */ rejudgeEveryMinutes?: number; /** 1-minute load average above which that tick is skipped (default 60). */ rejudgeMaxLoad?: number; /** TA-REPAIR-TICK-CAP — new repair launches per `tasks rejudge --all` (default 3, 0 = none). */ repairMaxPerTick?: number; parentHost?: { host?: string; cwd?: string; elanous?: string; configDir?: string; podPool?: string; approvalCapacity?: number } | Array<{ host?: string; cwd?: string; elanous?: string; configDir?: string; podPool?: string; approvalCapacity?: number }> };
|
|
3895
|
+
taskAgent?: { liveMoves?: string[]; /** TA-REJUDGE-PERIODIC — steward tick runs `tasks rejudge --all` every N minutes (absent/0 = off). */ rejudgeEveryMinutes?: number; /** 1-minute load average above which that tick is skipped (default 60). */ rejudgeMaxLoad?: number; /** TA-REPAIR-TICK-CAP — new repair launches per `tasks rejudge --all` (default 3, 0 = none). */ repairMaxPerTick?: number; /** TA-LAND-AFTER-REVIEW — opt-in external queue adapter, never a direct merge command. */ landQueue?: { command: string; remote: string }; parentHost?: { host?: string; cwd?: string; elanous?: string; configDir?: string; podPool?: string; approvalCapacity?: number } | Array<{ host?: string; cwd?: string; elanous?: string; configDir?: string; podPool?: string; approvalCapacity?: number }> };
|
|
3875
3896
|
events?: EventsConfig;
|
|
3876
3897
|
/** GATE-REMOTE — see GateRemoteConfig. Absent = defaults (auto on · node-b · load 20 · cap 2). */
|
|
3877
3898
|
gateRemote?: GateRemoteConfig;
|
|
@@ -3907,7 +3928,7 @@ export interface UserConfig {
|
|
|
3907
3928
|
followUp?: 'shadow' | 'live';
|
|
3908
3929
|
};
|
|
3909
3930
|
/** ☸️ Pod 실행 칸 — `pool` = 기존 기본 풀(`컨텍스트[@ssh호스트][:상한][#k3d-레지스트리:포트]` 쉼표 · 앞이 우선). harness 실행은 인자·ELANOUS_POD_POOL·harness.podPool 다음으로 읽는다. */
|
|
3910
|
-
pod?: { pool?: string; /** 호스트 Git 미러 디렉터리 — Pod Job 에 읽기 전용으로 마운트한다. */ hostMirror?: string; /** 원격 그라운딩 엔드포인트(호스트 nexus · tailnet 주소) — Pod 가 토큰으로 «질의→인용»만 묻는다(P13). */ groundingUrl?: string; /** 읽기 전용 Pod lease 권장에 쓰는 계정별 동시 수. */ lease?: { perAccount?: number }; /** 실측 권고를 Pod 발사 기본값으로 쓸지 (기본 off). */ memory?: { adviseDefaults?: boolean }; /** 명령 Job 자식 로그(child.log) 상한 바이트. 양의 정수만. 넘으면 끝부분 우선. */ childLogMaxBytes?: number };
|
|
3931
|
+
pod?: { pool?: string; /** 호스트 Git 미러 디렉터리 — Pod Job 에 읽기 전용으로 마운트한다. */ hostMirror?: string; /** 원격 그라운딩 엔드포인트(호스트 nexus · tailnet 주소) — Pod 가 토큰으로 «질의→인용»만 묻는다(P13). */ groundingUrl?: string; /** 읽기 전용 Pod lease 권장에 쓰는 계정별 동시 수. */ lease?: { perAccount?: number }; /** 실측 권고를 Pod 발사 기본값으로 쓸지 (기본 off). */ memory?: { adviseDefaults?: boolean }; /** 명령 Job 자식 로그(child.log) 상한 바이트. 양의 정수만. 넘으면 끝부분 우선. */ childLogMaxBytes?: number; /** warm Pod 재사용 실전 손잡이(소비자별 · 기본 off · 문자 그대로 true 만). 판정 = pod-warm-switch.ts `decideWarmReuse` — 증거가 모자라면 flag 가 켜져도 off. */ warmReuse?: { gateRecheck?: boolean; land?: boolean; ta?: boolean; /** 연속 일치 표본 하한(양의 정수 · 기본 3). */ minMatchSamples?: number } };
|
|
3911
3932
|
skillRouter: SkillRouterConfig;
|
|
3912
3933
|
llm: LLMConfig;
|
|
3913
3934
|
skills: SkillsConfig;
|
|
@@ -4195,7 +4216,21 @@ function parseTaskAgentConfig(raw: unknown): UserConfig['taskAgent'] {
|
|
|
4195
4216
|
if (Number.isSafeInteger(repairMaxPerTick) && (repairMaxPerTick as number) >= 0) rejudge.repairMaxPerTick = repairMaxPerTick as number;
|
|
4196
4217
|
else warnUserConfigDrop('taskAgent.repairMaxPerTick', `음이 아닌 정수가 아니다(${JSON.stringify(repairMaxPerTick)}) — 기본 3`);
|
|
4197
4218
|
}
|
|
4198
|
-
const
|
|
4219
|
+
const queueRaw = (raw as Record<string, unknown>).landQueue;
|
|
4220
|
+
let landQueue: { command: string; remote: string } | undefined;
|
|
4221
|
+
if (queueRaw !== undefined) {
|
|
4222
|
+
if (queueRaw && typeof queueRaw === 'object' && !Array.isArray(queueRaw)
|
|
4223
|
+
&& typeof (queueRaw as Record<string, unknown>).command === 'string'
|
|
4224
|
+
&& isAbsolute((queueRaw as Record<string, string>).command)
|
|
4225
|
+
&& typeof (queueRaw as Record<string, unknown>).remote === 'string'
|
|
4226
|
+
&& /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test((queueRaw as Record<string, string>).remote)) {
|
|
4227
|
+
landQueue = { command: (queueRaw as Record<string, string>).command, remote: (queueRaw as Record<string, string>).remote };
|
|
4228
|
+
} else {
|
|
4229
|
+
warnUserConfigDrop('taskAgent.landQueue', '절대 command 경로와 유효한 remote 호스트가 필요 — 착지 fail-closed');
|
|
4230
|
+
landQueue = { command: '', remote: '' };
|
|
4231
|
+
}
|
|
4232
|
+
}
|
|
4233
|
+
const extras = { ...rejudge, ...(parentHost ? { parentHost } : {}), ...(landQueue ? { landQueue } : {}) };
|
|
4199
4234
|
const liveMoves = (raw as Record<string, unknown>).liveMoves;
|
|
4200
4235
|
if (liveMoves === undefined) return Object.keys(extras).length ? extras : undefined;
|
|
4201
4236
|
// 설정이 «있으면» 환경 변수로 내려가지 않는다 — 배열이 아니면 빈 목록(fail-closed), 문자열 밖 항목은 글자로 바꿔 넘겨
|
|
@@ -5083,6 +5118,17 @@ export function buildUserConfig(path: string = defaultPath()): UserConfig {
|
|
|
5083
5118
|
return typeof lease.perAccount === 'number' && Number.isSafeInteger(lease.perAccount) && lease.perAccount > 0
|
|
5084
5119
|
? lease.perAccount : 4;
|
|
5085
5120
|
})() },
|
|
5121
|
+
warmReuse: (() => {
|
|
5122
|
+
const warm = legacyPod.warmReuse && typeof legacyPod.warmReuse === 'object' && !Array.isArray(legacyPod.warmReuse)
|
|
5123
|
+
? (legacyPod.warmReuse as Record<string, unknown>) : {};
|
|
5124
|
+
return {
|
|
5125
|
+
gateRecheck: warm.gateRecheck === true,
|
|
5126
|
+
land: warm.land === true,
|
|
5127
|
+
ta: warm.ta === true,
|
|
5128
|
+
minMatchSamples: typeof warm.minMatchSamples === 'number' && Number.isSafeInteger(warm.minMatchSamples) && warm.minMatchSamples > 0
|
|
5129
|
+
? warm.minMatchSamples : 3,
|
|
5130
|
+
};
|
|
5131
|
+
})(),
|
|
5086
5132
|
},
|
|
5087
5133
|
harness: {
|
|
5088
5134
|
edgeRail: (() => {
|
|
@@ -5452,6 +5498,7 @@ export function buildUserConfig(path: string = defaultPath()): UserConfig {
|
|
|
5452
5498
|
&& Number.isSafeInteger(chatFactQuestion.maxToolTurns) && chatFactQuestion.maxToolTurns > 0
|
|
5453
5499
|
? chatFactQuestion.maxToolTurns : CHAT_DEFAULTS.factQuestion.maxToolTurns,
|
|
5454
5500
|
},
|
|
5501
|
+
...((): { seatTurnCap?: Partial<SeatTurnCapConfig> } => { const c = parseSeatTurnCapConfig(chat.seatTurnCap); return c ? { seatTurnCap: c } : {}; })(),
|
|
5455
5502
|
fastPath: chat.fastPath === false || chat.fastPath === 'false' ? false : CHAT_DEFAULTS.fastPath,
|
|
5456
5503
|
conciseness: {
|
|
5457
5504
|
enabled: chatConciseness.enabled === false ? false : CHAT_CONCISENESS_DEFAULTS.enabled,
|
|
@@ -7078,16 +7125,6 @@ function parseMemoryJudge(raw: unknown): { enabled?: boolean; model?: string; cr
|
|
|
7078
7125
|
return (out.enabled !== undefined || out.model !== undefined || out.crossRecall !== undefined) ? out : undefined;
|
|
7079
7126
|
}
|
|
7080
7127
|
|
|
7081
|
-
function parseGeminiServerTools(raw: unknown): { googleSearch?: boolean; codeExecution?: boolean; urlContext?: boolean } | undefined {
|
|
7082
|
-
if (!raw || typeof raw !== 'object') return undefined;
|
|
7083
|
-
const obj = raw as Record<string, unknown>;
|
|
7084
|
-
const out: { googleSearch?: boolean; codeExecution?: boolean; urlContext?: boolean } = {};
|
|
7085
|
-
if (obj.googleSearch === true) out.googleSearch = true;
|
|
7086
|
-
if (obj.codeExecution === true) out.codeExecution = true;
|
|
7087
|
-
if (obj.urlContext === true) out.urlContext = true;
|
|
7088
|
-
return (Object.keys(out).length > 0) ? out : undefined;
|
|
7089
|
-
}
|
|
7090
|
-
|
|
7091
7128
|
function parseAnswerPriority(raw: unknown): 'cost' | 'balanced' | 'quality' | 'exhaustive' | undefined {
|
|
7092
7129
|
return raw === 'cost' || raw === 'balanced' || raw === 'quality' || raw === 'exhaustive'
|
|
7093
7130
|
? raw
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { spawnSync, type SpawnSyncOptionsWithStringEncoding } from 'node:child_process';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Default maxBuffer for harness · Pod · gate `spawnSync` calls that read child output.
|
|
5
|
+
* Node's 1 MiB default truncated `git ls-files` (1.54 MiB in W2b · 0.2.30 HARD #3) — same value as #28476.
|
|
6
|
+
* The ratchet `test/spawn-sync-max-buffer.test.ts` keeps new readers in those trees on an explicit maxBuffer.
|
|
7
|
+
*/
|
|
8
|
+
export const SPAWN_SYNC_MAX_BUFFER = 16 * 1024 * 1024;
|
|
9
|
+
|
|
3
10
|
/** Read command text completely or fail closed; never return a partial stdout. */
|
|
4
11
|
export function spawnSyncText(
|
|
5
12
|
cmd: string,
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// Fake executables on PATH for tests whose code under test spawns an external CLI
|
|
2
|
+
// (grok · magick · tesseract · …) that a gate Pod does not have.
|
|
3
|
+
//
|
|
4
|
+
// The industry-standard shape is a «PATH shim»: a tiny shell script with the real
|
|
5
|
+
// name, placed first on PATH. This module only makes that shape shared, so tests
|
|
6
|
+
// stop hand-writing `writeFileSync + chmodSync` (MOCK-REVIEW R6 · MOCK-DEVICES-2 ⓑ).
|
|
7
|
+
//
|
|
8
|
+
// Bun resolves a child's executable from the PATH the process STARTED with when the
|
|
9
|
+
// call passes no `env`; `test/preload-child-env.ts` makes a later PATH change visible
|
|
10
|
+
// to such calls. Code that passes its own `env` must receive `fakeBins.env` (or a
|
|
11
|
+
// PATH built from `fakeBins.path()`).
|
|
12
|
+
//
|
|
13
|
+
// ⛔ This is not a simulator of the real tool: a spec only fixes stdout · stderr ·
|
|
14
|
+
// exit code · lifetime, and records argv. Behaviour of the real tool stays with
|
|
15
|
+
// tests that run where the tool exists.
|
|
16
|
+
import { chmodSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
17
|
+
import { tmpdir } from 'node:os';
|
|
18
|
+
import { delimiter, join } from 'node:path';
|
|
19
|
+
|
|
20
|
+
export interface FakeBinSpec {
|
|
21
|
+
readonly stdout?: string;
|
|
22
|
+
readonly stderr?: string;
|
|
23
|
+
/** Exit code (default 0). */
|
|
24
|
+
readonly exitCode?: number;
|
|
25
|
+
/** Stay alive this long before exiting — for long-running daemons a test kills. */
|
|
26
|
+
readonly sleepSeconds?: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface FakeBinCall {
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly argv: readonly string[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface FakeBins {
|
|
35
|
+
/** Directory holding the fake executables. */
|
|
36
|
+
readonly dir: string;
|
|
37
|
+
/** Absolute path of one fake executable. */
|
|
38
|
+
bin(name: string): string;
|
|
39
|
+
/** PATH with the fake directory first (default base: the current PATH). */
|
|
40
|
+
path(base?: string): string;
|
|
41
|
+
/** `process.env` with the fake PATH, for code that passes its own `env`. */
|
|
42
|
+
readonly env: NodeJS.ProcessEnv;
|
|
43
|
+
/** Every recorded invocation, in order. */
|
|
44
|
+
calls(): FakeBinCall[];
|
|
45
|
+
/** Resolve once at least `count` invocations are recorded (a spawned child records asynchronously). */
|
|
46
|
+
waitForCalls(count: number, timeoutMs?: number): Promise<FakeBinCall[]>;
|
|
47
|
+
cleanup(): void;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const NAME = /^[A-Za-z0-9._+-]+$/;
|
|
51
|
+
|
|
52
|
+
function shellQuote(value: string): string {
|
|
53
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function script(name: string, spec: FakeBinSpec, dataDir: string, logPath: string): string {
|
|
57
|
+
const lines = ['#!/bin/sh'];
|
|
58
|
+
// One record per call: name and each argv entry NUL-terminated (one printf), then an ASCII record
|
|
59
|
+
// separator \x1e (a second printf). `calls()` drops the unterminated tail, so a reader never sees half a record.
|
|
60
|
+
lines.push(`{ printf '%s\\0' ${shellQuote(name)} "$@"; printf '\\036'; } >> ${shellQuote(logPath)}`);
|
|
61
|
+
if (spec.stdout !== undefined) {
|
|
62
|
+
const file = join(dataDir, `${name}.stdout`);
|
|
63
|
+
writeFileSync(file, spec.stdout);
|
|
64
|
+
lines.push(`cat ${shellQuote(file)}`);
|
|
65
|
+
}
|
|
66
|
+
if (spec.stderr !== undefined) {
|
|
67
|
+
const file = join(dataDir, `${name}.stderr`);
|
|
68
|
+
writeFileSync(file, spec.stderr);
|
|
69
|
+
lines.push(`cat ${shellQuote(file)} >&2`);
|
|
70
|
+
}
|
|
71
|
+
const exitCode = spec.exitCode ?? 0;
|
|
72
|
+
if (spec.sleepSeconds !== undefined && spec.sleepSeconds > 0) {
|
|
73
|
+
const seconds = Math.ceil(spec.sleepSeconds);
|
|
74
|
+
// exit 0: `exec` so killing the fake kills the sleep itself. Any other code needs the shell to
|
|
75
|
+
// outlive the sleep; a fake killed mid-sleep then leaves `sleep` until `sleepSeconds` ends.
|
|
76
|
+
if (exitCode === 0) lines.push(`exec sleep ${seconds}`);
|
|
77
|
+
else lines.push(`sleep ${seconds}`);
|
|
78
|
+
}
|
|
79
|
+
lines.push(`exit ${exitCode}`);
|
|
80
|
+
return `${lines.join('\n')}\n`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function createFakeBins(specs: Readonly<Record<string, FakeBinSpec>>): FakeBins {
|
|
84
|
+
for (const name of Object.keys(specs)) {
|
|
85
|
+
if (!NAME.test(name) || name === '.' || name === '..') throw new Error(`fake-bin: invalid executable name ${JSON.stringify(name)}`);
|
|
86
|
+
}
|
|
87
|
+
const root = mkdtempSync(join(tmpdir(), 'ux-sim-fake-bin-'));
|
|
88
|
+
const dir = join(root, 'bin');
|
|
89
|
+
const dataDir = join(root, 'data');
|
|
90
|
+
const logPath = join(root, 'calls.log');
|
|
91
|
+
try {
|
|
92
|
+
mkdirSync(dir);
|
|
93
|
+
mkdirSync(dataDir);
|
|
94
|
+
writeFileSync(logPath, '');
|
|
95
|
+
for (const [name, spec] of Object.entries(specs)) {
|
|
96
|
+
const file = join(dir, name);
|
|
97
|
+
writeFileSync(file, script(name, spec, dataDir, logPath));
|
|
98
|
+
chmodSync(file, 0o755);
|
|
99
|
+
}
|
|
100
|
+
} catch (error) {
|
|
101
|
+
rmSync(root, { recursive: true, force: true });
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
const path = (base = process.env.PATH ?? '') => (base ? `${dir}${delimiter}${base}` : dir);
|
|
105
|
+
return {
|
|
106
|
+
dir,
|
|
107
|
+
bin: (name) => join(dir, name),
|
|
108
|
+
path,
|
|
109
|
+
get env() {
|
|
110
|
+
return { ...process.env, PATH: path() };
|
|
111
|
+
},
|
|
112
|
+
calls() {
|
|
113
|
+
if (!existsSync(logPath)) return [];
|
|
114
|
+
// The segment after the last separator is either empty or a record still being written — never count it.
|
|
115
|
+
return readFileSync(logPath, 'utf8')
|
|
116
|
+
.split('\x1e')
|
|
117
|
+
.slice(0, -1)
|
|
118
|
+
.map((record) => {
|
|
119
|
+
const [name = '', ...argv] = record.split('\0').slice(0, -1);
|
|
120
|
+
return { name, argv };
|
|
121
|
+
});
|
|
122
|
+
},
|
|
123
|
+
async waitForCalls(count, timeoutMs = 5_000) {
|
|
124
|
+
const deadline = Date.now() + timeoutMs;
|
|
125
|
+
for (;;) {
|
|
126
|
+
const recorded = this.calls();
|
|
127
|
+
if (recorded.length >= count) return recorded;
|
|
128
|
+
if (Date.now() >= deadline) throw new Error(`fake-bin: expected ${count} call(s) within ${timeoutMs}ms, saw ${recorded.length}`);
|
|
129
|
+
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
cleanup: () => rmSync(root, { recursive: true, force: true }),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Put fake executables first on `process.env.PATH` for the duration of `run`,
|
|
138
|
+
* then restore PATH and remove the files — also when `run` throws.
|
|
139
|
+
*/
|
|
140
|
+
export async function withFakeBins<T>(
|
|
141
|
+
specs: Readonly<Record<string, FakeBinSpec>>,
|
|
142
|
+
run: (fakeBins: FakeBins) => T | Promise<T>,
|
|
143
|
+
): Promise<T> {
|
|
144
|
+
const fakeBins = createFakeBins(specs);
|
|
145
|
+
const previousPath = process.env.PATH;
|
|
146
|
+
process.env.PATH = fakeBins.path(previousPath ?? '');
|
|
147
|
+
try {
|
|
148
|
+
return await run(fakeBins);
|
|
149
|
+
} finally {
|
|
150
|
+
if (previousPath === undefined) delete process.env.PATH;
|
|
151
|
+
else process.env.PATH = previousPath;
|
|
152
|
+
fakeBins.cleanup();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Bun's real test timer implementation, scoped so exceptions cannot leave
|
|
2
|
+
// Date or timers mocked for the next test. Use only in serial tests: timer
|
|
3
|
+
// replacement is process-global and does not affect child processes.
|
|
4
|
+
import { jest } from 'bun:test';
|
|
5
|
+
|
|
6
|
+
export interface SimClock {
|
|
7
|
+
tick(ms: number): void;
|
|
8
|
+
setTime(now: number | Date): void;
|
|
9
|
+
now(): number;
|
|
10
|
+
pendingTimers(): number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let active = false;
|
|
14
|
+
|
|
15
|
+
export async function withSimClock<T>(now: number | Date, run: (clock: SimClock) => Promise<T> | T): Promise<T> {
|
|
16
|
+
if (active) throw new Error('sim clock is process-global; run scenarios serially');
|
|
17
|
+
active = true;
|
|
18
|
+
try {
|
|
19
|
+
jest.useFakeTimers({ now });
|
|
20
|
+
const clock: SimClock = {
|
|
21
|
+
tick(ms) {
|
|
22
|
+
if (!Number.isFinite(ms) || ms < 0) throw new Error('sim clock tick must be a nonnegative finite number');
|
|
23
|
+
jest.advanceTimersByTime(ms);
|
|
24
|
+
},
|
|
25
|
+
setTime(value) { jest.setSystemTime(value); },
|
|
26
|
+
now() { return Date.now(); },
|
|
27
|
+
pendingTimers() { return jest.getTimerCount(); },
|
|
28
|
+
};
|
|
29
|
+
return await run(clock);
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
jest.clearAllTimers();
|
|
33
|
+
jest.useRealTimers();
|
|
34
|
+
active = false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Capture the real dashboard/tui renderer at the stdout boundary, then let
|
|
2
|
+
// the already-installed xterm parser interpret its ANSI bytes. No child PTY.
|
|
3
|
+
import { Terminal } from '@xterm/headless';
|
|
4
|
+
import { renderDashboardFrame, type DashboardFrameInput } from '../dashboard/index.js';
|
|
5
|
+
import { resetRenderCache } from '../tui.js';
|
|
6
|
+
|
|
7
|
+
export interface HeadlessDashboardFrame {
|
|
8
|
+
lines: string[];
|
|
9
|
+
input: DashboardFrameInput;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface HeadlessDashboardSnapshot {
|
|
13
|
+
bytes: string;
|
|
14
|
+
lines: string[];
|
|
15
|
+
cursor: { row: number; col: number };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let capturing = false;
|
|
19
|
+
|
|
20
|
+
/** Serial-only: stdout and tui's frame cache are process globals. */
|
|
21
|
+
export async function simHeadlessDashboardFrames(
|
|
22
|
+
frames: readonly HeadlessDashboardFrame[],
|
|
23
|
+
size: { rows: number; cols: number } = { rows: 30, cols: 100 },
|
|
24
|
+
): Promise<HeadlessDashboardSnapshot[]> {
|
|
25
|
+
if (capturing) throw new Error('headless TUI simulation is already capturing stdout');
|
|
26
|
+
if (size.rows < 1 || size.cols < 1) throw new Error('headless TUI size must be positive');
|
|
27
|
+
const terminal = new Terminal({ rows: size.rows, cols: size.cols, scrollback: 0, allowProposedApi: true });
|
|
28
|
+
capturing = true;
|
|
29
|
+
const stdout = process.stdout;
|
|
30
|
+
const originalWrite = stdout.write;
|
|
31
|
+
const originalRows = Object.getOwnPropertyDescriptor(stdout, 'rows');
|
|
32
|
+
const originalColumns = Object.getOwnPropertyDescriptor(stdout, 'columns');
|
|
33
|
+
const snapshots: HeadlessDashboardSnapshot[] = [];
|
|
34
|
+
try {
|
|
35
|
+
Object.defineProperty(stdout, 'rows', { configurable: true, value: size.rows });
|
|
36
|
+
Object.defineProperty(stdout, 'columns', { configurable: true, value: size.cols });
|
|
37
|
+
resetRenderCache();
|
|
38
|
+
for (const frame of frames) {
|
|
39
|
+
const chunks: string[] = [];
|
|
40
|
+
stdout.write = ((chunk: string | Uint8Array, encoding?: BufferEncoding | ((error?: Error | null) => void), callback?: (error?: Error | null) => void) => {
|
|
41
|
+
chunks.push(typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString());
|
|
42
|
+
const done = typeof encoding === 'function' ? encoding : callback;
|
|
43
|
+
done?.(null);
|
|
44
|
+
return true;
|
|
45
|
+
}) as typeof stdout.write;
|
|
46
|
+
try {
|
|
47
|
+
renderDashboardFrame(frame.lines, frame.input);
|
|
48
|
+
} finally {
|
|
49
|
+
stdout.write = originalWrite;
|
|
50
|
+
}
|
|
51
|
+
const bytes = chunks.join('');
|
|
52
|
+
await new Promise<void>((resolve) => terminal.write(bytes, resolve));
|
|
53
|
+
const buffer = terminal.buffer.active;
|
|
54
|
+
snapshots.push({
|
|
55
|
+
bytes,
|
|
56
|
+
lines: Array.from({ length: size.rows }, (_, row) =>
|
|
57
|
+
buffer.getLine(buffer.viewportY + row)?.translateToString(true) ?? ''),
|
|
58
|
+
cursor: { row: buffer.cursorY + 1, col: buffer.cursorX + 1 },
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return snapshots;
|
|
62
|
+
} finally {
|
|
63
|
+
stdout.write = originalWrite;
|
|
64
|
+
if (originalRows) Object.defineProperty(stdout, 'rows', originalRows);
|
|
65
|
+
else Reflect.deleteProperty(stdout, 'rows');
|
|
66
|
+
if (originalColumns) Object.defineProperty(stdout, 'columns', originalColumns);
|
|
67
|
+
else Reflect.deleteProperty(stdout, 'columns');
|
|
68
|
+
resetRenderCache();
|
|
69
|
+
terminal.dispose();
|
|
70
|
+
capturing = false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -23,6 +23,7 @@ export interface InProcessCliOptions {
|
|
|
23
23
|
type MutableCommand = {
|
|
24
24
|
commands: MutableCommand[];
|
|
25
25
|
name(): string;
|
|
26
|
+
aliases(): string[];
|
|
26
27
|
_optionValues?: Record<string, unknown>;
|
|
27
28
|
_optionValueSources?: Record<string, string>;
|
|
28
29
|
args: string[];
|
|
@@ -35,7 +36,7 @@ function registeredCommandPath(root: MutableCommand, args: readonly string[]): s
|
|
|
35
36
|
let command = root;
|
|
36
37
|
for (const arg of args) {
|
|
37
38
|
if (arg.startsWith('-')) break;
|
|
38
|
-
const child = command.commands.find((candidate) => candidate.name() === arg);
|
|
39
|
+
const child = command.commands.find((candidate) => candidate.name() === arg || candidate.aliases().includes(arg));
|
|
39
40
|
if (!child) break;
|
|
40
41
|
path.push(arg);
|
|
41
42
|
command = child;
|