feat(cards): move and copy cards to other projects
Why
On the web, a card's Move… and Copy… menus send it to a card table in any project. The CLI could only cross projects through a wormhole someone had already set up. It couldn't copy a card, and after a wormhole move it never said where the card landed. CLI users miss all three.
What changed
cards move <card> --to-project <project>(or--to-card-table) moves the card to that project's card table.cards copy <card>copies it onto its own table or, with--to-project, another project's, and--include-commentsbrings the comments. Both wait for Basecamp to finish and print the new card. As on the web, the card lands in Triage, or in Done if it's completed.--to-wormholenow prints the card that landed, and--towith another project's column points to--to-project.cards show,cards stepsandtodos showfollow a moved card or to-do from its old id to its new one.
Scope
- Uses basecamp-sdk v0.30.0, the release of basecamp/basecamp-sdk#1053. v0.30.0 also adds the SDK's project-logo operations. The built-in MCP server serves
remove_project_logoand skips the upload, as it skips the other uploads. CLI logo commands come in a separate PR stacked on this one. - The bump also adds
move_recording,copy_recordingandget_filingto the built-in MCP server's catalog.
Tradeoffs
A copy is never retried. A copy that fails to start with a 5xx, or that's still running when the wait ends, says "don't copy again" and is not marked retryable, because Basecamp may already be making it.
Verification
bin/cipasses.- A local bc3 harness ran each web card path through the CLI: columns, On hold, Done, another table, wormhole, move to a project, and copy to a project and to its own table. Every path works, and a column from another project still fails. By hand,
--include-commentscarried a comment and a completed card landed in Done. - An independent GPT-6.1-sol review converged after 4 rounds. Each finding it raised has a test that fails without the fix.
Summary by cubic
Adds cross-project card moves and copies to the CLI, matching the web's Move… and Copy… menus.
cards move <card> --to-project <project>(or--to-card-table) files the card into that project's card table; it lands in Triage, or Done if completed, under a new id, with a bounded backoff wait on Basecamp's background move.- New
cards copy <card>copies onto its own table or, with--to-project, another project's;--include-commentscarries the comments. A copy that fails is never retried unless Basecamp answered 4xx, because a 5xx, dropped connection, or wait time-out may already have started it; rate limits stay retryable. --to-wormholenow prints where the card landed, andcards show,cards steps, andtodos showfollow a moved record from its old id to its new one;--toa foreign column suggests--to-project.- Source cards, card URLs, and destination card tables must belong to the session account on a trusted host, an explicit
--in/--projectmust match the card's own project, and a destination table URL whose project disagrees with--to-projectis refused. A record that reads back as any type other than a card is refused.
Scope
Bumps basecamp-sdk to v0.30.0, the release of the move, copy, and filing operations. It also brings project logos: the built-in MCP server serves remove_project_logo and skips the multipart upload.