elanous 0.2.31 → 0.2.34
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/{LSXfY0u9QtfDbejY0Ukf_ → L04y73dlwKeTW-GetaTF3}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/1162.c69abda138c7ce43.js +79 -0
- package/apps/pwa/out/_next/static/chunks/1449-1fede62af84c3e43.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1598-13fc845935e816df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1639.62c5e16fa20d242f.js +94 -0
- package/apps/pwa/out/_next/static/chunks/{4174.92ed04922709ac9e.js → 1644.35dd25240ae24e4b.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1661-adb8b2babc9aaf8c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2940-619bfd8ef337c611.js → 1895-60ed0e341c658bd4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5525.86debf231e181813.js → 2124.ed5bf480cea7f85b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2147.107c0fc6146fb15a.js +23 -0
- package/apps/pwa/out/_next/static/chunks/2202-ef1c9b000c3074fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2247.1e326638ee43e672.js +115 -0
- package/apps/pwa/out/_next/static/chunks/2268.56e1e3d58180abae.js +8 -0
- package/apps/pwa/out/_next/static/chunks/2469-606819c812414021.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6092.a7f99e68b188ca66.js → 2547.dd27303624cb4da8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2213.2ccbada92c33ea0f.js → 2554.3b5e200f5f5cfcd6.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/2593.e53c1620c0bb3599.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2690.e96671114222676a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2898-79ee1a5cc0cd9d13.js +1 -0
- package/apps/pwa/out/_next/static/chunks/298.26099a9f65e5c8ff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5173-233188df2f42c626.js → 2987-30cf9c2eb7b8bdd5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2992.51fc2a7295bd8139.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3541-ce3a5424ed5ad7f1.js → 3001-5a52788c813b6113.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3014-291245fba9df7b5b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3068.ee78201f0251a18d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3083.cd399a17e9365f78.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3103.84470c8445962f04.js +34 -0
- package/apps/pwa/out/_next/static/chunks/{6433.fc573af22bbc9ab7.js → 3110.0a7065f25c841818.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/3117-e1c474683fd1f824.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3121.779fafe3e44612c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3251-2c17bd5a91f8de2e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/326.3fb32322bb2ddf6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3411-f87314c6c66ebc73.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6157.0c9af021de4fb31b.js → 3414.172ad4ca2d9b08e8.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3421-7ff7fbaa156985a7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4745.67d6f99c245af3f7.js → 3498.cf2a15a8a9e5b926.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/381.f55dc63ea87735e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3819.163d4777f0a597f6.js +32 -0
- package/apps/pwa/out/_next/static/chunks/{5543.a438b8ab5a13ea47.js → 3837.722e053fb9f321ad.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4129-ab0a6189f1778633.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4361.93d14ba594b3a035.js +104 -0
- package/apps/pwa/out/_next/static/chunks/4364.7a7eb19cceb67d2f.js +286 -0
- package/apps/pwa/out/_next/static/chunks/4406.d71f506f7c3ee9d3.js +149 -0
- package/apps/pwa/out/_next/static/chunks/4461.2ad1514180ae7e29.js +148 -0
- package/apps/pwa/out/_next/static/chunks/4479.bd309cbe0e3842ee.js +64 -0
- package/apps/pwa/out/_next/static/chunks/4522-05966f777d66d13b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4543-9a3e9812e845de65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4557.f8f1d84a0d90d590.js +74 -0
- package/apps/pwa/out/_next/static/chunks/4589-79b11542179ef58c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4633-9f8f9f88ffbb8f5c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4831.23af4d10c0697b5e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4983.5951b85724f61f2a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b313b242.cb1265eea908db61.js → 4fa33ebd.21c1bd5b294496e6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{997ce8a5-2ad501927003b41b.js → 5014f970-22bef0b5210f7d60.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2112-e4efc21a6505d5bc.js → 5028-f0722e6114c313e7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2898.fd781bc7cf01a7b7.js → 5249.96a848656b582a93.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5311.16e0ffbfa5468b80.js +62 -0
- package/apps/pwa/out/_next/static/chunks/{9407.e49124dedf0f5e72.js → 5446.edf141cff9ef647d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9002.e5658224e3dc1b6f.js → 5489.ec2dd1b5272a19dc.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1335-6731f392c35216eb.js → 5576-82d3703636d5c4b9.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/559.df87695df637920c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5618-5c88f2f70178c4ad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5764.05487bf0b73ddb6b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5930.e678826c3f831aab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5dfb57f7.f2e3305326202474.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6053-d893974de92e6198.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2985.39ccdecd36848b12.js → 6086.913a69e6fa3e4a8b.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/6200-cefd6f33f59d765e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6314-edeba650ae686ac9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6316-bc9a9b74d7842d79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6476-13b9779b73528008.js +1 -0
- package/apps/pwa/out/_next/static/chunks/666-04db3ac4c8e3c66f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/670.682e55106ef915a6.js +77 -0
- package/apps/pwa/out/_next/static/chunks/{7862.30a8d6482bb238eb.js → 6740.43de73fc427c9fe2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6816.b7ba9d0a1a4a46a7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/690-fbbcc777f189af37.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6989.0d3d4020e5cb3df6.js +90 -0
- package/apps/pwa/out/_next/static/chunks/{2871.0bca6137343b3f76.js → 7005.1623d2aea78eb85f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7193-cf355cca5ba6c5d5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7217-d17393fe7af78fa6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7232.24edbd938a69c8d0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7295cd1e.b4b557908888eeee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7323.adb02de21991883c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7386.5d8e7e42e818dfb6.js +287 -0
- package/apps/pwa/out/_next/static/chunks/{7502.ccd5b8065545edd0.js → 7431.3051e9b8a4372d2d.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{3583.a05e88cc8d594628.js → 7448.478958ffbbba0ac0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7537.ba2208c5c656b8a3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7562.948255cbc3e79d33.js +41 -0
- package/apps/pwa/out/_next/static/chunks/7596-962ae6db6cfc9c83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7671.cff51beac212a2ba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7883.3916734ee16d3e58.js +27 -0
- package/apps/pwa/out/_next/static/chunks/{9989.3694300e5f000b14.js → 7952.b192c31b6a0e00cc.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/801.5b24e81eded22d1b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8176.8c9a8613f5a01ac1.js +36 -0
- package/apps/pwa/out/_next/static/chunks/819e78a6.fa3dd7f7da19bf61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8220-78978450c3183d8d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8221-eb60b5bc692a3361.js +1 -0
- package/apps/pwa/out/_next/static/chunks/826.e9a26064f474949e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5307.60f2209e809bd627.js → 8368.014caa8de2f5af34.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8459-a351487a4480f584.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8482-75823d513a4ce151.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8488.8da515248cda3f3a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9221.7d22eaf353a2d4e7.js → 8548.036c344973968847.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8584.388a1779d9b203af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8637.a55e098e61ffefb8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8817.61bb7ffbba502ecb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9398-6aed28f0a96d0d6f.js → 9131-fce7256c4180c4a5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9207-8e6a12db30373f32.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9263-00ae932c62696a86.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9318.caafc3a130e8769c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/932.da3fb55951882562.js +93 -0
- package/apps/pwa/out/_next/static/chunks/9433.002f8426ac75b6b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9464.dd631a5a14b1d660.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{3278.2e5d15b53a4091c8.js → 9550.d5f76828f972058c.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{2534.e85ae21ad0dac829.js → 9739.8d5f36ac67a3b236.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9743.beeabb9d5f86abe4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9843-a23d3f32dc43f715.js +1 -0
- package/apps/pwa/out/_next/static/chunks/994-28211077c7c587d5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7a1887c4.f36b88fba31da8fd.js → 9a8cb466.cc9fc9e6e46038aa.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{0bb0ff36.b8d418980951e5ba.js → 9b48c871.204d5d13e7809bd0.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/{409f1e57.d0649fc47691ebfe.js → abb4b98b.163e0f56e84ae35d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-3b4c947f174e33d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-369d5ce99483f859.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-63c0ed0eb26e5fce.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-62802c6003bc85cc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-ecb41560d4e77be9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-7b65ad8130c93e95.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-8755477c15a9060c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-5725447dd972c471.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-b979de0591a69375.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-6d0796bf4633751a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-59c31dc0394e67b4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-12dfc95f6cc5c718.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-25788244e66aa4dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-a2555dc705466322.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-4fb31eb476dcbad3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-3b4c947f174e33d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-578729adbeaa40cb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a1d20fffbec35205.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-4a558f94516b8004.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-9e3834705b86145e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-d7bff0f0905a662c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-cb1c5fe746ea4014.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-9ee320507356582a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66fd183b74835886.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-3272a064a01a9927.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-f281b7a7f6ef2529.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-d45a65f8b7124fcd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-e9c1fe684dd19a66.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-b8322932fc6e34de.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-82c66d9af2290575.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-63c6752009c97b05.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-bb33d42ebc358aec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-7e4c9379197d7214.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-38bf1e9a7001732b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-2e5b752012389d56.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-0a07363b130182a1.js → page-398c0faa173203f7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-002f53a965b6445c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7f75997f61a26269.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-3b4c947f174e33d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-05631753294f23fb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-edd700fd2cc3d7f8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-105f83ecb4594365.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-5823e87d2017f19c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-df3445b207ceceab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-b51ca09566c03de7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-8aacd5ded5dbac60.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-bae3365a0b3c6a8e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ed52b48ff1aa7fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-b6f8cad35fe00946.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-6d25ceda500d2457.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-b6401a5f2c962fe8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/ebf6cf5e.0d2f887b040e80fb.js +122 -0
- package/apps/pwa/out/_next/static/chunks/f09ec7d7-d29abe23edcbb193.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{ebc7d829.264a0bcb6c750b50.js → ffdc3a04.b9c23c1b28dd4a96.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-9322cb8a56ac081c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-2fbab294e49a1561.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-f36729f56621a8f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-2a62e450b47c6114.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-5e17f7b445f34d43.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-b4263e2190ea7adf.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 +9 -2
- package/docs/goal-context/README.md +1 -0
- package/graphs/default-loop.yaml +20 -3
- package/graphs/document-loop.yaml +21 -2
- package/graphs/implement-loop.yaml +11 -0
- package/graphs/journey/SCENARIOS.md +33 -0
- package/graphs/journey/recipes.yaml +1 -0
- package/graphs/journey/ta-journey.yaml +84 -0
- package/graphs/journey/units/author/author.yaml +20 -0
- package/graphs/journey/units/author/recipes.yaml +2 -0
- package/graphs/journey/units/green/green.yaml +20 -0
- package/graphs/journey/units/green/recipes.yaml +2 -0
- package/graphs/journey/units/pr/pr.yaml +20 -0
- package/graphs/journey/units/pr/recipes.yaml +2 -0
- package/graphs/journey/units/remember/recipes.yaml +2 -0
- package/graphs/journey/units/remember/remember.yaml +20 -0
- package/graphs/operate-loop.yaml +21 -2
- package/graphs/overlays/stop-heal-ladder.yaml +1 -1
- package/graphs/release-rehearsal/recipes.yaml +1 -1
- package/graphs/release-rehearsal/release-rehearsal.yaml +2 -2
- package/graphs/research-loop.yaml +23 -2
- package/graphs/units/dispatch-pod/dispatch-pod.yaml +50 -0
- package/graphs/units/dispatch-pod/recipes.yaml +14 -0
- package/graphs/units/entry/entry.yaml +50 -0
- package/graphs/units/entry/recipes.yaml +14 -0
- package/graphs/units/harvest/harvest.yaml +25 -0
- package/graphs/units/harvest/recipes.yaml +4 -0
- package/graphs/units/land/land.yaml +45 -0
- package/graphs/units/land/recipes.yaml +3 -0
- package/graphs/units/recipes.yaml +7 -0
- package/graphs/units/recover.yaml +39 -0
- package/graphs/units/reflect/recipes.yaml +3 -0
- package/graphs/units/reflect/reflect.yaml +15 -0
- package/graphs/units/task-agent-recover-review.yaml +17 -0
- package/graphs/units/task-agent-recover-wait.yaml +17 -0
- package/graphs/units/verbs/make-doc.yaml +34 -0
- package/graphs/units/verbs/recipes.yaml +33 -0
- package/graphs/units/verbs/verify.yaml +55 -0
- package/graphs/work/recipes.yaml +2 -0
- package/graphs/work/research-report.yaml +28 -0
- package/package.json +1 -1
- package/scripts/ci-typecheck-changed.ts +95 -17
- package/scripts/docs/generate-graph-anatomy.ts +19 -2
- package/scripts/graph-harvest-unit.ts +22 -0
- package/scripts/graph-units/journey-stub.ts +6 -0
- package/scripts/graph-units/land-enqueue.ts +78 -0
- package/scripts/graph-units/recover-plan.ts +15 -0
- package/scripts/graph-units/reflect-node.ts +88 -0
- package/scripts/graph-units/ta-journey-observe.ts +109 -0
- package/scripts/graph-units/verbs/headless-goal-loop.ts +152 -0
- package/scripts/graph-units/verbs/verify-stage.ts +75 -0
- package/scripts/graph-units/verbs-envelope.ts +139 -0
- package/scripts/hq/standby-snapshot.ts +25 -0
- package/scripts/measure-si-task-cpu.ts +143 -0
- package/scripts/public-export.ts +43 -1
- package/scripts/ratchets/test-interference-patterns.allowlist.txt +0 -2
- package/scripts/ratchets/train-side-invariants.sh +45 -0
- package/scripts/release-loop/auto-approve-node.ts +30 -16
- package/scripts/release-loop/gate-closure.ts +5 -1
- package/scripts/release-loop/gate-diff.ts +1 -1
- package/scripts/release-loop/gate-node.ts +498 -31
- package/scripts/release-loop/gate-partial.ts +3 -3
- package/scripts/release-loop/gate-radius-shadow.ts +138 -0
- package/scripts/release-loop/gate-traffic-mode.ts +128 -0
- package/scripts/release-loop/gate-triage-node.ts +5 -2
- package/scripts/release-loop/known-issues-0.2.33-approved.json +194 -0
- package/scripts/release-loop/known-issues-node.ts +77 -8
- package/scripts/release-loop/preflight.ts +93 -7
- package/scripts/release-loop/prepare-node.ts +102 -4
- package/scripts/release-loop/publish-node.ts +60 -9
- package/scripts/release-loop/resume-cap.ts +56 -0
- package/scripts/release-loop/resume-release.ts +114 -15
- package/scripts/release-loop/resume.ts +24 -1
- package/scripts/release-loop/tui-sim-node.ts +8 -2
- package/scripts/release-loop/unattended-release.ts +8 -2
- package/src/acp/core-turn-bridge.ts +36 -9
- package/src/acp/elanous-extensions.ts +3 -0
- package/src/acp/reasoning-thought-buffer.ts +45 -0
- package/src/acp/server.ts +3 -0
- package/src/acp/tool-trace.ts +186 -11
- package/src/agent/self-ambient-cache.ts +156 -0
- package/src/agent/self-ambient.ts +8 -1
- package/src/agent/task-notification.ts +5 -0
- package/src/agent-substrate/acp-reviewer.ts +52 -12
- package/src/agent-substrate/pr-reviewer.ts +3 -1
- package/src/agent-substrate/review-finding-key.ts +53 -0
- package/src/agent-substrate/self-review-cli.ts +126 -5
- package/src/ask-user-question/pending-questions.ts +1 -1
- 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 +213 -46
- package/src/capture/frame-state-detect.ts +39 -0
- package/src/capture/tui-self-report.ts +134 -6
- package/src/chat/index.ts +61 -15
- package/src/chat/pickers/modal-runtime.ts +6 -0
- package/src/chat/pickers/modals.ts +8 -2
- package/src/chat/tool-render/dispatch.ts +62 -10
- package/src/cli/ask-bare.ts +1 -0
- package/src/cli/control-cli.ts +24 -7
- package/src/cli/guardian-cli.ts +10 -0
- package/src/cli/import-cli.ts +12 -0
- package/src/cli/light-entry-route.ts +35 -0
- package/src/cli/llm-detect-cli.ts +23 -1
- package/src/cli/log-event-names.ts +10 -0
- package/src/cli/msg-cli.ts +1 -0
- package/src/cli/pod-cli.ts +14 -3
- package/src/cli/pr-cli.ts +140 -41
- package/src/cli/pr-land-base-read.ts +36 -0
- package/src/cli/pr-land-heavy-remote.ts +81 -25
- package/src/cli/pr-land-overlap-evidence.ts +200 -18
- package/src/cli/pr-land-pod-shadow-job.ts +26 -3
- package/src/cli/pr-land-recovery.ts +64 -0
- package/src/cli/pr-land-refusal.ts +20 -5
- package/src/cli/pty-takeover-cli.ts +94 -19
- package/src/cli/release-cli.ts +120 -33
- package/src/cli/release-run-if-ready.ts +29 -28
- package/src/cli/release-single-flight.ts +178 -0
- package/src/cli/seat-cli.ts +37 -0
- package/src/cli/setup-cli.ts +40 -1
- package/src/cli/sim-cli.ts +18 -0
- package/src/cli/tasks-cli.ts +149 -5
- package/src/context-bus/ops-events.ts +6 -2
- package/src/control/control-status.ts +8 -3
- package/src/control-plane/ledger.ts +5 -3
- package/src/control-plane/server.ts +5 -3
- package/src/core-turn/run-core-turn.ts +1 -0
- package/src/core-turn/run-goal-loop.ts +21 -0
- package/src/core-turn/short-question.ts +5 -1
- package/src/core-turn/types.ts +3 -0
- package/src/dashboard/acp-active-model.ts +42 -1
- package/src/dashboard/background-jobs-status.ts +66 -0
- package/src/dashboard/index.ts +153 -111
- package/src/dashboard/input/agent-wake.ts +242 -0
- package/src/dashboard/input/chat-main-entry-runtime.ts +5 -0
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +3 -0
- package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
- package/src/dashboard/input/external-input-host.ts +23 -9
- package/src/dashboard/input/mouse-wiring.ts +108 -11
- package/src/dashboard/input/seat-autowake.ts +56 -3
- package/src/dashboard/log-click-runtime.ts +118 -2
- package/src/dashboard/seat-boot-preamble.ts +1 -1
- package/src/dashboard/slash-runtime/ask-clarification.ts +48 -0
- package/src/dashboard/slash-runtime/dashboard-delegated-slashes.ts +68 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +62 -322
- package/src/dashboard/slash-runtime/dashboard-log-slash.ts +208 -0
- package/src/dashboard/turn-preamble.ts +163 -41
- package/src/dashboard/turn-session-layers.ts +4 -2
- package/src/dashboard/turn-start-segments.ts +222 -0
- package/src/dashboard/turn-stream-formatter.ts +34 -1
- package/src/dashboard/turn-stream-runtime.ts +2 -0
- package/src/dashboard/turn-typeahead-prompt-zone.ts +67 -0
- package/src/display/prompt-row-owner.ts +146 -0
- package/src/display/resize-listener.ts +33 -2
- package/src/domains/guardian-tick.ts +54 -2
- package/src/domains/outbound-alert.ts +3 -2
- package/src/extractors.ts +3 -1
- package/src/fold-stack.ts +4 -2
- package/src/git-fs/index.ts +263 -36
- package/src/git-fs/retry.ts +4 -0
- package/src/git-fs/runner.ts +2 -0
- package/src/graph-runner/runner.ts +114 -44
- package/src/grok/credential.ts +5 -0
- package/src/harness/gate-reserve.ts +87 -0
- package/src/harness/harness-cli-command.ts +39 -10
- package/src/harness/harness-incidents.ts +17 -0
- package/src/harness/harness-pod-dispatch.ts +38 -1
- package/src/harness/harness-queue.ts +15 -0
- package/src/harness/harness-salvage-cli.ts +14 -2
- package/src/index.ts +198 -12
- package/src/input/external-input-queue.ts +34 -9
- package/src/intake-plane/already-built-hint.ts +89 -0
- package/src/knowhow/pack.ts +199 -0
- package/src/light-cli.ts +95 -0
- package/src/llm/route-decision.ts +36 -0
- package/src/llm/tool-loop-steered-rejection.ts +8 -0
- package/src/llm-request-shape.ts +209 -0
- package/src/llm.ts +221 -276
- package/src/loops/budget.ts +95 -0
- package/src/loops/msg-wake.ts +8 -2
- package/src/loops/orchestrator/tick.ts +24 -2
- package/src/loops/orchestrator/traffic.ts +132 -1
- package/src/maturity/feature-maturity.ts +1 -1
- package/src/mss/logging/log-store.ts +4 -5
- package/src/mss/logging/render-categories.ts +5 -0
- package/src/nexus/api/graphs-api.ts +22 -3
- package/src/nexus/api/http-server.ts +1 -1
- package/src/nexus/api/ops-api.ts +12 -0
- package/src/oauth/claude-pty-maturity.ts +66 -0
- package/src/oauth/codex-access-mirror.ts +55 -0
- package/src/oauth/fallback-chain.ts +1 -1
- package/src/onboarding/first-run.ts +5 -3
- package/src/onboarding/non-interactive.ts +64 -13
- package/src/onboarding.ts +10 -2
- package/src/ops/overview-collect.ts +36 -1
- package/src/ops/overview.ts +70 -2
- package/src/pr-tool/census.ts +41 -8
- package/src/pr-tool/inflight-registry.ts +296 -0
- package/src/prompt-library/gpt6-family-addendum.ts +14 -1
- package/src/pty-shell/herdr-agent-report.ts +442 -0
- package/src/pty-shell/pty-control-ipc.ts +5 -5
- package/src/pty-shell/pty-manifest.ts +12 -3
- package/src/pty-shell/pty-write-outcome.ts +24 -6
- package/src/pty-shell/tui-run-state.ts +151 -6
- package/src/release-loop/checklist.ts +79 -5
- package/src/release-loop/feature-store.ts +19 -2
- package/src/release-loop/placement.ts +10 -3
- package/src/release-loop/rehearsal.ts +205 -25
- package/src/release-loop/rubric.ts +16 -2
- package/src/seat-loop/traffic-signal.ts +2 -1
- package/src/self-dev/ask-launch-flow.ts +13 -0
- package/src/self-dev/draft-residue.ts +243 -24
- package/src/self-dev/draft-sweep.ts +52 -3
- package/src/self-dev/graph-journey-nodes.ts +10 -6
- package/src/self-dev/graph-journey-route.ts +60 -6
- package/src/self-dev/orchestrate.ts +79 -3
- package/src/self-dev/run-supervisor.ts +107 -12
- package/src/self-dev/run-types.ts +5 -1
- package/src/self-dev/shard-plan.ts +11 -3
- package/src/self-dev/shard-run.ts +103 -10
- package/src/self-implement/elanous-tui-spawn.ts +14 -0
- package/src/self-implement/follow-up-placement.ts +79 -0
- package/src/self-implement/gate-artifacts.ts +15 -4
- package/src/self-implement/gate-baseline.ts +145 -10
- package/src/self-implement/gate-cli.ts +7 -2
- package/src/self-implement/gate-remote.ts +35 -6
- package/src/self-implement/goal-author-identity.ts +66 -0
- package/src/self-implement/goal-author-preservation-obligation.ts +35 -0
- package/src/self-implement/goal-author.ts +4 -120
- package/src/self-implement/graph-overlay-yaml.ts +17 -2
- package/src/self-implement/graph-unit-flatten.ts +103 -0
- package/src/self-implement/graph-unit-resolver.ts +107 -0
- package/src/self-implement/graph-yaml.ts +151 -1
- package/src/self-implement/headless-elanous-driver.ts +1 -0
- package/src/self-implement/host-regate.ts +36 -4
- package/src/self-implement/knowhow-pack.ts +103 -0
- package/src/self-implement/orchestrator.ts +109 -11
- package/src/self-implement/pod-warm-pool-profile.ts +45 -0
- package/src/self-implement/review-mustfix-class.ts +203 -0
- package/src/self-implement/run-ledger.ts +16 -14
- package/src/self-implement/run-stop.ts +8 -2
- package/src/self-implement/seams.ts +32 -1
- package/src/self-implement/stop-autoheal.ts +25 -1
- package/src/session/chat.ts +27 -0
- package/src/session-runtime/index.ts +22 -267
- package/src/session-runtime/retry-policy.ts +2 -1
- package/src/shell-runner/background-surface.ts +15 -5
- package/src/skills/tools/agent.ts +39 -6
- package/src/skills/tools/list-dir.ts +11 -0
- package/src/skills/tools/schedule-wakeup.ts +457 -0
- package/src/skills/tools/shell.ts +245 -3
- 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/release-day.ts +7 -3
- package/src/steward/triage.ts +47 -4
- package/src/surface/shell-runner-boot.ts +5 -2
- package/src/task-agent/harvest-unit.ts +141 -0
- package/src/task-agent/live-moves.ts +98 -12
- package/src/task-agent/parent-host.ts +93 -3
- package/src/task-agent/postland-card.ts +80 -1
- package/src/task-agent/rejudge-on-head.ts +112 -26
- package/src/task-agent/repair-branch-cas.ts +4 -1
- package/src/task-agent/repair-cycle.ts +16 -3
- package/src/task-agent/run-identity.ts +4 -3
- package/src/task-agent/shadow.ts +12 -2
- package/src/task-agent/task-hand.ts +76 -5
- package/src/task-agent/work-order-build.ts +22 -0
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +39 -3
- package/src/task-orchestrator/surfaces/pod-command-job.ts +67 -12
- package/src/task-orchestrator/surfaces/pod-lease.ts +98 -0
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +86 -8
- package/src/task-orchestrator/surfaces/pod-pool.ts +76 -18
- package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +10 -6
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +54 -4
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +548 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +389 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runner.ts +90 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +158 -3
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +230 -43
- package/src/task-orchestrator/surfaces/self-implement.ts +83 -2
- package/src/tool-runtime/truncation-store.ts +4 -0
- package/src/tui/chat/execution-badge.ts +5 -1
- package/src/tui/input-lag-probe.ts +230 -0
- package/src/tui-client/dashboard-session.ts +10 -1
- package/src/tui.ts +4 -0
- package/src/user-config/coercion.ts +36 -0
- package/src/user-config.ts +18 -41
- package/src/ux-sim/scenario.ts +314 -0
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +0 -27
- package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +0 -287
- package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +0 -62
- package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1654.32de4b324981a188.js +0 -23
- package/apps/pwa/out/_next/static/chunks/1834-50625904996a8fa8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +0 -149
- package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +0 -41
- package/apps/pwa/out/_next/static/chunks/2001.6c7e0fd02190886c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +0 -115
- package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +0 -64
- package/apps/pwa/out/_next/static/chunks/3267c0e6.d34854e7b3984a6e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3902.e1e71aaac850a045.js +0 -34
- package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +0 -36
- package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +0 -286
- package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +0 -77
- package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +0 -79
- package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +0 -148
- package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5458-16cd7a2b51b74c8c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +0 -74
- package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +0 -94
- package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +0 -90
- package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +0 -32
- package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +0 -104
- package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +0 -24
- package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +0 -93
- package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +0 -8
- package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8097-92f87bd108322f66.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +0 -1
- package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9138.b6e80031afb1d973.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9279-d28c5b7754d010ae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-bf3634a117322df7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-3535a4a69f1fafaa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-b9f51447f757fbf2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-2ebb8fd59b9461f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-a2fc4e49a4fa4ba8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-5a503541353e60a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-6025101384e361a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-f4b630cc8b5273cd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-a645f00a06483e9a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-61ac22cbab1ee4ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-e9bab7413b028b28.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-c992eafe028b642e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-e547e6ce55f1fb33.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-d27e1b9850fd54bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-805ac2e137b7a121.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-0fec29c7ba01894b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-339a07410cd6f36b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-349f2752d8cd37ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-d5c6dcf31c25cecc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-2fd93ed8c9f16580.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-9b564dbff0fefc35.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-62f4475d3c38fb9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-814ba51385225776.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-397d479626e5a459.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-af1bba4e3251b728.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ad3be5e7d3fdce9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-f219ccdbc0bf27df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4da93ad35d4a8d28.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-456666766e5ce6fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-7404e377e8adb8c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-14456240ed2a36ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-3a658d5fa6d16a25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-0157de6e85f8bb6b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-841d73d4ac44ed49.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6f43a3d1146e6377.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-521ee23ac8c0abfa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-a9992ee285efaa83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-3d48e85fa89ec04f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-d2ced71132fac9b2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-f08358bdf251adb9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-233c71cd5f68f0d7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-70151d78de2f375e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-dcac33a3e2cb72c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-149dc1caba411bb9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-0448145ccd5c45c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-9cb0c444903da65d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-17e504c396e0e389.js +0 -1
- package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +0 -122
- package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +0 -1
- package/apps/pwa/out/_next/static/css/3f5fc6f96e2cf7b2.css +0 -1
- package/src/cli/g6a-registration-probe.ts +0 -16
- /package/apps/pwa/out/_next/static/{LSXfY0u9QtfDbejY0Ukf_ → L04y73dlwKeTW-GetaTF3}/_ssgManifest.js +0 -0
|
@@ -6,13 +6,14 @@ import { constants, copyFileSync, existsSync, readFileSync, renameSync, writeFil
|
|
|
6
6
|
import { join } from 'node:path';
|
|
7
7
|
import { debug } from '../../src/debug/log.js';
|
|
8
8
|
import { effectiveInstanceRoot, releaseLedgerRoot } from '../../src/instance/resolve.js';
|
|
9
|
-
import { lastJsonObject, runGraph, type GraphRunState } from '../../src/graph-runner/runner.js';
|
|
9
|
+
import { lastJsonObject, runGraph, verifyReleaseCommandRoot, type GraphRunState } from '../../src/graph-runner/runner.js';
|
|
10
10
|
import { withOpSeatFlock } from '../../src/steward/resync-tick.js';
|
|
11
11
|
import { releaseRunUniverse } from './release-universe.js';
|
|
12
12
|
import { isReleaseVersion } from './release-version.js';
|
|
13
13
|
import { changedFilesBetween, clearPartialPlan, planPartialRegate, writePartialPlan } from './gate-partial.js';
|
|
14
|
-
import { gitClosureTree, testsReachingChanged, type ClosureTree } from './gate-closure.js';
|
|
15
|
-
import { releaseResumeAcceptedRegressions, releaseResumeGateExecutor, releaseResumeWaiver, type AcceptedRegression } from './resume.js';
|
|
14
|
+
import { gitClosureTree, testsReachingChanged, TRACEABLE_RELEASE_JSON, type ClosureTree } from './gate-closure.js';
|
|
15
|
+
import { releaseResumeAcceptedRegressions, releaseResumeGateExecutor, releaseResumeGatePodPool, releaseResumeWaiver, type AcceptedRegression } from './resume.js';
|
|
16
|
+
import { reserveReleaseResumeAttempt } from './resume-cap.js';
|
|
16
17
|
|
|
17
18
|
const GRAPH = join(import.meta.dir, '../../graphs/release/release-loop.yaml');
|
|
18
19
|
|
|
@@ -33,6 +34,20 @@ export interface ResumeReleaseDeps {
|
|
|
33
34
|
ledgerRoot?: string;
|
|
34
35
|
/** GATE-REUSE-BY-DIFF: the tip tree for the import closure — default read from git objects of the tip commit. */
|
|
35
36
|
closureTree?: (commit: string) => ClosureTree;
|
|
37
|
+
/** Source observation before the first resumed node. */
|
|
38
|
+
onSource?: (line: string) => void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface ResumeReleaseOptions {
|
|
42
|
+
runId: string; from: string; partial?: boolean; waive?: string; reason?: string;
|
|
43
|
+
acceptedRegressions?: AcceptedRegression[]; gateExecutor?: string; gateHost?: string; gatePodPool?: string;
|
|
44
|
+
commandRoot?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface ResumeReleasePlan {
|
|
48
|
+
runId: string; version: string; fromNode: string; commandRoot: string; tip: TipRefresh;
|
|
49
|
+
partial: PartialOutcome; gatePlan: { mode: 'not-run' | 'partial' | 'full'; reason?: string };
|
|
50
|
+
nextAttempt: number; attemptLimit: 2; preflight: 'passed';
|
|
36
51
|
}
|
|
37
52
|
|
|
38
53
|
/** CLI entry files: a production file that only names one (help text, a goal's command line) does not run it. */
|
|
@@ -66,6 +81,10 @@ function safeRunId(runId: string): string {
|
|
|
66
81
|
|
|
67
82
|
/** Point the saved version-release output at the current release/<v> tip (fast-forward of the recorded commit only). */
|
|
68
83
|
export function refreshReleaseBranchTip(runId: string, deps: ResumeReleaseDeps = {}, from?: string, waiverCommit?: string): TipRefresh {
|
|
84
|
+
return refreshReleaseBranchTipInternal(runId, deps, from, waiverCommit, false);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function refreshReleaseBranchTipInternal(runId: string, deps: ResumeReleaseDeps, from: string | undefined, waiverCommit: string | undefined, dryRun: boolean): TipRefresh {
|
|
69
88
|
const root = deps.root ?? effectiveInstanceRoot();
|
|
70
89
|
const statePath = join(root, 'graph-runs', 'release-loop', `${safeRunId(runId)}.json`);
|
|
71
90
|
const state = JSON.parse(readFileSync(statePath, 'utf8')) as GraphRunState;
|
|
@@ -89,8 +108,14 @@ export function refreshReleaseBranchTip(runId: string, deps: ResumeReleaseDeps =
|
|
|
89
108
|
const git = deps.git ?? gitRunner(deps.repo ?? process.cwd());
|
|
90
109
|
const advertised = git(['ls-remote', '--heads', 'origin', `refs/heads/${branch}`]).split(/\s+/)[0] ?? '';
|
|
91
110
|
if (!/^[0-9a-f]{40}$/i.test(advertised)) throw new Error(`${branch} is not on origin — this run was not cut as a release branch`);
|
|
92
|
-
|
|
93
|
-
|
|
111
|
+
let to: string;
|
|
112
|
+
if (dryRun) {
|
|
113
|
+
// Use the advertised object id directly: a preflight must not create/update local remote-tracking refs.
|
|
114
|
+
to = advertised;
|
|
115
|
+
} else {
|
|
116
|
+
git(['fetch', 'origin', `+refs/heads/${branch}:refs/remotes/origin/${branch}`]);
|
|
117
|
+
to = git(['rev-parse', '--verify', `refs/remotes/origin/${branch}^{commit}`]);
|
|
118
|
+
}
|
|
94
119
|
if (waiverCommit && (recorded.toLowerCase() !== waiverCommit.toLowerCase() || to.toLowerCase() !== waiverCommit.toLowerCase() || advertised.toLowerCase() !== waiverCommit.toLowerCase())) {
|
|
95
120
|
throw new Error('release branch moved — re-gate the new tip before waiving a node');
|
|
96
121
|
}
|
|
@@ -114,6 +139,7 @@ export function refreshReleaseBranchTip(runId: string, deps: ResumeReleaseDeps =
|
|
|
114
139
|
}
|
|
115
140
|
const stamp = (deps.now?.() ?? new Date()).toISOString().replace(/[:.]/g, '-');
|
|
116
141
|
const backup = `${statePath}.before-tip-${stamp}-${process.pid}-${to.slice(0, 12)}.bak`;
|
|
142
|
+
if (dryRun) return { version, branch, from: recorded, to, changed: true, statePath };
|
|
117
143
|
// Exclusive: a retry never overwrites an earlier backup.
|
|
118
144
|
copyFileSync(statePath, backup, constants.COPYFILE_EXCL);
|
|
119
145
|
const refreshed = { ...output, commit: to, refreshedFrom: recorded };
|
|
@@ -134,10 +160,10 @@ export type PartialOutcome = { requested: false }
|
|
|
134
160
|
|
|
135
161
|
/** Build (or clear) the partial re-gate plan for the new tip. Fail-closed: any doubt leaves a full gate.
|
|
136
162
|
* GATE-REUSE-BY-DIFF: `--from gate` on a moved tip plans by default (`partial: undefined`); `partial: false` opts out. */
|
|
137
|
-
function preparePartial(tip: TipRefresh, opts: { from: string; partial?: boolean }, deps: ResumeReleaseDeps): PartialOutcome {
|
|
163
|
+
function preparePartial(tip: TipRefresh, opts: { from: string; partial?: boolean }, deps: ResumeReleaseDeps, dryRun = false): PartialOutcome {
|
|
138
164
|
const root = deps.root ?? effectiveInstanceRoot();
|
|
139
165
|
// Any resume starts from no plan: one without a partial plan (from whatever node) never inherits an older plan.
|
|
140
|
-
clearPartialPlan(root, tip.version);
|
|
166
|
+
if (!dryRun) clearPartialPlan(root, tip.version);
|
|
141
167
|
const auto = opts.partial === undefined;
|
|
142
168
|
// The current graph checks public export before gate. A moved tip must resume there, so its gate still needs
|
|
143
169
|
// the diff plan; in older saved graphs export-check followed gate and cannot consume one.
|
|
@@ -182,6 +208,18 @@ function preparePartial(tip: TipRefresh, opts: { from: string; partial?: boolean
|
|
|
182
208
|
catch (error) { return fallback(`tip tree unreadable: ${String(error instanceof Error ? error.message : error).slice(0, 200)}`); }
|
|
183
209
|
const tracked = new Set(tree.files);
|
|
184
210
|
const tests = tree.files.filter((file) => GATE_TEST.test(file));
|
|
211
|
+
if (changed.includes(TRACEABLE_RELEASE_JSON)) {
|
|
212
|
+
// The one JSON exception is safe only while both the production reader and a test name this exact file at the tip.
|
|
213
|
+
// A renamed, computed or unreadable reader returns to the full gate instead of trusting a stale dependency map.
|
|
214
|
+
const reader = tree.read('scripts/release-loop/known-issues-node.ts');
|
|
215
|
+
if (!reader || !/readFileSync\(join\(import\.meta\.dir,\s*['"]known-issues-0\.2\.33-approved\.json['"]\)/.test(reader)) {
|
|
216
|
+
return fallback('known-issues JSON reader not statically verified — full gate');
|
|
217
|
+
}
|
|
218
|
+
const readerClosure = testsReachingChanged(tree, ['scripts/release-loop/known-issues-node.ts'], tests, { cliEntries: CLI_ENTRIES });
|
|
219
|
+
if (!readerClosure.ok || readerClosure.reached === 0) return fallback('known-issues JSON production reader reaches no verified test — full gate');
|
|
220
|
+
const jsonClosure = testsReachingChanged(tree, [TRACEABLE_RELEASE_JSON], tests, { cliEntries: CLI_ENTRIES });
|
|
221
|
+
if (!jsonClosure.ok || jsonClosure.reached === 0) return fallback('known-issues JSON reaches no verified test — full gate');
|
|
222
|
+
}
|
|
185
223
|
const planned = planPartialRegate({ version: tip.version, priorCommit: tip.from, forCommit: tip.to, changedFiles: changed,
|
|
186
224
|
priorFailures: prior.failures as string[], priorErrors: (prior.errors ?? []) as string[],
|
|
187
225
|
existsAtTip: (file) => tracked.has(file),
|
|
@@ -201,9 +239,9 @@ function preparePartial(tip: TipRefresh, opts: { from: string; partial?: boolean
|
|
|
201
239
|
}
|
|
202
240
|
if (!clean) return fallback(`no clean gate verdict for ${tip.from.slice(0, 12)} — full gate`);
|
|
203
241
|
}
|
|
204
|
-
const path = writePartialPlan(root, planned.plan);
|
|
242
|
+
const path = dryRun ? undefined : writePartialPlan(root, planned.plan);
|
|
205
243
|
debug.log('release-loop.resume', 'partial-planned', { version: tip.version, priorCommit: tip.from, commit: tip.to, files: planned.plan.files.length,
|
|
206
|
-
tests: tests.length, auto, path, ...(planned.closure ? { reached: planned.closure.reached, opaque: planned.closure.opaque } : {}) });
|
|
244
|
+
tests: tests.length, auto, ...(path ? { path } : {}), dryRun, ...(planned.closure ? { reached: planned.closure.reached, opaque: planned.closure.opaque } : {}) });
|
|
207
245
|
return { requested: true, applied: true, files: planned.plan.files.length, priorCommit: tip.from,
|
|
208
246
|
...(auto ? { auto: true as const } : {}), ...(planned.closure ? { closure: planned.closure } : {}) };
|
|
209
247
|
}
|
|
@@ -217,34 +255,87 @@ function savedGraphPath(statePath: string): string | undefined {
|
|
|
217
255
|
}
|
|
218
256
|
|
|
219
257
|
/** Refresh the branch tip, then restart the failed run at `from` with the saved graph snapshot. */
|
|
220
|
-
export async function resumeReleaseRun(opts:
|
|
258
|
+
export async function resumeReleaseRun(opts: ResumeReleaseOptions, deps: ResumeReleaseDeps = {}): Promise<{ tip: TipRefresh; partial: PartialOutcome; state: GraphRunState }> {
|
|
221
259
|
// The lock root is the OP seat's (opSeatLockRoot), never the injected ledger root: a different `deps.root` must not
|
|
222
260
|
// move this run onto a separate lock inode from the steward resync and the unattended release.
|
|
223
261
|
return withOpSeatFlock(() => resumeReleaseRunLocked(opts, deps));
|
|
224
262
|
}
|
|
225
263
|
|
|
226
|
-
|
|
264
|
+
/** Validate a resume without changing the saved run, attempt ledger, or partial-gate plan. */
|
|
265
|
+
export async function planResumeReleaseRun(opts: ResumeReleaseOptions, deps: ResumeReleaseDeps = {}): Promise<ResumeReleasePlan> {
|
|
266
|
+
return withOpSeatFlock(() => planResumeReleaseRunLocked(opts, deps));
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
async function planResumeReleaseRunLocked(opts: ResumeReleaseOptions, deps: ResumeReleaseDeps): Promise<ResumeReleasePlan> {
|
|
270
|
+
if (opts.from === 'version-release') throw new Error('--from version-release would cut again — resume at a later node');
|
|
271
|
+
deps = { ...deps, root: releaseRunUniverse({ root: deps.root }) };
|
|
272
|
+
const statePath = join(deps.root!, 'graph-runs', 'release-loop', `${safeRunId(opts.runId)}.json`);
|
|
273
|
+
const savedRun = JSON.parse(readFileSync(statePath, 'utf8')) as GraphRunState;
|
|
274
|
+
if (savedRun.graphId !== 'release-loop' || savedRun.runId !== opts.runId) throw new Error(`run identity mismatch: ${statePath}`);
|
|
275
|
+
if (opts.gateHost !== undefined && opts.gateExecutor === undefined) throw new Error('--gate-host requires --gate-executor host');
|
|
276
|
+
const hasOverrides = opts.waive !== undefined || opts.reason !== undefined || opts.acceptedRegressions !== undefined
|
|
277
|
+
|| opts.gateExecutor !== undefined || opts.gatePodPool !== undefined;
|
|
278
|
+
const original = hasOverrides ? savedRun : undefined;
|
|
279
|
+
if (original && opts.gateExecutor !== undefined) releaseResumeGateExecutor(original, { from: opts.from, executor: opts.gateExecutor, host: opts.gateHost });
|
|
280
|
+
if (original && opts.gatePodPool !== undefined) releaseResumeGatePodPool(original, { from: opts.from, pool: opts.gatePodPool });
|
|
281
|
+
const waiver = original && (opts.waive !== undefined || opts.reason !== undefined) ? releaseResumeWaiver(original, opts) : undefined;
|
|
282
|
+
if (original && opts.acceptedRegressions !== undefined && !waiver)
|
|
283
|
+
releaseResumeAcceptedRegressions(original, opts.acceptedRegressions, opts.from);
|
|
284
|
+
const attempt = reserveReleaseResumeAttempt(savedRun, deps.root!, { now: deps.now, checkOnly: true, noDecision: true });
|
|
285
|
+
let waiverCommit: string | undefined;
|
|
286
|
+
if (waiver) {
|
|
287
|
+
const output = lastJsonObject(savedRun.nodes.find((node) => node.nodeId === 'version-release')?.output);
|
|
288
|
+
const version = output?.version, recorded = output?.commit;
|
|
289
|
+
if (typeof version !== 'string' || typeof recorded !== 'string' || !isReleaseVersion(version) || !/^[0-9a-f]{40}$/i.test(recorded)) throw new Error('release waiver requires a recorded release commit');
|
|
290
|
+
const git = deps.git ?? gitRunner(deps.repo ?? process.cwd());
|
|
291
|
+
const branch = `release/${version}`;
|
|
292
|
+
const advertised = git(['ls-remote', '--heads', 'origin', `refs/heads/${branch}`]).split(/\s+/)[0];
|
|
293
|
+
if (advertised?.toLowerCase() !== recorded.toLowerCase()) throw new Error('release branch moved — re-gate the new tip before waiving a node');
|
|
294
|
+
waiverCommit = recorded;
|
|
295
|
+
}
|
|
296
|
+
const tip = refreshReleaseBranchTipInternal(opts.runId, deps, opts.from, waiverCommit, true);
|
|
297
|
+
const commandRoot = verifyReleaseCommandRoot(opts.commandRoot ?? process.cwd(), tip.to, deps.git);
|
|
298
|
+
const partial = preparePartial(tip, opts, deps, true);
|
|
299
|
+
const fromIndex = savedRun.path.indexOf(opts.from);
|
|
300
|
+
const gateIndex = savedRun.path.indexOf('gate');
|
|
301
|
+
const gateWillRun = fromIndex >= 0 && gateIndex >= fromIndex;
|
|
302
|
+
const gatePlan = !gateWillRun ? { mode: 'not-run' as const }
|
|
303
|
+
: partial.requested && partial.applied ? { mode: 'partial' as const }
|
|
304
|
+
: { mode: 'full' as const, reason: partial.requested ? partial.reason : opts.partial === false ? 'partial recheck disabled' : 'no partial plan applies' };
|
|
305
|
+
return { runId: opts.runId, version: tip.version, fromNode: opts.from, commandRoot, tip, partial,
|
|
306
|
+
gatePlan, nextAttempt: attempt.attempt, attemptLimit: 2, preflight: 'passed' };
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
async function resumeReleaseRunLocked(opts: ResumeReleaseOptions, deps: ResumeReleaseDeps): Promise<{ tip: TipRefresh; partial: PartialOutcome; state: GraphRunState }> {
|
|
227
310
|
if (opts.from === 'version-release') throw new Error('--from version-release would cut again — resume at a later node');
|
|
228
311
|
// RELEASE-LEDGER-UNIVERSE: decide the universe once; the run lookup and every resumed node use it.
|
|
229
312
|
deps = { ...deps, root: releaseRunUniverse({ root: deps.root }) };
|
|
230
313
|
const statePath = join(deps.root!, 'graph-runs', 'release-loop', `${safeRunId(opts.runId)}.json`);
|
|
314
|
+
const savedRun = JSON.parse(readFileSync(statePath, 'utf8')) as GraphRunState;
|
|
231
315
|
let waiverCommit: string | undefined;
|
|
232
316
|
if (opts.gateHost !== undefined && opts.gateExecutor === undefined) throw new Error('--gate-host requires --gate-executor host');
|
|
233
|
-
const original = opts.waive !== undefined || opts.reason !== undefined || opts.acceptedRegressions !== undefined || opts.gateExecutor !== undefined
|
|
234
|
-
?
|
|
317
|
+
const original = opts.waive !== undefined || opts.reason !== undefined || opts.acceptedRegressions !== undefined || opts.gateExecutor !== undefined || opts.gatePodPool !== undefined
|
|
318
|
+
? savedRun : undefined;
|
|
235
319
|
// GATE-HOST-EXECUTOR: checked before the tip refresh writes anything; the runner checks it again under the resume lock.
|
|
236
320
|
const gateExecutor = original && opts.gateExecutor !== undefined
|
|
237
321
|
? releaseResumeGateExecutor(original, { from: opts.from, executor: opts.gateExecutor, host: opts.gateHost }) : undefined;
|
|
322
|
+
const gatePodPool = original && opts.gatePodPool !== undefined
|
|
323
|
+
? releaseResumeGatePodPool(original, { from: opts.from, pool: opts.gatePodPool }) : undefined;
|
|
238
324
|
if (gateExecutor) debug.log('release-loop.resume', 'gate-executor', { runId: opts.runId, from: opts.from, executor: gateExecutor.set.gateExecutor, host: gateExecutor.set.gateRemote ?? null, previous: gateExecutor.previous });
|
|
325
|
+
if (gatePodPool) debug.log('release-loop.resume', 'gate-pod-pool', {
|
|
326
|
+
runId: opts.runId, from: opts.from, pool: gatePodPool.set.gatePodPool, previous: gatePodPool.previous,
|
|
327
|
+
});
|
|
239
328
|
const waiver = original && (opts.waive !== undefined || opts.reason !== undefined)
|
|
240
329
|
? releaseResumeWaiver(original, opts) : undefined;
|
|
241
330
|
if (waiver) debug.log('release-loop.resume', 'waiver', { runId: opts.runId, node: waiver.nodeId, reason: waiver.reason, unmeasured: waiver.unmeasured ?? null });
|
|
242
331
|
const acceptedRegressions = original && opts.acceptedRegressions !== undefined && !waiver
|
|
243
332
|
? releaseResumeAcceptedRegressions(original, opts.acceptedRegressions, opts.from) : undefined;
|
|
333
|
+
if (savedRun.graphId !== 'release-loop' || savedRun.runId !== opts.runId) throw new Error(`run identity mismatch: ${statePath}`);
|
|
334
|
+
// Validate request arguments before the cap, then block the third attempt before tip refresh.
|
|
335
|
+
reserveReleaseResumeAttempt(savedRun, deps.root!, { now: deps.now, checkOnly: true });
|
|
244
336
|
// A waived verdict may reuse its original commit. A moved tip still requires a full re-gate.
|
|
245
337
|
if (waiver) {
|
|
246
|
-
const
|
|
247
|
-
const versionRecord = saved.nodes.find((node) => node.nodeId === 'version-release');
|
|
338
|
+
const versionRecord = savedRun.nodes.find((node) => node.nodeId === 'version-release');
|
|
248
339
|
const output = lastJsonObject(versionRecord?.output);
|
|
249
340
|
const version = output?.version;
|
|
250
341
|
const recorded = output?.commit;
|
|
@@ -257,13 +348,21 @@ async function resumeReleaseRunLocked(opts: { runId: string; from: string; parti
|
|
|
257
348
|
}
|
|
258
349
|
// Check the refreshed tip before refresh writes a new version-release record or backup.
|
|
259
350
|
const tip = refreshReleaseBranchTip(opts.runId, deps, opts.from, waiverCommit);
|
|
351
|
+
const commandRoot = verifyReleaseCommandRoot(opts.commandRoot ?? process.cwd(), tip.to, deps.git);
|
|
260
352
|
const partial = preparePartial(tip, opts, deps);
|
|
353
|
+
// A failed preflight does not consume one of the two release resume attempts.
|
|
354
|
+
const attempt = reserveReleaseResumeAttempt(savedRun, deps.root!, { now: deps.now });
|
|
355
|
+
debug.log('release-loop.resume', 'attempt', { runId: opts.runId, attempt: attempt.attempt, limit: 2, ledger: attempt.path });
|
|
261
356
|
// Resume the graph at the path it was started from (its snapshot is used); only tests inject another path.
|
|
262
357
|
const graphPath = deps.graphPath ?? savedGraphPath(tip.statePath) ?? GRAPH;
|
|
358
|
+
const savedSource = JSON.parse(readFileSync(tip.statePath, 'utf8')) as GraphRunState;
|
|
359
|
+
deps.onSource?.(`레시피 출처: graph=${graphPath} · graph sha=${savedSource.graphSnapshot?.graphSha?.slice(0, 12) ?? 'legacy'} · recipes sha=${savedSource.graphSnapshot?.recipesSha?.slice(0, 12) ?? 'legacy'} · command-root=${commandRoot} · 컷 tip=${tip.to.slice(0, 12)}`);
|
|
263
360
|
const state = await (deps.graph ?? runGraph)(graphPath, { resumeRunId: opts.runId, fromNodeId: opts.from, pinChildUniverse: true,
|
|
361
|
+
releaseCommandSource: { root: commandRoot, cutTip: tip.to, ...(deps.git ? { git: deps.git } : {}) },
|
|
264
362
|
...(waiver ? { releaseWaiver: { ...waiver, requestedRegressions: opts.acceptedRegressions ?? [] } } : {}),
|
|
265
363
|
...(acceptedRegressions ? { releaseAcceptedRegressions: { requested: opts.acceptedRegressions!, acceptedRegressions } } : {}),
|
|
266
364
|
...(gateExecutor ? { releaseGateExecutor: { executor: gateExecutor.set.gateExecutor, ...(opts.gateHost !== undefined ? { host: opts.gateHost } : {}) } } : {}),
|
|
365
|
+
...(gatePodPool ? { releaseGatePodPool: gatePodPool.set.gatePodPool } : {}),
|
|
267
366
|
deps: { root: deps.root, ...(deps.runBash ? { runBash: deps.runBash } : {}) } });
|
|
268
367
|
return { tip, partial, state };
|
|
269
368
|
}
|
|
@@ -137,6 +137,28 @@ export interface GateExecutorOverride {
|
|
|
137
137
|
previous: { gateExecutor: unknown; gateRemote: unknown };
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
/** RESUME-GATE-POOL-OVERRIDE — replace the saved pool for a gate that will be re-run. */
|
|
141
|
+
export interface GatePodPoolOverride {
|
|
142
|
+
kind: 'gate-pod-pool';
|
|
143
|
+
at: string;
|
|
144
|
+
from: string;
|
|
145
|
+
set: { gatePodPool: string };
|
|
146
|
+
previous: { gatePodPool: unknown };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function releaseResumeGatePodPool(state: GraphRunState, opts: { from: string; pool: unknown; at?: string }): GatePodPoolOverride {
|
|
150
|
+
const input = state.input;
|
|
151
|
+
if (!input || typeof input !== 'object' || Array.isArray(input) || typeof (input as { version?: unknown }).version !== 'string') throw new Error('release run has no input');
|
|
152
|
+
if (typeof opts.pool !== 'string' || !opts.pool.trim()) throw new Error('--gate-pod-pool must not be empty');
|
|
153
|
+
const start = state.path.indexOf(opts.from);
|
|
154
|
+
if (start < 0) throw new Error(`--from ${opts.from} is not a node on the saved path`);
|
|
155
|
+
const gate = state.path.indexOf('gate');
|
|
156
|
+
if (gate >= 0 && start > gate) throw new Error('--gate-pod-pool needs a resume that re-runs gate (--from gate or earlier)');
|
|
157
|
+
const saved = input as { gatePodPool?: unknown };
|
|
158
|
+
return { kind: 'gate-pod-pool', at: opts.at ?? new Date().toISOString(), from: opts.from,
|
|
159
|
+
set: { gatePodPool: opts.pool.trim() }, previous: { gatePodPool: saved.gatePodPool ?? null } };
|
|
160
|
+
}
|
|
161
|
+
|
|
140
162
|
/**
|
|
141
163
|
* Switch the gate executor of a resumed release run. Not a waiver: the gate node runs again (the restart must be at or
|
|
142
164
|
* before gate) and produces a normal verdict; only where its sweep runs changes.
|
|
@@ -156,7 +178,8 @@ export function releaseResumeGateExecutor(state: GraphRunState, opts: { from: st
|
|
|
156
178
|
// A restart after gate keeps the recorded verdict — switching its executor there would record a choice nothing used.
|
|
157
179
|
if (gate >= 0 && start > gate) throw new Error('--gate-executor needs a resume that re-runs gate (--from gate or earlier)');
|
|
158
180
|
// Back to pod: restore the gateRemote the run started with (an earlier host override replaced it).
|
|
159
|
-
const firstHost = choice.executor === 'pod' ? state.inputOverrides?.find((item)
|
|
181
|
+
const firstHost = choice.executor === 'pod' ? state.inputOverrides?.find((item): item is GateExecutorOverride =>
|
|
182
|
+
item.kind === 'gate-executor' && item.set.gateRemote !== undefined) : undefined;
|
|
160
183
|
const restored = firstHost ? firstHost.previous.gateRemote : undefined;
|
|
161
184
|
return {
|
|
162
185
|
kind: 'gate-executor', at: opts.at ?? new Date().toISOString(), from: opts.from,
|
|
@@ -16,7 +16,7 @@ import { SPAWN_SYNC_MAX_BUFFER } from '../../src/util/spawn-sync-output.js';
|
|
|
16
16
|
import { copyFileSync, existsSync, mkdtempSync, openSync, symlinkSync } from 'node:fs';
|
|
17
17
|
import { tmpdir } from 'node:os';
|
|
18
18
|
import { basename, join, resolve } from 'node:path';
|
|
19
|
-
import { parseTuiRegress, regressWarning, tuiChecks, tuiVerdict, type TuiCheck, type TuiRegress } from './tui-node-checks';
|
|
19
|
+
import { parseTuiRegress, regressWarning, tuiChecks, tuiVerdict, validatedTuiRegress, type TuiCheck, type TuiRegress } from './tui-node-checks';
|
|
20
20
|
|
|
21
21
|
const log = (msg: string) => process.stderr.write(`[tui-node] ${msg}\n`);
|
|
22
22
|
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
|
@@ -83,7 +83,13 @@ export function measureTuiRegress(worktree: string, runner: typeof spawnSync = s
|
|
|
83
83
|
export function tuiNodeOutput(commit: string, attempts: Array<{ checks: TuiCheck[]; png?: string }>, regress: TuiRegress, failure?: string) {
|
|
84
84
|
const last = attempts.at(-1);
|
|
85
85
|
const verdict = !last ? 'error' : tuiVerdict(last.checks) === 'fail' ? 'fail' : attempts.length > 1 ? 'flaky' : 'pass';
|
|
86
|
-
|
|
86
|
+
const measured = validatedTuiRegress(regress);
|
|
87
|
+
const regressSummary = 'unmeasured' in measured
|
|
88
|
+
? `regress unmeasured: ${measured.unmeasured}`
|
|
89
|
+
: `regress ${measured.pass} pass / ${measured.fail} fail${measured.fail ? ` (${measured.results.filter((r) => !r.ok).map((r) => r.id).join(',')})` : ''}`;
|
|
90
|
+
const checks = last?.checks ?? [];
|
|
91
|
+
const summary = `TUI ${verdict}: basic ${checks.filter((check) => check.pass).length}/${checks.length} · ${regressSummary}`;
|
|
92
|
+
return { verdict, summary, commit, attempts: attempts.length, checks, png: last?.png, regress: measured, ...(failure ? { error: failure } : {}) };
|
|
87
93
|
}
|
|
88
94
|
|
|
89
95
|
async function main(): Promise<number> {
|
|
@@ -10,6 +10,7 @@ import { isLandingFreezeRefusal, readLandingFreeze, LandingFrozenError } from '.
|
|
|
10
10
|
import { debug } from '../../src/debug/log.js';
|
|
11
11
|
import { runGraph, type GraphRunState } from '../../src/graph-runner/runner.js';
|
|
12
12
|
import { withOpSeatFlock } from '../../src/steward/resync-tick.js';
|
|
13
|
+
import { ReleaseRunClaimConflict, findActiveReleaseRun } from '../../src/cli/release-single-flight.js';
|
|
13
14
|
import { releaseRunUniverse } from './release-universe.js';
|
|
14
15
|
import { baseVersion, isStableVersion, nextPrereleaseVersion, type PrereleaseKind } from './release-version.js';
|
|
15
16
|
import { publishAtError } from './publish-at.js';
|
|
@@ -19,6 +20,8 @@ const VERSION = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;
|
|
|
19
20
|
const GRAPH = join(import.meta.dir, '../../graphs/release/release-loop.yaml');
|
|
20
21
|
|
|
21
22
|
export interface ReleaseLoopConfig {
|
|
23
|
+
/** Mid-cycle full-gate rehearsal, hours before cut (default 12; 0 disables). */
|
|
24
|
+
rehearsalHardIntervalHours?: number;
|
|
22
25
|
gatePodPool?: string;
|
|
23
26
|
gatePodBunCache?: string;
|
|
24
27
|
gatePodShards?: number;
|
|
@@ -138,7 +141,7 @@ export function buildReleaseRunInput(version: string, deps: UnattendedReleaseDep
|
|
|
138
141
|
|
|
139
142
|
/** Fail closed at the entry boundary, before any graph node can change a release. */
|
|
140
143
|
export async function runUnattendedRelease(
|
|
141
|
-
opts: { version: string; dryRun?: boolean; cutCommit?: string; forceFreeze?: boolean; mainCut?: boolean; prerelease?: PrereleaseKind; publishAt?: string; gateExecutor?: string; gateHost?: string },
|
|
144
|
+
opts: { version: string; dryRun?: boolean; cutCommit?: string; forceFreeze?: boolean; forceNew?: boolean; mainCut?: boolean; prerelease?: PrereleaseKind; publishAt?: string; gateExecutor?: string; gateHost?: string },
|
|
142
145
|
deps: UnattendedReleaseDeps = {},
|
|
143
146
|
): Promise<{ input: ReleaseRunInput; dryRun: boolean; state?: GraphRunState }> {
|
|
144
147
|
// A dry run only builds the input and mutates nothing, so it neither creates nor waits on the OP-seat lock.
|
|
@@ -149,7 +152,7 @@ export async function runUnattendedRelease(
|
|
|
149
152
|
}
|
|
150
153
|
|
|
151
154
|
async function runUnattendedReleaseLocked(
|
|
152
|
-
opts: { version: string; dryRun?: boolean; cutCommit?: string; forceFreeze?: boolean; mainCut?: boolean; prerelease?: PrereleaseKind; publishAt?: string; gateExecutor?: string; gateHost?: string },
|
|
155
|
+
opts: { version: string; dryRun?: boolean; cutCommit?: string; forceFreeze?: boolean; forceNew?: boolean; mainCut?: boolean; prerelease?: PrereleaseKind; publishAt?: string; gateExecutor?: string; gateHost?: string },
|
|
153
156
|
deps: UnattendedReleaseDeps,
|
|
154
157
|
): Promise<{ input: ReleaseRunInput; dryRun: boolean; state?: GraphRunState }> {
|
|
155
158
|
// RELEASE-BRANCH (10-06): the default cut is a release branch, so main keeps landing and the run no longer needs a
|
|
@@ -188,6 +191,9 @@ async function runUnattendedReleaseLocked(
|
|
|
188
191
|
if (beforeGraph && !opts.forceFreeze) throw new LandingFrozenError(beforeGraph);
|
|
189
192
|
// RELEASE-LEDGER-UNIVERSE: one universe for the run ledger, the release ledger and every node subprocess.
|
|
190
193
|
const root = releaseRunUniverse({ root: deps.ledgerRoot });
|
|
194
|
+
// Resume and fresh runs share the OP-seat flock. Recheck under that flock so a
|
|
195
|
+
// resume that began after CLI preflight cannot slip between the ledger scan and graph start.
|
|
196
|
+
if (!opts.forceNew && findActiveReleaseRun(version, root)) throw new ReleaseRunClaimConflict();
|
|
191
197
|
const state = await (deps.graph ?? runGraph)(GRAPH, { input, pinChildUniverse: true, deps: { root } });
|
|
192
198
|
// A freeze switched on while the graph ran stops gate or publish inside it. Only a failed gate/publish node whose own
|
|
193
199
|
// record is the freeze refusal is reported as the freeze; any other failure keeps its own reason.
|
|
@@ -54,6 +54,7 @@ import { readOriginSessionMeta } from './origin-session-meta.js';
|
|
|
54
54
|
import { isFactQuestion } from './fact-question.js';
|
|
55
55
|
import { classifyTuiChatIntent, formatTuiRouteLine, isSeatOpsDirective, type TuiChatRoute } from '../core-turn/short-question.js';
|
|
56
56
|
import { HARNESS_ROLE_ENV } from '../harness/harness-space.js';
|
|
57
|
+
import { createReasoningThoughtBuffer } from './reasoning-thought-buffer.js';
|
|
57
58
|
|
|
58
59
|
const FACT_QUESTION_INSTRUCTION = '사실·최신 정보 질문이다. WebSearch 를 1~2회 쓰고 검색 결과(제목·스니펫·URL)로 답하라. 출처 링크를 붙여라. 셸·브라우저·파일 도구는 검색 결과로 부족할 때만. 도구 예산에 닿으면 지금까지 근거로 답하고 끝에 «더 찾아볼까요?»를 붙여라.';
|
|
59
60
|
|
|
@@ -67,8 +68,9 @@ const QUICK_TOOLS: Record<QuickTuiRoute, readonly string[]> = {
|
|
|
67
68
|
'조회': ['decisions_pending', 'ops_seats', 'ops_status', 'release_status', 'logs_query', 'context_now', 'memory_recall', 'Read'],
|
|
68
69
|
'설정 변경': ['DashboardConfigGet', 'DashboardConfigSet', 'LlmListAvailableModels', 'prompt_getRuntimeConfig', 'prompt_setRuntimeConfig', 'view_getConfig', 'view_applyRuntimeConfig', 'view_saveConfig', 'memory_recall'],
|
|
69
70
|
// MsgList is a read-only ledger listing (never acks); MsgPost · MsgAck · RunShell · Bash stay out (TUI-QUICK-ROUTE-EXPLICIT-CMD).
|
|
70
|
-
'조사': ['WebSearch', 'OmniSearch', 'Grep', 'Glob', 'Read', 'fact_check', 'memory_recall', 'MsgList'],
|
|
71
|
-
|
|
71
|
+
'조사': ['WebSearch', 'OmniSearch', 'Grep', 'Glob', 'Read', 'fact_check', 'memory_recall', 'MsgList', 'Agent'],
|
|
72
|
+
// ScheduleWakeup (H5) wakes this TUI in-process; schedule_manage is OS cron — both belong to «상시 일».
|
|
73
|
+
'상시 일': ['schedule_manage', 'schedule_list', 'schedule_create', 'schedule_update', 'ScheduleWakeup', 'session_manage', 'ops_status', 'memory_recall'],
|
|
72
74
|
};
|
|
73
75
|
|
|
74
76
|
export function toolsForTuiRoute(tools: readonly LLMToolSpec[], route: QuickTuiRoute): LLMToolSpec[] {
|
|
@@ -248,7 +250,7 @@ export function bridgeCoreTurnToAcp(
|
|
|
248
250
|
})
|
|
249
251
|
: { route: '코딩·구현' as const, reason: harness ? 'harness' : 'legacy', goalLoop: true };
|
|
250
252
|
const tools = !route.goalLoop && route.route !== '코딩·구현' && route.route !== '읽기·분석'
|
|
251
|
-
? toolsForTuiRoute(availableTools, route.route)
|
|
253
|
+
? toolsForTuiRoute(availableTools, route.route) // bridgeCoreTurnToAcp applies route allowlists here.
|
|
252
254
|
: availableTools;
|
|
253
255
|
if (deps.tuiRouting) {
|
|
254
256
|
debug.log('chat.route', 'decided', { route: route.route, reason: route.reason, goalLoop: route.goalLoop, seat, seatKnown });
|
|
@@ -317,6 +319,7 @@ export function bridgeCoreTurnToAcp(
|
|
|
317
319
|
let finalSupplement: { answer: string; supplement: string; finalText: string } | null = null;
|
|
318
320
|
// turnFamily 는 관측용으로만 유지(goal loop 아밍 판정은 위 사실 질문 판정 앞에서 한다).
|
|
319
321
|
const turnModel = modelOverride ?? getUserConfig().llm.model;
|
|
322
|
+
let resolvedRoute: { provider: string; model: string } | null = null;
|
|
320
323
|
const turnFamily = getModelFamily(turnModel);
|
|
321
324
|
if (armGoalLoop) {
|
|
322
325
|
// 관측 — 어느 family/모델에서 across-turn goal-loop 가 아밍됐나(전-family 개방 검증).
|
|
@@ -380,6 +383,16 @@ export function bridgeCoreTurnToAcp(
|
|
|
380
383
|
return approvedDispatch(name, args, dispatchCtx);
|
|
381
384
|
}
|
|
382
385
|
: approvedDispatch;
|
|
386
|
+
// TUI-TURN-NARRATION 조각 2 — 추론 요약을 «문단» 단위로 모아 ACP `agent_thought_chunk`
|
|
387
|
+
// (`_meta.reasoning: true`)로 보낸다. 대시보드가 흐린 💭 한 줄로 그린다(`acp-chat.ts`).
|
|
388
|
+
// ⛔ 전에는 debug.log 로만 남아 화면엔 «무엇을 하는지»가 0줄이었다(결함 #87).
|
|
389
|
+
const reasoningThoughts = createReasoningThoughtBuffer((text) => {
|
|
390
|
+
debug.log('llm.reasoning', 'thought-emitted', { sessionId: turnCtx.sessionId, chars: text.length });
|
|
391
|
+
void turnCtx.pushSessionUpdate(
|
|
392
|
+
{ sessionUpdate: 'agent_thought_chunk', content: { type: 'text', text } },
|
|
393
|
+
{ reasoning: true },
|
|
394
|
+
);
|
|
395
|
+
});
|
|
383
396
|
const dispatchResult = await runTurnDispatch({
|
|
384
397
|
sessionId: turnCtx.sessionId,
|
|
385
398
|
...(originSessionId ? { originSessionId } : {}),
|
|
@@ -401,6 +414,7 @@ export function bridgeCoreTurnToAcp(
|
|
|
401
414
|
// contract is synchronous onText. Chunks are delivered in
|
|
402
415
|
// order because `sessionUpdate` is serialized per-
|
|
403
416
|
// connection on the ACP SDK side.
|
|
417
|
+
if (delta.length > 0) reasoningThoughts.flush();
|
|
404
418
|
streamedTextSum += delta;
|
|
405
419
|
void turnCtx.push(delta);
|
|
406
420
|
},
|
|
@@ -418,20 +432,31 @@ export function bridgeCoreTurnToAcp(
|
|
|
418
432
|
toolKinds.add(call.name);
|
|
419
433
|
observeToolBudget();
|
|
420
434
|
}
|
|
435
|
+
reasoningThoughts.flush();
|
|
421
436
|
void turnCtx.pushToolCall(call);
|
|
422
437
|
},
|
|
423
438
|
onToolResult: (call) => { void turnCtx.pushToolResult(call); },
|
|
439
|
+
// 실제로 응답한 공급자·모델을 기억한다 — 폴백 체인이 넘기면(예 codex → grok) 턴 모델(turnModel)과 달라진다.
|
|
440
|
+
// streamLLMWithTools 가 스트림을 (다시) 열 때마다 부른다 → 사용량 직전 값 = 그 사용량을 낸 쪽.
|
|
441
|
+
onResolvedProvider: (provider, model) => { resolvedRoute = { provider, model }; },
|
|
424
442
|
// 턴 모델(라우팅 결과)을 실어 보낸다 — 대시보드 턴 지표가 설정 모델로 ctx·단가를 잡지 않게.
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
443
|
+
// ⭐ 폴백이면 «넘어간» 모델·공급자를 싣는다(TUI-MODEL-BADGE-ACTUAL · 완료 배지가 읽는다 · 상태줄·/model 은 후속 TUI-MODEL-BADGE-SOURCE).
|
|
444
|
+
onUsage: (usage) => {
|
|
445
|
+
void turnCtx.pushUsage({
|
|
446
|
+
...usage,
|
|
447
|
+
model: usage.model ?? resolvedRoute?.model ?? turnModel,
|
|
448
|
+
...(resolvedRoute ? { routeProvider: resolvedRoute.provider } : {}),
|
|
449
|
+
});
|
|
450
|
+
},
|
|
451
|
+
// Codex Responses API reasoning summary stream. Surfaced to the
|
|
452
|
+
// dashboard as `agent_thought_chunk` via `reasoningThoughts`
|
|
453
|
+
// (TUI-TURN-NARRATION 조각 2) ⊕ the forensic debug.log below.
|
|
430
454
|
// The forensic line carries the streamed delta and the
|
|
431
455
|
// running summary index so a single grep gives the
|
|
432
456
|
// reasoning trace in order. summary_part_added marks the
|
|
433
457
|
// paragraph boundary; summary_delta is the text within.
|
|
434
458
|
onReasoning: (event) => {
|
|
459
|
+
reasoningThoughts.onEvent(event);
|
|
435
460
|
if (debug.enabled) {
|
|
436
461
|
if (event.kind === 'summary_delta') {
|
|
437
462
|
debug.log('llm.reasoning', 'codex.summary.delta', {
|
|
@@ -447,6 +472,7 @@ export function bridgeCoreTurnToAcp(
|
|
|
447
472
|
}
|
|
448
473
|
},
|
|
449
474
|
onTurnComplete: async (newMessages) => {
|
|
475
|
+
reasoningThoughts.flush();
|
|
450
476
|
// Surface runtime-injected synthesis to ACP. emitTurnComplete
|
|
451
477
|
// pushes the final assistant text (which may be the W5-E/F/G
|
|
452
478
|
// force-synthesis output) into history. Compare to what was
|
|
@@ -580,7 +606,8 @@ export function bridgeCoreTurnToAcp(
|
|
|
580
606
|
}
|
|
581
607
|
},
|
|
582
608
|
},
|
|
583
|
-
|
|
609
|
+
// 오류·취소로 끝나 onTurnComplete 가 안 불려도 마지막 추론 문단을 내보낸다(#28964 리뷰 FU-1 · 빈 버퍼면 무동작).
|
|
610
|
+
}).finally(() => reasoningThoughts.flush());
|
|
584
611
|
// ⭐ 인증 거절은 코어 턴이 «던지지 않고» 돌려준다 — 여기서 안 읽으면 서버는 end_turn 을 내고
|
|
585
612
|
// TUI 엔 «✔ 완료»만 남는다(TUI 결함 #22). 던져서 실패 경로(prompt-failed · 오류 줄)로 보낸다.
|
|
586
613
|
const stopReason = (dispatchResult as { stopReason?: unknown } | null | undefined)?.stopReason;
|
|
@@ -81,6 +81,9 @@ export interface ElanousUiUsagePayload {
|
|
|
81
81
|
provider?: 'anthropic' | 'openai';
|
|
82
82
|
/** 그 턴이 실제로 요청한 모델(라우팅 결과 — 설정 모델과 다를 수 있다). */
|
|
83
83
|
model?: string;
|
|
84
|
+
/** 이 사용량을 낸 «실제» 공급자(폴백 체인이 넘겼으면 넘어간 쪽 · 예 `grok`). `provider` 는 과금 계열 축이라 따로 둔다
|
|
85
|
+
* (TUI-MODEL-BADGE-ACTUAL · 10-16). */
|
|
86
|
+
routeProvider?: string;
|
|
84
87
|
inputTokens?: number;
|
|
85
88
|
outputTokens?: number;
|
|
86
89
|
cacheReadInputTokens?: number;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// TUI-TURN-NARRATION 조각 2 — 추론 요약(reasoning summary)을 화면 한 줄로 낸다.
|
|
2
|
+
//
|
|
3
|
+
// 🩸 왜 있나 (결함 #87 · 2026-10-18): gpt-6 계열 TUI 턴은 도구 사이에 글을 0자 낸다
|
|
4
|
+
// (`llm.stream consume-end` `textChars=0`). 그런데 추론 요약은 라운드마다 24~37자씩 «온다»
|
|
5
|
+
// (`reasoningChars`). `core-turn-bridge` 의 `onReasoning` 이 debug.log 로만 남기고
|
|
6
|
+
// 화면으로 안 보내서, 사용자는 «무엇을 하는지» 한 줄도 못 봤다.
|
|
7
|
+
// 대시보드는 이미 `agent_thought_chunk` ⊕ `_meta.reasoning` 을 흐린 💭 줄로 그린다
|
|
8
|
+
// (`dashboard/chat/acp-chat.ts`) — 빠진 것은 «주는 자리» 하나였다.
|
|
9
|
+
//
|
|
10
|
+
// ⭐ 델타를 그대로 흘리지 않고 «문단» 단위로 모은다 — 델타마다 보내면 한 생각이 여러 줄로 찢긴다.
|
|
11
|
+
// 문단 경계 = 다음 `summary_part_added` · 도구 호출 · 답 글 시작 · 턴 끝.
|
|
12
|
+
|
|
13
|
+
export type ReasoningEvent =
|
|
14
|
+
| { kind: 'summary_part_added'; summaryIndex?: number }
|
|
15
|
+
| { kind: 'summary_delta'; delta: string; summaryIndex?: number };
|
|
16
|
+
|
|
17
|
+
export interface ReasoningThoughtBuffer {
|
|
18
|
+
onEvent(event: ReasoningEvent): void;
|
|
19
|
+
/** 모은 문단을 내보낸다(비었으면 아무것도 안 한다). */
|
|
20
|
+
flush(): void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** 요약 문단은 짧다(실측 24~37자). 폭주 방어로만 자른다. */
|
|
24
|
+
const MAX_THOUGHT_CHARS = 400;
|
|
25
|
+
|
|
26
|
+
export function createReasoningThoughtBuffer(emit: (text: string) => void): ReasoningThoughtBuffer {
|
|
27
|
+
let buf = '';
|
|
28
|
+
const flush = (): void => {
|
|
29
|
+
const text = buf.trim();
|
|
30
|
+
buf = '';
|
|
31
|
+
if (text.length === 0) return;
|
|
32
|
+
emit(text.length > MAX_THOUGHT_CHARS ? `${text.slice(0, MAX_THOUGHT_CHARS)}…` : text);
|
|
33
|
+
};
|
|
34
|
+
return {
|
|
35
|
+
onEvent(event) {
|
|
36
|
+
if (event.kind === 'summary_part_added') {
|
|
37
|
+
flush();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// 모으는 단계에서도 상한을 지킨다 — 문단 경계 없이 긴 스트림이 와도 버퍼가 무한히 크지 않게.
|
|
41
|
+
if (buf.length <= MAX_THOUGHT_CHARS) buf += event.delta.slice(0, MAX_THOUGHT_CHARS + 1 - buf.length);
|
|
42
|
+
},
|
|
43
|
+
flush,
|
|
44
|
+
};
|
|
45
|
+
}
|
package/src/acp/server.ts
CHANGED
|
@@ -838,6 +838,8 @@ export interface AcpTurnContext {
|
|
|
838
838
|
pushUsage: (usage: {
|
|
839
839
|
provider?: 'anthropic' | 'openai';
|
|
840
840
|
model?: string;
|
|
841
|
+
/** 실제로 응답한 공급자(폴백이면 넘어간 쪽). */
|
|
842
|
+
routeProvider?: string;
|
|
841
843
|
inputTokens?: number;
|
|
842
844
|
outputTokens?: number;
|
|
843
845
|
cacheReadInputTokens?: number;
|
|
@@ -1839,6 +1841,7 @@ function wireAcpConnection(
|
|
|
1839
1841
|
id: `turn:${Date.now()}`,
|
|
1840
1842
|
...(usage.provider !== undefined ? { provider: usage.provider } : {}),
|
|
1841
1843
|
...(usage.model !== undefined ? { model: usage.model } : {}),
|
|
1844
|
+
...(usage.routeProvider !== undefined ? { routeProvider: usage.routeProvider } : {}),
|
|
1842
1845
|
...(usage.inputTokens !== undefined ? { inputTokens: usage.inputTokens } : {}),
|
|
1843
1846
|
...(usage.outputTokens !== undefined ? { outputTokens: usage.outputTokens } : {}),
|
|
1844
1847
|
...(usage.cacheReadInputTokens !== undefined
|