elanous 0.2.38 → 0.2.41
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/README.md +7 -7
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/{RrjXTwz-urRAbChP1bX02 → GiOLWmt4MqDZePubBjA4Q}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/1115.434ae2ecb0ad986d.js +149 -0
- package/apps/pwa/out/_next/static/chunks/1121.667cec0bcdbb3fdb.js +36 -0
- package/apps/pwa/out/_next/static/chunks/1178.1aa9cad0e7695427.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1197-54da59d250a6e476.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5203.51e5d8b5f1dcfe53.js → 1219.7e17964e0e7cd8e5.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/1245.1cfd13b26dbd71d6.js +287 -0
- package/apps/pwa/out/_next/static/chunks/1494-f93046ff5c5a124d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1609.2b312797599b8e45.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1661.0dd330f3d89f73f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/167-0c121e4b47e0f9da.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1700.cdc2bf8cc685e221.js +90 -0
- package/apps/pwa/out/_next/static/chunks/1703-78e46acad29f3cfc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7573.2376e13c9c21f1f8.js → 1765.679b29625c8e88d4.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{3528.e4b8ab70d339f965.js → 1800.f7ff51dc4978a958.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1971-7efb628c471dc5a0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1999-8de7b7bb36801913.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2073.689dcb2680113d76.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2198-557d49184104d165.js +1 -0
- package/apps/pwa/out/_next/static/chunks/221-440ce67fa9f5c839.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8879.ac06755bcf3e44a1.js → 2263.e09b6edea33bad2d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2427-8ed8e98624cbd664.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2457-725c5827bc003795.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2491-2718b15a5ccb75a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2527-5c636a43c7cc5dde.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2692-1027cb16fe4ccf49.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2743.5d3f76948be32b34.js +41 -0
- package/apps/pwa/out/_next/static/chunks/2773.0e80b9d325fb5635.js +32 -0
- package/apps/pwa/out/_next/static/chunks/2873-0f3cb56c8e3528ea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9fe1b809.738da85c8b17e3fb.js → 2fdf2931.b431eee4fb468bc3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{eaad0cba.771200940c529df7.js → 2fe2c302.41b517f88d6fe502.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3097.864e92bdaa2f4d15.js +79 -0
- package/apps/pwa/out/_next/static/chunks/3136-d6870ba63300a93e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3173-0289113d434e83b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3230-49298c3b73ef2268.js +1 -0
- package/apps/pwa/out/_next/static/chunks/325-dd9208a1a0ab7ce4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3283.528f430dd043fb4e.js +74 -0
- package/apps/pwa/out/_next/static/chunks/3295.cc8cb13b8f0dae1a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3688-86e3b88abf18cb3b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3804-7220467a5473a8df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3808.3e1e247ce7bdf889.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b7478fef.5917716286213fcc.js → 385e4574.e9886ab32759eda3.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/3927.b5473ad109da44c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3934-98ea94832e194796.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4133.2056bb4d78f621af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4156.ba4de4a3664f04b4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4297-239ca82f293faab0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4320-dcc5a7734126f4c9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4434.94b4c552a2d91e69.js +148 -0
- package/apps/pwa/out/_next/static/chunks/{8911.bf5e712acb25fb6c.js → 4527.a69f2894d1bc9f4a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4579.03e4092f73950965.js +226 -0
- package/apps/pwa/out/_next/static/chunks/{5307.d7328020227880c2.js → 4667.97e31aa38c95c475.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/{6142.913b44e260a3f925.js → 4702.4a4adc1f16d7c93b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4815.481501c57b3568d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/487-d16e698ef14662d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4888-7a38bf522c9cc6fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5034-30e429d6bb086881.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5040-35c494e60dadd97d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/50c6ab1e.81a96e419350909d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5154.4b6a836179356f30.js +94 -0
- package/apps/pwa/out/_next/static/chunks/{8487.291666583bebe640.js → 5159.115f1c2ca471386c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5228-a8200df486278f2d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/530.d26346e18089640a.js +115 -0
- package/apps/pwa/out/_next/static/chunks/5379.97af106d09566f69.js +8 -0
- package/apps/pwa/out/_next/static/chunks/{89d6c04f-6b8ab341748e468a.js → 53aeb4ee-51c92f8d683f5220.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3291.f6c1005387d514bd.js → 5471.1e611302ed3a7c53.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/5479-b6372e762719f92f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5534-699c5cbcbc96c5d7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3086.fb14b60ce98b53d3.js → 5574.f35accf4f132b29d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5701.9c4e8f250312eeee.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{1632.7d87f998e714bede.js → 5744.b9415e18ad623100.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5300.677c97e0393742e6.js → 5892.2526d962339662d8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5937.c2df9e3447e1f667.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5941.8210cc93c9202c0a.js +286 -0
- package/apps/pwa/out/_next/static/chunks/{7161-8f22db3ec5ed005e.js → 5947-135e26537d80a6b9.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{3124-561f7f037943cde2.js → 5964-7e21164a8f2cf0ce.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5975.4004f820ae3cecd5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6142-7ccd48795d7abd55.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6160.bf9177b8c1bfb243.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6398.71ba0690c8027555.js +27 -0
- package/apps/pwa/out/_next/static/chunks/6492.2bd5c10edc1a064e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6552.a3840aa7da35ad68.js +62 -0
- package/apps/pwa/out/_next/static/chunks/6736.1e36d3ac5fa5e41d.js +24 -0
- package/apps/pwa/out/_next/static/chunks/6874.d5cf7eb8edb2cabe.js +2 -0
- package/apps/pwa/out/_next/static/chunks/6900.3ccbe069bdd4556a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/71327eb4.add50b365f94bf3a.js +122 -0
- package/apps/pwa/out/_next/static/chunks/7136.deca3e3a2ddaa374.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7139-ee9f8ed2677a40b3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2415.738b777642a02233.js → 7191.fdc955f7d96064a4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7423-e0aa5d9e2962120e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7453.afc1ea7e05d56a8c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7503-5e6a3d7fe67e4a0c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7761-476fd7bf768abd34.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7975.eafb12097a0a9e62.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1026-44010f405704050c.js → 8050-9b364bdef8f71927.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8152.64e253c35cccfaae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8190.620f0231b3924bcb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/83184dcd-0ee6247ff41eb3f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8448.45b6b1f1a99eeb35.js +104 -0
- package/apps/pwa/out/_next/static/chunks/8464-e24f10451b658aac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8477.e4c944bb3aa5d2f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8710.ca385257d5ca422e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8830.627ccf294ec2465c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8880.64c445592f04acaf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8981.c706964c8ba27aff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5638.107314dc479e2f37.js → 9048.212083de42d25be3.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/9053.bd0fffaff8d3f836.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9161-c66e723d7ec9d682.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9185.1ecdf9b65c0bb684.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9356.fccd5f58086b4ff5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9446.dc0406109371d329.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9506.dcf25d467a42627e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8019.21ca554a821dad01.js → 9507.7026657a2f47eb64.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/9541.eb8e2f8480c7feca.js +93 -0
- package/apps/pwa/out/_next/static/chunks/9577.ed7582186efa5482.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9579.4a8169600fff2058.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9642-ff2e039eb62e3b92.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9659-8f2323348113ad80.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9724.4c5623af2db43153.js +34 -0
- package/apps/pwa/out/_next/static/chunks/{6493.27ad77de7aac7966.js → 9834.63ab2bbc3153172e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3389.012c70767a872f9b.js → 9869.81a1e24ca682d5a0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{8994d93e.33ba491f95345fc2.js → a0a01613.6d1cca322238d7fe.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{de8b930d.d94c0f42acf807fc.js → addc2b32.8c4ff8f0aefe987d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-8d9d76ea322d855c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed2c4e59f9f1fe21.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-2dc99e03c5d76ca0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-b5a3a788330e920f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-866aac5ff226a7f3.js → page-14949db884bfa672.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-ea76c85b36388a97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-01716d20af62d325.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-62baf6881a64b1e9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-f89ba590c2af8afa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-22f8b0f78d9637e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-817f9d7e6820be80.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-ffb9bc0d2650249a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-f6d0e64873c0f629.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-8bfa0d4ba23a209d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-f5060462249e32c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-8d9d76ea322d855c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-b2049f8b1ef79117.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-1446c5fa93907f11.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-b48a7a07c5204156.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-e974b8c4ca47614c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-8a919b869bd28594.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-d31b8de6bfcd72ed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-64765f817909db29.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-d128c8569a36ee9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-b2679d357e9b9270.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-6fabec98a9e7b269.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-048f30149dcf1349.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-9113181d6b5a2725.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-40f9e19149024298.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-1e7a755a13227611.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-3c8f8b67a203cf07.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-18032f5437215062.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-da3b739192fd0ee3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d332545571bd6fd1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-5237aa5b3f3b8ec5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a142dfb0331a05f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-d16e56c3989c147e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6b6593600869e2cd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-8d9d76ea322d855c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-29e8b8a8396b55cb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-b3414d856a1a7e2f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-c3affa52b7ce961b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f21dddf9f95b6fab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-f5a30a24745bf088.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-8c8569a09b4d4e34.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-2ce32722c0243483.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-4767b0d9c0a98c6c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-116ee1339c387a75.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-35e8c50ca4ef7ffc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-52e17113356bb891.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7458ae05ed2ac1a0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/b2271e54.c1de3347976e90b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b7459770.6539b11860eb8a9c.js → c0c1a699.0ba79f97005965d4.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/framework-ad6c9dd524ad6ef8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-2ddd1f2b44d6aa59.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-e3d82bdc358d20c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-71d5aa3896e1655f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-03ffc54e00438546.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-56bb89af5a611d0b.js +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +22 -22
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +22 -22
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +22 -22
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +21 -21
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +21 -21
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +22 -22
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +21 -21
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +22 -22
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +22 -22
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +21 -21
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +22 -22
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +22 -22
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +22 -22
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +22 -22
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +21 -21
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +21 -21
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +22 -22
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +22 -22
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +22 -22
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +21 -21
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +21 -21
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +21 -21
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +22 -22
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +22 -22
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +21 -21
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +21 -21
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +21 -21
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +21 -21
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +22 -22
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +22 -22
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +21 -21
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +22 -22
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +22 -22
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +22 -22
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +22 -22
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +22 -22
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +21 -21
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +22 -22
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +22 -22
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +22 -22
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +22 -22
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +22 -22
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +22 -22
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +22 -22
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +22 -22
- package/bin/elanous.mjs +6 -1
- package/catalog/models/openai/gpt-6.1-sol.yaml +16 -0
- package/catalog/models/openai/gpt-6.1-terra.yaml +16 -0
- package/graphs/demo/persona-marketer/fixtures/marketer-scenario.yaml +10 -0
- package/graphs/demo/persona-marketer/persona-marketer.yaml +25 -0
- package/graphs/demo/persona-marketer/recipes.yaml +19 -0
- package/graphs/demo/persona-teacher/lesson-pack.yaml +16 -0
- package/graphs/demo/persona-teacher/recipes.yaml +17 -0
- package/graphs/demo/persona-teacher/weekly-lesson.yaml +36 -0
- package/graphs/overlays/stop-heal-ladder.yaml +23 -2
- package/graphs/release/release-loop.yaml +3 -1
- package/graphs/units/gate/gate.yaml +20 -0
- package/graphs/units/git/git.yaml +26 -0
- package/graphs/units/implement/implement.yaml +19 -0
- package/graphs/units/landing/landing.yaml +18 -0
- package/graphs/units/review/review.yaml +20 -0
- package/graphs/units/verbs/recipes.yaml +3 -0
- package/graphs/units/verbs/research.yaml +20 -0
- package/graphs/video/explainer-line.yaml +4 -1
- package/graphs/work/research-report.yaml +11 -1
- package/package.json +1 -1
- package/scripts/dead-code/report.ts +169 -0
- package/scripts/disk-steward.ts +46 -0
- package/scripts/fleet/node-setup.sh +50 -0
- package/scripts/graph-units/verbs/research.ts +55 -0
- package/scripts/lib/morning-report-options.ts +3 -4
- package/scripts/lib/tui-regress-evidence.ts +56 -0
- package/scripts/llm-cost-ledger.ts +179 -8
- package/scripts/measure-nl-routing-corpus.ts +10 -2
- package/scripts/morning-report.ts +5 -1
- package/scripts/persona-teacher/weekly-lesson-node.ts +172 -0
- package/scripts/public-copy-lint.ts +163 -19
- package/scripts/public-export.ts +15 -7
- package/scripts/ratchets/train-side-invariants.sh +0 -1
- package/scripts/release-loop/export-check-node.ts +21 -3
- package/scripts/release-loop/gate-autoheal.ts +117 -0
- package/scripts/release-loop/gate-baseline-receipt.ts +8 -1
- package/scripts/release-loop/gate-diff.ts +22 -3
- package/scripts/release-loop/gate-node.ts +583 -64
- package/scripts/release-loop/gate-shard-dispatch.ts +128 -0
- package/scripts/release-loop/gate-shard-load-flaky.ts +256 -0
- package/scripts/release-loop/gate-shard-receipts.ts +89 -0
- package/scripts/release-loop/gate-triage-node.ts +70 -10
- package/scripts/release-loop/gate-wall.ts +5 -5
- package/scripts/release-loop/preflight.ts +6 -2
- package/scripts/release-loop/resume-release.ts +267 -20
- package/scripts/release-loop/resume.ts +48 -0
- package/scripts/release-loop/traffic-node.ts +6 -3
- package/scripts/release-loop/unattended-release.ts +4 -2
- package/scripts/release-loop/version-node.ts +7 -2
- package/scripts/release-story/draft.ts +1 -1
- package/scripts/research-bench/README.md +53 -0
- package/scripts/research-bench/questions.json +66 -0
- package/scripts/research-bench/rubric.md +33 -0
- package/scripts/research-bench/run.ts +523 -0
- package/scripts/shadow-authoring-probe.ts +20 -0
- package/scripts/tui-regress.ts +85 -10
- package/scripts/ux-sim.ts +19 -2
- package/src/acp/core-turn-bridge.ts +94 -4
- package/src/agent/autonomous-tools.ts +10 -3
- package/src/agent/monad-agent-turn.ts +4 -1
- package/src/agent/registry.ts +26 -2
- package/src/agent/shared-app-tools.ts +1 -1
- package/src/agent/surface-ux/build.ts +12 -3
- package/src/agent/surface-ux/types.ts +1 -1
- package/src/agent/task-notification.ts +75 -6
- package/src/agent/types.ts +3 -0
- package/src/agent-mission/driver.ts +29 -3
- package/src/agent-mission/mission-cli.ts +2 -1
- package/src/agent-substrate/review-context-pack.ts +365 -0
- package/src/agent-substrate/self-review-cli.ts +291 -20
- package/src/ask-user-question/index.ts +6 -0
- package/src/ask-user-question/inline-resolver.ts +49 -0
- package/src/auto-research/question-ladder-contract.ts +22 -3
- package/src/auto-research/research-turn.ts +359 -17
- package/src/autopilot/agent-loop.ts +1 -1
- package/src/autopilot/discovery/wiki-claim-proposer.ts +22 -1
- package/src/autopilot/pty-control-loop.ts +8 -1
- package/src/boot/daemon-tools/index.ts +4 -3
- package/src/boot/daemon-tools/self-implement.ts +312 -7
- package/src/boot/daemon-tools/types.ts +2 -0
- package/src/budget/llm-cost.ts +44 -5
- package/src/budget/shadow-arms.ts +52 -0
- package/src/budget/unified-usage.ts +17 -1
- package/src/capture/tui-self-report.ts +14 -0
- package/src/chat/index.ts +33 -7
- package/src/chat/pickers/state.ts +7 -1
- package/src/cli/agent-cli.ts +43 -8
- package/src/cli/intake-cli.ts +22 -1
- package/src/cli/lesson-cli.ts +19 -3
- package/src/cli/log-event-names.ts +6 -0
- package/src/cli/mcp-login.ts +8 -18
- package/src/cli/msg-cli.ts +57 -1
- package/src/cli/pod-cli.ts +17 -2
- package/src/cli/pr-land-heavy-remote.ts +15 -9
- package/src/cli/pty-takeover-cli.ts +67 -7
- package/src/cli/release-cli.ts +79 -7
- package/src/cli/repo-cli.ts +2 -1
- package/src/cli/sim-cli.ts +7 -1
- package/src/cli/tasks-cli.ts +41 -13
- package/src/codex/models.ts +30 -15
- package/src/control-plane/ledger.ts +21 -4
- package/src/core-turn/run-core-turn.ts +47 -3
- package/src/core-turn/run-goal-loop.ts +240 -10
- package/src/core-turn/types.ts +9 -0
- package/src/dashboard/acp-boot.ts +72 -3
- package/src/dashboard/chat/acp-chat.ts +2 -2
- package/src/dashboard/classic-sigquit.ts +16 -0
- package/src/dashboard/index.ts +327 -27
- package/src/dashboard/input/chat-main-interaction-opts.ts +3 -0
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +7 -2
- package/src/dashboard/input/chat-main-slash-command.ts +7 -0
- package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
- package/src/dashboard/input/dashboard-priority-key-route.ts +21 -5
- package/src/dashboard/input/external-input-host.ts +2 -0
- package/src/dashboard/sidetab-runtime.ts +228 -0
- package/src/dashboard/slash-runtime/ask-clarification.ts +7 -1
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +20 -8
- package/src/dashboard/slash-runtime/help-from-registry.ts +2 -2
- package/src/dashboard/term-slash-runtime.ts +16 -18
- package/src/dashboard/turn-preamble.ts +14 -1
- package/src/disk-steward/judge.ts +73 -0
- package/src/disk-steward/ledger.ts +122 -0
- package/src/disk-steward/steward.ts +373 -0
- package/src/domains/guardian-tick.ts +191 -2
- package/src/domains/knowledge.ts +1 -1
- package/src/esc-abort-gate.ts +33 -1
- package/src/execution-loop/launch-gate.ts +206 -1
- package/src/graph-runner/graph-cli.ts +27 -4
- package/src/graph-runner/in-process-registry.ts +37 -0
- package/src/graph-runner/runner.ts +63 -11
- package/src/graph-wizard/generate.ts +16 -7
- package/src/graph-wizard/mission-compose.ts +201 -0
- package/src/grok/agent-search.ts +8 -2
- package/src/grok/credential.ts +5 -0
- package/src/grounding/ref-index.ts +30 -0
- package/src/grounding/ref-vector.ts +61 -0
- package/src/grounding/sources-cli.ts +11 -3
- package/src/grounding/sources.ts +15 -1
- package/src/harness/harness-cli-command.ts +305 -23
- package/src/harness/harness-incidents.ts +312 -7
- package/src/harness/harness-pod-dispatch.ts +7 -1
- package/src/harness/harness-space.ts +15 -1
- package/src/harness/progress-worker-entry.ts +59 -0
- package/src/harness/progress-worker-runtime.ts +11 -0
- package/src/index.ts +35 -5
- package/src/input/external-input-queue.ts +10 -0
- package/src/instance/dev-project.ts +25 -0
- package/src/intake-plane/collect-telegram-saved.ts +36 -1
- package/src/intake-plane/intake-to-tasks.ts +246 -3
- package/src/intelligence-map/model-alias.ts +6 -5
- package/src/intelligence-map/model-catalog.ts +59 -2
- package/src/lessons/friction-ledger.ts +154 -0
- package/src/live-supply/collector.ts +149 -0
- package/src/live-supply/probes.ts +52 -0
- package/src/live-supply/snapshot.ts +40 -0
- package/src/llm/model-defaults.ts +4 -4
- package/src/llm.ts +473 -87
- package/src/loops/orchestrator/tick.ts +56 -0
- package/src/mcp/mcp-oauth.ts +3 -1
- package/src/model-tier/llm-tier-map.ts +9 -9
- package/src/model-tier/turn-tier.ts +1 -1
- package/src/msg/msg-mirror-github.ts +80 -0
- package/src/msg/msg-mirror-policy.ts +61 -0
- package/src/msg/msg-mirror-runner.ts +219 -0
- package/src/msg/msg-mirror-state.ts +33 -0
- package/src/msg/msg-store.ts +11 -0
- package/src/nexus/api/harness-api.ts +2 -1
- package/src/output-truncation.ts +41 -12
- package/src/project/project-store.ts +48 -1
- package/src/pty/snapshot.py +132 -0
- package/src/pty-shell/pty-control-ipc.ts +29 -2
- package/src/pty-shell/pty-manifest.ts +59 -3
- package/src/pty-shell/registry.ts +2 -0
- package/src/pty-shell/tui-run-state.ts +80 -3
- package/src/release-loop/gate-host-reservation.ts +157 -4
- package/src/release-loop/gate-shard-ledger.ts +68 -0
- package/src/release-loop/merged-pr-checklist.ts +25 -2
- package/src/release-loop/rehearsal-shard-plan.ts +6 -1
- package/src/release-loop/rehearsal.ts +27 -0
- package/src/release-loop/release-schedule.ts +90 -1
- package/src/research/bloom-exemplars.ts +135 -0
- package/src/research/edge-decision.ts +124 -15
- package/src/research/gap-followup.ts +249 -0
- package/src/research/lenses/counter-evidence.ts +100 -0
- package/src/research/lenses/working-backwards.ts +89 -0
- package/src/research/plugin-discovery.ts +242 -0
- package/src/research-bridge/invoke.ts +4 -2
- package/src/research-bridge/types.ts +2 -0
- package/src/self-dev/ask-launch-flow.ts +73 -131
- package/src/self-dev/dev-cli.ts +19 -17
- package/src/self-dev/dev-pipeline.ts +8 -4
- package/src/self-dev/graph-front-nodes.ts +23 -0
- package/src/self-dev/graph-journey-route.ts +10 -2
- package/src/self-dev/launch-preflight-text.ts +2 -2
- package/src/self-dev/launch-preflight.ts +47 -11
- package/src/self-dev/orchestrate-cli.ts +1 -0
- package/src/self-dev/orchestrate.ts +15 -0
- package/src/self-dev/run-supervisor.ts +204 -3
- package/src/self-dev/run-types.ts +3 -0
- package/src/self-implement/device-first.ts +8 -2
- package/src/self-implement/doctor-visit.ts +76 -58
- package/src/self-implement/gate-artifacts.ts +16 -0
- package/src/self-implement/gate-baseline.ts +75 -4
- package/src/self-implement/gate-cli.ts +368 -30
- package/src/self-implement/gate-receipt-registry.ts +180 -0
- package/src/self-implement/gate-remote.ts +165 -24
- package/src/self-implement/goal-author-clarification.ts +205 -32
- package/src/self-implement/goal-author-decompose.ts +24 -15
- package/src/self-implement/goal-author.ts +86 -10
- package/src/self-implement/graph-stage-units.ts +172 -0
- package/src/self-implement/graph-templates.ts +162 -1
- package/src/self-implement/graph-variant.ts +37 -4
- package/src/self-implement/host-regate.ts +124 -49
- package/src/self-implement/impl-findings-feedback.ts +188 -0
- package/src/self-implement/knowhow-pack.ts +227 -10
- package/src/self-implement/off-diff-evidence.ts +124 -0
- package/src/self-implement/orchestrator.ts +320 -28
- package/src/self-implement/run-ledger.ts +110 -14
- package/src/self-implement/run-stop.ts +33 -2
- package/src/self-implement/running-runs.ts +35 -12
- package/src/self-implement/seams.ts +6 -3
- package/src/self-implement/self-implement-cli.ts +40 -6
- package/src/self-implement/stop-autoheal-operational.ts +43 -0
- package/src/self-implement/stop-autoheal.ts +15 -6
- package/src/session/chat.ts +66 -15
- package/src/session/request-size-guard.ts +123 -0
- package/src/session-runtime/provider-circuit.ts +140 -0
- package/src/shell-runner/file-engine.ts +1 -0
- package/src/shell-runner/types.ts +4 -0
- package/src/sidetab-core/model.ts +312 -0
- package/src/skills/tools/schedule-wakeup.ts +23 -1
- package/src/skills/tools/shell.ts +51 -5
- package/src/steward/directive-audit.ts +354 -0
- package/src/surface/child-process.ts +31 -0
- package/src/surface/tui-stderr-owner.ts +48 -0
- package/src/task-agent/cover.ts +30 -12
- package/src/task-agent/judge.ts +56 -0
- package/src/task-agent/parent-host.ts +14 -1
- package/src/task-agent/postland-card.ts +35 -2
- package/src/task-agent/rejudge-on-head.ts +46 -2
- package/src/task-agent/repair-cycle.ts +1 -1
- package/src/task-agent/task-hand.ts +133 -25
- package/src/task-agent/tier-split.ts +105 -21
- package/src/task-orchestrator/surfaces/pod-command-job.ts +330 -2
- package/src/task-orchestrator/surfaces/pod-config-snapshot.ts +123 -0
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +70 -2
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +29 -4
- package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +11 -8
- package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +74 -6
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +2 -1
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +56 -15
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +298 -45
- package/src/task-orchestrator/surfaces/self-implement.ts +18 -0
- package/src/tool-runtime/skill-exec-runtime.ts +95 -5
- package/src/tui/entry.ts +25 -5
- package/src/tui/inline-choice.ts +188 -0
- package/src/tui/sidetab/list.ts +36 -165
- package/src/tui/sidetab/nl-tool.ts +2 -136
- package/src/tui/sidetab/peek.ts +52 -0
- package/src/tui/slash/term.ts +12 -1
- package/src/tui-client/dashboard-session.ts +10 -1
- package/src/user-config.ts +45 -9
- package/src/ux-sim/classic-tui-seat-scenarios.ts +1 -7
- package/src/ux-sim/fake-land-queue.ts +88 -0
- package/src/ux-sim/fault-needs-human-reason-repair.ts +107 -0
- package/src/ux-sim/fault-pod-child-result.ts +42 -0
- package/src/ux-sim/gate-shard-host-reroute.ts +82 -0
- package/src/ux-sim/goal-interim-trace.ts +24 -0
- package/src/ux-sim/next-tui-seat-scenarios.ts +8 -13
- package/src/ux-sim/release-sim-rig.ts +262 -0
- package/src/ux-sim/seminar-rehearsal.ts +109 -0
- package/src/ux-sim/subagent-tools-device.ts +2 -2
- package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +4 -1
- package/src/version/packed-revision.json +1 -1
- package/src/video-pipeline/recipes/explainer.ts +54 -2
- package/src/web-search/grok.ts +32 -6
- package/src/web-search/index.ts +8 -7
- package/src/workflow-runtime/node-catalog.ts +53 -4
- package/apps/pwa/out/_next/static/chunks/1118.a8a74ea29aac3e46.js +0 -27
- package/apps/pwa/out/_next/static/chunks/1204-2aa830479adf80f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1341-43b7d2dc77d45c9d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1440-c3ea8882badfd9bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1698-9c11cbf97f13717e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1770-3b1fc92253ef9f2f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1923-5c1695332240246a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1938.0e6c60ee91c4d7f5.js +0 -148
- package/apps/pwa/out/_next/static/chunks/2104.70e086d5174a4736.js +0 -1
- package/apps/pwa/out/_next/static/chunks/213-20675f20673ba22a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/214.186a430da28338f1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2277.3bd4c0ac7f1b5996.js +0 -93
- package/apps/pwa/out/_next/static/chunks/240.e09f433f71c78ff4.js +0 -104
- package/apps/pwa/out/_next/static/chunks/2417.02151393605a7cd0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2463.cd2641a76daaa9ff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2576.b9e9c629c4b84c52.js +0 -1
- package/apps/pwa/out/_next/static/chunks/265-c021de53f0865bd9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2998-b1cc13956cd6a6e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2e4782d3.ba2f0ab2b63a53e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3130.626b54382b4dc379.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3221-1bb3f99a55088613.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3280.24edb1ffd03a7f3f.js +0 -24
- package/apps/pwa/out/_next/static/chunks/3288-eb3c22a1cbf2ae68.js +0 -1
- package/apps/pwa/out/_next/static/chunks/33.ef99e8374f96c6c4.js +0 -36
- package/apps/pwa/out/_next/static/chunks/3341-f09b9efbd7a82f70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3410-d7c0f14b329d6fda.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3421.c87d6313a7d670f7.js +0 -287
- package/apps/pwa/out/_next/static/chunks/3422-83a3953f9bd67e26.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3587-002e24e368c515a9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3644.f12a7d821ab940af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3660.d7516588e2d875c3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3695.b82e2610f4cd4ea9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3858.ca1f5bc0f577eac9.js +0 -94
- package/apps/pwa/out/_next/static/chunks/3959-e6ac4a139d9d4bcc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3f0de3de-2340c532c00395db.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4032.53f62176514ec0ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4199-f7c6eb40cd0322f8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4204-ef8484cbecd5d62f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4259-163129ca79913c4b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/428-eaa77df3d0c85969.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4432-97e400ffa1e161f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/449-aa427cf2cbb75f50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4491-39a0fd32bbaf3840.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4588.b7cf06d382953979.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4690.70ec8060825366ab.js +0 -32
- package/apps/pwa/out/_next/static/chunks/4804.6012b5cd33c22792.js +0 -90
- package/apps/pwa/out/_next/static/chunks/4881.e4d22d730e3b9df5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4937.ce2e340dc29cad3e.js +0 -79
- package/apps/pwa/out/_next/static/chunks/5-bb1c08d84bd71df3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5005.de98df23b37cdf3c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5035.dc64a89cad5573cc.js +0 -74
- package/apps/pwa/out/_next/static/chunks/5041-5aada92ca215ffdd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5207.1a224035455790fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5255-1b60d50eabe9f057.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5269.d0436ee6d773382a.js +0 -286
- package/apps/pwa/out/_next/static/chunks/5309.3367c4d50f52b489.js +0 -1
- package/apps/pwa/out/_next/static/chunks/552-689827d49780fa00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5539.34cc9d60622cb69b.js +0 -8
- package/apps/pwa/out/_next/static/chunks/5568.218dea0c00ca2ec7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5645.b7e3b055455a04ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5662.18cc0f30353cbd96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5671.da24fc9dc5e98325.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5b141171.324c40fd49cb6821.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6175-d4621f6a10b0cfab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6290.3eb53a20746b72ce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6415-9307f3eafa90837f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6579-3de35d00aacd71b5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/680-2f324c4e039a5b67.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6845-331b3c7481da3ba3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7000.28157393caaf5343.js +0 -62
- package/apps/pwa/out/_next/static/chunks/7311-60a7ea80d23c7521.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7401.525d0a12f7d02c06.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7438.c2cf72b66dca6aa4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7488.966b116789f3d41a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7524.ce973525d30b3d52.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7577.ea6e9ac72e035520.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7628.6b16863ac3972333.js +0 -34
- package/apps/pwa/out/_next/static/chunks/7657.8d1fb3d2f7ebe273.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7903-1435d5d2f0dd7807.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7954.4f7a8832663ee979.js +0 -115
- package/apps/pwa/out/_next/static/chunks/7978-30a91192c5dbe3c2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8025-8795821525cf1a07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8191.3674a00f0b565c23.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8217-604955d8885c5ef2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8298-eed6f5f2585a63f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8509.3a54d4e61893d7cb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8758.ac421f726a189125.js +0 -1
- package/apps/pwa/out/_next/static/chunks/891.d6c723a51a067b36.js +0 -149
- package/apps/pwa/out/_next/static/chunks/9223.cbcc88e0e9950426.js +0 -41
- package/apps/pwa/out/_next/static/chunks/9299.24e2a7d9b6d1f91b.js +0 -226
- package/apps/pwa/out/_next/static/chunks/9317.6a9869039c231bb3.js +0 -24
- package/apps/pwa/out/_next/static/chunks/9383.e4755f275b3c11ff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9581.da63ddf41acfad46.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9715.8c5529a0a5c41a36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9817.3009d65f0889ef1f.js +0 -2
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76873dd80da4f715.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed32b6ec5dea8f23.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-fdd40e15babf3d25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-384efc78e85e400b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-d91809c5aeed319a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-128f3522f89a81ab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-595961abf3b43ad1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-f41dccb76d8c0263.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-a3205c2e28b7d0d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-c39a80277814a3f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-1ab3f98194513195.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-a5246f7e254d77d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-0f92287bdb81217d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-5a37131ff63793ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-76873dd80da4f715.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-ac4bd14bb2348bfd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c348a3959c5b5fc6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-2addd81c0d3e2906.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-da6b765f58a3eefb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-0661e40f8780c32c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-b89af1b1c8e4875b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-da8aeb82ba751cdb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-cc71317b239439db.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-bde7fc1d64ffe369.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-e2797214f713fa58.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-2a35bcda70defaf6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3af03deedde45032.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-d1d1210f99f620ae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-46d1b5500885861d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-291ab19fe2acb173.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-7f569e533ddeecba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-990129c9fee46d8f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-7737f785ebb1cdaf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-9f3c73a4f7ffd2f8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-03be7fb347f01058.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-96b0280625e4df2b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-56855545049eb56d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-76873dd80da4f715.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-79a909c9981f0338.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-a9d9a3e66459c1e0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-c383cbf2013f7069.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f57c6a2e54dbdca4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-6b140f77593576eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-6b767ae2d9d0adfc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-116d6198d5da0e3d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-b9c9b778c7501370.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-a6c78392ab8f6335.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-455183deb4ed0cfe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-6a63e99526bd63d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-31c22caafe788c08.js +0 -1
- package/apps/pwa/out/_next/static/chunks/bb6987f9.3647e1a23b0e3217.js +0 -122
- package/apps/pwa/out/_next/static/chunks/framework-4b12a946f352cee2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-941155250ed2644b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-f8b6765abed6d149.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-78432194c85388f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-cdf7390829512b1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-d5f0964a9c2e92d2.js +0 -1
- package/scripts/ratchets/next-tui-entry-budget.ts +0 -124
- /package/apps/pwa/out/_next/static/{RrjXTwz-urRAbChP1bX02 → GiOLWmt4MqDZePubBjA4Q}/_ssgManifest.js +0 -0
|
@@ -20,9 +20,12 @@ import { resolveObserveOnlyDecision } from './observe-only.js';
|
|
|
20
20
|
import { getUserConfig } from '../user-config.js';
|
|
21
21
|
import { resolveAutoReview } from './context-capsule.js';
|
|
22
22
|
import { readDecomposeProposals } from '../self-dev/decompose-proposal.js';
|
|
23
|
+
import { tracedPathReferences } from './goal-author.js';
|
|
23
24
|
|
|
24
25
|
/** self implement CLI 옵션(commander) — `--no-draft` 는 draft:false 로, `--max-wait` 는 문자열로 도착. */
|
|
25
26
|
export interface SelfImplementCliOpts {
|
|
27
|
+
/** Managed tool dispatch cancellation signal, forwarded through the pipeline to the active implementation child. */
|
|
28
|
+
signal?: AbortSignal;
|
|
26
29
|
base?: string;
|
|
27
30
|
draft?: boolean;
|
|
28
31
|
openPr?: boolean;
|
|
@@ -63,6 +66,12 @@ export interface SelfImplementCliDeps {
|
|
|
63
66
|
resolveWantAutoReview?: (flag: boolean) => boolean | Promise<boolean>;
|
|
64
67
|
/** reroute 실행(테스트 주입). 기본 executeSelfImplementReroute. */
|
|
65
68
|
executeReroute?: typeof executeSelfImplementReroute;
|
|
69
|
+
/** Capability seam: false disables reason-repair reruns; omitted means available because this CLI has a production rerouter. */
|
|
70
|
+
reasonRepairExecutionAvailable?: boolean;
|
|
71
|
+
/** Supervisor side-effect seams for focused runtime tests. */
|
|
72
|
+
taskAgentShadow?: false;
|
|
73
|
+
taskAgentRejudge?: false;
|
|
74
|
+
sweepPendingMerges?: typeof import('./frozen-merges.js').sweepFrozenMerges;
|
|
66
75
|
/** ⭐ 산출물의 «눈» 심(테스트 주입). 기본은 실제 브라우저 검증(`observeDeliverables`).
|
|
67
76
|
* ⛔ 심이 «없으면» 이 배선을 시험으로 재현할 수 없고, 그러면 「손으로 돌려 봤다」만 남는다
|
|
68
77
|
* — 그것은 「그때 됐다」이지 「앞으로도 된다」가 아니다(리뷰 #10556 must-fix). */
|
|
@@ -122,11 +131,25 @@ export interface SingleRunSuperviseOptions {
|
|
|
122
131
|
type SelfImplementResultWithProposalMetadata = SelfImplementResult
|
|
123
132
|
& Pick<SelfDevJobResult, 'decomposeProposal' | 'goalPlanRevision'>;
|
|
124
133
|
|
|
125
|
-
|
|
134
|
+
/**
|
|
135
|
+
* NEEDS-HUMAN-REASON-REPAIR — 실행 범위 가드가 «대상 밖»으로 잰 변경을 감독 판정 재료로 옮긴다.
|
|
136
|
+
* ⛔ 가드가 잰 이름만 쓴다 — 결과에 없으면 빈 배열이고, 「없다」를 지어내지 않는다.
|
|
137
|
+
*/
|
|
138
|
+
function measuredOutsideTargetFiles(r: SelfImplementResult): string[] {
|
|
139
|
+
return [...new Set([
|
|
140
|
+
...(r.outOfScopeEdits ?? []),
|
|
141
|
+
...(r.scopeExpansion?.files.map((file) => file.path) ?? []),
|
|
142
|
+
])];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function singleRunAsJobResult(feature: string, r: SelfImplementResultWithProposalMetadata, includeDeclaredTargets = false): SupervisorJobResult {
|
|
146
|
+
const outsideTargetFiles = measuredOutsideTargetFiles(r);
|
|
147
|
+
const targetPaths = includeDeclaredTargets ? tracedPathReferences(feature).map(({ path }) => path) : [];
|
|
126
148
|
return {
|
|
127
149
|
taskId: r.runId,
|
|
128
150
|
runId: r.runId,
|
|
129
151
|
feature,
|
|
152
|
+
...(targetPaths.length ? { targetPaths } : {}),
|
|
130
153
|
status: r.ok ? 'done' : 'failed',
|
|
131
154
|
stage: r.stage,
|
|
132
155
|
...(!r.ok && r.detail ? { error: { message: r.detail } } : {}),
|
|
@@ -143,6 +166,7 @@ export function singleRunAsJobResult(feature: string, r: SelfImplementResultWith
|
|
|
143
166
|
...(r.abandonedClassification?.classification
|
|
144
167
|
? { failureClassification: r.abandonedClassification.classification } : {}),
|
|
145
168
|
...(r.decomposeProposal ? { decomposeProposal: r.decomposeProposal } : {}),
|
|
169
|
+
...(outsideTargetFiles.length > 0 ? { outsideTargetFiles } : {}),
|
|
146
170
|
...(r.rework ? { rework: r.rework } : {}),
|
|
147
171
|
...(r.review?.reviewed && r.review.mustFix?.length ? { reviewMustFix: r.review.mustFix } : {}),
|
|
148
172
|
...(r.goalPlanRevision ? { goalPlanRevision: r.goalPlanRevision } : {}),
|
|
@@ -228,8 +252,8 @@ export async function runSelfImplementCliCommand(
|
|
|
228
252
|
entry: opts.entry ?? 'external-verbatim', // CLI = 외부 창구(외부가 프롬프트 엔지니어 → verbatim 존중)
|
|
229
253
|
});
|
|
230
254
|
spec.entrance = opts.naturalLanguageDispatch ? 'nl-self-implement' : 'cli-self-implement';
|
|
231
|
-
const pipelineDeps = opts.approver || opts.progress
|
|
232
|
-
? { ...deps.pipelineDeps, ...(opts.approver ? { approver: opts.approver } : {}), ...(opts.progress ? { progress: opts.progress } : {}) }
|
|
255
|
+
const pipelineDeps = opts.approver || opts.progress || opts.signal
|
|
256
|
+
? { ...deps.pipelineDeps, ...(opts.approver ? { approver: opts.approver } : {}), ...(opts.progress ? { progress: opts.progress } : {}), ...(opts.signal ? { signal: opts.signal } : {}) }
|
|
233
257
|
: deps.pipelineDeps;
|
|
234
258
|
const exec = deps.executeReroute ?? executeSelfImplementReroute;
|
|
235
259
|
let { result, exitCode } = await exec(spec, pipelineDeps ? { pipelineDeps } : undefined);
|
|
@@ -266,10 +290,20 @@ export async function runSelfImplementCliCommand(
|
|
|
266
290
|
}
|
|
267
291
|
: undefined;
|
|
268
292
|
|
|
269
|
-
const
|
|
293
|
+
const reasonRepairEnabled = getUserConfig().tools.selfImplement.supervisor?.reasonRepair === true
|
|
294
|
+
&& (deps.reasonRepairExecutionAvailable ?? true);
|
|
295
|
+
const initialJob = singleRunAsJobResult(feature, result, reasonRepairEnabled);
|
|
296
|
+
// NEEDS-HUMAN-REASON-REPAIR — 사유별 수복 골을 «실행하는» 경로인가.
|
|
297
|
+
// ⛔ 아래 rerun 이 invocation.repairGoals[taskId] 를 spec.input.text 로 그대로 실행하므로 «그렇다».
|
|
298
|
+
// ⇒ 그래서 이 감독 경로는 사유별 수복(needs-human 전 1회)을 연다.
|
|
299
|
+
const repairGoalExecution = true;
|
|
270
300
|
await superviseRun({
|
|
271
301
|
initial: [initialJob],
|
|
272
|
-
|
|
302
|
+
...(deps.taskAgentShadow === false ? { taskAgentShadow: false } : {}),
|
|
303
|
+
...(deps.taskAgentRejudge === false ? { taskAgentRejudge: false } : {}),
|
|
304
|
+
...(deps.sweepPendingMerges ? { sweepPendingMerges: deps.sweepPendingMerges } : {}),
|
|
305
|
+
repairGoalExecution,
|
|
306
|
+
needsHumanReasonRepairExecution: reasonRepairEnabled,
|
|
273
307
|
limits,
|
|
274
308
|
...(deliverableEye ? { observeDeliverables: deliverableEye } : {}),
|
|
275
309
|
...(opts.supervise.onDecision ? { onDecision: opts.supervise.onDecision } : {}),
|
|
@@ -283,7 +317,7 @@ export async function runSelfImplementCliCommand(
|
|
|
283
317
|
const next = await exec(repairGoal ? { ...spec, input: { ...spec.input, text: repairGoal } } : spec, pipelineDeps ? { pipelineDeps } : undefined);
|
|
284
318
|
result = attachGoalPlanRevisionObservation(next.result, deps);
|
|
285
319
|
exitCode = next.exitCode;
|
|
286
|
-
return [{ ...singleRunAsJobResult(feature, result), taskId: initialJob.taskId }];
|
|
320
|
+
return [{ ...singleRunAsJobResult(feature, result, reasonRepairEnabled), taskId: initialJob.taskId }];
|
|
287
321
|
},
|
|
288
322
|
});
|
|
289
323
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** Production STOP-AUTOHEAL actions. A missing prerequisite is a failed action, never a healed run. */
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
|
|
4
|
+
import { runHostRegate, type HostRegateInput, type HostRegateResult } from './host-regate.js';
|
|
5
|
+
import type { AutohealActions, AutohealContext } from './stop-autoheal.js';
|
|
6
|
+
|
|
7
|
+
type PrHead = { headRefOid?: string; state?: string; isDraft?: boolean };
|
|
8
|
+
export interface OperationalAutohealDeps {
|
|
9
|
+
repoRoot: string;
|
|
10
|
+
readPr?: (number: number, repoRoot: string) => PrHead | null;
|
|
11
|
+
regate?: (input: HostRegateInput) => Promise<HostRegateResult>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function prFromEvidence(ctx: AutohealContext): number | null {
|
|
15
|
+
const match = /^https:\/\/github\.com\/[^/]+\/[^/]+\/pull\/([1-9]\d*)\/?$/.exec(ctx.record.evidenceRef);
|
|
16
|
+
return match ? Number(match[1]) : null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function readPr(number: number, repoRoot: string): PrHead | null {
|
|
20
|
+
const result = spawnSync('gh', ['pr', 'view', String(number), '--json', 'headRefOid,state,isDraft'], {
|
|
21
|
+
cwd: repoRoot, encoding: 'utf8', timeout: 30_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER,
|
|
22
|
+
});
|
|
23
|
+
if (result.status !== 0) return null;
|
|
24
|
+
try { return JSON.parse(result.stdout) as PrHead; } catch { return null; }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Re-gate an existing PR in a clean checkout against current main; never merge from the healer. */
|
|
28
|
+
export function operationalAutohealActions(deps: OperationalAutohealDeps): AutohealActions {
|
|
29
|
+
return {
|
|
30
|
+
'clean-workspace-regate': async (ctx) => {
|
|
31
|
+
const number = prFromEvidence(ctx);
|
|
32
|
+
if (!number) return { ok: false, detail: 'PR URL absent from stop evidence' };
|
|
33
|
+
const pr = (deps.readPr ?? readPr)(number, deps.repoRoot);
|
|
34
|
+
if (!pr?.headRefOid || pr.state !== 'OPEN' || typeof pr.isDraft !== 'boolean')
|
|
35
|
+
return { ok: false, detail: `PR #${number} is not an open PR with a measured head and draft state` };
|
|
36
|
+
const result = await (deps.regate ?? runHostRegate)({
|
|
37
|
+
prNumber: number, headCommit: pr.headRefOid, repoRoot: deps.repoRoot, verifyOnly: true,
|
|
38
|
+
...(pr.isDraft ? { allowDraft: true } : {}),
|
|
39
|
+
});
|
|
40
|
+
return { ok: result.passed, detail: `PR #${number} head ${pr.headRefOid} clean regate ${result.status ?? (result.passed ? 'passed' : 'failed')}${result.failures.length ? `: ${result.failures.map((failure) => failure.step).join(',')}` : ''}` };
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -13,11 +13,12 @@
|
|
|
13
13
|
* main-sync → rebase-regate 리베이스(MERGE-INTENT-RESOLVE 의도 해석) 뒤 재게이트
|
|
14
14
|
* pod-died → resume-from-salvage `salvage/run-<6hex>/<leaf>` 가지에서 resume(DRAFT-NOT-ARCHIVE)
|
|
15
15
|
* evidence-uncovered → derive-evidence-rejudge 런 출력·시험·배선에서 증거를 끌어내 1회 재판정
|
|
16
|
+
* review-budget-exhausted → needs-owner (code fallback; reauthor is an optional graph exit)
|
|
16
17
|
* review-repeat · review-out-of-scope · scope-escape · fabric · launch-failed · gate-failed · unclassified → needs-owner(새 라운드 없음)
|
|
17
18
|
*
|
|
18
19
|
* 사다리의 «출처»: `graphs/overlays/stop-heal-ladder.yaml` 이 갈래마다 처방 노드(id = 처방 이름)를 선언한다.
|
|
19
20
|
* 그 갈래에 얹힌 오버레이가 더한 노드 id 가 처방이다(source='graph'). 선언이 없거나 못 읽으면
|
|
20
|
-
* 위 표(`AUTOHEAL_ACTION_BY_CLASS`)로 간다(source='code-default').
|
|
21
|
+
* 위 표(`AUTOHEAL_ACTION_BY_CLASS`)로 간다(source='code-default'). 선택된 노드가 실제 실행 가능한지는 별도 경계다.
|
|
21
22
|
*
|
|
22
23
|
* 모드 `tools.selfImplement.autoheal.mode` = `shadow`(기본: 할 일을 원장에만 적고 손대지 않는다) | `live`.
|
|
23
24
|
* ⛔ live 에서도 행동은 주입 seam 으로만 한다 — seam 이 없는 행동은 `needs-owner`(action-unwired)로 떨어진다.
|
|
@@ -44,6 +45,7 @@ export type AutohealAction =
|
|
|
44
45
|
| 'rebase-regate'
|
|
45
46
|
| 'resume-from-salvage'
|
|
46
47
|
| 'derive-evidence-rejudge'
|
|
48
|
+
| 'review-round-reauthor'
|
|
47
49
|
| 'needs-owner';
|
|
48
50
|
|
|
49
51
|
/** 닫힌 목록 전체를 덮는다 — 새 class 가 생기면 여기서 타입 오류가 난다. */
|
|
@@ -55,6 +57,8 @@ export const AUTOHEAL_ACTION_BY_CLASS: Readonly<Record<RunStopClass, AutohealAct
|
|
|
55
57
|
'evidence-uncovered': 'derive-evidence-rejudge',
|
|
56
58
|
'review-repeat': 'needs-owner',
|
|
57
59
|
'review-out-of-scope': 'needs-owner',
|
|
60
|
+
// Reauthoring is an optional graph exit, not a code-level guarantee.
|
|
61
|
+
'review-budget-exhausted': 'needs-owner',
|
|
58
62
|
'scope-escape': 'needs-owner',
|
|
59
63
|
fabric: 'needs-owner',
|
|
60
64
|
'launch-failed': 'needs-owner',
|
|
@@ -64,7 +68,7 @@ export const AUTOHEAL_ACTION_BY_CLASS: Readonly<Record<RunStopClass, AutohealAct
|
|
|
64
68
|
|
|
65
69
|
/** 처방 노드 id 로 인정하는 이름 — 오버레이가 더한 노드 중 이 넷만 처방으로 읽는다. */
|
|
66
70
|
const HEAL_ACTION_NODE_IDS: ReadonlySet<string> = new Set<Exclude<AutohealAction, 'needs-owner'>>([
|
|
67
|
-
'clean-workspace-regate', 'rebase-regate', 'resume-from-salvage', 'derive-evidence-rejudge',
|
|
71
|
+
'clean-workspace-regate', 'rebase-regate', 'resume-from-salvage', 'derive-evidence-rejudge', 'review-round-reauthor',
|
|
68
72
|
]);
|
|
69
73
|
|
|
70
74
|
/** 처방이 «어디서» 왔나 — `graph` = 그 갈래에 얹힌 오버레이가 더한 노드 · `code-default` = 위 표. */
|
|
@@ -75,6 +79,8 @@ export interface AutohealPick {
|
|
|
75
79
|
source: AutohealActionSource;
|
|
76
80
|
/** source='graph' 일 때 그 처방 노드를 더한 오버레이. */
|
|
77
81
|
overlayId?: string;
|
|
82
|
+
/** Code fallback when an optional graph exit is not declared. */
|
|
83
|
+
fallbackReason?: string;
|
|
78
84
|
}
|
|
79
85
|
|
|
80
86
|
/** 사다리를 읽어 오는 자리 — 활성 템플릿 선언 ⊕ 오버레이 목록. 시험이 갈아 끼운다. */
|
|
@@ -93,7 +99,10 @@ function loadDefaultLadder(): AutohealLadder {
|
|
|
93
99
|
* «조용히» 코드 표로 간다 — 그 사실은 `source` 가 말한다. 던지지 않는다.
|
|
94
100
|
*/
|
|
95
101
|
export function pickAutohealAction(cls: RunStopClass, loadLadder: () => AutohealLadder = loadDefaultLadder): AutohealPick {
|
|
96
|
-
const codeDefault: AutohealPick = {
|
|
102
|
+
const codeDefault: AutohealPick = {
|
|
103
|
+
action: AUTOHEAL_ACTION_BY_CLASS[cls] ?? 'needs-owner', source: 'code-default',
|
|
104
|
+
...(cls === 'review-budget-exhausted' ? { fallbackReason: 'declared-node-unavailable: review-round-reauthor' } : {}),
|
|
105
|
+
};
|
|
97
106
|
try {
|
|
98
107
|
const { template, overlays } = loadLadder();
|
|
99
108
|
if (!template) return codeDefault;
|
|
@@ -297,8 +306,8 @@ export async function autohealFromStop(ctx: AutohealContext, deps: AutohealDeps
|
|
|
297
306
|
}
|
|
298
307
|
const mode = deps.mode ?? DEFAULT_AUTOHEAL_MODE;
|
|
299
308
|
const cls = ctx.record.class;
|
|
300
|
-
const { action, source, overlayId } = pickAutohealAction(cls, deps.loadLadder);
|
|
301
|
-
const base = { runId: ctx.runId, class: cls, action, source, ...(overlayId ? { overlayId } : {}), mode };
|
|
309
|
+
const { action, source, overlayId, fallbackReason } = pickAutohealAction(cls, deps.loadLadder);
|
|
310
|
+
const base = { runId: ctx.runId, class: cls, action, source, ...(overlayId ? { overlayId } : {}), ...(fallbackReason ? { fallbackReason } : {}), mode };
|
|
302
311
|
|
|
303
312
|
if (repeatedStop(deps.priorStops, ctx.record)) {
|
|
304
313
|
// ⛔ 같은 골에서 같은 갈래의 멈춤이 반복되면 자동 재시도를 하지 않는다 — 사유를 골 되먹임 대상으로 넘긴다.
|
|
@@ -329,7 +338,7 @@ export async function autohealFromStop(ctx: AutohealContext, deps: AutohealDeps
|
|
|
329
338
|
let detail: string | undefined;
|
|
330
339
|
if (action === 'needs-owner') {
|
|
331
340
|
outcome = 'needs-owner';
|
|
332
|
-
reason = `stop ${cls}: ${ctx.record.cause}`;
|
|
341
|
+
reason = `${fallbackReason ? `${fallbackReason}; ` : ''}stop ${cls}: ${ctx.record.cause}`;
|
|
333
342
|
} else if (mode === 'shadow') {
|
|
334
343
|
outcome = 'would-act';
|
|
335
344
|
} else {
|
package/src/session/chat.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
type SessionMeta, type SerializedMessage, type CreateSessionOpts,
|
|
18
18
|
} from './index.js';
|
|
19
19
|
import { debug } from '../debug/log.js';
|
|
20
|
+
import { createRequestSizeGuard, formatRequestSizeStatus, type RequestSizeGuard } from './request-size-guard.js';
|
|
20
21
|
import type { InputSourceKind } from '../input/input-source-kind.js';
|
|
21
22
|
import {
|
|
22
23
|
getProviderForConfig, streamLLMWithTools, type LLMMessage, type LLMOpts, type LLMProvider,
|
|
@@ -285,7 +286,8 @@ const childContextComposedSessions = new Set<string>();
|
|
|
285
286
|
export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
|
|
286
287
|
const loaded = loadSession(opts.sessionId);
|
|
287
288
|
if (!loaded) throw new Error(`session not found: ${opts.sessionId}`);
|
|
288
|
-
const { meta
|
|
289
|
+
const { meta } = loaded;
|
|
290
|
+
let messages = loaded.messages;
|
|
289
291
|
|
|
290
292
|
// Memory injection: build the block once per turn, folded into the
|
|
291
293
|
// system prompt. Never fails loud — if the store isn't set up, we
|
|
@@ -368,6 +370,19 @@ export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
|
|
|
368
370
|
};
|
|
369
371
|
appendMessage(opts.sessionId, userMsg);
|
|
370
372
|
|
|
373
|
+
const explicitTier = opts.llmOpts?.model ? undefined : explicitTurnTier(opts.userConfig, opts.sessionId);
|
|
374
|
+
const llmOpts = explicitTier ? {
|
|
375
|
+
...(opts.llmOpts ?? {}), model: explicitTier.model,
|
|
376
|
+
...(explicitTier.reasoningEffort && !opts.llmOpts?.reasoningEffort ? { reasoningEffort: explicitTier.reasoningEffort } : {}),
|
|
377
|
+
} : opts.llmOpts;
|
|
378
|
+
if (explicitTier) {
|
|
379
|
+
debug.log('llm.tier', 'turn-tier-applied', {
|
|
380
|
+
sessionId: opts.sessionId, tier: explicitTier.tier, source: explicitTier.source, model: explicitTier.model,
|
|
381
|
+
reasoningEffort: llmOpts?.reasoningEffort ?? null,
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
const provider = opts.provider ?? getProviderForConfig(opts.userConfig, llmOpts?.model);
|
|
385
|
+
|
|
371
386
|
// 2) Assemble, trim, call. When images are attached for THIS turn,
|
|
372
387
|
// swap the string content of the latest user message for
|
|
373
388
|
// ContentBlock[] so the provider adapter sends them multimodally.
|
|
@@ -386,18 +401,43 @@ export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
|
|
|
386
401
|
return trimToBudget(wire, opts.maxTokens ?? DEFAULT_TOKEN_BUDGET);
|
|
387
402
|
};
|
|
388
403
|
|
|
389
|
-
const
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
404
|
+
const requestSizeGuard: RequestSizeGuard | undefined =
|
|
405
|
+
meta.source === 'tui' && provider.name === 'openai-codex'
|
|
406
|
+
? createRequestSizeGuard({
|
|
407
|
+
compactOptions: () => ({
|
|
408
|
+
sessionId: opts.sessionId,
|
|
409
|
+
activeModelId: llmOpts?.model ?? provider.defaultModel,
|
|
410
|
+
preserveLastN: opts.userConfig.chat.autoCompact.preserveLastN,
|
|
411
|
+
archiveEnabled: opts.userConfig.chat.compact.archiveEnabled,
|
|
412
|
+
}),
|
|
413
|
+
// The first request has only the persisted transcript plus this
|
|
414
|
+
// user turn, so use the shared session compactor and rebuild from
|
|
415
|
+
// the rewritten history. Later tool rounds compact their live
|
|
416
|
+
// message list (shared guard) so no just-produced tool context is lost.
|
|
417
|
+
compactFirstRequest: async () => {
|
|
418
|
+
const { compactSessionHistory } = await import('./compact-session.js');
|
|
419
|
+
const result = await compactSessionHistory(opts.sessionId, {
|
|
420
|
+
config: opts.userConfig.chat.autoCompact,
|
|
421
|
+
force: true,
|
|
422
|
+
modelId: llmOpts?.model ?? provider.defaultModel,
|
|
423
|
+
});
|
|
424
|
+
if (!result.fired) return null;
|
|
425
|
+
const refreshed = loadSession(opts.sessionId);
|
|
426
|
+
if (!refreshed) return null;
|
|
427
|
+
// The persisted compacted session includes this turn's
|
|
428
|
+
// user message. Drop that final persisted row here, then
|
|
429
|
+
// assembleTurnMessages re-adds the canonical userMsg and
|
|
430
|
+
// any image blocks from opts.userImages exactly once.
|
|
431
|
+
messages = refreshed.messages.slice(0, -1);
|
|
432
|
+
const rebuilt = assembleTurnMessages(effectiveSystemPrompt).kept;
|
|
433
|
+
return { messages: rebuilt, reason: `session-${result.reason}` };
|
|
434
|
+
},
|
|
435
|
+
onMeasured: (measurement) => {
|
|
436
|
+
opts.onStatusLine?.(formatRequestSizeStatus(measurement));
|
|
437
|
+
},
|
|
438
|
+
})
|
|
439
|
+
: undefined;
|
|
440
|
+
|
|
401
441
|
let kept: LLMMessage[] = [];
|
|
402
442
|
let dropped = 0;
|
|
403
443
|
let used = 0;
|
|
@@ -432,6 +472,9 @@ export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
|
|
|
432
472
|
effectiveSystemPrompt = terminal.systemPromptParts.join('\n\n');
|
|
433
473
|
}
|
|
434
474
|
const turnLlmOpts = terminal ? terminal.llmOpts : llmOpts;
|
|
475
|
+
const guardedTurnLlmOpts = requestSizeGuard
|
|
476
|
+
? { ...(turnLlmOpts ?? {}), requestSizeGuard: turnLlmOpts?.requestSizeGuard ?? requestSizeGuard }
|
|
477
|
+
: turnLlmOpts;
|
|
435
478
|
({ kept, dropped, used } = assembleTurnMessages(effectiveSystemPrompt));
|
|
436
479
|
// Durable tool telemetry (추적성) — pair each call's args (onToolCall) with its
|
|
437
480
|
// result (onToolResult) and persist a role:'tool' message so later "어떤 도구
|
|
@@ -471,6 +514,8 @@ export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
|
|
|
471
514
|
userText: opts.userText,
|
|
472
515
|
messages: kept,
|
|
473
516
|
tools: turnTools,
|
|
517
|
+
...(guardedTurnLlmOpts?.requestSizeGuard
|
|
518
|
+
? { requestSizeGuard: guardedTurnLlmOpts.requestSizeGuard } : {}),
|
|
474
519
|
dispatchTool: async (name, args, ctx) => dispatchTool(name, args, ctx),
|
|
475
520
|
signal: opts.signal ?? new AbortController().signal,
|
|
476
521
|
callbacks: {
|
|
@@ -491,6 +536,8 @@ export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
|
|
|
491
536
|
},
|
|
492
537
|
...(turnLlmOpts?.model ? { modelOverride: turnLlmOpts.model } : {}),
|
|
493
538
|
...(turnLlmOpts?.budgetGrant ? { budgetGrant: turnLlmOpts.budgetGrant } : {}),
|
|
539
|
+
...(guardedTurnLlmOpts?.requestSizeGuard
|
|
540
|
+
? { requestSizeGuard: guardedTurnLlmOpts.requestSizeGuard } : {}),
|
|
494
541
|
};
|
|
495
542
|
const maxIterations = opts.goalLoopMaxIterations ?? goalLoopCfg?.maxIterations;
|
|
496
543
|
const gl = await runGoalLoop(coreCtx, maxIterations !== undefined ? { maxIterations } : {});
|
|
@@ -513,7 +560,7 @@ export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
|
|
|
513
560
|
},
|
|
514
561
|
},
|
|
515
562
|
{
|
|
516
|
-
...(
|
|
563
|
+
...(guardedTurnLlmOpts ?? {}),
|
|
517
564
|
tools: turnTools,
|
|
518
565
|
provider,
|
|
519
566
|
// ★ /cancel 범용화(대표 2026-07-12) — per-turn abort signal 을 tool 루프·llm 호출에 전파.
|
|
@@ -527,7 +574,11 @@ export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
|
|
|
527
574
|
}
|
|
528
575
|
} else {
|
|
529
576
|
({ kept, dropped, used } = assembleTurnMessages(effectiveSystemPrompt));
|
|
530
|
-
const plainOpts =
|
|
577
|
+
const plainOpts = {
|
|
578
|
+
...(llmOpts ?? {}),
|
|
579
|
+
...(requestSizeGuard ? { requestSizeGuard: llmOpts?.requestSizeGuard ?? requestSizeGuard } : {}),
|
|
580
|
+
...(opts.signal ? { signal: opts.signal } : {}),
|
|
581
|
+
};
|
|
531
582
|
const stream = provider.streamChat
|
|
532
583
|
? provider.streamChat(kept, plainOpts)
|
|
533
584
|
: wrapTextOnly(provider.chat(kept, plainOpts));
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// TUI-TOKEN-GUARD-WIRE — shared request-size guard (#32254 cap).
|
|
2
|
+
//
|
|
3
|
+
// The 400k-char cap used to be built only inside `session/chat.ts runTurn`.
|
|
4
|
+
// The production TUI does not run that function: it goes
|
|
5
|
+
// DashboardSession → bridgeCoreTurnToAcp → runCoreTurn/runGoalLoop, so the
|
|
6
|
+
// guard never reached `llm.ts` and no `request-size-compact` event fired
|
|
7
|
+
// (root cause: seat-state/OP/tmp/TUI-TOKEN-BURN-ROOT-CAUSE-1028.md).
|
|
8
|
+
//
|
|
9
|
+
// This module owns the guard construction so both paths share one policy:
|
|
10
|
+
// - `createRequestSizeGuard` — the `LLMOpts.requestSizeGuard` object.
|
|
11
|
+
// The first measured request may use a caller hook (`compactFirstRequest`)
|
|
12
|
+
// that compacts the caller's *persisted* history; every other request
|
|
13
|
+
// (and a first request whose hook declines) compacts the live message list.
|
|
14
|
+
// - `compactLiveMessages` — the live compaction (Layer 1/2 + optional
|
|
15
|
+
// Layer 3 summarize) shared by the guard and by hosts that compact their
|
|
16
|
+
// own history store.
|
|
17
|
+
// - `estimateRequestChars` — cheap pre-send estimate (JSON chars of the
|
|
18
|
+
// messages plus tool specs) used by the ACP bridge preflight.
|
|
19
|
+
//
|
|
20
|
+
// ⚠️ `llm.ts` applies the compacted list with `messages.splice(...)`, but the
|
|
21
|
+
// array it receives is a per-request copy (`mapProviderToolNamesInMessages`),
|
|
22
|
+
// not `streamLLMWithTools`'s `history`. Compaction therefore does not survive
|
|
23
|
+
// into the next tool round by itself — the guard re-measures each request —
|
|
24
|
+
// and only a host write-back (chat.ts session rewrite / dashboard history
|
|
25
|
+
// replace) makes it survive into the next prompt.
|
|
26
|
+
|
|
27
|
+
import type { LLMMessage, LLMOpts, LLMToolSpec } from '../llm.js';
|
|
28
|
+
import type { CompactProvider } from '../compact/provider.js';
|
|
29
|
+
|
|
30
|
+
/** #32254 — the wire cap for Codex TUI requests (serialized body chars). */
|
|
31
|
+
export const REQUEST_SIZE_MAX_CHARS = 400_000;
|
|
32
|
+
|
|
33
|
+
export type RequestSizeGuard = NonNullable<LLMOpts['requestSizeGuard']>;
|
|
34
|
+
export type RequestSizeMeasurement = Parameters<NonNullable<RequestSizeGuard['onMeasured']>>[0];
|
|
35
|
+
export type RequestSizeCompactInfo = Parameters<RequestSizeGuard['compactMessages']>[1];
|
|
36
|
+
export type RequestSizeCompactResult = Awaited<ReturnType<RequestSizeGuard['compactMessages']>>;
|
|
37
|
+
|
|
38
|
+
type RunCompactPipeline = typeof import('../compact/pipeline.js').runCompactPipeline;
|
|
39
|
+
|
|
40
|
+
export interface CompactLiveMessagesOptions {
|
|
41
|
+
sessionId?: string;
|
|
42
|
+
activeModelId?: string;
|
|
43
|
+
preserveLastN?: number;
|
|
44
|
+
archiveEnabled?: boolean;
|
|
45
|
+
/** Test seam — defaults to the real `runCompactPipeline` with the default compact provider. */
|
|
46
|
+
runCompactPipeline?: RunCompactPipeline;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Compact a live message list. Returns `null` when no layer changed anything. */
|
|
50
|
+
export async function compactLiveMessages(
|
|
51
|
+
messages: LLMMessage[],
|
|
52
|
+
opts: CompactLiveMessagesOptions,
|
|
53
|
+
): Promise<{ messages: LLMMessage[]; reason: string } | null> {
|
|
54
|
+
let run = opts.runCompactPipeline;
|
|
55
|
+
let provider: CompactProvider | undefined;
|
|
56
|
+
if (!run) {
|
|
57
|
+
run = (await import('../compact/pipeline.js')).runCompactPipeline;
|
|
58
|
+
provider = (await import('../compact/provider.js')).getDefaultCompactProvider();
|
|
59
|
+
}
|
|
60
|
+
const compacted = await run(messages, {
|
|
61
|
+
...(opts.sessionId !== undefined ? { sessionId: opts.sessionId } : {}),
|
|
62
|
+
...(provider !== undefined ? { provider } : {}),
|
|
63
|
+
...(opts.activeModelId !== undefined ? { activeModelId: opts.activeModelId } : {}),
|
|
64
|
+
policy: {
|
|
65
|
+
...(opts.preserveLastN !== undefined ? { preserveLastN: opts.preserveLastN } : {}),
|
|
66
|
+
...(opts.archiveEnabled !== undefined ? { archiveEnabled: opts.archiveEnabled } : {}),
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
const diagnostics = compacted.diagnostics;
|
|
70
|
+
const changed = diagnostics.layer1ResponsesTrimmed > 0
|
|
71
|
+
|| diagnostics.layer2MicrocompactCleared > 0
|
|
72
|
+
|| diagnostics.layer3SummaryApplied === 1
|
|
73
|
+
|| diagnostics.layer5FallbackTruncated === 1;
|
|
74
|
+
return changed ? { messages: compacted.messages, reason: 'live-request-compact' } : null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface CreateRequestSizeGuardOptions {
|
|
78
|
+
maxChars?: number;
|
|
79
|
+
/** Live-compaction options, resolved lazily at compaction time (config is
|
|
80
|
+
* read only when a request is actually over the cap). */
|
|
81
|
+
compactOptions: () => CompactLiveMessagesOptions;
|
|
82
|
+
/** First measured request only: compact the caller's persisted history and
|
|
83
|
+
* return the rebuilt request. `null` falls through to live compaction. */
|
|
84
|
+
compactFirstRequest?: (
|
|
85
|
+
currentMessages: LLMMessage[],
|
|
86
|
+
info: RequestSizeCompactInfo,
|
|
87
|
+
) => Promise<RequestSizeCompactResult>;
|
|
88
|
+
onMeasured?: (measurement: RequestSizeMeasurement) => void;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function createRequestSizeGuard(opts: CreateRequestSizeGuardOptions): RequestSizeGuard {
|
|
92
|
+
let measuredProviderRequests = 0;
|
|
93
|
+
return {
|
|
94
|
+
maxChars: opts.maxChars ?? REQUEST_SIZE_MAX_CHARS,
|
|
95
|
+
compactMessages: async (currentMessages, info) => {
|
|
96
|
+
if (measuredProviderRequests === 0 && opts.compactFirstRequest) {
|
|
97
|
+
const first = await opts.compactFirstRequest(currentMessages, info);
|
|
98
|
+
if (first) return first;
|
|
99
|
+
}
|
|
100
|
+
return compactLiveMessages(currentMessages, opts.compactOptions());
|
|
101
|
+
},
|
|
102
|
+
onMeasured: (measurement) => {
|
|
103
|
+
measuredProviderRequests += 1;
|
|
104
|
+
opts.onMeasured?.(measurement);
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Cheap pre-send size estimate: JSON chars of the messages plus tool specs.
|
|
110
|
+
* It tracks the Codex wire body closely (the wire also serializes both). */
|
|
111
|
+
export function estimateRequestChars(messages: readonly LLMMessage[], tools: readonly LLMToolSpec[] = []): number {
|
|
112
|
+
try {
|
|
113
|
+
return JSON.stringify(messages).length + (tools.length > 0 ? JSON.stringify(tools).length : 0);
|
|
114
|
+
} catch {
|
|
115
|
+
return 0;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** One-line status text shared by chat.ts and the ACP bridge. */
|
|
120
|
+
export function formatRequestSizeStatus(measurement: RequestSizeMeasurement): string {
|
|
121
|
+
return `ctx ${measurement.requestChars.toLocaleString()} chars / ${measurement.maxChars.toLocaleString()}`
|
|
122
|
+
+ (measurement.compacted ? ` · compact ${measurement.reason}` : '');
|
|
123
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ⚡ SURVIVAL-PROVIDER-CIRCUIT — 공급자별 회로 차단기 (S2)
|
|
3
|
+
* 정본: 내부 문서 `RFC-tui-never-stop-survival-ladder-2026-10-27` §3 S2 · §6 B
|
|
4
|
+
*
|
|
5
|
+
* 턴 «안»의 공급자 전환(src/llm.ts decideProviderFallback → provider-fallback)은
|
|
6
|
+
* 이미 있지만, 턴이 끝나면 «방금 누가 고장 났나»를 잊는다. 다음 턴은 다시
|
|
7
|
+
* 1순위부터 열어 매번 무응답 대기를 먼저 치른다. 이 모듈은 프로세스 안에
|
|
8
|
+
* 공급자별 회로 상태를 남겨 턴을 넘어 건강을 기억한다.
|
|
9
|
+
*
|
|
10
|
+
* ⭐ 사람 의도가 이긴다(src/oauth/fallback-chain.ts 규율 ②) — 회로는 어디까지나
|
|
11
|
+
* 폴백 판정 보조다. opts.provider 로 명시·고정된 턴은 회로를 보지 않는다.
|
|
12
|
+
*
|
|
13
|
+
* 상태기계:
|
|
14
|
+
* closed —(10분 창 안 «전환 사유» 연속 2회 실패)→ open (냉각 5분)
|
|
15
|
+
* open —(냉각 경과)→ half-open
|
|
16
|
+
* half-open —(다음 시도 1회)→ 성공: closed / 실패: open (냉각 2배, 상한 30분)
|
|
17
|
+
*
|
|
18
|
+
* 전환 사유 범주는 `isProviderFallbackEligible` 이 참인 범주
|
|
19
|
+
* (network-transient · rate-limit · overloaded · malformed) ⊕
|
|
20
|
+
* `StreamIdleTimeoutError`(stream-idle-timeout) · `OverloadFailoverError`
|
|
21
|
+
* (overload-failover) 로 한정한다. 그 외 범주(context-window · safety-blocked
|
|
22
|
+
* 등 사용자 탓)는 회로에 기록하지 않는다 — 사용자가 문면을 고치기 전까지
|
|
23
|
+
* 다른 공급자로 도망갈 이유가 없다.
|
|
24
|
+
*/
|
|
25
|
+
import { debug } from '../debug/log.js';
|
|
26
|
+
import { isProviderFallbackEligible, type RetryCategory } from './retry-policy.js';
|
|
27
|
+
|
|
28
|
+
export type ProviderCircuitState = 'closed' | 'open' | 'half-open';
|
|
29
|
+
|
|
30
|
+
/** 회로 실패로 세는 «전환 사유» 범주에 추가로 들어가는 두 에러의 범주명. */
|
|
31
|
+
export const CIRCUIT_EXTRA_CATEGORIES = ['stream-idle-timeout', 'overload-failover'] as const;
|
|
32
|
+
|
|
33
|
+
/** 10분 창 — 같은 공급자의 «전환 사유» 실패 2회가 이 창 안에 있어야 열린다. */
|
|
34
|
+
export const CIRCUIT_FAILURE_WINDOW_MS = 10 * 60_000;
|
|
35
|
+
/** 첫 냉각 5분 — 다시 열릴 때마다 2배. */
|
|
36
|
+
export const CIRCUIT_COOLDOWN_BASE_MS = 5 * 60_000;
|
|
37
|
+
export const CIRCUIT_COOLDOWN_MAX_MS = 30 * 60_000;
|
|
38
|
+
export const CIRCUIT_FAILURE_THRESHOLD = 2;
|
|
39
|
+
|
|
40
|
+
interface CircuitEntry {
|
|
41
|
+
/** «전환 사유» 실패 시각(에포크 ms) — 10분 창 밖은 다듬는다. */
|
|
42
|
+
eligibleFailures: number[];
|
|
43
|
+
state: 'closed' | 'open';
|
|
44
|
+
cooldownMs: number;
|
|
45
|
+
openedAt: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** 프로세스 안 상태 — 턴을 넘어 살아 있어야 하니 모듈 스코프에 둔다. */
|
|
49
|
+
const circuits = new Map<string, CircuitEntry>();
|
|
50
|
+
|
|
51
|
+
/** 실패 범주가 회로 실패(«전환 사유»)로 세는가 — 순수 판정. */
|
|
52
|
+
export function isCircuitFailureCategory(category: string): boolean {
|
|
53
|
+
if ((CIRCUIT_EXTRA_CATEGORIES as readonly string[]).includes(category)) return true;
|
|
54
|
+
return isProviderFallbackEligible(
|
|
55
|
+
new Error(`circuit:${category}`),
|
|
56
|
+
category as RetryCategory,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function entry(name: string): CircuitEntry {
|
|
61
|
+
let entry = circuits.get(name);
|
|
62
|
+
if (!entry) {
|
|
63
|
+
entry = { eligibleFailures: [], state: 'closed', cooldownMs: CIRCUIT_COOLDOWN_BASE_MS, openedAt: 0 };
|
|
64
|
+
circuits.set(name, entry);
|
|
65
|
+
}
|
|
66
|
+
return entry;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function logState(
|
|
70
|
+
event: 'circuit-open' | 'circuit-half-open' | 'circuit-closed',
|
|
71
|
+
provider: string,
|
|
72
|
+
failures: number,
|
|
73
|
+
cooldownMs: number,
|
|
74
|
+
): void {
|
|
75
|
+
debug.log('tui.survival', event, { provider, failures, cooldownMs });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** 회로 차단기에 실패를 기록한다. «전환 사유» 범주만 세며, half-open 시험
|
|
79
|
+
* 실패는 냉각을 2배(상한 30분)로 갈아 open 을 다시 연다. */
|
|
80
|
+
export function recordProviderFailure(name: string, category: string, now: number): void {
|
|
81
|
+
if (!isCircuitFailureCategory(category)) return;
|
|
82
|
+
const e = entry(name);
|
|
83
|
+
if (e.state === 'open' && now >= e.openedAt + e.cooldownMs) {
|
|
84
|
+
// half-open 시험 실패 — 다시 열리고 냉각은 2배(상한 30분).
|
|
85
|
+
e.cooldownMs = Math.min(e.cooldownMs * 2, CIRCUIT_COOLDOWN_MAX_MS);
|
|
86
|
+
e.openedAt = now;
|
|
87
|
+
e.eligibleFailures.push(now);
|
|
88
|
+
logState('circuit-open', name, e.eligibleFailures.length, e.cooldownMs);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
e.eligibleFailures = e.eligibleFailures.filter((t) => now - t <= CIRCUIT_FAILURE_WINDOW_MS);
|
|
92
|
+
e.eligibleFailures.push(now);
|
|
93
|
+
if (e.state === 'closed' && e.eligibleFailures.length >= CIRCUIT_FAILURE_THRESHOLD) {
|
|
94
|
+
e.state = 'open';
|
|
95
|
+
e.openedAt = now;
|
|
96
|
+
e.cooldownMs = CIRCUIT_COOLDOWN_BASE_MS;
|
|
97
|
+
logState('circuit-open', name, e.eligibleFailures.length, e.cooldownMs);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** 성공 — half-open 이면 closed 로 회복하고, closed 의 실패 이력 창을 정리한다. */
|
|
102
|
+
export function recordProviderSuccess(name: string, now: number): void {
|
|
103
|
+
const e = circuits.get(name);
|
|
104
|
+
if (!e) return;
|
|
105
|
+
if (e.state === 'open' && now >= e.openedAt + e.cooldownMs) {
|
|
106
|
+
e.state = 'closed';
|
|
107
|
+
e.cooldownMs = CIRCUIT_COOLDOWN_BASE_MS;
|
|
108
|
+
e.eligibleFailures = [];
|
|
109
|
+
logState('circuit-closed', name, 0, e.cooldownMs);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (e.eligibleFailures.length > 0) e.eligibleFailures = [];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** 현재 회로 상태 — 주입 시계로만 판정한다. */
|
|
116
|
+
export function circuitState(name: string, now: number): ProviderCircuitState {
|
|
117
|
+
const e = circuits.get(name);
|
|
118
|
+
if (!e || e.state === 'closed') return 'closed';
|
|
119
|
+
return now < e.openedAt + e.cooldownMs ? 'open' : 'half-open';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** 턴의 첫 공급자 후보 — 체인 순서 그대로 첫 `closed`, 없으면 첫 `half-open`,
|
|
123
|
+
* 모두 `open` 이면 `undefined`(호출부가 원래 1순위로 열며 `circuit-all-open` 을 남긴다). */
|
|
124
|
+
export function pickInitialProvider(
|
|
125
|
+
chainNames: readonly string[],
|
|
126
|
+
now: number,
|
|
127
|
+
): string | undefined {
|
|
128
|
+
let firstHalfOpen: string | undefined;
|
|
129
|
+
for (const name of chainNames) {
|
|
130
|
+
const state = circuitState(name, now);
|
|
131
|
+
if (state === 'closed') return name;
|
|
132
|
+
if (state === 'half-open' && firstHalfOpen === undefined) firstHalfOpen = name;
|
|
133
|
+
}
|
|
134
|
+
return firstHalfOpen;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** 테스트 전용 — 프로세스 안 회로 상태를 리셋한다. */
|
|
138
|
+
export function resetProviderCircuitForTest(): void {
|
|
139
|
+
circuits.clear();
|
|
140
|
+
}
|
|
@@ -368,6 +368,7 @@ function buildResult(
|
|
|
368
368
|
const aggCapped = capString(agg, meta.maxOutputBytes);
|
|
369
369
|
const r: ShellResult = {
|
|
370
370
|
...(meta.exitCode !== undefined ? { exitCode: meta.exitCode } : {}),
|
|
371
|
+
...(meta.spawnError !== undefined ? { failureReason: meta.spawnError } : {}),
|
|
371
372
|
stdout: stdout.toStream(meta.maxOutputBytes),
|
|
372
373
|
stderr: stderr.toStream(meta.maxOutputBytes),
|
|
373
374
|
aggregated: aggCapped,
|
|
@@ -213,6 +213,10 @@ export interface StreamOutput {
|
|
|
213
213
|
|
|
214
214
|
export interface ShellResult {
|
|
215
215
|
exitCode?: number;
|
|
216
|
+
/** Failure detail captured at the execution boundary (for example,
|
|
217
|
+
* the original spawn error). Kept separate from outcome so callers
|
|
218
|
+
* can explain why no process exit status exists. */
|
|
219
|
+
failureReason?: string;
|
|
216
220
|
stdout: StreamOutput;
|
|
217
221
|
stderr: StreamOutput;
|
|
218
222
|
/** Merged (interleaved) stream in spawn order. For File engine
|