Skip to content

feat(task): add attachment download shortcut - #2274

Open
zhouyijian wants to merge 3 commits into
larksuite:mainfrom
zhouyijian:codex/task-attachment-download
Open

feat(task): add attachment download shortcut#2274
zhouyijian wants to merge 3 commits into
larksuite:mainfrom
zhouyijian:codex/task-attachment-download

Conversation

@zhouyijian

@zhouyijian zhouyijian commented Aug 10, 2026

Copy link
Copy Markdown

Summary

Add a first-class Task attachment download workflow that resolves an attachment GUID to a short-lived URL and streams the file through the CLI FileIO provider without exposing signed URL material.

Changes

  • add task +download-attachment with safe output-path handling, overwrite protection, URL refresh, and structured output
  • add an opaque URL download transport mode that preserves typed errors without leaking signed URL query parameters or response bodies
  • add command affordance, Task skill guidance, unit coverage, dry-run E2E coverage, and a self-cleaning live workflow test

Test Plan

  • make unit-test
  • make vet
  • make fmt-check
  • go mod tidy leaves go.mod and go.sum unchanged
  • QUALITY_GATE_CHANGED_FROM=upstream/main make quality-gate
  • golangci-lint v2.1.6 reports 0 issues for changes from upstream/main
  • source lint, lint contract tests, and go-licenses checks pass
  • focused Task download dry-run E2E passes
  • manual --help and dry-run verification confirms the two-step Task API and external download flow
  • live upload-to-download E2E requires tenant test credentials and was skipped locally

Related Issues

  • None

Summary by CodeRabbit

  • New Features

    • Added task +download-attachment for downloading task attachments by ID.
    • Supports output paths, safe filenames, overwrite controls, dry runs, and temporary-URL refresh.
    • Validates secure download URLs and reports download and save errors clearly.
  • Security

    • Sensitive temporary URLs and authentication details are excluded from errors and command output.
  • Documentation

    • Added usage guidance, permissions, options, examples, and recovery instructions.
  • Tests

    • Added comprehensive unit and end-to-end coverage for successful, failed, and dry-run downloads.

@CLAassistant

CLAassistant commented Aug 10, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions github-actions Bot added domain/task PR touches the task domain size/L Large or sensitive change across domains or core paths labels Aug 10, 2026
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds the task +download-attachment shortcut. It validates attachment and output paths, downloads temporary URLs with refresh handling, prevents sensitive error details, documents the command, registers the shortcut, and adds unit and end-to-end tests.

Changes

Task attachment download

Layer / File(s) Summary
Opaque download transport
internal/download/transport.go, internal/download/transport_test.go
OpaqueURL hides signed URL and response details while preserving error classification and causes.
Download shortcut implementation
shortcuts/task/...
The shortcut retrieves metadata, validates HTTPS temporary URLs and output paths, refreshes unauthorized URLs, saves files, supports dry-run and overwrite options, and reports results.
Documentation and affordance wiring
skills/lark-task/..., affordance/task.md, internal/affordance/task_source_test.go
The skill, reference, and affordance documentation describe the command, permission, flags, URL handling, and output behavior.
End-to-end validation
tests/cli_e2e/task/...
Tests cover dry-run request planning and live upload/download validation, including byte, GUID, output, and credential-redaction checks.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant TaskAPI
  participant TemporaryURL
  CLI->>TaskAPI: Request attachment metadata
  TaskAPI-->>CLI: Return metadata and temporary URL
  CLI->>TemporaryURL: Download attachment stream
  TemporaryURL-->>CLI: Return file bytes or authorization error
  CLI->>TaskAPI: Refresh metadata after authorization error
  TaskAPI-->>CLI: Return refreshed temporary URL
  CLI->>TemporaryURL: Retry download with refreshed URL
Loading

Possibly related PRs

  • larksuite/cli#2223: Both changes modify direct-URL download transport and sensitive error-detail handling.

Suggested reviewers: liangshuo-1

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the new Task attachment download shortcut.
Description check ✅ Passed The description includes all required sections and clearly documents the changes, verification steps, and skipped credential-dependent test.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@zhouyijian
zhouyijian force-pushed the codex/task-attachment-download branch from abadce5 to 04b5e61 Compare August 10, 2026 14:29
@zhouyijian
zhouyijian marked this pull request as ready for review August 10, 2026 14:33

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
internal/affordance/task_source_test.go (1)

17-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use internal/vfs for filesystem access in this internal test.

The test uses os.DirFS and os.ReadFile. Route repository filesystem access through internal/vfs, or adapt the source injection helper to accept the repository VFS.

As per coding guidelines, “Use internal/vfs filesystem APIs instead of os filesystem APIs.”

Also applies to: 39-42

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/affordance/task_source_test.go` at line 17, Update the test’s
filesystem setup and reads around SetSource to use the repository’s internal/vfs
APIs instead of os.DirFS and os.ReadFile. Reuse the existing repository VFS or
adapt the source injection helper to accept it, while preserving the test’s
current paths and behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/download/transport_test.go`:
- Around line 137-175: Extend the OpaqueURL error tests with cases for malformed
signed URLs and CheckRedirect failures, alongside
TestOpaqueURLDoesNotLeakSignedURLOrResponseBody and
TestOpaqueURLDoesNotLeakSignedURLOnTransportFailure. For each case, assert the
error omits both the signed URL material and query key, and verify
errs.ProblemOf reports the expected retryable network/transport metadata.
- Around line 153-155: Update both transport failure tests to assert
problem.Category is CategoryNetwork and problem.Subtype is
SubtypeNetworkTransport alongside the existing HTTP 403 check. In
TestOpaqueURLDoesNotLeakSignedURLOnTransportFailure, retain the original source
error and verify errors.Is(err, cause) after extracting metadata with
errs.ProblemOf.

In `@shortcuts/task/task_download_attachment.go`:
- Around line 185-191: Update the output-path inspection logic around
runtime.FileIO().Stat in the download flow: keep path-validation failures as the
existing invalid-argument validation error, but classify non-fs.ErrNotExist
permission and filesystem failures with the prescribed typed file-I/O error
constructor while preserving the original cause. Apply the same classification
to the related error branch around the output handling at the referenced second
location.
- Around line 173-175: Update the attachment response handling around
metadata.GUID to reject responses whose server-provided GUID is empty or
whitespace by returning errs.NewInternalError(errs.SubtypeInvalidResponse, ...);
remove the fallback assignment from the requested guid, and add a test covering
this invalid response shape.

---

Nitpick comments:
In `@internal/affordance/task_source_test.go`:
- Line 17: Update the test’s filesystem setup and reads around SetSource to use
the repository’s internal/vfs APIs instead of os.DirFS and os.ReadFile. Reuse
the existing repository VFS or adapt the source injection helper to accept it,
while preserving the test’s current paths and behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0d874e90-1c5a-4217-9a31-1bbdaa752ccd

📥 Commits

Reviewing files that changed from the base of the PR and between ed65049 and 04b5e61.

📒 Files selected for processing (12)
  • affordance/task.md
  • internal/affordance/task_source_test.go
  • internal/download/transport.go
  • internal/download/transport_test.go
  • shortcuts/task/shortcuts.go
  • shortcuts/task/task_download_attachment.go
  • shortcuts/task/task_download_attachment_test.go
  • skills/lark-task/SKILL.md
  • skills/lark-task/references/lark-task-download-attachment.md
  • tests/cli_e2e/task/coverage.md
  • tests/cli_e2e/task/task_download_attachment_dryrun_test.go
  • tests/cli_e2e/task/task_download_attachment_workflow_test.go

Comment thread internal/download/transport_test.go
Comment thread internal/download/transport_test.go Outdated
Comment thread shortcuts/task/task_download_attachment.go
Comment thread shortcuts/task/task_download_attachment.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@shortcuts/task/task_download_attachment_test.go`:
- Around line 212-231: Update the test around DownloadAttachmentTask to track
requests to the temporary download URL with an OnMatch counter on downloadStub,
then assert that the counter remains zero after runMountedTaskShortcut returns.
Replace the CapturedBodies assertion, which does not reliably indicate whether
this non-reusable stub was called.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a61455e8-af3a-400a-9089-5e7c800180d0

📥 Commits

Reviewing files that changed from the base of the PR and between 04b5e61 and 759384c.

📒 Files selected for processing (3)
  • internal/download/transport_test.go
  • shortcuts/task/task_download_attachment.go
  • shortcuts/task/task_download_attachment_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • shortcuts/task/task_download_attachment.go

Comment thread shortcuts/task/task_download_attachment_test.go
@zhouyijian

Copy link
Copy Markdown
Author

Hi @liangshuo-1, all review threads have been addressed and the relevant local checks pass (make fmt-check, make vet, make unit-test, and the related Task/download/affordance/E2E packages). The fork workflows are awaiting maintainer approval. Could you please approve the runs and review the PR when convenient? Thank you.

@github-actions

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@8072aee8ace9fb659554a7f6138f934d5cba5533

🧩 Skill update

npx skills add zhouyijian/cli#codex/task-attachment-download -y -g

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/task PR touches the task domain size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants