reeval 0.10.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 +64 -39
- package/THIRD_PARTY_NOTICES.md +75 -106
- package/bin/mcp-timer.cjs +224 -0
- package/dist/{adapter-DWlpOtRn.js → adapter-DigeVFWC.js} +3 -3
- package/dist/{adapter-DWlpOtRn.js.map → adapter-DigeVFWC.js.map} +1 -1
- package/dist/{agent-CaS_2Sce.js → agent-CatUEo5h.js} +21 -6
- package/dist/{agent-CaS_2Sce.js.map → agent-CatUEo5h.js.map} +1 -1
- package/dist/{assemble-B9Alds-z.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 +15 -7
- package/dist/{capture-CNb9SuU5.js → capture-BiD7lVaM.js} +26 -18
- package/dist/{capture-CNb9SuU5.js.map → capture-BiD7lVaM.js.map} +1 -1
- package/dist/capture-Dp3q7K7Y.js +1 -0
- package/dist/{cli-D303Vj5N.js → cli-B5zQCR2r.js} +266 -547
- package/dist/cli-B5zQCR2r.js.map +1 -0
- package/dist/{cli-spec-BPZbQG2p.js → cli-spec-BXIBUlaK.js} +46 -18
- package/dist/cli-spec-BXIBUlaK.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/{command-BT9a37ZR.js → command-BMHXHqMT.js} +17 -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-BLfT7vnQ.js → command-CaZgCTIw.js} +13 -17
- package/dist/command-CaZgCTIw.js.map +1 -0
- package/dist/{command-CMJtHKRa.js → command-DTgBZR0k.js} +6 -6
- package/dist/{command-CMJtHKRa.js.map → command-DTgBZR0k.js.map} +1 -1
- package/dist/{commands-1p-bIWhN.js → commands-BXzIDB3X.js} +1 -1
- package/dist/commands-CjpGBUWr.js +666 -0
- package/dist/commands-CjpGBUWr.js.map +1 -0
- package/dist/{config-DEgnUiU-.js → config-Dv5MG7Rp.js} +31 -34
- 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-CcoMLC_y.js +101 -0
- package/dist/contrasts-CcoMLC_y.js.map +1 -0
- 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-B8hJImYt.js → dist-CMjp3qqF.js} +81 -14
- package/dist/dist-CMjp3qqF.js.map +1 -0
- package/dist/{docker-sZrNrr82.js → docker-BbTlMmYi.js} +2 -2
- package/dist/{docker-sZrNrr82.js.map → docker-BbTlMmYi.js.map} +1 -1
- package/dist/{docker-7b_2SaH7.js → docker-CCXdbREk.js} +20 -4
- package/dist/{docker-7b_2SaH7.js.map → docker-CCXdbREk.js.map} +1 -1
- package/dist/{docker-yauK-9X8.js → docker-DC69dKxB.js} +1 -1
- package/dist/{doctor-BYNok4UO.js → doctor-CqttrZcs.js} +56 -22
- package/dist/doctor-CqttrZcs.js.map +1 -0
- package/dist/{egress-C4PZTSSe.js → egress-BfK_O9ce.js} +435 -31
- package/dist/egress-BfK_O9ce.js.map +1 -0
- package/dist/{environment-DNjRk0nU.js → environment-BBz1Yes9.js} +225 -12
- package/dist/environment-BBz1Yes9.js.map +1 -0
- package/dist/{evaluate-D4zeRGBF.js → evaluate-CXQ1o-pd.js} +539 -562
- package/dist/evaluate-CXQ1o-pd.js.map +1 -0
- package/dist/{evaluate-C1UVL21l.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-BXUdY8tr.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-DQmHE7pb.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-DfG-YJ1u.js → git-DhykwgKF.js} +2 -2
- package/dist/{git-DfG-YJ1u.js.map → git-DhykwgKF.js.map} +1 -1
- package/dist/{harness-B8QC9u0O.js → harness-BAjw1fcr.js} +3 -3
- package/dist/{harness-B8QC9u0O.js.map → harness-BAjw1fcr.js.map} +1 -1
- package/dist/harness.d.ts +1 -1
- package/dist/harness.js +1 -1
- package/dist/{header-hK-Z_Po9.js → header-kSmWatcO.js} +10 -3
- package/dist/{header-hK-Z_Po9.js.map → header-kSmWatcO.js.map} +1 -1
- package/dist/{images-0On0cztu.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-DbGfBAA_.js → invocations-CQTbP092.js} +3 -3
- package/dist/{invocations-DbGfBAA_.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-h_cDtcRr.js → model-B-mel-Gv.js} +46 -20
- 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-oqcDplJG.js → model-CWlAqmbU.js} +150 -46
- 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-Bh2W63dK.js → options-CPUW97_7.js} +9 -12
- 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-Zac5aIRM.js → patch-D4oluWzH.js} +2 -2
- package/dist/{patch-Zac5aIRM.js.map → patch-D4oluWzH.js.map} +1 -1
- package/dist/{plan-C9Cy27Ay.js → plan-OkwUcJQ9.js} +31 -12
- 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-CPWpQeBI.js → preflight-B6pY89bF.js} +1 -1
- package/dist/{preflight-D7iFPKeK.js → preflight-Bjm7_ylE.js} +14 -10
- package/dist/preflight-Bjm7_ylE.js.map +1 -0
- package/dist/{prepare-doGxaAGR.js → prepare-CQmK3SBn.js} +71 -24
- package/dist/prepare-CQmK3SBn.js.map +1 -0
- package/dist/prepare-DbdgtZKe.js +2 -0
- package/dist/{provenance-DmE9uPVt.js → provenance-B3Y17oCC.js} +2 -2
- package/dist/{provenance-DmE9uPVt.js.map → provenance-B3Y17oCC.js.map} +1 -1
- package/dist/providers-CXN2RFz-.js +1 -0
- package/dist/{providers-tAOD1NQN.js → providers-eoniqK6w.js} +24 -10
- package/dist/providers-eoniqK6w.js.map +1 -0
- package/dist/query-CLRZmWBT.js +139 -0
- package/dist/query-CLRZmWBT.js.map +1 -0
- package/dist/query-CmBDYt0_.js +1 -0
- package/dist/{questions-DjAwMxZ3.js → questions-1XOulevV.js} +6 -6
- package/dist/{questions-DjAwMxZ3.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-HDRt16ew.js → remote-cE2VWfkJ.js} +3 -3
- package/dist/{remote-HDRt16ew.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-DuauQI3Z.js → results-Drtt0uFl.js} +33 -7
- package/dist/results-Drtt0uFl.js.map +1 -0
- package/dist/{resume-BRfa8E_s.js → resume-BEFazUfy.js} +4 -4
- package/dist/{resume-BRfa8E_s.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-D3A8oUb7.js → sandbox-CQaJj7n9.js} +2 -2
- package/dist/{sandbox-D3A8oUb7.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-XDleKaF_.js → server-xK0les4f.js} +8 -8
- package/dist/{server-XDleKaF_.js.map → server-xK0les4f.js.map} +1 -1
- package/dist/{shared-DYpIb1BI.js → shared-CA61BuPJ.js} +25 -3
- package/dist/shared-CA61BuPJ.js.map +1 -0
- package/dist/source-BDow_oW8.js +1 -0
- package/dist/{source-C8xumIWj.js → source-Q1hEKbCs.js} +2 -2
- package/dist/{source-C8xumIWj.js.map → source-Q1hEKbCs.js.map} +1 -1
- package/dist/src-B9L9yGKI.js +1 -0
- package/dist/{src-ofUaYbuY.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-C_lPtowT.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-B7treWa8.js → src-LekQrr_S.js} +324 -32
- 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-jzagbuqH.js → src-ynBVosfX.js} +1 -1
- package/dist/state-BQR_BCm4.js +1 -0
- package/dist/{state-C__9swoG.js → state-BmZ8QVZ8.js} +12 -12
- package/dist/{state-C__9swoG.js.map → state-BmZ8QVZ8.js.map} +1 -1
- package/dist/studio-app/assets/index-CnYJijyI.js +58 -0
- package/dist/studio-app/index.html +1 -1
- package/dist/suite-BaHPmAGy.js +1 -0
- package/dist/suite-C8sw2pox.js +481 -0
- package/dist/suite-C8sw2pox.js.map +1 -0
- package/dist/summary-0oQNGskv.js +837 -0
- 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-g17bRAzt.d.ts → types-GraZtfHN.d.ts} +858 -39
- package/dist/usage-BDo2q_yu.js +1 -0
- package/dist/{command-Bge8F7Ko.js → validate-BdoXUuL_.js} +35 -383
- package/dist/validate-BdoXUuL_.js.map +1 -0
- package/dist/view/index.d.ts +20 -9
- package/dist/view/index.js +7 -6
- package/dist/views-BoUoX4_A.js +125 -0
- package/dist/views-BoUoX4_A.js.map +1 -0
- package/dist/views-noVQNCUP.js +2 -0
- package/dist/{worker-entry-yOchGYYv.js → worker-entry-D0-GErmU.js} +2 -2
- package/dist/{worker-entry-yOchGYYv.js.map → worker-entry-D0-GErmU.js.map} +1 -1
- package/dist/{workspace-D8sSgpiy.js → workspace-B90YDU_a.js} +1 -1
- package/dist/{workspace-CgyHEM0l.js → workspace-tjZFkjxC.js} +4 -4
- package/dist/{workspace-CgyHEM0l.js.map → workspace-tjZFkjxC.js.map} +1 -1
- package/package.json +10 -8
- package/skills/eval-rubric/SKILL.md +130 -0
- package/dist/agent-CURAwx_q.js +0 -334
- package/dist/agent-CURAwx_q.js.map +0 -1
- package/dist/assemble-B9Alds-z.js.map +0 -1
- package/dist/assemble-J5MukZFY.js +0 -1
- package/dist/capture-jquXZBKK.js +0 -1
- package/dist/cli-D303Vj5N.js.map +0 -1
- package/dist/cli-spec-BPZbQG2p.js.map +0 -1
- package/dist/command-BLfT7vnQ.js.map +0 -1
- package/dist/command-BT9a37ZR.js.map +0 -1
- package/dist/command-Bge8F7Ko.js.map +0 -1
- package/dist/command-BkFjijN2.js +0 -1
- package/dist/commands-BFx16WB8.js +0 -225
- package/dist/commands-BFx16WB8.js.map +0 -1
- package/dist/config-DEgnUiU-.js.map +0 -1
- package/dist/context-C1mxXh80.js.map +0 -1
- package/dist/db-CdHizc4_.js +0 -1406
- package/dist/db-CdHizc4_.js.map +0 -1
- package/dist/db-Dm1cRJJP.js +0 -2
- package/dist/dist-B8hJImYt.js.map +0 -1
- package/dist/doctor-BYNok4UO.js.map +0 -1
- package/dist/duration-CEOQww97.js +0 -26
- package/dist/duration-CEOQww97.js.map +0 -1
- package/dist/egress-C4PZTSSe.js.map +0 -1
- package/dist/environment-DNjRk0nU.js.map +0 -1
- package/dist/evaluate-D4zeRGBF.js.map +0 -1
- package/dist/family-D2b7WD10.js +0 -67
- package/dist/family-D2b7WD10.js.map +0 -1
- package/dist/files-BXUdY8tr.js.map +0 -1
- package/dist/files-BhyltlDB.js +0 -1
- package/dist/files-DQmHE7pb.js.map +0 -1
- package/dist/files-ZZPqfAo6.js +0 -1
- package/dist/images-0On0cztu.js.map +0 -1
- package/dist/init-B77Rpcqc.js +0 -360
- package/dist/init-B77Rpcqc.js.map +0 -1
- package/dist/init-BrOWin3W.js +0 -1
- package/dist/judge-DW_GDOmB.js.map +0 -1
- package/dist/model-NM3ID0uR.js +0 -1
- package/dist/model-h_cDtcRr.js.map +0 -1
- package/dist/model-nwWJvaUR.js +0 -1
- package/dist/model-oqcDplJG.js.map +0 -1
- package/dist/options-Bh2W63dK.js.map +0 -1
- package/dist/plan-C9Cy27Ay.js.map +0 -1
- package/dist/preflight-D7iFPKeK.js.map +0 -1
- package/dist/prepare-BGjePFQl.js +0 -2
- package/dist/prepare-doGxaAGR.js.map +0 -1
- package/dist/process-CSVO_jsc.js +0 -119
- package/dist/process-CSVO_jsc.js.map +0 -1
- package/dist/providers-gDMko8fl.js +0 -1
- package/dist/providers-tAOD1NQN.js.map +0 -1
- package/dist/query-Bes9Kh6Y.js +0 -91
- package/dist/query-Bes9Kh6Y.js.map +0 -1
- package/dist/query-C_G_svLU.js +0 -1
- package/dist/record-BKmMvZ6O.js.map +0 -1
- package/dist/results-DuauQI3Z.js.map +0 -1
- package/dist/server-C7sg1ndo.js +0 -1
- package/dist/shared-DYpIb1BI.js.map +0 -1
- package/dist/source-fGd0SaKP.js +0 -1
- package/dist/src-B7treWa8.js.map +0 -1
- package/dist/src-DNnG4e4R.js +0 -2
- package/dist/src-DTbrY1hi.js +0 -2
- package/dist/src-DdyJEh2v.js +0 -2
- package/dist/src-Dj9PAroc.js +0 -2
- package/dist/src-Du8H85Qq.js +0 -2
- package/dist/src-FGXhkEkH.js.map +0 -1
- package/dist/src-pJZOrYR9.js +0 -1
- package/dist/src-u8_ixn_F.js.map +0 -1
- package/dist/state-CgjQo29K.js +0 -1
- package/dist/studio-app/assets/index-DrQc2Yxd.js +0 -58
- package/dist/summary-BLAVLySU.js +0 -385
- package/dist/summary-BLAVLySU.js.map +0 -1
- package/dist/summary-DgyjUh_l.js +0 -192
- package/dist/summary-DgyjUh_l.js.map +0 -1
- package/dist/text-gEcKjAyp.js.map +0 -1
- package/dist/tools-GCyNYSc1.js +0 -249
- package/dist/tools-GCyNYSc1.js.map +0 -1
- package/dist/views-BW6oCDUQ.js +0 -2
- package/dist/views-BmQF4UCI.js +0 -225
- package/dist/views-BmQF4UCI.js.map +0 -1
|
@@ -1,9 +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 } from "./src-B7treWa8.js";
|
|
6
|
-
import { n as shellQuote, t as run } from "./process-CSVO_jsc.js";
|
|
7
7
|
import { existsSync } from "node:fs";
|
|
8
8
|
import { tmpdir } from "node:os";
|
|
9
9
|
import { dirname, join, win32 } from "node:path";
|
|
@@ -165,8 +165,20 @@ function opencodeMcpServers(servers) {
|
|
|
165
165
|
}];
|
|
166
166
|
}));
|
|
167
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();
|
|
168
173
|
/** Goose's extension shape (its `config.yaml`); it has no SSE transport. */
|
|
169
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
|
+
}
|
|
170
182
|
return Object.fromEntries(Object.entries(servers).map(([name, s]) => {
|
|
171
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`);
|
|
172
184
|
return s.transport === "stdio" ? [name, {
|
|
@@ -184,11 +196,18 @@ function gooseMcpServers(servers) {
|
|
|
184
196
|
/**
|
|
185
197
|
* pi's `mcp.json` shape, which the adapter escapes and sets `"exposure": "direct"` on. pi
|
|
186
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>`.
|
|
187
201
|
*/
|
|
188
202
|
function piMcpServers(servers) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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`);
|
|
192
211
|
return s.transport === "stdio" ? [name, {
|
|
193
212
|
command: s.command,
|
|
194
213
|
args: s.args,
|
|
@@ -271,58 +290,236 @@ function cursorMcpServers(servers) {
|
|
|
271
290
|
headers: s.headers
|
|
272
291
|
}]));
|
|
273
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
|
+
}
|
|
274
450
|
/** Where each agent with an image reads rules and skills. */
|
|
275
451
|
const LAYOUTS = {
|
|
276
452
|
cursor: {
|
|
277
453
|
rulesFile: "AGENTS.md",
|
|
278
454
|
workspaceSkillDir: ".cursor/skills",
|
|
279
|
-
harnessSkillDir: ".agents/skills"
|
|
455
|
+
harnessSkillDir: ".agents/skills",
|
|
456
|
+
pluginPlacement: "flat",
|
|
457
|
+
pluginUnpack: CURSOR_PLUGIN_UNPACK,
|
|
458
|
+
pluginHookEvents: Object.keys(CURSOR_HOOK_EVENTS)
|
|
280
459
|
},
|
|
281
460
|
"claude-code": {
|
|
282
461
|
rulesFile: "CLAUDE.md",
|
|
283
462
|
workspaceSkillDir: ".claude/skills",
|
|
284
|
-
harnessSkillDir: ".claude/skills"
|
|
463
|
+
harnessSkillDir: ".claude/skills",
|
|
464
|
+
pluginPlacement: "namespaced",
|
|
465
|
+
pluginFiles: claudePluginFiles
|
|
285
466
|
},
|
|
286
467
|
antigravity: {
|
|
287
468
|
rulesFile: "AGENTS.md",
|
|
288
469
|
workspaceSkillDir: ".agents/skills",
|
|
289
|
-
harnessSkillDir: ".gemini/config/skills"
|
|
470
|
+
harnessSkillDir: ".gemini/config/skills",
|
|
471
|
+
pluginPlacement: "namespaced",
|
|
472
|
+
pluginHookEvents: [
|
|
473
|
+
"SessionStart",
|
|
474
|
+
"PreToolUse",
|
|
475
|
+
"PostToolUse",
|
|
476
|
+
"Stop"
|
|
477
|
+
]
|
|
290
478
|
},
|
|
291
479
|
opencode: {
|
|
292
480
|
rulesFile: "AGENTS.md",
|
|
293
481
|
workspaceSkillDir: ".opencode/skills",
|
|
294
|
-
harnessSkillDir: ".config/opencode/skills"
|
|
482
|
+
harnessSkillDir: ".config/opencode/skills",
|
|
483
|
+
pluginPlacement: "flat",
|
|
484
|
+
pluginUnpack: OPENCODE_PLUGIN_UNPACK
|
|
295
485
|
},
|
|
296
486
|
goose: {
|
|
297
487
|
rulesFile: "AGENTS.md",
|
|
298
488
|
workspaceSkillDir: ".goose/skills",
|
|
299
|
-
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"
|
|
300
491
|
},
|
|
301
492
|
pi: {
|
|
302
493
|
rulesFile: "AGENTS.md",
|
|
303
494
|
workspaceSkillDir: ".pi/skills",
|
|
304
|
-
harnessSkillDir: ".pi/agent/skills"
|
|
495
|
+
harnessSkillDir: ".pi/agent/skills",
|
|
496
|
+
pluginPlacement: "flat",
|
|
497
|
+
pluginUnpack: PI_PLUGIN_UNPACK
|
|
305
498
|
},
|
|
306
499
|
codex: {
|
|
307
500
|
rulesFile: "AGENTS.md",
|
|
308
501
|
workspaceSkillDir: ".agents/skills",
|
|
309
|
-
harnessSkillDir: ".agents/skills"
|
|
502
|
+
harnessSkillDir: ".agents/skills",
|
|
503
|
+
pluginPlacement: "namespaced"
|
|
310
504
|
},
|
|
311
505
|
fx: {
|
|
312
506
|
rulesFile: "AGENTS.md",
|
|
313
507
|
workspaceSkillDir: ".fx/skills",
|
|
314
|
-
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"
|
|
315
510
|
},
|
|
316
511
|
"grok-build": {
|
|
317
512
|
rulesFile: "AGENTS.md",
|
|
318
513
|
workspaceSkillDir: ".grok/skills",
|
|
319
|
-
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"
|
|
320
516
|
}
|
|
321
517
|
};
|
|
322
518
|
/** Every real agent reeval can drive, by harness kind. */
|
|
323
519
|
const AGENTS = {
|
|
324
520
|
cursor: {
|
|
325
521
|
...LAYOUTS.cursor,
|
|
522
|
+
pluginParts: PLUGIN_PARTS,
|
|
326
523
|
name: "Cursor",
|
|
327
524
|
factory: "cursor",
|
|
328
525
|
credential: "CURSOR_API_KEY",
|
|
@@ -334,7 +531,7 @@ const AGENTS = {
|
|
|
334
531
|
},
|
|
335
532
|
unreported: cursorUnreported,
|
|
336
533
|
mcpServers: cursorMcpServers,
|
|
337
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
534
|
+
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-C0xowZ3C.js")).createCursorSdk({
|
|
338
535
|
auth,
|
|
339
536
|
...mcpServers ? { mcpServers } : {},
|
|
340
537
|
...descriptor.kind === "cursor" && descriptor.params ? { modelParams: descriptor.params } : {},
|
|
@@ -344,6 +541,7 @@ const AGENTS = {
|
|
|
344
541
|
},
|
|
345
542
|
"claude-code": {
|
|
346
543
|
...LAYOUTS["claude-code"],
|
|
544
|
+
pluginParts: CLAUDE_FORMAT_PARTS,
|
|
347
545
|
name: "Claude Code",
|
|
348
546
|
factory: "claudeCode",
|
|
349
547
|
credential: "ANTHROPIC_API_KEY",
|
|
@@ -370,7 +568,7 @@ const AGENTS = {
|
|
|
370
568
|
}
|
|
371
569
|
],
|
|
372
570
|
mcpServers: claudeMcpServers,
|
|
373
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./dist-
|
|
571
|
+
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./dist-CMjp3qqF.js")).createClaudeCode({
|
|
374
572
|
auth,
|
|
375
573
|
...mcpServers ? { mcpServers } : {},
|
|
376
574
|
...descriptor.kind === "claude-code" && descriptor.effort ? { effort: descriptor.effort } : {},
|
|
@@ -382,6 +580,13 @@ const AGENTS = {
|
|
|
382
580
|
},
|
|
383
581
|
antigravity: {
|
|
384
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
|
+
],
|
|
385
590
|
name: "Antigravity",
|
|
386
591
|
factory: "antigravity",
|
|
387
592
|
credential: "GEMINI_API_KEY",
|
|
@@ -392,15 +597,25 @@ const AGENTS = {
|
|
|
392
597
|
},
|
|
393
598
|
servedModel: geminiServedModel,
|
|
394
599
|
mcpServers: antigravityMcpServers,
|
|
395
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
600
|
+
adapter: async ({ auth, mcpServers, descriptor, plugins }) => (await import("./src-bCnsA6Vp.js")).createAntigravity({
|
|
396
601
|
auth,
|
|
397
602
|
...mcpServers ? { mcpServers } : {},
|
|
603
|
+
...plugins.length ? { plugins: plugins.map(({ name, dir }) => ({
|
|
604
|
+
name,
|
|
605
|
+
dir
|
|
606
|
+
})) } : {},
|
|
398
607
|
...descriptor.kind === "antigravity" && descriptor.effort ? { effort: descriptor.effort } : {},
|
|
399
608
|
requireCredentialBrokering: true
|
|
400
609
|
})
|
|
401
610
|
},
|
|
402
611
|
opencode: {
|
|
403
612
|
...LAYOUTS.opencode,
|
|
613
|
+
pluginParts: [
|
|
614
|
+
"skills",
|
|
615
|
+
"agents",
|
|
616
|
+
"commands",
|
|
617
|
+
"mcp"
|
|
618
|
+
],
|
|
404
619
|
name: "OpenCode",
|
|
405
620
|
factory: "opencode",
|
|
406
621
|
credential: "GOOGLE_GENERATIVE_AI_API_KEY",
|
|
@@ -408,7 +623,7 @@ const AGENTS = {
|
|
|
408
623
|
servedModel: geminiServedModel,
|
|
409
624
|
forModel: opencodeForModel,
|
|
410
625
|
mcpServers: opencodeMcpServers,
|
|
411
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
626
|
+
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-Bcah6ZkT.js")).createOpenCode({
|
|
412
627
|
auth,
|
|
413
628
|
model: descriptor.model,
|
|
414
629
|
vars: opencodeVars(descriptor.model),
|
|
@@ -419,13 +634,18 @@ const AGENTS = {
|
|
|
419
634
|
},
|
|
420
635
|
goose: {
|
|
421
636
|
...LAYOUTS.goose,
|
|
637
|
+
pluginParts: ["skills", "mcp"],
|
|
422
638
|
name: "Goose",
|
|
423
639
|
factory: "goose",
|
|
424
640
|
credential: "GOOGLE_GENERATIVE_AI_API_KEY",
|
|
425
641
|
endpoints: GOOSE_ENDPOINTS,
|
|
642
|
+
expectedBlocked: {
|
|
643
|
+
hosts: ["models.dev"],
|
|
644
|
+
why: "Goose's model catalogue refresh, which no setting turns off"
|
|
645
|
+
},
|
|
426
646
|
servedModel: geminiServedModel,
|
|
427
647
|
mcpServers: gooseMcpServers,
|
|
428
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
648
|
+
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-DPIjmReZ.js")).createGoose({
|
|
429
649
|
auth: { GOOGLE_API_KEY: auth.GOOGLE_GENERATIVE_AI_API_KEY ?? "" },
|
|
430
650
|
model: descriptor.model,
|
|
431
651
|
...descriptor.kind === "goose" && descriptor.effort ? { effort: descriptor.effort } : {},
|
|
@@ -435,13 +655,18 @@ const AGENTS = {
|
|
|
435
655
|
},
|
|
436
656
|
pi: {
|
|
437
657
|
...LAYOUTS.pi,
|
|
658
|
+
pluginParts: [
|
|
659
|
+
"skills",
|
|
660
|
+
"commands",
|
|
661
|
+
"mcp"
|
|
662
|
+
],
|
|
438
663
|
name: "pi",
|
|
439
664
|
factory: "pi",
|
|
440
665
|
credential: "GOOGLE_GENERATIVE_AI_API_KEY",
|
|
441
666
|
endpoints: GEMINI_ENDPOINTS,
|
|
442
667
|
servedModel: geminiServedModel,
|
|
443
668
|
mcpServers: piMcpServers,
|
|
444
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
669
|
+
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-ynBVosfX.js")).createPi({
|
|
445
670
|
auth: { GEMINI_API_KEY: auth.GOOGLE_GENERATIVE_AI_API_KEY ?? "" },
|
|
446
671
|
...descriptor.kind === "pi" && descriptor.effort ? { effort: descriptor.effort } : {},
|
|
447
672
|
...mcpServers ? { mcpServers } : {},
|
|
@@ -450,28 +675,47 @@ const AGENTS = {
|
|
|
450
675
|
},
|
|
451
676
|
codex: {
|
|
452
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,
|
|
453
683
|
name: "Codex",
|
|
454
684
|
factory: "codex",
|
|
455
685
|
credential: "OPENAI_API_KEY",
|
|
456
686
|
endpoints: OPENAI_ENDPOINTS,
|
|
457
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
|
+
},
|
|
458
697
|
servedModel: openaiServedModel,
|
|
459
698
|
mcpServers: codexMcpServers,
|
|
460
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
699
|
+
adapter: async ({ auth, mcpServers, descriptor, plugins }) => (await import("./src-DLtyz4w5.js")).createCodex({
|
|
461
700
|
auth,
|
|
462
701
|
...descriptor.kind === "codex" && descriptor.effort ? { effort: descriptor.effort } : {},
|
|
463
702
|
...mcpServers ? { mcpServers } : {},
|
|
703
|
+
...plugins.length ? { plugins: plugins.map(({ name, dir }) => ({
|
|
704
|
+
name,
|
|
705
|
+
dir
|
|
706
|
+
})) } : {},
|
|
464
707
|
requireCredentialBrokering: true
|
|
465
708
|
})
|
|
466
709
|
},
|
|
467
710
|
fx: {
|
|
468
711
|
...LAYOUTS.fx,
|
|
712
|
+
pluginParts: ["skills", "mcp"],
|
|
469
713
|
name: "fx",
|
|
470
714
|
factory: "fx",
|
|
471
715
|
...fxForModel("provider/model"),
|
|
472
716
|
forModel: fxForModel,
|
|
473
717
|
mcpServers: acpMcpServers,
|
|
474
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
718
|
+
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-DXNh5mTr.js")).createFx({
|
|
475
719
|
auth,
|
|
476
720
|
model: descriptor.model,
|
|
477
721
|
...mcpServers ? { mcpServers } : {},
|
|
@@ -480,6 +724,8 @@ const AGENTS = {
|
|
|
480
724
|
},
|
|
481
725
|
"grok-build": {
|
|
482
726
|
...LAYOUTS["grok-build"],
|
|
727
|
+
pluginParts: CLAUDE_FORMAT_PARTS,
|
|
728
|
+
pluginServersByName: true,
|
|
483
729
|
name: "Grok Build",
|
|
484
730
|
factory: "grokBuild",
|
|
485
731
|
credential: "XAI_API_KEY",
|
|
@@ -487,9 +733,13 @@ const AGENTS = {
|
|
|
487
733
|
modelResponses: XAI_MODEL_RESPONSES,
|
|
488
734
|
servedModel: xaiServedModel,
|
|
489
735
|
mcpServers: acpMcpServers,
|
|
490
|
-
adapter: async ({ auth, mcpServers, descriptor }) => (await import("./src-
|
|
736
|
+
adapter: async ({ auth, mcpServers, descriptor, plugins }) => (await import("./src-CHIfIKUu.js")).createGrokBuild({
|
|
491
737
|
auth,
|
|
492
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
|
+
} : {},
|
|
493
743
|
...descriptor.kind === "grok-build" && descriptor.effort ? { effort: descriptor.effort } : {},
|
|
494
744
|
...mcpServers ? { mcpServers } : {},
|
|
495
745
|
requireCredentialBrokering: true
|
|
@@ -528,6 +778,139 @@ function refusedMcp(harness, layers) {
|
|
|
528
778
|
throw error;
|
|
529
779
|
}
|
|
530
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
|
+
}
|
|
531
914
|
/** A real agent's catalog entry, with what its model's provider decides. */
|
|
532
915
|
function agentFor(h) {
|
|
533
916
|
const agent = AGENTS[h.kind];
|
|
@@ -544,17 +927,22 @@ const credentialOf = (h) => agentOf(h)?.credential;
|
|
|
544
927
|
const FAKE_LAYOUT = {
|
|
545
928
|
rulesFile: "AGENTS.md",
|
|
546
929
|
workspaceSkillDir: ".agents/skills",
|
|
547
|
-
harnessSkillDir: ".agents/skills"
|
|
930
|
+
harnessSkillDir: ".agents/skills",
|
|
931
|
+
pluginPlacement: "flat"
|
|
548
932
|
};
|
|
549
933
|
/** Where a harness's agent reads rules and skills; a fake one with `layout` mimics that agent. */
|
|
550
934
|
function layoutOf(descriptor) {
|
|
551
935
|
if (descriptor.kind !== "fake") return LAYOUTS[descriptor.kind];
|
|
552
936
|
return descriptor.layout ? LAYOUTS[descriptor.layout] : FAKE_LAYOUT;
|
|
553
937
|
}
|
|
554
|
-
/**
|
|
555
|
-
|
|
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) {
|
|
556
943
|
const kind = descriptor.kind === "fake" ? descriptor.layout : descriptor.kind;
|
|
557
|
-
|
|
944
|
+
const expected = kind ? AGENTS[kind].expectedBlocked : void 0;
|
|
945
|
+
return expected?.withPlugins && !plugins ? void 0 : expected;
|
|
558
946
|
}
|
|
559
947
|
/**
|
|
560
948
|
* How the APIs behind the harnesses say they refused a key: an HTTP 401, Anthropic's and OpenAI's
|
|
@@ -702,10 +1090,21 @@ async function createFakeSandbox(descriptor, env = {}) {
|
|
|
702
1090
|
const base = await mkdtemp(join(parent, "reeval-sandbox-"));
|
|
703
1091
|
const workdir = join(base, "work");
|
|
704
1092
|
await mkdir(workdir);
|
|
1093
|
+
const stateDir = `${base}.state`;
|
|
1094
|
+
await mkdir(stateDir);
|
|
705
1095
|
let destroyed;
|
|
706
1096
|
const resolve = (path) => path.startsWith("~/") ? join(base, path.slice(2)) : join(workdir, path);
|
|
707
1097
|
return {
|
|
708
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
|
+
}),
|
|
709
1108
|
exec: (command, { cwd, env: extra, signal } = {}) => {
|
|
710
1109
|
const tag = process.platform === "win32" && signal ? randomUUID() : void 0;
|
|
711
1110
|
const stop = () => killTagged(sh, tag);
|
|
@@ -731,6 +1130,10 @@ async function createFakeSandbox(descriptor, env = {}) {
|
|
|
731
1130
|
},
|
|
732
1131
|
destroy: () => {
|
|
733
1132
|
destroyed ??= (async () => {
|
|
1133
|
+
await rm(stateDir, {
|
|
1134
|
+
recursive: true,
|
|
1135
|
+
force: true
|
|
1136
|
+
}).catch(() => {});
|
|
734
1137
|
if (process.platform === "win32") {
|
|
735
1138
|
if (existsSync(base)) await runSh(sh, KILL_UNDER, base);
|
|
736
1139
|
await removeTree(base);
|
|
@@ -768,11 +1171,12 @@ function harnessHosts(harness) {
|
|
|
768
1171
|
if (harness.kind !== "fake" && isAgentKind(harness.kind)) return agentFor(harness).hosts ?? HARNESS_HOSTS[harness.kind];
|
|
769
1172
|
return harness.kind === "fake" && harness.layout ? HARNESS_HOSTS[harness.layout] : [];
|
|
770
1173
|
}
|
|
771
|
-
/** 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. */
|
|
772
1175
|
function mcpServerHosts(layers) {
|
|
773
1176
|
const urls = /* @__PURE__ */ new Map();
|
|
774
1177
|
for (const { spec } of layers) for (const [name, server] of Object.entries(spec.mcp ?? {})) if (server.transport === "stdio") urls.delete(name);
|
|
775
1178
|
else urls.set(name, server.url);
|
|
1179
|
+
for (const [name, server] of localPluginServers(layers)) if (server.transport !== "stdio") urls.set(name, server.url);
|
|
776
1180
|
return [...urls.values()].flatMap((url) => URL.parse(url)?.hostname ?? []);
|
|
777
1181
|
}
|
|
778
1182
|
/**
|
|
@@ -832,6 +1236,6 @@ function egressLabel({ policy, auto }) {
|
|
|
832
1236
|
return auto.length ? `${own} + auto: ${auto.join(", ")}` : own;
|
|
833
1237
|
}
|
|
834
1238
|
//#endregion
|
|
835
|
-
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 };
|
|
836
1240
|
|
|
837
|
-
//# sourceMappingURL=egress-
|
|
1241
|
+
//# sourceMappingURL=egress-BfK_O9ce.js.map
|