@cursor/july 0.1.101 → 0.1.102
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 +27 -0
- package/dist/channels/slack/api.d.ts +1 -1
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +3 -1
- package/dist/channels/slack/assistant.d.ts +1 -1
- package/dist/channels/slack/assistant.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.d.ts +3 -2
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +28 -8
- package/dist/channels/slack/inbound.d.ts +8 -0
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +28 -0
- package/dist/channels/slack/manifest.d.ts.map +1 -1
- package/dist/channels/slack/manifest.js +2 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.BASO9Kih.js → app.CLA03RCz.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.FAqdWIXo.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.DwkqxoE0.js → VPLocalSearchBox.ifxv-cJV.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CCil_13e.js → theme.DWCwM6p-.js} +2 -2
- package/dist/docs/assets/concepts.md.rPzW2HZN.js +1 -0
- package/dist/docs/assets/guides_cloud-agents.md.DumwWXba.js +9 -0
- package/dist/docs/assets/guides_cloud-agents.md.DumwWXba.lean.js +1 -0
- package/dist/docs/assets/{guides_cloud-runtime.md.CkYbjnAX.js → guides_cloud-runtime.md.BRirbRAN.js} +1 -1
- package/dist/docs/assets/index.md.Kiht7ell.js +5 -0
- package/dist/docs/assets/{index.md.Bb4k8kUm.lean.js → index.md.Kiht7ell.lean.js} +1 -1
- package/dist/docs/assets/reference_extensions.md.9WQMZe1l.js +56 -0
- package/dist/docs/assets/reference_extensions.md.9WQMZe1l.lean.js +1 -0
- package/dist/docs/assets/{reference_project-layout.md.Bv4KOtlB.js → reference_project-layout.md.CA6QP6Lw.js} +2 -2
- package/dist/docs/assets/{reference_project-layout.md.Bv4KOtlB.lean.js → reference_project-layout.md.CA6QP6Lw.lean.js} +1 -1
- package/dist/docs/assets/{reference_skills.md.BFW9retM.js → reference_skills.md.l2ezAcaN.js} +1 -1
- package/dist/docs/assets/{reference_tools.md.CvAHsdSp.js → reference_tools.md.B1up2r9W.js} +1 -1
- package/dist/docs/assets/skills_framework-map.md.DDa4MeEW.js +1 -0
- package/dist/docs/assets/{skills_framework-map.md.BTi817yv.lean.js → skills_framework-map.md.DDa4MeEW.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +5 -5
- package/dist/docs/concepts.md +3 -3
- package/dist/docs/deployment.html +4 -4
- package/dist/docs/evals.html +4 -4
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/cloud-agents.html +35 -0
- package/dist/docs/guides/cloud-agents.md +93 -0
- package/dist/docs/guides/cloud-runtime.html +6 -6
- package/dist/docs/guides/cloud-runtime.md +2 -0
- package/dist/docs/guides/convert-automation.html +4 -4
- package/dist/docs/guides/github.html +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +4 -4
- package/dist/docs/guides/opentelemetry.html +5 -5
- package/dist/docs/guides/slack.html +4 -4
- package/dist/docs/guides/webhooks.html +4 -4
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +4 -4
- package/dist/docs/index.html +6 -6
- package/dist/docs/index.md +5 -1
- package/dist/docs/llms-full.txt +321 -4
- package/dist/docs/llms.txt +2 -0
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +4 -4
- package/dist/docs/reference/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +5 -5
- package/dist/docs/reference/cli.html +4 -4
- package/dist/docs/reference/connections.html +4 -4
- package/dist/docs/reference/extensions.html +82 -0
- package/dist/docs/reference/extensions.md +200 -0
- package/dist/docs/reference/hooks.html +4 -4
- package/dist/docs/reference/http-api.html +4 -4
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +6 -6
- package/dist/docs/reference/project-layout.md +3 -0
- package/dist/docs/reference/prompt.html +4 -4
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +4 -4
- package/dist/docs/reference/skills.html +6 -6
- package/dist/docs/reference/skills.md +2 -0
- package/dist/docs/reference/subagents.html +5 -5
- package/dist/docs/reference/tools.html +6 -6
- package/dist/docs/reference/tools.md +2 -0
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/skills/ab.html +4 -4
- package/dist/docs/skills/create-agent.html +4 -4
- package/dist/docs/skills/debug.html +4 -4
- package/dist/docs/skills/evals.html +4 -4
- package/dist/docs/skills/framework-map.html +5 -5
- package/dist/docs/skills/framework-map.md +1 -0
- package/dist/docs/skills/github.html +4 -4
- package/dist/docs/skills/hillclimb.html +4 -4
- package/dist/docs/skills/index.html +4 -4
- package/dist/docs/skills/mcp-auth.html +4 -4
- package/dist/docs/skills/otel.html +4 -4
- package/dist/docs/skills/setup-slack.html +4 -4
- package/dist/docs/storage.html +4 -4
- package/dist/docs/templates/agentic-owners.html +4 -4
- package/dist/docs/templates/agents-md.html +4 -4
- package/dist/docs/templates/code-wiki.html +4 -4
- package/dist/docs/templates/demo.html +4 -4
- package/dist/docs/templates/pr-autofixer.html +4 -4
- package/dist/docs/templates/security-help.html +4 -4
- package/dist/docs/templates/security-reviewer.html +4 -4
- package/dist/docs/templates/triage.html +4 -4
- package/dist/docs/troubleshooting.html +4 -4
- package/dist/extensions/cursor-cloud-agents/extension.d.ts +9 -7
- package/dist/extensions/cursor-cloud-agents/extension.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/extension.js +9 -7
- package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts +78 -0
- package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/backend.js +286 -0
- package/dist/extensions/cursor-cloud-agents/lib/inputs.d.ts +5 -0
- package/dist/extensions/cursor-cloud-agents/lib/inputs.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/inputs.js +4 -0
- package/dist/extensions/cursor-cloud-agents/lib/transcript.d.ts +8 -0
- package/dist/extensions/cursor-cloud-agents/lib/transcript.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/transcript.js +15 -0
- package/dist/extensions/cursor-cloud-agents/skills/handoff.md +21 -7
- package/dist/extensions/cursor-cloud-agents/tools/cancel.d.ts +4 -0
- package/dist/extensions/cursor-cloud-agents/tools/cancel.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/tools/cancel.js +26 -0
- package/dist/extensions/cursor-cloud-agents/tools/dump.d.ts +4 -0
- package/dist/extensions/cursor-cloud-agents/tools/dump.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/tools/dump.js +54 -0
- package/dist/extensions/cursor-cloud-agents/tools/get.d.ts +4 -0
- package/dist/extensions/cursor-cloud-agents/tools/get.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/tools/get.js +25 -0
- package/dist/extensions/cursor-cloud-agents/tools/launch.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/tools/launch.js +14 -38
- package/dist/extensions/cursor-cloud-agents/tools/list.js +1 -1
- package/dist/extensions/cursor-cloud-agents/tools/reply.d.ts +4 -0
- package/dist/extensions/cursor-cloud-agents/tools/reply.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/tools/{follow_up.js → reply.js} +12 -14
- package/dist/extensions.d.ts +38 -14
- package/dist/extensions.d.ts.map +1 -1
- package/dist/extensions.js +49 -12
- package/dist/files-backends/cursor-hosted.d.ts +0 -8
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +1 -11
- package/dist/files.d.ts +5 -1
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +22 -18
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/internal/conversation-mirror.d.ts.map +1 -1
- package/dist/internal/conversation-mirror.js +13 -15
- package/dist/internal/cursor/backend-client.d.ts +8 -1
- package/dist/internal/cursor/backend-client.d.ts.map +1 -1
- package/dist/internal/cursor/backend-client.js +25 -9
- package/dist/internal/cursor/hosted-store-secrets.d.ts +11 -0
- package/dist/internal/cursor/hosted-store-secrets.d.ts.map +1 -1
- package/dist/internal/cursor/hosted-store-secrets.js +15 -0
- package/dist/internal/discovery/ab.d.ts +9 -0
- package/dist/internal/discovery/ab.d.ts.map +1 -0
- package/dist/internal/discovery/ab.js +101 -0
- package/dist/internal/discovery/agent-config.d.ts +35 -0
- package/dist/internal/discovery/agent-config.d.ts.map +1 -0
- package/dist/internal/discovery/agent-config.js +173 -0
- package/dist/internal/discovery/agent.d.ts +11 -0
- package/dist/internal/discovery/agent.d.ts.map +1 -0
- package/dist/internal/discovery/agent.js +306 -0
- package/dist/internal/discovery/channels.d.ts +10 -0
- package/dist/internal/discovery/channels.d.ts.map +1 -0
- package/dist/internal/discovery/channels.js +97 -0
- package/dist/internal/discovery/connections.d.ts +17 -0
- package/dist/internal/discovery/connections.d.ts.map +1 -0
- package/dist/internal/discovery/connections.js +436 -0
- package/dist/internal/discovery/context.d.ts +20 -0
- package/dist/internal/discovery/context.d.ts.map +1 -0
- package/dist/internal/discovery/context.js +30 -0
- package/dist/internal/discovery/cursor-plugin.d.ts +25 -0
- package/dist/internal/discovery/cursor-plugin.d.ts.map +1 -0
- package/dist/internal/discovery/cursor-plugin.js +570 -0
- package/dist/internal/discovery/extensions.d.ts +19 -0
- package/dist/internal/discovery/extensions.d.ts.map +1 -0
- package/dist/internal/discovery/extensions.js +238 -0
- package/dist/internal/discovery/fs.d.ts +15 -0
- package/dist/internal/discovery/fs.d.ts.map +1 -0
- package/dist/internal/discovery/fs.js +115 -0
- package/dist/internal/discovery/hooks.d.ts +7 -0
- package/dist/internal/discovery/hooks.d.ts.map +1 -0
- package/dist/internal/discovery/hooks.js +48 -0
- package/dist/internal/discovery/info.d.ts +6 -0
- package/dist/internal/discovery/info.d.ts.map +1 -0
- package/dist/internal/discovery/info.js +141 -0
- package/dist/internal/discovery/instructions.d.ts +7 -0
- package/dist/internal/discovery/instructions.d.ts.map +1 -0
- package/dist/internal/discovery/instructions.js +95 -0
- package/dist/internal/discovery/modules.d.ts +20 -0
- package/dist/internal/discovery/modules.d.ts.map +1 -0
- package/dist/internal/discovery/modules.js +101 -0
- package/dist/internal/discovery/names.d.ts +12 -0
- package/dist/internal/discovery/names.d.ts.map +1 -0
- package/dist/internal/discovery/names.js +36 -0
- package/dist/internal/discovery/project.d.ts +53 -0
- package/dist/internal/discovery/project.d.ts.map +1 -0
- package/dist/internal/discovery/project.js +239 -0
- package/dist/internal/discovery/runtime.d.ts +34 -0
- package/dist/internal/discovery/runtime.d.ts.map +1 -0
- package/dist/internal/discovery/runtime.js +98 -0
- package/dist/internal/discovery/schedules.d.ts +7 -0
- package/dist/internal/discovery/schedules.d.ts.map +1 -0
- package/dist/internal/discovery/schedules.js +97 -0
- package/dist/internal/discovery/seed-files.d.ts +7 -0
- package/dist/internal/discovery/seed-files.d.ts.map +1 -0
- package/dist/internal/discovery/seed-files.js +41 -0
- package/dist/internal/discovery/services.d.ts +17 -0
- package/dist/internal/discovery/services.d.ts.map +1 -0
- package/dist/internal/discovery/services.js +104 -0
- package/dist/internal/discovery/skills.d.ts +16 -0
- package/dist/internal/discovery/skills.d.ts.map +1 -0
- package/dist/internal/discovery/skills.js +151 -0
- package/dist/internal/discovery/subagent.d.ts +13 -0
- package/dist/internal/discovery/subagent.d.ts.map +1 -0
- package/dist/internal/discovery/subagent.js +19 -0
- package/dist/internal/discovery/tools.d.ts +18 -0
- package/dist/internal/discovery/tools.d.ts.map +1 -0
- package/dist/internal/discovery/tools.js +159 -0
- package/dist/internal/discovery.d.ts +8 -62
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +8 -2505
- package/dist/internal/framework-file-storage.js +6 -6
- package/dist/internal/framework-storage-selection.d.ts.map +1 -1
- package/dist/internal/framework-storage-selection.js +8 -7
- package/dist/internal/frontmatter.d.ts +11 -3
- package/dist/internal/frontmatter.d.ts.map +1 -1
- package/dist/internal/frontmatter.js +29 -3
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +37 -20
- package/dist/internal/otel/collector.d.ts +13 -0
- package/dist/internal/otel/collector.d.ts.map +1 -1
- package/dist/internal/otel/collector.js +84 -17
- package/dist/internal/otel/http.d.ts.map +1 -1
- package/dist/internal/otel/http.js +2 -10
- package/dist/internal/otel/mcp.d.ts +16 -0
- package/dist/internal/otel/mcp.d.ts.map +1 -0
- package/dist/internal/otel/mcp.js +68 -0
- package/dist/internal/otel/propagation.d.ts +6 -0
- package/dist/internal/otel/propagation.d.ts.map +1 -0
- package/dist/internal/otel/propagation.js +14 -0
- package/dist/internal/otel/runtime.d.ts.map +1 -1
- package/dist/internal/otel/runtime.js +2 -0
- package/dist/internal/session-engine.d.ts +5 -0
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +68 -32
- package/dist/internal/session-run-log.d.ts +2 -1
- package/dist/internal/session-run-log.d.ts.map +1 -1
- package/dist/internal/session-run-log.js +13 -14
- package/dist/internal/start-log-store.d.ts +1 -1
- package/dist/internal/start-log-store.d.ts.map +1 -1
- package/dist/internal/start-log-store.js +12 -14
- package/dist/internal/storage-coordinator.d.ts +4 -1
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +15 -13
- package/dist/internal/tool-catalog.d.ts.map +1 -1
- package/dist/internal/tool-catalog.js +9 -6
- package/dist/internal/turn-cost.d.ts +14 -0
- package/dist/internal/turn-cost.d.ts.map +1 -1
- package/dist/internal/turn-cost.js +41 -9
- package/dist/internal/v2-hosting.d.ts +22 -0
- package/dist/internal/v2-hosting.d.ts.map +1 -0
- package/dist/internal/v2-hosting.js +23 -0
- package/dist/otel.d.ts +16 -0
- package/dist/otel.d.ts.map +1 -1
- package/dist/otel.js +26 -0
- package/dist/playground/assets/index-B6C9S9nG.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage-protocol.d.ts +24 -23
- package/dist/storage-protocol.d.ts.map +1 -1
- package/dist/storage-protocol.js +68 -65
- package/dist/storage.d.ts +2 -2
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +1 -1
- package/dist/tools.d.ts +9 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +9 -0
- package/dist/types.d.ts +39 -3
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +5 -1
- package/docs/concepts.md +3 -3
- package/docs/guides/cloud-agents.md +98 -0
- package/docs/guides/cloud-runtime.md +2 -0
- package/docs/reference/extensions.md +205 -0
- package/docs/reference/project-layout.md +3 -0
- package/docs/reference/skills.md +2 -0
- package/docs/reference/tools.md +2 -0
- package/package.json +1 -1
- package/skills/framework-map/SKILL.md +1 -0
- package/src/channels/slack/api.ts +4 -2
- package/src/channels/slack/assistant.ts +1 -1
- package/src/channels/slack/dispatch.ts +27 -2
- package/src/channels/slack/inbound.ts +37 -0
- package/src/channels/slack/manifest.ts +2 -1
- package/src/extensions/cursor-cloud-agents/extension.ts +9 -7
- package/src/extensions/cursor-cloud-agents/lib/backend.ts +395 -0
- package/src/extensions/cursor-cloud-agents/lib/inputs.ts +5 -0
- package/src/extensions/cursor-cloud-agents/lib/transcript.ts +23 -0
- package/src/extensions/cursor-cloud-agents/skills/handoff.md +21 -7
- package/src/extensions/cursor-cloud-agents/tools/cancel.ts +19 -0
- package/src/extensions/cursor-cloud-agents/tools/dump.ts +51 -0
- package/src/extensions/cursor-cloud-agents/tools/get.ts +18 -0
- package/src/extensions/cursor-cloud-agents/tools/launch.ts +22 -42
- package/src/extensions/cursor-cloud-agents/tools/list.ts +1 -1
- package/src/extensions/cursor-cloud-agents/tools/reply.ts +34 -0
- package/src/extensions.ts +55 -12
- package/src/files-backends/cursor-hosted.ts +1 -17
- package/src/files.ts +43 -34
- package/src/index.ts +10 -1
- package/src/internal/conversation-mirror.ts +23 -18
- package/src/internal/cursor/backend-client.ts +32 -10
- package/src/internal/cursor/hosted-store-secrets.ts +27 -0
- package/src/internal/discovery/ab.ts +111 -0
- package/src/internal/discovery/agent-config.ts +222 -0
- package/src/internal/discovery/agent.ts +360 -0
- package/src/internal/discovery/channels.ts +103 -0
- package/src/internal/discovery/connections.ts +540 -0
- package/src/internal/discovery/context.ts +46 -0
- package/src/internal/discovery/cursor-plugin.ts +708 -0
- package/src/internal/discovery/extensions.ts +348 -0
- package/src/internal/discovery/fs.ts +108 -0
- package/src/internal/discovery/hooks.ts +45 -0
- package/src/internal/discovery/info.ts +179 -0
- package/src/internal/discovery/instructions.ts +113 -0
- package/src/internal/discovery/modules.ts +107 -0
- package/src/internal/discovery/names.ts +44 -0
- package/src/internal/discovery/project.ts +270 -0
- package/src/internal/discovery/runtime.ts +159 -0
- package/src/internal/discovery/schedules.ts +94 -0
- package/src/internal/discovery/seed-files.ts +37 -0
- package/src/internal/discovery/services.ts +124 -0
- package/src/internal/discovery/skills.ts +176 -0
- package/src/internal/discovery/subagent.ts +29 -0
- package/src/internal/discovery/tools.ts +182 -0
- package/src/internal/discovery.ts +20 -3081
- package/src/internal/framework-file-storage.ts +6 -6
- package/src/internal/framework-storage-selection.ts +9 -9
- package/src/internal/frontmatter.ts +36 -3
- package/src/internal/mcp-host.ts +84 -31
- package/src/internal/otel/collector.ts +125 -25
- package/src/internal/otel/http.ts +2 -12
- package/src/internal/otel/mcp.ts +69 -0
- package/src/internal/otel/propagation.ts +17 -0
- package/src/internal/otel/runtime.ts +2 -0
- package/src/internal/session-engine.ts +96 -11
- package/src/internal/session-run-log.ts +17 -16
- package/src/internal/start-log-store.ts +13 -16
- package/src/internal/storage-coordinator.ts +19 -16
- package/src/internal/tool-catalog.ts +9 -6
- package/src/internal/turn-cost.ts +47 -4
- package/src/internal/v2-hosting.ts +38 -0
- package/src/otel.ts +38 -0
- package/src/storage-protocol.ts +101 -91
- package/src/storage.ts +4 -0
- package/src/tools.ts +18 -0
- package/src/types.ts +43 -2
- package/dist/docs/assets/chunks/@localSearchIndexroot.DbFXINq2.js +0 -1
- package/dist/docs/assets/concepts.md.lwAgBIMI.js +0 -1
- package/dist/docs/assets/index.md.Bb4k8kUm.js +0 -5
- package/dist/docs/assets/skills_framework-map.md.BTi817yv.js +0 -1
- package/dist/extensions/cursor-cloud-agents/lib/cloud.d.ts +0 -30
- package/dist/extensions/cursor-cloud-agents/lib/cloud.d.ts.map +0 -1
- package/dist/extensions/cursor-cloud-agents/lib/cloud.js +0 -45
- package/dist/extensions/cursor-cloud-agents/tools/follow_up.d.ts +0 -4
- package/dist/extensions/cursor-cloud-agents/tools/follow_up.d.ts.map +0 -1
- package/dist/extensions/cursor-cloud-agents/tools/status.d.ts +0 -4
- package/dist/extensions/cursor-cloud-agents/tools/status.d.ts.map +0 -1
- package/dist/extensions/cursor-cloud-agents/tools/status.js +0 -41
- package/dist/playground/assets/index-DBQCwFp0.css +0 -1
- package/src/extensions/cursor-cloud-agents/lib/cloud.ts +0 -79
- package/src/extensions/cursor-cloud-agents/tools/follow_up.ts +0 -29
- package/src/extensions/cursor-cloud-agents/tools/status.ts +0 -39
- /package/dist/docs/assets/{concepts.md.lwAgBIMI.lean.js → concepts.md.rPzW2HZN.lean.js} +0 -0
- /package/dist/docs/assets/{guides_cloud-runtime.md.CkYbjnAX.lean.js → guides_cloud-runtime.md.BRirbRAN.lean.js} +0 -0
- /package/dist/docs/assets/{reference_skills.md.BFW9retM.lean.js → reference_skills.md.l2ezAcaN.lean.js} +0 -0
- /package/dist/docs/assets/{reference_tools.md.CvAHsdSp.lean.js → reference_tools.md.B1up2r9W.lean.js} +0 -0
- /package/dist/playground/assets/{index-BnNN1-EK.js → index-ZqNoT8Ie.js} +0 -0
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agent/mcp-connections/*.ts` and `agent/host-connections/*.ts`: MCP servers for the model and the host.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import {
|
|
7
|
+
type ConnectionDefinition,
|
|
8
|
+
type ConnectionTransport,
|
|
9
|
+
cursorAccountServersHasMixedWildcard,
|
|
10
|
+
type DiscoveredConnection,
|
|
11
|
+
type InlineStdioConnectionConfig,
|
|
12
|
+
isInlineStdioConnection,
|
|
13
|
+
isToolEffect,
|
|
14
|
+
normalizeConnectionEffects,
|
|
15
|
+
normalizeConnectionTools,
|
|
16
|
+
normalizeCursorAccountServers,
|
|
17
|
+
type ToolEffect,
|
|
18
|
+
} from "../../types.js";
|
|
19
|
+
import { packageInlineStdioConnection } from "../package-inline-stdio.js";
|
|
20
|
+
import {
|
|
21
|
+
type DiscoveryContext,
|
|
22
|
+
displayPath,
|
|
23
|
+
errorMessage,
|
|
24
|
+
isBlank,
|
|
25
|
+
} from "./context.js";
|
|
26
|
+
import { isDirectory } from "./fs.js";
|
|
27
|
+
import { importDefault, moduleEntries } from "./modules.js";
|
|
28
|
+
import { NAME_PATTERN } from "./names.js";
|
|
29
|
+
|
|
30
|
+
/** One-line `/v1/info` label for a connection transport. */
|
|
31
|
+
export function connectionTransportLabel(
|
|
32
|
+
transport: ConnectionTransport
|
|
33
|
+
): string {
|
|
34
|
+
if ("cursorAccount" in transport) {
|
|
35
|
+
return transport.servers === undefined
|
|
36
|
+
? "cursor-account"
|
|
37
|
+
: `cursor-account:${transport.servers.join(",")}`;
|
|
38
|
+
}
|
|
39
|
+
if ("agent" in transport) {
|
|
40
|
+
return `agent:${transport.agent}`;
|
|
41
|
+
}
|
|
42
|
+
if ("url" in transport) {
|
|
43
|
+
return transport.oauth === true
|
|
44
|
+
? `${transport.url} (oauth)`
|
|
45
|
+
: transport.url;
|
|
46
|
+
}
|
|
47
|
+
return transport.command;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function hasAuthorizationHeader(
|
|
51
|
+
headers: Record<string, string> | undefined
|
|
52
|
+
): boolean {
|
|
53
|
+
if (headers === undefined) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
return Object.keys(headers).some(
|
|
57
|
+
(key) => key.toLowerCase() === "authorization"
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function parseConnectionEffects(
|
|
62
|
+
effects: unknown
|
|
63
|
+
): { ok: true; value: ToolEffect[] | undefined } | { ok: false } {
|
|
64
|
+
if (effects === undefined) {
|
|
65
|
+
return { ok: true, value: undefined };
|
|
66
|
+
}
|
|
67
|
+
const raw = typeof effects === "string" ? [effects] : effects;
|
|
68
|
+
if (!Array.isArray(raw) || raw.length === 0) {
|
|
69
|
+
return { ok: false };
|
|
70
|
+
}
|
|
71
|
+
const parsed: ToolEffect[] = [];
|
|
72
|
+
for (const value of raw) {
|
|
73
|
+
if (!isToolEffect(value)) {
|
|
74
|
+
return { ok: false };
|
|
75
|
+
}
|
|
76
|
+
parsed.push(value);
|
|
77
|
+
}
|
|
78
|
+
return { ok: true, value: normalizeConnectionEffects(parsed) };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function parseConnectionTools(
|
|
82
|
+
tools: unknown
|
|
83
|
+
): { ok: true; value: string[] | undefined } | { ok: false } {
|
|
84
|
+
if (tools === undefined) {
|
|
85
|
+
return { ok: true, value: undefined };
|
|
86
|
+
}
|
|
87
|
+
if (!Array.isArray(tools) || tools.length === 0) {
|
|
88
|
+
return { ok: false };
|
|
89
|
+
}
|
|
90
|
+
if (tools.some((name) => typeof name !== "string")) {
|
|
91
|
+
return { ok: false };
|
|
92
|
+
}
|
|
93
|
+
const normalized = normalizeConnectionTools(tools);
|
|
94
|
+
if (normalized.length === 0) {
|
|
95
|
+
return { ok: false };
|
|
96
|
+
}
|
|
97
|
+
return { ok: true, value: normalized };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function connectionHasSpawnOrRemote(connection: ConnectionDefinition): boolean {
|
|
101
|
+
if ("cursorAccount" in connection && connection.cursorAccount === true) {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
if ("agent" in connection && !isBlank(connection.agent)) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
if ("url" in connection && !isBlank(connection.url)) {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
return "command" in connection && !isBlank(connection.command);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function connectionTransport(
|
|
114
|
+
connection: ConnectionDefinition
|
|
115
|
+
): ConnectionTransport | undefined {
|
|
116
|
+
if ("cursorAccount" in connection && connection.cursorAccount === true) {
|
|
117
|
+
const servers = normalizeCursorAccountServers(connection.servers);
|
|
118
|
+
return {
|
|
119
|
+
cursorAccount: true,
|
|
120
|
+
...(servers === undefined ? {} : { servers }),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
if ("agent" in connection && !isBlank(connection.agent)) {
|
|
124
|
+
return { agent: connection.agent };
|
|
125
|
+
}
|
|
126
|
+
if ("url" in connection && !isBlank(connection.url)) {
|
|
127
|
+
return {
|
|
128
|
+
type: connection.type,
|
|
129
|
+
url: connection.url,
|
|
130
|
+
headers: connection.headers,
|
|
131
|
+
oauth: connection.oauth === true ? true : undefined,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
if ("command" in connection && !isBlank(connection.command)) {
|
|
135
|
+
return {
|
|
136
|
+
...(connection.type === undefined ? {} : { type: connection.type }),
|
|
137
|
+
command: connection.command,
|
|
138
|
+
...(connection.args === undefined ? {} : { args: connection.args }),
|
|
139
|
+
...(connection.env === undefined ? {} : { env: connection.env }),
|
|
140
|
+
...(connection.cwd === undefined ? {} : { cwd: connection.cwd }),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Prefer `agent/mcp-connections/`. Keep loading `agent/connections/` with a
|
|
148
|
+
* deprecation warning so existing agents keep working during the rename.
|
|
149
|
+
*/
|
|
150
|
+
export async function resolveMcpConnectionsDir(
|
|
151
|
+
ctx: DiscoveryContext,
|
|
152
|
+
agentDir: string
|
|
153
|
+
): Promise<string> {
|
|
154
|
+
const preferred = join(agentDir, "mcp-connections");
|
|
155
|
+
const legacy = join(agentDir, "connections");
|
|
156
|
+
const hasPreferred = await isDirectory(preferred);
|
|
157
|
+
const hasLegacy = await isDirectory(legacy);
|
|
158
|
+
if (hasPreferred && hasLegacy) {
|
|
159
|
+
ctx.diagnostics.push({
|
|
160
|
+
severity: "warning",
|
|
161
|
+
path: displayPath(ctx, legacy),
|
|
162
|
+
message:
|
|
163
|
+
"Both agent/mcp-connections/ and agent/connections/ exist; using mcp-connections/ and ignoring connections/. Rename or remove the legacy directory.",
|
|
164
|
+
});
|
|
165
|
+
return preferred;
|
|
166
|
+
}
|
|
167
|
+
if (hasLegacy) {
|
|
168
|
+
ctx.diagnostics.push({
|
|
169
|
+
severity: "warning",
|
|
170
|
+
path: displayPath(ctx, legacy),
|
|
171
|
+
message:
|
|
172
|
+
"agent/connections/ is deprecated; rename it to agent/mcp-connections/. Loading from the legacy path for now.",
|
|
173
|
+
});
|
|
174
|
+
return legacy;
|
|
175
|
+
}
|
|
176
|
+
return preferred;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export async function loadHostConnections(
|
|
180
|
+
ctx: DiscoveryContext,
|
|
181
|
+
agentDir: string,
|
|
182
|
+
modelConnections: readonly DiscoveredConnection[]
|
|
183
|
+
): Promise<DiscoveredConnection[]> {
|
|
184
|
+
const hostDir = join(agentDir, "host-connections");
|
|
185
|
+
const loaded = await loadConnections(ctx, hostDir, "host");
|
|
186
|
+
const modelNames = new Set(
|
|
187
|
+
modelConnections.map((connection) => connection.name)
|
|
188
|
+
);
|
|
189
|
+
const hostConnections: DiscoveredConnection[] = [];
|
|
190
|
+
for (const connection of loaded) {
|
|
191
|
+
if (modelNames.has(connection.name)) {
|
|
192
|
+
ctx.diagnostics.push({
|
|
193
|
+
severity: "error",
|
|
194
|
+
path: displayPath(ctx, join(hostDir, `${connection.name}.ts`)),
|
|
195
|
+
message: `Host connection "${connection.name}" collides with agent/mcp-connections/${connection.name}. Rename one of them.`,
|
|
196
|
+
});
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
if (connection.advertiseTools === true) {
|
|
200
|
+
ctx.diagnostics.push({
|
|
201
|
+
severity: "error",
|
|
202
|
+
path: displayPath(ctx, join(hostDir, `${connection.name}.ts`)),
|
|
203
|
+
message:
|
|
204
|
+
"Host connections are off the model. `advertiseTools` cannot apply. Drop it.",
|
|
205
|
+
});
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
if (connection.auth !== undefined) {
|
|
209
|
+
ctx.diagnostics.push({
|
|
210
|
+
severity: "error",
|
|
211
|
+
path: displayPath(ctx, join(hostDir, `${connection.name}.ts`)),
|
|
212
|
+
message:
|
|
213
|
+
"Host connections are off the model. `auth` cannot apply. Use static headers or `oauth: true`.",
|
|
214
|
+
});
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
hostConnections.push(connection);
|
|
218
|
+
}
|
|
219
|
+
return hostConnections;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export async function loadConnections(
|
|
223
|
+
ctx: DiscoveryContext,
|
|
224
|
+
connectionsDir: string,
|
|
225
|
+
role: "model" | "host" = "model"
|
|
226
|
+
): Promise<DiscoveredConnection[]> {
|
|
227
|
+
const connections: DiscoveredConnection[] = [];
|
|
228
|
+
for (const { name, path } of await moduleEntries(
|
|
229
|
+
ctx,
|
|
230
|
+
connectionsDir,
|
|
231
|
+
"connection"
|
|
232
|
+
)) {
|
|
233
|
+
const definition = await importDefault(ctx, path, "connection");
|
|
234
|
+
if (definition === undefined) {
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
const connection = await compileConnection(
|
|
238
|
+
ctx,
|
|
239
|
+
path,
|
|
240
|
+
name,
|
|
241
|
+
definition as ConnectionDefinition,
|
|
242
|
+
role
|
|
243
|
+
);
|
|
244
|
+
if (connection !== undefined) {
|
|
245
|
+
connections.push(connection);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return connections;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/** Validate one `defineConnection` and resolve its transport. */
|
|
252
|
+
export async function compileConnection(
|
|
253
|
+
ctx: DiscoveryContext,
|
|
254
|
+
entryPath: string,
|
|
255
|
+
name: string,
|
|
256
|
+
connection: ConnectionDefinition,
|
|
257
|
+
role: "model" | "host"
|
|
258
|
+
): Promise<DiscoveredConnection | undefined> {
|
|
259
|
+
if (Object.hasOwn(connection, "hostOnly")) {
|
|
260
|
+
ctx.diagnostics.push({
|
|
261
|
+
severity: "error",
|
|
262
|
+
path: displayPath(ctx, entryPath),
|
|
263
|
+
message:
|
|
264
|
+
"MCP connection `hostOnly` was removed. Files under `agent/mcp-connections/` are always visible to the model. Put privileged servers in `agent/host-connections/` so only host tools can call them.",
|
|
265
|
+
});
|
|
266
|
+
return undefined;
|
|
267
|
+
}
|
|
268
|
+
if (
|
|
269
|
+
isInlineStdioConnection(connection) &&
|
|
270
|
+
connectionHasSpawnOrRemote(connection)
|
|
271
|
+
) {
|
|
272
|
+
ctx.diagnostics.push({
|
|
273
|
+
severity: "error",
|
|
274
|
+
path: displayPath(ctx, entryPath),
|
|
275
|
+
message:
|
|
276
|
+
"MCP connection `tools` cannot be combined with `command`, `url`, `agent`, or `cursorAccount`. Author TypeScript tools, or point at an existing server, not both.",
|
|
277
|
+
});
|
|
278
|
+
return undefined;
|
|
279
|
+
}
|
|
280
|
+
if (connection.auth !== undefined && typeof connection.auth !== "function") {
|
|
281
|
+
ctx.diagnostics.push({
|
|
282
|
+
severity: "error",
|
|
283
|
+
path: displayPath(ctx, entryPath),
|
|
284
|
+
message:
|
|
285
|
+
"MCP connection `auth` must be a function: (session) => { headers }.",
|
|
286
|
+
});
|
|
287
|
+
return undefined;
|
|
288
|
+
}
|
|
289
|
+
if (connection.auth !== undefined && !("url" in connection)) {
|
|
290
|
+
ctx.diagnostics.push({
|
|
291
|
+
severity: "error",
|
|
292
|
+
path: displayPath(ctx, entryPath),
|
|
293
|
+
message:
|
|
294
|
+
"MCP connection `auth` (per-session headers) is only supported on http/sse connections (`url`).",
|
|
295
|
+
});
|
|
296
|
+
return undefined;
|
|
297
|
+
}
|
|
298
|
+
if (
|
|
299
|
+
connection.advertiseTools !== undefined &&
|
|
300
|
+
typeof connection.advertiseTools !== "boolean"
|
|
301
|
+
) {
|
|
302
|
+
ctx.diagnostics.push({
|
|
303
|
+
severity: "error",
|
|
304
|
+
path: displayPath(ctx, entryPath),
|
|
305
|
+
message: "MCP connection `advertiseTools` must be a boolean.",
|
|
306
|
+
});
|
|
307
|
+
return undefined;
|
|
308
|
+
}
|
|
309
|
+
const parsedEffects = parseConnectionEffects(connection.effects);
|
|
310
|
+
if (!parsedEffects.ok) {
|
|
311
|
+
ctx.diagnostics.push({
|
|
312
|
+
severity: "error",
|
|
313
|
+
path: displayPath(ctx, entryPath),
|
|
314
|
+
message:
|
|
315
|
+
'MCP connection `effects` must be "read", "write", or a non-empty array of those.',
|
|
316
|
+
});
|
|
317
|
+
return undefined;
|
|
318
|
+
}
|
|
319
|
+
if (parsedEffects.value !== undefined && connection.advertiseTools !== true) {
|
|
320
|
+
ctx.diagnostics.push({
|
|
321
|
+
severity: "error",
|
|
322
|
+
path: displayPath(ctx, entryPath),
|
|
323
|
+
message:
|
|
324
|
+
"MCP connection `effects` filters advertised tools; set `advertiseTools: true` or drop `effects`.",
|
|
325
|
+
});
|
|
326
|
+
return undefined;
|
|
327
|
+
}
|
|
328
|
+
const parsedTools = isInlineStdioConnection(connection)
|
|
329
|
+
? { ok: true as const, value: undefined }
|
|
330
|
+
: parseConnectionTools(connection.tools);
|
|
331
|
+
if (!parsedTools.ok) {
|
|
332
|
+
ctx.diagnostics.push({
|
|
333
|
+
severity: "error",
|
|
334
|
+
path: displayPath(ctx, entryPath),
|
|
335
|
+
message:
|
|
336
|
+
"MCP connection `tools` allowlist must be a non-empty array of tool names.",
|
|
337
|
+
});
|
|
338
|
+
return undefined;
|
|
339
|
+
}
|
|
340
|
+
if (
|
|
341
|
+
isInlineStdioConnection(connection) &&
|
|
342
|
+
connection.disallowedTools !== undefined
|
|
343
|
+
) {
|
|
344
|
+
ctx.diagnostics.push({
|
|
345
|
+
severity: "error",
|
|
346
|
+
path: displayPath(ctx, entryPath),
|
|
347
|
+
message:
|
|
348
|
+
"MCP connection `disallowedTools` is not supported on inline `tools` connections — author only the tools you want.",
|
|
349
|
+
});
|
|
350
|
+
return undefined;
|
|
351
|
+
}
|
|
352
|
+
const parsedDisallowed = isInlineStdioConnection(connection)
|
|
353
|
+
? { ok: true as const, value: undefined }
|
|
354
|
+
: parseConnectionTools(connection.disallowedTools);
|
|
355
|
+
if (!parsedDisallowed.ok) {
|
|
356
|
+
ctx.diagnostics.push({
|
|
357
|
+
severity: "error",
|
|
358
|
+
path: displayPath(ctx, entryPath),
|
|
359
|
+
message:
|
|
360
|
+
"MCP connection `disallowedTools` must be a non-empty array of tool names.",
|
|
361
|
+
});
|
|
362
|
+
return undefined;
|
|
363
|
+
}
|
|
364
|
+
if (
|
|
365
|
+
(parsedTools.value !== undefined || parsedDisallowed.value !== undefined) &&
|
|
366
|
+
role === "model" &&
|
|
367
|
+
connection.advertiseTools !== true
|
|
368
|
+
) {
|
|
369
|
+
ctx.diagnostics.push({
|
|
370
|
+
severity: "error",
|
|
371
|
+
path: displayPath(ctx, entryPath),
|
|
372
|
+
message:
|
|
373
|
+
"MCP connection `tools` / `disallowedTools` filter advertised tools; set `advertiseTools: true` or drop the name list. Put the connection in `agent/host-connections/` to restrict `host.mcp` only.",
|
|
374
|
+
});
|
|
375
|
+
return undefined;
|
|
376
|
+
}
|
|
377
|
+
if (
|
|
378
|
+
connection.advertiseTools === true &&
|
|
379
|
+
isInlineStdioConnection(connection)
|
|
380
|
+
) {
|
|
381
|
+
ctx.diagnostics.push({
|
|
382
|
+
severity: "error",
|
|
383
|
+
path: displayPath(ctx, entryPath),
|
|
384
|
+
message:
|
|
385
|
+
"MCP connection `advertiseTools` is not supported on inline `tools` connections — author those as agent/tools/ server tools instead.",
|
|
386
|
+
});
|
|
387
|
+
return undefined;
|
|
388
|
+
}
|
|
389
|
+
if (
|
|
390
|
+
connection.auth !== undefined &&
|
|
391
|
+
"url" in connection &&
|
|
392
|
+
connection.oauth === true
|
|
393
|
+
) {
|
|
394
|
+
ctx.diagnostics.push({
|
|
395
|
+
severity: "error",
|
|
396
|
+
path: displayPath(ctx, entryPath),
|
|
397
|
+
message:
|
|
398
|
+
"MCP connection `oauth: true` cannot be combined with `auth` (per-session headers): the host OAuth provider owns the Authorization header. Drop one of them.",
|
|
399
|
+
});
|
|
400
|
+
return undefined;
|
|
401
|
+
}
|
|
402
|
+
if (isInlineStdioConnection(connection)) {
|
|
403
|
+
return loadInlineStdioConnection(ctx, name, entryPath, connection);
|
|
404
|
+
}
|
|
405
|
+
if (
|
|
406
|
+
"url" in connection &&
|
|
407
|
+
connection.oauth === true &&
|
|
408
|
+
hasAuthorizationHeader(connection.headers)
|
|
409
|
+
) {
|
|
410
|
+
ctx.diagnostics.push({
|
|
411
|
+
severity: "error",
|
|
412
|
+
path: displayPath(ctx, entryPath),
|
|
413
|
+
message:
|
|
414
|
+
"MCP connection `oauth: true` cannot set an Authorization header. Drop the header or remove `oauth`.",
|
|
415
|
+
});
|
|
416
|
+
return undefined;
|
|
417
|
+
}
|
|
418
|
+
if (
|
|
419
|
+
"cursorAccount" in connection &&
|
|
420
|
+
connection.cursorAccount === true &&
|
|
421
|
+
cursorAccountServersHasMixedWildcard(connection.servers)
|
|
422
|
+
) {
|
|
423
|
+
ctx.diagnostics.push({
|
|
424
|
+
severity: "error",
|
|
425
|
+
path: displayPath(ctx, entryPath),
|
|
426
|
+
message:
|
|
427
|
+
'Cursor account MCP connection `servers` cannot mix `"*"` with connector names. Use `"*"` / `["*"]` (or omit `servers`) for every connected server, or list only concrete connector names.',
|
|
428
|
+
});
|
|
429
|
+
return undefined;
|
|
430
|
+
}
|
|
431
|
+
const transport = connectionTransport(connection);
|
|
432
|
+
if (transport === undefined) {
|
|
433
|
+
ctx.diagnostics.push({
|
|
434
|
+
severity: "error",
|
|
435
|
+
path: displayPath(ctx, entryPath),
|
|
436
|
+
message:
|
|
437
|
+
"MCP connections require a `url` (http/sse), a `command` (stdio), `tools` (TypeScript packaged as stdio), an `agent` (peer agent slug on the same serve host), or `cursorAccount: true` (the Cursor account's MCP connectors).",
|
|
438
|
+
});
|
|
439
|
+
return undefined;
|
|
440
|
+
}
|
|
441
|
+
if (
|
|
442
|
+
"cursorAccount" in transport &&
|
|
443
|
+
transport.servers !== undefined &&
|
|
444
|
+
(transport.servers.length === 0 ||
|
|
445
|
+
transport.servers.some((server) => isBlank(server)))
|
|
446
|
+
) {
|
|
447
|
+
ctx.diagnostics.push({
|
|
448
|
+
severity: "error",
|
|
449
|
+
path: displayPath(ctx, entryPath),
|
|
450
|
+
message:
|
|
451
|
+
'Cursor account MCP connection `servers` must be a non-empty list of connector names, `"*"` / `["*"]` for every connected server, or omitted for the same all-connectors behavior.',
|
|
452
|
+
});
|
|
453
|
+
return undefined;
|
|
454
|
+
}
|
|
455
|
+
if ("agent" in transport && !NAME_PATTERN.test(transport.agent)) {
|
|
456
|
+
ctx.diagnostics.push({
|
|
457
|
+
severity: "error",
|
|
458
|
+
path: displayPath(ctx, entryPath),
|
|
459
|
+
message: `Peer MCP connection agent "${transport.agent}" must be a mount slug matching ${NAME_PATTERN}.`,
|
|
460
|
+
});
|
|
461
|
+
return undefined;
|
|
462
|
+
}
|
|
463
|
+
return {
|
|
464
|
+
name,
|
|
465
|
+
transport,
|
|
466
|
+
description: connection.description,
|
|
467
|
+
auth: connection.auth,
|
|
468
|
+
advertiseTools: connection.advertiseTools,
|
|
469
|
+
effects: parsedEffects.value,
|
|
470
|
+
tools: parsedTools.value,
|
|
471
|
+
disallowedTools: parsedDisallowed.value,
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
async function loadInlineStdioConnection(
|
|
476
|
+
ctx: DiscoveryContext,
|
|
477
|
+
name: string,
|
|
478
|
+
entryPath: string,
|
|
479
|
+
connection: InlineStdioConnectionConfig & {
|
|
480
|
+
description?: string;
|
|
481
|
+
}
|
|
482
|
+
): Promise<DiscoveredConnection | undefined> {
|
|
483
|
+
const tools = connection.tools;
|
|
484
|
+
const names = Object.keys(tools);
|
|
485
|
+
if (names.length === 0) {
|
|
486
|
+
ctx.diagnostics.push({
|
|
487
|
+
severity: "error",
|
|
488
|
+
path: displayPath(ctx, entryPath),
|
|
489
|
+
message: "MCP connection `tools` must declare at least one tool.",
|
|
490
|
+
});
|
|
491
|
+
return undefined;
|
|
492
|
+
}
|
|
493
|
+
for (const toolName of names) {
|
|
494
|
+
if (!NAME_PATTERN.test(toolName)) {
|
|
495
|
+
ctx.diagnostics.push({
|
|
496
|
+
severity: "error",
|
|
497
|
+
path: displayPath(ctx, entryPath),
|
|
498
|
+
message: `MCP tool name "${toolName}" must match ${NAME_PATTERN}.`,
|
|
499
|
+
});
|
|
500
|
+
return undefined;
|
|
501
|
+
}
|
|
502
|
+
const tool = tools[toolName];
|
|
503
|
+
if (tool === undefined || isBlank(tool.description)) {
|
|
504
|
+
ctx.diagnostics.push({
|
|
505
|
+
severity: "error",
|
|
506
|
+
path: displayPath(ctx, entryPath),
|
|
507
|
+
message: `MCP tool "${toolName}" requires a non-empty description.`,
|
|
508
|
+
});
|
|
509
|
+
return undefined;
|
|
510
|
+
}
|
|
511
|
+
if (typeof tool.execute !== "function") {
|
|
512
|
+
ctx.diagnostics.push({
|
|
513
|
+
severity: "error",
|
|
514
|
+
path: displayPath(ctx, entryPath),
|
|
515
|
+
message: `MCP tool "${toolName}" requires an execute(input) function.`,
|
|
516
|
+
});
|
|
517
|
+
return undefined;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
try {
|
|
521
|
+
const transport = await packageInlineStdioConnection({
|
|
522
|
+
name,
|
|
523
|
+
entryPath,
|
|
524
|
+
tools,
|
|
525
|
+
absWorkingDir: ctx.rootDir,
|
|
526
|
+
});
|
|
527
|
+
return {
|
|
528
|
+
name,
|
|
529
|
+
transport,
|
|
530
|
+
description: connection.description,
|
|
531
|
+
};
|
|
532
|
+
} catch (error) {
|
|
533
|
+
ctx.diagnostics.push({
|
|
534
|
+
severity: "error",
|
|
535
|
+
path: displayPath(ctx, entryPath),
|
|
536
|
+
message: `Failed to package inline stdio MCP connection: ${errorMessage(error)}`,
|
|
537
|
+
});
|
|
538
|
+
return undefined;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared discovery state: the loader options, the per-project context every loader receives, and the diagnostic helpers.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { relative } from "node:path";
|
|
6
|
+
import { pathToFileURL } from "node:url";
|
|
7
|
+
import type { Diagnostic } from "../../types.js";
|
|
8
|
+
import { toPosix } from "./fs.js";
|
|
9
|
+
|
|
10
|
+
export interface LoadAgentProjectOptions {
|
|
11
|
+
/** Override the module loader (embedders / tests). */
|
|
12
|
+
importModule?: (absolutePath: string) => Promise<Record<string, unknown>>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type ImportModule = (absolutePath: string) => Promise<Record<string, unknown>>;
|
|
16
|
+
|
|
17
|
+
export async function defaultImportModule(
|
|
18
|
+
absolutePath: string
|
|
19
|
+
): Promise<Record<string, unknown>> {
|
|
20
|
+
return (await import(pathToFileURL(absolutePath).href)) as Record<
|
|
21
|
+
string,
|
|
22
|
+
unknown
|
|
23
|
+
>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface DiscoveryContext {
|
|
27
|
+
rootDir: string;
|
|
28
|
+
diagnostics: Diagnostic[];
|
|
29
|
+
importModule: ImportModule;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function displayPath(
|
|
33
|
+
ctx: DiscoveryContext,
|
|
34
|
+
absolutePath: string
|
|
35
|
+
): string {
|
|
36
|
+
const rel = relative(ctx.rootDir, absolutePath);
|
|
37
|
+
return rel.startsWith("..") ? absolutePath : toPosix(rel);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function errorMessage(error: unknown): string {
|
|
41
|
+
return error instanceof Error ? error.message : String(error);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function isBlank(value: unknown): boolean {
|
|
45
|
+
return typeof value !== "string" || value.trim() === "";
|
|
46
|
+
}
|