Skip to content

Latest commit

 

History

History
69 lines (46 loc) · 3.91 KB

File metadata and controls

69 lines (46 loc) · 3.91 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

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/lib/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.

Architecture

ESM-only TypeScript CLI using Commander.js. Entry point: src/index.ts creates the program and registers four command modules.

Command pattern

Each file in src/commands/ exports a registerXxxCommand(program) function that defines subcommands with Commander's chaining API. Commands use async action handlers.

Lib modules

  • 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() and outputList() handle three output modes (human/json/ndjson). Commands define a humanFormatter function and an essentialKeys array for JSON field filtering. formatError / formatErrorJson accept either positional (code, message, hints?) or a BaseCliError instance — errors thrown by @doist/cli-core helpers (e.g. the delegated changelog command) route through the top-level parseAsync().catch in src/index.ts, which dispatches via isJsonMode().
  • spinner.ts: withSpinner(opts, fn) wrapper using yocto-spinner. Auto-disables on non-TTY, JSON output, CI, --no-spinner flag.
  • markdown.ts: Terminal markdown rendering via marked + marked-terminal.

Key patterns

  • Document IDs are resolved from full URLs or slugs via regex extraction in resolveId().
  • Text input for create/update supports --text inline or --file path, with auto title extraction from markdown headings.
  • Delete operations require --confirm flag.

Testing

Vitest with module mocking. Tests are colocated next to the source they cover (foo.ts → foo.test.ts); shared test fixtures live in src/_fixtures/. Common patterns:

  • Mock apiRequest with vi.mock()
  • Stub fetch globally for API tests
  • Capture output with captureConsole(method?) / captureStream(stream?) from @doist/cli-core/testing (auto-restoring spies); read spy.mock.calls for assertions
  • Build the command harness with createTestProgram(register) from @doist/cli-core/testing (applies exitOverride()), then program.parseAsync()
  • Auth tests use tmpdir with process.pid for filesystem isolation

Skill Content (Agent Command Reference)

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

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.

After updating SKILL_CONTENT:

  1. Run npm run build && npm run sync:skill to regenerate skills/outline-cli/SKILL.md (the standalone skill file used by npx skills add)
  2. Run ol skill update claude-code (and any other installed agents) to propagate changes to installed skill files

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

Style

  • Biome: tabs for indentation, auto-sorted imports
  • TypeScript strict mode, target ES2022, NodeNext modules
  • Avoid any types and forced typecasts
  • Prefer for loops over .forEach()