elanous 0.2.40 → 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/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/{HjeK7zONHfR7op1hKXp4k → 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/{4769.9fd582071301f382.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/{470.51a72a2348306455.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/{7219-15bdd9a80661af8e.js → 1455-530ca16c7e71baff.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1281.d81877e35b9068f4.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/{1350.59f40e39e02d91b1.js → 2456.b6de0e1c05f28843.js} +1 -1
- 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/2690.0521c738b7749931.js +115 -0
- package/apps/pwa/out/_next/static/chunks/{5436.fdf6fa8ae3e9588d.js → 2974.595d1e29d040cb6a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5383.bdfa5d886e39a826.js → 3207.a756c95e9ec8c3c8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3285.89ee2f298682f5e5.js +93 -0
- package/apps/pwa/out/_next/static/chunks/{2177.df8547f9d7215c4e.js → 3347.f846266b5e5f3ede.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +41 -0
- package/apps/pwa/out/_next/static/chunks/{9184.45afbf44fec87574.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/{8099.1cccf31c1baa7e1c.js → 3741.9cf76acaa2ee5298.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3837.a210d7d0db8d8abd.js +1 -0
- 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/{4864a2ca.1c1c280a7772c5e5.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/{3330.7443183b7e6fdbdf.js → 4276.336d76d858fcdf1b.js} +1 -1
- 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/{3b355b3d.6f73c98bf6f9c749.js → 50061469.0326382241ef3b2d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5112.4b9f300124fab7b3.js +149 -0
- 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/{8d173e38.18a2f7b4e1848bdb.js → 53c73f84.373b6160adfa89a4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1537-6bb97b5214928ea9.js → 5431-72a1dbde59400691.js} +1 -1
- 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/{261.0d471e8aded799f3.js → 6131.348b7d6bdcd267ce.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +90 -0
- package/apps/pwa/out/_next/static/chunks/{9175.2de5209a5ce6f68a.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/{2226.2cf61ec781827219.js → 6632.0eac1c554f8f2ef3.js} +2 -2
- 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/7279-c199ea83f34338fa.js +1 -0
- 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/{b84cad00.594027ebe0531fe2.js → 73d2eb0e.4966ad55293c801a.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{6257.c0037b8949239f5e.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/{9189505a.980427ac048c8c60.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/{2566.beaffc3a5e1fcd2e.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/{8272-025653884f9645d2.js → 8546-6f03f8ea34dd61d9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6051-0ae955eedb10adb9.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/{4351.0f37a6db2b34d50b.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/9353-12bfff0c130104cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9415.69e4a21c60c7d2db.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6749.0744ce6eb08d40e9.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/{7611.85f045bf232053ac.js → 9633.ce5bddc56784da72.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3746-f80a78f220bf37b5.js → 9656-374232558fd528d0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9832.f4a98c878ecf2c0a.js +62 -0
- 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-83d27757e2b8060a.js → page-0e3d7b9421b79dac.js} +1 -1
- 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-139d722de1dcd6c1.js → page-bf067887b3307423.js} +1 -1
- 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/{409c787b.e48c5bec8ec10456.js → b450776b.3db34d8d965f82d3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{ca3702f8.2913182e73889fa2.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/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/docs/goal-context/04-mock-scenarios.md +13 -0
- package/graphs/catalog/catalog.yaml +1 -1
- 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/heal/heal-loop.yaml +1 -0
- package/graphs/overlays/stop-heal-ladder.yaml +136 -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 +13 -10
- package/graphs/units/verbs/research.yaml +20 -0
- package/graphs/work/research-report.yaml +21 -3
- package/package.json +1 -1
- 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/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/llm-cost-ledger.ts +179 -8
- package/scripts/measure-nl-routing-corpus.ts +10 -2
- package/scripts/persona-teacher/weekly-lesson-node.ts +172 -0
- package/scripts/public-copy-lint.ts +163 -19
- package/scripts/ratchets/train-side-invariants.sh +0 -1
- package/scripts/release-loop/gate-autoheal.ts +117 -0
- package/scripts/release-loop/gate-baseline-receipt.ts +55 -10
- package/scripts/release-loop/gate-diff.ts +22 -3
- 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 +489 -62
- 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-shard-load-flaky.ts +256 -0
- package/scripts/release-loop/gate-train-receipts.ts +122 -0
- package/scripts/release-loop/gate-triage-node.ts +70 -10
- package/scripts/release-loop/resume-release.ts +330 -23
- package/scripts/release-loop/traffic-node.ts +6 -3
- package/scripts/release-loop/unattended-release.ts +4 -2
- package/scripts/shadow-authoring-probe.ts +20 -0
- package/scripts/ux-sim.ts +37 -3
- 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 +99 -4
- 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 +267 -40
- package/src/auto-research/research-turn.ts +133 -51
- package/src/autopilot/discovery/wiki-claim-proposer.ts +22 -1
- package/src/autopilot/pr-manager.ts +38 -7
- package/src/autopilot/pty-control-loop.ts +2 -0
- package/src/boot/daemon-tools/self-implement.ts +46 -9
- package/src/budget/shadow-arms.ts +52 -0
- package/src/capture/tui-self-report.ts +22 -6
- package/src/chat/index.ts +1 -1
- package/src/chat/pickers/state.ts +7 -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/log-event-names.ts +5 -0
- package/src/cli/mcp-login.ts +8 -18
- package/src/cli/msg-cli.ts +57 -1
- package/src/cli/pr-land-heavy-remote.ts +47 -9
- 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/release-cli.ts +27 -1
- package/src/cli/research-cli.ts +4 -5
- package/src/cli/sim-cli.ts +7 -1
- package/src/cli/tasks-cli.ts +12 -4
- package/src/codex/models.ts +30 -15
- 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 +313 -89
- package/src/core-turn/run-goal-loop.ts +106 -2
- package/src/core-turn/types.ts +2 -0
- package/src/dashboard/acp-boot.ts +72 -3
- package/src/dashboard/classic-sidetab-mission-job.ts +58 -0
- package/src/dashboard/classic-sidetab-mission.ts +185 -0
- package/src/dashboard/index.ts +155 -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 +65 -16
- package/src/dashboard/turn-prompt-runtime.ts +4 -2
- 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/graph-runner/graph-cli.ts +44 -7
- package/src/graph-runner/graph-tick.ts +10 -2
- package/src/graph-runner/in-process-registry.ts +37 -0
- package/src/graph-runner/runner.ts +34 -4
- package/src/grok/agent-search.ts +14 -4
- package/src/grok/credential.ts +28 -11
- package/src/grounding/ref-index.ts +19 -0
- package/src/grounding/sources-cli.ts +9 -1
- package/src/harness/harness-cli-command.ts +267 -14
- package/src/harness/harness-incidents.ts +312 -7
- package/src/harness/harness-pod-dispatch.ts +81 -15
- package/src/harness/harness-space.ts +15 -1
- package/src/harness/harness-stop.ts +155 -11
- package/src/harness/progress-worker-entry.ts +59 -0
- package/src/harness/progress-worker-runtime.ts +11 -0
- package/src/index.ts +52 -7
- package/src/instance/dev-project.ts +25 -0
- package/src/instance/spawn-elanous.ts +6 -4
- package/src/intelligence-map/model-alias.ts +6 -5
- package/src/intelligence-map/model-catalog.ts +59 -2
- package/src/llm/model-defaults.ts +4 -4
- package/src/llm.ts +208 -19
- package/src/loops/orchestrator/coordinator-shadow.ts +226 -0
- package/src/loops/orchestrator/tick.ts +61 -0
- package/src/maturity/feature-maturity.ts +1 -1
- 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/native-tool-catalog.ts +2 -2
- package/src/nexus/api/harness-traversal.ts +11 -0
- package/src/output-truncation.ts +41 -12
- package/src/pr-tool/census.ts +3 -2
- package/src/project/project-store.ts +48 -1
- 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/release-loop/gate-host-reservation.ts +144 -0
- package/src/release-loop/release-schedule.ts +90 -1
- package/src/repl/index.ts +43 -2
- package/src/research/axis-fanout.ts +121 -16
- package/src/research/bloom-exemplars.ts +137 -0
- 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/ask-launch-flow.ts +39 -25
- package/src/self-dev/decompose.ts +119 -5
- package/src/self-dev/dev-cli.ts +17 -17
- package/src/self-dev/graph-front-nodes.ts +23 -0
- package/src/self-dev/launch-preflight-text.ts +5 -6
- package/src/self-dev/launch-preflight.ts +9 -4
- package/src/self-dev/orchestrate.ts +27 -2
- package/src/self-dev/review-provider-fallback.ts +9 -2
- package/src/self-dev/run-supervisor.ts +226 -6
- package/src/self-dev/run-types.ts +7 -0
- package/src/self-implement/doctor-visit.ts +88 -0
- package/src/self-implement/gate-artifacts.ts +13 -0
- package/src/self-implement/gate-cli.ts +54 -24
- package/src/self-implement/gate-remote.ts +23 -5
- package/src/self-implement/goal-author-clarification.ts +31 -12
- package/src/self-implement/goal-author.ts +403 -8
- package/src/self-implement/graph-overlay-yaml.ts +7 -0
- 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/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 +31 -8
- package/src/self-implement/knowhow-pack.ts +38 -0
- package/src/self-implement/merge-train.ts +5 -0
- package/src/self-implement/orchestrator.ts +359 -30
- 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 +176 -17
- package/src/self-implement/run-stop.ts +208 -5
- package/src/self-implement/running-runs.ts +35 -12
- package/src/self-implement/self-implement-cli.ts +36 -4
- package/src/self-implement/stop-autoheal-operational.ts +43 -0
- package/src/self-implement/stop-autoheal.ts +28 -6
- package/src/session/chat.ts +69 -58
- package/src/session/request-size-guard.ts +123 -0
- package/src/session-runtime/index.ts +98 -4
- package/src/session-runtime/tier-flip.ts +3 -3
- package/src/sidetab-core/model.ts +150 -0
- 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/parent-host.ts +14 -1
- package/src/task-agent/pod-distributor-entry.ts +3 -0
- package/src/task-agent/task-hand.ts +31 -1
- package/src/task-orchestrator/surfaces/pod-distributor.ts +48 -0
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +43 -0
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +38 -1
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +29 -4
- 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 +280 -60
- package/src/task-orchestrator/surfaces/self-implement.ts +18 -0
- 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 +24 -7
- package/src/tui/sidetab/attach.ts +47 -0
- package/src/tui/sidetab/list.ts +45 -0
- package/src/tui/sidetab/nl-tool.ts +2 -136
- package/src/tui/sidetab/peek.ts +52 -0
- package/src/tui-client/dashboard-session.ts +3 -0
- package/src/tui-client/local-chat-turn.ts +26 -13
- package/src/tui.ts +22 -0
- package/src/user-config.ts +11 -5
- package/src/ux-sim/fake-kubectl.ts +37 -3
- 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/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/release-sim-rig.ts +262 -0
- package/src/ux-sim/scenario.ts +116 -23
- package/src/ux-sim/seminar-rehearsal.ts +109 -0
- package/src/ux-sim/subagent-tools-device.ts +2 -2
- 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/1060.014f1f01a17aec26.js +0 -115
- package/apps/pwa/out/_next/static/chunks/1415.79821ec7ae99acdb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1452.162bb2d9d699e82a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/147.f92f63bbc5e85fa5.js +0 -286
- package/apps/pwa/out/_next/static/chunks/1661.fb425a1d8a065b72.js +0 -149
- package/apps/pwa/out/_next/static/chunks/1671-1c22b40b50b208f2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1758.0204d3f48783c49d.js +0 -90
- package/apps/pwa/out/_next/static/chunks/1806.027bf78b6a94d340.js +0 -104
- package/apps/pwa/out/_next/static/chunks/2047.8f23e210995d4548.js +0 -2
- package/apps/pwa/out/_next/static/chunks/2061-7f2bbc53ae96c88b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2066.a77257c8c350770a.js +0 -23
- package/apps/pwa/out/_next/static/chunks/2096-a938496bc996dcbd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2200-9a453b8f99687d49.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2281-b8cede695c6c650e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2499.02fbfd18126c10c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2522.f2766b76d22c8bdf.js +0 -34
- package/apps/pwa/out/_next/static/chunks/2615.3c9738153de3ef3f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2727.e703d99ac414916d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2752.7904b8df0254d0ae.js +0 -27
- package/apps/pwa/out/_next/static/chunks/2762-5051a862dfa40e99.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2767-31784bfedf8e245d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2774-719820e3f5b2a3eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2812-f016aa0dda149287.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2829-734fe8bf2eee7347.js +0 -1
- package/apps/pwa/out/_next/static/chunks/311-32dcac79970985e8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3175-f93f7495cd28253c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3184.8da993f5502d2140.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3231-d7c981db0ff8bdcc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3250.151309c5176d6b4b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3517.a5aa1797a9dbf2ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3567-45f676877ed9e8a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3819.8a1de79b2e8c7298.js +0 -24
- package/apps/pwa/out/_next/static/chunks/39.9b37b0be4c128a83.js +0 -77
- package/apps/pwa/out/_next/static/chunks/4023.a19045970a9ce16a.js +0 -36
- package/apps/pwa/out/_next/static/chunks/413-24c8284bda08241d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4135.e45d6ebc29e20647.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4283.65502f5d0e6ff6c0.js +0 -287
- package/apps/pwa/out/_next/static/chunks/4305-4e28fa92a7b34a5b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4335-50efa61fd7613142.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4720.ecbd1693fa151068.js +0 -1
- package/apps/pwa/out/_next/static/chunks/483.725e4a61be922788.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4969-4b209d7307410c00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5068-c7f53862f83c0917.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5315.bc96711c24dfefe2.js +0 -74
- package/apps/pwa/out/_next/static/chunks/5542.efbf14f16baed4dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5622.94893f5aea7185d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5644.8f401a25601d05fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5658.35f70eb9871a54bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5721.7bdc0e904c76ab51.js +0 -8
- package/apps/pwa/out/_next/static/chunks/5790-eef0ca20884a6bdf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5802.ef0d8598ca68fe84.js +0 -62
- package/apps/pwa/out/_next/static/chunks/5890.fb974729788dcb71.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5924.5ef25cddd36d5dbf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5979-e59c099ebf8d1f35.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6020.714cfeada2315e2e.js +0 -94
- package/apps/pwa/out/_next/static/chunks/6027-dfe0349d8c50f698.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6178.bc4730c86cf74536.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6273.d808b0dcb3c2b155.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6292.6ef1df64fa6a4c8a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/647-af8dd920ba46533c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6541-170dc5c59e135c0c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6624.981ef7caeb680560.js +0 -32
- package/apps/pwa/out/_next/static/chunks/6742-a1ad4a94ba7bc37a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6836-493dc55c39187949.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6856-53ac421c06039a18.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6908.06008c67f6380ea9.js +0 -148
- package/apps/pwa/out/_next/static/chunks/6915.096931864206f522.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6925.5e181fb7dcf90193.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6cc1d1d6.9a98dd4622f1afc6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7203-800e11037adc41eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7279.6170f591105936bb.js +0 -93
- package/apps/pwa/out/_next/static/chunks/7349-373165c7fbdcc3df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7514-a533ba0ca1cae4f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7515.1ad6efe157fa4448.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7521.d919cc1fab80c1d9.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7538.90e97bbdf9178cff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7825-39203196a12579b2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7869.5e1a9a12fd70d6c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8086.1ab9103c41be884f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8179-e61fffbdb70f1152.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8265.bdeb991b34db6a06.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8357.1aaa713b052a78b1.js +0 -309
- package/apps/pwa/out/_next/static/chunks/8638-e42615f2166165b5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8639-92c11d069792429e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8691.54e22831d5e8ccf8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9069.657590a84afb8fac.js +0 -41
- package/apps/pwa/out/_next/static/chunks/9125-ae588d88a0293b93.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9311.f9f641a46a508611.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9371-a6fee8378ebfa3ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9421-3aa9ff4fa7f63d8a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9992.07ce73c10bd5e6a1.js +0 -79
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76394dc618d322c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-1b948637c37b3abd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-c63400f1bcf3e47c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-95d0957267819586.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-ba957ff875a026a0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-bb6fd0714879cb87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-8f9038520d2acbef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-d4b48397e05fce2c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-72d5744245dc0c27.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-37625dc8300fa43a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-fbef9d160272dbc1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-58424168df84928e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-72c12ba430ac57c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-d53f3e9ed806d7e0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-4d2fbd45feee0829.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-76394dc618d322c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-8783dc0ed7590a2c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-3706cb390606e930.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-9b0a86598e0111fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-4edb8df90f4537ce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-47398b9ba1cc5e1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-fb86f55cfe2e681d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e22345fc8fd47b1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-fca2e59a81744d9e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-6e96bda63100b31e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-4d17ad8e0db8cea4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-121f92766c33beaa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-43f14212c545f92d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ccec2023e7a974ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-b04f33f548b89a94.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-c8792823c0917021.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-8c0e32782ceef4cb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-94bd3922eb230ce8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-bca565887bafa03c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ac1dffafe649fc6c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-52374edb5e23e455.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ad4ebca120d43ca7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-76394dc618d322c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-718b89ce4b4ae4e4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-204eca33eeeaddec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-e58ba9bcdb9ac0f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-98f6dd50bafd7734.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-5a4bdd72bff27057.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-6f6ab17d44f984ce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-aabb7bd15fb72da9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-e4322319164a4436.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-e9efc0c8f32e2371.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-ccde99f07aaf71f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-80464aced9614390.js +0 -1
- package/apps/pwa/out/_next/static/chunks/c696986b.5dc8bb1143af16d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/d5d3cefc-373c4eb722ed848b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/d8de0de2-dd0f4ac8e5ab1832.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-002b472a66935d31.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-49b88d47292c0476.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-fff2549cb10a133f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-32abbbba3f3b76b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-9d9cfef60c60dd7a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-cc7f483fa294034a.js +0 -1
- package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +0 -1
- package/scripts/ratchets/next-tui-entry-budget.ts +0 -124
- /package/apps/pwa/out/_next/static/{HjeK7zONHfR7op1hKXp4k → X1ucLw10Cds_h614NoEnh}/_ssgManifest.js +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { resolveInstanceName } from '../instance-identity.js';
|
|
2
|
+
import type { LLMToolSpec } from '../llm.js';
|
|
2
3
|
import { listPtyManifestRows, type PtyManifestRow } from '../pty-shell/pty-manifest.js';
|
|
3
4
|
import { describePtyRunState } from '../pty-shell/tui-run-state.js';
|
|
4
5
|
|
|
@@ -174,3 +175,152 @@ export function formatSidetabLines(
|
|
|
174
175
|
if (mode === 'list' && lines.length < Math.floor(height)) lines.push(fit(' + new · /side new'));
|
|
175
176
|
return lines;
|
|
176
177
|
}
|
|
178
|
+
|
|
179
|
+
/** NL/IPC side-tab contract and action policy, kept independent from either TUI renderer. */
|
|
180
|
+
export const NEXT_SIDETAB_TOOL_NAME = 'NextSidetab';
|
|
181
|
+
const NEXT_SIDETAB_CALL = 'elanous.sidetab.call';
|
|
182
|
+
const NEXT_SIDETAB_RESULT = 'elanous.sidetab.result';
|
|
183
|
+
|
|
184
|
+
export type NextSidetabAction = 'list' | 'switch' | 'attach' | 'detach' | 'new' | 'mission' | 'kill';
|
|
185
|
+
export interface NextSidetabRequest {
|
|
186
|
+
action: NextSidetabAction;
|
|
187
|
+
target?: string;
|
|
188
|
+
character?: 'shell' | 'elanous';
|
|
189
|
+
mission?: string;
|
|
190
|
+
agent?: 'codex' | 'claude';
|
|
191
|
+
confirm?: boolean;
|
|
192
|
+
}
|
|
193
|
+
export interface NextSidetabCall { type: typeof NEXT_SIDETAB_CALL; callId: string; request: NextSidetabRequest }
|
|
194
|
+
export interface NextSidetabResult { type: typeof NEXT_SIDETAB_RESULT; callId: string; result: unknown }
|
|
195
|
+
export type NextSidetabHandler = (request: NextSidetabRequest) => Promise<unknown>;
|
|
196
|
+
export interface NextSidetabHostDeps {
|
|
197
|
+
rows(): readonly SidetabRow[] | Promise<readonly SidetabRow[]>;
|
|
198
|
+
selected(): number;
|
|
199
|
+
switchSession(row: SidetabRow): Promise<unknown>;
|
|
200
|
+
attach(row: SidetabRow): Promise<unknown>;
|
|
201
|
+
detach(): unknown;
|
|
202
|
+
spawn(character: 'shell' | 'elanous'): unknown;
|
|
203
|
+
runMission?(agent: 'codex' | 'claude', mission: string): Promise<unknown>;
|
|
204
|
+
kill(row: SidetabRow): unknown;
|
|
205
|
+
}
|
|
206
|
+
export interface NextSidetabIpcProcess {
|
|
207
|
+
send?: (message: unknown) => boolean | void;
|
|
208
|
+
on(event: 'message', listener: (message: unknown) => void): unknown;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export const nextSidetabToolSpec: LLMToolSpec = {
|
|
212
|
+
name: NEXT_SIDETAB_TOOL_NAME,
|
|
213
|
+
description: 'Control the Next TUI side tab: list/view sessions and PTYs, switch sessions, attach or detach, start a local shell or elanous PTY, run a mission in a visible Codex or Claude side-tab and return its verified result file, or kill a PTY. Ask the user to confirm before calling kill with confirm=true.',
|
|
214
|
+
parameters: {
|
|
215
|
+
type: 'object',
|
|
216
|
+
properties: {
|
|
217
|
+
action: { type: 'string', enum: ['list', 'switch', 'attach', 'detach', 'new', 'mission', 'kill'] },
|
|
218
|
+
target: { type: 'string', description: 'Optional exact or partial row id/label; required for targeted actions.' },
|
|
219
|
+
character: { type: 'string', enum: ['shell', 'elanous'], description: 'Only used with action=new.' },
|
|
220
|
+
mission: { type: 'string', description: 'Mission text to type visibly into a new Codex or Claude side-tab PTY; the tool appends a result-file path and checks the completion marker.' },
|
|
221
|
+
agent: { type: 'string', enum: ['codex', 'claude'], description: 'Coding agent for action=mission; defaults to codex.' },
|
|
222
|
+
confirm: { type: 'boolean', description: 'Must be true only after the user explicitly confirmed killing the selected PTY.' },
|
|
223
|
+
},
|
|
224
|
+
required: ['action'],
|
|
225
|
+
additionalProperties: false,
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export function isNextSidetabCall(value: unknown): value is NextSidetabCall {
|
|
230
|
+
const call = value as Partial<NextSidetabCall> | null;
|
|
231
|
+
return Boolean(call && call.type === NEXT_SIDETAB_CALL && typeof call.callId === 'string'
|
|
232
|
+
&& call.request && typeof call.request === 'object');
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export async function answerNextSidetabCall(handler: NextSidetabHandler, call: NextSidetabCall): Promise<NextSidetabResult> {
|
|
236
|
+
try { return { type: NEXT_SIDETAB_RESULT, callId: call.callId, result: await handler(call.request) }; }
|
|
237
|
+
catch (error) {
|
|
238
|
+
return { type: NEXT_SIDETAB_RESULT, callId: call.callId, result: { error: error instanceof Error ? error.message : String(error) } };
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export function createNextSidetabHostHandler(deps: NextSidetabHostDeps): NextSidetabHandler {
|
|
243
|
+
return async (request) => {
|
|
244
|
+
if (!request || !['list', 'switch', 'attach', 'detach', 'new', 'mission', 'kill'].includes(request.action)) {
|
|
245
|
+
return { error: '지원하지 않는 사이드탭 동작입니다' };
|
|
246
|
+
}
|
|
247
|
+
if (request.action === 'new') {
|
|
248
|
+
if (request.character !== 'shell' && request.character !== 'elanous') return { error: 'character는 shell 또는 elanous여야 합니다' };
|
|
249
|
+
return deps.spawn(request.character);
|
|
250
|
+
}
|
|
251
|
+
if (request.action === 'mission') {
|
|
252
|
+
const mission = request.mission?.trim();
|
|
253
|
+
if (!mission) return { error: 'mission 텍스트가 필요합니다' };
|
|
254
|
+
if (!deps.runMission) return { error: '사이드탭 미션 실행기가 연결되지 않았습니다' };
|
|
255
|
+
if (request.agent !== undefined && request.agent !== 'codex' && request.agent !== 'claude') return { error: 'agent는 codex 또는 claude여야 합니다' };
|
|
256
|
+
return deps.runMission(request.agent ?? 'codex', mission);
|
|
257
|
+
}
|
|
258
|
+
if (request.action === 'detach') return deps.detach();
|
|
259
|
+
const rows = await deps.rows();
|
|
260
|
+
if (request.action === 'list') return rows.map(({ id, label, kind, badge, sessionId }) => ({ id, label, kind, badge, ...(sessionId ? { sessionId } : {}) }));
|
|
261
|
+
const target = request.target?.trim();
|
|
262
|
+
const exact = target ? rows.find((item) => item.id === target)
|
|
263
|
+
?? rows.find((item) => item.label.toLowerCase() === target.toLowerCase()) : undefined;
|
|
264
|
+
const partial = target && !exact ? rows.filter((item) => item.label.toLowerCase().includes(target.toLowerCase())) : [];
|
|
265
|
+
if (partial.length > 1) return { error: `사이드탭 항목이 여러 개 일치합니다: ${target}` };
|
|
266
|
+
const row = exact ?? partial[0] ?? (target ? undefined : rows[deps.selected()]);
|
|
267
|
+
if (!row) return { error: target ? `사이드탭 항목을 찾지 못했습니다: ${target}` : '선택된 사이드탭 항목이 없습니다' };
|
|
268
|
+
if (request.action === 'switch') return row.kind === 'tui' ? deps.switchSession(row) : { error: 'Next TUI 세션만 전환할 수 있습니다' };
|
|
269
|
+
if (request.action === 'attach') return deps.attach(row);
|
|
270
|
+
if (row.currentProcess) return { error: '현재 TUI 세션은 사이드탭에서 종료할 수 없습니다' };
|
|
271
|
+
if (request.confirm !== true) return { needsConfirmation: true, message: `PTY 종료 확인 필요: ${row.label}` };
|
|
272
|
+
return deps.kill(row);
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export function createReplNextSidetabTool(
|
|
277
|
+
proc: NextSidetabIpcProcess,
|
|
278
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
279
|
+
timeoutMs = 15_000,
|
|
280
|
+
missionTimeoutMs = 420_000,
|
|
281
|
+
): { spec: LLMToolSpec; dispatch: (args: Record<string, unknown>) => Promise<unknown> } | null {
|
|
282
|
+
if (env.ELANOUS_NEXT_TUI_SIDETAB_IPC !== '1' || typeof proc.send !== 'function') return null;
|
|
283
|
+
const send = proc.send.bind(proc);
|
|
284
|
+
const waiting = new Map<string, (result: unknown) => void>();
|
|
285
|
+
let sequence = 0;
|
|
286
|
+
const listener = (message: unknown): void => {
|
|
287
|
+
const result = message as Partial<NextSidetabResult> | null;
|
|
288
|
+
if (!result || result.type !== NEXT_SIDETAB_RESULT || typeof result.callId !== 'string') return;
|
|
289
|
+
const resolve = waiting.get(result.callId);
|
|
290
|
+
if (!resolve) return;
|
|
291
|
+
waiting.delete(result.callId);
|
|
292
|
+
resolve(result.result);
|
|
293
|
+
};
|
|
294
|
+
proc.on('message', listener);
|
|
295
|
+
return {
|
|
296
|
+
spec: nextSidetabToolSpec,
|
|
297
|
+
dispatch: (args) => new Promise((resolve) => {
|
|
298
|
+
const callId = `s${++sequence}`;
|
|
299
|
+
const callTimeoutMs = args.action === 'mission' ? missionTimeoutMs : timeoutMs;
|
|
300
|
+
const timer = setTimeout(() => {
|
|
301
|
+
if (!waiting.delete(callId)) return;
|
|
302
|
+
resolve({ error: 'Next TUI did not answer the side-tab request' });
|
|
303
|
+
}, callTimeoutMs);
|
|
304
|
+
waiting.set(callId, (result) => { clearTimeout(timer); resolve(result); });
|
|
305
|
+
try {
|
|
306
|
+
send({ type: NEXT_SIDETAB_CALL, callId, request: args as unknown as NextSidetabRequest } satisfies NextSidetabCall);
|
|
307
|
+
} catch (error) {
|
|
308
|
+
waiting.delete(callId);
|
|
309
|
+
clearTimeout(timer);
|
|
310
|
+
resolve({ error: `Next TUI IPC send failed: ${error instanceof Error ? error.message : String(error)}` });
|
|
311
|
+
}
|
|
312
|
+
}),
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export function registerNextSidetabReplTool(
|
|
317
|
+
specs: LLMToolSpec[],
|
|
318
|
+
dispatchByName: Map<string, (args: Record<string, unknown>) => Promise<unknown>>,
|
|
319
|
+
proc: NextSidetabIpcProcess,
|
|
320
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
321
|
+
): void {
|
|
322
|
+
const tool = createReplNextSidetabTool(proc, env);
|
|
323
|
+
if (!tool) return;
|
|
324
|
+
specs.push(tool.spec);
|
|
325
|
+
dispatchByName.set(tool.spec.name, tool.dispatch);
|
|
326
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { screenNeedsTrust } from '../agent-mission/parse.js';
|
|
4
|
+
import { sanitizeForPtyInput } from '../agent-mission/provision.js';
|
|
5
|
+
|
|
6
|
+
export interface VisibleMissionPty {
|
|
7
|
+
snapshot(): string;
|
|
8
|
+
write(bytes: string): void;
|
|
9
|
+
isAlive(): boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface VisibleMissionResult {
|
|
13
|
+
ok: boolean;
|
|
14
|
+
path: string;
|
|
15
|
+
content?: string;
|
|
16
|
+
firstLine?: string;
|
|
17
|
+
promptReady: boolean;
|
|
18
|
+
missionVisible: boolean;
|
|
19
|
+
promptReturned: boolean;
|
|
20
|
+
completionMarker: boolean;
|
|
21
|
+
error?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface VisibleMissionDeps {
|
|
25
|
+
pty: VisibleMissionPty;
|
|
26
|
+
mission: string;
|
|
27
|
+
outputPath: string;
|
|
28
|
+
handleTrust(screen: string, write: (bytes: string) => void): boolean;
|
|
29
|
+
readFile?(path: string): string;
|
|
30
|
+
sleep?(ms: number): Promise<void>;
|
|
31
|
+
readyTimeoutMs?: number;
|
|
32
|
+
visibilityTimeoutMs?: number;
|
|
33
|
+
completionTimeoutMs?: number;
|
|
34
|
+
pollMs?: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const sleepDefault = (ms: number): Promise<void> => new Promise(resolve => setTimeout(resolve, ms));
|
|
38
|
+
|
|
39
|
+
export function isAgentInputPrompt(screen: string): boolean {
|
|
40
|
+
const plain = stripAnsi(screen);
|
|
41
|
+
return /(?:^|\n)\s*[›❯]\s*(?:Ask\b|Try\b|$)/m.test(plain)
|
|
42
|
+
|| /Ask anything|Ask (?:Codex|Claude)(?: Code)? to do anything|What would you like to do\?/i.test(plain);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Drive a visible agent PTY, verify its result, then request a separate completion marker. */
|
|
46
|
+
export async function runVisibleAgentMission(deps: VisibleMissionDeps): Promise<VisibleMissionResult> {
|
|
47
|
+
const sleep = deps.sleep ?? sleepDefault;
|
|
48
|
+
const pollMs = deps.pollMs ?? 150;
|
|
49
|
+
const readFile = deps.readFile ?? ((path: string) => readFileSync(path, 'utf8'));
|
|
50
|
+
let promptReady = false;
|
|
51
|
+
let missionVisible = false;
|
|
52
|
+
let promptReturned = false;
|
|
53
|
+
let completionMarker = false;
|
|
54
|
+
try {
|
|
55
|
+
const readyDeadline = Date.now() + (deps.readyTimeoutMs ?? 60_000);
|
|
56
|
+
let lastScreen = '';
|
|
57
|
+
|
|
58
|
+
while (Date.now() < readyDeadline) {
|
|
59
|
+
if (!deps.pty.isAlive()) return { ok: false, path: deps.outputPath, promptReady: false, missionVisible: false, promptReturned: false, completionMarker: false, error: 'Agent PTY exited before its prompt appeared' };
|
|
60
|
+
lastScreen = deps.pty.snapshot();
|
|
61
|
+
if (screenNeedsTrust(lastScreen) && deps.handleTrust(lastScreen, bytes => deps.pty.write(bytes))) {
|
|
62
|
+
await sleep(500);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (isAgentInputPrompt(lastScreen)) { promptReady = true; break; }
|
|
66
|
+
await sleep(pollMs);
|
|
67
|
+
}
|
|
68
|
+
if (!promptReady) {
|
|
69
|
+
return {
|
|
70
|
+
ok: false, path: deps.outputPath, promptReady: false, missionVisible: false, promptReturned: false, completionMarker: false,
|
|
71
|
+
error: `Agent input prompt was not observed: ${lastScreen.slice(-240).replace(/\s+/g, ' ')}`,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const mission = sanitizeForPtyInput(deps.mission, 4_000);
|
|
76
|
+
if (!mission) return { ok: false, path: deps.outputPath, promptReady, missionVisible: false, promptReturned: false, completionMarker: false, error: 'Mission text is empty after input sanitization' };
|
|
77
|
+
try {
|
|
78
|
+
readFile(deps.outputPath);
|
|
79
|
+
return { ok: false, path: deps.outputPath, promptReady, missionVisible: false, promptReturned: false, completionMarker: false, error: 'Result path already exists; refusing to reuse a previous mission file' };
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if (!isFileNotFound(error)) {
|
|
82
|
+
return { ok: false, path: deps.outputPath, promptReady, missionVisible: false, promptReturned: false, completionMarker: false, error: `Could not verify a fresh result path: ${error instanceof Error ? error.message : String(error)}` };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const missionPrompt = `Write the result to the exact file path ${deps.outputPath} (create parent directories if needed). ${mission}`;
|
|
86
|
+
deps.pty.write(missionPrompt);
|
|
87
|
+
const visibleMissionTail = mission.slice(-Math.min(24, mission.length));
|
|
88
|
+
const visibilityDeadline = Date.now() + (deps.visibilityTimeoutMs ?? 5_000);
|
|
89
|
+
while (Date.now() < visibilityDeadline) {
|
|
90
|
+
const visibleText = stripAnsi(deps.pty.snapshot()).replace(/\s+/g, ' ');
|
|
91
|
+
if (visibleText.includes(visibleMissionTail)) { missionVisible = true; break; }
|
|
92
|
+
await sleep(Math.min(pollMs || 25, Math.max(1, visibilityDeadline - Date.now())));
|
|
93
|
+
}
|
|
94
|
+
if (!missionVisible) {
|
|
95
|
+
return { ok: false, path: deps.outputPath, promptReady, missionVisible: false, promptReturned: false, completionMarker: false, error: 'Mission text was not visible in the agent PTY before submission' };
|
|
96
|
+
}
|
|
97
|
+
deps.pty.write('\r');
|
|
98
|
+
|
|
99
|
+
const completionDeadline = Date.now() + (deps.completionTimeoutMs ?? 300_000);
|
|
100
|
+
let resultFileObserved = false;
|
|
101
|
+
while (Date.now() < completionDeadline) {
|
|
102
|
+
if (!deps.pty.isAlive()) break;
|
|
103
|
+
lastScreen = deps.pty.snapshot();
|
|
104
|
+
if (screenNeedsTrust(lastScreen) && deps.handleTrust(lastScreen, bytes => deps.pty.write(bytes))) {
|
|
105
|
+
await sleep(500);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (!resultFileObserved) {
|
|
109
|
+
try {
|
|
110
|
+
const candidate = readFile(deps.outputPath);
|
|
111
|
+
resultFileObserved = Boolean(candidate.trim());
|
|
112
|
+
} catch { /* the agent has not written the result file yet */ }
|
|
113
|
+
}
|
|
114
|
+
if (resultFileObserved && isAgentInputPrompt(lastScreen)) { promptReturned = true; break; }
|
|
115
|
+
await sleep(pollMs);
|
|
116
|
+
}
|
|
117
|
+
if (!resultFileObserved) {
|
|
118
|
+
return { ok: false, path: deps.outputPath, promptReady, missionVisible, promptReturned, completionMarker: false, error: 'Agent did not create a non-empty result file before the timeout' };
|
|
119
|
+
}
|
|
120
|
+
if (!promptReturned) {
|
|
121
|
+
return { ok: false, path: deps.outputPath, promptReady, missionVisible, promptReturned: false, completionMarker: false, error: 'Agent did not return to its input prompt after writing the result file' };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let content: string;
|
|
125
|
+
try { content = readFile(deps.outputPath); }
|
|
126
|
+
catch (error) {
|
|
127
|
+
return { ok: false, path: deps.outputPath, promptReady, missionVisible, promptReturned, completionMarker: false, error: `Result file disappeared after the agent returned: ${error instanceof Error ? error.message : String(error)}` };
|
|
128
|
+
}
|
|
129
|
+
const firstLine = content.split(/\r?\n/).map(line => line.trim()).find(Boolean);
|
|
130
|
+
if (!firstLine) return { ok: false, path: deps.outputPath, promptReady, missionVisible, promptReturned, completionMarker: false, error: 'Result file is empty' };
|
|
131
|
+
|
|
132
|
+
// Keep the marker request separate and short: the marker itself never occurs
|
|
133
|
+
// in the mission prompt, so only the agent's final output can satisfy it.
|
|
134
|
+
const completionMarkerText = `M-${randomUUID().replaceAll('-', '').slice(0, 12)}`;
|
|
135
|
+
const markerPrompt = `Say ${completionMarkerText} alone.`;
|
|
136
|
+
deps.pty.write(markerPrompt);
|
|
137
|
+
const markerVisibleDeadline = Date.now() + (deps.visibilityTimeoutMs ?? 5_000);
|
|
138
|
+
let markerRequestVisible = false;
|
|
139
|
+
while (Date.now() < markerVisibleDeadline) {
|
|
140
|
+
const markerInputScreen = stripAnsi(deps.pty.snapshot()).replace(/\s+/g, ' ');
|
|
141
|
+
if (markerInputScreen.includes(completionMarkerText)) { markerRequestVisible = true; break; }
|
|
142
|
+
await sleep(Math.min(pollMs || 25, Math.max(1, markerVisibleDeadline - Date.now())));
|
|
143
|
+
}
|
|
144
|
+
if (!markerRequestVisible) {
|
|
145
|
+
return { ok: false, path: deps.outputPath, firstLine, promptReady, missionVisible, promptReturned, completionMarker: false, error: 'Completion marker request was not visible in the agent PTY' };
|
|
146
|
+
}
|
|
147
|
+
if (screenShowsCompletionMarker(deps.pty.snapshot(), completionMarkerText)) {
|
|
148
|
+
return { ok: false, path: deps.outputPath, firstLine, promptReady, missionVisible, promptReturned, completionMarker: false, error: 'Completion marker appeared in the PTY input before submission' };
|
|
149
|
+
}
|
|
150
|
+
deps.pty.write('\r');
|
|
151
|
+
|
|
152
|
+
while (Date.now() < completionDeadline) {
|
|
153
|
+
if (!deps.pty.isAlive()) break;
|
|
154
|
+
if (screenShowsCompletionMarker(deps.pty.snapshot(), completionMarkerText)) { completionMarker = true; break; }
|
|
155
|
+
await sleep(pollMs);
|
|
156
|
+
}
|
|
157
|
+
if (!completionMarker) {
|
|
158
|
+
return { ok: false, path: deps.outputPath, firstLine, promptReady, missionVisible, promptReturned, completionMarker: false, error: 'Agent did not show its completion marker before the timeout' };
|
|
159
|
+
}
|
|
160
|
+
return { ok: true, path: deps.outputPath, content, firstLine, promptReady, missionVisible, promptReturned, completionMarker };
|
|
161
|
+
} catch (error) {
|
|
162
|
+
return {
|
|
163
|
+
ok: false,
|
|
164
|
+
path: deps.outputPath,
|
|
165
|
+
promptReady,
|
|
166
|
+
missionVisible,
|
|
167
|
+
promptReturned,
|
|
168
|
+
completionMarker,
|
|
169
|
+
error: error instanceof Error ? error.message : String(error),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function screenShowsCompletionMarker(screen: string, marker: string): boolean {
|
|
175
|
+
const escaped = marker.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
176
|
+
return new RegExp(`^\\s*(?:(?:[•⏺└│╰⎿])\\s*)?${escaped}\\s*$`, 'm').test(stripAnsi(screen));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function stripAnsi(screen: string): string {
|
|
180
|
+
return screen.replace(/\u001b\][^\u0007]*(?:\u0007|\u001b\\)/g, '')
|
|
181
|
+
.replace(/\u001b\[[0-?]*[ -/]*[@-~]/g, '');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function isFileNotFound(error: unknown): boolean {
|
|
185
|
+
return typeof error === 'object' && error !== null && 'code' in error && error.code === 'ENOENT';
|
|
186
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Canonicalize a spoken/typed skill slug while retaining letters and digits. */
|
|
2
|
+
export function normalizeSkillName(value: string): string {
|
|
3
|
+
return value.normalize('NFKC').toLowerCase().replace(/[\s\p{P}\p{S}_]+/gu, '');
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/** Return a canonical catalog entry only when the normalized name is unique. */
|
|
7
|
+
export function resolveSkillName<T extends { name: string }>(
|
|
8
|
+
requested: string,
|
|
9
|
+
entries: readonly T[],
|
|
10
|
+
): { entry?: T; ambiguous: T[] } {
|
|
11
|
+
// Keep accidental surrounding whitespace out of execution; only the
|
|
12
|
+
// slug's internal separators are fuzzy.
|
|
13
|
+
if (requested !== requested.trim()) return { ambiguous: [] };
|
|
14
|
+
const normalized = normalizeSkillName(requested);
|
|
15
|
+
if (!normalized) return { ambiguous: [] };
|
|
16
|
+
const matches = entries.filter((entry) => normalizeSkillName(entry.name) === normalized);
|
|
17
|
+
return matches.length === 1
|
|
18
|
+
? { entry: matches[0], ambiguous: [] }
|
|
19
|
+
: { ambiguous: matches.length > 1 ? matches : [] };
|
|
20
|
+
}
|
|
@@ -271,6 +271,10 @@ export interface AgentToolArgs {
|
|
|
271
271
|
* child keeps running; completion emits a task-notification
|
|
272
272
|
* (P2) which the parent sees in the next turn's user message. */
|
|
273
273
|
run_in_background?: boolean;
|
|
274
|
+
/** How a background completion reaches an idle parent TUI. */
|
|
275
|
+
completion_delivery?: 'follow-up' | 'supplement';
|
|
276
|
+
/** Best-effort wall-clock budget for a research child, in minutes. */
|
|
277
|
+
budget_minutes?: number;
|
|
274
278
|
/** When true, a background launch that hits the fan-out ceiling WAITS on
|
|
275
279
|
* the session's shared admission queue instead of being refused: it spawns
|
|
276
280
|
* as soon as a live background agent terminals (subagent waits are
|
|
@@ -349,6 +353,7 @@ export function buildAgentTool(): LLMToolSpec {
|
|
|
349
353
|
'Delegate heavy multistep work that would overflow your context, fan out independent units in parallel, ' +
|
|
350
354
|
'and hand off long investigations; use run_in_background for long-running work so you can keep coordinating ' +
|
|
351
355
|
'and finish after the results arrive.\n' +
|
|
356
|
+
'For parallel research, prefer completion_delivery="supplement" and budget_minutes=8: ask each child for its best verified evidence within the budget; late results appear as one chat line without reopening a TUI turn.\n' +
|
|
352
357
|
'\n' +
|
|
353
358
|
'The sub-agent gets its own tools (Bash/Read/Edit/Grep/WebFetch by default) and its own ' +
|
|
354
359
|
'turn budget (default 20). It returns ONE final message which becomes your tool_result. ' +
|
|
@@ -377,6 +382,17 @@ export function buildAgentTool(): LLMToolSpec {
|
|
|
377
382
|
type: 'boolean',
|
|
378
383
|
description: 'When true, returns the spawn handle immediately instead of waiting for completion. The child keeps running; its final message arrives in your next turn as a <task-notification> user message. Use for long-running explorations (multi-minute research, 10+ tool calls) so you can keep working in parallel.',
|
|
379
384
|
},
|
|
385
|
+
completion_delivery: {
|
|
386
|
+
type: 'string',
|
|
387
|
+
enum: ['follow-up', 'supplement'],
|
|
388
|
+
description: 'Background-only routing. supplement adds one concise chat line when the child finishes and never opens a new TUI turn; follow-up keeps default result retrieval.',
|
|
389
|
+
},
|
|
390
|
+
budget_minutes: {
|
|
391
|
+
type: 'number',
|
|
392
|
+
minimum: 1,
|
|
393
|
+
maximum: 60,
|
|
394
|
+
description: 'Background-only best-effort wall-clock research budget. Ask the child to stop researching at this point and return currently verified evidence; default 8 minutes for supplement delivery.',
|
|
395
|
+
},
|
|
380
396
|
wait_for_slot: {
|
|
381
397
|
type: 'boolean',
|
|
382
398
|
description: 'Only meaningful with run_in_background. When the per-session background fan-out ceiling is already full, this launch waits on the shared admission queue instead of being refused, and spawns as soon as one live background agent finishes. Waiting subagent spawns (ones that name a subagent_type) are admitted before general-purpose ones; launches with the same class keep arrival order. Omit it to get the immediate "NOT SPAWNED" refusal and re-issue later.',
|
|
@@ -423,6 +439,8 @@ export function buildAgentTool(): LLMToolSpec {
|
|
|
423
439
|
}
|
|
424
440
|
|
|
425
441
|
export interface DispatchAgentOpts {
|
|
442
|
+
/** Owning conversation session, copied to background completion receipts. */
|
|
443
|
+
parentSessionId?: string;
|
|
426
444
|
/** Tools the host makes available — typically the same tool list the
|
|
427
445
|
* parent skill is using, MINUS the Agent tool itself (no recursion).
|
|
428
446
|
* When omitted, the sub-agent runs with no tools (text-only). */
|
|
@@ -507,6 +525,10 @@ export async function dispatchAgent(
|
|
|
507
525
|
|
|
508
526
|
// PFC-S1 P1: new optional fields.
|
|
509
527
|
const runInBackground = args.run_in_background === true;
|
|
528
|
+
const completionDelivery = args.completion_delivery === 'supplement' ? 'supplement' : 'follow-up';
|
|
529
|
+
const requestedBudgetMinutes = typeof args.budget_minutes === 'number' && Number.isFinite(args.budget_minutes)
|
|
530
|
+
? Math.max(1, Math.min(60, Math.floor(args.budget_minutes)))
|
|
531
|
+
: (completionDelivery === 'supplement' ? 8 : undefined);
|
|
510
532
|
const waitsForSlot = args.wait_for_slot === true;
|
|
511
533
|
const spawnName = typeof args.name === 'string' && args.name.trim() ? args.name.trim() : undefined;
|
|
512
534
|
const teamName = typeof args.team_name === 'string' && args.team_name.trim() ? args.team_name.trim() : undefined;
|
|
@@ -923,9 +945,12 @@ export async function dispatchAgent(
|
|
|
923
945
|
}
|
|
924
946
|
|
|
925
947
|
const hasNoTools = childTools.length === 0;
|
|
926
|
-
const
|
|
948
|
+
const budgetPrompt = runInBackground && completionDelivery === 'supplement' && requestedBudgetMinutes
|
|
949
|
+
? `\n\n[Research time budget: ${requestedBudgetMinutes} minutes]\nReturn the best currently verified evidence within this budget. Do not wait for more sources or extend the research; state remaining uncertainty in the final message.`
|
|
950
|
+
: '';
|
|
951
|
+
const childPrompt = (hasNoTools
|
|
927
952
|
? `${prompt}\n\nNo tools are available; if a request requires reading files or executing commands, report that as unavailable rather than guessing.`
|
|
928
|
-
: prompt;
|
|
953
|
+
: prompt) + budgetPrompt;
|
|
929
954
|
|
|
930
955
|
debug.log('agent.spawn', 'dispatch', {
|
|
931
956
|
cid: debugCorrelationId,
|
|
@@ -935,6 +960,7 @@ export async function dispatchAgent(
|
|
|
935
960
|
promptChars: childPrompt.length,
|
|
936
961
|
model: definition.model || '(inherit)',
|
|
937
962
|
maxTurns: requestedMaxTurns,
|
|
963
|
+
...(runInBackground ? { completionDelivery, ...(requestedBudgetMinutes ? { researchBudgetMinutes: requestedBudgetMinutes } : {}) } : {}),
|
|
938
964
|
tools: childTools.map(t => t.name),
|
|
939
965
|
noTools: hasNoTools,
|
|
940
966
|
});
|
|
@@ -943,6 +969,7 @@ export async function dispatchAgent(
|
|
|
943
969
|
const handle = globalAgentRegistry.spawn({
|
|
944
970
|
definition,
|
|
945
971
|
prompt: childPrompt,
|
|
972
|
+
...(opts.parentSessionId ? { parentSessionId: opts.parentSessionId } : {}),
|
|
946
973
|
label: spawnName ?? description, // PFC-S1 P1: explicit `name`
|
|
947
974
|
// wins, else fall back to the task label
|
|
948
975
|
// (kept for existing callers).
|
|
@@ -963,6 +990,7 @@ export async function dispatchAgent(
|
|
|
963
990
|
...(teamName ? { teamName } : {}),
|
|
964
991
|
...(childCwd ? { cwd: childCwd } : {}),
|
|
965
992
|
...(runInBackground ? { background: true } : {}),
|
|
993
|
+
...(runInBackground ? { completionDelivery } : {}),
|
|
966
994
|
});
|
|
967
995
|
|
|
968
996
|
// Terminal release for this dispatch's reserved fan-out slot: the
|
|
@@ -73,16 +73,39 @@ export function buildOmniSearchTool(): LLMToolSpec {
|
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
const RESEARCH_GROK_TIMEOUT_MS = 8_000;
|
|
77
|
+
|
|
76
78
|
export async function dispatchOmniSearch(
|
|
77
79
|
rawArgs: Record<string, unknown>,
|
|
78
80
|
opts: OmniSearchDispatchOpts = {},
|
|
81
|
+
): Promise<OmniSearchResult> {
|
|
82
|
+
return dispatchWithProviders(validate(rawArgs), opts);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export async function dispatchResearchOmniSearch(
|
|
86
|
+
rawArgs: Record<string, unknown>,
|
|
87
|
+
opts: OmniSearchDispatchOpts = {},
|
|
79
88
|
): Promise<OmniSearchResult> {
|
|
80
89
|
const args = validate(rawArgs);
|
|
90
|
+
const selected = getAvailableResearchProviders();
|
|
91
|
+
const requested = args.engines === undefined ? undefined : new Set(args.engines.map(id => id.toLowerCase()));
|
|
92
|
+
const providers = requested === undefined
|
|
93
|
+
? selected
|
|
94
|
+
: selected.filter(provider => requested.has(provider.id.toLowerCase()));
|
|
95
|
+
return dispatchWithProviders(args, opts, providers, { grokTimeoutMs: RESEARCH_GROK_TIMEOUT_MS });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async function dispatchWithProviders(
|
|
99
|
+
args: OmniSearchArgs,
|
|
100
|
+
opts: OmniSearchDispatchOpts,
|
|
101
|
+
selectedProviders?: ReturnType<typeof getAvailableWebSearchProviders>,
|
|
102
|
+
researchLimits?: { grokTimeoutMs: number },
|
|
103
|
+
): Promise<OmniSearchResult> {
|
|
81
104
|
const merge = args.merge ?? 'interleave';
|
|
82
105
|
const limit = Math.max(1, Math.min(args.limit ?? DEFAULT_LIMIT, MAX_LIMIT));
|
|
83
106
|
|
|
84
|
-
let providers = getAvailableWebSearchProviders();
|
|
85
|
-
if (args.engines && args.engines.length > 0) {
|
|
107
|
+
let providers = selectedProviders ?? getAvailableWebSearchProviders();
|
|
108
|
+
if (!selectedProviders && args.engines && args.engines.length > 0) {
|
|
86
109
|
const wanted = new Set(args.engines.map(e => e.toLowerCase()));
|
|
87
110
|
providers = providers.filter(p => wanted.has(p.id.toLowerCase()));
|
|
88
111
|
}
|
|
@@ -105,13 +128,33 @@ export async function dispatchOmniSearch(
|
|
|
105
128
|
const start = Date.now();
|
|
106
129
|
emit({ engine: p.id, phase: 'start' });
|
|
107
130
|
try {
|
|
108
|
-
const
|
|
131
|
+
const query = {
|
|
109
132
|
query: args.query,
|
|
110
133
|
limit,
|
|
111
134
|
allowDomains: args.allow_domains,
|
|
112
135
|
blockDomains: args.block_domains,
|
|
113
136
|
recencyDays: args.recency_days,
|
|
114
|
-
}
|
|
137
|
+
};
|
|
138
|
+
let result;
|
|
139
|
+
if (researchLimits && (p.id === 'grok' || p.id === 'grok-api')) {
|
|
140
|
+
const controller = new AbortController();
|
|
141
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
142
|
+
try {
|
|
143
|
+
result = await Promise.race([
|
|
144
|
+
p.search(query, controller.signal),
|
|
145
|
+
new Promise<never>((_, reject) => {
|
|
146
|
+
timer = setTimeout(() => {
|
|
147
|
+
controller.abort();
|
|
148
|
+
reject(new DOMException(`Grok research search timed out after ${researchLimits.grokTimeoutMs}ms`, 'TimeoutError'));
|
|
149
|
+
}, researchLimits.grokTimeoutMs);
|
|
150
|
+
}),
|
|
151
|
+
]);
|
|
152
|
+
} finally {
|
|
153
|
+
if (timer !== undefined) clearTimeout(timer);
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
result = await p.search(query);
|
|
157
|
+
}
|
|
115
158
|
perEngine[p.id] = { hits: result.hits, durationMs: Date.now() - start };
|
|
116
159
|
for (const hit of result.hits) {
|
|
117
160
|
try {
|
|
@@ -165,11 +208,30 @@ export async function dispatchOmniSearch(
|
|
|
165
208
|
};
|
|
166
209
|
}
|
|
167
210
|
|
|
168
|
-
/** Probe-compatible: at least 2 search providers available. */
|
|
211
|
+
/** Probe-compatible: at least 2 search providers available for ordinary omni_search. */
|
|
169
212
|
export function omniSearchAvailable(): boolean {
|
|
170
213
|
return getAvailableWebSearchProviders().length >= 2;
|
|
171
214
|
}
|
|
172
215
|
|
|
216
|
+
/** Research-only probe: require the bounded Grok/Firecrawl research pair. */
|
|
217
|
+
export function researchOmniSearchAvailable(): boolean {
|
|
218
|
+
return getAvailableResearchProviders().length >= 2;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export function getAvailableResearchSearchEngineIds(): string[] {
|
|
222
|
+
return getAvailableResearchProviders().map(provider => provider.id);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function getAvailableResearchProviders(): ReturnType<typeof getAvailableWebSearchProviders> {
|
|
226
|
+
const available = getAvailableWebSearchProviders();
|
|
227
|
+
const grok = available.find(provider => provider.id === 'grok')
|
|
228
|
+
?? available.find(provider => provider.id === 'grok-api');
|
|
229
|
+
return [
|
|
230
|
+
...(grok ? [grok] : []),
|
|
231
|
+
...available.filter(provider => provider.id === 'firecrawl'),
|
|
232
|
+
];
|
|
233
|
+
}
|
|
234
|
+
|
|
173
235
|
function interleaveHits(perEngine: Record<string, { hits: WebSearchHit[] }>): WebSearchHit[] {
|
|
174
236
|
const lists = Object.values(perEngine).map(v => v.hits.slice());
|
|
175
237
|
const merged: WebSearchHit[] = [];
|
|
@@ -43,6 +43,17 @@ export type ParentHostSetting = Partial<ParentHostConfig> | readonly Partial<Par
|
|
|
43
43
|
export const PARENT_HOST_ENV = 'ELANOUS_TA_PARENT_HOST';
|
|
44
44
|
const DEFAULT_REMOTE_ELANOUS = '$HOME/.local/share/elanous/bin/elanous';
|
|
45
45
|
const DEFAULT_REMOTE_CONFIG_DIR = '$HOME/.elanous';
|
|
46
|
+
/**
|
|
47
|
+
* 원격 부모 상태 루트의 출처 태그 — 루트(`ELANOUS_STATE_DIR`)와 «한 벌»로 넘긴다(src/agent/identity-env.ts).
|
|
48
|
+
* HQ 가 git worktree/`--test` 라면 그 env 에 `derived` 가 실린다. 루트만 원격 값으로 바꾸고 태그를 그대로
|
|
49
|
+
* 흘리면 원격 부모는 «명시한 운영 루트 + 파생 태그»를 받아 자기 우주를 test 로 오독한다 —
|
|
50
|
+
* `SOURCE === 'derived'` 를 보는 codexCredentialRoot(src/budget/codex-reset-credit-state.ts)·
|
|
51
|
+
* harnessLaunchPolicyConfig(src/harness/harness-substrate-default.ts) 가 그 자리다.
|
|
52
|
+
* 떼어 띄운 운영 부모의 기존 꼴(src/task-orchestrator/surfaces/pod-si-warm-runner.ts)과 같은 `explicit` 를 찍는다.
|
|
53
|
+
*/
|
|
54
|
+
const REMOTE_STATE_DIR_SOURCE = 'explicit';
|
|
55
|
+
/** 원격 발사에서 HQ 값을 버리고 원격 기준으로 다시 찍는 상태 루트 env(한 벌). */
|
|
56
|
+
const STATE_ROOT_ENV_KEYS: ReadonlySet<string> = new Set(['ELANOUS_STATE_DIR', 'ELANOUS_STATE_DIR_SOURCE']);
|
|
46
57
|
const HOST_RE = /^[A-Za-z0-9][A-Za-z0-9._@-]{0,127}$/;
|
|
47
58
|
/** A parent can wait for a child for tens of minutes; the two-minute HTTP refresh floor is too short here. */
|
|
48
59
|
export const PARENT_CHILD_CREDENTIAL_MIN_REMAINING_MS = 60 * 60_000;
|
|
@@ -227,7 +238,9 @@ export function remoteLaunchScript(target: ParentHostConfig, args: readonly stri
|
|
|
227
238
|
const log = remoteParentLogPath(target, env.ELANOUS_RUN_ID ?? 'unknown');
|
|
228
239
|
// --config-dir keeps the parent's operational config/state; authStorePath()
|
|
229
240
|
// reads XDG_CONFIG_HOME/elanous/auth.json first, as the entrypoint test proves.
|
|
230
|
-
|
|
241
|
+
// 상태 루트는 태그와 한 벌로 넘긴다(REMOTE_STATE_DIR_SOURCE 주석) — HQ 의 derived 태그가
|
|
242
|
+
// 함께 흐르면 방금 명시한 운영 루트를 원격 부모가 test 우주로 오독한다.
|
|
243
|
+
const envPart = [...Object.entries(env).filter(([key]) => !STATE_ROOT_ENV_KEYS.has(key) && /^[A-Z_][A-Z0-9_]*$/.test(key)).map(([key, value]) => `${key}=${key === 'XDG_CONFIG_HOME' || key === 'CODEX_HOME' || key === 'GH_CONFIG_DIR' ? remotePath(value) : shellQuote(value)}`), `ELANOUS_STATE_DIR=${remotePath(configDir)}`, `ELANOUS_STATE_DIR_SOURCE=${shellQuote(REMOTE_STATE_DIR_SOURCE)}`].join(' ');
|
|
231
244
|
const argv = [remotePath(elanous), '--config-dir', remotePath(configDir), ...remoteParentArgs(args, target.podPool).map(shellQuote)].join(' ');
|
|
232
245
|
// 준비가 실패하면 «확실히 안 띄웠다»(not-launched=…)를 찍고 끝낸다 — 그때만 호출부가 로컬로 돌아간다.
|
|
233
246
|
// 띄운 뒤에는 짧게 살아 있는지 보고 pid 를 찍는다(조기 종료면 early-exit — 역시 «안 돈다»가 확실).
|