reeval 0.11.0 → 0.12.0
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 +3 -1
- package/bin/mcp-timer.cjs +224 -0
- package/dist/{adapter-Bwy3QxAK.js → adapter-DigeVFWC.js} +3 -3
- package/dist/{adapter-Bwy3QxAK.js.map → adapter-DigeVFWC.js.map} +1 -1
- package/dist/{agent-DpE80WPz.js → agent-CatUEo5h.js} +21 -6
- package/dist/{agent-DpE80WPz.js.map → agent-CatUEo5h.js.map} +1 -1
- package/dist/{assemble-D9GWr-HS.js → assemble-CF063ms6.js} +19 -17
- package/dist/assemble-CF063ms6.js.map +1 -0
- package/dist/assemble-CJoD_Rzr.js +1 -0
- package/dist/bridge/index.mjs +2 -1
- package/dist/{capture-BQlGHiMC.js → capture-BiD7lVaM.js} +25 -17
- package/dist/{capture-BQlGHiMC.js.map → capture-BiD7lVaM.js.map} +1 -1
- package/dist/capture-Dp3q7K7Y.js +1 -0
- package/dist/{cli-ClpPT8kn.js → cli-B5zQCR2r.js} +161 -116
- package/dist/cli-B5zQCR2r.js.map +1 -0
- package/dist/{cli-spec-qmEnQ25_.js → cli-spec-BXIBUlaK.js} +34 -15
- package/dist/cli-spec-BXIBUlaK.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/{command-TgbzPizb.js → command-BMHXHqMT.js} +15 -14
- package/dist/command-BMHXHqMT.js.map +1 -0
- package/dist/command-C94CQNh8.js +91 -0
- package/dist/command-C94CQNh8.js.map +1 -0
- package/dist/command-CVtgyqlM.js +335 -0
- package/dist/command-CVtgyqlM.js.map +1 -0
- package/dist/{command-DbAe1Rzb.js → command-CaZgCTIw.js} +14 -17
- package/dist/command-CaZgCTIw.js.map +1 -0
- package/dist/{command-BlM0y8jN.js → command-DTgBZR0k.js} +6 -6
- package/dist/{command-BlM0y8jN.js.map → command-DTgBZR0k.js.map} +1 -1
- package/dist/{commands-CthqwkAn.js → commands-BXzIDB3X.js} +1 -1
- package/dist/commands-CjpGBUWr.js +666 -0
- package/dist/commands-CjpGBUWr.js.map +1 -0
- package/dist/{config-DrVSEVN0.js → config-Dv5MG7Rp.js} +27 -48
- package/dist/config-Dv5MG7Rp.js.map +1 -0
- package/dist/{context-C1mxXh80.js → context-Dgn48BqT.js} +13 -2
- package/dist/context-Dgn48BqT.js.map +1 -0
- package/dist/{contrasts-5zsj32gk.js → contrasts-CcoMLC_y.js} +3 -3
- package/dist/{contrasts-5zsj32gk.js.map → contrasts-CcoMLC_y.js.map} +1 -1
- package/dist/db-BeqRiWLl.js +602 -0
- package/dist/db-BeqRiWLl.js.map +1 -0
- package/dist/db-CJDRVQal.js +2 -0
- package/dist/{dist-CuY4ehEk.js → dist-CMjp3qqF.js} +2 -2
- package/dist/{dist-CuY4ehEk.js.map → dist-CMjp3qqF.js.map} +1 -1
- package/dist/{docker-DOvjji9I.js → docker-BbTlMmYi.js} +2 -2
- package/dist/{docker-DOvjji9I.js.map → docker-BbTlMmYi.js.map} +1 -1
- package/dist/{docker-D1HZDS6q.js → docker-CCXdbREk.js} +20 -4
- package/dist/{docker-D1HZDS6q.js.map → docker-CCXdbREk.js.map} +1 -1
- package/dist/{docker-DNmMPOBb.js → docker-DC69dKxB.js} +1 -1
- package/dist/{doctor-D2MbNO8L.js → doctor-CqttrZcs.js} +57 -22
- package/dist/doctor-CqttrZcs.js.map +1 -0
- package/dist/{egress-2-qzPvGi.js → egress-BfK_O9ce.js} +435 -30
- package/dist/egress-BfK_O9ce.js.map +1 -0
- package/dist/env-BQqj93gu.js +21 -0
- package/dist/env-BQqj93gu.js.map +1 -0
- package/dist/{environment-Cca6a4wB.js → environment-BBz1Yes9.js} +224 -10
- package/dist/environment-BBz1Yes9.js.map +1 -0
- package/dist/{evaluate-DKIl54Hb.js → evaluate-CXQ1o-pd.js} +539 -559
- package/dist/evaluate-CXQ1o-pd.js.map +1 -0
- package/dist/{evaluate-DMyaGQEj.d.ts → evaluate-yjZKUexW.d.ts} +2 -2
- package/dist/facts-DtENlf9s.js +898 -0
- package/dist/facts-DtENlf9s.js.map +1 -0
- package/dist/{files-BpUYBwGu.js → files-B-eUpCZ1.js} +30 -7
- package/dist/files-B-eUpCZ1.js.map +1 -0
- package/dist/files-BsQbYz2i.js +65 -0
- package/dist/files-BsQbYz2i.js.map +1 -0
- package/dist/{files-BXHZFWmx.js → files-COHQLEHE.js} +6 -17
- package/dist/files-COHQLEHE.js.map +1 -0
- package/dist/files-DqCBW7i8.js +1 -0
- package/dist/files-Ha-jsQXf.js +1 -0
- package/dist/generate-Cs2TMH_k.js +1647 -0
- package/dist/generate-Cs2TMH_k.js.map +1 -0
- package/dist/{git-Crl3b87o.js → git-DhykwgKF.js} +2 -2
- package/dist/{git-Crl3b87o.js.map → git-DhykwgKF.js.map} +1 -1
- package/dist/{harness-CEuntrla.js → harness-BAjw1fcr.js} +2 -2
- package/dist/{harness-CEuntrla.js.map → harness-BAjw1fcr.js.map} +1 -1
- package/dist/harness.d.ts +1 -1
- package/dist/harness.js +1 -1
- package/dist/{header-DHQv_ZrF.js → header-kSmWatcO.js} +10 -3
- package/dist/{header-DHQv_ZrF.js.map → header-kSmWatcO.js.map} +1 -1
- package/dist/{images-Bi3aGxb9.js → images-BmJRuTpm.js} +61 -13
- package/dist/images-BmJRuTpm.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4 -4
- package/dist/init-Bwc9byQr.js +543 -0
- package/dist/init-Bwc9byQr.js.map +1 -0
- package/dist/init-D7Y1ny1z.js +1 -0
- package/dist/insights-B2Xmhz9o.js +64 -0
- package/dist/insights-B2Xmhz9o.js.map +1 -0
- package/dist/{invocations-BYDPe3fV.js → invocations-CQTbP092.js} +3 -3
- package/dist/{invocations-BYDPe3fV.js.map → invocations-CQTbP092.js.map} +1 -1
- package/dist/{judge-DW_GDOmB.js → judge-Dt6KW6_O.js} +5 -3
- package/dist/judge-Dt6KW6_O.js.map +1 -0
- package/dist/judge.d.ts +7 -6
- package/dist/judge.js +8 -7
- package/dist/judge.js.map +1 -1
- package/dist/{live-jlfszAbb.js → live-DYd2QEyR.js} +2 -2
- package/dist/{live-jlfszAbb.js.map → live-DYd2QEyR.js.map} +1 -1
- package/dist/{model-D0IcOQao.js → model-B-mel-Gv.js} +43 -18
- package/dist/model-B-mel-Gv.js.map +1 -0
- package/dist/model-BGKYVpoj.js +1 -0
- package/dist/{model-DaVCY3rb.js → model-C7tSwT7f.js} +2 -2
- package/dist/{model-DaVCY3rb.js.map → model-C7tSwT7f.js.map} +1 -1
- package/dist/{model-DaX4bNLZ.js → model-CWlAqmbU.js} +135 -40
- package/dist/model-CWlAqmbU.js.map +1 -0
- package/dist/model-DHY-dfoO.js +1 -0
- package/dist/{node-B3ydHo6t.js → node-D0mtjRAO.js} +3 -3
- package/dist/{node-B3ydHo6t.js.map → node-D0mtjRAO.js.map} +1 -1
- package/dist/{options-C0d0AzeR.js → options-CPUW97_7.js} +7 -9
- package/dist/options-CPUW97_7.js.map +1 -0
- package/dist/{pairs-CnInRu-G.js → pairs-DP6XOJby.js} +2 -2
- package/dist/{pairs-CnInRu-G.js.map → pairs-DP6XOJby.js.map} +1 -1
- package/dist/{patch-B1bnfhN-.js → patch-D4oluWzH.js} +2 -2
- package/dist/{patch-B1bnfhN-.js.map → patch-D4oluWzH.js.map} +1 -1
- package/dist/{plan-DgQxp9yy.js → plan-OkwUcJQ9.js} +21 -8
- package/dist/plan-OkwUcJQ9.js.map +1 -0
- package/dist/plugins-CUWMnSNb.js +654 -0
- package/dist/plugins-CUWMnSNb.js.map +1 -0
- package/dist/{preflight-DlQvbySb.js → preflight-B6pY89bF.js} +1 -1
- package/dist/{preflight-BRzD30L5.js → preflight-Bjm7_ylE.js} +14 -10
- package/dist/preflight-Bjm7_ylE.js.map +1 -0
- package/dist/{prepare-B_y-AFMv.js → prepare-CQmK3SBn.js} +70 -23
- package/dist/prepare-CQmK3SBn.js.map +1 -0
- package/dist/prepare-DbdgtZKe.js +2 -0
- package/dist/{provenance-DQ0AXn6c.js → provenance-B3Y17oCC.js} +3 -3
- package/dist/{provenance-DQ0AXn6c.js.map → provenance-B3Y17oCC.js.map} +1 -1
- package/dist/providers-CXN2RFz-.js +1 -0
- package/dist/{providers-DoTq1jHW.js → providers-eoniqK6w.js} +24 -10
- package/dist/providers-eoniqK6w.js.map +1 -0
- package/dist/{query-BO-ux7RB.js → query-CLRZmWBT.js} +3 -3
- package/dist/{query-BO-ux7RB.js.map → query-CLRZmWBT.js.map} +1 -1
- package/dist/query-CmBDYt0_.js +1 -0
- package/dist/{questions-C2dym2ce.js → questions-1XOulevV.js} +6 -6
- package/dist/{questions-C2dym2ce.js.map → questions-1XOulevV.js.map} +1 -1
- package/dist/{record-BKmMvZ6O.js → record-kk9M1hj-.js} +8 -4
- package/dist/record-kk9M1hj-.js.map +1 -0
- package/dist/remarks-1521zwfW.js +38 -0
- package/dist/remarks-1521zwfW.js.map +1 -0
- package/dist/remarks-BhAV1H4V.js +1 -0
- package/dist/remarks-DlJCqWRs.js +278 -0
- package/dist/remarks-DlJCqWRs.js.map +1 -0
- package/dist/{remote-CPPW86Q9.js → remote-cE2VWfkJ.js} +3 -3
- package/dist/{remote-CPPW86Q9.js.map → remote-cE2VWfkJ.js.map} +1 -1
- package/dist/resolve-C4zeccCH.js +724 -0
- package/dist/resolve-C4zeccCH.js.map +1 -0
- package/dist/resolve-D30yZYmB.js +1 -0
- package/dist/{results-BE2f-1XS.js → results-Drtt0uFl.js} +33 -8
- package/dist/results-Drtt0uFl.js.map +1 -0
- package/dist/{resume-Ca1c8vix.js → resume-BEFazUfy.js} +4 -4
- package/dist/{resume-Ca1c8vix.js.map → resume-BEFazUfy.js.map} +1 -1
- package/dist/rules-BFzQqPIm.js +317 -0
- package/dist/rules-BFzQqPIm.js.map +1 -0
- package/dist/run-BeMy92Us.js +88 -0
- package/dist/run-BeMy92Us.js.map +1 -0
- package/dist/{sandbox-DLrsvu7U.js → sandbox-CQaJj7n9.js} +2 -2
- package/dist/{sandbox-DLrsvu7U.js.map → sandbox-CQaJj7n9.js.map} +1 -1
- package/dist/sandbox.d.ts +1 -1
- package/dist/sandbox.js +1 -1
- package/dist/server-V4-2w0l8.js +1 -0
- package/dist/{server-TUY5xA_A.js → server-xK0les4f.js} +8 -8
- package/dist/{server-TUY5xA_A.js.map → server-xK0les4f.js.map} +1 -1
- package/dist/source-BDow_oW8.js +1 -0
- package/dist/{source-DJGS0a0u.js → source-Q1hEKbCs.js} +2 -2
- package/dist/{source-DJGS0a0u.js.map → source-Q1hEKbCs.js.map} +1 -1
- package/dist/src-B9L9yGKI.js +1 -0
- package/dist/{src-CLoOMVWI.js → src-Bcah6ZkT.js} +1 -1
- package/dist/{src-DvCg0NBs.js → src-BhmaorOU.js} +28 -6
- package/dist/{src-DvCg0NBs.js.map → src-BhmaorOU.js.map} +1 -1
- package/dist/{src-CF17Ug08.js → src-C0CeKiLU.js} +19 -4
- package/dist/{src-CF17Ug08.js.map → src-C0CeKiLU.js.map} +1 -1
- package/dist/src-C0xowZ3C.js +2 -0
- package/dist/src-CHIfIKUu.js +2 -0
- package/dist/src-DLtyz4w5.js +2 -0
- package/dist/src-DPIjmReZ.js +2 -0
- package/dist/{src-BxfCKA3_.js → src-DXNh5mTr.js} +1 -1
- package/dist/{src-FGXhkEkH.js → src-DiLMkIr9.js} +142 -13
- package/dist/src-DiLMkIr9.js.map +1 -0
- package/dist/{src-ftu5wPSt.js → src-LekQrr_S.js} +209 -29
- package/dist/src-LekQrr_S.js.map +1 -0
- package/dist/src-bCnsA6Vp.js +2 -0
- package/dist/{src-u8_ixn_F.js → src-cbCb-MPy.js} +20 -4
- package/dist/src-cbCb-MPy.js.map +1 -0
- package/dist/{src-DvK0EIZx.js → src-qGoFkuJF.js} +55 -6
- package/dist/{src-DvK0EIZx.js.map → src-qGoFkuJF.js.map} +1 -1
- package/dist/{src-DSYYPEOj.js → src-ynBVosfX.js} +1 -1
- package/dist/state-BQR_BCm4.js +1 -0
- package/dist/{state-DfpHox6b.js → state-BmZ8QVZ8.js} +12 -12
- package/dist/{state-DfpHox6b.js.map → state-BmZ8QVZ8.js.map} +1 -1
- package/dist/studio-app/assets/{index-CBkhNAv8.js → index-CnYJijyI.js} +9 -9
- package/dist/studio-app/index.html +1 -1
- package/dist/suite-BaHPmAGy.js +1 -0
- package/dist/{suite-Cw_7G2RM.js → suite-C8sw2pox.js} +80 -28
- package/dist/suite-C8sw2pox.js.map +1 -0
- package/dist/{summary-BUKfU-9l.js → summary-0oQNGskv.js} +273 -47
- package/dist/summary-0oQNGskv.js.map +1 -0
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +2 -2
- package/dist/{text-gEcKjAyp.js → text-CrVy5ioL.js} +18 -2
- package/dist/text-CrVy5ioL.js.map +1 -0
- package/dist/{transcript-BNNANU8A.js → transcript-BTxJpW4R.js} +2 -2
- package/dist/{transcript-BNNANU8A.js.map → transcript-BTxJpW4R.js.map} +1 -1
- package/dist/types-C5vI3g1C.js.map +1 -1
- package/dist/{types-BYdlwMwo.d.ts → types-GraZtfHN.d.ts} +848 -34
- package/dist/usage-BDo2q_yu.js +1 -0
- package/dist/{command-Bj39y-Wm.js → validate-BdoXUuL_.js} +15 -372
- package/dist/validate-BdoXUuL_.js.map +1 -0
- package/dist/view/index.d.ts +20 -257
- package/dist/view/index.js +7 -6
- package/dist/{views-B8w2J-gD.js → views-BoUoX4_A.js} +8 -98
- package/dist/views-BoUoX4_A.js.map +1 -0
- package/dist/views-noVQNCUP.js +2 -0
- package/dist/{worker-entry-DNnveLqx.js → worker-entry-D0-GErmU.js} +2 -2
- package/dist/{worker-entry-DNnveLqx.js.map → worker-entry-D0-GErmU.js.map} +1 -1
- package/dist/{workspace-C_X0tdv6.js → workspace-B90YDU_a.js} +1 -1
- package/dist/{workspace-C4RA3srV.js → workspace-tjZFkjxC.js} +4 -4
- package/dist/{workspace-C4RA3srV.js.map → workspace-tjZFkjxC.js.map} +1 -1
- package/package.json +3 -1
- package/skills/eval-rubric/SKILL.md +130 -0
- package/dist/agent-D483ru7D.js +0 -334
- package/dist/agent-D483ru7D.js.map +0 -1
- package/dist/assemble-D5KGrwnJ.js +0 -1
- package/dist/assemble-D9GWr-HS.js.map +0 -1
- package/dist/capture-CYGLpWxR.js +0 -1
- package/dist/cli-ClpPT8kn.js.map +0 -1
- package/dist/cli-spec-qmEnQ25_.js.map +0 -1
- package/dist/command-Bj39y-Wm.js.map +0 -1
- package/dist/command-C-cVjlny.js +0 -1
- package/dist/command-DbAe1Rzb.js.map +0 -1
- package/dist/command-TgbzPizb.js.map +0 -1
- package/dist/commands-YUwlyTbr.js +0 -228
- package/dist/commands-YUwlyTbr.js.map +0 -1
- package/dist/config-DrVSEVN0.js.map +0 -1
- package/dist/context-C1mxXh80.js.map +0 -1
- package/dist/db-CKg5NtiW.js +0 -2
- package/dist/db-DfhipHEF.js +0 -1416
- package/dist/db-DfhipHEF.js.map +0 -1
- package/dist/doctor-D2MbNO8L.js.map +0 -1
- package/dist/egress-2-qzPvGi.js.map +0 -1
- package/dist/environment-Cca6a4wB.js.map +0 -1
- package/dist/evaluate-DKIl54Hb.js.map +0 -1
- package/dist/files-BXHZFWmx.js.map +0 -1
- package/dist/files-BpUYBwGu.js.map +0 -1
- package/dist/files-Bw8lWEjg.js +0 -1
- package/dist/files-D6J0iSdx.js +0 -1
- package/dist/images-Bi3aGxb9.js.map +0 -1
- package/dist/init-Cl3f3NBT.js +0 -360
- package/dist/init-Cl3f3NBT.js.map +0 -1
- package/dist/init-fhOXED8F.js +0 -1
- package/dist/judge-DW_GDOmB.js.map +0 -1
- package/dist/model-CXhrziBe.js +0 -1
- package/dist/model-D0IcOQao.js.map +0 -1
- package/dist/model-DaX4bNLZ.js.map +0 -1
- package/dist/model-_bxNrk2h.js +0 -1
- package/dist/options-C0d0AzeR.js.map +0 -1
- package/dist/plan-DgQxp9yy.js.map +0 -1
- package/dist/preflight-BRzD30L5.js.map +0 -1
- package/dist/prepare-B_y-AFMv.js.map +0 -1
- package/dist/prepare-DCKTLHN3.js +0 -2
- package/dist/providers-B9yTdIqF.js +0 -1
- package/dist/providers-DoTq1jHW.js.map +0 -1
- package/dist/query-CRQfsw0e.js +0 -1
- package/dist/record-BKmMvZ6O.js.map +0 -1
- package/dist/results-BE2f-1XS.js.map +0 -1
- package/dist/server-Dp8eOeK5.js +0 -1
- package/dist/source-DdbLGR1M.js +0 -1
- package/dist/src-CcrQbpG8.js +0 -2
- package/dist/src-DCFtJRp0.js +0 -2
- package/dist/src-DYO3DdnQ.js +0 -1
- package/dist/src-FGXhkEkH.js.map +0 -1
- package/dist/src-WD-zgQYZ.js +0 -2
- package/dist/src-_oI9AePb.js +0 -2
- package/dist/src-ftu5wPSt.js.map +0 -1
- package/dist/src-qsKCqv7a.js +0 -2
- package/dist/src-u8_ixn_F.js.map +0 -1
- package/dist/state-DpAxYyED.js +0 -1
- package/dist/suite-Cw_7G2RM.js.map +0 -1
- package/dist/suite-DamAEnNF.js +0 -1
- package/dist/summary-BUKfU-9l.js.map +0 -1
- package/dist/summary-Baa4rTHS.js +0 -192
- package/dist/summary-Baa4rTHS.js.map +0 -1
- package/dist/text-gEcKjAyp.js.map +0 -1
- package/dist/tools-DLHgetpx.js +0 -249
- package/dist/tools-DLHgetpx.js.map +0 -1
- package/dist/views-B8w2J-gD.js.map +0 -1
- package/dist/views-DblnI3kA.js +0 -2
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { n as UsageError } from "./errors-B6BSMs03.js";
|
|
2
|
-
import { w as plannedSecrets } from "./environment-
|
|
2
|
+
import { w as plannedSecrets } from "./environment-BBz1Yes9.js";
|
|
3
|
+
import { F as PACKAGE_HOSTS, N as DOCKER_EGRESS, P as HARNESS_HOSTS, lt as run, ut as shellQuote } from "./src-LekQrr_S.js";
|
|
4
|
+
import { D as pluginServerName, a as PLUGIN_PARTS, n as PLUGIN_DIR, r as PLUGIN_MANIFEST, t as PART_PATHS, y as localPluginServers } from "./plugins-CUWMnSNb.js";
|
|
3
5
|
import { a as providerServedModel, i as providerModelResponses, n as providerEndpoints, r as providerHosts, s as resolveOpenCodeProvider } from "./opencode-providers-J9colP0-.js";
|
|
4
6
|
import { t as InfraError } from "./types-C5vI3g1C.js";
|
|
5
|
-
import { D as HARNESS_HOSTS, E as DOCKER_EGRESS, O as PACKAGE_HOSTS, nt as shellQuote, tt as run } from "./src-ftu5wPSt.js";
|
|
6
7
|
import { existsSync } from "node:fs";
|
|
7
8
|
import { tmpdir } from "node:os";
|
|
8
9
|
import { dirname, join, win32 } from "node:path";
|
|
@@ -164,8 +165,20 @@ function opencodeMcpServers(servers) {
|
|
|
164
165
|
}];
|
|
165
166
|
}));
|
|
166
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* The key Goose keeps an extension by (its `name_to_key`): whitespace dropped, anything but ASCII
|
|
170
|
+
* letters, digits, `_` and `-` made `_`, lower-cased. Of two extensions with one key it keeps one.
|
|
171
|
+
*/
|
|
172
|
+
const gooseKey = (name) => name.replace(/\s/g, "").replace(/[^A-Za-z0-9_-]/g, "_").toLowerCase();
|
|
167
173
|
/** Goose's extension shape (its `config.yaml`); it has no SSE transport. */
|
|
168
174
|
function gooseMcpServers(servers) {
|
|
175
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
176
|
+
for (const name of Object.keys(servers)) {
|
|
177
|
+
const key = gooseKey(name);
|
|
178
|
+
const other = byKey.get(key);
|
|
179
|
+
if (other !== void 0) throw new InfraError(`Goose keys the ${other} and ${name} MCP servers both as ${key}, and keeps only one: rename one`);
|
|
180
|
+
byKey.set(key, name);
|
|
181
|
+
}
|
|
169
182
|
return Object.fromEntries(Object.entries(servers).map(([name, s]) => {
|
|
170
183
|
if (s.transport === "sse") throw new InfraError(`Goose has no SSE MCP transport, so it can't use the ${name} server (mcp.sse): use mcp.http or mcp.stdio`);
|
|
171
184
|
return s.transport === "stdio" ? [name, {
|
|
@@ -183,11 +196,18 @@ function gooseMcpServers(servers) {
|
|
|
183
196
|
/**
|
|
184
197
|
* pi's `mcp.json` shape, which the adapter escapes and sets `"exposure": "direct"` on. pi
|
|
185
198
|
* skips a server whose name isn't letters, digits, `_` and `-`, so the plan refuses it instead.
|
|
199
|
+
* A plugin's server, `<plugin>:<server>`, is named `<plugin>_<server>`, so its tools are
|
|
200
|
+
* `mcp__<plugin>_<server>__<tool>`.
|
|
186
201
|
*/
|
|
187
202
|
function piMcpServers(servers) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
203
|
+
const named = /* @__PURE__ */ new Map();
|
|
204
|
+
return Object.fromEntries(Object.entries(servers).map(([key, s]) => {
|
|
205
|
+
const name = /^[a-z0-9-]+:[^:]+$/.test(key) ? key.replace(":", "_") : key;
|
|
206
|
+
if (!/^[A-Za-z0-9_-]+$/.test(name)) throw new InfraError(`pi takes MCP server names of letters, digits, "_" and "-" only, so it can't use the ${key} server: rename it`);
|
|
207
|
+
const other = named.get(name);
|
|
208
|
+
if (other) throw new InfraError(`pi names the ${key} MCP server ${name}, as it does the ${other} server, and keeps only one: rename one`);
|
|
209
|
+
named.set(name, key);
|
|
210
|
+
if (s.transport === "sse") throw new InfraError(`pi has no SSE MCP transport, so it can't use the ${key} server (mcp.sse): use mcp.http or mcp.stdio`);
|
|
191
211
|
return s.transport === "stdio" ? [name, {
|
|
192
212
|
command: s.command,
|
|
193
213
|
args: s.args,
|
|
@@ -270,58 +290,236 @@ function cursorMcpServers(servers) {
|
|
|
270
290
|
headers: s.headers
|
|
271
291
|
}]));
|
|
272
292
|
}
|
|
293
|
+
/** Claude Code's hook events as Cursor names them, as the Cursor SDK converts Claude Code's own. */
|
|
294
|
+
const CURSOR_HOOK_EVENTS = {
|
|
295
|
+
SessionStart: "sessionStart",
|
|
296
|
+
SessionEnd: "sessionEnd",
|
|
297
|
+
UserPromptSubmit: "beforeSubmitPrompt",
|
|
298
|
+
PreToolUse: "preToolUse",
|
|
299
|
+
PostToolUse: "postToolUse",
|
|
300
|
+
SubagentStop: "subagentStop",
|
|
301
|
+
PreCompact: "preCompact",
|
|
302
|
+
Stop: "stop"
|
|
303
|
+
};
|
|
304
|
+
/** Claude Code's tool names as Cursor's hooks match them; null for one Cursor has no tool for. */
|
|
305
|
+
const CURSOR_HOOK_TOOLS = {
|
|
306
|
+
Bash: "Shell",
|
|
307
|
+
Read: "Read",
|
|
308
|
+
Write: "Write",
|
|
309
|
+
Edit: "Write",
|
|
310
|
+
Glob: null,
|
|
311
|
+
Grep: "Grep",
|
|
312
|
+
WebFetch: "WebFetch",
|
|
313
|
+
WebSearch: "WebSearch",
|
|
314
|
+
Task: "Task"
|
|
315
|
+
};
|
|
316
|
+
/**
|
|
317
|
+
* A Claude Code hook group's tool matcher as Cursor's, on the tool events only: each name mapped,
|
|
318
|
+
* `mcp__<server>__<tool>` as `MCP:<tool>`; null when it names only tools Cursor lacks.
|
|
319
|
+
*/
|
|
320
|
+
function cursorHookMatcher(event, matcher) {
|
|
321
|
+
if (event !== "PreToolUse" && event !== "PostToolUse") return void 0;
|
|
322
|
+
if (!matcher || matcher === "*") return void 0;
|
|
323
|
+
const out = [];
|
|
324
|
+
for (const raw of matcher.split("|")) {
|
|
325
|
+
const name = raw.trim();
|
|
326
|
+
const parts = name.split("__");
|
|
327
|
+
const tool = name.startsWith("mcp__") && parts.length >= 3 ? `MCP:${parts.slice(2).join("__")}` : CURSOR_HOOK_TOOLS[name] === void 0 ? name : CURSOR_HOOK_TOOLS[name];
|
|
328
|
+
if (tool && !out.includes(tool)) out.push(tool);
|
|
329
|
+
}
|
|
330
|
+
return out.length ? out.join("|") : null;
|
|
331
|
+
}
|
|
332
|
+
/** Where Cursor reads what reeval unpacks from a plugin, in the workspace (settingSources `project`). */
|
|
333
|
+
const CURSOR_PLUGIN_UNPACK = {
|
|
334
|
+
rules: ".cursor/rules",
|
|
335
|
+
agents: ".cursor/agents",
|
|
336
|
+
commands: ".cursor/commands",
|
|
337
|
+
hooks: {
|
|
338
|
+
file: ".cursor/hooks.json",
|
|
339
|
+
events: CURSOR_HOOK_EVENTS,
|
|
340
|
+
matcher: cursorHookMatcher
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
/**
|
|
344
|
+
* A plugin subagent's or command's frontmatter as OpenCode 2 takes it: the description, and a
|
|
345
|
+
* subagent's `mode`. OpenCode skips a file whose frontmatter its schema refuses, without saying,
|
|
346
|
+
* and Claude Code's `tools: Read, Grep`, `model: sonnet` and `allowed-tools` are such keys.
|
|
347
|
+
*/
|
|
348
|
+
function opencodeFrontmatter(part, front) {
|
|
349
|
+
const d = front.description;
|
|
350
|
+
const description = typeof d === "string" || typeof d === "number" || typeof d === "boolean" ? String(d) : void 0;
|
|
351
|
+
return {
|
|
352
|
+
...description ? { description } : {},
|
|
353
|
+
...part === "agents" ? { mode: "subagent" } : {}
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
/** Where OpenCode reads plugin subagents and commands, in the workspace's config directory. */
|
|
357
|
+
const OPENCODE_PLUGIN_UNPACK = {
|
|
358
|
+
agents: ".opencode/agents",
|
|
359
|
+
commands: ".opencode/commands",
|
|
360
|
+
frontmatter: opencodeFrontmatter
|
|
361
|
+
};
|
|
362
|
+
/**
|
|
363
|
+
* Where pi reads plugin commands, as prompt templates (`/<name>`), in the workspace, which its
|
|
364
|
+
* `--approve` trusts. Its frontmatter takes `description` and `argument-hint`, and ignores the
|
|
365
|
+
* rest of Claude Code's.
|
|
366
|
+
*/
|
|
367
|
+
const PI_PLUGIN_UNPACK = { commands: ".pi/prompts" };
|
|
368
|
+
/**
|
|
369
|
+
* What Claude Code's plugin format bundles, which Grok Build reads too: every part but rules,
|
|
370
|
+
* which neither loads from a plugin.
|
|
371
|
+
*/
|
|
372
|
+
const CLAUDE_FORMAT_PARTS = PLUGIN_PARTS.filter((p) => p !== "rules");
|
|
373
|
+
/** The marketplace Claude Code's settings name for the session's plugins. */
|
|
374
|
+
const CLAUDE_PLUGIN_MARKETPLACE = "reeval";
|
|
375
|
+
/**
|
|
376
|
+
* Claude Code's settings for the session's plugins: a `directory` marketplace at the directory
|
|
377
|
+
* they were copied to, listing each, and each enabled as `<plugin>@reeval`. Claude Code installs
|
|
378
|
+
* and loads them as it starts, since the bridge leaves every settings source on.
|
|
379
|
+
*/
|
|
380
|
+
function claudePluginFiles(plugins) {
|
|
381
|
+
const [first] = plugins;
|
|
382
|
+
if (!first) return [];
|
|
383
|
+
const json = (value) => `${JSON.stringify(value, null, 2)}\n`;
|
|
384
|
+
const marketplace = {
|
|
385
|
+
name: CLAUDE_PLUGIN_MARKETPLACE,
|
|
386
|
+
owner: { name: "reeval" },
|
|
387
|
+
plugins: plugins.map((p) => ({
|
|
388
|
+
name: p.name,
|
|
389
|
+
source: `./${p.name}`
|
|
390
|
+
}))
|
|
391
|
+
};
|
|
392
|
+
const settings = {
|
|
393
|
+
extraKnownMarketplaces: { [CLAUDE_PLUGIN_MARKETPLACE]: { source: {
|
|
394
|
+
source: "directory",
|
|
395
|
+
path: first.dir.slice(0, first.dir.lastIndexOf("/"))
|
|
396
|
+
} } },
|
|
397
|
+
enabledPlugins: Object.fromEntries(plugins.map((p) => [`${p.name}@${CLAUDE_PLUGIN_MARKETPLACE}`, true]))
|
|
398
|
+
};
|
|
399
|
+
return [{
|
|
400
|
+
path: `${PLUGIN_DIR}/.claude-plugin/marketplace.json`,
|
|
401
|
+
content: json(marketplace)
|
|
402
|
+
}, {
|
|
403
|
+
path: "~/.claude/settings.json",
|
|
404
|
+
content: json(settings),
|
|
405
|
+
merge: true
|
|
406
|
+
}];
|
|
407
|
+
}
|
|
408
|
+
const isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
409
|
+
/**
|
|
410
|
+
* Writes the layout's plugin files into the sandbox and returns their paths. A `merge` file's keys
|
|
411
|
+
* go into the JSON object already at its path (an object-valued key merged one level down), so
|
|
412
|
+
* settings an environment's `files` wrote there stay.
|
|
413
|
+
*/
|
|
414
|
+
async function writePluginFiles(sandbox, layout, plugins) {
|
|
415
|
+
const written = [];
|
|
416
|
+
for (const f of layout.pluginFiles?.(plugins) ?? []) {
|
|
417
|
+
const existing = f.merge ? await sandbox.readFile(f.path) : null;
|
|
418
|
+
let content = f.content;
|
|
419
|
+
if (existing?.trim()) {
|
|
420
|
+
let base;
|
|
421
|
+
try {
|
|
422
|
+
base = JSON.parse(existing);
|
|
423
|
+
} catch {}
|
|
424
|
+
if (!isObject(base)) throw new InfraError(`${f.path} isn't a JSON object, so reeval can't enable the session's plugins in it: write it as one in files, or leave it out`);
|
|
425
|
+
const ours = JSON.parse(f.content);
|
|
426
|
+
const merged = { ...base };
|
|
427
|
+
for (const [k, v] of Object.entries(ours)) {
|
|
428
|
+
const was = base[k];
|
|
429
|
+
merged[k] = isObject(v) && isObject(was) ? {
|
|
430
|
+
...was,
|
|
431
|
+
...v
|
|
432
|
+
} : v;
|
|
433
|
+
}
|
|
434
|
+
content = `${JSON.stringify(merged, null, 2)}\n`;
|
|
435
|
+
}
|
|
436
|
+
await sandbox.writeFile(f.path, content);
|
|
437
|
+
written.push(f.path);
|
|
438
|
+
}
|
|
439
|
+
return written;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* The MCP servers the agent is given: all of them, less the plugins' own where it takes plugin
|
|
443
|
+
* items namespaced, since it loads those from the plugin and would otherwise start each twice.
|
|
444
|
+
*/
|
|
445
|
+
function agentMcp(layout, mcp, plugins) {
|
|
446
|
+
if (layout.pluginPlacement !== "namespaced") return mcp;
|
|
447
|
+
const own = new Set(plugins.flatMap((p) => p.servers));
|
|
448
|
+
return Object.fromEntries(Object.entries(mcp).filter(([name]) => !own.has(name)));
|
|
449
|
+
}
|
|
273
450
|
/** Where each agent with an image reads rules and skills. */
|
|
274
451
|
const LAYOUTS = {
|
|
275
452
|
cursor: {
|
|
276
453
|
rulesFile: "AGENTS.md",
|
|
277
454
|
workspaceSkillDir: ".cursor/skills",
|
|
278
|
-
harnessSkillDir: ".agents/skills"
|
|
455
|
+
harnessSkillDir: ".agents/skills",
|
|
456
|
+
pluginPlacement: "flat",
|
|
457
|
+
pluginUnpack: CURSOR_PLUGIN_UNPACK,
|
|
458
|
+
pluginHookEvents: Object.keys(CURSOR_HOOK_EVENTS)
|
|
279
459
|
},
|
|
280
460
|
"claude-code": {
|
|
281
461
|
rulesFile: "CLAUDE.md",
|
|
282
462
|
workspaceSkillDir: ".claude/skills",
|
|
283
|
-
harnessSkillDir: ".claude/skills"
|
|
463
|
+
harnessSkillDir: ".claude/skills",
|
|
464
|
+
pluginPlacement: "namespaced",
|
|
465
|
+
pluginFiles: claudePluginFiles
|
|
284
466
|
},
|
|
285
467
|
antigravity: {
|
|
286
468
|
rulesFile: "AGENTS.md",
|
|
287
469
|
workspaceSkillDir: ".agents/skills",
|
|
288
|
-
harnessSkillDir: ".gemini/config/skills"
|
|
470
|
+
harnessSkillDir: ".gemini/config/skills",
|
|
471
|
+
pluginPlacement: "namespaced",
|
|
472
|
+
pluginHookEvents: [
|
|
473
|
+
"SessionStart",
|
|
474
|
+
"PreToolUse",
|
|
475
|
+
"PostToolUse",
|
|
476
|
+
"Stop"
|
|
477
|
+
]
|
|
289
478
|
},
|
|
290
479
|
opencode: {
|
|
291
480
|
rulesFile: "AGENTS.md",
|
|
292
481
|
workspaceSkillDir: ".opencode/skills",
|
|
293
|
-
harnessSkillDir: ".config/opencode/skills"
|
|
482
|
+
harnessSkillDir: ".config/opencode/skills",
|
|
483
|
+
pluginPlacement: "flat",
|
|
484
|
+
pluginUnpack: OPENCODE_PLUGIN_UNPACK
|
|
294
485
|
},
|
|
295
486
|
goose: {
|
|
296
487
|
rulesFile: "AGENTS.md",
|
|
297
488
|
workspaceSkillDir: ".goose/skills",
|
|
298
|
-
harnessSkillDir: ".ai-sdk-harness/.harness-bootstrap/goose/implementation/home/.config/goose/skills"
|
|
489
|
+
harnessSkillDir: ".ai-sdk-harness/.harness-bootstrap/goose/implementation/home/.config/goose/skills",
|
|
490
|
+
pluginPlacement: "flat"
|
|
299
491
|
},
|
|
300
492
|
pi: {
|
|
301
493
|
rulesFile: "AGENTS.md",
|
|
302
494
|
workspaceSkillDir: ".pi/skills",
|
|
303
|
-
harnessSkillDir: ".pi/agent/skills"
|
|
495
|
+
harnessSkillDir: ".pi/agent/skills",
|
|
496
|
+
pluginPlacement: "flat",
|
|
497
|
+
pluginUnpack: PI_PLUGIN_UNPACK
|
|
304
498
|
},
|
|
305
499
|
codex: {
|
|
306
500
|
rulesFile: "AGENTS.md",
|
|
307
501
|
workspaceSkillDir: ".agents/skills",
|
|
308
|
-
harnessSkillDir: ".agents/skills"
|
|
502
|
+
harnessSkillDir: ".agents/skills",
|
|
503
|
+
pluginPlacement: "namespaced"
|
|
309
504
|
},
|
|
310
505
|
fx: {
|
|
311
506
|
rulesFile: "AGENTS.md",
|
|
312
507
|
workspaceSkillDir: ".fx/skills",
|
|
313
|
-
harnessSkillDir: ".ai-sdk-harness/.harness-bootstrap/fx/implementation/home/.fx/skills"
|
|
508
|
+
harnessSkillDir: ".ai-sdk-harness/.harness-bootstrap/fx/implementation/home/.fx/skills",
|
|
509
|
+
pluginPlacement: "flat"
|
|
314
510
|
},
|
|
315
511
|
"grok-build": {
|
|
316
512
|
rulesFile: "AGENTS.md",
|
|
317
513
|
workspaceSkillDir: ".grok/skills",
|
|
318
|
-
harnessSkillDir: ".ai-sdk-harness/.harness-bootstrap/grok-build/implementation/home/.grok/skills"
|
|
514
|
+
harnessSkillDir: ".ai-sdk-harness/.harness-bootstrap/grok-build/implementation/home/.grok/skills",
|
|
515
|
+
pluginPlacement: "namespaced"
|
|
319
516
|
}
|
|
320
517
|
};
|
|
321
518
|
/** Every real agent reeval can drive, by harness kind. */
|
|
322
519
|
const AGENTS = {
|
|
323
520
|
cursor: {
|
|
324
521
|
...LAYOUTS.cursor,
|
|
522
|
+
pluginParts: PLUGIN_PARTS,
|
|
325
523
|
name: "Cursor",
|
|
326
524
|
factory: "cursor",
|
|
327
525
|
credential: "CURSOR_API_KEY",
|
|
@@ -333,7 +531,7 @@ const AGENTS = {
|
|
|
333
531
|
},
|
|
334
532
|
unreported: cursorUnreported,
|
|
335
533
|
mcpServers: cursorMcpServers,
|
|
336
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
534
|
+
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-C0xowZ3C.js")).createCursorSdk({
|
|
337
535
|
auth,
|
|
338
536
|
...mcpServers ? { mcpServers } : {},
|
|
339
537
|
...descriptor.kind === "cursor" && descriptor.params ? { modelParams: descriptor.params } : {},
|
|
@@ -343,6 +541,7 @@ const AGENTS = {
|
|
|
343
541
|
},
|
|
344
542
|
"claude-code": {
|
|
345
543
|
...LAYOUTS["claude-code"],
|
|
544
|
+
pluginParts: CLAUDE_FORMAT_PARTS,
|
|
346
545
|
name: "Claude Code",
|
|
347
546
|
factory: "claudeCode",
|
|
348
547
|
credential: "ANTHROPIC_API_KEY",
|
|
@@ -369,7 +568,7 @@ const AGENTS = {
|
|
|
369
568
|
}
|
|
370
569
|
],
|
|
371
570
|
mcpServers: claudeMcpServers,
|
|
372
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./dist-
|
|
571
|
+
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./dist-CMjp3qqF.js")).createClaudeCode({
|
|
373
572
|
auth,
|
|
374
573
|
...mcpServers ? { mcpServers } : {},
|
|
375
574
|
...descriptor.kind === "claude-code" && descriptor.effort ? { effort: descriptor.effort } : {},
|
|
@@ -381,6 +580,13 @@ const AGENTS = {
|
|
|
381
580
|
},
|
|
382
581
|
antigravity: {
|
|
383
582
|
...LAYOUTS.antigravity,
|
|
583
|
+
pluginParts: PLUGIN_PARTS,
|
|
584
|
+
pluginManifestsFirst: [
|
|
585
|
+
"plugin.json",
|
|
586
|
+
".antigravity-plugin/plugin.json",
|
|
587
|
+
".gemini-plugin/plugin.json",
|
|
588
|
+
"gemini-extension.json"
|
|
589
|
+
],
|
|
384
590
|
name: "Antigravity",
|
|
385
591
|
factory: "antigravity",
|
|
386
592
|
credential: "GEMINI_API_KEY",
|
|
@@ -391,15 +597,25 @@ const AGENTS = {
|
|
|
391
597
|
},
|
|
392
598
|
servedModel: geminiServedModel,
|
|
393
599
|
mcpServers: antigravityMcpServers,
|
|
394
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
600
|
+
adapter: async ({ auth, mcpServers, descriptor, plugins }) => (await import("./src-bCnsA6Vp.js")).createAntigravity({
|
|
395
601
|
auth,
|
|
396
602
|
...mcpServers ? { mcpServers } : {},
|
|
603
|
+
...plugins.length ? { plugins: plugins.map(({ name, dir }) => ({
|
|
604
|
+
name,
|
|
605
|
+
dir
|
|
606
|
+
})) } : {},
|
|
397
607
|
...descriptor.kind === "antigravity" && descriptor.effort ? { effort: descriptor.effort } : {},
|
|
398
608
|
requireCredentialBrokering: true
|
|
399
609
|
})
|
|
400
610
|
},
|
|
401
611
|
opencode: {
|
|
402
612
|
...LAYOUTS.opencode,
|
|
613
|
+
pluginParts: [
|
|
614
|
+
"skills",
|
|
615
|
+
"agents",
|
|
616
|
+
"commands",
|
|
617
|
+
"mcp"
|
|
618
|
+
],
|
|
403
619
|
name: "OpenCode",
|
|
404
620
|
factory: "opencode",
|
|
405
621
|
credential: "GOOGLE_GENERATIVE_AI_API_KEY",
|
|
@@ -407,7 +623,7 @@ const AGENTS = {
|
|
|
407
623
|
servedModel: geminiServedModel,
|
|
408
624
|
forModel: opencodeForModel,
|
|
409
625
|
mcpServers: opencodeMcpServers,
|
|
410
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
626
|
+
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-Bcah6ZkT.js")).createOpenCode({
|
|
411
627
|
auth,
|
|
412
628
|
model: descriptor.model,
|
|
413
629
|
vars: opencodeVars(descriptor.model),
|
|
@@ -418,13 +634,18 @@ const AGENTS = {
|
|
|
418
634
|
},
|
|
419
635
|
goose: {
|
|
420
636
|
...LAYOUTS.goose,
|
|
637
|
+
pluginParts: ["skills", "mcp"],
|
|
421
638
|
name: "Goose",
|
|
422
639
|
factory: "goose",
|
|
423
640
|
credential: "GOOGLE_GENERATIVE_AI_API_KEY",
|
|
424
641
|
endpoints: GOOSE_ENDPOINTS,
|
|
642
|
+
expectedBlocked: {
|
|
643
|
+
hosts: ["models.dev"],
|
|
644
|
+
why: "Goose's model catalogue refresh, which no setting turns off"
|
|
645
|
+
},
|
|
425
646
|
servedModel: geminiServedModel,
|
|
426
647
|
mcpServers: gooseMcpServers,
|
|
427
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
648
|
+
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-DPIjmReZ.js")).createGoose({
|
|
428
649
|
auth: { GOOGLE_API_KEY: auth.GOOGLE_GENERATIVE_AI_API_KEY ?? "" },
|
|
429
650
|
model: descriptor.model,
|
|
430
651
|
...descriptor.kind === "goose" && descriptor.effort ? { effort: descriptor.effort } : {},
|
|
@@ -434,13 +655,18 @@ const AGENTS = {
|
|
|
434
655
|
},
|
|
435
656
|
pi: {
|
|
436
657
|
...LAYOUTS.pi,
|
|
658
|
+
pluginParts: [
|
|
659
|
+
"skills",
|
|
660
|
+
"commands",
|
|
661
|
+
"mcp"
|
|
662
|
+
],
|
|
437
663
|
name: "pi",
|
|
438
664
|
factory: "pi",
|
|
439
665
|
credential: "GOOGLE_GENERATIVE_AI_API_KEY",
|
|
440
666
|
endpoints: GEMINI_ENDPOINTS,
|
|
441
667
|
servedModel: geminiServedModel,
|
|
442
668
|
mcpServers: piMcpServers,
|
|
443
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
669
|
+
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-ynBVosfX.js")).createPi({
|
|
444
670
|
auth: { GEMINI_API_KEY: auth.GOOGLE_GENERATIVE_AI_API_KEY ?? "" },
|
|
445
671
|
...descriptor.kind === "pi" && descriptor.effort ? { effort: descriptor.effort } : {},
|
|
446
672
|
...mcpServers ? { mcpServers } : {},
|
|
@@ -449,28 +675,47 @@ const AGENTS = {
|
|
|
449
675
|
},
|
|
450
676
|
codex: {
|
|
451
677
|
...LAYOUTS.codex,
|
|
678
|
+
pluginParts: ["skills", "mcp"],
|
|
679
|
+
pluginApps: "they need a ChatGPT login",
|
|
680
|
+
pluginManifestsFirst: ["plugin.json", ".codex-plugin/plugin.json"],
|
|
681
|
+
pluginRootManifestNeedsSchema: true,
|
|
682
|
+
pluginServersByName: true,
|
|
452
683
|
name: "Codex",
|
|
453
684
|
factory: "codex",
|
|
454
685
|
credential: "OPENAI_API_KEY",
|
|
455
686
|
endpoints: OPENAI_ENDPOINTS,
|
|
456
687
|
modelResponses: OPENAI_ENDPOINTS,
|
|
688
|
+
expectedBlocked: {
|
|
689
|
+
hosts: [
|
|
690
|
+
"github.com",
|
|
691
|
+
"api.github.com",
|
|
692
|
+
"chatgpt.com"
|
|
693
|
+
],
|
|
694
|
+
why: "Codex's plugin sync, which it runs on every turn once plugins are on",
|
|
695
|
+
withPlugins: true
|
|
696
|
+
},
|
|
457
697
|
servedModel: openaiServedModel,
|
|
458
698
|
mcpServers: codexMcpServers,
|
|
459
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
699
|
+
adapter: async ({ auth, mcpServers, descriptor, plugins }) => (await import("./src-DLtyz4w5.js")).createCodex({
|
|
460
700
|
auth,
|
|
461
701
|
...descriptor.kind === "codex" && descriptor.effort ? { effort: descriptor.effort } : {},
|
|
462
702
|
...mcpServers ? { mcpServers } : {},
|
|
703
|
+
...plugins.length ? { plugins: plugins.map(({ name, dir }) => ({
|
|
704
|
+
name,
|
|
705
|
+
dir
|
|
706
|
+
})) } : {},
|
|
463
707
|
requireCredentialBrokering: true
|
|
464
708
|
})
|
|
465
709
|
},
|
|
466
710
|
fx: {
|
|
467
711
|
...LAYOUTS.fx,
|
|
712
|
+
pluginParts: ["skills", "mcp"],
|
|
468
713
|
name: "fx",
|
|
469
714
|
factory: "fx",
|
|
470
715
|
...fxForModel("provider/model"),
|
|
471
716
|
forModel: fxForModel,
|
|
472
717
|
mcpServers: acpMcpServers,
|
|
473
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
718
|
+
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-DXNh5mTr.js")).createFx({
|
|
474
719
|
auth,
|
|
475
720
|
model: descriptor.model,
|
|
476
721
|
...mcpServers ? { mcpServers } : {},
|
|
@@ -479,6 +724,8 @@ const AGENTS = {
|
|
|
479
724
|
},
|
|
480
725
|
"grok-build": {
|
|
481
726
|
...LAYOUTS["grok-build"],
|
|
727
|
+
pluginParts: CLAUDE_FORMAT_PARTS,
|
|
728
|
+
pluginServersByName: true,
|
|
482
729
|
name: "Grok Build",
|
|
483
730
|
factory: "grokBuild",
|
|
484
731
|
credential: "XAI_API_KEY",
|
|
@@ -486,9 +733,13 @@ const AGENTS = {
|
|
|
486
733
|
modelResponses: XAI_MODEL_RESPONSES,
|
|
487
734
|
servedModel: xaiServedModel,
|
|
488
735
|
mcpServers: acpMcpServers,
|
|
489
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
736
|
+
adapter: async ({ auth, mcpServers, descriptor, plugins }) => (await import("./src-CHIfIKUu.js")).createGrokBuild({
|
|
490
737
|
auth,
|
|
491
738
|
model: descriptor.model,
|
|
739
|
+
...plugins.length ? {
|
|
740
|
+
pluginDirs: plugins.map((p) => p.dir),
|
|
741
|
+
pluginMcpServers: plugins.flatMap((p) => p.servers.map((s) => s.slice(p.name.length + 1)))
|
|
742
|
+
} : {},
|
|
492
743
|
...descriptor.kind === "grok-build" && descriptor.effort ? { effort: descriptor.effort } : {},
|
|
493
744
|
...mcpServers ? { mcpServers } : {},
|
|
494
745
|
requireCredentialBrokering: true
|
|
@@ -527,6 +778,139 @@ function refusedMcp(harness, layers) {
|
|
|
527
778
|
throw error;
|
|
528
779
|
}
|
|
529
780
|
}
|
|
781
|
+
/** The first host variable a plugin MCP server reads (`${VAR}`), as `VAR`; undefined for none. */
|
|
782
|
+
function hostVariable(s) {
|
|
783
|
+
const values = Object.entries(s.transport === "stdio" ? s.env : s.headers);
|
|
784
|
+
for (const [key, v] of values) {
|
|
785
|
+
if (typeof v === "string") continue;
|
|
786
|
+
if (v.kind === "secret") return v.from ?? key;
|
|
787
|
+
return /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/.exec(v.template)?.[1] ?? key;
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
const quoted = (parts) => parts.map((p) => `'${p}'`).join(", ");
|
|
791
|
+
/**
|
|
792
|
+
* Why a harness's agent can't take the plugins, in the agent's own words: a part it doesn't
|
|
793
|
+
* load, apps it can't take (`pluginApps`), a hook event or type it doesn't run, a plugin MCP
|
|
794
|
+
* server it refuses (named `<plugin>:<server>`) or whose `<plugin>:<server>` key `mcp` already has,
|
|
795
|
+
* or, where it takes plugin items flat, a skill or MCP server whose name another already has, or a
|
|
796
|
+
* subagent, command or rule another unpacks to the same file. `own` names the
|
|
797
|
+
* environment's own skills and MCP servers, and `unread` the plugins not fetched yet (git and
|
|
798
|
+
* npm ones, at plan time) by their call. Undefined when it can take them.
|
|
799
|
+
*/
|
|
800
|
+
function refusedPlugins(harness, plugins, own, unread = []) {
|
|
801
|
+
if (plugins.length === 0 && unread.length === 0) return void 0;
|
|
802
|
+
const agent = isAgentKind(harness.kind) ? AGENTS[harness.kind] : void 0;
|
|
803
|
+
const mimics = harness.kind === "fake" && harness.layout ? AGENTS[harness.layout] : void 0;
|
|
804
|
+
const loads = (agent ?? mimics)?.pluginParts ?? PLUGIN_PARTS;
|
|
805
|
+
const name = agent?.name ?? (mimics ? `The fake agent with ${mimics.name}'s layout` : "The fake agent");
|
|
806
|
+
if (loads.length === 0) return `${name} can't load plugins yet: leave ${plugins[0] ? `the ${plugins[0].name} plugin` : unread[0]} out of this cell`;
|
|
807
|
+
for (const p of plugins) {
|
|
808
|
+
const refused = p.kept.filter((part) => !loads.includes(part));
|
|
809
|
+
if (refused.length === 0) continue;
|
|
810
|
+
const can = p.kept.filter((part) => loads.includes(part));
|
|
811
|
+
const what = refused.map((part) => `${part} (${PART_PATHS[part]})`).join(" and ");
|
|
812
|
+
const fix = can.length ? `use only: [${quoted(can)}], or leave` : "leave";
|
|
813
|
+
return `${name} can't load the ${p.name} plugin's ${what}: ${fix} the plugin out of this cell`;
|
|
814
|
+
}
|
|
815
|
+
const reads = agent ?? mimics;
|
|
816
|
+
const first = reads?.pluginManifestsFirst ?? [];
|
|
817
|
+
for (const p of plugins) {
|
|
818
|
+
const other = p.manifests.find((m) => first.includes(m) && (m !== "plugin.json" || !reads?.pluginRootManifestNeedsSchema || p.rootSchema));
|
|
819
|
+
if (other) return `${name} reads the ${p.name} plugin's ${other} in place of its ${PLUGIN_MANIFEST}, so reeval can't hold it to the parts it places: remove ${other} from the plugin, or leave the plugin out of this cell`;
|
|
820
|
+
}
|
|
821
|
+
const apps = (agent ?? mimics)?.pluginApps;
|
|
822
|
+
const withApps = apps ? plugins.find((p) => p.apps) : void 0;
|
|
823
|
+
if (withApps) return `${name} can't load the ${withApps.name} plugin's apps: ${apps}`;
|
|
824
|
+
const layout = layoutOf(harness);
|
|
825
|
+
const runs = layout.pluginHookEvents;
|
|
826
|
+
for (const p of runs ? plugins : []) {
|
|
827
|
+
const event = p.hooks.events.find((e) => !runs?.includes(e));
|
|
828
|
+
const type = p.hooks.otherTypes[0];
|
|
829
|
+
if (!event && !type) continue;
|
|
830
|
+
const rest = p.kept.filter((part) => part !== "hooks");
|
|
831
|
+
const fix = rest.length ? `use only: [${quoted(rest)}], or leave` : "leave";
|
|
832
|
+
return event ? `${name} can't run the ${p.name} plugin's ${event} hooks (hooks/hooks.json): it runs ${runs?.join(", ")} hooks; ${fix} the plugin out of this cell` : `${name} can't run the ${p.name} plugin's ${type} hooks (hooks/hooks.json): it runs only command hooks; ${fix} the plugin out of this cell`;
|
|
833
|
+
}
|
|
834
|
+
const servers = Object.fromEntries(plugins.flatMap((p) => Object.entries(p.mcp).map(([server, s]) => [pluginServerName(p.name, server), s.transport === "stdio" ? {
|
|
835
|
+
...s,
|
|
836
|
+
env: {}
|
|
837
|
+
} : {
|
|
838
|
+
...s,
|
|
839
|
+
headers: {}
|
|
840
|
+
}])));
|
|
841
|
+
if (agent && Object.keys(servers).length) {
|
|
842
|
+
const alongside = agent.pluginPlacement === "flat" ? Object.fromEntries(own.mcp.map((n) => [n, {
|
|
843
|
+
transport: "stdio",
|
|
844
|
+
command: "true",
|
|
845
|
+
args: [],
|
|
846
|
+
env: {}
|
|
847
|
+
}])) : {};
|
|
848
|
+
try {
|
|
849
|
+
agent.mcpServers({
|
|
850
|
+
...alongside,
|
|
851
|
+
...servers
|
|
852
|
+
});
|
|
853
|
+
} catch (error) {
|
|
854
|
+
if (error instanceof InfraError) return error.message;
|
|
855
|
+
throw error;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
for (const p of plugins) for (const server of Object.keys(p.mcp)) {
|
|
859
|
+
const key = pluginServerName(p.name, server);
|
|
860
|
+
if (own.mcp.includes(key)) return `the ${p.name} plugin's MCP server "${server}" would join mcp as ${key}, which mcp already names: rename mcp["${key}"]`;
|
|
861
|
+
}
|
|
862
|
+
if (layout.pluginPlacement === "namespaced") {
|
|
863
|
+
for (const p of plugins) {
|
|
864
|
+
if (!p.kept.includes("mcp")) continue;
|
|
865
|
+
for (const [server, s] of Object.entries(p.mcp)) {
|
|
866
|
+
const secret = hostVariable(s);
|
|
867
|
+
if (!secret) continue;
|
|
868
|
+
const rest = p.kept.filter((part) => part !== "mcp");
|
|
869
|
+
return `${name} loads the ${p.name} plugin's MCP server "${server}" itself, so reeval can't give it ${secret} from the host: use only: [${quoted(rest)}] and declare the server in mcp, where reeval fills it in`;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
if (!(agent ?? mimics)?.pluginServersByName) return void 0;
|
|
873
|
+
const byName = new Map(own.mcp.map((n) => [n, `mcp.${n}`]));
|
|
874
|
+
for (const p of plugins) for (const server of Object.keys(p.mcp)) {
|
|
875
|
+
const other = byName.get(server);
|
|
876
|
+
if (other) return `${name} names the ${p.name} plugin's MCP server "${server}" by its own name, as it does ${other}, and keeps only one: rename one, or leave mcp out of the plugin with only`;
|
|
877
|
+
byName.set(server, `the ${p.name} plugin's MCP server "${server}"`);
|
|
878
|
+
}
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
const serverOwner = new Map(own.mcp.map((n) => [n, `mcp.${n}`]));
|
|
882
|
+
for (const p of plugins) for (const server of Object.keys(p.mcp)) {
|
|
883
|
+
const other = serverOwner.get(server);
|
|
884
|
+
if (other) return `the ${p.name} plugin's MCP server "${server}" clashes with ${other}`;
|
|
885
|
+
serverOwner.set(server, `the ${p.name} plugin's MCP server "${server}"`);
|
|
886
|
+
}
|
|
887
|
+
const skillOwner = new Map(own.skills.map((s) => [s.name, `${s.call}'s "${s.name}"`]));
|
|
888
|
+
for (const p of plugins) for (const { name: skill } of p.skills) {
|
|
889
|
+
const other = skillOwner.get(skill);
|
|
890
|
+
if (other) return `the ${p.name} plugin's skill "${skill}" and ${other} would both be placed at ~/${layout.harnessSkillDir}/${skill}: rename one, or narrow it with only or exclude`;
|
|
891
|
+
skillOwner.set(skill, `the ${p.name} plugin's skill "${skill}"`);
|
|
892
|
+
}
|
|
893
|
+
for (const part of ["agents", "commands"]) {
|
|
894
|
+
const dir = layout.pluginUnpack?.[part];
|
|
895
|
+
if (!dir) continue;
|
|
896
|
+
const owner = /* @__PURE__ */ new Map();
|
|
897
|
+
for (const p of plugins) for (const item of p[part]) {
|
|
898
|
+
const other = owner.get(item);
|
|
899
|
+
const what = part === "agents" ? "subagent" : "command";
|
|
900
|
+
if (other) return `the ${p.name} plugin's ${what} "${item}" and the ${other} plugin's would both be placed at ${dir}/${item}.md: rename one, or narrow one with only`;
|
|
901
|
+
owner.set(item, p.name);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
const rules = layout.pluginUnpack?.rules;
|
|
905
|
+
const ruleOwner = /* @__PURE__ */ new Map();
|
|
906
|
+
for (const p of rules ? plugins : []) for (const rule of p.rules) {
|
|
907
|
+
const file = `${p.name}-${rule.replace(/\.mdc?$/, "")}.mdc`;
|
|
908
|
+
const what = `the ${p.name} plugin's rule "${rule}"`;
|
|
909
|
+
const other = ruleOwner.get(file);
|
|
910
|
+
if (other) return `${what} and ${other} would both be placed at ${rules}/${file}: rename one, or narrow one with only`;
|
|
911
|
+
ruleOwner.set(file, what);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
530
914
|
/** A real agent's catalog entry, with what its model's provider decides. */
|
|
531
915
|
function agentFor(h) {
|
|
532
916
|
const agent = AGENTS[h.kind];
|
|
@@ -543,17 +927,22 @@ const credentialOf = (h) => agentOf(h)?.credential;
|
|
|
543
927
|
const FAKE_LAYOUT = {
|
|
544
928
|
rulesFile: "AGENTS.md",
|
|
545
929
|
workspaceSkillDir: ".agents/skills",
|
|
546
|
-
harnessSkillDir: ".agents/skills"
|
|
930
|
+
harnessSkillDir: ".agents/skills",
|
|
931
|
+
pluginPlacement: "flat"
|
|
547
932
|
};
|
|
548
933
|
/** Where a harness's agent reads rules and skills; a fake one with `layout` mimics that agent. */
|
|
549
934
|
function layoutOf(descriptor) {
|
|
550
935
|
if (descriptor.kind !== "fake") return LAYOUTS[descriptor.kind];
|
|
551
936
|
return descriptor.layout ? LAYOUTS[descriptor.layout] : FAKE_LAYOUT;
|
|
552
937
|
}
|
|
553
|
-
/**
|
|
554
|
-
|
|
938
|
+
/**
|
|
939
|
+
* The hosts a harness's agent is known to try in a session with or without plugins; a fake agent
|
|
940
|
+
* with `layout` expects that agent's.
|
|
941
|
+
*/
|
|
942
|
+
function expectedBlockedFor(descriptor, plugins) {
|
|
555
943
|
const kind = descriptor.kind === "fake" ? descriptor.layout : descriptor.kind;
|
|
556
|
-
|
|
944
|
+
const expected = kind ? AGENTS[kind].expectedBlocked : void 0;
|
|
945
|
+
return expected?.withPlugins && !plugins ? void 0 : expected;
|
|
557
946
|
}
|
|
558
947
|
/**
|
|
559
948
|
* How the APIs behind the harnesses say they refused a key: an HTTP 401, Anthropic's and OpenAI's
|
|
@@ -701,10 +1090,21 @@ async function createFakeSandbox(descriptor, env = {}) {
|
|
|
701
1090
|
const base = await mkdtemp(join(parent, "reeval-sandbox-"));
|
|
702
1091
|
const workdir = join(base, "work");
|
|
703
1092
|
await mkdir(workdir);
|
|
1093
|
+
const stateDir = `${base}.state`;
|
|
1094
|
+
await mkdir(stateDir);
|
|
704
1095
|
let destroyed;
|
|
705
1096
|
const resolve = (path) => path.startsWith("~/") ? join(base, path.slice(2)) : join(workdir, path);
|
|
706
1097
|
return {
|
|
707
1098
|
workdir,
|
|
1099
|
+
stateDir,
|
|
1100
|
+
execOwn: (command, { signal } = {}) => run(sh, ["-c", command], {
|
|
1101
|
+
cwd: workdir,
|
|
1102
|
+
env: {
|
|
1103
|
+
HOME: base,
|
|
1104
|
+
...env
|
|
1105
|
+
},
|
|
1106
|
+
signal
|
|
1107
|
+
}),
|
|
708
1108
|
exec: (command, { cwd, env: extra, signal } = {}) => {
|
|
709
1109
|
const tag = process.platform === "win32" && signal ? randomUUID() : void 0;
|
|
710
1110
|
const stop = () => killTagged(sh, tag);
|
|
@@ -730,6 +1130,10 @@ async function createFakeSandbox(descriptor, env = {}) {
|
|
|
730
1130
|
},
|
|
731
1131
|
destroy: () => {
|
|
732
1132
|
destroyed ??= (async () => {
|
|
1133
|
+
await rm(stateDir, {
|
|
1134
|
+
recursive: true,
|
|
1135
|
+
force: true
|
|
1136
|
+
}).catch(() => {});
|
|
733
1137
|
if (process.platform === "win32") {
|
|
734
1138
|
if (existsSync(base)) await runSh(sh, KILL_UNDER, base);
|
|
735
1139
|
await removeTree(base);
|
|
@@ -767,11 +1171,12 @@ function harnessHosts(harness) {
|
|
|
767
1171
|
if (harness.kind !== "fake" && isAgentKind(harness.kind)) return agentFor(harness).hosts ?? HARNESS_HOSTS[harness.kind];
|
|
768
1172
|
return harness.kind === "fake" && harness.layout ? HARNESS_HOSTS[harness.layout] : [];
|
|
769
1173
|
}
|
|
770
|
-
/** MCP `http`/`sse` servers' hosts: the agent connects to them from the sandbox. */
|
|
1174
|
+
/** MCP `http`/`sse` servers' hosts, local plugins' included: the agent connects to them from the sandbox. */
|
|
771
1175
|
function mcpServerHosts(layers) {
|
|
772
1176
|
const urls = /* @__PURE__ */ new Map();
|
|
773
1177
|
for (const { spec } of layers) for (const [name, server] of Object.entries(spec.mcp ?? {})) if (server.transport === "stdio") urls.delete(name);
|
|
774
1178
|
else urls.set(name, server.url);
|
|
1179
|
+
for (const [name, server] of localPluginServers(layers)) if (server.transport !== "stdio") urls.set(name, server.url);
|
|
775
1180
|
return [...urls.values()].flatMap((url) => URL.parse(url)?.hostname ?? []);
|
|
776
1181
|
}
|
|
777
1182
|
/**
|
|
@@ -831,6 +1236,6 @@ function egressLabel({ policy, auto }) {
|
|
|
831
1236
|
return auto.length ? `${own} + auto: ${auto.join(", ")}` : own;
|
|
832
1237
|
}
|
|
833
1238
|
//#endregion
|
|
834
|
-
export {
|
|
1239
|
+
export { writePluginFiles as S, expectedBlockedFor as _, unenforceable as a, refusedMcp as b, DEFAULT_HARNESS as c, agentFor as d, agentMcp as f, credentialOf as g, claudeMcpServers as h, plannedEgress as i, HARNESS_EXAMPLE as l, brokeringFor as m, allowedHosts as n, createFakeSandbox as o, authHint as p, egressLabel as r, AGENTS as s, DEFAULT_EGRESS_ALLOW as t, agentAuth as u, isAgentKind as v, refusedPlugins as x, layoutOf as y };
|
|
835
1240
|
|
|
836
|
-
//# sourceMappingURL=egress-
|
|
1241
|
+
//# sourceMappingURL=egress-BfK_O9ce.js.map
|