Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .agents/checks/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Rules lint and types can't express. Most are written in `AGENTS.md` and `CODEBAS
- Reference parsing (ids, URLs, fuzzy names) written again instead of using `src/lib/refs.ts`.
- A positional `[workspace-ref]` without the `--workspace` alias, or one that accepts both without an error.
- A new top-level command not wired into the lazy registry in `src/index.ts`.
- A barrel file, or a helper that duplicates one in `src/lib/` or `@doist/cli-core`. Where cli-core has a convention, the CLI follows it.
- A barrel file, or a helper that duplicates one in `src/lib/` or `@todoist/cli-core`. Where cli-core has a convention, the CLI follows it.

## Fine

Expand Down
2 changes: 1 addition & 1 deletion .agents/checks/evidence.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Apply to the PR description and any report from an agent.

- A behaviour claim ("fixed", "works", "safe", "no regressions") with no test or command that ran it.
- A "Not verified" section missing when something could not be checked: the real Comms API, output in a real terminal, the other Node version CI tests on.
- A change to shared code (`src/lib/`, command registration or global flags in `src/index.ts`, an `@doist/cli-core` or `@doist/comms-sdk` upgrade) without the one fact that makes it safe.
- A change to shared code (`src/lib/`, command registration or global flags in `src/index.ts`, an `@todoist/cli-core` or `@doist/comms-sdk` upgrade) without the one fact that makes it safe.
- A PR title whose type doesn't match the change: behaviour changes need `feat:`, `fix:` or `perf:` to release (`!` for breaking); tooling and docs use `chore:`, `ci:`, `docs:` or `test:` so they don't.

## Fine
Expand Down
4 changes: 2 additions & 2 deletions .agents/scripts/instructions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ it('lists every skill in AGENTS.md, and only those', () => {
expect(listedUnder(text, '## Skills').toSorted()).toEqual(skills.toSorted())
})

it('names only test helpers that the fixtures, global-args or @doist/cli-core/testing export', async () => {
it('names only test helpers that the fixtures, global-args or @todoist/cli-core/testing export', async () => {
const skill = readFileSync(join(SKILLS_DIR, 'write-tests/SKILL.md'), 'utf8')
const section = skill.split('## Helpers')[1]?.split('\n## ')[0] ?? ''
const named = [...section.matchAll(/`(\w+)`/g)].map((match) => match[1] ?? '')
Expand All @@ -161,7 +161,7 @@ it('names only test helpers that the fixtures, global-args or @doist/cli-core/te
),
].map((match) => match[1]),
)
const shared = Object.keys(await import('@doist/cli-core/testing'))
const shared = Object.keys(await import('@todoist/cli-core/testing'))
expect(named.length).toBeGreaterThan(5)
expect(named.filter((name) => !local.includes(name) && !shared.includes(name))).toEqual([])
})
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/review-changes/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Done when the brief is written and the tree holds only the change, with no secre
## 2. Run the reviews in parallel

- **Task review**, always: a fresh subagent with the brief and the diff. It looks for missing pieces, unrequested changes, unhandled cases, tests that would pass with the feature broken, and, in a refactor, any changed test input or assertion. Doistbot can't do this: it never sees the task.
- **Blast-radius review**, when the change alters code others rely on: `src/lib/` (the client and caches in `src/lib/api.ts` above all), command registration, global flags or argv handling in `src/index.ts`, the `@doist/cli-core` or `@doist/comms-sdk` version, other `package.json` dependencies, build or CI config. It names the one fact that makes the change safe and proves it by running code. It looks where text search stops: library versions in `package-lock.json`, the shape of API responses, scripts and installed skills reading `--json` output.
- **Blast-radius review**, when the change alters code others rely on: `src/lib/` (the client and caches in `src/lib/api.ts` above all), command registration, global flags or argv handling in `src/index.ts`, the `@todoist/cli-core` or `@doist/comms-sdk` version, other `package.json` dependencies, build or CI config. It names the one fact that makes the change safe and proves it by running code. It looks where text search stops: library versions in `package-lock.json`, the shape of API responses, scripts and installed skills reading `--json` output.
- **Code review**: Doistbot if it is set up (below). Otherwise one subagent per relevant check in `.agents/checks/`, each with the brief and that check.

Every brief says: **the shared working tree is read-only.** A reviewer that needs to run or break code makes its own copy with `npm run review:worktree -- <dir>`, then `npm ci` in it, and removes it after.
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/verify/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Rate every claim on this ladder:

Claims about behaviour ("fixed", "works", "safe", "no regressions") need **ran** or higher. A fact the code shows needs **cited**. Anything lower goes under **Not verified**, with why.

For a change to code others rely on (shared helpers in `src/lib/`, command registration and global flags in `src/index.ts`, an `@doist/cli-core` or `@doist/comms-sdk` upgrade), name the one fact that makes it safe, and how you proved it.
For a change to code others rely on (shared helpers in `src/lib/`, command registration and global flags in `src/index.ts`, an `@todoist/cli-core` or `@doist/comms-sdk` upgrade), name the one fact that makes it safe, and how you proved it.

Report format:

Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/write-tests/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ description: Writes or changes tests in this repository to its quality bar, with

## Helpers

From `src/lib/__fixtures__/accounts.ts`: `STORED_ALAN`, `STORED_ELLIE`, `ACCOUNT_ALAN`, `ACCOUNT_ELLIE`. From `@doist/cli-core/testing`: `createTestProgram`, `captureConsole`, `captureStream`, `describeEmptyMachineOutput` (the shared check that `--json` and `--ndjson` print nothing extra for an empty result). Reset global flag state between tests with `resetGlobalArgs` from `src/lib/global-args.ts`.
From `src/lib/__fixtures__/accounts.ts`: `STORED_ALAN`, `STORED_ELLIE`, `ACCOUNT_ALAN`, `ACCOUNT_ELLIE`. From `@todoist/cli-core/testing`: `createTestProgram`, `captureConsole`, `captureStream`, `describeEmptyMachineOutput` (the shared check that `--json` and `--ndjson` print nothing extra for an empty result). Reset global flag state between tests with `resetGlobalArgs` from `src/lib/global-args.ts`.

## The quality bar

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
with:
node-version: '24'
cache: npm
scope: '@doist'
scope: '@todoist'
registry-url: 'https://registry.npmjs.org/'

- name: Install dependencies
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ The project uses two tsconfig files: `tsconfig.json` includes test files for typ

Tests are colocated next to the module they cover (for example `src/commands/thread/thread.test.ts` or `src/lib/refs.test.ts`). Shared Vitest manual mocks for npm packages live in `src/__mocks__/` (e.g. `chalk.ts`).

`vitest.config.ts` lists `@doist/cli-core` in `server.deps.inline` so `vi.mock('@doist/cli-core', …)` and `vi.doMock('node:fs/promises', …)` reach cli-core's compiled imports. Without it, vitest treats the package as external and Node's native resolver bypasses the mock substitution, breaking the `auth` / `config` / spinner suites.
`vitest.config.ts` lists `@todoist/cli-core` in `server.deps.inline` so `vi.mock('@todoist/cli-core', …)` and `vi.doMock('node:fs/promises', …)` reach cli-core's compiled imports. Without it, vitest treats the package as external and Node's native resolver bypasses the mock substitution, breaking the `auth` / `config` / spinner suites.

Run a single test file:

Expand Down Expand Up @@ -95,7 +95,7 @@ This is a TypeScript CLI (`tdc`) for Comms messaging, built with Commander.js.

## Error Handling

- **Always use `CliError` from `src/lib/errors.ts`** instead of bare `throw new Error(...)`, `console.error() + process.exit(1)`, or `console.error() + process.exitCode = 1`. This ensures structured error output in `--json` mode and consistent formatting in text mode. The global error handler in `src/index.ts` catches all errors, formats them appropriately, and sets the exit code. The same handler also matches `BaseCliError` (re-exported from `src/lib/errors.ts`) so errors thrown by `@doist/cli-core` helpers route through the same formatter.
- **Always use `CliError` from `src/lib/errors.ts`** instead of bare `throw new Error(...)`, `console.error() + process.exit(1)`, or `console.error() + process.exitCode = 1`. This ensures structured error output in `--json` mode and consistent formatting in text mode. The global error handler in `src/index.ts` catches all errors, formats them appropriately, and sets the exit code. The same handler also matches `BaseCliError` (re-exported from `src/lib/errors.ts`) so errors thrown by `@todoist/cli-core` helpers route through the same formatter.

```typescript
import { CliError } from '../../lib/errors.js'
Expand Down
12 changes: 6 additions & 6 deletions CODEBASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@

## What this project is

`@doist/comms-cli` is a **TypeScript CLI** for Comms messaging. Binary name:
`@todoist/comms-cli` is a **TypeScript CLI** for Comms messaging. Binary name:
`tdc`. It wraps `@doist/comms-sdk` and publishes a single executable
(`dist/index.js`).

ESM-only · Node `^20.19 || >=22.12` · Commander 14 · vitest · oxlint + oxfmt (no
eslint/prettier) · semantic-release on merge to `main`. Shared building blocks
(config I/O, output formatters, spinner, OAuth/keyring auth, command attachers)
come from `@doist/cli-core`.
come from `@todoist/cli-core`.

## Top-level layout

Expand Down Expand Up @@ -46,7 +46,7 @@ come from `@doist/cli-core`.
├─ README.md / CONTRIBUTING.md
├─ tsconfig.json # Includes src + tests (type-check, IDE)
├─ tsconfig.build.json # Excludes *.test.ts/.spec.ts, __mocks__, __fixtures__
├─ vitest.config.ts # { globals, root: 'src', inlines @doist/cli-core }
├─ vitest.config.ts # { globals, root: 'src', inlines @todoist/cli-core }
├─ .oxlintrc.json / .oxfmtrc.json
├─ lefthook.yml # Git hooks: branch guard; pre-commit lint, format, types;
│ # pre-push tests
Expand Down Expand Up @@ -217,7 +217,7 @@ is tried as an id vs a name.

## Auth & token storage

`@doist/cli-core/auth` owns the keyring, multi-user `TokenStore`, OAuth flow,
`@todoist/cli-core/auth` owns the keyring, multi-user `TokenStore`, OAuth flow,
and the `login` / `logout` / `status` / `token view` and `account
list/use/current/remove` attachers. comms supplies (a) a
`UserRecordStore<CommsAccount>` adapter (`user-records.ts`) over its config file
Expand Down Expand Up @@ -259,8 +259,8 @@ see a per-command `--user`).
- **Fixtures:** `src/lib/__fixtures__/accounts.ts` (`ACCOUNT_ALAN` /
`ACCOUNT_ELLIE`) — don't hand-build account objects. Manual npm-package mocks
in `src/__mocks__/` (`chalk.ts`).
- **`@doist/cli-core` inlining:** `vitest.config.ts` lists it in
`server.deps.inline` so `vi.mock('@doist/cli-core', …)` /
- **`@todoist/cli-core` inlining:** `vitest.config.ts` lists it in
`server.deps.inline` so `vi.mock('@todoist/cli-core', …)` /
`vi.doMock('node:fs/promises', …)` reach its compiled imports — without it the
auth/config/spinner suites break.

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ To test features before publishing a stable release:
### Installing a pre-release

```sh
npm install @doist/comms-cli@next
npm install @todoist/comms-cli@next
```

## License
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ A command-line interface for Comms.
## Installation

> ```bash
> npm install -g @doist/comms-cli
> npm install -g @todoist/comms-cli
> ```

Previously published as `@doist/comms-cli`. Both packages install the `tdc` binary, so uninstall the old one first: `npm uninstall -g @doist/comms-cli`.

### Agent Skills

Install skills for your coding agent:
Expand Down Expand Up @@ -43,7 +45,7 @@ tdc skill uninstall <agent>
Then uninstall the CLI:

```bash
npm uninstall -g @doist/comms-cli
npm uninstall -g @todoist/comms-cli
```

## Local Setup
Expand Down
2 changes: 1 addition & 1 deletion docs/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ __tests__/ # Test suite

## Package & Binary

- **Package name**: `@doist/comms-cli`
- **Package name**: `@todoist/comms-cli`
- **Binary**: `tdc`

## Authentication
Expand Down
Loading
Loading