canonry

CLAUDE.md

Project Overview

canonry is an open-source agent-first AEO monitoring platform that tracks how AI answer engines cite a domain for tracked keywords. Published as @ainyc/canonry on npm. The CLI and API are the primary interfaces — the web dashboard is supplementary.

Workspace Map

apps/api/                 Cloud API entry point (imports packages/api-routes)
apps/worker/              Cloud worker entry point
apps/web/                 Vite SPA source (bundled into packages/canonry/assets/)
packages/canonry/         Publishable npm package (CLI + server + bundled SPA)
packages/api-routes/      Shared Fastify route plugins
packages/contracts/       DTOs, enums, config-schema, error codes
packages/config/          Typed environment parsing
packages/db/              Drizzle ORM schema, migrations, client (SQLite/Postgres)
packages/provider-gemini/ Gemini adapter
packages/provider-openai/ OpenAI adapter
packages/provider-claude/ Claude/Anthropic adapter
packages/provider-local/  Local LLM adapter (OpenAI-compatible API)
docs/                     Architecture, roadmap, testing, ADRs

Start with docs/README.md when you need the current doc map, active plans, ADR index, or canonical roadmap.

Commands

# One-command dev setup: install deps, build all packages, install canonry globally
./canonry-install.sh

pnpm install
pnpm run typecheck
pnpm run test
pnpm run lint
pnpm run dev:web

# CLI (after Phase 2 implementation)
canonry init
canonry serve
canonry project create <name> --domain <domain> --country US --language en
canonry keyword add <project> <keyword>...
canonry run <project>
canonry run <project> --provider gemini          # single-provider run
canonry status <project>
canonry apply <file...>                          # multi-doc YAML + multiple files
canonry export <project>

Dependency Boundary

Surface Priority

THIS IS AN AGENT-FIRST PLATFORM. The CLI and API are the primary interfaces. The web UI is a nice-to-have — it must never block or delay CLI/API work.

Priority order

  1. API — the shared backbone. Every capability must be exposed here first.
  2. CLI — the primary user-facing surface. Must feel complete and polished.
  3. Web UI — important but lower priority. Ideally all features have a UI, but never block a release on it.

When adding a new feature

  1. Required: Add the API endpoint in packages/api-routes/.
  2. Required: Add the CLI command in packages/canonry/src/commands/.
  3. Ideal: Add the UI interaction in apps/web/ — aim to include it, but never block a release waiting for UI work.

Agent & automation design principles

Maintenance Guidance

Database Schema Changes (Critical)

Every new sqliteTable(...) in packages/db/src/schema.ts MUST have a corresponding migration in packages/db/src/migrate.ts.

This is not optional. If you add a table to the schema but omit the migration, the table will never be created in any existing or new database, and every query against it will throw no such table at runtime.

Rules

  1. New table → add CREATE TABLE IF NOT EXISTS ... to the MIGRATIONS array in migrate.ts. Include all indexes from the schema definition.
  2. New column → add ALTER TABLE ... ADD COLUMN ... to MIGRATIONS. SQLite ignores duplicate ADD COLUMN attempts, so these are safe to re-run.
  3. Removed column or table → SQLite does not support DROP COLUMN on older versions; document the intent and leave the migration as a no-op comment if needed.
  4. Never edit MIGRATION_SQL (the initial block at the top). That block bootstraps brand-new installs. All incremental changes go in the MIGRATIONS array only.

Pattern

// In packages/db/src/migrate.ts — MIGRATIONS array:

// v12: My new feature — my_new_table
`CREATE TABLE IF NOT EXISTS my_new_table (
  id          TEXT PRIMARY KEY,
  project_id  TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
  value       TEXT NOT NULL,
  created_at  TEXT NOT NULL
)`,
`CREATE INDEX IF NOT EXISTS idx_my_new_table_project ON my_new_table(project_id)`,

Checklist for any schema change

Authentication Storage

Config-as-Code

Projects are managed via canonry.yaml files with Kubernetes-style structure:

apiVersion: canonry/v1
kind: Project
metadata:
  name: my-project
spec:
  displayName: My Project
  canonicalDomain: example.com
  country: US
  language: en
  keywords:
    - keyword one
  competitors:
    - competitor.com
  providers:
    - gemini
    - openai

Locations are project-scoped via spec.locations and spec.defaultLocation. Runs choose the default location, an explicit location, all configured locations, or no location. Do not model locations as keyword-owned state.

Multiple projects can be defined in one file using --- document separators. Apply with canonry apply <file...> (accepts multiple files) or POST /api/v1/apply. Applied project YAML is declarative input; runtime project/run data lives in the DB, while local authentication credentials live in ~/.canonry/config.yaml.

API Surface

All endpoints under /api/v1/. Auth via Authorization: Bearer cnry_.... Key endpoints:

See OpenAPI spec at /api/v1/openapi.json for the complete API surface.

UI Design System

The web dashboard follows a dark, professional analytics aesthetic inspired by Vercel’s design system — clean, minimal, high-contrast, and information-dense. Rival tools like Semrush, Ahrefs, and Profound for data richness, but match Vercel for polish: generous whitespace, sharp typography, subtle borders, no visual noise. Follow these conventions for all UI work:

Layout

Color & Theme

Components & Patterns

Data Density

Accessibility

Don’ts

Roadmap

See docs/roadmap.md for the full feature roadmap including competitive analysis, priority matrix, and phased implementation order.

API Stability

Never change existing API endpoint paths or HTTP methods during revisions. The CLI, UI, and any external integrations are hard-coded to the published routes. Changing a path or method is a breaking change regardless of the reason.

Versioning

Every non-documentation change must include a version bump. The root package.json and packages/canonry/package.json versions must always be kept in sync with each other and with the latest published version on npm (@ainyc/canonry).

Testing

Every non-trivial change must include tests. If you are adding a feature, fixing a bug, or refactoring logic, ship tests alongside the code. Trivial changes (typo fixes, comment updates, config-only changes) are exempt.

Skills Maintenance

The skills/canonry-setup/ directory contains an OpenClaw/Claude skill that documents how to install, configure, and operate canonry. Keep this skill in sync with the codebase.

When to update skills

What NOT to put in skills

CI Guidance