@cursor/july 0.1.102 → 0.1.103
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/AGENTS.md +34 -32
- package/README.md +10 -12
- package/dist/ab.d.ts +1 -1
- package/dist/ab.js +1 -1
- package/dist/bin/agent-serve.d.ts +12 -12
- package/dist/bin/agent-serve.js +114 -36
- package/dist/channels/bitbucket/api.d.ts +176 -0
- package/dist/channels/bitbucket/api.d.ts.map +1 -0
- package/dist/channels/bitbucket/api.js +419 -0
- package/dist/channels/bitbucket/binding.d.ts +71 -0
- package/dist/channels/bitbucket/binding.d.ts.map +1 -0
- package/dist/channels/bitbucket/binding.js +269 -0
- package/dist/channels/bitbucket/bitbucket-channel.d.ts +33 -0
- package/dist/channels/bitbucket/bitbucket-channel.d.ts.map +1 -0
- package/dist/channels/bitbucket/bitbucket-channel.js +120 -0
- package/dist/channels/bitbucket/bitbucket-webhook.d.ts +61 -0
- package/dist/channels/bitbucket/bitbucket-webhook.d.ts.map +1 -0
- package/dist/channels/bitbucket/bitbucket-webhook.js +394 -0
- package/dist/channels/bitbucket/checks.d.ts +67 -0
- package/dist/channels/bitbucket/checks.d.ts.map +1 -0
- package/dist/channels/bitbucket/checks.js +102 -0
- package/dist/channels/bitbucket/cursor-account.d.ts +37 -0
- package/dist/channels/bitbucket/cursor-account.d.ts.map +1 -0
- package/dist/channels/bitbucket/cursor-account.js +65 -0
- package/dist/channels/bitbucket/defaults.d.ts +26 -0
- package/dist/channels/bitbucket/defaults.d.ts.map +1 -0
- package/dist/channels/bitbucket/defaults.js +73 -0
- package/dist/channels/bitbucket/events.d.ts +22 -0
- package/dist/channels/bitbucket/events.d.ts.map +1 -0
- package/dist/channels/bitbucket/events.js +64 -0
- package/dist/channels/bitbucket/index.d.ts +34 -0
- package/dist/channels/bitbucket/index.d.ts.map +1 -0
- package/dist/channels/bitbucket/index.js +33 -0
- package/dist/channels/bitbucket/replay.d.ts +63 -0
- package/dist/channels/bitbucket/replay.d.ts.map +1 -0
- package/dist/channels/bitbucket/replay.js +304 -0
- package/dist/channels/bitbucket/state.d.ts +35 -0
- package/dist/channels/bitbucket/state.d.ts.map +1 -0
- package/dist/channels/bitbucket/state.js +21 -0
- package/dist/channels/bitbucket/types.d.ts +229 -0
- package/dist/channels/bitbucket/types.d.ts.map +1 -0
- package/dist/channels/bitbucket/types.js +1 -0
- package/dist/channels/deployments/deployments-channel.d.ts +22 -14
- package/dist/channels/deployments/deployments-channel.d.ts.map +1 -1
- package/dist/channels/deployments/deployments-channel.js +25 -27
- package/dist/channels/deployments/types.d.ts +12 -6
- package/dist/channels/deployments/types.d.ts.map +1 -1
- package/dist/channels/github/binding.d.ts +6 -0
- package/dist/channels/github/binding.d.ts.map +1 -1
- package/dist/channels/github/binding.js +3 -3
- package/dist/channels/github/cursor-account.d.ts +7 -3
- package/dist/channels/github/cursor-account.d.ts.map +1 -1
- package/dist/channels/github/cursor-account.js +10 -6
- package/dist/channels/github/events.d.ts +1 -1
- package/dist/channels/github/events.js +1 -1
- package/dist/channels/github/forward.d.ts +1 -1
- package/dist/channels/github/forward.d.ts.map +1 -1
- package/dist/channels/github/forward.js +3 -2
- package/dist/channels/github/github-channel.d.ts +29 -39
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +68 -101
- package/dist/channels/github/replay.d.ts +1 -1
- package/dist/channels/github/replay.js +1 -1
- package/dist/channels/github/state.d.ts +2 -0
- package/dist/channels/github/state.d.ts.map +1 -1
- package/dist/channels/github/state.js +14 -11
- package/dist/channels/github/types.d.ts +2 -4
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/gitlab/api.d.ts +91 -0
- package/dist/channels/gitlab/api.d.ts.map +1 -0
- package/dist/channels/gitlab/api.js +150 -0
- package/dist/channels/gitlab/binding.d.ts +58 -0
- package/dist/channels/gitlab/binding.d.ts.map +1 -0
- package/dist/channels/gitlab/binding.js +139 -0
- package/dist/channels/gitlab/checks.d.ts +110 -0
- package/dist/channels/gitlab/checks.d.ts.map +1 -0
- package/dist/channels/gitlab/checks.js +126 -0
- package/dist/channels/gitlab/cursor-account.d.ts +36 -0
- package/dist/channels/gitlab/cursor-account.d.ts.map +1 -0
- package/dist/channels/gitlab/cursor-account.js +65 -0
- package/dist/channels/gitlab/defaults.d.ts +25 -0
- package/dist/channels/gitlab/defaults.d.ts.map +1 -0
- package/dist/channels/gitlab/defaults.js +60 -0
- package/dist/channels/gitlab/events.d.ts +12 -0
- package/dist/channels/gitlab/events.d.ts.map +1 -0
- package/dist/channels/gitlab/events.js +28 -0
- package/dist/channels/gitlab/gitlab-channel.d.ts +33 -0
- package/dist/channels/gitlab/gitlab-channel.d.ts.map +1 -0
- package/dist/channels/gitlab/gitlab-channel.js +120 -0
- package/dist/channels/gitlab/gitlab-webhook.d.ts +45 -0
- package/dist/channels/gitlab/gitlab-webhook.d.ts.map +1 -0
- package/dist/channels/gitlab/gitlab-webhook.js +397 -0
- package/dist/channels/gitlab/index.d.ts +31 -0
- package/dist/channels/gitlab/index.d.ts.map +1 -0
- package/dist/channels/gitlab/index.js +30 -0
- package/dist/channels/gitlab/replay.d.ts +105 -0
- package/dist/channels/gitlab/replay.d.ts.map +1 -0
- package/dist/channels/gitlab/replay.js +206 -0
- package/dist/channels/gitlab/state.d.ts +33 -0
- package/dist/channels/gitlab/state.d.ts.map +1 -0
- package/dist/channels/gitlab/state.js +23 -0
- package/dist/channels/gitlab/types.d.ts +214 -0
- package/dist/channels/gitlab/types.d.ts.map +1 -0
- package/dist/channels/gitlab/types.js +1 -0
- package/dist/channels/origin/api.d.ts.map +1 -1
- package/dist/channels/origin/api.js +4 -2
- package/dist/channels/origin/origin-channel.d.ts +4 -9
- package/dist/channels/origin/origin-channel.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.js +8 -48
- package/dist/channels/origin/types.d.ts +20 -2
- package/dist/channels/origin/types.d.ts.map +1 -1
- package/dist/channels/slack/eval-directive.d.ts.map +1 -1
- package/dist/channels/slack/eval-directive.js +1 -7
- package/dist/channels/slack/init.d.ts.map +1 -1
- package/dist/channels/slack/init.js +3 -3
- package/dist/channels/slack/setup.d.ts +1 -1
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +6 -13
- package/dist/channels/slack/types.d.ts +1 -1
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/channels.d.ts +1 -1
- package/dist/channels.d.ts.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/connections.d.ts +1 -1
- package/dist/connections.js +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.CLA03RCz.js → app.DW9pXkpL.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.nrl1ifBq.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.ifxv-cJV.js → VPLocalSearchBox.CdEIUwDg.js} +1 -1
- package/dist/docs/assets/chunks/{theme.DWCwM6p-.js → theme.YZMHgPgg.js} +2 -2
- package/dist/docs/assets/concepts.md.DgEcZOfT.js +1 -0
- package/dist/docs/assets/{concepts.md.rPzW2HZN.lean.js → concepts.md.DgEcZOfT.lean.js} +1 -1
- package/dist/docs/assets/{evals.md.CPzDAwoH.js → evals.md.CbMoebP1.js} +1 -1
- package/dist/docs/assets/guides_cloud-agents.md.DS8RIjwx.js +9 -0
- package/dist/docs/assets/{guides_github.md.BtPr9GaP.js → guides_github.md.DKYiT9do.js} +1 -1
- package/dist/docs/assets/{guides_opentelemetry.md.BVTXDCRg.js → guides_opentelemetry.md.COh9jFVg.js} +7 -8
- package/dist/docs/assets/{guides_opentelemetry.md.BVTXDCRg.lean.js → guides_opentelemetry.md.COh9jFVg.lean.js} +1 -1
- package/dist/docs/assets/{index.md.Kiht7ell.js → index.md.D75GWhPl.js} +1 -1
- package/dist/docs/assets/{reference_agent-config.md.BHeYMgme.js → reference_agent-config.md.CHNpiyp4.js} +3 -3
- package/dist/docs/assets/{reference_channels.md.Cd2f2iyV.js → reference_channels.md.Dz8Cnudp.js} +2 -2
- package/dist/docs/assets/{reference_channels.md.Cd2f2iyV.lean.js → reference_channels.md.Dz8Cnudp.lean.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.DfoeyvL0.js → reference_cli.md.CJNc_xYK.js} +1 -1
- package/dist/docs/assets/{reference_extensions.md.9WQMZe1l.js → reference_extensions.md.DykHW3qL.js} +11 -5
- package/dist/docs/assets/reference_extensions.md.DykHW3qL.lean.js +1 -0
- package/dist/docs/assets/reference_hooks.md.Ddt5DdgJ.js +73 -0
- package/dist/docs/assets/{reference_hooks.md.a8BJxMR5.lean.js → reference_hooks.md.Ddt5DdgJ.lean.js} +1 -1
- package/dist/docs/assets/{reference_playground.md.DnX5nL-B.js → reference_playground.md.4myJPxrf.js} +1 -1
- package/dist/docs/assets/{reference_project-layout.md.CA6QP6Lw.js → reference_project-layout.md.DuBu9a96.js} +2 -2
- package/dist/docs/assets/reference_result.md.BK5SxDrf.js +19 -0
- package/dist/docs/assets/reference_result.md.BK5SxDrf.lean.js +1 -0
- package/dist/docs/assets/{reference_sessions.md.NxFP_CAC.js → reference_sessions.md.CueyOHSL.js} +1 -1
- package/dist/docs/assets/{reference_sessions.md.NxFP_CAC.lean.js → reference_sessions.md.CueyOHSL.lean.js} +1 -1
- package/dist/docs/assets/{reference_tools.md.B1up2r9W.js → reference_tools.md.aGrn99hP.js} +1 -1
- package/dist/docs/assets/skills_framework-map.md.haibFyoB.js +1 -0
- package/dist/docs/assets/{skills_otel.md.CgiZryR3.js → skills_otel.md.CqhobH3B.js} +3 -3
- package/dist/docs/assets/{skills_otel.md.CgiZryR3.lean.js → skills_otel.md.CqhobH3B.lean.js} +1 -1
- package/dist/docs/assets/{templates_pr-autofixer.md.x5zl6-GT.js → templates_pr-autofixer.md.Bds_XWcV.js} +2 -2
- package/dist/docs/assets/{templates_pr-autofixer.md.x5zl6-GT.lean.js → templates_pr-autofixer.md.Bds_XWcV.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 +2 -4
- package/dist/docs/deployment.html +4 -4
- package/dist/docs/design/runtime-abstraction.md +2 -3
- package/dist/docs/evals.html +6 -6
- package/dist/docs/evals.md +9 -7
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/cloud-agents.html +6 -6
- package/dist/docs/guides/cloud-agents.md +4 -6
- package/dist/docs/guides/convert-automation.html +4 -4
- package/dist/docs/guides/github.html +6 -6
- package/dist/docs/guides/github.md +0 -1
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +5 -5
- package/dist/docs/guides/opentelemetry.html +10 -11
- package/dist/docs/guides/opentelemetry.md +41 -17
- 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 +2 -2
- package/dist/docs/llms-full.txt +501 -262
- package/dist/docs/llms.txt +2 -2
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +8 -8
- package/dist/docs/reference/agent-config.md +6 -10
- package/dist/docs/reference/artifacts.html +5 -5
- package/dist/docs/reference/channels.html +6 -6
- package/dist/docs/reference/channels.md +18 -8
- package/dist/docs/reference/cli.html +5 -5
- package/dist/docs/reference/cli.md +3 -4
- package/dist/docs/reference/connections.html +4 -4
- package/dist/docs/reference/extensions.html +16 -10
- package/dist/docs/reference/extensions.md +86 -22
- package/dist/docs/reference/hooks.html +69 -10
- package/dist/docs/reference/hooks.md +215 -46
- package/dist/docs/reference/http-api.html +4 -4
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +5 -5
- package/dist/docs/reference/playground.md +3 -0
- package/dist/docs/reference/project-layout.html +6 -6
- package/dist/docs/reference/project-layout.md +2 -1
- package/dist/docs/reference/prompt.html +4 -4
- package/dist/docs/reference/result.html +45 -0
- package/dist/docs/reference/result.md +89 -0
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +5 -5
- package/dist/docs/reference/sessions.md +3 -1
- package/dist/docs/reference/skills.html +4 -4
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +5 -5
- package/dist/docs/reference/tools.md +1 -2
- 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 +3 -1
- 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 +7 -7
- package/dist/docs/skills/otel.md +8 -3
- 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 +6 -6
- package/dist/docs/templates/pr-autofixer.md +0 -3
- 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/evals.d.ts +1 -1
- package/dist/evals.d.ts.map +1 -1
- package/dist/extensions.d.ts +20 -7
- package/dist/extensions.d.ts.map +1 -1
- package/dist/extensions.js +36 -5
- package/dist/files.d.ts +16 -3
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +16 -3
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/internal/ab-snapshot.d.ts.map +1 -1
- package/dist/internal/ab-snapshot.js +0 -1
- package/dist/internal/advertise-tools.d.ts.map +1 -1
- package/dist/internal/advertise-tools.js +1 -3
- package/dist/internal/authored-alias-hooks.d.ts +4 -13
- package/dist/internal/authored-alias-hooks.d.ts.map +1 -1
- package/dist/internal/authored-alias-hooks.js +4 -20
- package/dist/internal/authored-loaders.d.ts +2 -3
- package/dist/internal/authored-loaders.d.ts.map +1 -1
- package/dist/internal/authored-loaders.js +6 -20
- package/dist/internal/channel-dispatch.d.ts +43 -0
- package/dist/internal/channel-dispatch.d.ts.map +1 -0
- package/dist/internal/channel-dispatch.js +77 -0
- package/dist/internal/chat-client.d.ts +1 -1
- package/dist/internal/chat-client.js +1 -1
- package/dist/internal/cli-ax.d.ts +5 -5
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +5 -5
- package/dist/internal/cli-bitbucket.d.ts +33 -0
- package/dist/internal/cli-bitbucket.d.ts.map +1 -0
- package/dist/internal/cli-bitbucket.js +359 -0
- package/dist/internal/cli-convert-automation.d.ts +1 -1
- package/dist/internal/cli-convert-automation.js +2 -2
- package/dist/internal/cli-cursor.d.ts +1 -1
- package/dist/internal/cli-cursor.d.ts.map +1 -1
- package/dist/internal/cli-cursor.js +2 -4
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +2 -6
- package/dist/internal/cli-github.d.ts +1 -1
- package/dist/internal/cli-github.js +3 -3
- package/dist/internal/cli-gitlab.d.ts +37 -0
- package/dist/internal/cli-gitlab.d.ts.map +1 -0
- package/dist/internal/cli-gitlab.js +380 -0
- package/dist/internal/cli-mcp.d.ts.map +1 -1
- package/dist/internal/cli-mcp.js +2 -6
- package/dist/internal/cli-slack.d.ts +1 -1
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +2 -4
- package/dist/internal/continuation-channel.d.ts +14 -0
- package/dist/internal/continuation-channel.d.ts.map +1 -1
- package/dist/internal/continuation-channel.js +56 -3
- package/dist/internal/continuation-identity.d.ts +14 -15
- package/dist/internal/continuation-identity.d.ts.map +1 -1
- package/dist/internal/continuation-identity.js +182 -7
- package/dist/internal/conversation-mirror.d.ts.map +1 -1
- package/dist/internal/conversation-mirror.js +4 -3
- package/dist/internal/convert-automation/types.d.ts +1 -1
- package/dist/internal/convert-automation/types.js +1 -1
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +1 -3
- package/dist/internal/cursor/backend-client.d.ts +5 -4
- package/dist/internal/cursor/backend-client.d.ts.map +1 -1
- package/dist/internal/cursor/backend-client.js +5 -6
- package/dist/internal/cursor/bound-secret-file.d.ts +56 -0
- package/dist/internal/cursor/bound-secret-file.d.ts.map +1 -0
- package/dist/internal/cursor/bound-secret-file.js +88 -0
- package/dist/internal/cursor/credentials.d.ts +39 -5
- package/dist/internal/cursor/credentials.d.ts.map +1 -1
- package/dist/internal/cursor/credentials.js +58 -8
- package/dist/internal/cursor/hosted-bound-secrets.d.ts +41 -0
- package/dist/internal/cursor/hosted-bound-secrets.d.ts.map +1 -0
- package/dist/internal/cursor/hosted-bound-secrets.js +54 -0
- package/dist/internal/cursor/hosted-deployment-secrets.d.ts +19 -5
- package/dist/internal/cursor/hosted-deployment-secrets.d.ts.map +1 -1
- package/dist/internal/cursor/hosted-deployment-secrets.js +29 -9
- package/dist/internal/cursor/hosted-store-secrets.d.ts +1 -1
- package/dist/internal/cursor/hosted-store-secrets.js +1 -1
- package/dist/internal/cursor-account-mcp-auth.d.ts.map +1 -1
- package/dist/internal/cursor-account-mcp-auth.js +2 -4
- package/dist/internal/cursor-deployment-relay.d.ts +6 -2
- package/dist/internal/cursor-deployment-relay.d.ts.map +1 -1
- package/dist/internal/cursor-deployment-relay.js +13 -9
- package/dist/internal/deploy-manifest.d.ts +1 -1
- package/dist/internal/deploy-manifest.d.ts.map +1 -1
- package/dist/internal/deploy-manifest.js +1 -1
- package/dist/internal/discovery/ab.d.ts +1 -1
- package/dist/internal/discovery/ab.d.ts.map +1 -1
- package/dist/internal/discovery/ab.js +21 -9
- package/dist/internal/discovery/agent.d.ts +6 -1
- package/dist/internal/discovery/agent.d.ts.map +1 -1
- package/dist/internal/discovery/agent.js +65 -116
- package/dist/internal/discovery/channels.d.ts +1 -1
- package/dist/internal/discovery/channels.d.ts.map +1 -1
- package/dist/internal/discovery/channels.js +14 -14
- package/dist/internal/discovery/connections.d.ts +1 -5
- package/dist/internal/discovery/connections.d.ts.map +1 -1
- package/dist/internal/discovery/connections.js +30 -44
- package/dist/internal/discovery/cursor-plugin.d.ts.map +1 -1
- package/dist/internal/discovery/cursor-plugin.js +1 -3
- package/dist/internal/discovery/extension-overlay.d.ts +32 -0
- package/dist/internal/discovery/extension-overlay.d.ts.map +1 -0
- package/dist/internal/discovery/extension-overlay.js +191 -0
- package/dist/internal/discovery/extensions.d.ts +11 -2
- package/dist/internal/discovery/extensions.d.ts.map +1 -1
- package/dist/internal/discovery/extensions.js +211 -74
- package/dist/internal/discovery/hooks.d.ts +1 -1
- package/dist/internal/discovery/hooks.d.ts.map +1 -1
- package/dist/internal/discovery/hooks.js +15 -2
- package/dist/internal/discovery/info.d.ts.map +1 -1
- package/dist/internal/discovery/info.js +7 -1
- package/dist/internal/discovery/modules.d.ts.map +1 -1
- package/dist/internal/discovery/modules.js +8 -2
- package/dist/internal/discovery/names.d.ts +1 -1
- package/dist/internal/discovery/names.d.ts.map +1 -1
- package/dist/internal/discovery/names.js +1 -0
- package/dist/internal/discovery/project.d.ts +0 -2
- package/dist/internal/discovery/project.d.ts.map +1 -1
- package/dist/internal/discovery/project.js +64 -10
- package/dist/internal/discovery/runtime.d.ts.map +1 -1
- package/dist/internal/discovery/runtime.js +1 -2
- package/dist/internal/discovery/schedules.d.ts +1 -1
- package/dist/internal/discovery/schedules.d.ts.map +1 -1
- package/dist/internal/discovery/schedules.js +23 -2
- package/dist/internal/discovery/services.d.ts +6 -2
- package/dist/internal/discovery/services.d.ts.map +1 -1
- package/dist/internal/discovery/services.js +31 -1
- package/dist/internal/discovery/skills.d.ts +1 -6
- package/dist/internal/discovery/skills.d.ts.map +1 -1
- package/dist/internal/discovery/skills.js +8 -3
- package/dist/internal/discovery/subagent.d.ts +3 -0
- package/dist/internal/discovery/subagent.d.ts.map +1 -1
- package/dist/internal/discovery/subagent.js +109 -0
- package/dist/internal/discovery.d.ts +1 -2
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +1 -2
- package/dist/internal/distribution.d.ts +10 -27
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +25 -73
- package/dist/internal/docs-site.js +1 -1
- package/dist/internal/eval-run-store.d.ts +0 -1
- package/dist/internal/eval-run-store.d.ts.map +1 -1
- package/dist/internal/eval-runner.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.d.ts +8 -0
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +8 -8
- package/dist/internal/github-fanout.d.ts +1 -1
- package/dist/internal/github-fanout.js +1 -1
- package/dist/internal/guest-network.d.ts +101 -0
- package/dist/internal/guest-network.d.ts.map +1 -0
- package/dist/internal/guest-network.js +304 -0
- package/dist/internal/host-otel.d.ts +3 -3
- package/dist/internal/host-otel.d.ts.map +1 -1
- package/dist/internal/host-otel.js +8 -4
- package/dist/internal/hosted-admission-adapter.d.ts +8 -7
- package/dist/internal/hosted-admission-adapter.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.d.ts +6 -0
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +18 -5
- package/dist/internal/hosted-delivery.d.ts +18 -0
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +248 -118
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +1 -3
- package/dist/internal/init-interview.d.ts.map +1 -1
- package/dist/internal/init-interview.js +1 -3
- package/dist/internal/init-project.d.ts +2 -2
- package/dist/internal/init-project.js +2 -2
- package/dist/internal/inline-stdio-define-stub.d.ts +1 -1
- package/dist/internal/inline-stdio-define-stub.d.ts.map +1 -1
- package/dist/internal/inline-stdio-define-stub.js +1 -1
- package/dist/internal/is-record.d.ts +2 -0
- package/dist/internal/is-record.d.ts.map +1 -0
- package/dist/internal/is-record.js +3 -0
- package/dist/internal/json-schema.d.ts.map +1 -1
- package/dist/internal/json-schema.js +18 -10
- package/dist/internal/local-control-plane.d.ts +1 -2
- package/dist/internal/local-control-plane.d.ts.map +1 -1
- package/dist/internal/local-control-plane.js +3 -20
- package/dist/internal/mcp-endpoint.d.ts.map +1 -1
- package/dist/internal/mcp-endpoint.js +1 -3
- package/dist/internal/otel/collector.d.ts +12 -3
- package/dist/internal/otel/collector.d.ts.map +1 -1
- package/dist/internal/otel/collector.js +77 -125
- package/dist/internal/otel/config.d.ts +0 -2
- package/dist/internal/otel/config.d.ts.map +1 -1
- package/dist/internal/otel/config.js +17 -20
- package/dist/internal/otel/http.d.ts +2 -0
- package/dist/internal/otel/http.d.ts.map +1 -1
- package/dist/internal/otel/http.js +7 -1
- package/dist/internal/otel/mcp.d.ts.map +1 -1
- package/dist/internal/otel/mcp.js +3 -16
- package/dist/internal/otel/runtime.d.ts +26 -1
- package/dist/internal/otel/runtime.d.ts.map +1 -1
- package/dist/internal/otel/runtime.js +164 -15
- package/dist/internal/package-inline-stdio.d.ts.map +1 -1
- package/dist/internal/package-inline-stdio.js +3 -11
- package/dist/internal/playground/toolchain.d.ts +1 -1
- package/dist/internal/playground/toolchain.d.ts.map +1 -1
- package/dist/internal/playground/toolchain.js +1 -1
- package/dist/internal/request-error-status.d.ts +12 -0
- package/dist/internal/request-error-status.d.ts.map +1 -0
- package/dist/internal/request-error-status.js +52 -0
- package/dist/internal/resolve-prod-target.d.ts +1 -1
- package/dist/internal/resolve-prod-target.d.ts.map +1 -1
- package/dist/internal/resolve-prod-target.js +3 -7
- package/dist/internal/result-output.d.ts +18 -0
- package/dist/internal/result-output.d.ts.map +1 -0
- package/dist/internal/result-output.js +33 -0
- package/dist/internal/run-client.d.ts +2 -2
- package/dist/internal/run-client.js +2 -2
- package/dist/internal/runtime-dispatch-runner.d.ts +1 -11
- package/dist/internal/runtime-dispatch-runner.d.ts.map +1 -1
- package/dist/internal/runtime-dispatch-runner.js +2 -15
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +3 -6
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +110 -35
- package/dist/internal/session-cost.d.ts +3 -3
- package/dist/internal/session-cost.d.ts.map +1 -1
- package/dist/internal/session-cost.js +3 -3
- package/dist/internal/session-engine.d.ts +26 -11
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +146 -76
- package/dist/internal/session-run-log.d.ts.map +1 -1
- package/dist/internal/session-run-log.js +1 -3
- package/dist/internal/skills-sync.d.ts +1 -4
- package/dist/internal/skills-sync.d.ts.map +1 -1
- package/dist/internal/skills-sync.js +10 -50
- package/dist/internal/sleep.d.ts +2 -0
- package/dist/internal/sleep.d.ts.map +1 -0
- package/dist/internal/sleep.js +3 -0
- package/dist/internal/store-mirror.d.ts +29 -0
- package/dist/internal/store-mirror.d.ts.map +1 -0
- package/dist/internal/store-mirror.js +70 -0
- package/dist/internal/tenant-slack/relay.d.ts +73 -0
- package/dist/internal/tenant-slack/relay.d.ts.map +1 -0
- package/dist/internal/tenant-slack/relay.js +138 -0
- package/dist/internal/testing/scm-continuation-fixtures.d.ts +33 -0
- package/dist/internal/testing/scm-continuation-fixtures.d.ts.map +1 -0
- package/dist/internal/testing/scm-continuation-fixtures.js +253 -0
- package/dist/internal/workspace-sync.d.ts +22 -0
- package/dist/internal/workspace-sync.d.ts.map +1 -0
- package/dist/internal/workspace-sync.js +49 -0
- package/dist/internal/workspace.d.ts +7 -0
- package/dist/internal/workspace.d.ts.map +1 -1
- package/dist/internal/workspace.js +13 -0
- package/dist/otel.d.ts +23 -1
- package/dist/otel.d.ts.map +1 -1
- package/dist/otel.js +93 -2
- package/dist/playground/assets/index-59KvgREd.js +67 -0
- package/dist/playground/assets/index-MbMxXg-y.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/result.d.ts +24 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js +27 -0
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +7 -4
- package/dist/storage-protocol.d.ts.map +1 -1
- package/dist/storage-protocol.js +1 -3
- package/dist/types.d.ts +90 -23
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +2 -2
- package/docs/concepts.md +2 -4
- package/docs/design/runtime-abstraction.md +2 -3
- package/docs/evals.md +9 -7
- package/docs/guides/cloud-agents.md +4 -6
- package/docs/guides/github.md +0 -1
- package/docs/guides/opentelemetry.md +41 -17
- package/docs/reference/agent-config.md +6 -10
- package/docs/reference/channels.md +18 -8
- package/docs/reference/cli.md +3 -4
- package/docs/reference/extensions.md +87 -23
- package/docs/reference/hooks.md +215 -46
- package/docs/reference/playground.md +3 -0
- package/docs/reference/project-layout.md +2 -1
- package/docs/reference/result.md +94 -0
- package/docs/reference/sessions.md +3 -1
- package/docs/reference/tools.md +1 -2
- package/docs/templates/pr-autofixer.md +0 -3
- package/package.json +29 -10
- package/skills/framework-map/SKILL.md +3 -1
- package/skills/otel/SKILL.md +8 -3
- package/src/ab.ts +1 -1
- package/src/bin/agent-serve.ts +121 -21
- package/src/channels/bitbucket/api.ts +623 -0
- package/src/channels/bitbucket/binding.ts +414 -0
- package/src/channels/bitbucket/bitbucket-channel.ts +182 -0
- package/src/channels/bitbucket/bitbucket-webhook.ts +576 -0
- package/src/channels/bitbucket/checks.ts +154 -0
- package/src/channels/bitbucket/cursor-account.ts +117 -0
- package/src/channels/bitbucket/defaults.ts +110 -0
- package/src/channels/bitbucket/events.ts +84 -0
- package/src/channels/bitbucket/index.ts +49 -0
- package/src/channels/bitbucket/replay.ts +439 -0
- package/src/channels/bitbucket/state.ts +59 -0
- package/src/channels/bitbucket/types.ts +266 -0
- package/src/channels/deployments/deployments-channel.ts +25 -43
- package/src/channels/deployments/types.ts +12 -6
- package/src/channels/github/binding.ts +8 -1
- package/src/channels/github/cursor-account.ts +17 -6
- package/src/channels/github/events.ts +1 -1
- package/src/channels/github/forward.ts +3 -2
- package/src/channels/github/github-channel.ts +74 -221
- package/src/channels/github/replay.ts +1 -1
- package/src/channels/github/state.ts +6 -0
- package/src/channels/github/types.ts +2 -5
- package/src/channels/gitlab/api.ts +228 -0
- package/src/channels/gitlab/binding.ts +233 -0
- package/src/channels/gitlab/checks.ts +243 -0
- package/src/channels/gitlab/cursor-account.ts +114 -0
- package/src/channels/gitlab/defaults.ts +93 -0
- package/src/channels/gitlab/events.ts +44 -0
- package/src/channels/gitlab/gitlab-channel.ts +176 -0
- package/src/channels/gitlab/gitlab-webhook.ts +555 -0
- package/src/channels/gitlab/index.ts +43 -0
- package/src/channels/gitlab/replay.ts +347 -0
- package/src/channels/gitlab/state.ts +55 -0
- package/src/channels/gitlab/types.ts +263 -0
- package/src/channels/origin/api.ts +4 -2
- package/src/channels/origin/origin-channel.ts +19 -94
- package/src/channels/origin/types.ts +23 -2
- package/src/channels/slack/eval-directive.ts +1 -6
- package/src/channels/slack/init.ts +6 -3
- package/src/channels/slack/setup.ts +7 -6
- package/src/channels/slack/types.ts +1 -1
- package/src/channels.ts +0 -1
- package/src/client.ts +1 -1
- package/src/connections.ts +1 -1
- package/src/evals.ts +1 -1
- package/src/extensions.ts +47 -5
- package/src/files.ts +21 -3
- package/src/index.ts +20 -28
- package/src/internal/ab-snapshot.ts +0 -3
- package/src/internal/advertise-tools.ts +1 -4
- package/src/internal/authored-alias-hooks.ts +4 -21
- package/src/internal/authored-loaders.ts +6 -23
- package/src/internal/channel-dispatch.ts +160 -0
- package/src/internal/chat-client.ts +1 -1
- package/src/internal/cli-ax.ts +5 -5
- package/src/internal/cli-bitbucket.ts +477 -0
- package/src/internal/cli-convert-automation.ts +7 -7
- package/src/internal/cli-cursor.ts +2 -5
- package/src/internal/cli-deploy.ts +2 -8
- package/src/internal/cli-github.ts +3 -3
- package/src/internal/cli-gitlab.ts +485 -0
- package/src/internal/cli-mcp.ts +2 -7
- package/src/internal/cli-slack.ts +2 -5
- package/src/internal/continuation-channel.ts +82 -1
- package/src/internal/continuation-identity.ts +229 -11
- package/src/internal/conversation-mirror.ts +4 -3
- package/src/internal/convert-automation/types.ts +1 -1
- package/src/internal/cursor/account-mcp.ts +1 -4
- package/src/internal/cursor/backend-client.ts +9 -10
- package/src/internal/cursor/bound-secret-file.ts +108 -0
- package/src/internal/cursor/credentials.ts +75 -10
- package/src/internal/cursor/hosted-bound-secrets.ts +75 -0
- package/src/internal/cursor/hosted-deployment-secrets.ts +42 -11
- package/src/internal/cursor/hosted-store-secrets.ts +1 -1
- package/src/internal/cursor-account-mcp-auth.ts +2 -5
- package/src/internal/cursor-deployment-relay.ts +11 -7
- package/src/internal/deploy-manifest.ts +4 -2
- package/src/internal/discovery/ab.ts +29 -9
- package/src/internal/discovery/agent.ts +94 -135
- package/src/internal/discovery/channels.ts +15 -13
- package/src/internal/discovery/connections.ts +55 -50
- package/src/internal/discovery/cursor-plugin.ts +1 -4
- package/src/internal/discovery/extension-overlay.ts +274 -0
- package/src/internal/discovery/extensions.ts +330 -105
- package/src/internal/discovery/hooks.ts +20 -2
- package/src/internal/discovery/info.ts +7 -0
- package/src/internal/discovery/modules.ts +8 -2
- package/src/internal/discovery/names.ts +2 -1
- package/src/internal/discovery/project.ts +80 -9
- package/src/internal/discovery/runtime.ts +1 -2
- package/src/internal/discovery/schedules.ts +28 -2
- package/src/internal/discovery/services.ts +37 -1
- package/src/internal/discovery/skills.ts +13 -3
- package/src/internal/discovery/subagent.ts +107 -0
- package/src/internal/discovery.ts +0 -2
- package/src/internal/distribution.ts +35 -83
- package/src/internal/docs-site.ts +1 -1
- package/src/internal/eval-run-store.ts +0 -7
- package/src/internal/eval-runner.ts +0 -1
- package/src/internal/framework-file-storage.ts +8 -8
- package/src/internal/github-fanout.ts +1 -1
- package/src/internal/guest-network.ts +383 -0
- package/src/internal/host-otel.ts +8 -4
- package/src/internal/hosted-admission-adapter.ts +8 -8
- package/src/internal/hosted-delivery-protocol.ts +26 -1
- package/src/internal/hosted-delivery.ts +376 -192
- package/src/internal/http-channel.ts +1 -4
- package/src/internal/init-interview.ts +1 -4
- package/src/internal/init-project.ts +2 -2
- package/src/internal/inline-stdio-define-stub.ts +1 -1
- package/src/internal/is-record.ts +3 -0
- package/src/internal/json-schema.ts +19 -10
- package/src/internal/local-control-plane.ts +5 -24
- package/src/internal/mcp-endpoint.ts +1 -4
- package/src/internal/otel/collector.ts +94 -159
- package/src/internal/otel/config.ts +10 -14
- package/src/internal/otel/http.ts +14 -1
- package/src/internal/otel/mcp.ts +3 -16
- package/src/internal/otel/runtime.ts +240 -25
- package/src/internal/package-inline-stdio.ts +3 -12
- package/src/internal/playground/toolchain.ts +1 -1
- package/src/internal/request-error-status.ts +72 -0
- package/src/internal/resolve-prod-target.ts +3 -8
- package/src/internal/result-output.ts +34 -0
- package/src/internal/run-client.ts +2 -2
- package/src/internal/runtime-dispatch-runner.ts +3 -21
- package/src/internal/sdk-runner.ts +3 -7
- package/src/internal/server.ts +153 -44
- package/src/internal/session-cost.ts +3 -3
- package/src/internal/session-engine.ts +182 -74
- package/src/internal/session-run-log.ts +1 -4
- package/src/internal/skills-sync.ts +13 -63
- package/src/internal/sleep.ts +3 -0
- package/src/internal/store-mirror.ts +86 -0
- package/src/internal/tenant-slack/relay.ts +179 -0
- package/src/internal/testing/scm-continuation-fixtures.ts +286 -0
- package/src/internal/workspace-sync.ts +55 -0
- package/src/internal/workspace.ts +14 -0
- package/src/otel.ts +143 -3
- package/src/result.ts +36 -0
- package/src/storage-backends/cursor-hosted.ts +7 -4
- package/src/storage-protocol.ts +1 -4
- package/src/types.ts +105 -34
- package/templates/triage/agent/lib/types.ts +0 -2
- package/dist/continuation.d.ts +0 -20
- package/dist/continuation.d.ts.map +0 -1
- package/dist/continuation.js +0 -18
- package/dist/docs/assets/chunks/@localSearchIndexroot.FAqdWIXo.js +0 -1
- package/dist/docs/assets/concepts.md.rPzW2HZN.js +0 -1
- package/dist/docs/assets/guides_cloud-agents.md.DumwWXba.js +0 -9
- package/dist/docs/assets/guides_cloud-runtime.md.BRirbRAN.js +0 -9
- package/dist/docs/assets/guides_cloud-runtime.md.BRirbRAN.lean.js +0 -1
- package/dist/docs/assets/reference_extensions.md.9WQMZe1l.lean.js +0 -1
- package/dist/docs/assets/reference_hooks.md.a8BJxMR5.js +0 -14
- package/dist/docs/assets/skills_framework-map.md.DDa4MeEW.js +0 -1
- package/dist/docs/guides/cloud-runtime.html +0 -35
- package/dist/docs/guides/cloud-runtime.md +0 -117
- package/dist/internal/convert-automation/index.d.ts +0 -3
- package/dist/internal/convert-automation/index.d.ts.map +0 -1
- package/dist/internal/convert-automation/index.js +0 -1
- package/dist/internal/grokbot/runner.d.ts +0 -64
- package/dist/internal/grokbot/runner.d.ts.map +0 -1
- package/dist/internal/grokbot/runner.js +0 -282
- package/dist/internal/managed-delivery.d.ts +0 -80
- package/dist/internal/managed-delivery.d.ts.map +0 -1
- package/dist/internal/managed-delivery.js +0 -86
- package/dist/internal/review-comments.d.ts +0 -370
- package/dist/internal/review-comments.d.ts.map +0 -1
- package/dist/internal/review-comments.js +0 -921
- package/dist/internal/shallow-clone.d.ts +0 -176
- package/dist/internal/shallow-clone.d.ts.map +0 -1
- package/dist/internal/shallow-clone.js +0 -419
- package/dist/playground/assets/index-B6C9S9nG.css +0 -1
- package/dist/playground/assets/index-ZqNoT8Ie.js +0 -69
- package/docs/guides/cloud-runtime.md +0 -122
- package/src/continuation.ts +0 -49
- package/src/internal/convert-automation/index.ts +0 -10
- package/src/internal/grokbot/runner.ts +0 -370
- package/src/internal/managed-delivery.ts +0 -125
- package/src/internal/review-comments.ts +0 -1363
- package/src/internal/shallow-clone.ts +0 -609
- /package/dist/docs/assets/{evals.md.CPzDAwoH.lean.js → evals.md.CbMoebP1.lean.js} +0 -0
- /package/dist/docs/assets/{guides_cloud-agents.md.DumwWXba.lean.js → guides_cloud-agents.md.DS8RIjwx.lean.js} +0 -0
- /package/dist/docs/assets/{guides_github.md.BtPr9GaP.lean.js → guides_github.md.DKYiT9do.lean.js} +0 -0
- /package/dist/docs/assets/{index.md.Kiht7ell.lean.js → index.md.D75GWhPl.lean.js} +0 -0
- /package/dist/docs/assets/{reference_agent-config.md.BHeYMgme.lean.js → reference_agent-config.md.CHNpiyp4.lean.js} +0 -0
- /package/dist/docs/assets/{reference_cli.md.DfoeyvL0.lean.js → reference_cli.md.CJNc_xYK.lean.js} +0 -0
- /package/dist/docs/assets/{reference_playground.md.DnX5nL-B.lean.js → reference_playground.md.4myJPxrf.lean.js} +0 -0
- /package/dist/docs/assets/{reference_project-layout.md.CA6QP6Lw.lean.js → reference_project-layout.md.DuBu9a96.lean.js} +0 -0
- /package/dist/docs/assets/{reference_tools.md.B1up2r9W.lean.js → reference_tools.md.aGrn99hP.lean.js} +0 -0
- /package/dist/docs/assets/{skills_framework-map.md.DDa4MeEW.lean.js → skills_framework-map.md.haibFyoB.lean.js} +0 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitLab REST v4 client for the GitLab channel — the `createGitHubOctokit`
|
|
3
|
+
* / `createOriginClient` analogue.
|
|
4
|
+
*
|
|
5
|
+
* Two transports:
|
|
6
|
+
*
|
|
7
|
+
* - **Direct**: `PRIVATE-TOKEN` against `https://<host>/api/v4` with a
|
|
8
|
+
* project / group / personal access token from options or `GITLAB_TOKEN`.
|
|
9
|
+
* The host defaults to `GITLAB_API_BASE_URL`, else gitlab.com. `ctx.gitlab`
|
|
10
|
+
* never derives it from the webhook payload; only the replay CLI passes a
|
|
11
|
+
* user-supplied `projectWebUrl`.
|
|
12
|
+
* - **Proxy** (`--cursor-scm-proxy` with `cursorAccount`): the backend
|
|
13
|
+
* forwarder at `/v0/gitlab-proxy`. Calls carry the Cursor API key as the
|
|
14
|
+
* bearer plus `x-cursor-gitlab-projects` naming the project the call is
|
|
15
|
+
* scoped to; the backend swaps in the tenant's GitLab credential.
|
|
16
|
+
*
|
|
17
|
+
* Deliberately fetch-based rather than `@gitbeaker/rest`: the pack needs a
|
|
18
|
+
* handful of endpoints and one header hook, not a full SDK dependency.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
export const DEFAULT_GITLAB_API_BASE_URL = "https://gitlab.com/api/v4";
|
|
22
|
+
|
|
23
|
+
/** Header the SCM proxy reads to scope a GitLab call to one project. */
|
|
24
|
+
export const CURSOR_GITLAB_PROJECTS_HEADER = "x-cursor-gitlab-projects";
|
|
25
|
+
|
|
26
|
+
export type GitLabApiMethod = "DELETE" | "GET" | "PATCH" | "POST" | "PUT";
|
|
27
|
+
|
|
28
|
+
/** Normalized GitLab REST failure — the `GitHubApiError` analogue. */
|
|
29
|
+
export class GitLabApiError extends Error {
|
|
30
|
+
readonly body: unknown;
|
|
31
|
+
readonly method: string;
|
|
32
|
+
readonly path: string;
|
|
33
|
+
readonly status: number;
|
|
34
|
+
|
|
35
|
+
constructor(input: {
|
|
36
|
+
body: unknown;
|
|
37
|
+
method: string;
|
|
38
|
+
path: string;
|
|
39
|
+
status: number;
|
|
40
|
+
}) {
|
|
41
|
+
super(
|
|
42
|
+
`GitLab ${input.method} ${input.path} failed with HTTP ${input.status}.`
|
|
43
|
+
);
|
|
44
|
+
this.name = "GitLabApiError";
|
|
45
|
+
this.body = input.body;
|
|
46
|
+
this.method = input.method;
|
|
47
|
+
this.path = input.path;
|
|
48
|
+
this.status = input.status;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type GitLabTokenProvider = () => Promise<string> | string;
|
|
53
|
+
|
|
54
|
+
/** Backend SCM-proxy transport bound by the serve host in proxy mode. */
|
|
55
|
+
export interface GitLabProxyTransport {
|
|
56
|
+
/** `/v0/gitlab-proxy` base, see `resolveCursorGitLabProxyUrl`. */
|
|
57
|
+
apiBaseUrl: string;
|
|
58
|
+
/** Cursor API key sent as the bearer; the proxy swaps in the GitLab token. */
|
|
59
|
+
getApiKey: () => Promise<string>;
|
|
60
|
+
/** Static headers added to every call (project scope when declared). */
|
|
61
|
+
headers?: Readonly<Record<string, string>>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface GitLabClientOptions {
|
|
65
|
+
/** REST base, e.g. `https://gitlab.example.com/api/v4`. */
|
|
66
|
+
apiBaseUrl?: string;
|
|
67
|
+
/** Access token or provider for direct calls. Falls back to `GITLAB_TOKEN`. */
|
|
68
|
+
token?: string | GitLabTokenProvider;
|
|
69
|
+
/** Route through the Cursor SCM proxy instead of calling GitLab directly. */
|
|
70
|
+
proxy?: GitLabProxyTransport;
|
|
71
|
+
/**
|
|
72
|
+
* Project (`group/project`) every call is scoped to. Proxy mode sends it
|
|
73
|
+
* as `x-cursor-gitlab-projects` when no static header names one.
|
|
74
|
+
*/
|
|
75
|
+
project?: string;
|
|
76
|
+
/** Injectable fetch for tests. */
|
|
77
|
+
fetch?: typeof fetch;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface GitLabRequestInput {
|
|
81
|
+
method: GitLabApiMethod;
|
|
82
|
+
/** Path under the API base, e.g. `/projects/42/statuses/<sha>`. */
|
|
83
|
+
path: string;
|
|
84
|
+
query?: Record<string, string | number | boolean | undefined>;
|
|
85
|
+
body?: unknown;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Minimal authenticated GitLab REST client. */
|
|
89
|
+
export interface GitLabClient {
|
|
90
|
+
readonly apiBaseUrl: string;
|
|
91
|
+
/** Call a GitLab v4 path. Throws {@link GitLabApiError} on non-2xx. */
|
|
92
|
+
request<T = unknown>(input: GitLabRequestInput): Promise<T>;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function envValue(value: string | undefined): string | undefined {
|
|
96
|
+
const trimmed = value?.trim();
|
|
97
|
+
return trimmed === undefined || trimmed === "" ? undefined : trimmed;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** `GITLAB_TOKEN` when set. */
|
|
101
|
+
export function envGitLabToken(
|
|
102
|
+
env: NodeJS.ProcessEnv = process.env
|
|
103
|
+
): string | undefined {
|
|
104
|
+
return envValue(env.GITLAB_TOKEN);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* REST base for direct calls: `GITLAB_API_BASE_URL`, else `/api/v4` on the
|
|
109
|
+
* given project web URL's origin (self-managed hosts), else gitlab.com.
|
|
110
|
+
*/
|
|
111
|
+
export function gitlabApiBaseUrl(input?: {
|
|
112
|
+
projectWebUrl?: string;
|
|
113
|
+
env?: NodeJS.ProcessEnv;
|
|
114
|
+
}): string {
|
|
115
|
+
const fromEnv = envValue((input?.env ?? process.env).GITLAB_API_BASE_URL);
|
|
116
|
+
if (fromEnv !== undefined) {
|
|
117
|
+
return fromEnv.replace(/\/+$/, "");
|
|
118
|
+
}
|
|
119
|
+
if (input?.projectWebUrl !== undefined) {
|
|
120
|
+
try {
|
|
121
|
+
return `${new URL(input.projectWebUrl).origin}/api/v4`;
|
|
122
|
+
} catch {
|
|
123
|
+
// fall through to the default host
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return DEFAULT_GITLAB_API_BASE_URL;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* GitLab's `:id` path segment accepts a numeric id or a URL-encoded
|
|
131
|
+
* `group/project` path.
|
|
132
|
+
*/
|
|
133
|
+
export function gitlabProjectPathSegment(project: number | string): string {
|
|
134
|
+
return typeof project === "number"
|
|
135
|
+
? String(project)
|
|
136
|
+
: encodeURIComponent(project.replace(/^\/+|\/+$/g, ""));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function buildQuery(query: GitLabRequestInput["query"]): string {
|
|
140
|
+
if (query === undefined) {
|
|
141
|
+
return "";
|
|
142
|
+
}
|
|
143
|
+
const params = new URLSearchParams();
|
|
144
|
+
for (const [key, value] of Object.entries(query)) {
|
|
145
|
+
if (value !== undefined) {
|
|
146
|
+
params.set(key, String(value));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const encoded = params.toString();
|
|
150
|
+
return encoded === "" ? "" : `?${encoded}`;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function createGitLabClient(
|
|
154
|
+
options: GitLabClientOptions = {}
|
|
155
|
+
): GitLabClient {
|
|
156
|
+
const fetchImpl = options.fetch ?? fetch;
|
|
157
|
+
const apiBaseUrl = (
|
|
158
|
+
options.proxy?.apiBaseUrl ??
|
|
159
|
+
options.apiBaseUrl ??
|
|
160
|
+
gitlabApiBaseUrl()
|
|
161
|
+
).replace(/\/+$/, "");
|
|
162
|
+
const project = options.project?.trim().replace(/^\/+|\/+$/g, "");
|
|
163
|
+
|
|
164
|
+
const authHeaders = async (): Promise<Record<string, string>> => {
|
|
165
|
+
if (options.proxy !== undefined) {
|
|
166
|
+
const headers: Record<string, string> = {
|
|
167
|
+
authorization: `Bearer ${await options.proxy.getApiKey()}`,
|
|
168
|
+
...options.proxy.headers,
|
|
169
|
+
};
|
|
170
|
+
if (
|
|
171
|
+
(headers[CURSOR_GITLAB_PROJECTS_HEADER] ?? "").trim() === "" &&
|
|
172
|
+
project !== undefined &&
|
|
173
|
+
project !== ""
|
|
174
|
+
) {
|
|
175
|
+
headers[CURSOR_GITLAB_PROJECTS_HEADER] = project.toLowerCase();
|
|
176
|
+
}
|
|
177
|
+
return headers;
|
|
178
|
+
}
|
|
179
|
+
const token =
|
|
180
|
+
typeof options.token === "function"
|
|
181
|
+
? await options.token()
|
|
182
|
+
: (options.token ?? envGitLabToken());
|
|
183
|
+
if (token === undefined || token === "") {
|
|
184
|
+
throw new Error(
|
|
185
|
+
"gitlabChannel: no GitLab credential available (pass token, set GITLAB_TOKEN, or serve with --cursor-scm-proxy and cursorAccount)."
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
return { "private-token": token };
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
return {
|
|
192
|
+
apiBaseUrl,
|
|
193
|
+
async request<T = unknown>(input: GitLabRequestInput): Promise<T> {
|
|
194
|
+
const path = input.path.startsWith("/") ? input.path : `/${input.path}`;
|
|
195
|
+
const response = await fetchImpl(
|
|
196
|
+
`${apiBaseUrl}${path}${buildQuery(input.query)}`,
|
|
197
|
+
{
|
|
198
|
+
method: input.method,
|
|
199
|
+
headers: {
|
|
200
|
+
...(await authHeaders()),
|
|
201
|
+
accept: "application/json",
|
|
202
|
+
...(input.body === undefined
|
|
203
|
+
? {}
|
|
204
|
+
: { "content-type": "application/json" }),
|
|
205
|
+
},
|
|
206
|
+
body:
|
|
207
|
+
input.body === undefined ? undefined : JSON.stringify(input.body),
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
const text = await response.text();
|
|
211
|
+
let parsed: unknown;
|
|
212
|
+
try {
|
|
213
|
+
parsed = text === "" ? undefined : JSON.parse(text);
|
|
214
|
+
} catch {
|
|
215
|
+
parsed = text;
|
|
216
|
+
}
|
|
217
|
+
if (!response.ok) {
|
|
218
|
+
throw new GitLabApiError({
|
|
219
|
+
body: parsed,
|
|
220
|
+
method: input.method,
|
|
221
|
+
path,
|
|
222
|
+
status: response.status,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
return parsed as T;
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project / merge-request binding parsed from a GitLab webhook payload.
|
|
3
|
+
*
|
|
4
|
+
* Every GitLab hook payload carries `project` (`id`, `path_with_namespace`,
|
|
5
|
+
* `web_url`); the merge request lives under `object_attributes` for
|
|
6
|
+
* `merge_request` events and under `merge_request` for `note` / `pipeline`.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
createGitLabClient,
|
|
11
|
+
type GitLabClient,
|
|
12
|
+
type GitLabProxyTransport,
|
|
13
|
+
type GitLabRequestInput,
|
|
14
|
+
type GitLabTokenProvider,
|
|
15
|
+
gitlabApiBaseUrl,
|
|
16
|
+
} from "./api.js";
|
|
17
|
+
import {
|
|
18
|
+
createGitLabCheck,
|
|
19
|
+
type GitLabCheck,
|
|
20
|
+
type GitLabCheckCreateInput,
|
|
21
|
+
type GitLabCommitStatus,
|
|
22
|
+
type GitLabCommitStatusInput,
|
|
23
|
+
setGitLabCommitStatus,
|
|
24
|
+
} from "./checks.js";
|
|
25
|
+
import type {
|
|
26
|
+
GitLabMergeRequestEvent,
|
|
27
|
+
GitLabNoteableType,
|
|
28
|
+
GitLabProjectRef,
|
|
29
|
+
GitLabUser,
|
|
30
|
+
} from "./types.js";
|
|
31
|
+
|
|
32
|
+
/** GitLab operations exposed to hooks (`ctx.gitlab`), bound to the project. */
|
|
33
|
+
export interface GitLabHandle {
|
|
34
|
+
project: GitLabProjectRef;
|
|
35
|
+
/** Call a GitLab v4 path. Throws `GitLabApiError` on API failure. */
|
|
36
|
+
request<T = unknown>(input: GitLabRequestInput): Promise<T>;
|
|
37
|
+
/** Post a commit status on the bound project. */
|
|
38
|
+
setCommitStatus(
|
|
39
|
+
input: Omit<GitLabCommitStatusInput, "project">
|
|
40
|
+
): Promise<GitLabCommitStatus>;
|
|
41
|
+
/** Open a commit status through the shared check lifecycle. */
|
|
42
|
+
createCheck(
|
|
43
|
+
input: Omit<GitLabCheckCreateInput, "gitlab" | "project">
|
|
44
|
+
): Promise<GitLabCheck>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Build `ctx.gitlab` for one delivery. Lazy: no credential is resolved until
|
|
49
|
+
* the first call, so channels without outbound GitLab access still dispatch.
|
|
50
|
+
* Proxy mode (`cursorAccount` + `--cursor-scm-proxy`) wins when the host
|
|
51
|
+
* bound a transport; otherwise direct access with `token` / `GITLAB_TOKEN`.
|
|
52
|
+
*
|
|
53
|
+
* Nothing credentialed is derived from the payload: the API base comes from
|
|
54
|
+
* `apiBaseUrl` / `GITLAB_API_BASE_URL` (else gitlab.com), never from the
|
|
55
|
+
* delivery's `project.web_url`, so a forged hook cannot redirect the token to
|
|
56
|
+
* another host. Writes address the project by `path_with_namespace` — the
|
|
57
|
+
* same field the `projects` allowlist admits on — rather than by the
|
|
58
|
+
* independently forgeable numeric `project.id`.
|
|
59
|
+
*/
|
|
60
|
+
export function buildGitLabBinding(input: {
|
|
61
|
+
project: GitLabProjectRef;
|
|
62
|
+
proxy?: GitLabProxyTransport;
|
|
63
|
+
token?: string | GitLabTokenProvider;
|
|
64
|
+
apiBaseUrl?: string;
|
|
65
|
+
fetch?: typeof fetch;
|
|
66
|
+
}): GitLabHandle {
|
|
67
|
+
let client: GitLabClient | undefined;
|
|
68
|
+
const getClient = (): GitLabClient => {
|
|
69
|
+
client ??= createGitLabClient({
|
|
70
|
+
proxy: input.proxy,
|
|
71
|
+
token: input.token,
|
|
72
|
+
apiBaseUrl: input.apiBaseUrl ?? gitlabApiBaseUrl(),
|
|
73
|
+
project: input.project.pathWithNamespace,
|
|
74
|
+
fetch: input.fetch,
|
|
75
|
+
});
|
|
76
|
+
return client;
|
|
77
|
+
};
|
|
78
|
+
return {
|
|
79
|
+
project: input.project,
|
|
80
|
+
request: (request) => getClient().request(request),
|
|
81
|
+
setCommitStatus: (status) =>
|
|
82
|
+
setGitLabCommitStatus(getClient(), {
|
|
83
|
+
...status,
|
|
84
|
+
project: input.project.pathWithNamespace,
|
|
85
|
+
}),
|
|
86
|
+
createCheck: (check) =>
|
|
87
|
+
createGitLabCheck({
|
|
88
|
+
...check,
|
|
89
|
+
gitlab: getClient(),
|
|
90
|
+
project: input.project.pathWithNamespace,
|
|
91
|
+
}),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function asRecord(value: unknown): Record<string, unknown> | undefined {
|
|
96
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
97
|
+
? (value as Record<string, unknown>)
|
|
98
|
+
: undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function asNonEmptyString(value: unknown): string | undefined {
|
|
102
|
+
return typeof value === "string" && value.trim() !== ""
|
|
103
|
+
? value.trim()
|
|
104
|
+
: undefined;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function asPositiveInt(value: unknown): number | undefined {
|
|
108
|
+
if (typeof value === "number" && Number.isInteger(value) && value > 0) {
|
|
109
|
+
return value;
|
|
110
|
+
}
|
|
111
|
+
if (typeof value === "string" && /^[1-9]\d*$/.test(value)) {
|
|
112
|
+
return Number(value);
|
|
113
|
+
}
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function asBoolean(value: unknown): boolean | undefined {
|
|
118
|
+
return typeof value === "boolean" ? value : undefined;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function gitlabProjectFromPayload(
|
|
122
|
+
payload: Record<string, unknown>
|
|
123
|
+
): GitLabProjectRef | undefined {
|
|
124
|
+
const project = asRecord(payload.project);
|
|
125
|
+
const id = asPositiveInt(project?.id) ?? asPositiveInt(payload.project_id);
|
|
126
|
+
const pathWithNamespace = asNonEmptyString(project?.path_with_namespace);
|
|
127
|
+
if (id === undefined || pathWithNamespace === undefined) {
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
const webUrl =
|
|
131
|
+
asNonEmptyString(project?.web_url) ??
|
|
132
|
+
`https://gitlab.com/${pathWithNamespace}`;
|
|
133
|
+
const defaultBranch = asNonEmptyString(project?.default_branch);
|
|
134
|
+
return {
|
|
135
|
+
id,
|
|
136
|
+
pathWithNamespace,
|
|
137
|
+
webUrl,
|
|
138
|
+
...(defaultBranch === undefined ? {} : { defaultBranch }),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function gitlabUser(value: unknown): GitLabUser | undefined {
|
|
143
|
+
const record = asRecord(value);
|
|
144
|
+
const id = asPositiveInt(record?.id);
|
|
145
|
+
const username = asNonEmptyString(record?.username);
|
|
146
|
+
if (id === undefined || username === undefined) {
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
const name = asNonEmptyString(record?.name);
|
|
150
|
+
return name === undefined ? { id, username } : { id, username, name };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* The actor of a delivery. Most hooks nest it under `user`; `push` and
|
|
155
|
+
* `tag_push` flatten it to top-level `user_id` / `user_username` /
|
|
156
|
+
* `user_name` instead.
|
|
157
|
+
*/
|
|
158
|
+
export function gitlabSender(
|
|
159
|
+
payload: Record<string, unknown>
|
|
160
|
+
): GitLabUser | undefined {
|
|
161
|
+
return (
|
|
162
|
+
gitlabUser(payload.user) ??
|
|
163
|
+
gitlabUser({
|
|
164
|
+
id: payload.user_id,
|
|
165
|
+
username: payload.user_username,
|
|
166
|
+
name: payload.user_name,
|
|
167
|
+
})
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function gitlabMergeRequestUrl(
|
|
172
|
+
project: GitLabProjectRef,
|
|
173
|
+
iid: number,
|
|
174
|
+
explicit?: string
|
|
175
|
+
): string {
|
|
176
|
+
return explicit ?? `${project.webUrl}/-/merge_requests/${iid}`;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Normalize a merge-request record (`object_attributes` or `merge_request`). */
|
|
180
|
+
export function gitlabMergeRequestFromRecord(
|
|
181
|
+
project: GitLabProjectRef,
|
|
182
|
+
record: Record<string, unknown> | undefined
|
|
183
|
+
): GitLabMergeRequestEvent | undefined {
|
|
184
|
+
const iid = asPositiveInt(record?.iid);
|
|
185
|
+
if (record === undefined || iid === undefined) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
const labels = Array.isArray(record.labels)
|
|
189
|
+
? record.labels
|
|
190
|
+
.map((label) => asNonEmptyString(asRecord(label)?.title))
|
|
191
|
+
.filter((title): title is string => title !== undefined)
|
|
192
|
+
: undefined;
|
|
193
|
+
const description =
|
|
194
|
+
record.description === null
|
|
195
|
+
? null
|
|
196
|
+
: typeof record.description === "string"
|
|
197
|
+
? record.description
|
|
198
|
+
: undefined;
|
|
199
|
+
return {
|
|
200
|
+
action: asNonEmptyString(record.action),
|
|
201
|
+
iid,
|
|
202
|
+
id: asPositiveInt(record.id),
|
|
203
|
+
url: gitlabMergeRequestUrl(project, iid, asNonEmptyString(record.url)),
|
|
204
|
+
title: asNonEmptyString(record.title),
|
|
205
|
+
description,
|
|
206
|
+
state: asNonEmptyString(record.state),
|
|
207
|
+
draft: asBoolean(record.draft) ?? asBoolean(record.work_in_progress),
|
|
208
|
+
sourceBranch: asNonEmptyString(record.source_branch),
|
|
209
|
+
targetBranch: asNonEmptyString(record.target_branch),
|
|
210
|
+
headSha: asNonEmptyString(asRecord(record.last_commit)?.id),
|
|
211
|
+
oldrev: asNonEmptyString(record.oldrev),
|
|
212
|
+
authorId: asPositiveInt(record.author_id),
|
|
213
|
+
...(labels === undefined ? {} : { labels }),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const NOTEABLE_TYPES: Readonly<Record<string, GitLabNoteableType>> = {
|
|
218
|
+
MergeRequest: "merge_request",
|
|
219
|
+
Issue: "issue",
|
|
220
|
+
Commit: "commit",
|
|
221
|
+
Snippet: "snippet",
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
/** `noteable_type: "MergeRequest"` → `merge_request`; unknown values pass through. */
|
|
225
|
+
export function normalizeGitLabNoteableType(
|
|
226
|
+
value: unknown
|
|
227
|
+
): string | undefined {
|
|
228
|
+
const raw = asNonEmptyString(value);
|
|
229
|
+
if (raw === undefined) {
|
|
230
|
+
return undefined;
|
|
231
|
+
}
|
|
232
|
+
return NOTEABLE_TYPES[raw] ?? raw.toLowerCase();
|
|
233
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitLab commit statuses — the GitLab {@link CiCheckWriter} behind the shared
|
|
3
|
+
* check lifecycle in `../checks.js`.
|
|
4
|
+
*
|
|
5
|
+
* GitLab has no Checks API; the merge-request widget shows **commit
|
|
6
|
+
* statuses** (`POST /projects/:id/statuses/:sha`, one row per `name`). The
|
|
7
|
+
* writer maps the shared status / conclusion pair onto GitLab's state set
|
|
8
|
+
* and re-posts the full desired state on every write, so `resumeGitLabCheck`
|
|
9
|
+
* needs only `(project, sha, name)` to rebuild a handle after a restart.
|
|
10
|
+
*
|
|
11
|
+
* Posting needs a token with `api` scope (Developer role or above); through
|
|
12
|
+
* the SCM proxy that is the tenant's project / host credential.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
type CiCheck,
|
|
17
|
+
type CiCheckConcludeInput,
|
|
18
|
+
type CiCheckConclusion,
|
|
19
|
+
type CiCheckCreateInput,
|
|
20
|
+
type CiCheckOutput,
|
|
21
|
+
type CiCheckRef,
|
|
22
|
+
type CiCheckStatus,
|
|
23
|
+
type CiChecksClient,
|
|
24
|
+
type CiCheckUpdateInput,
|
|
25
|
+
type CiCheckWriter,
|
|
26
|
+
openCiCheck,
|
|
27
|
+
resumeCiCheck,
|
|
28
|
+
} from "../checks.js";
|
|
29
|
+
import { type GitLabApiMethod, gitlabProjectPathSegment } from "./api.js";
|
|
30
|
+
|
|
31
|
+
/** Any client that can call the GitLab REST API. */
|
|
32
|
+
export interface GitLabCheckClient {
|
|
33
|
+
request<T = unknown>(input: {
|
|
34
|
+
method: GitLabApiMethod;
|
|
35
|
+
path: string;
|
|
36
|
+
body?: unknown;
|
|
37
|
+
}): Promise<T>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** GitLab commit status `state` values. */
|
|
41
|
+
export type GitLabCommitStatusState =
|
|
42
|
+
| "pending"
|
|
43
|
+
| "running"
|
|
44
|
+
| "success"
|
|
45
|
+
| "failed"
|
|
46
|
+
| "canceled";
|
|
47
|
+
|
|
48
|
+
export interface GitLabCommitStatusInput {
|
|
49
|
+
/** Numeric project id or `group/project` path. */
|
|
50
|
+
project: number | string;
|
|
51
|
+
sha: string;
|
|
52
|
+
state: GitLabCommitStatusState;
|
|
53
|
+
/** Status name shown in the MR widget, e.g. `cursor/security-review`. */
|
|
54
|
+
name: string;
|
|
55
|
+
/** "Details" link. */
|
|
56
|
+
targetUrl?: string;
|
|
57
|
+
/** Short description (GitLab truncates long values). */
|
|
58
|
+
description?: string;
|
|
59
|
+
/** Attach the status to a specific pipeline instead of the latest one. */
|
|
60
|
+
pipelineId?: number;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Response subset of `POST /projects/:id/statuses/:sha`. */
|
|
64
|
+
export interface GitLabCommitStatus {
|
|
65
|
+
id?: number;
|
|
66
|
+
status?: string;
|
|
67
|
+
target_url?: string | null;
|
|
68
|
+
[key: string]: unknown;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const DESCRIPTION_MAX_CHARS = 255;
|
|
72
|
+
|
|
73
|
+
/** Post one commit status. Throws `GitLabApiError` on API failure. */
|
|
74
|
+
export async function setGitLabCommitStatus(
|
|
75
|
+
gitlab: GitLabCheckClient,
|
|
76
|
+
input: GitLabCommitStatusInput
|
|
77
|
+
): Promise<GitLabCommitStatus> {
|
|
78
|
+
return await gitlab.request<GitLabCommitStatus>({
|
|
79
|
+
method: "POST",
|
|
80
|
+
path: `/projects/${gitlabProjectPathSegment(input.project)}/statuses/${encodeURIComponent(input.sha)}`,
|
|
81
|
+
body: {
|
|
82
|
+
state: input.state,
|
|
83
|
+
name: input.name,
|
|
84
|
+
...(input.targetUrl === undefined ? {} : { target_url: input.targetUrl }),
|
|
85
|
+
...(input.description === undefined
|
|
86
|
+
? {}
|
|
87
|
+
: { description: input.description.slice(0, DESCRIPTION_MAX_CHARS) }),
|
|
88
|
+
...(input.pipelineId === undefined
|
|
89
|
+
? {}
|
|
90
|
+
: { pipeline_id: input.pipelineId }),
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Shared check status / conclusion → GitLab commit status state. */
|
|
96
|
+
export function gitlabCommitStatusState(input: {
|
|
97
|
+
status: CiCheckStatus;
|
|
98
|
+
conclusion?: CiCheckConclusion;
|
|
99
|
+
}): GitLabCommitStatusState {
|
|
100
|
+
if (input.status === "queued") {
|
|
101
|
+
return "pending";
|
|
102
|
+
}
|
|
103
|
+
if (input.status === "in_progress") {
|
|
104
|
+
return "running";
|
|
105
|
+
}
|
|
106
|
+
switch (input.conclusion) {
|
|
107
|
+
case "success":
|
|
108
|
+
case "neutral":
|
|
109
|
+
case "skipped":
|
|
110
|
+
return "success";
|
|
111
|
+
case "cancelled":
|
|
112
|
+
return "canceled";
|
|
113
|
+
case "failure":
|
|
114
|
+
case "action_required":
|
|
115
|
+
case "timed_out":
|
|
116
|
+
case undefined:
|
|
117
|
+
return "failed";
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export type GitLabCheckOutput = CiCheckOutput;
|
|
122
|
+
export type GitLabCheckUpdateInput = CiCheckUpdateInput;
|
|
123
|
+
export type GitLabCheckConcludeInput = CiCheckConcludeInput;
|
|
124
|
+
|
|
125
|
+
/** A created commit status. All methods throw `GitLabApiError` on failure. */
|
|
126
|
+
export type GitLabCheck = CiCheck & CiCheckRef;
|
|
127
|
+
|
|
128
|
+
export interface GitLabCheckIdentityInput {
|
|
129
|
+
/** Client used for every API call on the returned handle. */
|
|
130
|
+
gitlab: GitLabCheckClient;
|
|
131
|
+
/** Numeric project id or `group/project` path. */
|
|
132
|
+
project: number | string;
|
|
133
|
+
/** Status name shown in the MR widget, e.g. `"cursor/security-review"`. */
|
|
134
|
+
name: string;
|
|
135
|
+
/** Commit the status attaches to (usually the MR head SHA). */
|
|
136
|
+
sha: string;
|
|
137
|
+
/** Pin the status to one pipeline. */
|
|
138
|
+
pipelineId?: number;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface GitLabCheckCreateInput
|
|
142
|
+
extends GitLabCheckIdentityInput,
|
|
143
|
+
CiCheckCreateInput {}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* GitLab writer: every write re-posts the status row for `(sha, name)`, and
|
|
147
|
+
* a commit status has no partial update, so the writer carries the last
|
|
148
|
+
* status, details link, and title forward when a write omits them.
|
|
149
|
+
*/
|
|
150
|
+
function gitlabCheckWriter(
|
|
151
|
+
input: GitLabCheckIdentityInput & {
|
|
152
|
+
status?: CiCheckStatus;
|
|
153
|
+
url?: string;
|
|
154
|
+
title?: string;
|
|
155
|
+
}
|
|
156
|
+
): CiCheckWriter {
|
|
157
|
+
let lastStatus: CiCheckStatus = input.status ?? "in_progress";
|
|
158
|
+
let lastUrl: string | undefined = input.url;
|
|
159
|
+
let lastTitle: string | undefined = input.title;
|
|
160
|
+
return async (write) => {
|
|
161
|
+
const status =
|
|
162
|
+
write.status ??
|
|
163
|
+
(write.conclusion === undefined ? lastStatus : "completed");
|
|
164
|
+
lastStatus = status;
|
|
165
|
+
lastUrl = write.detailsUrl ?? lastUrl;
|
|
166
|
+
lastTitle = write.output?.title ?? lastTitle;
|
|
167
|
+
const posted = await setGitLabCommitStatus(input.gitlab, {
|
|
168
|
+
project: input.project,
|
|
169
|
+
sha: input.sha,
|
|
170
|
+
name: input.name,
|
|
171
|
+
state: gitlabCommitStatusState({ status, conclusion: write.conclusion }),
|
|
172
|
+
targetUrl: lastUrl,
|
|
173
|
+
description: lastTitle,
|
|
174
|
+
pipelineId: input.pipelineId,
|
|
175
|
+
});
|
|
176
|
+
return {
|
|
177
|
+
...(typeof posted?.id === "number" ? { id: posted.id } : {}),
|
|
178
|
+
...(typeof posted?.target_url === "string"
|
|
179
|
+
? { url: posted.target_url }
|
|
180
|
+
: {}),
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Open a commit status on `sha` and return a handle for later updates.
|
|
187
|
+
*
|
|
188
|
+
* ```ts
|
|
189
|
+
* const check = await createGitLabCheck({
|
|
190
|
+
* gitlab: ctx.gitlab,
|
|
191
|
+
* project: ctx.project.id,
|
|
192
|
+
* name: "cursor/security-review",
|
|
193
|
+
* sha: mergeRequest.headSha,
|
|
194
|
+
* detailsUrl: sessionUrl,
|
|
195
|
+
* output: { title: "Running…", summary: "" },
|
|
196
|
+
* });
|
|
197
|
+
* await check.conclude({ conclusion: "success", output: { title: "Clean", summary: "" } });
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
export function createGitLabCheck(
|
|
201
|
+
input: GitLabCheckCreateInput
|
|
202
|
+
): Promise<GitLabCheck> {
|
|
203
|
+
return openCiCheck(gitlabCheckWriter(input), input);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Rebuild a {@link GitLabCheck} handle for an existing status row from its
|
|
208
|
+
* identity. No API call is made until the first update.
|
|
209
|
+
*/
|
|
210
|
+
export function resumeGitLabCheck(
|
|
211
|
+
input: GitLabCheckIdentityInput & {
|
|
212
|
+
/** Last known status; defaults to `"in_progress"`. */
|
|
213
|
+
status?: CiCheckStatus;
|
|
214
|
+
/** Last known details link, kept on writes that omit `detailsUrl`. */
|
|
215
|
+
url?: string;
|
|
216
|
+
/** Last known title, kept on writes that omit `output`. */
|
|
217
|
+
title?: string;
|
|
218
|
+
id?: number;
|
|
219
|
+
}
|
|
220
|
+
): GitLabCheck {
|
|
221
|
+
return resumeCiCheck(
|
|
222
|
+
gitlabCheckWriter(input),
|
|
223
|
+
input.id === undefined ? undefined : { id: input.id }
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Project-bound checks adapter satisfying the shared {@link CiChecksClient}
|
|
229
|
+
* contract for forge-agnostic check code.
|
|
230
|
+
*/
|
|
231
|
+
export function bindGitLabChecks(input: {
|
|
232
|
+
gitlab: GitLabCheckClient;
|
|
233
|
+
project: number | string;
|
|
234
|
+
}): CiChecksClient {
|
|
235
|
+
return {
|
|
236
|
+
createCheck: (check) =>
|
|
237
|
+
createGitLabCheck({
|
|
238
|
+
...check,
|
|
239
|
+
gitlab: input.gitlab,
|
|
240
|
+
project: input.project,
|
|
241
|
+
}),
|
|
242
|
+
};
|
|
243
|
+
}
|