elanous 0.2.41 → 0.2.42
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/{GiOLWmt4MqDZePubBjA4Q → X1ucLw10Cds_h614NoEnh}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5159.115f1c2ca471386c.js → 1063.2fb8a9dc55c731f2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +36 -0
- package/apps/pwa/out/_next/static/chunks/1147-5196d19c222051b3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9048.212083de42d25be3.js → 1262.e804feb8fd1acb8c.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1319.b9b815ae0f181e06.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1455-530ca16c7e71baff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4527.a69f2894d1bc9f4a.js → 1487.2f67b79444062da6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1574.878c18ecc97b1bd4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +32 -0
- package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1945.7b54990d578c119b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +286 -0
- package/apps/pwa/out/_next/static/chunks/2160.a097e7b138ae1c55.js +23 -0
- package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +34 -0
- package/apps/pwa/out/_next/static/chunks/2456.b6de0e1c05f28843.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +1 -0
- package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{530.d26346e18089640a.js → 2690.0521c738b7749931.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4702.4a4adc1f16d7c93b.js → 2974.595d1e29d040cb6a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2263.e09b6edea33bad2d.js → 3207.a756c95e9ec8c3c8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9541.eb8e2f8480c7feca.js → 3285.89ee2f298682f5e5.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{9507.7026657a2f47eb64.js → 3347.f846266b5e5f3ede.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +41 -0
- package/apps/pwa/out/_next/static/chunks/{1178.1aa9cad0e7695427.js → 3482.a9ae9d2ad6a5bd97.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3507.97e1977bc4d5fb0a.js +2 -0
- package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +24 -0
- package/apps/pwa/out/_next/static/chunks/3741.9cf76acaa2ee5298.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1661.0dd330f3d89f73f3.js → 3837.a210d7d0db8d8abd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2fdf2931.b431eee4fb468bc3.js → 3d0154af.5331fec737ffe8c3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4043.6b91203436c9c86b.js +309 -0
- package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +77 -0
- package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4276.336d76d858fcdf1b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4320.583cbab64db6be02.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4770.769c9cd9c7034eba.js +148 -0
- package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +74 -0
- package/apps/pwa/out/_next/static/chunks/50061469.0326382241ef3b2d.js +122 -0
- package/apps/pwa/out/_next/static/chunks/{1115.434ae2ecb0ad986d.js → 5112.4b9f300124fab7b3.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +27 -0
- package/apps/pwa/out/_next/static/chunks/53c73f84.373b6160adfa89a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5431-72a1dbde59400691.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5440-4236de26c5ea5856.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5885.0a3e52c8faccec98.js +287 -0
- package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6131.348b7d6bdcd267ce.js +226 -0
- package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +90 -0
- package/apps/pwa/out/_next/static/chunks/{2073.689dcb2680113d76.js → 6377.bc7df239edbff244.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1800.f7ff51dc4978a958.js → 6632.0eac1c554f8f2ef3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +104 -0
- package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +94 -0
- package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2527-5c636a43c7cc5dde.js → 7279-c199ea83f34338fa.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{385e4574.e9886ab32759eda3.js → 73d2eb0e.4966ad55293c801a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5471.1e611302ed3a7c53.js → 7411.9b4b8b747dc7b802.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +24 -0
- package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +1 -0
- package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2fe2c302.41b517f88d6fe502.js → 7a98bc80.fa935989e829f9c2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8138.6c10b2a356d52fca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5574.f35accf4f132b29d.js → 8262.ddc03e06b733f184.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +8 -0
- package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8505.fd803c6c33b54cc3.js +79 -0
- package/apps/pwa/out/_next/static/chunks/{8050-9b364bdef8f71927.js → 8546-6f03f8ea34dd61d9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5947-135e26537d80a6b9.js → 8673-bab689a55f7e13b9.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9211-330b6736a63d4cb3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5937.c2df9e3447e1f667.js → 9249.976f1e69a9d80754.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1971-7efb628c471dc5a0.js → 9353-12bfff0c130104cf.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{7191.fdc955f7d96064a4.js → 9415.69e4a21c60c7d2db.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1219.7e17964e0e7cd8e5.js → 9427.96aa912ddb5801e0.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9633.ce5bddc56784da72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5964-7e21164a8f2cf0ce.js → 9656-374232558fd528d0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6552.a3840aa7da35ad68.js → 9832.f4a98c878ecf2c0a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9a852a62-6192a6ea9346ced3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-0e3d7b9421b79dac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-0f291d3c8fd55a3a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-bf067887b3307423.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{a0a01613.6d1cca322238d7fe.js → b450776b.3db34d8d965f82d3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{c0c1a699.0ba79f97005965d4.js → e8543907.5b040a5f22a0b0e5.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +1 -0
- package/apps/pwa/out/_next/static/css/{b9d8151e48998417.css → 62c858ad53854f47.css} +1 -1
- 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 +23 -24
- 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 +22 -22
- 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 +23 -24
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +23 -24
- 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/docs/goal-context/04-mock-scenarios.md +13 -0
- package/graphs/catalog/catalog.yaml +1 -1
- package/graphs/heal/heal-loop.yaml +1 -0
- package/graphs/overlays/stop-heal-ladder.yaml +113 -0
- package/graphs/units/verbs/recipes.yaml +11 -11
- package/graphs/work/research-report.yaml +10 -2
- package/package.json +1 -1
- package/scripts/heal/run-role.ts +99 -5
- package/scripts/land-global-checks.ts +6 -1
- package/scripts/lib/decompose-ab.ts +1 -0
- package/scripts/lib/fixtures/tui-regress/help-insufficient-commands.txt +15 -0
- package/scripts/lib/fixtures/tui-regress/help-live.txt +42 -0
- package/scripts/lib/fixtures/tui-regress/help-missing-keys.txt +21 -0
- package/scripts/lib/fixtures/tui-regress/help-original.txt +51 -0
- package/scripts/lib/fixtures/tui-regress/help-shifted-input.txt +26 -0
- package/scripts/lib/tui-regress-checks.ts +33 -13
- package/scripts/release-loop/gate-baseline-receipt.ts +47 -9
- package/scripts/release-loop/gate-image-pin.ts +81 -0
- package/scripts/release-loop/gate-node-sim.ts +207 -0
- package/scripts/release-loop/gate-node.ts +285 -46
- package/scripts/release-loop/gate-pod-image-sticky-plan.ts +99 -0
- package/scripts/release-loop/gate-radius-live.ts +97 -13
- package/scripts/release-loop/gate-shard-dispatch.ts +43 -0
- package/scripts/release-loop/gate-train-receipts.ts +122 -0
- package/scripts/release-loop/resume-release.ts +83 -8
- package/scripts/ux-sim.ts +18 -1
- package/scripts/warm-pool-provider-config.ts +263 -0
- package/skills/omni-crawl/SKILL.md +5 -2
- package/skills/omni-crawl/scripts/main.ts +84 -23
- package/src/acp/core-turn-bridge.ts +13 -0
- package/src/agent/registry.ts +2 -0
- package/src/agent/task-notification.ts +25 -5
- package/src/agent/types.ts +6 -0
- package/src/agent-mission/mission-cli.ts +24 -0
- package/src/agent-mission/mission-out.ts +595 -0
- package/src/agent-mission/tool-install.ts +88 -2
- package/src/agent-substrate/context-strategy.ts +4 -4
- package/src/agent-substrate/self-review-cli.ts +178 -13
- package/src/auto-research/research-turn.ts +123 -50
- package/src/autopilot/pr-manager.ts +38 -7
- package/src/autopilot/pty-control-loop.ts +2 -0
- package/src/capture/tui-self-report.ts +22 -6
- package/src/chat/index.ts +1 -1
- package/src/cli/fixtures/review-loop-breaker/opwaiver-32646-1694ccc7a170.json +1 -0
- package/src/cli/fixtures/review-loop-breaker/opwaiver-32853-bd8f73595c83.json +1 -0
- package/src/cli/fixtures/review-loop-breaker/opwaiver-33097-1cc85900413c.json +1 -0
- package/src/cli/fixtures/review-loop-breaker/opwaiver-33106-972f31e4a3ca.json +1 -0
- package/src/cli/fixtures/review-loop-breaker/opwaiver-33113-3ab51f05968f.json +1 -0
- package/src/cli/fixtures/review-loop-breaker/pr-33097-1cc85900413c.json +1 -0
- package/src/cli/pr-land-heavy-remote.ts +32 -0
- package/src/cli/pr-land-overlap-evidence.ts +100 -1
- package/src/cli/pr-land-pod-shadow-job.ts +60 -0
- package/src/cli/release-checklist-read-cli.ts +20 -10
- package/src/cli/research-cli.ts +4 -5
- package/src/cli/tasks-cli.ts +7 -0
- package/src/compact/auto.ts +8 -1
- package/src/control-plane/ledger.ts +52 -2
- package/src/control-plane/server.ts +16 -2
- package/src/core-turn/run-core-turn.ts +311 -90
- package/src/core-turn/run-goal-loop.ts +18 -0
- package/src/core-turn/types.ts +2 -0
- package/src/dashboard/classic-sidetab-mission-job.ts +58 -0
- package/src/dashboard/classic-sidetab-mission.ts +185 -0
- package/src/dashboard/index.ts +149 -15
- package/src/dashboard/input/agent-wake.ts +23 -1
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +9 -0
- package/src/dashboard/mission-cli-consumer.ts +153 -0
- package/src/dashboard/seat-boot-preamble.ts +171 -1
- package/src/dashboard/side-basic-runtime.ts +54 -1
- package/src/dashboard/sidetab-runtime.ts +90 -1
- package/src/dashboard/skill-catalog-preamble.ts +101 -0
- package/src/dashboard/skill-detection-runtime.ts +55 -15
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +15 -0
- package/src/dashboard/turn-preamble.ts +53 -15
- package/src/dashboard/turn-prompt-runtime.ts +4 -2
- package/src/graph-runner/graph-cli.ts +23 -7
- package/src/graph-runner/graph-tick.ts +10 -2
- package/src/graph-runner/runner.ts +1 -1
- package/src/grok/agent-search.ts +14 -4
- package/src/grok/credential.ts +28 -11
- package/src/harness/harness-pod-dispatch.ts +81 -15
- package/src/harness/harness-stop.ts +155 -11
- package/src/index.ts +34 -5
- package/src/instance/spawn-elanous.ts +6 -4
- package/src/llm.ts +166 -8
- package/src/loops/orchestrator/coordinator-shadow.ts +226 -0
- package/src/loops/orchestrator/tick.ts +13 -0
- package/src/maturity/feature-maturity.ts +1 -1
- package/src/native-tool-catalog.ts +2 -2
- package/src/nexus/api/harness-traversal.ts +11 -0
- package/src/pr-tool/census.ts +3 -2
- package/src/pty-shell/tui-run-state.ts +188 -2
- package/src/release-loop/checklist-target-path-hint.ts +13 -0
- package/src/release-loop/checklist.ts +9 -1
- package/src/repl/index.ts +43 -2
- package/src/research/axis-fanout.ts +121 -16
- package/src/research/bloom-exemplars.ts +3 -1
- package/src/research/gap-followup.ts +13 -1
- package/src/research/plugin-discovery.ts +36 -14
- package/src/research-bridge/invoke.ts +22 -5
- package/src/research-bridge/types.ts +2 -0
- package/src/self-dev/decompose.ts +119 -5
- package/src/self-dev/launch-preflight-text.ts +5 -6
- package/src/self-dev/orchestrate.ts +12 -2
- package/src/self-dev/review-provider-fallback.ts +9 -2
- package/src/self-dev/run-supervisor.ts +42 -4
- package/src/self-dev/run-types.ts +4 -0
- package/src/self-implement/doctor-visit.ts +88 -0
- package/src/self-implement/goal-author.ts +326 -3
- package/src/self-implement/graph-overlay-yaml.ts +7 -0
- package/src/self-implement/headless-elanous-driver.ts +31 -2
- package/src/self-implement/heal-intake.ts +112 -4
- package/src/self-implement/heal-triage.ts +20 -0
- package/src/self-implement/host-regate.ts +27 -4
- package/src/self-implement/merge-train.ts +5 -0
- package/src/self-implement/orchestrator.ts +126 -11
- package/src/self-implement/regate-detail.ts +38 -1
- package/src/self-implement/rework-child-provider.ts +25 -0
- package/src/self-implement/run-chart.ts +119 -0
- package/src/self-implement/run-ledger.ts +112 -11
- package/src/self-implement/run-stop.ts +188 -4
- package/src/self-implement/stop-autoheal.ts +13 -0
- package/src/session/chat.ts +38 -4
- package/src/session-runtime/index.ts +98 -4
- package/src/session-runtime/tier-flip.ts +3 -3
- package/src/sidetab-core/model.ts +19 -5
- package/src/sidetab-core/visible-agent-mission.ts +186 -0
- package/src/skills/name-match.ts +20 -0
- package/src/skills/tools/agent.ts +30 -2
- package/src/skills/tools/omni-search.ts +67 -5
- package/src/task-agent/pod-distributor-entry.ts +3 -0
- package/src/task-agent/task-hand.ts +27 -0
- package/src/task-orchestrator/surfaces/pod-distributor.ts +48 -0
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +38 -1
- package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +33 -6
- package/src/task-orchestrator/surfaces/pod-source-bundle.ts +45 -9
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +163 -13
- package/src/task-orchestrator/surfaces/pod-source-spec.ts +3 -3
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +209 -39
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +80 -3
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +165 -45
- package/src/tokens.ts +35 -2
- package/src/tool-runtime/agent-runtime.ts +1 -0
- package/src/tool-runtime/elanous-skills-list-runtime.ts +5 -1
- package/src/tool-runtime/skill-exec-runtime.ts +33 -13
- package/src/tool-runtime/types.ts +1 -0
- package/src/tui/entry.ts +14 -4
- package/src/tui/sidetab/attach.ts +47 -0
- package/src/tui-client/local-chat-turn.ts +26 -13
- package/src/tui.ts +22 -0
- package/src/ux-sim/fake-kubectl.ts +37 -3
- package/src/ux-sim/fault-pool-cap.ts +11 -6
- package/src/ux-sim/mock-scenario-catalog.json +41 -0
- package/src/ux-sim/mock-scenario-catalog.ts +156 -0
- package/src/ux-sim/scenario.ts +116 -23
- package/src/version/packed-revision.json +1 -1
- package/src/voice/voice-tts-singleton.ts +18 -3
- package/src/web-search/grok.ts +5 -9
- package/apps/pwa/out/_next/static/chunks/1121.667cec0bcdbb3fdb.js +0 -36
- package/apps/pwa/out/_next/static/chunks/1197-54da59d250a6e476.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1245.1cfd13b26dbd71d6.js +0 -287
- package/apps/pwa/out/_next/static/chunks/1494-f93046ff5c5a124d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1609.2b312797599b8e45.js +0 -1
- package/apps/pwa/out/_next/static/chunks/167-0c121e4b47e0f9da.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1700.cdc2bf8cc685e221.js +0 -90
- package/apps/pwa/out/_next/static/chunks/1703-78e46acad29f3cfc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1765.679b29625c8e88d4.js +0 -77
- package/apps/pwa/out/_next/static/chunks/1999-8de7b7bb36801913.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2198-557d49184104d165.js +0 -1
- package/apps/pwa/out/_next/static/chunks/221-440ce67fa9f5c839.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2427-8ed8e98624cbd664.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2457-725c5827bc003795.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2491-2718b15a5ccb75a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2692-1027cb16fe4ccf49.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2743.5d3f76948be32b34.js +0 -41
- package/apps/pwa/out/_next/static/chunks/2773.0e80b9d325fb5635.js +0 -32
- package/apps/pwa/out/_next/static/chunks/2873-0f3cb56c8e3528ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3097.864e92bdaa2f4d15.js +0 -79
- package/apps/pwa/out/_next/static/chunks/3136-d6870ba63300a93e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3173-0289113d434e83b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3230-49298c3b73ef2268.js +0 -1
- package/apps/pwa/out/_next/static/chunks/325-dd9208a1a0ab7ce4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3283.528f430dd043fb4e.js +0 -74
- package/apps/pwa/out/_next/static/chunks/3295.cc8cb13b8f0dae1a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3688-86e3b88abf18cb3b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3804-7220467a5473a8df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3808.3e1e247ce7bdf889.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3927.b5473ad109da44c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3934-98ea94832e194796.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4133.2056bb4d78f621af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4156.ba4de4a3664f04b4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4297-239ca82f293faab0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4320-dcc5a7734126f4c9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4434.94b4c552a2d91e69.js +0 -148
- package/apps/pwa/out/_next/static/chunks/4579.03e4092f73950965.js +0 -226
- package/apps/pwa/out/_next/static/chunks/4667.97e31aa38c95c475.js +0 -309
- package/apps/pwa/out/_next/static/chunks/4815.481501c57b3568d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/487-d16e698ef14662d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4888-7a38bf522c9cc6fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5034-30e429d6bb086881.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5040-35c494e60dadd97d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/50c6ab1e.81a96e419350909d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5154.4b6a836179356f30.js +0 -94
- package/apps/pwa/out/_next/static/chunks/5228-a8200df486278f2d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5379.97af106d09566f69.js +0 -8
- package/apps/pwa/out/_next/static/chunks/53aeb4ee-51c92f8d683f5220.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5479-b6372e762719f92f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5534-699c5cbcbc96c5d7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5701.9c4e8f250312eeee.js +0 -24
- package/apps/pwa/out/_next/static/chunks/5744.b9415e18ad623100.js +0 -23
- package/apps/pwa/out/_next/static/chunks/5892.2526d962339662d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5941.8210cc93c9202c0a.js +0 -286
- package/apps/pwa/out/_next/static/chunks/5975.4004f820ae3cecd5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6142-7ccd48795d7abd55.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6160.bf9177b8c1bfb243.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6398.71ba0690c8027555.js +0 -27
- package/apps/pwa/out/_next/static/chunks/6492.2bd5c10edc1a064e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6736.1e36d3ac5fa5e41d.js +0 -24
- package/apps/pwa/out/_next/static/chunks/6874.d5cf7eb8edb2cabe.js +0 -2
- package/apps/pwa/out/_next/static/chunks/6900.3ccbe069bdd4556a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/71327eb4.add50b365f94bf3a.js +0 -122
- package/apps/pwa/out/_next/static/chunks/7136.deca3e3a2ddaa374.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7139-ee9f8ed2677a40b3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7423-e0aa5d9e2962120e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7453.afc1ea7e05d56a8c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7503-5e6a3d7fe67e4a0c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7761-476fd7bf768abd34.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7975.eafb12097a0a9e62.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8152.64e253c35cccfaae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8190.620f0231b3924bcb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/83184dcd-0ee6247ff41eb3f2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8448.45b6b1f1a99eeb35.js +0 -104
- package/apps/pwa/out/_next/static/chunks/8464-e24f10451b658aac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8477.e4c944bb3aa5d2f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8710.ca385257d5ca422e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8830.627ccf294ec2465c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8880.64c445592f04acaf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8981.c706964c8ba27aff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9053.bd0fffaff8d3f836.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9161-c66e723d7ec9d682.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9185.1ecdf9b65c0bb684.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9356.fccd5f58086b4ff5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9446.dc0406109371d329.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9506.dcf25d467a42627e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9577.ed7582186efa5482.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9579.4a8169600fff2058.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9642-ff2e039eb62e3b92.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9659-8f2323348113ad80.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9724.4c5623af2db43153.js +0 -34
- package/apps/pwa/out/_next/static/chunks/9834.63ab2bbc3153172e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9869.81a1e24ca682d5a0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/addc2b32.8c4ff8f0aefe987d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-8d9d76ea322d855c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed2c4e59f9f1fe21.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-2dc99e03c5d76ca0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-b5a3a788330e920f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-14949db884bfa672.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-ea76c85b36388a97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-01716d20af62d325.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-62baf6881a64b1e9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-f89ba590c2af8afa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-22f8b0f78d9637e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-817f9d7e6820be80.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-ffb9bc0d2650249a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-f6d0e64873c0f629.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-8bfa0d4ba23a209d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-f5060462249e32c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-8d9d76ea322d855c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-b2049f8b1ef79117.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-1446c5fa93907f11.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-b48a7a07c5204156.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-e974b8c4ca47614c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-8a919b869bd28594.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-d31b8de6bfcd72ed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-64765f817909db29.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-d128c8569a36ee9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-b2679d357e9b9270.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-6fabec98a9e7b269.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-048f30149dcf1349.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-9113181d6b5a2725.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-40f9e19149024298.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-1e7a755a13227611.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-3c8f8b67a203cf07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-18032f5437215062.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-da3b739192fd0ee3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d332545571bd6fd1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-5237aa5b3f3b8ec5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a142dfb0331a05f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-d16e56c3989c147e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6b6593600869e2cd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-8d9d76ea322d855c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-29e8b8a8396b55cb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-b3414d856a1a7e2f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-c3affa52b7ce961b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f21dddf9f95b6fab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-f5a30a24745bf088.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-8c8569a09b4d4e34.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-2ce32722c0243483.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-4767b0d9c0a98c6c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-116ee1339c387a75.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-35e8c50ca4ef7ffc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-52e17113356bb891.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7458ae05ed2ac1a0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/b2271e54.c1de3347976e90b0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-ad6c9dd524ad6ef8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-2ddd1f2b44d6aa59.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-e3d82bdc358d20c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-71d5aa3896e1655f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-03ffc54e00438546.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-56bb89af5a611d0b.js +0 -1
- package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +0 -1
- /package/apps/pwa/out/_next/static/{GiOLWmt4MqDZePubBjA4Q → X1ucLw10Cds_h614NoEnh}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { chmodSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, isAbsolute, join } from 'node:path';
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { userConfigPath } from '../src/user-config.js';
|
|
7
|
+
|
|
8
|
+
const TOKEN = /^[a-f0-9]{64}$/;
|
|
9
|
+
const SHA = /^[a-f0-9]{40}$/;
|
|
10
|
+
const DIGEST = /^sha256:[a-f0-9]{64}$/;
|
|
11
|
+
const LOCK_HASH = /^[a-f0-9]{64}$/;
|
|
12
|
+
const TIERS = new Set(['lite', 'standard']);
|
|
13
|
+
|
|
14
|
+
type JsonObject = Record<string, unknown>;
|
|
15
|
+
|
|
16
|
+
export interface WarmPoolProviderConfig {
|
|
17
|
+
candidates: [];
|
|
18
|
+
poolTemplates: Array<{
|
|
19
|
+
host: string;
|
|
20
|
+
tier: 'lite' | 'standard';
|
|
21
|
+
spec: {
|
|
22
|
+
name: string;
|
|
23
|
+
namespace: string;
|
|
24
|
+
kubectlContext: string;
|
|
25
|
+
workerId: string;
|
|
26
|
+
image: string;
|
|
27
|
+
sourceUrl?: string;
|
|
28
|
+
sourceMirrorHostPath?: string;
|
|
29
|
+
nodeName: string;
|
|
30
|
+
cutSha: string;
|
|
31
|
+
key: { context: string; imageDigest: string; lockHash: string; architecture: string };
|
|
32
|
+
memoryLimit: '2Gi' | '16Gi';
|
|
33
|
+
hostProbeUrl: string;
|
|
34
|
+
prodProbeUrl: string;
|
|
35
|
+
};
|
|
36
|
+
}>;
|
|
37
|
+
profileConfig: { pod: { warmPoolProfile: string } };
|
|
38
|
+
controlUrl: string;
|
|
39
|
+
memberToken: string;
|
|
40
|
+
machineTokens: Record<string, string>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface AssembleWarmPoolProviderConfigInput {
|
|
44
|
+
config: unknown;
|
|
45
|
+
controlUrl: string;
|
|
46
|
+
memberToken: string;
|
|
47
|
+
machineTokens: Record<string, string>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function object(value: unknown, label: string): JsonObject {
|
|
51
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${label} is required`);
|
|
52
|
+
return value as JsonObject;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function text(value: unknown, label: string): string {
|
|
56
|
+
if (typeof value !== 'string' || !value.trim()) throw new Error(`${label} is required`);
|
|
57
|
+
return value.trim();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function token(value: unknown, label: string): string {
|
|
61
|
+
const parsed = text(value, label);
|
|
62
|
+
if (!TOKEN.test(parsed)) throw new Error(`${label} must be a 64-character hexadecimal token`);
|
|
63
|
+
return parsed;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function httpUrl(value: unknown, label: string, hostname?: string): string {
|
|
67
|
+
const parsed = text(value, label);
|
|
68
|
+
try {
|
|
69
|
+
const url = new URL(parsed);
|
|
70
|
+
if (url.protocol !== 'http:' || !url.port || url.username || url.password || url.search || url.hash
|
|
71
|
+
|| (hostname !== undefined && url.hostname !== hostname)) throw new Error();
|
|
72
|
+
return url.href;
|
|
73
|
+
} catch { throw new Error(`${label} must be an http URL${hostname ? ` for ${hostname}` : ''}`); }
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function controlUrl(value: unknown): string {
|
|
77
|
+
const parsed = text(value, 'controlUrl');
|
|
78
|
+
try {
|
|
79
|
+
const url = new URL(parsed);
|
|
80
|
+
const authority = /^(?:http|https):\/\/([^/?#]*)/i.exec(parsed)?.[1] ?? '';
|
|
81
|
+
const explicitPort = !authority.includes('\\') && /^(?:\[[^\]]+\]|[^:]+):\d+$/.test(authority);
|
|
82
|
+
if (!['http:', 'https:'].includes(url.protocol) || !explicitPort || authority.includes('@') || url.username || url.password
|
|
83
|
+
|| parsed.includes('?') || parsed.includes('#') || url.search || url.hash)
|
|
84
|
+
throw new Error();
|
|
85
|
+
return url.href;
|
|
86
|
+
} catch { throw new Error('controlUrl must be an http or https URL with an explicit port'); }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function privateSource(pool: JsonObject): Pick<WarmPoolProviderConfig['poolTemplates'][number]['spec'], 'sourceUrl' | 'sourceMirrorHostPath'> {
|
|
90
|
+
const mirror = pool.sourceMirrorHostPath;
|
|
91
|
+
const source = pool.sourceUrl;
|
|
92
|
+
if (typeof mirror === 'string' && mirror.trim()) {
|
|
93
|
+
if (!isAbsolute(mirror) || mirror.trim() !== mirror) throw new Error('pod.warmPool.sourceMirrorHostPath must be an absolute normalized path');
|
|
94
|
+
return { sourceMirrorHostPath: mirror };
|
|
95
|
+
}
|
|
96
|
+
if (typeof source === 'string' && source.trim()) {
|
|
97
|
+
try {
|
|
98
|
+
const url = new URL(source);
|
|
99
|
+
if (url.protocol !== 'https:' || !url.hostname || url.username || url.password || url.search || url.hash) throw new Error();
|
|
100
|
+
return { sourceUrl: url.href };
|
|
101
|
+
} catch { throw new Error('pod.warmPool.sourceUrl must be a public https URL'); }
|
|
102
|
+
}
|
|
103
|
+
throw new Error('pod.warmPool.sourceMirrorHostPath or pod.warmPool.sourceUrl is required');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Convert canonical user config plus operator-supplied private credentials into the two provider loaders' shared format. */
|
|
107
|
+
export function assembleWarmPoolProviderConfig(input: AssembleWarmPoolProviderConfigInput): WarmPoolProviderConfig {
|
|
108
|
+
const root = object(input.config, 'config');
|
|
109
|
+
const pod = object(root.pod, 'pod');
|
|
110
|
+
const harness = object(root.harness, 'harness');
|
|
111
|
+
const profile = text(pod.warmPoolProfile, 'pod.warmPoolProfile');
|
|
112
|
+
const pool = object(pod.warmPool, 'pod.warmPool');
|
|
113
|
+
const cutSha = text(harness.imageCommit, 'harness.imageCommit');
|
|
114
|
+
if (!SHA.test(cutSha)) throw new Error('harness.imageCommit must be a 40-character commit SHA');
|
|
115
|
+
const kubectlContext = text(harness.podPool, 'harness.podPool');
|
|
116
|
+
const namespace = text(pool.namespace, 'pod.warmPool.namespace');
|
|
117
|
+
const imageRepository = text(pool.imageRepository, 'pod.warmPool.imageRepository').replace(/\/$/, '');
|
|
118
|
+
const imageDigest = text(pool.imageDigest, 'pod.warmPool.imageDigest');
|
|
119
|
+
if (!DIGEST.test(imageDigest)) throw new Error('pod.warmPool.imageDigest must be a sha256 digest');
|
|
120
|
+
const lockHash = text(pool.lockHash, 'pod.warmPool.lockHash');
|
|
121
|
+
if (!LOCK_HASH.test(lockHash)) throw new Error('pod.warmPool.lockHash must be a 64-character SHA-256');
|
|
122
|
+
const architecture = text(pool.architecture, 'pod.warmPool.architecture');
|
|
123
|
+
const hostProbeUrl = httpUrl(pool.hostProbeUrl, 'pod.warmPool.hostProbeUrl', 'host.orb.internal');
|
|
124
|
+
const prodProbeUrl = httpUrl(pool.prodProbeUrl, 'pod.warmPool.prodProbeUrl', 'core.elanous-prod');
|
|
125
|
+
const source = privateSource(pool);
|
|
126
|
+
const templates = pool.templates;
|
|
127
|
+
if (!Array.isArray(templates) || templates.length === 0) throw new Error('pod.warmPool.templates is required');
|
|
128
|
+
const seen = new Set<string>();
|
|
129
|
+
const machineTokens: Record<string, string> = {};
|
|
130
|
+
const poolTemplates = templates.map((raw, index) => {
|
|
131
|
+
const row = object(raw, `pod.warmPool.templates[${index}]`);
|
|
132
|
+
const host = text(row.host, `pod.warmPool.templates[${index}].host`);
|
|
133
|
+
const tier = text(row.tier, `pod.warmPool.templates[${index}].tier`);
|
|
134
|
+
if (!TIERS.has(tier)) throw new Error(`pod.warmPool.templates[${index}].tier must be lite or standard`);
|
|
135
|
+
const nodeName = text(row.nodeName, `pod.warmPool.templates[${index}].nodeName`);
|
|
136
|
+
const identity = `${host}/${tier}`;
|
|
137
|
+
if (seen.has(identity)) throw new Error(`duplicate pod.warmPool template ${identity}`);
|
|
138
|
+
seen.add(identity);
|
|
139
|
+
machineTokens[host] = token(input.machineTokens[host], `machine token for ${host}`);
|
|
140
|
+
return {
|
|
141
|
+
host,
|
|
142
|
+
tier: tier as 'lite' | 'standard',
|
|
143
|
+
spec: {
|
|
144
|
+
name: `warm-${host}-${tier}-template`, namespace, kubectlContext,
|
|
145
|
+
workerId: `warm-${host}-${cutSha.slice(0, 12)}`, image: `${imageRepository}@${imageDigest}`,
|
|
146
|
+
...source, nodeName, cutSha,
|
|
147
|
+
key: { context: kubectlContext, imageDigest, lockHash, architecture },
|
|
148
|
+
memoryLimit: tier === 'lite' ? '2Gi' as const : '16Gi' as const,
|
|
149
|
+
hostProbeUrl, prodProbeUrl,
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
return { candidates: [], poolTemplates, profileConfig: { pod: { warmPoolProfile: profile } },
|
|
154
|
+
controlUrl: controlUrl(input.controlUrl), memberToken: token(input.memberToken, 'member token'), machineTokens };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Atomically replace the private provider config and repair permissions on an existing file. */
|
|
158
|
+
export function writeWarmPoolProviderConfig(path: string, config: WarmPoolProviderConfig): void {
|
|
159
|
+
if (!isAbsolute(path)) throw new Error('output path must be absolute');
|
|
160
|
+
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
161
|
+
const temporary = `${path}.${randomUUID()}.tmp`;
|
|
162
|
+
try {
|
|
163
|
+
writeFileSync(temporary, `${JSON.stringify(config, null, 2)}\n`, { encoding: 'utf8', flag: 'wx', mode: 0o600 });
|
|
164
|
+
renameSync(temporary, path);
|
|
165
|
+
chmodSync(path, 0o600);
|
|
166
|
+
} catch (error) {
|
|
167
|
+
try { unlinkSync(temporary); } catch { /* no temporary output */ }
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function redact(config: WarmPoolProviderConfig): unknown {
|
|
173
|
+
return { ...config, memberToken: '[redacted]', machineTokens: Object.fromEntries(Object.keys(config.machineTokens).map(host => [host, '[redacted]'])) };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function shellQuote(value: string): string { return `'${value.replaceAll("'", "'\\''")}'`; }
|
|
177
|
+
|
|
178
|
+
interface CliOptions {
|
|
179
|
+
configPath: string;
|
|
180
|
+
controlUrl: string;
|
|
181
|
+
memberTokenFile: string;
|
|
182
|
+
machineTokenFiles: Record<string, string>;
|
|
183
|
+
output: string;
|
|
184
|
+
dryRun: boolean;
|
|
185
|
+
serve: boolean;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function parseArgs(argv: readonly string[]): CliOptions {
|
|
189
|
+
let configPath = userConfigPath(), controlUrl = '', memberTokenFile = '', output = '';
|
|
190
|
+
let dryRun = false, serve = false;
|
|
191
|
+
const machineTokenFiles: Record<string, string> = {};
|
|
192
|
+
for (let index = 0; index < argv.length; index++) {
|
|
193
|
+
const arg = argv[index];
|
|
194
|
+
const next = () => {
|
|
195
|
+
const value = argv[++index];
|
|
196
|
+
if (!value) throw new Error(`missing value for ${arg}`);
|
|
197
|
+
return value;
|
|
198
|
+
};
|
|
199
|
+
if (arg === '--config') configPath = next();
|
|
200
|
+
else if (arg === '--control-url') controlUrl = next();
|
|
201
|
+
else if (arg === '--member-token-file') memberTokenFile = next();
|
|
202
|
+
else if (arg === '--machine-token') {
|
|
203
|
+
const [host, file, extra] = next().split('=');
|
|
204
|
+
if (!host || !file || extra !== undefined) throw new Error('--machine-token must be HOST=FILE');
|
|
205
|
+
machineTokenFiles[host] = file;
|
|
206
|
+
} else if (arg === '--output') output = next();
|
|
207
|
+
else if (arg === '--dry-run') dryRun = true;
|
|
208
|
+
else if (arg === '--serve') serve = true;
|
|
209
|
+
else throw new Error(`unknown argument: ${arg}`);
|
|
210
|
+
}
|
|
211
|
+
if (!isAbsolute(configPath) || !controlUrl || !isAbsolute(memberTokenFile))
|
|
212
|
+
throw new Error('usage: --config ABSOLUTE --control-url URL --member-token-file ABSOLUTE --machine-token HOST=ABSOLUTE [--output ABSOLUTE] [--dry-run|--serve]');
|
|
213
|
+
if (Object.values(machineTokenFiles).some(file => !isAbsolute(file))) throw new Error('machine token files must be absolute');
|
|
214
|
+
if (dryRun && serve) throw new Error('--dry-run and --serve cannot be combined');
|
|
215
|
+
return { configPath, controlUrl, memberTokenFile, machineTokenFiles,
|
|
216
|
+
output: output || join(dirname(configPath), 'warm-pod-provider.json'), dryRun, serve };
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function readPrivateToken(path: string, label: string): string {
|
|
220
|
+
if (!isAbsolute(path)) throw new Error(`${label} path must be absolute`);
|
|
221
|
+
return token(readFileSync(path, 'utf8').trim(), label);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export async function runWarmPoolProviderConfig(argv: readonly string[]): Promise<void> {
|
|
225
|
+
const options = parseArgs(argv);
|
|
226
|
+
const config = JSON.parse(readFileSync(options.configPath, 'utf8')) as unknown;
|
|
227
|
+
const machineTokens = Object.fromEntries(Object.entries(options.machineTokenFiles)
|
|
228
|
+
.map(([host, path]) => [host, readPrivateToken(path, `machine token for ${host}`)]));
|
|
229
|
+
const assembled = assembleWarmPoolProviderConfig({ config, controlUrl: options.controlUrl,
|
|
230
|
+
memberToken: readPrivateToken(options.memberTokenFile, 'member token'), machineTokens });
|
|
231
|
+
if (!options.dryRun) writeWarmPoolProviderConfig(options.output, assembled);
|
|
232
|
+
process.stdout.write(`${JSON.stringify({ output: options.output, config: redact(assembled),
|
|
233
|
+
...(options.serve ? { serve: { command: `ELANOUS_WARM_POD_PROVIDER_CONFIG=${shellQuote(options.output)} bun src/task-orchestrator/surfaces/pod-warm-worker-provider.ts --serve` } } : {}) })}\n`);
|
|
234
|
+
if (!options.serve) return;
|
|
235
|
+
const provider = fileURLToPath(new URL('../src/task-orchestrator/surfaces/pod-warm-worker-provider.ts', import.meta.url));
|
|
236
|
+
const child = spawn(process.execPath, [provider, '--serve'], { stdio: 'inherit',
|
|
237
|
+
env: { ...process.env, ELANOUS_WARM_POD_PROVIDER_CONFIG: options.output } });
|
|
238
|
+
const forwardSignal = (signal: NodeJS.Signals) => { if (child.exitCode === null && child.signalCode === null) child.kill(signal); };
|
|
239
|
+
const forwardInterrupt = () => forwardSignal('SIGINT');
|
|
240
|
+
const forwardTerminate = () => forwardSignal('SIGTERM');
|
|
241
|
+
process.on('SIGINT', forwardInterrupt);
|
|
242
|
+
process.on('SIGTERM', forwardTerminate);
|
|
243
|
+
try {
|
|
244
|
+
await new Promise<void>((resolve, reject) => {
|
|
245
|
+
child.once('error', reject);
|
|
246
|
+
child.once('close', (code, signal) => {
|
|
247
|
+
process.exitCode = code ?? (signal === 'SIGINT' ? 130 : signal === 'SIGTERM' ? 143 : 2);
|
|
248
|
+
resolve();
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
} finally {
|
|
252
|
+
process.off('SIGINT', forwardInterrupt);
|
|
253
|
+
process.off('SIGTERM', forwardTerminate);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (import.meta.main) {
|
|
258
|
+
try { await runWarmPoolProviderConfig(process.argv.slice(2)); }
|
|
259
|
+
catch (error) {
|
|
260
|
+
process.stderr.write(`warm-pool-provider-config: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
261
|
+
process.exitCode = 2;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
@@ -81,13 +81,16 @@ requires: []
|
|
|
81
81
|
자체 합성 파이프라인 (Tavily Research 엔드포인트 미사용 — 콜당 15~250cr 폭탄 회피):
|
|
82
82
|
|
|
83
83
|
```
|
|
84
|
-
1) 다각도
|
|
85
|
-
|
|
84
|
+
1) 다각도 검색 ×3 (Tavily 사용 가능 시 Tavily, 키 없음/비활성 시 Firecrawl) 병렬
|
|
85
|
+
런타임 0건/실패면 다음 유료 엔진, 두 검색축이 모두 비었을 때만 DDG 무료 최후 폴백
|
|
86
|
+
2) URL dedup → 상위 5개 Firecrawl 풀스크랩 (캐시 2h)
|
|
86
87
|
3) grok-community 1콜 (X+레딧 여론 각도) ~$0.05
|
|
87
88
|
4) 기술 주제면 fc-dev 1콜 자동 가세 (looksTechnical 게이트) ~2cr
|
|
88
89
|
→ 통합 마크다운 (풀본문이 스니펫보다 dedup 우선 생존)
|
|
89
90
|
```
|
|
90
91
|
|
|
92
|
+
각 각도 검색과 URL 스크랩은 엔진·단계별 경과 시간을 로그에 남긴다. Tavily 키가 없는 정상 경로는 Firecrawl 검색으로 세 각도를 채우며, DDG는 Tavily와 Firecrawl이 모두 없거나 0건일 때만 최후 폴백으로 호출한다.
|
|
93
|
+
|
|
91
94
|
## 실행
|
|
92
95
|
|
|
93
96
|
이 스킬 폴더에서 실행합니다.
|
|
@@ -153,7 +153,7 @@ async function main(query: string) {
|
|
|
153
153
|
|
|
154
154
|
// ── Deep research 파이프라인 (자체 합성 — Tavily Research 엔드포인트 미사용·비용 예측성) ──
|
|
155
155
|
//
|
|
156
|
-
// 1) 다각도
|
|
156
|
+
// 1) 다각도 웹 검색 ×3 (Tavily 사용 가능 시 Tavily, 아니면 Firecrawl) 병렬
|
|
157
157
|
// 2) URL dedup → 상위 K=5 를 firecrawl 풀스크랩 (maxAge 2h 캐시)
|
|
158
158
|
// 3) grok-community 1콜 (X+레딧 여론 각도)
|
|
159
159
|
// 카버당 비용: tavily ~6cr + firecrawl ~5cr + grok ~$0.03 — 예측 가능.
|
|
@@ -173,15 +173,11 @@ async function runDeep(query: string): Promise<CrawlResult[]> {
|
|
|
173
173
|
const results: CrawlResult[] = [];
|
|
174
174
|
|
|
175
175
|
// 1) 다각도 검색 + grok-community 동시 발사
|
|
176
|
-
//
|
|
177
|
-
//
|
|
178
|
-
|
|
176
|
+
// 키 부재·비활성뿐 아니라 Tavily/Firecrawl 런타임 공백도 다음 엔진으로 넘긴다.
|
|
177
|
+
// Tavily 부재 시 Firecrawl이 우선이며 DDG는 두 유료 검색축이 모두 비었을 때만 최후 폴백.
|
|
178
|
+
const angleEngines = deepAngleSearchOrder(tavilyEnabled() && tavilyAvailable(), firecrawlAvailable());
|
|
179
179
|
const searchTasks: Array<Promise<CrawlResult | null>> = [
|
|
180
|
-
...
|
|
181
|
-
searchTavily(a.q, { depth: 'advanced', maxResults: 5, chunksPerSource: 3, timeRange: flags['time-range'] })
|
|
182
|
-
.then(r => ({ ...r, engine: `tavily:${a.label}` }))
|
|
183
|
-
.catch(e => { console.log(` [deep] tavily(${a.label}) 실패: ${e.message?.slice(0, 80)}`); return null; }),
|
|
184
|
-
) : []),
|
|
180
|
+
...angles.map(a => searchDeepAngle(a, angleEngines)),
|
|
185
181
|
searchGrok({ query, mode: 'community' })
|
|
186
182
|
.catch(e => { console.log(` [deep] grok-community 실패: ${e.message?.slice(0, 80)}`); return null; }),
|
|
187
183
|
// 기술 주제면 개발자 인덱스 1콜 추가(실측 ~2cr) — 패시지가 곧 인용이라 풀스크랩 콜을 아낀다.
|
|
@@ -193,20 +189,11 @@ async function runDeep(query: string): Promise<CrawlResult[]> {
|
|
|
193
189
|
const settled = await Promise.all(searchTasks);
|
|
194
190
|
for (const r of settled) if (r) results.push(r as CrawlResult);
|
|
195
191
|
|
|
196
|
-
// 1-b) tavily 축이 비면(기본 OFF · 키 없음 · 장애) ddg 무료가 각도 검색을 담당한다.
|
|
197
|
-
const gotTavily = results.some(r => r.engine.startsWith('tavily') && r.totalItems > 0);
|
|
198
|
-
if (!gotTavily) {
|
|
199
|
-
console.log(' [deep] ddg 무료 티어로 각도 검색');
|
|
200
|
-
const ddgResults = await Promise.all(angles.map(a =>
|
|
201
|
-
searchDdg(a.q, { maxResults: 5 }).then(r => ({ ...r, engine: `ddg:${a.label}` })).catch(() => null)));
|
|
202
|
-
for (const r of ddgResults) if (r && r.totalItems > 0) results.push(r as CrawlResult);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
192
|
// 2) 검색 히트에서 상위 URL 추출 → firecrawl 풀스크랩 (병렬·캐시 2h)
|
|
206
193
|
const seen = new Set<string>();
|
|
207
194
|
const topUrls: string[] = [];
|
|
208
195
|
for (const r of results) {
|
|
209
|
-
if (!r.engine.startsWith('tavily') && !r.engine.startsWith('ddg')) continue;
|
|
196
|
+
if (!r.engine.startsWith('tavily') && !r.engine.startsWith('firecrawl') && !r.engine.startsWith('ddg')) continue;
|
|
210
197
|
for (const it of r.items) {
|
|
211
198
|
if (!it.url || seen.has(it.url)) continue;
|
|
212
199
|
seen.add(it.url);
|
|
@@ -217,9 +204,21 @@ async function runDeep(query: string): Promise<CrawlResult[]> {
|
|
|
217
204
|
}
|
|
218
205
|
if (topUrls.length) {
|
|
219
206
|
console.log(` [deep] 상위 ${topUrls.length}개 URL 풀스크랩 (firecrawl·캐시 2h)`);
|
|
220
|
-
const scraped = await Promise.all(topUrls.map(u =>
|
|
221
|
-
|
|
222
|
-
|
|
207
|
+
const scraped = await Promise.all(topUrls.map(async u => {
|
|
208
|
+
const startedAt = Date.now();
|
|
209
|
+
try {
|
|
210
|
+
const result = await scrapeFirecrawl(u, { maxAge: 2 * 3600_000 });
|
|
211
|
+
if (!result) {
|
|
212
|
+
console.log(` [deep:firecrawl:scrape] ${u} · 실패 · ${Date.now() - startedAt}ms · 본문 없음`);
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
console.log(` [deep:firecrawl:scrape] ${u} · ${Date.now() - startedAt}ms · ${result.content.length}자`);
|
|
216
|
+
return result;
|
|
217
|
+
} catch (e: any) {
|
|
218
|
+
console.log(` [deep:firecrawl:scrape] ${u} · 실패 · ${Date.now() - startedAt}ms · ${e.message?.slice(0, 80)}`);
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
}));
|
|
223
222
|
const items: CrawlItem[] = [];
|
|
224
223
|
for (let i = 0; i < scraped.length; i++) {
|
|
225
224
|
const s = scraped[i];
|
|
@@ -248,12 +247,54 @@ async function runDeep(query: string): Promise<CrawlResult[]> {
|
|
|
248
247
|
if (s) items.push({ engine: 'fc-deep', query, url: missed[i], text: s.content.slice(0, 6000), metadata: { via: s.method, title: s.title } });
|
|
249
248
|
}
|
|
250
249
|
}
|
|
251
|
-
if (items.length)
|
|
250
|
+
if (items.length) {
|
|
251
|
+
console.log(` [deep:firecrawl:fullscrape] ${items.length}/${topUrls.length}건 본문 확보`);
|
|
252
|
+
results.push({ engine: 'deep-fullscrape', query, items, totalItems: items.length, costNote: `firecrawl ~${scraped.filter(Boolean).length}cr + 무료` });
|
|
253
|
+
} else {
|
|
254
|
+
console.log(` [deep:firecrawl:fullscrape] 0/${topUrls.length}건 본문 확보`);
|
|
255
|
+
}
|
|
252
256
|
}
|
|
253
257
|
|
|
254
258
|
return results;
|
|
255
259
|
}
|
|
256
260
|
|
|
261
|
+
type DeepAngleEngine = 'tavily' | 'firecrawl' | 'ddg';
|
|
262
|
+
|
|
263
|
+
function deepAngleSearchOrder(tavilyReady: boolean, firecrawlReady: boolean): DeepAngleEngine[] {
|
|
264
|
+
return [
|
|
265
|
+
...(tavilyReady ? ['tavily' as const] : []),
|
|
266
|
+
...(firecrawlReady ? ['firecrawl' as const] : []),
|
|
267
|
+
'ddg',
|
|
268
|
+
];
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function firecrawlTbsFromTimeRange(timeRange?: string): string | undefined {
|
|
272
|
+
if (!timeRange) return undefined;
|
|
273
|
+
return ({ day: 'qdr:d', week: 'qdr:w', month: 'qdr:m', year: 'qdr:y' } as Record<string, string>)[timeRange];
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
async function searchDeepAngle(
|
|
277
|
+
angle: { q: string; label: string },
|
|
278
|
+
engines: DeepAngleEngine[],
|
|
279
|
+
): Promise<CrawlResult | null> {
|
|
280
|
+
for (const engine of engines) {
|
|
281
|
+
const startedAt = Date.now();
|
|
282
|
+
try {
|
|
283
|
+
const result = engine === 'tavily'
|
|
284
|
+
? await searchTavily(angle.q, { depth: 'advanced', maxResults: 5, chunksPerSource: 3, timeRange: flags['time-range'] })
|
|
285
|
+
: engine === 'firecrawl'
|
|
286
|
+
? await searchFirecrawl(angle.q, { limit: 5, tbs: firecrawlTbsFromTimeRange(flags['time-range']) })
|
|
287
|
+
: await searchDdg(angle.q, { maxResults: 5 });
|
|
288
|
+
const elapsedMs = Date.now() - startedAt;
|
|
289
|
+
console.log(` [deep:${engine}:${angle.label}] ${result.totalItems}건 · ${elapsedMs}ms`);
|
|
290
|
+
if (result.totalItems > 0) return { ...result, engine: `${engine}:${angle.label}` };
|
|
291
|
+
} catch (e: any) {
|
|
292
|
+
console.log(` [deep:${engine}:${angle.label}] 실패 · ${Date.now() - startedAt}ms · ${e.message?.slice(0, 80)}`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
|
|
257
298
|
// ── 폴백 체인: tavily ↔ firecrawl → (최후) ddg 무료 (웹 검색 축 공백 방지) ──
|
|
258
299
|
//
|
|
259
300
|
// 원칙: 유료(tavily/firecrawl)가 1순위·기본. 유료가 공백/미가용일 때만 무료(ddg)로 강등.
|
|
@@ -494,6 +535,26 @@ function runSelfTest() {
|
|
|
494
535
|
else { console.log(` FAIL: looksTechnical("${q}") expect ${expect}, got ${got}`); failed++; }
|
|
495
536
|
}
|
|
496
537
|
|
|
538
|
+
const angleEngineCases: Array<[string, boolean, boolean, string]> = [
|
|
539
|
+
['Tavily and Firecrawl ready', true, true, 'tavily,firecrawl,ddg'],
|
|
540
|
+
['Tavily unavailable', false, true, 'firecrawl,ddg'],
|
|
541
|
+
['Tavily disabled', false, true, 'firecrawl,ddg'],
|
|
542
|
+
['both paid search engines unavailable', false, false, 'ddg'],
|
|
543
|
+
];
|
|
544
|
+
for (const [label, tavilyReady, firecrawlReady, expected] of angleEngineCases) {
|
|
545
|
+
const got = deepAngleSearchOrder(tavilyReady, firecrawlReady).join(',');
|
|
546
|
+
if (got === expected) { console.log(` PASS: deep angle fallback ${label} → ${got}`); passed++; }
|
|
547
|
+
else { console.log(` FAIL: deep angle fallback ${label} expect ${expected}, got ${got}`); failed++; }
|
|
548
|
+
}
|
|
549
|
+
const tbsCases: Array<[string, string | undefined]> = [
|
|
550
|
+
['day', 'qdr:d'], ['week', 'qdr:w'], ['month', 'qdr:m'], ['year', 'qdr:y'], ['unset', undefined],
|
|
551
|
+
];
|
|
552
|
+
for (const [timeRange, expected] of tbsCases) {
|
|
553
|
+
const got = firecrawlTbsFromTimeRange(timeRange === 'unset' ? undefined : timeRange);
|
|
554
|
+
if (got === expected) { console.log(` PASS: Firecrawl time range ${timeRange} → ${got ?? 'unset'}`); passed++; }
|
|
555
|
+
else { console.log(` FAIL: Firecrawl time range ${timeRange} expect ${expected}, got ${got}`); failed++; }
|
|
556
|
+
}
|
|
557
|
+
|
|
497
558
|
console.log(`\n결과: ${passed} passed, ${failed} failed`);
|
|
498
559
|
if (failed > 0) process.exit(1);
|
|
499
560
|
}
|
|
@@ -38,6 +38,7 @@ import { nextTurnFallbackProvider, resolveDefaultProvider, type LLMMessage, type
|
|
|
38
38
|
import { readAutohealProviderFallback } from '../self-health/autoheal.js';
|
|
39
39
|
import { debug, redactSecretText } from '../debug/log.js';
|
|
40
40
|
import { CoreTurnAuthRejectedError } from '../core-turn/auth-rejected-notice.js';
|
|
41
|
+
import { globalTaskNotificationQueue, renderTaskNotificationsXml } from '../agent/task-notification.js';
|
|
41
42
|
import {
|
|
42
43
|
runCoreTurn,
|
|
43
44
|
runGoalLoop,
|
|
@@ -452,6 +453,11 @@ export function bridgeCoreTurnToAcp(
|
|
|
452
453
|
? runGoalLoop(c, {
|
|
453
454
|
// ACP owns an interactive provider loop: keep its post-completion response contract.
|
|
454
455
|
terminalCompletionShortcut: false,
|
|
456
|
+
drainIterationMessages: () => {
|
|
457
|
+
const pending = globalTaskNotificationQueue.drainForParentSessionOrUnscoped(c.sessionId);
|
|
458
|
+
const xml = renderTaskNotificationsXml(pending);
|
|
459
|
+
return xml ? [{ role: 'user', content: xml }] : [];
|
|
460
|
+
},
|
|
455
461
|
...(goalLoopCfg?.maxIterations !== undefined ? { maxIterations: goalLoopCfg.maxIterations } : {}),
|
|
456
462
|
// #29 처방 — 자리 판정으로 goal loop 에 «되돌아온» 턴만 빈 evidence 완료를 답으로 받는다.
|
|
457
463
|
...(route.reason.startsWith('seat-') ? { lenientCompletionEvidence: true } : {}),
|
|
@@ -543,6 +549,13 @@ export function bridgeCoreTurnToAcp(
|
|
|
543
549
|
streamedTextSum += delta;
|
|
544
550
|
void turnCtx.push(delta);
|
|
545
551
|
},
|
|
552
|
+
onReplaceText: (full) => {
|
|
553
|
+
reasoningThoughts.flush();
|
|
554
|
+
streamedTextSum = full;
|
|
555
|
+
// Match the existing ACP clear/replace convention used for final synthesis.
|
|
556
|
+
void turnCtx.push('');
|
|
557
|
+
void turnCtx.push(full);
|
|
558
|
+
},
|
|
546
559
|
// P2-bridge-ext — forward tool + usage events as ACP
|
|
547
560
|
// sessionUpdate notifications so extension-aware clients
|
|
548
561
|
// (dashboard as ACP client / future web / iphone) can
|
package/src/agent/registry.ts
CHANGED
|
@@ -123,6 +123,7 @@ export class AgentRegistry {
|
|
|
123
123
|
id: randomUUID(),
|
|
124
124
|
definition: opts.definition,
|
|
125
125
|
prompt: opts.prompt,
|
|
126
|
+
...(opts.parentSessionId ? { parentSessionId: opts.parentSessionId } : {}),
|
|
126
127
|
depth,
|
|
127
128
|
...(opts.label ? { label: opts.label } : {}),
|
|
128
129
|
...(opts.correlationId ? { correlationId: opts.correlationId } : {}),
|
|
@@ -136,6 +137,7 @@ export class AgentRegistry {
|
|
|
136
137
|
...(opts.teamName ? { teamName: opts.teamName } : {}),
|
|
137
138
|
...(opts.cwd ? { cwd: opts.cwd } : {}),
|
|
138
139
|
...(opts.background ? { background: true } : {}),
|
|
140
|
+
...(opts.completionDelivery ? { completionDelivery: opts.completionDelivery } : {}),
|
|
139
141
|
// MSS M1.2: brand the spawn with an AgentUri (caller may pre-mint
|
|
140
142
|
// for cross-task tracing; default = fresh mint). The legacy UUID
|
|
141
143
|
// `id` stays the registry key — agentUri rides alongside.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// "(running in background)" message on the same turn. To surface the
|
|
6
6
|
// eventual result, we collect a `PendingTaskNotification` per completed
|
|
7
7
|
// background task and inject a `<task-notification>` XML user message
|
|
8
|
-
// at the start of the parent's
|
|
8
|
+
// at the start of the parent's next turn or at a live goal-loop boundary.
|
|
9
9
|
//
|
|
10
10
|
// Why XML injection instead of a tool ──
|
|
11
11
|
// • Tool-loop parents would need to remember to poll; the reliability
|
|
@@ -43,11 +43,14 @@ export const TASK_NOTIFICATION_OUTPUT_CAP = 500;
|
|
|
43
43
|
|
|
44
44
|
export interface PendingTaskNotification {
|
|
45
45
|
taskId: string;
|
|
46
|
+
parentSessionId?: string;
|
|
46
47
|
agentName: string;
|
|
47
48
|
/** Caller-supplied short label (Agent tool's `name` arg). */
|
|
48
49
|
label?: string;
|
|
49
50
|
/** Team context this task belonged to (Agent tool's `team_name`). */
|
|
50
51
|
teamName?: string;
|
|
52
|
+
/** Parent-selected route; supplemental results never reopen a TUI turn. */
|
|
53
|
+
completionDelivery?: 'follow-up' | 'supplement';
|
|
51
54
|
/** Final state of the task — parent LLM sees this to choose follow-up. */
|
|
52
55
|
state: 'done' | 'error' | 'aborted';
|
|
53
56
|
/** Child's final text (capped at TASK_NOTIFICATION_OUTPUT_CAP). */
|
|
@@ -150,11 +153,26 @@ export class TaskNotificationQueue {
|
|
|
150
153
|
}
|
|
151
154
|
}
|
|
152
155
|
|
|
153
|
-
/** Return all pending notifications
|
|
154
|
-
* call this exactly once per turn-start. */
|
|
156
|
+
/** Return all pending notifications and remove them from the queue. */
|
|
155
157
|
drain(): PendingTaskNotification[] {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
+
return this.drainMatching(() => true);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** Drain only results owned by one parent session; leave sibling sessions queued. */
|
|
162
|
+
drainForParentSession(parentSessionId: string): PendingTaskNotification[] {
|
|
163
|
+
return this.drainMatching((item) => item.parentSessionId === parentSessionId);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Drain one session's receipts plus legacy sessionless receipts; keep sibling sessions queued. */
|
|
167
|
+
drainForParentSessionOrUnscoped(parentSessionId: string): PendingTaskNotification[] {
|
|
168
|
+
return this.drainMatching((item) => item.parentSessionId === undefined || item.parentSessionId === parentSessionId);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private drainMatching(matches: (item: PendingTaskNotification) => boolean): PendingTaskNotification[] {
|
|
172
|
+
const out = this.queue.filter(matches);
|
|
173
|
+
if (out.length === 0) return out;
|
|
174
|
+
const drained = new Set(out);
|
|
175
|
+
this.queue = this.queue.filter((item) => !drained.has(item));
|
|
158
176
|
this.persist();
|
|
159
177
|
// NOTE: we keep `seen` populated so a listener firing a second
|
|
160
178
|
// time for the same task (rare but possible under races) still
|
|
@@ -260,9 +278,11 @@ function buildPendingFromTask(task: AgentTask): PendingTaskNotification | null {
|
|
|
260
278
|
const output = task.result ?? '';
|
|
261
279
|
return {
|
|
262
280
|
taskId: task.id,
|
|
281
|
+
...(task.parentSessionId ? { parentSessionId: task.parentSessionId } : {}),
|
|
263
282
|
agentName: task.definition.name,
|
|
264
283
|
...(task.label ? { label: task.label } : {}),
|
|
265
284
|
...(task.teamName ? { teamName: task.teamName } : {}),
|
|
285
|
+
...(task.completionDelivery ? { completionDelivery: task.completionDelivery } : {}),
|
|
266
286
|
state,
|
|
267
287
|
output,
|
|
268
288
|
truncated: false,
|
package/src/agent/types.ts
CHANGED
|
@@ -154,6 +154,8 @@ export interface AgentTask {
|
|
|
154
154
|
* the runner drains events in the background; completion emits
|
|
155
155
|
* a task-notification (PFC-S1 P2). */
|
|
156
156
|
background?: boolean;
|
|
157
|
+
/** How a background completion reaches an idle parent TUI. */
|
|
158
|
+
completionDelivery?: 'follow-up' | 'supplement';
|
|
157
159
|
/** MSS M1.2: branded URI form of this spawn's identity. The
|
|
158
160
|
* registry mints one alongside the UUID-keyed `id`. Downstream
|
|
159
161
|
* MSS bridges (M3 signal sender · M4 memory participant) reference
|
|
@@ -183,6 +185,8 @@ export interface AgentSpawnOpts {
|
|
|
183
185
|
definition: AgentDefinition;
|
|
184
186
|
/** User message / query the agent should answer. */
|
|
185
187
|
prompt: string;
|
|
188
|
+
/** Session that owns this spawn; scopes background completion delivery. */
|
|
189
|
+
parentSessionId?: string;
|
|
186
190
|
/** Short task label — used by UI panes (e.g. agent-roster in
|
|
187
191
|
* wd-scratch) to distinguish spawns that share a definition.
|
|
188
192
|
* Stored verbatim on AgentTask.label. Optional; when omitted,
|
|
@@ -225,6 +229,8 @@ export interface AgentSpawnOpts {
|
|
|
225
229
|
* immediately and drains events off-thread. Completion emits a
|
|
226
230
|
* task-notification (see src/agent/task-notification.ts, P2). */
|
|
227
231
|
background?: boolean;
|
|
232
|
+
/** Parent-selected routing for background completions. */
|
|
233
|
+
completionDelivery?: 'follow-up' | 'supplement';
|
|
228
234
|
/** MSS M1.2: when the caller has already minted an AgentUri (e.g. a
|
|
229
235
|
* parent spawn pre-allocating ids for tracing), pass it here.
|
|
230
236
|
* Otherwise registry.spawn mints one. */
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import { readFileSync } from 'node:fs';
|
|
8
8
|
import type { AgentBackend, AgentMissionResult, EvidenceMode } from './driver.js';
|
|
9
|
+
import type { AgentCliDetection } from './tool-install.js';
|
|
9
10
|
import { buildAgentMissionDevSpec, executeAgentMissionReroute, type runDevPipeline } from '../self-dev/dev-pipeline.js';
|
|
10
11
|
import { parsePositiveInt } from '../self-dev/dev-cli.js';
|
|
11
12
|
import { parsePluginRef } from './in-agent-plugin.js';
|
|
@@ -33,6 +34,8 @@ export interface MissionCliOpts {
|
|
|
33
34
|
|
|
34
35
|
export interface MissionCliDeps {
|
|
35
36
|
resolveBackend: (name?: string) => AgentBackend;
|
|
37
|
+
detectAgentCli?: (agent: 'claude' | 'codex') => AgentCliDetection;
|
|
38
|
+
onStatus?: (line: string) => void;
|
|
36
39
|
signal?: AbortSignal;
|
|
37
40
|
readFile?: (path: string) => string;
|
|
38
41
|
runDevPipeline?: typeof runDevPipeline;
|
|
@@ -114,6 +117,27 @@ export async function runAgentMissionCliCommand(
|
|
|
114
117
|
...(opts.deliverable ? { deliverableHint: opts.deliverable } : {}),
|
|
115
118
|
...(opts.screens ? { screensDir: opts.screens } : {}),
|
|
116
119
|
});
|
|
120
|
+
// The production CLI injects the host probe; injected tests can assert this preflight
|
|
121
|
+
// without spawning an agent CLI. For a chain, inspect each external CLI before any launch.
|
|
122
|
+
const externalAgents = [...new Set((chain ?? [agentBackend.name]).filter(
|
|
123
|
+
(name): name is 'claude' | 'codex' => name === 'claude' || name === 'codex',
|
|
124
|
+
))];
|
|
125
|
+
const detections = deps.detectAgentCli ? externalAgents.map((agent) => deps.detectAgentCli!(agent)) : [];
|
|
126
|
+
const statusLine = detections.map(({ message }) => message).join(' · ');
|
|
127
|
+
if (statusLine) deps.onStatus?.(statusLine);
|
|
128
|
+
const notReady = detections.find(({ installed, login }) => installed !== true || login !== 'ready');
|
|
129
|
+
if (notReady) {
|
|
130
|
+
const message = notReady.installed === false
|
|
131
|
+
? `${notReady.message}; 공식 설치 후 다시 실행`
|
|
132
|
+
: notReady.installed === null
|
|
133
|
+
? `${notReady.message}; 설치 상태를 확인한 뒤 다시 실행`
|
|
134
|
+
: notReady.login === 'api-key'
|
|
135
|
+
? `${notReady.message}; API 키 요금 고지와 동의 화면이 아직 없어 미션을 시작하지 않습니다 — Codex 구독 로그인(codex login) 후 다시 실행`
|
|
136
|
+
: notReady.login === 'needed'
|
|
137
|
+
? `${notReady.message}; ${notReady.agent} login 후 다시 실행`
|
|
138
|
+
: `${notReady.message}; 로그인 상태를 확인한 뒤 다시 실행`;
|
|
139
|
+
return { ok: false, message, exitCode: 1 };
|
|
140
|
+
}
|
|
117
141
|
const { result, exitCode } = await executeAgentMissionReroute(
|
|
118
142
|
spec, agentBackend,
|
|
119
143
|
{ ...(deps.runDevPipeline ? { runDevPipeline: deps.runDevPipeline } : {}), ...(deps.signal ? { signal: deps.signal } : {}) },
|