elanous 0.2.42 → 0.2.44
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/{X1ucLw10Cds_h614NoEnh → HMXsxdy5MIIcHPMHv1wD4}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/08334415.f0e80896acbef722.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1032-78ba4f6391258cab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1082-53f86a26e03d309d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1109-7d0e264f6f2edbc7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1124-7c26330402481143.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2160.a097e7b138ae1c55.js → 118.2a89982fe4276880.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1244.6c435dbf1bf21d8a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1252.9e665904d3aa3b1a.js +32 -0
- package/apps/pwa/out/_next/static/chunks/1266.a46cc33cb6a72d75.js +104 -0
- package/apps/pwa/out/_next/static/chunks/1306.967240ede9a0f757.js +24 -0
- package/apps/pwa/out/_next/static/chunks/1344.3b95f3bd1b77a3fe.js +94 -0
- package/apps/pwa/out/_next/static/chunks/{4043.6b91203436c9c86b.js → 1401.22dfe92640a2b1ac.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/1431-f7c78bd5be21e011.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1451-cdd35a8a0b31834b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6632.0eac1c554f8f2ef3.js → 1694.18debfd77562e56d.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1708-f03d587b7a7545c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1775-fa7152bdeff6c95f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/178-4da509cd7266672a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1850-522de4ee34957210.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1876-c6f6e0ddcc76c6a1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1976.097066b072432242.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3507.97e1977bc4d5fb0a.js → 1978.eeb60a606dc5deac.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/2043.e233e3b5a3e790f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2150.71b94e3348107c83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2158.ebc6fc5a10280ab7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2216.802962c04f40a26e.js +64 -0
- package/apps/pwa/out/_next/static/chunks/2294.7890edcfa046c97d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/235.c89aaae4bcd6233a.js +74 -0
- package/apps/pwa/out/_next/static/chunks/{5885.0a3e52c8faccec98.js → 239.de075467b5523469.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/249.ba7051590d603c8f.js +226 -0
- package/apps/pwa/out/_next/static/chunks/2571.a6ac4e26c8618403.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2610.e149cd564a08913e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2705.9816f3c244f8b85f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2801.afeb8a4dae22f85f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2954.bbefc95d6b20e0d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2e0f720a.a0697c08e3806a60.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3042.96ec235fe41c8d4e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3097-8e358f158acef46b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3205-93b1abe28b4fb16a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3273.b4434f0dcae7eb29.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3311.9cbc43ea0c90d60c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1487.2f67b79444062da6.js → 3349.b5f09ee474d9533e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3503.a47a9755fb4d97b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3506-5f429b3b7e1392b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3843.bad404d008893291.js +77 -0
- package/apps/pwa/out/_next/static/chunks/3877-4b40e530b47e3bf9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/435-ce2958253cf7de61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4393.28fa5228d0eec217.js +149 -0
- package/apps/pwa/out/_next/static/chunks/4404.7281c847c6e10dfc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8673-bab689a55f7e13b9.js → 4415-b9d6a90960920a4a.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/447-5b304de1fe098f43.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4484-8ebea83d431e6fae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8262.ddc03e06b733f184.js → 4502.bdcc877abd437a05.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4599-f95790fc5c65b8df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1262.e804feb8fd1acb8c.js → 46.57c783fa4884714f.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/463-b9114e411f33728e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4659.a57d1f0c5d754cd2.js +36 -0
- package/apps/pwa/out/_next/static/chunks/4722-a847e7a28115035f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1063.2fb8a9dc55c731f2.js → 4757.67c6d7473a038e78.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4874-c86f878ec4502ad3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6377.bc7df239edbff244.js → 4891.3f80ba517a3b2373.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4998.810ca8833084caa9.js +62 -0
- package/apps/pwa/out/_next/static/chunks/4f98febc.ea5841d4d616bfb2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3482.a9ae9d2ad6a5bd97.js → 5052.7dbb12a55d4f18f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5166-ca73b3e361085a6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5180-039f4a18b07ad387.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5232.5a2ce4daf7a9e11d.js +115 -0
- package/apps/pwa/out/_next/static/chunks/5439.3fec6dbce29ecb36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5612-074d9a5e00dfac6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5675-01989d524a84c505.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5751.af641a1adf5ec697.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5758-c6cb98714d18ab0c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/578eded8.b582637306e16964.js +122 -0
- package/apps/pwa/out/_next/static/chunks/5790.5eb06a653ebd8571.js +34 -0
- package/apps/pwa/out/_next/static/chunks/5853-4033e5bd5afbe06b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5904.97d70bb7f46b2db7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3347.f846266b5e5f3ede.js → 5989.7ecd362c5c44b747.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{73d2eb0e.4966ad55293c801a.js → 5a34fb2f.52f1b4e1baebb48a.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{7a98bc80.fa935989e829f9c2.js → 5a5078f8.2099200e5ea95e16.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6036-c302c34ff0b3d410.js +1 -0
- package/apps/pwa/out/_next/static/chunks/606.ef81c313381f4264.js +1 -0
- package/apps/pwa/out/_next/static/chunks/616.1af54a928b1ba704.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6201.bc936f71f613a8e9.js +41 -0
- package/apps/pwa/out/_next/static/chunks/6204-fdc86e0e64c4f92d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7411.9b4b8b747dc7b802.js → 6245.1182e007e9d230d9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{b450776b.3db34d8d965f82d3.js → 63699a35.17262e162bc514b2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6420.494801a80030160c.js +27 -0
- package/apps/pwa/out/_next/static/chunks/{e8543907.5b040a5f22a0b0e5.js → 6549dad0.2740b25e51bf8f05.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9427.96aa912ddb5801e0.js → 6881.9e7955847640c7fe.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/6931.fcdfb94141e67b3d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6991-8e081c6ce38c0ba1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7010.1bbd17a7f2b3e376.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7029.d1466acf55fae2ed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7152-a123aa8e129c131f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7455.196168fffac3b9c4.js +24 -0
- package/apps/pwa/out/_next/static/chunks/7638.6ca4770dd1129138.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7649-f37d76260e5e2a5a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7679.32c40cdd14f20b4a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7751.04bfbd16b4c6cd0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7864.b1ff31d4030b8994.js +148 -0
- package/apps/pwa/out/_next/static/chunks/7869-c47bd2c075c1fefa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8138.6c10b2a356d52fca.js → 8442.2f09ca969d631615.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8445.2738dbd59a78c78c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8447.5510c439f9938c6d.js +286 -0
- package/apps/pwa/out/_next/static/chunks/{9415.69e4a21c60c7d2db.js → 8551.f762945c2cda2e95.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8635-57a9d8d9db70f4f1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/86961958-4b0689a5048f756b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8709.3c6019bb18f8554f.js +8 -0
- package/apps/pwa/out/_next/static/chunks/8759.c999528a0a907bf6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9a852a62-6192a6ea9346ced3.js → 87f498e5-0881de09f2e44707.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8843.c3197f904c952b81.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3d0154af.5331fec737ffe8c3.js → 892fd990.456232f326cc39c2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8965-135a2c9eaa2464cb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8971-8d3b9c96f8a6c958.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9059.c8598d96f8e5e9cd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9115.90447ae198b84eae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9147.d9b0a02e0babc9b4.js +93 -0
- package/apps/pwa/out/_next/static/chunks/9204-83075f4b70c61cdc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9244-c32ef14b5dc72bdf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/930.2a9a30f964350c66.js +90 -0
- package/apps/pwa/out/_next/static/chunks/9398.1f56e3f17795f43f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9527.3e5ad31c891c5fcb.js +79 -0
- package/apps/pwa/out/_next/static/chunks/9571-4ac933e774d1225c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-9fc644de2d8edae3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-0c9dace2db62bee8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f5e65c3dc9d89f2a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-2a9c19b9a140b7b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-61533ad92141adfb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-112004ced6fd0329.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-f733318c237a49d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-51ea677d2d33bbc0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-428b41f2f9566e3c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-1b29396ea90a61e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-cf83ec613ac904bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-3f4c0ecbc284bb5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-b63c322f54f70cc6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-fe328c4ee9aac6b4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-bfb855c584f0fb98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-9fc644de2d8edae3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-47b1710c110eabd7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-42895214458bc6d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-d03de0ebd8366e23.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-3ed6c47e4b1c61c2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-ae653e9bf261c738.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-23f3f0a0209c0ac4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-88c691273aae66f9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e187ac52a95538b3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-6e45828daed1295e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-edb5d7287bb46186.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-4a7eaacd93c3f6a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ca073d43d74cc84.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1e9fee67b1199436.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-df1283ea963c6816.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-19fcf8d8301ccd18.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-5ab699e0303bbb40.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-7cde0d29756984c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-9d4c598e8ee22f7a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-cc1609a71f44ec62.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7659a9a1345bfaa9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-0afef60ecc0c4af5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-a3553949f8f34f5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-9fc644de2d8edae3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-057a69702f3c67c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-c0f0e570f3f74c73.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-1825071ae34e3b89.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-6244e3e135d8ccfc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-da787e8a10b8a82e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-1316d32498e2be42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-4df94572e343de2e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-708969f7475e88c1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-c58add08c919a1dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-a24847f45e5d5bf9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-acfec65a3a60e22e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-3dfc598e6fbde245.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-c658a626118411b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-4c73685fd891445b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-6310f7e5de7dd01d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-51c326bf48610be1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-d0beadf754da59b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-acd243bfbf3f6732.js +1 -0
- package/apps/pwa/out/_next/static/css/d1f8bb401740a549.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 +23 -23
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +23 -23
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/catalog/external-commands.yaml +5 -3
- package/catalog/meta/catalogVersion.yaml +2 -1
- package/catalog/signing/catalog-signing-public.pem +3 -0
- package/graphs/intake/intake-daily.yaml +16 -0
- package/graphs/intake/news-sources.yaml +1 -0
- package/graphs/intake/recipes.yaml +7 -0
- package/graphs/overlays/README.md +6 -0
- package/graphs/overlays/examples/research-runtime-empty-terminal.yaml +28 -0
- package/graphs/profiles/local.yaml +5 -0
- package/graphs/profiles/pod.yaml +4 -0
- package/graphs/release/release-loop.yaml +33 -17
- package/graphs/units/verbs/make-doc.yaml +1 -0
- package/package.json +6 -2
- package/plugins/demo-absorption-briefing/plugin.json +18 -0
- package/plugins/demo-absorption-briefing/skills/demo-absorption-briefing/SKILL.md +8 -0
- package/plugins/demo-browser-hand/plugin.json +13 -0
- package/plugins/demo-browser-hand/skills/demo-browser-hand/SKILL.md +8 -0
- package/plugins/demo-linear-secretary/plugin.json +15 -0
- package/plugins/demo-linear-secretary/skills/demo-linear-secretary/SKILL.md +8 -0
- package/plugins/demo-plugin-wizard/plugin.json +11 -0
- package/plugins/demo-plugin-wizard/skills/demo-plugin-wizard/SKILL.md +8 -0
- package/plugins/demo-research/plugin.json +16 -0
- package/plugins/demo-research/skills/demo-research/SKILL.md +8 -0
- package/plugins/demo-video-briefing/plugin.json +15 -0
- package/plugins/demo-video-briefing/skills/demo-video-briefing/SKILL.md +8 -0
- package/scripts/bench-metering-plan.ts +229 -0
- package/scripts/build-signed-catalog.ts +48 -0
- package/scripts/ci-typecheck-main-delta.sh +88 -0
- package/scripts/codex-fallback-live-probe.ts +1 -1
- package/scripts/demo/demo1104-parallel-host.ts +56 -0
- package/scripts/demo/demo1104-parallel-scenes.ts +301 -0
- package/scripts/demo/demo1104-parallel.ts +72 -0
- package/scripts/demo/demo1104-stage.config.ts +21 -0
- package/scripts/demo/demo1104-stage.ts +316 -0
- package/scripts/goal-method-audit.ts +17 -1
- package/scripts/graph-units/land-enqueue.ts +90 -0
- package/scripts/hooks/codex-notify.sh +32 -0
- package/scripts/install.sh +10 -38
- package/scripts/landing-heal/land-plan.ts +57 -0
- package/scripts/public-leak-baseline.txt +0 -1
- package/scripts/release-loop/auto-approve-node.ts +1 -1
- package/scripts/release-loop/docs-node.ts +4 -2
- package/scripts/release-loop/gate-autoheal-sim-evidence.ts +60 -0
- package/scripts/release-loop/gate-image-pin.ts +116 -2
- package/scripts/release-loop/gate-method.ts +139 -0
- package/scripts/release-loop/gate-node.ts +395 -43
- package/scripts/release-loop/gate-progress-sim.ts +73 -0
- package/scripts/release-loop/gate-traffic-mode.ts +151 -3
- package/scripts/release-loop/node-verdict.ts +38 -25
- package/scripts/release-loop/notes-repair.ts +18 -1
- package/scripts/release-loop/preflight.ts +544 -10
- package/scripts/release-loop/render-warm-control-manifest.ts +22 -0
- package/scripts/release-loop/resume-release.ts +9 -7
- package/scripts/release-loop/resume.ts +13 -4
- package/scripts/release-loop/unattended-release.ts +20 -9
- package/scripts/release-loop/warm-control-forward.ts +178 -0
- package/scripts/retro-cycle.ts +30 -8
- package/scripts/rhythm/daily.ts +39 -4
- package/scripts/rhythm/linear-progress-sync.ts +311 -0
- package/scripts/ux-sim.ts +7 -1
- package/scripts/video-pipeline.ts +9 -1
- package/scripts/warm-pool-provider-config.ts +35 -7
- package/src/acp/agent-manager.ts +1 -0
- package/src/acp/codex-app-server-agent.ts +33 -0
- package/src/acp/codex-app-server-client.ts +153 -16
- package/src/acp/core-turn-bridge.ts +17 -12
- package/src/acp/event-router.ts +20 -1
- package/src/acp/server.ts +6 -0
- package/src/agent-mission/browser-roundtrip-coordinator.ts +85 -0
- package/src/agent-mission/claude-headless.ts +4 -1
- package/src/agent-mission/codex-exec.ts +105 -0
- package/src/agent-mission/driver.ts +192 -11
- package/src/agent-mission/grok-auth-status.ts +107 -0
- package/src/agent-mission/hand-hooks.ts +101 -0
- package/src/agent-mission/mission-cli.ts +56 -21
- package/src/agent-mission/mission-hand-reply.ts +118 -0
- package/src/agent-mission/mission-line.ts +180 -0
- package/src/agent-mission/mission-out.ts +256 -18
- package/src/agent-mission/tool-install.ts +122 -11
- package/src/agent-substrate/pr-reviewer.ts +147 -11
- package/src/agent-substrate/self-review-cli.ts +10 -2
- package/src/agents/general-purpose.md +1 -1
- package/src/auto-research/research-fanout.ts +221 -0
- package/src/auto-research/research-turn.ts +362 -31
- package/src/autopilot/mission-codebase-gate.ts +7 -3
- package/src/autopilot/pr-manager.ts +31 -3
- package/src/boot/daemon-tools/self-implement.ts +3 -1
- package/src/boot/daemon-tools/web-search.ts +1 -2
- package/src/briefing/brief-items.ts +55 -11
- package/src/cli/agent-cli.ts +2 -1
- package/src/cli/catalog-cli.ts +31 -0
- package/src/cli/connector-cli.ts +16 -0
- package/src/cli/control-cli.ts +15 -6
- package/src/cli/doctor-fix.ts +2 -2
- package/src/cli/intake-source-cli.ts +44 -8
- package/src/cli/log-event-names.ts +8 -0
- package/src/cli/msg-cli.ts +32 -3
- package/src/cli/pr-cli.ts +21 -1
- package/src/cli/pr-land-heavy-remote.ts +44 -6
- package/src/cli/pr-land-overlap-evidence.ts +13 -1
- package/src/cli/pr-land-pod-shadow-job.ts +143 -5
- package/src/cli/pr-land-pod-shadow.ts +9 -2
- package/src/cli/release-checklist-read-cli.ts +44 -16
- package/src/cli/release-cli.ts +23 -3
- package/src/cli/research-cli.ts +9 -0
- package/src/cli/setup-cli.ts +166 -6
- package/src/cli/setup-keys.ts +199 -0
- package/src/cli/task-plugin-wizard-host.ts +114 -0
- package/src/cli/tasks-cli.ts +54 -9
- package/src/cli/tui-test-cli.ts +190 -0
- package/src/config.ts +4 -2
- package/src/connectors/linear-daily-progress.ts +228 -0
- package/src/connectors/linear-projector.ts +34 -12
- package/src/connectors/linear.ts +151 -7
- package/src/control-plane/ledger.ts +42 -4
- package/src/control-plane/member-tokens.ts +25 -2
- package/src/control-plane/ports.ts +8 -3
- package/src/control-plane/server.ts +26 -5
- package/src/core-turn/deep-turn-bloom.ts +67 -0
- package/src/core-turn/research-policy.ts +43 -0
- package/src/core-turn/run-core-turn.ts +488 -51
- package/src/core-turn/types.ts +4 -0
- package/src/dashboard/chat/acp-chat.ts +10 -0
- package/src/dashboard/classic-sidetab-mission-job.ts +192 -0
- package/src/dashboard/classic-sidetab-mission-pair.ts +82 -0
- package/src/dashboard/classic-sidetab-mission-trio.ts +242 -0
- package/src/dashboard/classic-sidetab-mission.ts +169 -5
- package/src/dashboard/index.ts +387 -14
- package/src/dashboard/input/chat-main-acp-dispatch.ts +23 -0
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +8 -0
- package/src/dashboard/mission-cli-consumer.ts +20 -8
- package/src/dashboard/plugin-wizard-runtime.ts +50 -0
- package/src/dashboard/plugin-wizard-tool.ts +55 -0
- package/src/dashboard/sidetab-runtime.ts +3 -1
- package/src/dashboard/terminal-popup-runtime.ts +6 -3
- package/src/dashboard/visible-mission-diagnostics.ts +16 -0
- package/src/decisions/linear-progress-summary.ts +78 -0
- package/src/decisions/linear-progress-sync.ts +152 -0
- package/src/domains/outbound-alert.ts +49 -11
- package/src/domains/retro-cycle-observation.ts +43 -0
- package/src/domains/retro-cycle.ts +13 -2
- package/src/domains/retro-proposals.ts +92 -0
- package/src/domains/retro-report.ts +6 -1
- package/src/domains/telegram-kind-route.ts +16 -9
- package/src/graph-runner/arg-allowance.ts +13 -0
- package/src/graph-runner/graph-cli.ts +24 -1
- package/src/graph-runner/graph-grow-llm.ts +3 -1
- package/src/graph-runner/graph-run-api.ts +3 -1
- package/src/graph-runner/runner.ts +310 -46
- package/src/graph-wizard/mission-compose.ts +407 -12
- package/src/harness/dispatch-backpressure.ts +54 -1
- package/src/harness/dispatch-shadow-compare.ts +74 -0
- package/src/harness/harness-cli-command.ts +15 -3
- package/src/harness/harness-pod-dispatch.ts +3 -0
- package/src/harness/skill-exec.ts +21 -9
- package/src/harness/skill-select.ts +1 -1
- package/src/hooks/error-report-cloud.ts +101 -0
- package/src/hooks/receiver.ts +29 -2
- package/src/index.ts +129 -12
- package/src/intake-plane/actions.ts +354 -0
- package/src/intake-plane/adapters/telegram-ambient.ts +34 -18
- package/src/intake-plane/intake-sources.ts +78 -8
- package/src/intake-plane/items.ts +14 -4
- package/src/intake-plane/linear-mission-sync.ts +80 -0
- package/src/intake-plane/linear-secretary-runtime.ts +178 -0
- package/src/intake-plane/linear-wish.ts +227 -1
- package/src/life/life-cli.ts +168 -0
- package/src/life/life-kinds.ts +160 -0
- package/src/live-supply/budget-consumer.ts +78 -0
- package/src/live-supply/read.ts +3 -0
- package/src/live-supply/snapshot.ts +45 -0
- package/src/llm/child-first-llm-observation.ts +112 -0
- package/src/llm/provider-credentials.ts +68 -6
- package/src/llm/provider-failure-evidence.ts +44 -0
- package/src/llm.ts +172 -12
- package/src/maturity/feature-maturity.ts +3 -3
- package/src/mcp/client.ts +7 -0
- package/src/mcp/proxy-runtime.ts +6 -1
- package/src/mcp/server.ts +54 -0
- package/src/msg/msg-sse-server.ts +3 -3
- package/src/msg/msg-store.ts +177 -19
- package/src/native-tool-catalog.ts +36 -2
- package/src/nexus/api/consult-requests.ts +18 -6
- package/src/nexus/api/discord-trigger-bot.ts +6 -6
- package/src/nexus/api/graphs-api.ts +4 -2
- package/src/nexus/api/grokbot-trigger-bot.ts +206 -0
- package/src/nexus/api/http-server.ts +37 -1
- package/src/nexus/api/mcp-public-allowlist.ts +2 -0
- package/src/nexus/api/telegram-trigger-bot.ts +6 -6
- package/src/nexus/boot/register-mcp-clients.ts +114 -8
- package/src/nexus/index.ts +22 -2
- package/src/nexus/outbound/format.ts +9 -0
- package/src/nexus/outbound/grokbot-adapter.ts +71 -0
- package/src/nexus/outbound/router.ts +121 -16
- package/src/nexus/setup-status.ts +9 -0
- package/src/nexus/state/state.ts +3 -0
- package/src/oauth/codex-account-store.ts +20 -7
- package/src/oauth/codex-owner-mirror.ts +81 -0
- package/src/oauth/codex.ts +17 -2
- package/src/oauth/fallback-chain.ts +47 -17
- package/src/onboarding/first-run-doctor.ts +8 -1
- package/src/onboarding/first-run.ts +126 -29
- package/src/onboarding/key-setup.ts +103 -0
- package/src/onboarding/menu-answer.ts +13 -0
- package/src/onboarding/secret-prompt.ts +37 -0
- package/src/plugins/install/plugin-install.ts +59 -0
- package/src/pr-tool/census.ts +130 -0
- package/src/preview/terminal.ts +22 -7
- package/src/prompt-enhance/enhance.ts +10 -0
- package/src/pty-shell/pty-control-ipc.ts +4 -1
- package/src/pty-shell/pty-write-provenance.ts +21 -3
- package/src/pty-shell/registry.ts +9 -2
- package/src/registry/catalog-server.ts +232 -0
- package/src/registry/loader.ts +45 -1
- package/src/registry/types.ts +1 -2
- package/src/release-loop/proposal-auto-place.ts +83 -0
- package/src/research/axis-fanout.ts +79 -29
- package/src/research/lenses/second-order.ts +312 -0
- package/src/self-dev/ask-launch-flow.ts +72 -1
- package/src/self-dev/dev-cli.ts +7 -2
- package/src/self-dev/dev-pipeline.ts +5 -0
- package/src/self-dev/draft-residue.ts +64 -5
- package/src/self-dev/draft-sweep.ts +31 -10
- package/src/self-dev/draft-triage-rules.ts +60 -3
- package/src/self-dev/graph-front-nodes.ts +2 -1
- package/src/self-dev/graph-journey-route.ts +76 -21
- package/src/self-dev/launch-preflight.ts +58 -0
- package/src/self-dev/orchestrate.ts +1 -1
- package/src/self-dev/run-supervisor.ts +152 -2
- package/src/self-dev/shard-aggregate.ts +4 -0
- package/src/self-dev/shard-run.ts +36 -15
- package/src/self-implement/abandoned-classification.ts +12 -3
- package/src/self-implement/budget-gate.ts +7 -0
- package/src/self-implement/child-llm-preference.ts +10 -1
- package/src/self-implement/doctor-visit.ts +30 -8
- package/src/self-implement/elanous-tui-spawn.ts +3 -0
- package/src/self-implement/fixtures/tdd-green-missing-passing-child-transcript.txt +2 -0
- package/src/self-implement/gate-artifacts.ts +2 -1
- package/src/self-implement/goal-author-cli.ts +4 -2
- package/src/self-implement/goal-author.ts +549 -10
- package/src/self-implement/graph-overlay-yaml.ts +181 -4
- package/src/self-implement/graph-overlay.ts +3 -1
- package/src/self-implement/graph-profile-yaml.ts +107 -0
- package/src/self-implement/graph-yaml.ts +94 -5
- package/src/self-implement/off-diff-evidence.ts +249 -5
- package/src/self-implement/orchestrator.ts +298 -26
- package/src/self-implement/run-chart.ts +6 -3
- package/src/self-implement/run-ledger.ts +51 -1
- package/src/self-implement/runtime-overlay-run-steps.ts +95 -0
- package/src/self-implement/tdd-evidence-tags.ts +9 -0
- package/src/self-implement/test-scenario-request.ts +37 -6
- package/src/self-implement/train-gate-receipt.ts +166 -0
- package/src/self-implement/train-gate-remote.ts +62 -18
- package/src/session/chat.ts +6 -4
- package/src/session/session-fanout.ts +2 -0
- package/src/session/streaming/acp-stream-sink.ts +2 -1
- package/src/session/streaming/chunk-producer.ts +6 -0
- package/src/session/streaming/stream-compositor.ts +3 -2
- package/src/session-runtime/index.ts +74 -6
- package/src/session-runtime/retry-policy.ts +1 -1
- package/src/setup/llm-env-detect.ts +3 -0
- package/src/setup/service-key-catalog.ts +46 -0
- package/src/setup/service-keys.ts +241 -0
- package/src/sidetab-core/model.ts +205 -10
- package/src/sidetab-core/visible-agent-mission-pair.ts +51 -0
- package/src/sidetab-core/visible-agent-mission.ts +182 -48
- package/src/skills/tools/agent.ts +23 -4
- package/src/skills/tools/omni-search.ts +127 -27
- package/src/task-agent/parent-host.ts +29 -1
- package/src/task-agent/recall-inject.ts +98 -0
- package/src/task-agent/repair-outcomes.ts +65 -0
- package/src/task-agent/task-hand.ts +46 -14
- package/src/task-orchestrator/dispatcher.ts +14 -1
- package/src/task-orchestrator/linear-capture-events.ts +55 -0
- package/src/task-orchestrator/store.ts +16 -5
- package/src/task-orchestrator/surfaces/pod-artifact-return.ts +23 -1
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +107 -1
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +113 -14
- package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +21 -9
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +23 -11
- package/src/task-orchestrator/surfaces/pod-warm-switch.ts +2 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +467 -77
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +45 -3
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +210 -14
- package/src/task-orchestrator/surfaces/self-implement.ts +27 -3
- package/src/task-orchestrator/surfaces/warm-reuse-evidence.ts +169 -0
- package/src/task-orchestrator/types.ts +14 -0
- package/src/telegram.ts +14 -16
- package/src/terminal/coding-agent.ts +14 -5
- package/src/terminal/session-registry.ts +1 -1
- package/src/tool-hints/gate.ts +46 -14
- package/src/tool-hints/signals.ts +1 -1
- package/src/tool-hints/types.ts +2 -0
- package/src/tool-runtime/agent-runtime.ts +1 -0
- package/src/tool-runtime/browser-hand-runtime.ts +391 -0
- package/src/tool-runtime/browser-runtime.ts +33 -19
- package/src/tool-runtime/elanous-linear-issue-runtime.ts +76 -0
- package/src/tool-runtime/elanous-linear-secretary-runtime.ts +173 -0
- package/src/tool-runtime/graph-mcp-runtimes.ts +240 -0
- package/src/tool-runtime/index.ts +6 -0
- package/src/tool-runtime/types.ts +5 -0
- package/src/tui/entry.ts +51 -8
- package/src/tui/sidetab/attach.ts +252 -11
- package/src/tui/sidetab/herdr-portal.ts +225 -0
- package/src/tui/sidetab/list.ts +3 -2
- package/src/tui-client/next-dashboard-runtime.ts +52 -0
- package/src/user-config.ts +34 -9
- package/src/user-intent/types.ts +4 -3
- package/src/ux-sim/browser-hand.ts +165 -0
- package/src/ux-sim/draft-inventory-builder.ts +199 -0
- package/src/ux-sim/fake-browser-page.ts +81 -0
- package/src/ux-sim/fake-linear-device.ts +31 -0
- package/src/ux-sim/graph-engine-sim.ts +47 -0
- package/src/ux-sim/linear-secretary.ts +208 -0
- package/src/ux-sim/mock-scenario-catalog.json +81 -26
- package/src/ux-sim/mock-scenario-catalog.ts +175 -5
- package/src/ux-sim/onboarding-first-run-device.ts +31 -21
- package/src/ux-sim/release-sim-rig.ts +62 -18
- package/src/ux-sim/scenario.ts +70 -26
- package/src/ux-sim/service-key-setup.ts +113 -0
- package/src/ux-sim/term-slash-device.ts +74 -0
- package/src/ux-sim/turn-throw-sim.ts +31 -0
- package/src/version/packed-revision.json +1 -1
- package/src/web-search/exa.ts +77 -0
- package/src/web-search/index.ts +30 -9
- package/src/web-search/provider.ts +4 -1
- package/src/web-search/x-intent.ts +5 -0
- package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +0 -36
- package/apps/pwa/out/_next/static/chunks/1147-5196d19c222051b3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1319.b9b815ae0f181e06.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1455-530ca16c7e71baff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1574.878c18ecc97b1bd4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +0 -32
- package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1945.7b54990d578c119b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +0 -286
- package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +0 -34
- package/apps/pwa/out/_next/static/chunks/2456.b6de0e1c05f28843.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +0 -1
- package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2690.0521c738b7749931.js +0 -115
- package/apps/pwa/out/_next/static/chunks/2974.595d1e29d040cb6a.js +0 -64
- package/apps/pwa/out/_next/static/chunks/3207.a756c95e9ec8c3c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3285.89ee2f298682f5e5.js +0 -93
- package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +0 -41
- package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +0 -24
- package/apps/pwa/out/_next/static/chunks/3741.9cf76acaa2ee5298.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3837.a210d7d0db8d8abd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +0 -77
- package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4276.336d76d858fcdf1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4320.583cbab64db6be02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4770.769c9cd9c7034eba.js +0 -148
- package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +0 -74
- package/apps/pwa/out/_next/static/chunks/50061469.0326382241ef3b2d.js +0 -122
- package/apps/pwa/out/_next/static/chunks/5112.4b9f300124fab7b3.js +0 -149
- package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +0 -27
- package/apps/pwa/out/_next/static/chunks/53c73f84.373b6160adfa89a4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5431-72a1dbde59400691.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5440-4236de26c5ea5856.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6131.348b7d6bdcd267ce.js +0 -226
- package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +0 -90
- package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +0 -104
- package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +0 -94
- package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7279-c199ea83f34338fa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +0 -1
- package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +0 -8
- package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8505.fd803c6c33b54cc3.js +0 -79
- package/apps/pwa/out/_next/static/chunks/8546-6f03f8ea34dd61d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9211-330b6736a63d4cb3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9249.976f1e69a9d80754.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9353-12bfff0c130104cf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9633.ce5bddc56784da72.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9656-374232558fd528d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9832.f4a98c878ecf2c0a.js +0 -62
- package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-0e3d7b9421b79dac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-0f291d3c8fd55a3a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-bf067887b3307423.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +0 -1
- package/apps/pwa/out/_next/static/css/be9019f696217521.css +0 -1
- /package/apps/pwa/out/_next/static/{X1ucLw10Cds_h614NoEnh → HMXsxdy5MIIcHPMHv1wD4}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { mkdirSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { getSecretAsync } from '../../src/nexus/config/secrets/index.js';
|
|
5
|
+
import { commentLinearIssue } from '../../src/connectors/linear.js';
|
|
6
|
+
import { listChecklist, type Checklist, type ChecklistItem } from '../../src/release-loop/checklist.js';
|
|
7
|
+
import { DecisionLedger, type DecisionEntry } from '../../src/decisions/decision-ledger.js';
|
|
8
|
+
import { effectiveInstanceRoot } from '../../src/instance/resolve.js';
|
|
9
|
+
import { debug } from '../../src/debug/log.js';
|
|
10
|
+
import { acquireLockAsync } from '../../src/storage/file-lock.js';
|
|
11
|
+
|
|
12
|
+
export type ProgressIssue = {
|
|
13
|
+
id: string; identifier: string; title: string; url: string; description: string; state: string;
|
|
14
|
+
/** Verified Linear team key; live writes fail closed unless this is DEMO. */
|
|
15
|
+
teamKey: string;
|
|
16
|
+
};
|
|
17
|
+
export type ProgressLink = { issue: ProgressIssue; cells: ChecklistItem[]; decisions: DecisionEntry[]; sources: Array<{ cellId: string; field: string }> };
|
|
18
|
+
export type ProgressPreview = { identifier: string; body: string; sources: Array<{ cellId: string; field: string }> };
|
|
19
|
+
export type ProgressSyncResult = {
|
|
20
|
+
day: string; candidates: ProgressPreview[]; posted: string[]; alreadyPresent: string[];
|
|
21
|
+
skipped: string[]; failures: Array<{ identifier: string; reason: string }>;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const kstDay = (date: Date) => new Date(date.getTime() + 9 * 3_600_000).toISOString().slice(0, 10);
|
|
25
|
+
const escapeRegExp = (value: string) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
26
|
+
|
|
27
|
+
function exactReference(source: string, token: string): boolean {
|
|
28
|
+
return new RegExp(`(^|[^A-Z0-9_-])${escapeRegExp(token)}($|[^A-Z0-9_-])`).test(source);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function declaredIssueRefs(source: string): string[] {
|
|
32
|
+
const refs: string[] = [];
|
|
33
|
+
for (const declaration of source.matchAll(/\blinear-ref\s*[:=]\s*([^\r\n]+)/gi)) {
|
|
34
|
+
refs.push(...[...(declaration[1] ?? '').matchAll(/\b[A-Z]{2,8}-\d+\b/g)].map(match => match[0]!));
|
|
35
|
+
}
|
|
36
|
+
return [...new Set(refs)];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Only `linear-ref:` declarations in checklist fields and exact checklist IDs in issue descriptions create a link. */
|
|
40
|
+
export function resolveExplicitProgressLinks(issues: readonly ProgressIssue[], checklist: Checklist, decisions: readonly DecisionEntry[] = []): ProgressLink[] {
|
|
41
|
+
const links: ProgressLink[] = [];
|
|
42
|
+
for (const issue of issues) {
|
|
43
|
+
const cells = new Map<string, ChecklistItem>();
|
|
44
|
+
const sources: Array<{ cellId: string; field: string }> = [];
|
|
45
|
+
for (const cell of checklist.items) {
|
|
46
|
+
const declared: Array<[string, string]> = [
|
|
47
|
+
['title', cell.title], ['evidence', cell.evidence ?? ''], ['refs', (cell.refs ?? []).join('\n')],
|
|
48
|
+
];
|
|
49
|
+
for (const [field, value] of declared) {
|
|
50
|
+
if (declaredIssueRefs(value).includes(issue.identifier)) {
|
|
51
|
+
cells.set(cell.id, cell);
|
|
52
|
+
sources.push({ cellId: cell.id, field: `checklist.${field}` });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (exactReference(issue.description, cell.id)) {
|
|
56
|
+
cells.set(cell.id, cell);
|
|
57
|
+
sources.push({ cellId: cell.id, field: 'issue.description' });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const linkedDecisions = decisions.filter(decision => decision.refs?.some(ref => ref === issue.identifier || ref === issue.url));
|
|
61
|
+
for (const decision of linkedDecisions) sources.push({ cellId: decision.id, field: 'decision.refs' });
|
|
62
|
+
if (cells.size || linkedDecisions.length) links.push({ issue, cells: [...cells.values()], decisions: linkedDecisions, sources });
|
|
63
|
+
}
|
|
64
|
+
return links;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function changedStatuses(checklist: Checklist, cellIds: ReadonlySet<string>, day: string): Array<{ id: string; from: string; to: string }> {
|
|
68
|
+
return checklist.history.flatMap(entry => {
|
|
69
|
+
if (!cellIds.has(entry.id) || entry.field !== 'status' || !entry.at || kstDay(new Date(entry.at)) !== day) return [];
|
|
70
|
+
return [{ id: entry.id, from: String(entry.from ?? 'unknown'), to: String(entry.to ?? 'unknown') }];
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function renderProgressPreview(link: ProgressLink, checklist: Checklist, day: string): ProgressPreview {
|
|
75
|
+
const ids = new Set(link.cells.map(cell => cell.id));
|
|
76
|
+
const transitions = changedStatuses(checklist, ids, day);
|
|
77
|
+
const statusLines = link.cells.map(cell => {
|
|
78
|
+
const evidence = cell.evidence ?? '';
|
|
79
|
+
const simulated = cell.status === 'green' && /green\(sim\)/i.test(evidence);
|
|
80
|
+
const e4Pending = simulated && /(?:설치본|installed)(?: CLI)?[^\n.]{0,24}E4[^\n.]{0,24}(?:미완|incomplete|not complete|not done)/i.test(evidence);
|
|
81
|
+
return `- 연결 칸: ${cell.id} — ${simulated ? `green(sim)${e4Pending ? ' · 설치본 E4 미완' : ''}` : cell.status}`;
|
|
82
|
+
});
|
|
83
|
+
const transitionLines = transitions.map(change => `- 오늘 상태 변화: ${change.id} ${change.from} → ${change.to}`);
|
|
84
|
+
const decisionLines = link.decisions.filter(decision => {
|
|
85
|
+
const timestamp = decision.decidedAt ?? decision.withdrawnAt ?? decision.raisedAt;
|
|
86
|
+
return !!timestamp && kstDay(new Date(timestamp)) === day;
|
|
87
|
+
})
|
|
88
|
+
.map(decision => `- 연결 결정: ${decision.id} — ${decision.status}`);
|
|
89
|
+
const landedPrs = [...new Set(link.cells.flatMap(cell => {
|
|
90
|
+
const text = cell.evidence ?? '';
|
|
91
|
+
return [...text.matchAll(/\bPR\s*#(\d+)\b[^\n]{0,120}\bmerged\b/gi)].map(match => `#${match[1]}`);
|
|
92
|
+
}))];
|
|
93
|
+
const nextCell = link.cells.find(cell => cell.status !== 'green' && cell.status !== 'done');
|
|
94
|
+
const simulatedCell = link.cells.find(cell => cell.status === 'green' && /green\(sim\)/i.test(cell.evidence ?? ''));
|
|
95
|
+
const simulatedEvidence = simulatedCell?.evidence ?? '';
|
|
96
|
+
const simulatedE4Pending = !!simulatedCell && /(?:설치본|installed)(?: CLI)?[^\n.]{0,24}E4[^\n.]{0,24}(?:미완|incomplete|not complete|not done)/i.test(simulatedEvidence);
|
|
97
|
+
const next = nextCell ? `연결 칸 ${nextCell.id}의 남은 완료 경계 진행`
|
|
98
|
+
: simulatedCell ? `연결 칸 ${simulatedCell.id}의 ${simulatedE4Pending ? '설치본 E4 실물 증거 확보' : '설치본 실물 증거 확인'}` : '연결된 칸은 현재 green/done';
|
|
99
|
+
const body = [
|
|
100
|
+
`${day} 진행 요약`,
|
|
101
|
+
`- 상태: ${link.issue.state} — ${link.issue.url}`,
|
|
102
|
+
...statusLines,
|
|
103
|
+
...transitionLines,
|
|
104
|
+
...decisionLines,
|
|
105
|
+
...(landedPrs.length ? [`- 연결 착지 PR: ${landedPrs.join(', ')}`] : []),
|
|
106
|
+
`- 다음: ${next}`,
|
|
107
|
+
`<!-- elanous-linear-progress:${day}:${link.issue.identifier} -->`,
|
|
108
|
+
].join('\n');
|
|
109
|
+
return { identifier: link.issue.identifier, body, sources: link.sources };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function fetchTeamIssues(apiKey: string, teamKey: string, fetchFn: typeof fetch = fetch): Promise<ProgressIssue[]> {
|
|
113
|
+
const query = `query LinearProgressIssues($teamKey: String!, $after: String) {
|
|
114
|
+
issues(filter: { team: { key: { eq: $teamKey } } }, first: 100, after: $after) {
|
|
115
|
+
nodes { id identifier title url description state { name } team { key } }
|
|
116
|
+
pageInfo { hasNextPage endCursor }
|
|
117
|
+
}
|
|
118
|
+
}`;
|
|
119
|
+
const issues: ProgressIssue[] = [];
|
|
120
|
+
const cursors = new Set<string>();
|
|
121
|
+
let after: string | null = null;
|
|
122
|
+
do {
|
|
123
|
+
const response = await fetchFn('https://api.linear.app/graphql', {
|
|
124
|
+
method: 'POST', headers: { Authorization: apiKey, 'Content-Type': 'application/json' },
|
|
125
|
+
body: JSON.stringify({ query, variables: { teamKey, after } }),
|
|
126
|
+
});
|
|
127
|
+
if (!response.ok) throw new Error(`Linear GraphQL HTTP ${response.status}`);
|
|
128
|
+
const result = await response.json() as { errors?: unknown[]; data?: { issues?: { nodes?: Array<Record<string, unknown>>; pageInfo?: { hasNextPage: boolean; endCursor: string | null } } } };
|
|
129
|
+
const page = result.data?.issues;
|
|
130
|
+
if (result.errors?.length || !Array.isArray(page?.nodes)) throw new Error(`Linear ${teamKey} issue query failed`);
|
|
131
|
+
for (const node of page.nodes) {
|
|
132
|
+
if (typeof node.id !== 'string' || typeof node.identifier !== 'string' || typeof node.title !== 'string' || typeof node.url !== 'string') continue;
|
|
133
|
+
const state = node.state && typeof node.state === 'object' ? (node.state as { name?: unknown }).name : undefined;
|
|
134
|
+
const team = node.team && typeof node.team === 'object' ? (node.team as { key?: unknown }).key : undefined;
|
|
135
|
+
issues.push({ id: node.id, identifier: node.identifier, title: node.title, url: node.url,
|
|
136
|
+
description: typeof node.description === 'string' ? node.description : '', state: typeof state === 'string' ? state : 'unknown',
|
|
137
|
+
teamKey: typeof team === 'string' ? team : '' });
|
|
138
|
+
}
|
|
139
|
+
const info = page.pageInfo;
|
|
140
|
+
if (info?.hasNextPage && (!info.endCursor || cursors.has(info.endCursor))) throw new Error(`Linear ${teamKey} cursor missing or repeated`);
|
|
141
|
+
after = info?.hasNextPage ? info.endCursor : null;
|
|
142
|
+
if (after) cursors.add(after);
|
|
143
|
+
} while (after);
|
|
144
|
+
return issues;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async function fetchAllowlistedIssue(apiKey: string, identifier: string, fetchFn: typeof fetch = fetch): Promise<ProgressIssue | null> {
|
|
148
|
+
const query = `query LinearAllowlistedProgressIssue($identifier: String!) {
|
|
149
|
+
issue(id: $identifier) { id identifier title url description state { name } team { key } }
|
|
150
|
+
}`;
|
|
151
|
+
const response = await fetchFn('https://api.linear.app/graphql', {
|
|
152
|
+
method: 'POST', headers: { Authorization: apiKey, 'Content-Type': 'application/json' },
|
|
153
|
+
body: JSON.stringify({ query, variables: { identifier } }),
|
|
154
|
+
});
|
|
155
|
+
if (!response.ok) throw new Error(`Linear ${identifier} lookup HTTP ${response.status}`);
|
|
156
|
+
const result = await response.json() as { errors?: unknown[]; data?: { issue?: Record<string, unknown> | null } };
|
|
157
|
+
const node = result.data?.issue;
|
|
158
|
+
if (result.errors?.length) throw new Error(`Linear ${identifier} lookup failed`);
|
|
159
|
+
if (!node || typeof node.id !== 'string' || typeof node.identifier !== 'string' || typeof node.title !== 'string' || typeof node.url !== 'string') return null;
|
|
160
|
+
const state = node.state && typeof node.state === 'object' ? (node.state as { name?: unknown }).name : undefined;
|
|
161
|
+
const team = node.team && typeof node.team === 'object' ? (node.team as { key?: unknown }).key : undefined;
|
|
162
|
+
return { id: node.id, identifier: node.identifier, title: node.title, url: node.url,
|
|
163
|
+
description: typeof node.description === 'string' ? node.description : '', state: typeof state === 'string' ? state : 'unknown',
|
|
164
|
+
teamKey: typeof team === 'string' ? team : '' };
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function countMarker(apiKey: string, issueId: string, marker: string, fetchFn: typeof fetch = fetch): Promise<number> {
|
|
168
|
+
const query = `query LinearProgressComments($id: String!, $after: String) {
|
|
169
|
+
issue(id: $id) { comments(first: 100, after: $after) { nodes { body } pageInfo { hasNextPage endCursor } } }
|
|
170
|
+
}`;
|
|
171
|
+
const cursors = new Set<string>();
|
|
172
|
+
let after: string | null = null;
|
|
173
|
+
let count = 0;
|
|
174
|
+
do {
|
|
175
|
+
const response = await fetchFn('https://api.linear.app/graphql', {
|
|
176
|
+
method: 'POST', headers: { Authorization: apiKey, 'Content-Type': 'application/json' },
|
|
177
|
+
body: JSON.stringify({ query, variables: { id: issueId, after } }),
|
|
178
|
+
});
|
|
179
|
+
if (!response.ok) throw new Error(`Linear comment lookup HTTP ${response.status}`);
|
|
180
|
+
const result = await response.json() as { errors?: unknown[]; data?: { issue?: { comments?: { nodes?: Array<{ body?: unknown }>; pageInfo?: { hasNextPage: boolean; endCursor: string | null } } } } };
|
|
181
|
+
const comments = result.data?.issue?.comments;
|
|
182
|
+
if (result.errors?.length || !Array.isArray(comments?.nodes)) throw new Error('Linear comment lookup failed');
|
|
183
|
+
count += comments.nodes.filter(comment => typeof comment.body === 'string' && comment.body.includes(marker)).length;
|
|
184
|
+
const info = comments.pageInfo;
|
|
185
|
+
if (info?.hasNextPage && (!info.endCursor || cursors.has(info.endCursor))) throw new Error('Linear comment cursor missing or repeated');
|
|
186
|
+
after = info?.hasNextPage ? info.endCursor : null;
|
|
187
|
+
if (after) cursors.add(after);
|
|
188
|
+
} while (after);
|
|
189
|
+
return count;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export async function runLinearProgressSync(options: {
|
|
193
|
+
version: string; now?: Date; root?: string; runId?: string; apply?: boolean;
|
|
194
|
+
allowIssueIdentifiers?: readonly string[];
|
|
195
|
+
checklist?: Checklist; issues?: readonly ProgressIssue[]; decisions?: readonly DecisionEntry[];
|
|
196
|
+
getApiKey?: (id: string) => Promise<string | undefined>;
|
|
197
|
+
fetch?: typeof fetch;
|
|
198
|
+
countMarker?: (issue: ProgressIssue, marker: string) => Promise<number>;
|
|
199
|
+
postComment?: (issue: ProgressIssue, body: string) => Promise<void>;
|
|
200
|
+
log?: (event: string, data: Record<string, unknown>) => void;
|
|
201
|
+
}): Promise<ProgressSyncResult> {
|
|
202
|
+
const now = options.now ?? new Date();
|
|
203
|
+
const day = kstDay(now);
|
|
204
|
+
const root = options.root ?? effectiveInstanceRoot();
|
|
205
|
+
const checklist = options.checklist ?? listChecklist(options.version, root);
|
|
206
|
+
const decisions = options.decisions ?? new DecisionLedger({ stateDir: root }).list({ status: 'all' });
|
|
207
|
+
const apiKey = (options.getApiKey ?? getSecretAsync)('connector.linear.apiKey');
|
|
208
|
+
const resolvedKey = await apiKey;
|
|
209
|
+
const fetchFn = options.fetch ?? fetch;
|
|
210
|
+
if (!resolvedKey) throw new Error('connector.linear.apiKey missing');
|
|
211
|
+
const allowedIdentifiers = [...new Set(options.allowIssueIdentifiers ?? [])];
|
|
212
|
+
const lookupFailures: Array<{ identifier: string; reason: string }> = [];
|
|
213
|
+
let issues: ProgressIssue[];
|
|
214
|
+
if (options.issues) issues = [...options.issues];
|
|
215
|
+
else if (options.apply) {
|
|
216
|
+
const lookups = await Promise.all(allowedIdentifiers.map(async identifier => {
|
|
217
|
+
try {
|
|
218
|
+
const issue = await fetchAllowlistedIssue(resolvedKey, identifier, fetchFn);
|
|
219
|
+
if (!issue) lookupFailures.push({ identifier, reason: 'allowlisted issue not found' });
|
|
220
|
+
return issue;
|
|
221
|
+
} catch (error) {
|
|
222
|
+
lookupFailures.push({ identifier, reason: (error instanceof Error ? error.message : String(error)).slice(0, 200) });
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
}));
|
|
226
|
+
issues = lookups.filter((issue): issue is ProgressIssue => issue !== null);
|
|
227
|
+
} else issues = await fetchTeamIssues(resolvedKey, 'DEMO', fetchFn);
|
|
228
|
+
const links = resolveExplicitProgressLinks(issues, checklist, decisions);
|
|
229
|
+
const previews = links.map(link => renderProgressPreview(link, checklist, day));
|
|
230
|
+
const linkedIdentifiers = new Set(links.map(link => link.issue.identifier));
|
|
231
|
+
const fetchedIdentifiers = new Set(issues.map(issue => issue.identifier));
|
|
232
|
+
const lookupFailureIdentifiers = new Set(lookupFailures.map(failure => failure.identifier));
|
|
233
|
+
const missingApproved = options.apply ? allowedIdentifiers.filter(identifier => !fetchedIdentifiers.has(identifier) && !lookupFailureIdentifiers.has(identifier))
|
|
234
|
+
.map(identifier => ({ identifier, reason: 'allowlisted issue not found' })) : [];
|
|
235
|
+
const unlinkedApproved = options.apply ? allowedIdentifiers.filter(identifier => issues.some(issue => issue.identifier === identifier) && !linkedIdentifiers.has(identifier))
|
|
236
|
+
.map(identifier => ({ identifier, reason: 'allowlisted issue has no explicit checklist/decision link' })) : [];
|
|
237
|
+
const unresolvedApproved = [...lookupFailures, ...missingApproved, ...unlinkedApproved];
|
|
238
|
+
const result: ProgressSyncResult = { day, candidates: previews, posted: [], alreadyPresent: [], skipped: [], failures: unresolvedApproved };
|
|
239
|
+
const log = (event: string, data: Record<string, unknown>) => {
|
|
240
|
+
const enriched = { day, ...data, ...(options.runId ? { runId: options.runId } : {}) };
|
|
241
|
+
if (options.log) options.log(event, enriched);
|
|
242
|
+
else debug.log('loop.rhythm-daily.linear-progress', event, enriched);
|
|
243
|
+
};
|
|
244
|
+
const check = options.countMarker ?? ((issue: ProgressIssue, marker: string) => countMarker(resolvedKey, issue.id, marker, fetchFn));
|
|
245
|
+
const post = options.postComment ?? ((issue: ProgressIssue, body: string) => commentLinearIssue({ apiKey: resolvedKey, issueId: issue.id, body }));
|
|
246
|
+
for (const failure of unresolvedApproved) log('approved-issue-unresolved', failure);
|
|
247
|
+
for (const preview of previews) {
|
|
248
|
+
const issue = links.find(link => link.issue.identifier === preview.identifier)!.issue;
|
|
249
|
+
const marker = `<!-- elanous-linear-progress:${day}:${issue.identifier} -->`;
|
|
250
|
+
if (issue.teamKey !== 'DEMO') {
|
|
251
|
+
result.skipped.push(issue.identifier);
|
|
252
|
+
log('not-demo-team', { identifier: issue.identifier, teamKey: issue.teamKey || 'unknown', sources: preview.sources });
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
let release: (() => void) | undefined;
|
|
256
|
+
let stillHeld: (() => boolean) | undefined;
|
|
257
|
+
try {
|
|
258
|
+
if (options.apply && !options.allowIssueIdentifiers?.includes(issue.identifier)) {
|
|
259
|
+
result.skipped.push(issue.identifier);
|
|
260
|
+
log('not-approved', { identifier: issue.identifier, sources: preview.sources });
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
if (options.apply) {
|
|
264
|
+
const lockDir = join(root, 'rhythm', 'linear-progress-sync');
|
|
265
|
+
mkdirSync(lockDir, { recursive: true, mode: 0o700 });
|
|
266
|
+
const lockName = createHash('sha256').update(`${day}:${issue.id}`).digest('hex');
|
|
267
|
+
const lock = await acquireLockAsync(join(lockDir, `${lockName}.lock`), { staleMs: 120_000, maxTries: 240 });
|
|
268
|
+
release = lock.release;
|
|
269
|
+
stillHeld = lock.stillHeld;
|
|
270
|
+
if (!stillHeld()) throw new Error('Linear progress lock lost before marker check');
|
|
271
|
+
}
|
|
272
|
+
const existing = await check(issue, marker);
|
|
273
|
+
if (existing > 1) {
|
|
274
|
+
result.failures.push({ identifier: issue.identifier, reason: `duplicate-marker-count=${existing}` });
|
|
275
|
+
log('duplicate-marker', { identifier: issue.identifier, markerCount: existing, sources: preview.sources });
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
if (existing === 1) {
|
|
279
|
+
result.alreadyPresent.push(issue.identifier);
|
|
280
|
+
log('already-present', { identifier: issue.identifier, markerCount: 1, sources: preview.sources });
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
if (!options.apply) {
|
|
284
|
+
result.skipped.push(issue.identifier);
|
|
285
|
+
log('dry-run', { identifier: issue.identifier, markerCount: 0, sources: preview.sources });
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (!release || !stillHeld?.()) throw new Error('Linear progress write lock unavailable or lost');
|
|
289
|
+
await post(issue, preview.body);
|
|
290
|
+
const verified = await check(issue, marker);
|
|
291
|
+
if (verified !== 1) throw new Error(`post-verification-marker-count=${verified}`);
|
|
292
|
+
result.posted.push(issue.identifier);
|
|
293
|
+
log('posted', { identifier: issue.identifier, markerCount: verified, sources: preview.sources });
|
|
294
|
+
} catch (error) {
|
|
295
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
296
|
+
result.failures.push({ identifier: issue.identifier, reason: reason.slice(0, 200) });
|
|
297
|
+
log('failed', { identifier: issue.identifier, reason: reason.slice(0, 200), sources: preview.sources });
|
|
298
|
+
} finally {
|
|
299
|
+
release?.();
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return result;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (import.meta.main) {
|
|
306
|
+
const version = process.argv.find((arg, index) => process.argv[index - 1] === '--version');
|
|
307
|
+
if (!version) throw new Error('--version required');
|
|
308
|
+
if (process.argv.includes('--apply')) throw new Error('live posting requires the approved scheduled daily path');
|
|
309
|
+
const result = await runLinearProgressSync({ version, apply: false });
|
|
310
|
+
console.log(JSON.stringify(result));
|
|
311
|
+
}
|
package/scripts/ux-sim.ts
CHANGED
|
@@ -21,10 +21,11 @@
|
|
|
21
21
|
// bun scripts/ux-sim.ts emit child-error-long --json # 사건 주입(L0): 격리 우주 원장에 주입 줄 → 소비자 목록
|
|
22
22
|
//
|
|
23
23
|
// catalog list/show 는 재사용 장치의 참조를 보여 준다. 선언된 TUI 장면은 실제 위젯 render() 를 부른다 — 흉내 렌더러가 아니다.
|
|
24
|
+
// catalog devices 는 장치별 진입 명령·logs/event·최근 사용 메타데이터를 읽기 전용으로 출력한다.
|
|
24
25
|
import { simRenderLogFrame } from '../src/ux-sim/render-frame.js';
|
|
25
26
|
import { simTypeaheadState, type TurnPhase, type TurnSimSpec } from '../src/ux-sim/turn-states.js';
|
|
26
27
|
import { renderTurnTypeaheadQueueRow, renderTurnTypeaheadEcho } from '../src/chat/turn-typeahead.js';
|
|
27
|
-
import { loadMockScenarioCatalog, renderMockScenarioDetails, renderMockScenarioList } from '../src/ux-sim/mock-scenario-catalog.js';
|
|
28
|
+
import { loadMockScenarioCatalog, renderMockScenarioDetails, renderMockScenarioDevices, renderMockScenarioList } from '../src/ux-sim/mock-scenario-catalog.js';
|
|
28
29
|
|
|
29
30
|
const PHASES: TurnPhase[] = [
|
|
30
31
|
'idle', 'thinking', 'streaming', 'streaming-with-subagents', 'harness-child', 'interrupted',
|
|
@@ -37,6 +38,11 @@ if (argv[0] === 'list') {
|
|
|
37
38
|
console.log(renderMockScenarioList(loadMockScenarioCatalog()).join('\n'));
|
|
38
39
|
process.exit(0);
|
|
39
40
|
}
|
|
41
|
+
if (argv[0] === 'devices') {
|
|
42
|
+
if (argv.length !== 1) { console.error('usage: bun scripts/ux-sim.ts devices'); process.exit(2); }
|
|
43
|
+
console.log(renderMockScenarioDevices(loadMockScenarioCatalog()).join('\n'));
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
40
46
|
if (argv[0] === 'show') {
|
|
41
47
|
if (argv.length !== 2) { console.error('usage: bun scripts/ux-sim.ts show <MS-id>'); process.exit(2); }
|
|
42
48
|
try {
|
|
@@ -1092,7 +1092,15 @@ async function plan() {
|
|
|
1092
1092
|
ovSelections = sel.selections.map((x) => ({ overlayId: x.overlayId, verdict: x.verdict, detail: x.detail }));
|
|
1093
1093
|
if (sel.applied.length > 0) {
|
|
1094
1094
|
const applied = applyGraphOverlays(decl.template, sel.applied);
|
|
1095
|
-
if (applied.ok) ovPatches = applied.patches.map((x) =>
|
|
1095
|
+
if (applied.ok) ovPatches = applied.patches.map((x) => {
|
|
1096
|
+
if (x.field === 'edge-rerouted') return {
|
|
1097
|
+
overlayId: x.overlayId, node: x.from, field: x.field, before: x.was, after: x.to,
|
|
1098
|
+
};
|
|
1099
|
+
if (x.field === 'node-added') return {
|
|
1100
|
+
overlayId: x.overlayId, node: x.node, field: x.field, before: null, after: x.kind,
|
|
1101
|
+
};
|
|
1102
|
+
return { overlayId: x.overlayId, node: x.node, field: x.field, before: x.before, after: x.after };
|
|
1103
|
+
});
|
|
1096
1104
|
else ovError = `얹다가 거절됐다 — ${applied.rejections.map((r) => r.kind).join(', ')}`;
|
|
1097
1105
|
}
|
|
1098
1106
|
}
|
|
@@ -4,6 +4,7 @@ import { dirname, isAbsolute, join } from 'node:path';
|
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
6
|
import { userConfigPath } from '../src/user-config.js';
|
|
7
|
+
import type { WarmWorkerCandidate } from '../src/task-orchestrator/surfaces/pod-warm-worker-provider.js';
|
|
7
8
|
|
|
8
9
|
const TOKEN = /^[a-f0-9]{64}$/;
|
|
9
10
|
const SHA = /^[a-f0-9]{40}$/;
|
|
@@ -14,7 +15,8 @@ const TIERS = new Set(['lite', 'standard']);
|
|
|
14
15
|
type JsonObject = Record<string, unknown>;
|
|
15
16
|
|
|
16
17
|
export interface WarmPoolProviderConfig {
|
|
17
|
-
candidates: [];
|
|
18
|
+
candidates: WarmWorkerCandidate[];
|
|
19
|
+
expandPoolTemplatesToQuota: boolean;
|
|
18
20
|
poolTemplates: Array<{
|
|
19
21
|
host: string;
|
|
20
22
|
tier: 'lite' | 'standard';
|
|
@@ -47,6 +49,25 @@ export interface AssembleWarmPoolProviderConfigInput {
|
|
|
47
49
|
machineTokens: Record<string, string>;
|
|
48
50
|
}
|
|
49
51
|
|
|
52
|
+
/** Keep a deployment canary to one explicit worker instead of expanding its profile quota. */
|
|
53
|
+
export function selectSingleWarmPoolCandidate(config: WarmPoolProviderConfig, selection: string): WarmPoolProviderConfig {
|
|
54
|
+
const match = /^([a-zA-Z0-9][a-zA-Z0-9._-]*)\/(lite|standard)$/.exec(selection);
|
|
55
|
+
if (!match) throw new Error('--single-candidate must be HOST/lite or HOST/standard');
|
|
56
|
+
const [, host, tier] = match;
|
|
57
|
+
const template = config.poolTemplates.find(candidate => candidate.host === host && candidate.tier === tier);
|
|
58
|
+
if (!template) throw new Error(`warm pool template not found: ${host}/${tier}`);
|
|
59
|
+
const index = 1;
|
|
60
|
+
return {
|
|
61
|
+
...config,
|
|
62
|
+
candidates: [{ host, tier: tier as 'lite' | 'standard', spec: {
|
|
63
|
+
...template.spec,
|
|
64
|
+
name: `warm-${host}-${tier}-${index}`,
|
|
65
|
+
workerId: `${template.spec.workerId}-${tier}-${index}`,
|
|
66
|
+
} }],
|
|
67
|
+
poolTemplates: [],
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
50
71
|
function object(value: unknown, label: string): JsonObject {
|
|
51
72
|
if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${label} is required`);
|
|
52
73
|
return value as JsonObject;
|
|
@@ -117,6 +138,9 @@ export function assembleWarmPoolProviderConfig(input: AssembleWarmPoolProviderCo
|
|
|
117
138
|
const imageRepository = text(pool.imageRepository, 'pod.warmPool.imageRepository').replace(/\/$/, '');
|
|
118
139
|
const imageDigest = text(pool.imageDigest, 'pod.warmPool.imageDigest');
|
|
119
140
|
if (!DIGEST.test(imageDigest)) throw new Error('pod.warmPool.imageDigest must be a sha256 digest');
|
|
141
|
+
const expandPoolTemplatesToQuota = pool.expandPoolTemplatesToQuota;
|
|
142
|
+
if (expandPoolTemplatesToQuota !== undefined && typeof expandPoolTemplatesToQuota !== 'boolean')
|
|
143
|
+
throw new Error('pod.warmPool.expandPoolTemplatesToQuota must be a boolean');
|
|
120
144
|
const lockHash = text(pool.lockHash, 'pod.warmPool.lockHash');
|
|
121
145
|
if (!LOCK_HASH.test(lockHash)) throw new Error('pod.warmPool.lockHash must be a 64-character SHA-256');
|
|
122
146
|
const architecture = text(pool.architecture, 'pod.warmPool.architecture');
|
|
@@ -150,7 +174,8 @@ export function assembleWarmPoolProviderConfig(input: AssembleWarmPoolProviderCo
|
|
|
150
174
|
},
|
|
151
175
|
};
|
|
152
176
|
});
|
|
153
|
-
return { candidates: [],
|
|
177
|
+
return { candidates: [], expandPoolTemplatesToQuota: expandPoolTemplatesToQuota === true,
|
|
178
|
+
poolTemplates, profileConfig: { pod: { warmPoolProfile: profile } },
|
|
154
179
|
controlUrl: controlUrl(input.controlUrl), memberToken: token(input.memberToken, 'member token'), machineTokens };
|
|
155
180
|
}
|
|
156
181
|
|
|
@@ -183,11 +208,12 @@ interface CliOptions {
|
|
|
183
208
|
output: string;
|
|
184
209
|
dryRun: boolean;
|
|
185
210
|
serve: boolean;
|
|
211
|
+
singleCandidate?: string;
|
|
186
212
|
}
|
|
187
213
|
|
|
188
214
|
function parseArgs(argv: readonly string[]): CliOptions {
|
|
189
215
|
let configPath = userConfigPath(), controlUrl = '', memberTokenFile = '', output = '';
|
|
190
|
-
let dryRun = false, serve = false;
|
|
216
|
+
let dryRun = false, serve = false, singleCandidate: string | undefined;
|
|
191
217
|
const machineTokenFiles: Record<string, string> = {};
|
|
192
218
|
for (let index = 0; index < argv.length; index++) {
|
|
193
219
|
const arg = argv[index];
|
|
@@ -206,14 +232,15 @@ function parseArgs(argv: readonly string[]): CliOptions {
|
|
|
206
232
|
} else if (arg === '--output') output = next();
|
|
207
233
|
else if (arg === '--dry-run') dryRun = true;
|
|
208
234
|
else if (arg === '--serve') serve = true;
|
|
235
|
+
else if (arg === '--single-candidate') singleCandidate = next();
|
|
209
236
|
else throw new Error(`unknown argument: ${arg}`);
|
|
210
237
|
}
|
|
211
238
|
if (!isAbsolute(configPath) || !controlUrl || !isAbsolute(memberTokenFile))
|
|
212
|
-
throw new Error('usage: --config ABSOLUTE --control-url URL --member-token-file ABSOLUTE --machine-token HOST=ABSOLUTE [--output ABSOLUTE] [--dry-run|--serve]');
|
|
239
|
+
throw new Error('usage: --config ABSOLUTE --control-url URL --member-token-file ABSOLUTE --machine-token HOST=ABSOLUTE [--output ABSOLUTE] [--single-candidate HOST/TIER] [--dry-run|--serve]');
|
|
213
240
|
if (Object.values(machineTokenFiles).some(file => !isAbsolute(file))) throw new Error('machine token files must be absolute');
|
|
214
241
|
if (dryRun && serve) throw new Error('--dry-run and --serve cannot be combined');
|
|
215
242
|
return { configPath, controlUrl, memberTokenFile, machineTokenFiles,
|
|
216
|
-
output: output || join(dirname(configPath), 'warm-pod-provider.json'), dryRun, serve };
|
|
243
|
+
output: output || join(dirname(configPath), 'warm-pod-provider.json'), dryRun, serve, singleCandidate };
|
|
217
244
|
}
|
|
218
245
|
|
|
219
246
|
function readPrivateToken(path: string, label: string): string {
|
|
@@ -228,8 +255,9 @@ export async function runWarmPoolProviderConfig(argv: readonly string[]): Promis
|
|
|
228
255
|
.map(([host, path]) => [host, readPrivateToken(path, `machine token for ${host}`)]));
|
|
229
256
|
const assembled = assembleWarmPoolProviderConfig({ config, controlUrl: options.controlUrl,
|
|
230
257
|
memberToken: readPrivateToken(options.memberTokenFile, 'member token'), machineTokens });
|
|
231
|
-
|
|
232
|
-
|
|
258
|
+
const selected = options.singleCandidate ? selectSingleWarmPoolCandidate(assembled, options.singleCandidate) : assembled;
|
|
259
|
+
if (!options.dryRun) writeWarmPoolProviderConfig(options.output, selected);
|
|
260
|
+
process.stdout.write(`${JSON.stringify({ output: options.output, config: redact(selected),
|
|
233
261
|
...(options.serve ? { serve: { command: `ELANOUS_WARM_POD_PROVIDER_CONFIG=${shellQuote(options.output)} bun src/task-orchestrator/surfaces/pod-warm-worker-provider.ts --serve` } } : {}) })}\n`);
|
|
234
262
|
if (!options.serve) return;
|
|
235
263
|
const provider = fileURLToPath(new URL('../src/task-orchestrator/surfaces/pod-warm-worker-provider.ts', import.meta.url));
|
package/src/acp/agent-manager.ts
CHANGED
|
@@ -76,6 +76,7 @@ export class AcpAgentManager {
|
|
|
76
76
|
agent = new CodexAppServerAgent({
|
|
77
77
|
backendId,
|
|
78
78
|
...opts,
|
|
79
|
+
remoteSocketPath: process.env.ELANOUS_CODEX_REMOTE_SIDETAB_SOCKET || undefined,
|
|
79
80
|
elicitationHandler: createAskUserElicitationHandler(),
|
|
80
81
|
}) as unknown as AcpAgent;
|
|
81
82
|
} else {
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
import {
|
|
32
32
|
CodexAppServerClient,
|
|
33
33
|
spawnCodexAppServer,
|
|
34
|
+
spawnCodexRemoteTui,
|
|
34
35
|
type SpawnCodexAppServerOpts,
|
|
35
36
|
type SpawnedCodexAppServer,
|
|
36
37
|
} from './codex-app-server-client.js';
|
|
@@ -713,6 +714,8 @@ export interface CodexAppServerAgentOpts {
|
|
|
713
714
|
readonly codexBinary?: string;
|
|
714
715
|
/** Session-scoped argv forwarded to `spawnCodexAppServer`. */
|
|
715
716
|
readonly codexArgs?: readonly string[];
|
|
717
|
+
/** Explicit opt-in Codex remote side-tab Unix socket path. */
|
|
718
|
+
readonly remoteSocketPath?: string;
|
|
716
719
|
readonly env?: Record<string, string>;
|
|
717
720
|
readonly log?: (msg: string) => void;
|
|
718
721
|
/** Called after a successful initialize with this backend's advertised capabilities.
|
|
@@ -770,6 +773,7 @@ export interface CodexAppServerAgentOpts {
|
|
|
770
773
|
readonly _spawnFactory?: (
|
|
771
774
|
opts: SpawnCodexAppServerOpts,
|
|
772
775
|
) => SpawnedCodexAppServer;
|
|
776
|
+
readonly _remoteTuiSpawnForTesting?: typeof spawnCodexRemoteTui;
|
|
773
777
|
}
|
|
774
778
|
|
|
775
779
|
export class CodexAppServerAgent {
|
|
@@ -777,12 +781,14 @@ export class CodexAppServerAgent {
|
|
|
777
781
|
private readonly cwd?: string;
|
|
778
782
|
private readonly codexBinary?: string;
|
|
779
783
|
private readonly codexArgs?: readonly string[];
|
|
784
|
+
private readonly remoteSocketPath?: string;
|
|
780
785
|
private readonly env?: Record<string, string>;
|
|
781
786
|
private readonly log: (msg: string) => void;
|
|
782
787
|
private readonly onCapabilities: ((capabilities: ElanousCapabilities) => void) | undefined;
|
|
783
788
|
|
|
784
789
|
private client: CodexAppServerClient | null;
|
|
785
790
|
private child: SpawnedCodexAppServer['child'] | null = null;
|
|
791
|
+
private remoteTuiChild: ReturnType<typeof spawnCodexRemoteTui> | null = null;
|
|
786
792
|
private initialized = false;
|
|
787
793
|
|
|
788
794
|
private readonly approvalAdapter: CodexApprovalAdapter;
|
|
@@ -877,12 +883,14 @@ export class CodexAppServerAgent {
|
|
|
877
883
|
private readonly _spawnFactory:
|
|
878
884
|
| ((opts: SpawnCodexAppServerOpts) => SpawnedCodexAppServer)
|
|
879
885
|
| undefined;
|
|
886
|
+
private readonly _remoteTuiSpawnForTesting: typeof spawnCodexRemoteTui | undefined;
|
|
880
887
|
|
|
881
888
|
constructor(opts: CodexAppServerAgentOpts) {
|
|
882
889
|
this.backendId = opts.backendId;
|
|
883
890
|
this.cwd = opts.cwd;
|
|
884
891
|
this.codexBinary = opts.codexBinary;
|
|
885
892
|
this.codexArgs = opts.codexArgs ? [...opts.codexArgs] : undefined;
|
|
893
|
+
this.remoteSocketPath = opts.remoteSocketPath;
|
|
886
894
|
this.env = opts.env;
|
|
887
895
|
this.log = opts.log ?? ((msg) => debug.log('acp.cxn.appserver.agent', msg));
|
|
888
896
|
this.onCapabilities = opts.onCapabilities;
|
|
@@ -894,6 +902,7 @@ export class CodexAppServerAgent {
|
|
|
894
902
|
this.imageTempDir = opts.imageTempDir ?? defaultImageTempDir();
|
|
895
903
|
this._clientForTesting = opts._clientForTesting;
|
|
896
904
|
this._spawnFactory = opts._spawnFactory;
|
|
905
|
+
this._remoteTuiSpawnForTesting = opts._remoteTuiSpawnForTesting;
|
|
897
906
|
this.threadIndex = opts._threadIndexForTesting ?? globalCasThreadIndex();
|
|
898
907
|
// M6 · idle hibernate config. Env override only applies when opts
|
|
899
908
|
// didn't set it explicitly so tests can pin a value regardless of
|
|
@@ -979,6 +988,7 @@ export class CodexAppServerAgent {
|
|
|
979
988
|
env: { ...rotatedCodexChildEnv(childEnv), ...(this.env ?? {}) },
|
|
980
989
|
codexBinary,
|
|
981
990
|
codexArgs: this.codexArgs,
|
|
991
|
+
remoteSocketPath: this.remoteSocketPath,
|
|
982
992
|
};
|
|
983
993
|
const spawned = spawnFn(spawnOpts);
|
|
984
994
|
this.client = spawned.client;
|
|
@@ -1069,6 +1079,13 @@ export class CodexAppServerAgent {
|
|
|
1069
1079
|
/* swallow */
|
|
1070
1080
|
}
|
|
1071
1081
|
}
|
|
1082
|
+
if (this.remoteTuiChild) {
|
|
1083
|
+
try {
|
|
1084
|
+
this.remoteTuiChild.kill('SIGTERM');
|
|
1085
|
+
} catch {
|
|
1086
|
+
/* swallow */
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1072
1089
|
if (this.child) {
|
|
1073
1090
|
try {
|
|
1074
1091
|
this.child.kill('SIGTERM');
|
|
@@ -1078,6 +1095,7 @@ export class CodexAppServerAgent {
|
|
|
1078
1095
|
}
|
|
1079
1096
|
this.client = null;
|
|
1080
1097
|
this.child = null;
|
|
1098
|
+
this.remoteTuiChild = null;
|
|
1081
1099
|
this.initialized = false;
|
|
1082
1100
|
this.sessionToThread.clear();
|
|
1083
1101
|
this.threadToSession.clear();
|
|
@@ -1110,6 +1128,7 @@ export class CodexAppServerAgent {
|
|
|
1110
1128
|
* disabled. unref() so a CLI can still exit cleanly when the daemon
|
|
1111
1129
|
* is the only thing keeping the loop alive. */
|
|
1112
1130
|
private armIdleTimer(): void {
|
|
1131
|
+
if (this.remoteSocketPath) return;
|
|
1113
1132
|
if (this.idleTimerHandle !== null) return;
|
|
1114
1133
|
if (this.idleTimeoutMs <= 0) return;
|
|
1115
1134
|
this.idleTimerHandle = setInterval(() => {
|
|
@@ -1328,6 +1347,20 @@ export class CodexAppServerAgent {
|
|
|
1328
1347
|
// M6 · brand-new sessions are alive in the current daemon by
|
|
1329
1348
|
// definition · no thread/resume needed before the first turn.
|
|
1330
1349
|
this.currentDaemonSessions.add(sessionId);
|
|
1350
|
+
if (this.remoteSocketPath && !this.remoteTuiChild) {
|
|
1351
|
+
const explicitEnv = this.env ?? {};
|
|
1352
|
+
const tuiEnv = {
|
|
1353
|
+
...rotatedCodexChildEnv({ ...process.env, ...explicitEnv }),
|
|
1354
|
+
...explicitEnv,
|
|
1355
|
+
};
|
|
1356
|
+
const spawnRemoteTui = this._remoteTuiSpawnForTesting ?? spawnCodexRemoteTui;
|
|
1357
|
+
this.remoteTuiChild = spawnRemoteTui({
|
|
1358
|
+
codexBinary: this.codexBinary ?? resolvePreferredCodexBinary(),
|
|
1359
|
+
socketPath: this.remoteSocketPath,
|
|
1360
|
+
cwd: this.cwd,
|
|
1361
|
+
env: tuiEnv,
|
|
1362
|
+
});
|
|
1363
|
+
}
|
|
1331
1364
|
debug.log('acp.client', 'session-new', { backendId: this.backendId, sessionId });
|
|
1332
1365
|
return sessionId;
|
|
1333
1366
|
}
|