This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
npm install # install dependencies
npm run build # compile TypeScript to dist/
npm run dev # watch mode (rebuild on changes)
npm run type-check # typecheck without emitting
npm run test # run all tests
npx vitest run src/__tests__/output.test.ts # run a single test file
npm run format # biome lint + format (auto-fix)After building, npm link makes the ol binary available globally.
ESM-only TypeScript CLI using Commander.js. Entry point: src/index.ts creates the program and registers four command modules.
Each file in src/commands/ exports a registerXxxCommand(program) function that defines subcommands with Commander's chaining API. Commands use async action handlers.
- api.ts: Single
apiRequest<T>(path, body)function. All Outline API calls are POST with Bearer auth. Wraps requests in spinner with per-endpoint messages (SPINNER_MESSAGES map). - auth.ts: Config stored at
~/.config/outline-cli/config.json. Token/URL resolution: env var → config file → default. - output.ts:
outputItem()andoutputList()handle three output modes (human/json/ndjson). Commands define ahumanFormatterfunction and anessentialKeysarray for JSON field filtering. - spinner.ts:
withSpinner(opts, fn)wrapper using yocto-spinner. Auto-disables on non-TTY, JSON output, CI,--no-spinnerflag. - markdown.ts: Terminal markdown rendering via marked + marked-terminal.
- Document IDs are resolved from full URLs or slugs via regex extraction in
resolveId(). - Text input for create/update supports
--textinline or--filepath, with auto title extraction from markdown headings. - Delete operations require
--confirmflag.
Vitest with module mocking. Tests live in src/__tests__/. Common patterns:
- Mock
apiRequestwithvi.mock() - Stub
fetchglobally for API tests - Capture
console.logcalls in an array for output assertions - Use
program.exitOverride()+program.parseAsync()to test command parsing - Auth tests use tmpdir with
process.pidfor filesystem isolation
- Biome: tabs for indentation, auto-sorted imports
- TypeScript strict mode, target ES2022, NodeNext modules
- Avoid
anytypes and forced typecasts - Prefer
forloops over.forEach()