Skip to content

Commit b30c0a9

Browse files
authored
chore: drop Twist branding and legacy migration code (#1)
1 parent ea28735 commit b30c0a9

106 files changed

Lines changed: 1834 additions & 2638 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/skills/add-command/SKILL.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: add-command
3-
description: Guide for adding new CLI commands or subcommands to twist-cli. Use when implementing new SDK endpoints, adding subcommands to existing command groups, or extending CLI functionality.
3+
description: Guide for adding new CLI commands or subcommands to comms-cli. Use when implementing new SDK endpoints, adding subcommands to existing command groups, or extending CLI functionality.
44
---
55

66
# Adding a New CLI Command or Subcommand
@@ -19,7 +19,7 @@ Color convention:
1919

2020
## 2. Read-Only Permissions (`src/lib/permissions.ts`)
2121

22-
If the new command uses a **read-only** SDK method (e.g., `getXxx`, `listXxx`), add it to the `KNOWN_SAFE_API_METHODS` set. This set uses a default-deny approach: any method **not** listed is treated as mutating and will be blocked when the CLI is authenticated with a read-only OAuth token (`tw auth login --read-only`).
22+
If the new command uses a **read-only** SDK method (e.g., `getXxx`, `listXxx`), add it to the `KNOWN_SAFE_API_METHODS` set. This set uses a default-deny approach: any method **not** listed is treated as mutating and will be blocked when the CLI is authenticated with a read-only OAuth token (`tdc auth login --read-only`).
2323

2424
- **Read-only methods** (fetch/list/view): add to `KNOWN_SAFE_API_METHODS`
2525
- **Mutating methods** (create/update/delete/archive/mute): do NOT add — they are blocked by default, which is the correct behavior
@@ -60,7 +60,7 @@ Single-subcommand commands (e.g., `channel.ts`, `inbox.ts`) remain as flat files
6060

6161
### ID resolution
6262

63-
- `resolveThreadId(ref)` — resolve thread by numeric ID or Twist URL
63+
- `resolveThreadId(ref)` — resolve thread by numeric ID or Comms URL
6464
- `resolveChannelId(ref)` — resolve channel by numeric ID, URL, or fuzzy name
6565
- `resolveWorkspaceRef(ref)` — resolve workspace by ID or fuzzy name
6666
- `resolveConversationId(ref)` — resolve conversation by numeric ID or URL
@@ -89,7 +89,7 @@ The variable assignment (`const myCmd = ...`) is needed so the `.action()` callb
8989

9090
### Implicit view subcommand
9191

92-
For entity commands with a `view` subcommand, mark it as the default so `tw thread 123` maps to `tw thread view 123`:
92+
For entity commands with a `view` subcommand, mark it as the default so `tdc thread 123` maps to `tdc thread view 123`:
9393

9494
```typescript
9595
thread
@@ -128,7 +128,7 @@ const commands: Record<string, [string, () => Promise<(p: Command) => void>]> =
128128

129129
## 4. Accessibility (`src/lib/output.ts`)
130130

131-
The CLI supports accessible mode via `isAccessible()` (checks `TW_ACCESSIBLE=1` or `--accessible` flag). When adding output that uses color or visual elements, consider whether information is conveyed **only** by color or decoration.
131+
The CLI supports accessible mode via `isAccessible()` (checks `TDC_ACCESSIBLE=1` or `--accessible` flag). When adding output that uses color or visual elements, consider whether information is conveyed **only** by color or decoration.
132132

133133
### When to add accessible alternatives
134134

@@ -160,12 +160,12 @@ Tests mock the API layer directly using `vi.mock` and `vi.hoisted`. Follow the e
160160

161161
```typescript
162162
const apiMocks = vi.hoisted(() => ({
163-
getTwistClient: vi.fn(),
163+
getCommsClient: vi.fn(),
164164
}))
165165

166166
vi.mock('../lib/api.js', async (importOriginal) => ({
167167
...(await importOriginal<typeof import('../lib/api.js')>()),
168-
getTwistClient: apiMocks.getTwistClient,
168+
getCommsClient: apiMocks.getCommsClient,
169169
}))
170170

171171
vi.mock('../lib/markdown.js', () => ({
@@ -218,7 +218,7 @@ After all code changes are complete:
218218
npm run build && npm run sync:skill
219219
```
220220

221-
This builds the project and regenerates `skills/twist-cli/SKILL.md` from the compiled skill content. The regenerated file must be committed. CI will fail (`npm run check:skill-sync`) if it is out of sync.
221+
This builds the project and regenerates `skills/comms-cli/SKILL.md` from the compiled skill content. The regenerated file must be committed. CI will fail (`npm run check:skill-sync`) if it is out of sync.
222222

223223
## 8. Verify
224224

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: add-command
3-
description: Guide for adding new CLI commands or subcommands to twist-cli. Use when implementing new SDK endpoints, adding subcommands to existing command groups, or extending CLI functionality.
3+
description: Guide for adding new CLI commands or subcommands to comms-cli. Use when implementing new SDK endpoints, adding subcommands to existing command groups, or extending CLI functionality.
44
---
55

66
See [/.agents/skills/add-command/SKILL.md](../../../.agents/skills/add-command/SKILL.md) for the full guide.

.github/workflows/release.yml

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,6 @@ jobs:
6868
- name: Install dependencies
6969
run: npm ci
7070

71-
- name: Capture previous tag
72-
if: github.ref_name == 'main'
73-
id: previous_tag
74-
run: echo "tag=$(git describe --tags --abbrev=0 --exclude='*-*' 2>/dev/null || true)" >> "$GITHUB_OUTPUT"
75-
7671
- name: Release
7772
run: npx semantic-release
7873
env:
@@ -81,57 +76,3 @@ jobs:
8176
GIT_AUTHOR_EMAIL: ${{ steps.bot_user.outputs.id }}+${{ steps.generate_token.outputs.app-slug }}[bot]@users.noreply.github.com
8277
GIT_COMMITTER_NAME: ${{ steps.generate_token.outputs.app-slug }}[bot]
8378
GIT_COMMITTER_EMAIL: ${{ steps.bot_user.outputs.id }}+${{ steps.generate_token.outputs.app-slug }}[bot]@users.noreply.github.com
84-
85-
- name: Derive release announcement
86-
if: github.ref_name == 'main'
87-
id: announcement
88-
env:
89-
PREVIOUS_TAG: ${{ steps.previous_tag.outputs.tag }}
90-
run: |
91-
git fetch --force --tags origin
92-
93-
new_tag="$(git describe --tags --abbrev=0 2>/dev/null || true)"
94-
if [ -z "${new_tag}" ] || [ "${new_tag}" = "${PREVIOUS_TAG}" ]; then
95-
echo "should_announce=false" >> "$GITHUB_OUTPUT"
96-
exit 0
97-
fi
98-
99-
package_name="$(node -p "JSON.parse(require('fs').readFileSync('package.json', 'utf8')).name")"
100-
package_version="$(node -p "JSON.parse(require('fs').readFileSync('package.json', 'utf8')).version")"
101-
release_version="${new_tag#v}"
102-
103-
package_url="https://www.npmjs.com/package/${package_name}/v/${package_version}"
104-
release_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/tag/${new_tag}"
105-
repo_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}"
106-
107-
if [ -n "${PREVIOUS_TAG}" ]; then
108-
changelog="$(git log --no-merges --reverse --pretty='format:- %s (%H-%h)' "${PREVIOUS_TAG}..${new_tag}" | grep -v '^- chore(release): ' || true)"
109-
else
110-
changelog="$(git log --no-merges --reverse --pretty='format:- %s (%H-%h)' "${new_tag}" | grep -v '^- chore(release): ' || true)"
111-
fi
112-
113-
if [ -z "${changelog}" ]; then
114-
changelog='- No additional commits listed.'
115-
else
116-
changelog="$(printf '%s\n' "${changelog}" | sed -E -e 's,\(([a-f0-9]+)-([a-f0-9]+)\),([`\2`]('"${repo_url}"'/commit/\1)),g' | sed -E -e 's,\(#([0-9]+)\),([#\1]('"${repo_url}"'/pull/\1)),g')"
117-
fi
118-
119-
{
120-
echo "should_announce=true"
121-
echo "message<<EOF"
122-
echo "**Twist CLI ${new_tag} published** 🚀"
123-
echo
124-
printf '%s\n' "${changelog}"
125-
echo
126-
echo "[GitHub release](${release_url}) | [npm package](${package_url})"
127-
echo "EOF"
128-
} >> "$GITHUB_OUTPUT"
129-
130-
- name: Announce release in Twist
131-
if: github.ref_name == 'main' && steps.announcement.outputs.should_announce == 'true'
132-
uses: Doist/twist-post-action@74a0255b75ad93c06b9eb1009960106efe13f5ca
133-
with:
134-
message: ${{ steps.announcement.outputs.message }}
135-
install_id: ${{ secrets.TWIST_RELEASE_INSTALL_ID }}
136-
install_token: ${{ secrets.TWIST_RELEASE_INSTALL_TOKEN }}
137-
continue-on-error: true
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Update Twist SDK
1+
name: Update Comms SDK
22

33
on:
44
workflow_dispatch:
@@ -8,7 +8,7 @@ permissions:
88
pull-requests: write
99

1010
jobs:
11-
update-twist-sdk:
11+
update-comms-sdk:
1212
runs-on: ubuntu-latest
1313
timeout-minutes: 10
1414

@@ -27,8 +27,8 @@ jobs:
2727
- name: Install current dependencies
2828
run: npm ci
2929

30-
- name: Update @doist/twist-sdk to latest
31-
run: npm install @doist/twist-sdk@latest
30+
- name: Update @doist/comms-sdk to latest
31+
run: npm install @doist/comms-sdk@latest
3232

3333
- name: Build
3434
run: npm run build
@@ -46,10 +46,10 @@ jobs:
4646
id: changes
4747
run: |
4848
if git diff --quiet package.json package-lock.json; then
49-
echo "No updates available - @doist/twist-sdk is already at the latest version"
49+
echo "No updates available - @doist/comms-sdk is already at the latest version"
5050
echo "has_changes=false" >> $GITHUB_OUTPUT
5151
else
52-
echo "Changes detected - @doist/twist-sdk has been updated"
52+
echo "Changes detected - @doist/comms-sdk has been updated"
5353
echo "has_changes=true" >> $GITHUB_OUTPUT
5454
fi
5555
@@ -59,7 +59,7 @@ jobs:
5959
git config --local user.email "action@github.com"
6060
git config --local user.name "GitHub Action"
6161
git add package.json package-lock.json
62-
git commit -m "fix(deps): update to latest \`@doist/twist-sdk\` package"
62+
git commit -m "fix(deps): update to latest \`@doist/comms-sdk\` package"
6363
git push
6464
6565
- name: Trigger release workflow
@@ -74,9 +74,9 @@ jobs:
7474
- name: Report success
7575
run: |
7676
if [ "${{ steps.changes.outputs.has_changes }}" == "true" ]; then
77-
echo "✅ Successfully updated @doist/twist-sdk package"
77+
echo "✅ Successfully updated @doist/comms-sdk package"
7878
echo "📦 Changes committed to main branch"
7979
echo "🚀 Release workflow triggered - semantic release will create a new patch version"
8080
else
81-
echo "ℹ️ No updates needed - @doist/twist-sdk is already at the latest version"
81+
echo "ℹ️ No updates needed - @doist/comms-sdk is already at the latest version"
8282
fi

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ dist/
66
*.tsbuildinfo
77
.DS_Store
88
.claude/settings.local.json
9+
.claude/scheduled_tasks.lock

AGENTS.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,27 +36,27 @@ node dist/index.js <command>
3636

3737
## Architecture
3838

39-
This is a TypeScript CLI (`tw`) for Twist messaging, built with Commander.js.
39+
This is a TypeScript CLI (`tdc`) for Comms messaging, built with Commander.js.
4040

4141
**Entry point**: `src/index.ts` registers all commands with Commander.
4242

4343
**Commands** (`src/commands/`): Commands with multiple subcommands use a folder-based structure (`src/commands/<entity>/index.ts`) where the index file exports a `register*Command(program)` function and wires Commander subcommands to handler functions in sibling files. Single-command files remain as flat files (`src/commands/<entity>.ts`). Each subcommand handler file exports one async action function and imports from `../../lib/`. An optional `helpers.ts` holds shared constants/utilities used by multiple subcommands. Commands support `--json`, `--ndjson`, and `--full` flags for machine-readable output.
4444

4545
**Lib** (`src/lib/`):
4646

47-
- `api.ts` - Singleton TwistApi client from `@doist/twist-sdk`, workspace/user caching
48-
- `refs.ts` - Reference parsing: accepts IDs (`id:123` or bare `123`), Twist URLs, or fuzzy names for workspaces/users
47+
- `api.ts` - Singleton CommsApi client from `@doist/comms-sdk`, workspace/user caching
48+
- `refs.ts` - Reference parsing: accepts IDs (`id:123` or bare `123`), Comms URLs, or fuzzy names for workspaces/users
4949
- `output.ts` - JSON/NDJSON formatting with essential field filtering per entity type
50-
- `config.ts` - Persists config to `~/.config/twist-cli/config.json`
50+
- `config.ts` - Persists config to `~/.config/comms-cli/config.json`
5151
- `auth.ts` - Token loading/saving/clearing (env var or config file)
5252
- `markdown.ts` - Terminal markdown rendering via `marked` + `marked-terminal`
5353
- `completion.ts` - Commander tree-walker + completion helpers for shell tab completion
5454

55-
**Reference system**: The CLI accepts flexible references throughout - numeric IDs, `id:` prefixed IDs, full Twist URLs (parsed via `parseTwistUrl`), or fuzzy name matching for workspaces/users.
55+
**Reference system**: The CLI accepts flexible references throughout - numeric IDs, `id:` prefixed IDs, full Comms URLs (parsed via `parseCommsUrl`), or fuzzy name matching for workspaces/users.
5656

5757
## Key Patterns
5858

59-
- **Implicit view subcommand**: `tw thread <ref>` defaults to `tw thread view <ref>` via Commander's `{ isDefault: true }`. Same for `conversation` and `msg`. Edge case: if a ref matches a subcommand name (e.g., "reply"), the subcommand wins — user must use `tw thread view reply`
59+
- **Implicit view subcommand**: `tdc thread <ref>` defaults to `tdc thread view <ref>` via Commander's `{ isDefault: true }`. Same for `conversation` and `msg`. Edge case: if a ref matches a subcommand name (e.g., "reply"), the subcommand wins — user must use `tdc thread view reply`
6060
- **Named flag aliases**: Where commands accept positional `[workspace-ref]`, the `--workspace` flag is also accepted. Error if both positional and flag are provided
6161
- **JSON output on mutating commands**: Mutating commands (create, update, delete, archive) should support `--json` output where it provides scripting value. Commands that return an object from the API (create/update) should also support `--full`. Commands where the API returns void should output a minimal status object (e.g. `{ id, deleted: true }` or `{ id, isArchived: true }`). Extend `MutationOptions` in `src/lib/options.ts` (which already includes `json` and `full`) rather than adding these fields ad hoc. Use `formatJson()` from `src/lib/output.ts` for the output. See `src/commands/away.ts` as the reference implementation.
6262
- **Spinner messages**: When adding new SDK method calls, add a corresponding entry in the `API_SPINNER_MESSAGES` map in `src/lib/api.ts`. Every user-facing API call should have a spinner message so the CLI shows progress feedback.
@@ -87,7 +87,7 @@ Lefthook runs type-check, oxlint, and oxfmt on pre-commit, tests on pre-push.
8787

8888
## Skill Content (Agent Command Reference)
8989

90-
The file `src/lib/skills/content.ts` exports `SKILL_CONTENT` — a comprehensive command reference that gets installed into AI agent skill directories via `tw skill install`. This is the source of truth that agents use to understand available CLI commands.
90+
The file `src/lib/skills/content.ts` exports `SKILL_CONTENT` — a comprehensive command reference that gets installed into AI agent skill directories via `tdc skill install`. This is the source of truth that agents use to understand available CLI commands.
9191

9292
**Whenever commands, subcommands, flags, or options are added, updated, or removed in `src/commands/`, the `SKILL_CONTENT` in `src/lib/skills/content.ts` must be updated to match.** This includes:
9393

@@ -98,7 +98,7 @@ The file `src/lib/skills/content.ts` exports `SKILL_CONTENT` — a comprehensive
9898

9999
After updating `SKILL_CONTENT`:
100100

101-
1. Run `npm run build && npm run sync:skill` to regenerate `skills/twist-cli/SKILL.md` (the standalone skill file used by `npx skills add`)
102-
2. Run `tw skill update claude-code` (and any other installed agents) to propagate changes to installed skill files
101+
1. Run `npm run build && npm run sync:skill` to regenerate `skills/comms-cli/SKILL.md` (the standalone skill file used by `npx skills add`)
102+
2. Run `tdc skill update claude-code` (and any other installed agents) to propagate changes to installed skill files
103103

104-
A CI check (`npm run check:skill-sync`) runs on pull requests and will fail if `skills/twist-cli/SKILL.md` is out of sync with `content.ts`.
104+
A CI check (`npm run check:skill-sync`) runs on pull requests and will fail if `skills/comms-cli/SKILL.md` is out of sync with `content.ts`.

CONTRIBUTING.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
# Contributing to Twist CLI
1+
# Contributing to Comms CLI
22

3-
The following is a set of guidelines for contributing to Twist CLI. Please read these guidelines before creating an issue or pull request.
3+
The following is a set of guidelines for contributing to Comms CLI. Please read these guidelines before creating an issue or pull request.
44

55
## Open Development
66

7-
All work on Twist CLI happens directly on [GitHub](https://github.com/Doist/twist-cli). Both core team members and external contributors send pull requests that go through the same review process.
7+
All work on Comms CLI happens directly on [GitHub](https://github.com/Doist/comms-cli). Both core team members and external contributors send pull requests that go through the same review process.
88

99
## Semantic Versioning
1010

11-
Twist CLI follows [semantic versioning](https://semver.org/). We release patch versions for bugfixes, minor versions for new features or non-essential changes, and major versions for any breaking changes.
11+
Comms CLI follows [semantic versioning](https://semver.org/). We release patch versions for bugfixes, minor versions for new features or non-essential changes, and major versions for any breaking changes.
1212

1313
Every significant change is documented in the [CHANGELOG.md](CHANGELOG.md) file.
1414

1515
## Branch Organization
1616

17-
Submit all changes to the [main](https://github.com/Doist/twist-cli/tree/main) branch (via PR) by default. For pre-release work, target the `next` branch instead — see [Release Process](#release-process-core-team-only) for details.
17+
Submit all changes to the [main](https://github.com/Doist/comms-cli/tree/main) branch (via PR) by default. For pre-release work, target the `next` branch instead — see [Release Process](#release-process-core-team-only) for details.
1818

1919
We do our best to keep `main` in good shape, with all tests passing.
2020

@@ -91,9 +91,9 @@ To test features before publishing a stable release:
9191
### Installing a pre-release
9292

9393
```sh
94-
npm install @doist/twist-cli@next
94+
npm install @doist/comms-cli@next
9595
```
9696

9797
## License
9898

99-
By contributing to Twist CLI, you agree that your contributions will be licensed under its [MIT license](LICENSE).
99+
By contributing to Comms CLI, you agree that your contributions will be licensed under its [MIT license](LICENSE).

0 commit comments

Comments
 (0)