Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions skills/twist-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,16 @@ tw channel threads <ref> --since 2026-01-01 # Filter by last-updated date (ISO)
tw channel threads <ref> --limit 20 # Max threads per page (default: 50)
tw channel threads <ref> --limit 20 --cursor <cursor-from-prev> # Paginate
tw channel threads <ref> --json # { results, nextCursor } with isUnread + url
tw channel create "Name" # Create a new (public) channel in the default/current workspace
tw channel create "Name" --workspace <ref> # Target a different workspace
tw channel create "Name" --private # Create a private channel
tw channel create "Name" --description "..." # Set channel description
tw channel create "Name" --json --full # Output created channel as JSON (all fields)
tw channel delete <channel-ref> --yes # Delete a channel (requires --yes; usually admin-only on Twist)
tw channel delete <ref> --workspace <ref> --yes # Target a different workspace
tw channel delete <ref> --dry-run # Preview deletion
tw channel archive <channel-ref> # Archive a channel (no-op if already archived)
tw channel unarchive id:<id> # Unarchive a channel (pass id:/numeric ref for archived channels)
tw groups # List workspace groups
tw groups --search "frontend" # Filter groups by name (case-insensitive)
tw groups --json # JSON output
Expand Down
57 changes: 57 additions & 0 deletions src/commands/channel/archive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { archiveChannel, getCurrentWorkspaceId, unarchiveChannel } from '../../lib/api.js'
import type { MutationOptions } from '../../lib/options.js'
import { formatJson, printDryRun } from '../../lib/output.js'
import { resolveChannelRef, resolveWorkspaceRef } from '../../lib/refs.js'

type ArchiveChannelOptions = MutationOptions & { workspace?: string }

async function setArchiveState(
ref: string,
options: ArchiveChannelOptions,
archive: boolean,
): Promise<void> {
const action = archive ? 'archive' : 'unarchive'
const workspaceId = options.workspace
? (await resolveWorkspaceRef(options.workspace)).id
: await getCurrentWorkspaceId()
const channel = await resolveChannelRef(ref, workspaceId)

if (options.dryRun) {
printDryRun(`${action} channel`, {
Channel: `${channel.name} (id:${channel.id})`,
'Currently archived': channel.archived ? 'yes' : 'no',
})
return
}

if (channel.archived !== archive) {
if (archive) {
await archiveChannel(channel.id)
} else {
await unarchiveChannel(channel.id)
}
}

if (options.json) {
console.log(formatJson({ id: channel.id, archived: archive }))
return
}

const verb = archive ? 'archived' : 'unarchived'
const noop = channel.archived === archive ? ' (already in target state)' : ''
console.log(`Channel "${channel.name}" (id:${channel.id}) ${verb}${noop}.`)
}

export async function archiveChannelCommand(
ref: string,
options: ArchiveChannelOptions,
): Promise<void> {
await setArchiveState(ref, options, true)
}

export async function unarchiveChannelCommand(
ref: string,
options: ArchiveChannelOptions,
): Promise<void> {
await setArchiveState(ref, options, false)
}
Loading
Loading