Skip to content

feat(cursor): add list artifacts and download artifact tools#3970

Merged
waleedlatif1 merged 3 commits intostagingfrom
waleedlatif1/cursor-artifact-tools
Apr 5, 2026
Merged

feat(cursor): add list artifacts and download artifact tools#3970
waleedlatif1 merged 3 commits intostagingfrom
waleedlatif1/cursor-artifact-tools

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

Summary

  • Add cursor_list_artifacts tool to list generated artifact files for a cloud agent
  • Add cursor_download_artifact tool with internal API route that fetches presigned URLs from Cursor and downloads files with security validation
  • Both tools have v1 (content/metadata) and v2 (API-aligned, file output) variants
  • Download artifact v2 uses type: 'file' output for execution file system integration
  • Add .trim() on agentId in URL paths across existing tools
  • Add prUrl filter param to list agents
  • Add CREATING to agent status enum
  • Add mode: 'advanced' on optional block fields
  • Update docs and integrations.json

Type of Change

  • New feature

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Apr 5, 2026 2:34am

Request Review

@cursor
Copy link
Copy Markdown

cursor bot commented Apr 5, 2026

PR Summary

Medium Risk
Adds new Cursor artifact download flow that fetches a presigned URL and downloads remote content via a new internal API route; mistakes could affect SSRF/file handling despite added URL validation and pinned-IP fetching. Other changes are mostly additive (new tool params/outputs and input trimming).

Overview
Adds support for Cursor agent artifacts: a new cursor_list_artifacts tool to enumerate artifact files and a new cursor_download_artifact tool (plus v2 variants) that returns downloaded files for execution storage.

Implements a new internal API route POST /api/tools/cursor/download-artifact that requests a presigned URL from Cursor, validates the resolved destination, and downloads the file content before returning it as base64.

Extends cursor_list_agents with an optional prUrl filter and normalizes agent IDs by trimming whitespace across existing Cursor tool URLs; also updates block configuration (advanced-only optional fields), integration metadata, and docs.

Reviewed by Cursor Bugbot for commit d98bda6. Configure here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 5, 2026

Greptile Summary

This PR adds cursor_list_artifacts and cursor_download_artifact tools (v1 and v2 variants) to the Cursor integration, plus a prUrl filter for list_agents, CREATING status to the agent enum, and mode: 'advanced' on optional block fields.

The new download artifact flow correctly routes through an internal /api/tools/cursor/download-artifact proxy with checkInternalAuth, Zod validation, DNS-pinning (validateUrlWithDNS + secureFetchWithPinnedIP), and the correct status-passthrough on presigned URL failures. The list artifacts tool makes a direct external GET call—consistent with how all other Cursor read operations work. The v1/v2 split pattern is applied consistently. All three issues raised in previous review rounds have been addressed.

Key changes:

  • New cursor_list_artifacts / cursor_list_artifacts_v2 tools: v1 wraps result in content+metadata, v2 returns API-aligned artifacts array
  • New cursor_download_artifact / cursor_download_artifact_v2 tools: v1 returns content+metadata (no binary blob), v2 returns file object for execution storage
  • New internal API route with SSRF-safe presigned URL fetching
  • .trim() added to agentId across all existing Cursor tool URLs
  • CREATING added to AgentMetadata status union in types.ts
  • CursorV2Block outputs extended with artifacts and file fields

Confidence Score: 5/5

Safe to merge — all three previous P0/P1 issues (type mismatch, redundant guard, hardcoded status code) have been resolved; remaining findings are P2 style suggestions.

The security-critical download artifact path is correctly implemented with DNS pinning, IP locking, and internal auth. The v1/v2 split is consistent with the codebase pattern. The only remaining findings are a missing null guard in the v2 list_agents transformResponse (inconsistent with the same-PR list_artifacts pattern) and an any usage in satisfies constraints — both P2 and non-blocking.

apps/sim/tools/cursor/list_agents.ts — v2 transformResponse accesses data.agents without a fallback; minor inconsistency with the defensive pattern used in list_artifacts.ts

Important Files Changed

Filename Overview
apps/sim/app/api/tools/cursor/download-artifact/route.ts New internal proxy route with solid security: internal auth check, Zod validation, DNS pinning via validateUrlWithDNS + secureFetchWithPinnedIP, and proper status passthrough on all error paths
apps/sim/tools/cursor/download_artifact.ts New v1/v2 download artifact tools sharing a base config; v1 returns content+metadata string form, v2 returns binary file object; trim() applied to agentId and path
apps/sim/tools/cursor/list_artifacts.ts New v1/v2 list artifacts tools; v1 wraps in content+metadata envelope, v2 returns API-aligned artifacts array; defensive ?? [] guard applied correctly in v1
apps/sim/tools/cursor/list_agents.ts Added prUrl filter param and new v2 variant; v2 transformResponse accesses data.agents without a null guard, inconsistent with the ?? [] pattern used in list_artifacts.ts
apps/sim/tools/cursor/types.ts New ListArtifactsParams, ArtifactMetadata, DownloadArtifactParams, DownloadArtifactResponse, DownloadArtifactV2Response types; CREATING added to AgentMetadata status union; CursorResponse union extended
apps/sim/blocks/blocks/cursor.ts Legacy CursorBlock updated with list_artifacts and download_artifact operations; CursorV2Block correctly extends outputs with artifacts (json) and file (file) fields and wires v2 tool variants via createVersionedToolSelector
apps/sim/tools/cursor/index.ts Barrel exports updated with cursorDownloadArtifactTool, cursorListArtifactsTool and their v2 counterparts
apps/sim/tools/registry.ts cursor_list_artifacts, cursor_list_artifacts_v2, cursor_download_artifact, cursor_download_artifact_v2 registered correctly
apps/sim/tools/cursor/get_agent.ts Added .trim() to agentId in URL builder; no functional changes beyond that
apps/sim/tools/cursor/add_followup.ts Added .trim() to agentId in URL builder; body construction unchanged

Sequence Diagram

sequenceDiagram
    participant W as Workflow Executor
    participant R as Tool Registry
    participant LA as listArtifactsV2Tool
    participant DA as downloadArtifactV2Tool
    participant IR as /api/tools/cursor/download-artifact
    participant CA as api.cursor.com
    participant PS as Presigned URL (Storage)

    W->>R: resolve cursor_list_artifacts_v2
    R->>LA: transformResponse()
    LA->>CA: GET /v0/agents/{agentId}/artifacts<br/>(Authorization: Basic ...)
    CA-->>LA: { artifacts: [...] }
    LA-->>W: { output: { artifacts } }

    W->>R: resolve cursor_download_artifact_v2
    R->>DA: request to /api/tools/cursor/download-artifact
    DA->>IR: POST { apiKey, agentId, path }
    IR->>IR: checkInternalAuth + Zod.parse
    IR->>CA: GET /v0/agents/{agentId}/artifacts/download?path=...
    CA-->>IR: { url: "https://presigned..." }
    IR->>IR: validateUrlWithDNS(presignedUrl)
    IR->>PS: secureFetchWithPinnedIP(url, resolvedIP)
    PS-->>IR: binary file content
    IR-->>DA: { success, output: { file: { name, mimeType, data, size } } }
    DA-->>W: { output: { file } }
Loading

Reviews (2): Last reviewed commit: "fix(cursor): address PR review feedback" | Re-trigger Greptile

…ct types

- Remove invalid wandConfig with unsupported generationType 'json-array' from promptImages subBlock
- Remove invalid 'optional' property from summary output definition
- Split DownloadArtifactResponse into v1 (content/metadata) and v2 (file) response types
- Remove redundant Array.isArray guards in list_artifacts.ts
- Pass through actual HTTP status on presigned URL download failure instead of hardcoded 400
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit d98bda6. Configure here.

@waleedlatif1 waleedlatif1 merged commit adfcb67 into staging Apr 5, 2026
12 checks passed
@waleedlatif1 waleedlatif1 deleted the waleedlatif1/cursor-artifact-tools branch April 5, 2026 02:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant