feat(channel): add delete, archive, unarchive subcommands#8
Merged
Conversation
Ports the remaining channel-lifecycle commands from twist-cli #246 (create already existed). Wraps the SDK's deleteChannel, archiveChannel and unarchiveChannel endpoints so channel lifecycle no longer requires the web UI. - delete requires --yes to mutate, short-circuits MISSING_YES_FLAG in --json mode before any lookup, and translates a 403 into a clear FORBIDDEN CliError (deletion is typically admin-only). - archive/unarchive share a setArchiveState helper and skip the API call when the channel is already in the target state. - All three support --workspace, --dry-run and --json. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
doistbot
reviewed
May 27, 2026
Member
doistbot
left a comment
There was a problem hiding this comment.
Thanks scottlovegrove for your contribution 🤗. The implementation for these new lifecycle commands is excellent, particularly the shared archive state mutation and clean error mapping.
Few things worth tightening:
- Bypass workspace resolution for direct channel refs (
id:or URLs) usinggetDirectChannelId(), matching howchannel updatehandles cross-workspace channels. - Add test coverage for the
--workspaceflag across these new subcommands to verify the correct workspace ID is passed to the resolver.
I also included a few optional follow-up notes in the details below.
Optional follow-up note (1)
- [P3] src/commands/channel/delete.ts:19: This does the full workspace/channel resolution before the plain
!options.yesearly return below. On a name ref,resolveChannelRef()loads the channel list for the workspace, sotdc channel delete <name>without--yesstill pays for multiple API calls just to printUse --yes to confirm.Consider moving the non---yes/non---dry-runreturn above the lookup and using the raw ref in that message so the no-op path stays local.
Addresses doistbot feedback on PR #8. - Add a shared resolveChannelByRef helper: direct refs (id:/URL) are fetched by ID via getChannel (workspace-agnostic), so deleting or (un)archiving a channel in another workspace no longer fails with CHANNEL_NOT_FOUND. Name refs still resolve a workspace. Mirrors how `channel update` already special-cases direct refs. - delete: move the non-yes/non-dry-run early return above the channel lookup and reference the raw ref, so the confirmation prompt no longer pays for API calls. - Tests: table-driven --workspace coverage (asserts the passed workspace ID reaches resolveChannelRef) and direct-ref bypass coverage (asserts getChannel is used and no workspace is resolved) across all three subcommands. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
doist-release-bot Bot
added a commit
that referenced
this pull request
May 27, 2026
## [1.2.0](v1.1.0...v1.2.0) (2026-05-27) ### Features * **channel:** add delete, archive, unarchive subcommands ([#8](#8)) ([41acfe6](41acfe6)), closes [#246](https://github.com/Doist/comms-cli/issues/246)
Contributor
|
🎉 This PR is included in version 1.2.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ports the remaining channel-lifecycle commands from Doist/twist-cli#246.
createalready existed in comms-cli, so this adds the missing three:All three support
--workspace,--dry-runand--json.--yesto mutate; short-circuits a structuredMISSING_YES_FLAGCliError in--jsonmode before any lookup, and translates a Comms 403 into a clearFORBIDDENCliError (channel deletion is typically restricted to workspace admins).setArchiveStatehelper and skip the API call when the channel is already in the target state. Name-ref resolution only finds active channels, sounarchivedocuments passingid:/numeric refs.Adaptations from the twist-cli source
comms-cli diverges, so this is not a 1:1 copy:
idis a base58 string; the SDK'sdeleteChannel/archiveChannel/unarchiveChanneltakeid: string.getCommsClient().channels.X(...)(matching siblingcreate.ts/update.ts), not api.ts wrappers. Only spinner-message entries were added toapi.ts.CommsRequestError(from@doist/comms-sdk) for the 403 check, instead of twist'sTwistRequestError.tdcnaming throughout.No scope changes needed —
channels:write/channels:removealready landed with the membership PR (#7). The read-only write-gate applies automatically via the safe-by-defaultisMutatingMethod.Files
src/commands/channel/delete.ts(new)src/commands/channel/archive.ts(new)src/lib/api.tssrc/lib/errors.ts(FORBIDDEN)src/commands/channel/index.tssrc/lib/skills/content.ts+ regeneratedskills/comms-cli/SKILL.mdsrc/commands/channel/channel.test.ts(+13)Test plan
npm run type-checknpm run lintnpm test— 668/668 passing (13 new across delete/archive/unarchive)npm run sync:skill(SKILL.md regenerated)--helpsmoke for all three commands🤖 Generated with Claude Code