@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,348 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agent/extensions/<ns>.ts` | `agent/extensions/<ns>/extension.ts`: agent-shaped trees and Cursor plugins mounted under a namespace.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Dirent } from "node:fs";
|
|
6
|
+
import { join, resolve } from "node:path";
|
|
7
|
+
import type {
|
|
8
|
+
ConnectionDefinition,
|
|
9
|
+
DiscoveredConnection,
|
|
10
|
+
DiscoveredExtension,
|
|
11
|
+
DiscoveredSkill,
|
|
12
|
+
DiscoveredTool,
|
|
13
|
+
ExtensionMount,
|
|
14
|
+
ResolvedAgent,
|
|
15
|
+
ToolDefinition,
|
|
16
|
+
} from "../../types.js";
|
|
17
|
+
import { getDefinitionKind } from "../brand.js";
|
|
18
|
+
import { compileConnection } from "./connections.js";
|
|
19
|
+
import { type DiscoveryContext, displayPath } from "./context.js";
|
|
20
|
+
import { type CursorPluginAgent, readCursorPlugin } from "./cursor-plugin.js";
|
|
21
|
+
import {
|
|
22
|
+
findModuleFile,
|
|
23
|
+
isDirectory,
|
|
24
|
+
isFile,
|
|
25
|
+
isModuleFile,
|
|
26
|
+
moduleStem,
|
|
27
|
+
sortedEntries,
|
|
28
|
+
} from "./fs.js";
|
|
29
|
+
import { helperCall, importDefault, moduleEntries } from "./modules.js";
|
|
30
|
+
import { validateName } from "./names.js";
|
|
31
|
+
import { loadSkills } from "./skills.js";
|
|
32
|
+
import { subagent } from "./subagent.js";
|
|
33
|
+
import { compileTool, loadTools } from "./tools.js";
|
|
34
|
+
|
|
35
|
+
/** The agent's authored slot lists that mounted extensions append to. */
|
|
36
|
+
export interface ExtensionContributions {
|
|
37
|
+
tools: DiscoveredTool[];
|
|
38
|
+
skills: DiscoveredSkill[];
|
|
39
|
+
connections: DiscoveredConnection[];
|
|
40
|
+
subagents: ResolvedAgent[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Mount every extension under `agent/extensions/` and append what it
|
|
45
|
+
* contributes to the authored lists as `<ns>__<name>`, stamped with
|
|
46
|
+
* `extension`. The namespace is the mount's filename stem or directory name.
|
|
47
|
+
*/
|
|
48
|
+
export async function appendExtensions(
|
|
49
|
+
ctx: DiscoveryContext,
|
|
50
|
+
extensionsDir: string,
|
|
51
|
+
into: ExtensionContributions
|
|
52
|
+
): Promise<DiscoveredExtension[]> {
|
|
53
|
+
if (!(await isDirectory(extensionsDir))) {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
const extensions: DiscoveredExtension[] = [];
|
|
57
|
+
for (const entry of await sortedEntries(extensionsDir)) {
|
|
58
|
+
const path = join(extensionsDir, entry.name);
|
|
59
|
+
const site = await resolveMountSite(ctx, path, entry);
|
|
60
|
+
if (site === undefined) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (extensions.some((extension) => extension.name === site.ns)) {
|
|
64
|
+
ctx.diagnostics.push({
|
|
65
|
+
severity: "error",
|
|
66
|
+
path: displayPath(ctx, path),
|
|
67
|
+
message: `Extension "${site.ns}" is mounted twice (as a file and as a directory).`,
|
|
68
|
+
});
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const mount = await importDefault(ctx, site.mountPath, "extension");
|
|
72
|
+
if (mount === undefined) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
extensions.push(
|
|
76
|
+
await mountExtension(ctx, site, mount as ExtensionMount, into)
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
return extensions;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
interface MountSite {
|
|
83
|
+
ns: string;
|
|
84
|
+
/** The module default-exporting the {@link ExtensionMount}. */
|
|
85
|
+
mountPath: string;
|
|
86
|
+
/** A directory mount; its `tools/` and `skills/` overlay the extension's. */
|
|
87
|
+
overlayDir?: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function resolveMountSite(
|
|
91
|
+
ctx: DiscoveryContext,
|
|
92
|
+
path: string,
|
|
93
|
+
entry: Dirent
|
|
94
|
+
): Promise<MountSite | undefined> {
|
|
95
|
+
if (entry.isDirectory()) {
|
|
96
|
+
if (!validateName(ctx, "extension", entry.name, path)) {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
const mountPath = await findModuleFile(path, "extension");
|
|
100
|
+
if (mountPath === undefined) {
|
|
101
|
+
ctx.diagnostics.push({
|
|
102
|
+
severity: "error",
|
|
103
|
+
path: displayPath(ctx, path),
|
|
104
|
+
message:
|
|
105
|
+
"A directory mount needs an extension.ts default-exporting the mount (`export default ci({ ... })`).",
|
|
106
|
+
});
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
return { ns: entry.name, mountPath, overlayDir: path };
|
|
110
|
+
}
|
|
111
|
+
if (!entry.isFile() || !isModuleFile(entry.name)) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
const ns = moduleStem(entry.name);
|
|
115
|
+
return validateName(ctx, "extension", ns, path)
|
|
116
|
+
? { ns, mountPath: path }
|
|
117
|
+
: undefined;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** What a mounted tree contributes, under the tree's own names. */
|
|
121
|
+
interface ExtensionTree {
|
|
122
|
+
description?: string;
|
|
123
|
+
tools: DiscoveredTool[];
|
|
124
|
+
skills: DiscoveredSkill[];
|
|
125
|
+
connections: DiscoveredConnection[];
|
|
126
|
+
/** Connection names the tree declares but left to the mount's overlay. */
|
|
127
|
+
overlaidServers: string[];
|
|
128
|
+
agents: CursorPluginAgent[];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Read the extension's tree, lay the mount's overlay on top (a same-named
|
|
133
|
+
* file replaces, `disableTool()` removes), then namespace what is left.
|
|
134
|
+
*/
|
|
135
|
+
async function mountExtension(
|
|
136
|
+
ctx: DiscoveryContext,
|
|
137
|
+
site: MountSite,
|
|
138
|
+
mount: ExtensionMount,
|
|
139
|
+
into: ExtensionContributions
|
|
140
|
+
): Promise<DiscoveredExtension> {
|
|
141
|
+
const mounted: DiscoveredExtension = {
|
|
142
|
+
name: site.ns,
|
|
143
|
+
description: mount.extension.description,
|
|
144
|
+
tools: [],
|
|
145
|
+
skills: [],
|
|
146
|
+
connections: [],
|
|
147
|
+
subagents: [],
|
|
148
|
+
};
|
|
149
|
+
const root = resolve(ctx.rootDir, mount.extension.root);
|
|
150
|
+
if (!(await isDirectory(root))) {
|
|
151
|
+
const hint =
|
|
152
|
+
"layout" in mount.extension
|
|
153
|
+
? "Point `path` at the plugin directory."
|
|
154
|
+
: "Pass `import.meta.dirname` from extension.ts.";
|
|
155
|
+
ctx.diagnostics.push({
|
|
156
|
+
severity: "error",
|
|
157
|
+
path: displayPath(ctx, site.mountPath),
|
|
158
|
+
message: `Extension "${site.ns}" declares root ${root}, which is not a directory. ${hint}`,
|
|
159
|
+
});
|
|
160
|
+
return mounted;
|
|
161
|
+
}
|
|
162
|
+
// The connection overlay is read first so the tree can leave overlaid
|
|
163
|
+
// servers uncompiled: a plugin server you replace or drop needs no values.
|
|
164
|
+
const connectionOverlay =
|
|
165
|
+
site.overlayDir === undefined
|
|
166
|
+
? []
|
|
167
|
+
: await moduleEntries(
|
|
168
|
+
ctx,
|
|
169
|
+
join(site.overlayDir, "mcp-connections"),
|
|
170
|
+
"connection"
|
|
171
|
+
);
|
|
172
|
+
const tree = await readExtensionTree(
|
|
173
|
+
ctx,
|
|
174
|
+
site,
|
|
175
|
+
mount,
|
|
176
|
+
root,
|
|
177
|
+
new Set(connectionOverlay.map((entry) => entry.name))
|
|
178
|
+
);
|
|
179
|
+
if (tree === undefined) {
|
|
180
|
+
return mounted;
|
|
181
|
+
}
|
|
182
|
+
mounted.description = mount.extension.description ?? tree.description;
|
|
183
|
+
const tools = byName(tree.tools);
|
|
184
|
+
const skills = byName(tree.skills);
|
|
185
|
+
const connections = byName(tree.connections);
|
|
186
|
+
if (site.overlayDir !== undefined) {
|
|
187
|
+
await overlaySlot(
|
|
188
|
+
ctx,
|
|
189
|
+
site,
|
|
190
|
+
tools,
|
|
191
|
+
await moduleEntries(ctx, join(site.overlayDir, "tools"), "tool"),
|
|
192
|
+
{
|
|
193
|
+
kind: "tool",
|
|
194
|
+
declared: new Set(tools.keys()),
|
|
195
|
+
compile: (ctx, path, name, definition) =>
|
|
196
|
+
compileTool(ctx, path, name, definition as ToolDefinition),
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
await overlaySlot(ctx, site, connections, connectionOverlay, {
|
|
200
|
+
kind: "connection",
|
|
201
|
+
declared: new Set([...connections.keys(), ...tree.overlaidServers]),
|
|
202
|
+
compile: (ctx, path, name, definition) =>
|
|
203
|
+
compileConnection(
|
|
204
|
+
ctx,
|
|
205
|
+
path,
|
|
206
|
+
name,
|
|
207
|
+
definition as ConnectionDefinition,
|
|
208
|
+
"model"
|
|
209
|
+
),
|
|
210
|
+
});
|
|
211
|
+
for (const skill of await loadSkills(
|
|
212
|
+
ctx,
|
|
213
|
+
join(site.overlayDir, "skills")
|
|
214
|
+
)) {
|
|
215
|
+
skills.set(skill.name, skill);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
for (const [name, tool] of tools) {
|
|
219
|
+
const composed = `${site.ns}__${name}`;
|
|
220
|
+
into.tools.push({ ...tool, name: composed, extension: site.ns });
|
|
221
|
+
mounted.tools.push(composed);
|
|
222
|
+
}
|
|
223
|
+
for (const [name, skill] of skills) {
|
|
224
|
+
const composed = `${site.ns}__${name}`;
|
|
225
|
+
into.skills.push({ ...skill, name: composed, extension: site.ns });
|
|
226
|
+
mounted.skills.push(composed);
|
|
227
|
+
}
|
|
228
|
+
for (const [name, connection] of connections) {
|
|
229
|
+
const composed = `${site.ns}__${name}`;
|
|
230
|
+
into.connections.push({ ...connection, name: composed });
|
|
231
|
+
mounted.connections.push(composed);
|
|
232
|
+
}
|
|
233
|
+
for (const agent of tree.agents) {
|
|
234
|
+
const composed = `${site.ns}__${agent.name}`;
|
|
235
|
+
into.subagents.push(subagent(composed, agent));
|
|
236
|
+
mounted.subagents.push(composed);
|
|
237
|
+
}
|
|
238
|
+
return mounted;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
async function readExtensionTree(
|
|
242
|
+
ctx: DiscoveryContext,
|
|
243
|
+
site: MountSite,
|
|
244
|
+
mount: ExtensionMount,
|
|
245
|
+
root: string,
|
|
246
|
+
overlaidServers: ReadonlySet<string>
|
|
247
|
+
): Promise<ExtensionTree | undefined> {
|
|
248
|
+
if ("layout" in mount.extension) {
|
|
249
|
+
const plugin = await readCursorPlugin(
|
|
250
|
+
ctx,
|
|
251
|
+
root,
|
|
252
|
+
site.mountPath,
|
|
253
|
+
mount.extension.variables,
|
|
254
|
+
overlaidServers
|
|
255
|
+
);
|
|
256
|
+
return plugin === undefined ? undefined : { ...plugin, tools: [] };
|
|
257
|
+
}
|
|
258
|
+
await warnUnsupportedExtensionSlots(ctx, root);
|
|
259
|
+
return {
|
|
260
|
+
tools: await loadTools(ctx, join(root, "tools")),
|
|
261
|
+
skills: await loadSkills(ctx, join(root, "skills")),
|
|
262
|
+
connections: [],
|
|
263
|
+
overlaidServers: [],
|
|
264
|
+
agents: [],
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function byName<T extends { name: string }>(items: T[]): Map<string, T> {
|
|
269
|
+
return new Map(items.map((item) => [item.name, item]));
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** One overlayable slot: what a file may export and how it compiles. */
|
|
273
|
+
interface OverlaySlot<T> {
|
|
274
|
+
kind: "tool" | "connection";
|
|
275
|
+
/** Names the extension contributes; a disable marker must name one. */
|
|
276
|
+
declared: ReadonlySet<string>;
|
|
277
|
+
compile: (
|
|
278
|
+
ctx: DiscoveryContext,
|
|
279
|
+
path: string,
|
|
280
|
+
name: string,
|
|
281
|
+
definition: unknown
|
|
282
|
+
) => Promise<T | undefined> | T | undefined;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Lay a directory mount's slot over the extension's contributions: a
|
|
287
|
+
* same-named file replaces, a disable marker removes, a new name adds.
|
|
288
|
+
*/
|
|
289
|
+
async function overlaySlot<T extends { name: string }>(
|
|
290
|
+
ctx: DiscoveryContext,
|
|
291
|
+
site: MountSite,
|
|
292
|
+
contributed: Map<string, T>,
|
|
293
|
+
entries: Array<{ name: string; path: string }>,
|
|
294
|
+
slot: OverlaySlot<T>
|
|
295
|
+
): Promise<void> {
|
|
296
|
+
const disabledKind = `disabled-${slot.kind}` as const;
|
|
297
|
+
for (const { name, path } of entries) {
|
|
298
|
+
const definition = await importDefault(ctx, path, [
|
|
299
|
+
slot.kind,
|
|
300
|
+
disabledKind,
|
|
301
|
+
]);
|
|
302
|
+
if (definition === undefined) {
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
if (getDefinitionKind(definition) === disabledKind) {
|
|
306
|
+
contributed.delete(name);
|
|
307
|
+
if (!slot.declared.has(name)) {
|
|
308
|
+
ctx.diagnostics.push({
|
|
309
|
+
severity: "error",
|
|
310
|
+
path: displayPath(ctx, path),
|
|
311
|
+
message: `${helperCall(disabledKind)} targets "${name}", which extension "${site.ns}" does not contribute.`,
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
const item = await slot.compile(ctx, path, name, definition);
|
|
317
|
+
if (item !== undefined) {
|
|
318
|
+
contributed.set(name, item);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/** Slots an agent has that an extension tree may not contribute (yet). */
|
|
324
|
+
async function warnUnsupportedExtensionSlots(
|
|
325
|
+
ctx: DiscoveryContext,
|
|
326
|
+
root: string
|
|
327
|
+
): Promise<void> {
|
|
328
|
+
const unsupported = [
|
|
329
|
+
["instructions.md", "instructions"],
|
|
330
|
+
["connections", "connections"],
|
|
331
|
+
["mcp-connections", "MCP connections"],
|
|
332
|
+
["hooks", "hooks"],
|
|
333
|
+
["subagents", "subagents"],
|
|
334
|
+
["channels", "channels"],
|
|
335
|
+
["schedules", "schedules"],
|
|
336
|
+
["extensions", "nested extensions"],
|
|
337
|
+
] as const;
|
|
338
|
+
for (const [slot, label] of unsupported) {
|
|
339
|
+
const path = join(root, slot);
|
|
340
|
+
if ((await isDirectory(path)) || (await isFile(path))) {
|
|
341
|
+
ctx.diagnostics.push({
|
|
342
|
+
severity: "warning",
|
|
343
|
+
path: displayPath(ctx, path),
|
|
344
|
+
message: `Extension ${label} are not supported yet; only tools/ and skills/ are mounted. Ignoring.`,
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem primitives discovery walks with: module-file detection, directory listing, and project-root markers.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Dirent } from "node:fs";
|
|
6
|
+
import { readdir, readFile, stat } from "node:fs/promises";
|
|
7
|
+
import { extname, join } from "node:path";
|
|
8
|
+
|
|
9
|
+
const MODULE_EXTENSIONS = new Set([".ts", ".mts", ".js", ".mjs"]);
|
|
10
|
+
|
|
11
|
+
export async function findModuleFile(
|
|
12
|
+
dir: string,
|
|
13
|
+
stem: string
|
|
14
|
+
): Promise<string | undefined> {
|
|
15
|
+
for (const extension of [".ts", ".mts", ".js", ".mjs"]) {
|
|
16
|
+
const candidate = join(dir, `${stem}${extension}`);
|
|
17
|
+
if (await isFile(candidate)) {
|
|
18
|
+
return candidate;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function isModuleFile(fileName: string): boolean {
|
|
25
|
+
if (fileName.endsWith(".d.ts") || fileName.startsWith(".")) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
if (!MODULE_EXTENSIONS.has(extname(fileName))) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
// Colocated unit tests (Vitest/Jest convention) are not definitions.
|
|
32
|
+
// Without this, `channels/slack.test.ts` is scanned as a channel named
|
|
33
|
+
// "slack.test", fails NAME_PATTERN, and the whole agent refuses to serve.
|
|
34
|
+
const stem = moduleStem(fileName);
|
|
35
|
+
return !stem.endsWith(".test") && !stem.endsWith(".spec");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function moduleStem(fileName: string): string {
|
|
39
|
+
return fileName.slice(0, -extname(fileName).length);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export async function sortedEntries(dir: string): Promise<Dirent[]> {
|
|
43
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
44
|
+
return entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function walkFiles(dir: string): Promise<string[]> {
|
|
48
|
+
const files: string[] = [];
|
|
49
|
+
for (const entry of await sortedEntries(dir)) {
|
|
50
|
+
if (entry.name.startsWith(".")) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const entryPath = join(dir, entry.name);
|
|
54
|
+
if (entry.isDirectory()) {
|
|
55
|
+
files.push(...(await walkFiles(entryPath)));
|
|
56
|
+
} else if (entry.isFile()) {
|
|
57
|
+
files.push(entryPath);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return files;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export async function isDirectory(path: string): Promise<boolean> {
|
|
64
|
+
try {
|
|
65
|
+
return (await stat(path)).isDirectory();
|
|
66
|
+
} catch {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export async function isFile(path: string): Promise<boolean> {
|
|
72
|
+
try {
|
|
73
|
+
return (await stat(path)).isFile();
|
|
74
|
+
} catch {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function toPosix(path: string): string {
|
|
80
|
+
return path.split("\\").join("/");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export async function hasFlatLayoutMarkers(rootDir: string): Promise<boolean> {
|
|
84
|
+
if (await isFile(join(rootDir, "instructions.md"))) {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
return (await findModuleFile(rootDir, "agent")) !== undefined;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export async function readPackageName(
|
|
91
|
+
rootDir: string
|
|
92
|
+
): Promise<string | undefined> {
|
|
93
|
+
const packageJsonPath = join(rootDir, "package.json");
|
|
94
|
+
if (!(await isFile(packageJsonPath))) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const parsed = JSON.parse(await readFile(packageJsonPath, "utf8")) as {
|
|
99
|
+
name?: unknown;
|
|
100
|
+
};
|
|
101
|
+
if (typeof parsed.name === "string" && parsed.name !== "") {
|
|
102
|
+
return parsed.name;
|
|
103
|
+
}
|
|
104
|
+
} catch {
|
|
105
|
+
// Malformed package.json falls back to the directory name.
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agent/hooks/*.ts`: observe-only event subscribers.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { basename, extname, relative } from "node:path";
|
|
6
|
+
import type { DiscoveredHook, HookDefinition } from "../../types.js";
|
|
7
|
+
import { type DiscoveryContext, displayPath } from "./context.js";
|
|
8
|
+
import { isDirectory, isModuleFile, toPosix, walkFiles } from "./fs.js";
|
|
9
|
+
import { importDefault } from "./modules.js";
|
|
10
|
+
|
|
11
|
+
export async function loadHooks(
|
|
12
|
+
ctx: DiscoveryContext,
|
|
13
|
+
hooksDir: string
|
|
14
|
+
): Promise<DiscoveredHook[]> {
|
|
15
|
+
if (!(await isDirectory(hooksDir))) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
const hooks: DiscoveredHook[] = [];
|
|
19
|
+
for (const filePath of await walkFiles(hooksDir)) {
|
|
20
|
+
if (!isModuleFile(basename(filePath))) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const rel = toPosix(relative(hooksDir, filePath));
|
|
24
|
+
const name = rel.slice(0, -extname(rel).length);
|
|
25
|
+
const definition = await importDefault(ctx, filePath, "hook");
|
|
26
|
+
if (definition === undefined) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const hook = definition as HookDefinition;
|
|
30
|
+
if (
|
|
31
|
+
typeof hook.events !== "object" ||
|
|
32
|
+
hook.events === null ||
|
|
33
|
+
Object.keys(hook.events).length === 0
|
|
34
|
+
) {
|
|
35
|
+
ctx.diagnostics.push({
|
|
36
|
+
severity: "warning",
|
|
37
|
+
path: displayPath(ctx, filePath),
|
|
38
|
+
message: "Hook declares no event handlers.",
|
|
39
|
+
});
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
hooks.push({ name, definition: hook });
|
|
43
|
+
}
|
|
44
|
+
return hooks;
|
|
45
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `info` / `GET /v1/info` projection of an {@link AgentProject}.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { resolveABMaxPlaygroundSessions } from "../../ab.js";
|
|
6
|
+
import { resolveArtifactsMax } from "../../artifacts.js";
|
|
7
|
+
import {
|
|
8
|
+
type AgentProject,
|
|
9
|
+
type AgentProjectInfo,
|
|
10
|
+
toPublicCloudInfo,
|
|
11
|
+
} from "../../types.js";
|
|
12
|
+
import { toolInputJsonSchema } from "../json-schema.js";
|
|
13
|
+
import { MCP_ENDPOINT_PATH, mcpEndpointToolNames } from "../mcp-endpoint.js";
|
|
14
|
+
import { connectionTransportLabel } from "./connections.js";
|
|
15
|
+
|
|
16
|
+
export function projectInfo(project: AgentProject): AgentProjectInfo {
|
|
17
|
+
const agent = project.agent;
|
|
18
|
+
const httpRoutes: AgentProjectInfo["channels"][number]["routes"] = [
|
|
19
|
+
{ method: "POST", path: "/v1/session", url: "/v1/session" },
|
|
20
|
+
{
|
|
21
|
+
method: "POST",
|
|
22
|
+
path: "/v1/session/:sessionId",
|
|
23
|
+
url: "/v1/session/:sessionId",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
method: "POST",
|
|
27
|
+
path: "/v1/session/:sessionId/stop",
|
|
28
|
+
url: "/v1/session/:sessionId/stop",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
method: "GET",
|
|
32
|
+
path: "/v1/session/:sessionId/stream",
|
|
33
|
+
url: "/v1/session/:sessionId/stream",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
method: "GET",
|
|
37
|
+
path: "/v1/session/:sessionId/approvals",
|
|
38
|
+
url: "/v1/session/:sessionId/approvals",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
method: "POST",
|
|
42
|
+
path: "/v1/session/:sessionId/approvals/:callId",
|
|
43
|
+
url: "/v1/session/:sessionId/approvals/:callId",
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
return {
|
|
47
|
+
name: project.name,
|
|
48
|
+
description: agent.description,
|
|
49
|
+
model: agent.model,
|
|
50
|
+
runtime: agent.runtime,
|
|
51
|
+
cloud:
|
|
52
|
+
agent.cloud === undefined ? undefined : toPublicCloudInfo(agent.cloud),
|
|
53
|
+
local: agent.local,
|
|
54
|
+
hosting: agent.hosting,
|
|
55
|
+
concurrency: agent.concurrency,
|
|
56
|
+
mcp: { path: MCP_ENDPOINT_PATH, tools: mcpEndpointToolNames(project) },
|
|
57
|
+
instructions:
|
|
58
|
+
agent.instructions === undefined
|
|
59
|
+
? undefined
|
|
60
|
+
: {
|
|
61
|
+
chars: agent.instructions.length,
|
|
62
|
+
preview:
|
|
63
|
+
agent.instructions.length > 280
|
|
64
|
+
? `${agent.instructions.slice(0, 277)}...`
|
|
65
|
+
: agent.instructions,
|
|
66
|
+
},
|
|
67
|
+
tools: agent.tools.map((tool) => ({
|
|
68
|
+
name: tool.name,
|
|
69
|
+
description: tool.description,
|
|
70
|
+
execution: tool.execution,
|
|
71
|
+
needsApproval: tool.needsApproval,
|
|
72
|
+
effect: tool.effect,
|
|
73
|
+
inputSchema: tool.inputSchema,
|
|
74
|
+
})),
|
|
75
|
+
skills: agent.skills.map((skill) => ({
|
|
76
|
+
name: skill.name,
|
|
77
|
+
description: skill.description,
|
|
78
|
+
})),
|
|
79
|
+
extensions: agent.extensions ?? [],
|
|
80
|
+
connections: agent.connections.map((connection) => ({
|
|
81
|
+
name: connection.name,
|
|
82
|
+
transport: connectionTransportLabel(connection.transport),
|
|
83
|
+
advertiseTools: connection.advertiseTools,
|
|
84
|
+
effects: connection.effects,
|
|
85
|
+
tools: connection.tools,
|
|
86
|
+
disallowedTools: connection.disallowedTools,
|
|
87
|
+
cursorAccountServers:
|
|
88
|
+
"cursorAccount" in connection.transport
|
|
89
|
+
? (connection.transport.servers ?? "*")
|
|
90
|
+
: undefined,
|
|
91
|
+
})),
|
|
92
|
+
subagents: agent.subagents.map((subagent) => ({
|
|
93
|
+
name: subagent.name,
|
|
94
|
+
description: subagent.description,
|
|
95
|
+
model: subagent.model,
|
|
96
|
+
})),
|
|
97
|
+
channels: [
|
|
98
|
+
{ id: "http", routes: httpRoutes },
|
|
99
|
+
...project.channels.map((channel) => {
|
|
100
|
+
const info: AgentProjectInfo["channels"][number] = {
|
|
101
|
+
id: channel.id,
|
|
102
|
+
routes: (channel.definition.routes ?? []).map((r) => {
|
|
103
|
+
const routeInfo: AgentProjectInfo["channels"][number]["routes"][number] =
|
|
104
|
+
{
|
|
105
|
+
method: r.method,
|
|
106
|
+
path: r.path,
|
|
107
|
+
url: `/v1/channels/${channel.id}${r.path}`,
|
|
108
|
+
};
|
|
109
|
+
if (r.description !== undefined) {
|
|
110
|
+
routeInfo.description = r.description;
|
|
111
|
+
}
|
|
112
|
+
if (r.bodySchema !== undefined) {
|
|
113
|
+
routeInfo.bodySchema = toolInputJsonSchema(r.bodySchema);
|
|
114
|
+
}
|
|
115
|
+
if (r.querySchema !== undefined) {
|
|
116
|
+
routeInfo.querySchema = toolInputJsonSchema(r.querySchema);
|
|
117
|
+
}
|
|
118
|
+
return routeInfo;
|
|
119
|
+
}),
|
|
120
|
+
};
|
|
121
|
+
const meta = channel.definition.meta;
|
|
122
|
+
if (meta?.kind !== undefined) {
|
|
123
|
+
info.kind = meta.kind;
|
|
124
|
+
}
|
|
125
|
+
if (meta?.githubWebhookEvents !== undefined) {
|
|
126
|
+
info.githubWebhookEvents = meta.githubWebhookEvents;
|
|
127
|
+
}
|
|
128
|
+
if (meta?.originWebhookEvents !== undefined) {
|
|
129
|
+
info.originWebhookEvents = meta.originWebhookEvents;
|
|
130
|
+
}
|
|
131
|
+
if (meta?.deploymentEventTypes !== undefined) {
|
|
132
|
+
info.deploymentEventTypes = meta.deploymentEventTypes;
|
|
133
|
+
}
|
|
134
|
+
if (meta?.slackChannelPosts !== undefined) {
|
|
135
|
+
info.slackChannelPosts = meta.slackChannelPosts;
|
|
136
|
+
}
|
|
137
|
+
return info;
|
|
138
|
+
}),
|
|
139
|
+
],
|
|
140
|
+
schedules: project.schedules.map((schedule) => ({
|
|
141
|
+
name: schedule.name,
|
|
142
|
+
cron: schedule.cron,
|
|
143
|
+
kind: schedule.kind,
|
|
144
|
+
})),
|
|
145
|
+
hooks: project.hooks.map((hook) => hook.name),
|
|
146
|
+
abs: project.abs.map((experiment) => experiment.name),
|
|
147
|
+
...(project.abConfig === undefined && project.abs.length === 0
|
|
148
|
+
? {}
|
|
149
|
+
: {
|
|
150
|
+
abConfig: {
|
|
151
|
+
maxPlaygroundSessions: resolveABMaxPlaygroundSessions(
|
|
152
|
+
project.abConfig?.maxPlaygroundSessions
|
|
153
|
+
),
|
|
154
|
+
durableSamples: project.storage?.abs !== undefined,
|
|
155
|
+
durableSnapshots: project.storage?.abs?.putSnapshot !== undefined,
|
|
156
|
+
},
|
|
157
|
+
}),
|
|
158
|
+
storage:
|
|
159
|
+
project.storage === undefined
|
|
160
|
+
? undefined
|
|
161
|
+
: { name: project.storage.name },
|
|
162
|
+
artifacts:
|
|
163
|
+
project.artifacts === undefined
|
|
164
|
+
? undefined
|
|
165
|
+
: {
|
|
166
|
+
kinds: Object.keys(project.artifacts.kinds ?? {}),
|
|
167
|
+
agentTool: project.artifacts.agentTool === true,
|
|
168
|
+
max: resolveArtifactsMax(project.artifacts),
|
|
169
|
+
},
|
|
170
|
+
otel:
|
|
171
|
+
project.otel === undefined
|
|
172
|
+
? undefined
|
|
173
|
+
: {
|
|
174
|
+
enabled: true as const,
|
|
175
|
+
serviceName: project.otel.serviceName,
|
|
176
|
+
},
|
|
177
|
+
diagnostics: project.diagnostics,
|
|
178
|
+
};
|
|
179
|
+
}
|