fix(refs): resolve unjoined-but-public channels by name#11
Merged
Conversation
resolveChannelRef name-branch only called getChannels (membership-scoped), so `tdc channel <action> "Public Channel I Haven't Joined"` failed with CHANNEL_NOT_FOUND. Merge with workspaces.getPublicChannels and dedupe by id — same shape as src/commands/channel/list.ts. Ports Doist/twist-cli#249. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
doistbot
reviewed
May 28, 2026
Member
doistbot
left a comment
There was a problem hiding this comment.
Thanks scottlovegrove for your contribution 😊. Porting this fix from the twist-cli is a great catch, and the comprehensive test additions cover the new resolution paths well.
Few things worth tightening:
- Defer the
workspaces.getPublicChannels()fetch until after checking for an exact match in the joined channels list to save an unnecessary workspace-wide API call. - Use distinct object instances with the same ID in the deduplication test (rather than the same reference) to properly simulate the real API and ensure dedupe-by-id works as expected.
I also included a few optional follow-up notes in the details below.
Optional follow-up note (1)
- [P3] src/lib/refs.ts:279: This re-implements the same joined/public merge+d edupe rules that
src/commands/channel/list.tsalready has. Now that channel discoverability semantics live in two places, the next visibility/API change can fix one path and miss the other again. Please extract a small shared helper for this merged channel set and reuse it here and inchannel/list.
- Skip workspaces.getPublicChannels when an exact match already exists in the joined list. Common case (user types channel they're in) avoids the workspace-wide call. - Dedupe test now uses distinct object instances with the same id, so it proves dedupe-by-id rather than reference equality. 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 28, 2026
## [1.3.2](v1.3.1...v1.3.2) (2026-05-28) ### Bug Fixes * **refs:** resolve unjoined-but-public channels by name ([#11](#11)) ([0e2aefb](0e2aefb))
Contributor
|
🎉 This PR is included in version 1.3.2 🎉 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
resolveChannelRef's name branch only calledclient.channels.getChannels({ workspaceId }), which is membership-scoped and excludes public channels the current user hasn't joined.tdc channel <action> "Public Channel I Haven't Joined"fails withCHANNEL_NOT_FOUND, whileid:Nand URL refs work becausegetChannel(id)isn't membership-filtered.getChannelswithworkspaces.getPublicChannelsand dedupes by id. Same shapesrc/commands/channel/list.ts:170-174already uses for the--scope publicpath.Ports Doist/twist-cli#249.
Test plan
npm run lint— cleannpm run type-check— cleannpx vitest run src/lib/refs.test.ts— 84/84 pass (4 new tests: unjoined-public exact match, unjoined-public substring match, dedup of joined-and-public, ambiguity across joined+public)Out of scope
id:and URL branches — already work for unjoined channels viagetChannel(id).🤖 Generated with Claude Code