fix(dropbox): align integration with Dropbox API docs, add revision/sharing tools#5468
Conversation
…haring tools - fix search root-path bug: Dropbox requires "" not "/" for root, same fix already applied to list_folder - fix create_shared_link to return the existing link's metadata (url) when Dropbox reports shared_link_already_exists with matching settings, instead of just erroring - fix upload route autorename default (was true, Dropbox's documented default is false) - trim() all path/fromPath/toPath/rev params to guard against copy-pasted whitespace - mark nullable output fields (id, size, path_display, etc.) optional: true so folder/deleted items don't imply always-present file fields - widen path_display/path_lower types to optional, matching the real API - add dropbox_list_shared_links, dropbox_list_revisions, dropbox_restore tools + block wiring, filling gaps flagged during the audit (revision history/version recovery, and a companion to create_shared_link for looking up existing links)
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Bug fixes: Search now maps a root scope of New capabilities: Adds Hardening: Trims whitespace on path-related params across tools; widens types and marks several metadata output fields Reviewed by Cursor Bugbot for commit 3cb41c9. Configure here. |
Greptile SummaryThis PR fixes three confirmed Dropbox API compatibility bugs and adds three new tools (List Shared Links, List Revisions, Restore File) with full block and registry wiring. All changes are additive or corrective with no breaking changes to existing tool IDs, param names, or output keys.
Confidence Score: 5/5Safe to merge — all changes are either targeted bug fixes verified against the Dropbox API spec or purely additive new tools. The bug fixes address real, reproducible failures (search returning 400 on root path, autorename silently conflicting with the documented API default). The three new tools follow the established Dropbox tool pattern exactly — correct type definitions, proper error handling, consistent use of ?? defaults, and trimmed path inputs. Existing tool IDs, param names, and output keys are untouched, so there is no backward-compatibility risk. No files require special attention. The create_shared_link existingLink check relies on Dropbox returning null for the settings-mismatch case, which the author verified against the live API. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant U as User/Block
participant LSL as list_shared_links
participant LR as list_revisions
participant R as restore
participant DB as Dropbox API
Note over U,DB: List Shared Links
U->>LSL: path? / cursor? / directOnly?
LSL->>DB: POST /sharing/list_shared_links (path omitted if / or empty)
DB-->>LSL: "{links, has_more, cursor?}"
LSL-->>U: "{links[], hasMore, cursor?}"
Note over U,DB: List Revisions
U->>LR: path (required), limit?, beforeRev?
LR->>DB: "POST /files/list_revisions {path, mode:path, limit, before_rev?}"
DB-->>LR: "{entries[], is_deleted, has_more}"
LR-->>U: "{entries[], isDeleted, hasMore}"
Note over U,DB: Restore File
U->>R: path (required), rev (required)
R->>DB: "POST /files/restore {path, rev}"
DB-->>R: FileMetadata
R-->>U: "{metadata}"
Note over U,DB: Create Shared Link (updated error path)
U->>DB: POST /sharing/create_shared_link_with_settings
DB-->>U: 409 shared_link_already_exists
alt existingLink present - settings match
U-->>U: "success=true, sharedLink=existingLink"
else existingLink null - settings differ
U-->>U: "success=false, error message"
end
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant U as User/Block
participant LSL as list_shared_links
participant LR as list_revisions
participant R as restore
participant DB as Dropbox API
Note over U,DB: List Shared Links
U->>LSL: path? / cursor? / directOnly?
LSL->>DB: POST /sharing/list_shared_links (path omitted if / or empty)
DB-->>LSL: "{links, has_more, cursor?}"
LSL-->>U: "{links[], hasMore, cursor?}"
Note over U,DB: List Revisions
U->>LR: path (required), limit?, beforeRev?
LR->>DB: "POST /files/list_revisions {path, mode:path, limit, before_rev?}"
DB-->>LR: "{entries[], is_deleted, has_more}"
LR-->>U: "{entries[], isDeleted, hasMore}"
Note over U,DB: Restore File
U->>R: path (required), rev (required)
R->>DB: "POST /files/restore {path, rev}"
DB-->>R: FileMetadata
R-->>U: "{metadata}"
Note over U,DB: Create Shared Link (updated error path)
U->>DB: POST /sharing/create_shared_link_with_settings
DB-->>U: 409 shared_link_already_exists
alt existingLink present - settings match
U-->>U: "success=true, sharedLink=existingLink"
else existingLink null - settings differ
U-->>U: "success=false, error message"
end
Reviews (6): Last reviewed commit: "fix(dropbox): wire cursor pagination for..." | Re-trigger Greptile |
…red_links Consistency nit from Greptile review - matches the ?? pattern already used by every other transformResponse in this PR.
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ 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 1e76782. Configure here.
…nsistency Greptile flagged that path_display was left required in list_folder.ts and list_revisions.ts despite being widened to optional in types.ts and most other output schemas in this PR. Fixed those two plus create_folder.ts, restore.ts, upload.ts, and list_shared_links.ts, which had the same gap.
|
@greptile review |
|
@cursor review |
…tion Cursor Bugbot flagged two real gaps: - list_shared_links sent path: "" for root/all, but Dropbox only returns every link account-wide when path is omitted entirely; "" scopes to the root folder specifically. Now omits the field for root/empty/"/" input. - list_revisions exposed hasMore but no way to actually fetch more pages (Dropbox's before_rev cursor). Added a beforeRev param + advanced-mode block field. A third flagged issue (create_shared_link's error.shared_link_already_exists.metadata path) was verified against the official sharing.stone spec and confirmed correct as-is - replied on the PR thread with the citation, no change needed.
|
@greptile review |
|
@cursor review |
The prior fix read data.error.shared_link_already_exists.metadata, which is wrong per Stone's own JSON serialization rules: a union member whose payload is a struct (SharedLinkMetadata) flattens that struct's fields alongside ".tag" rather than nesting under a wrapper key. The real shape is data.error.shared_link_already_exists directly (with an extra ".tag" field mixed in) - there is no nested .metadata key, so the existing-link fast path never fired before this fix. Also marks list_shared_links' expires output optional, matching every other optional field in this PR and the SharedLinkMetadata spec.
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
1 issue from previous review remains unresolved.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit e00b2d8. Configure here.
The dropbox_list_shared_links tool already accepted a cursor param, but the block never exposed it, so a workflow couldn't page past the first batch when hasMore was true. Adds an advanced-mode cursor subBlock + input entry, mirroring List Revisions' beforeRev field added in the same PR.
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ 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 3cb41c9. Configure here.

Summary
"", not"/"— our UI placeholder told users to type/for "search all" but the code never normalized it, so that literally errored against the live API (list_folder already had this fix, search didn't).shared_link_already_existswith matching settings, instead of just erroring and telling the user to call a tool that didn't exist.autorenametotruewhen omitted — Dropbox's documented default isfalse, so this was a silent behavior deviation from the real API..trim()on all path/fromPath/toPath/rev params to guard against copy-pasted whitespace.id,size,path_display, etc.)optional: trueso folder/deleted-item responses don't imply file-only fields are always present.path_display/path_lowertypes to optional, matching the real Dropbox API response shape.dropbox_list_shared_links,dropbox_list_revisions, anddropbox_restoretools + full block wiring — gaps flagged during the audit (revision history/version recovery, and a companion to Create Shared Link for looking up existing links, which our own error message already referenced but didn't provide).Type of Change
Testing
tsc --noEmitclean,biome checkcleanChecklist