Skip to content
Documentation GitHub
Getting Started

AGENTS

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

General Behavior

  • When the user provides a URL or references external content, fetch/read it FIRST before responding. Do not begin analysis or planning without the referenced material.

Task Interpretation

  • When asked to create Linear issues or update project management tools, do NOT explore the codebase or begin implementation unless explicitly asked. Focus solely on the PM task first.
  • When the user asks for a plan or design discussion, stay in planning mode. Do not start implementation unless explicitly instructed to proceed with coding.

Linear Integration

  • When setting Linear labels, always use label IDs rather than label names. Fetch available labels first if IDs are unknown.
  • Before creating a new Linear/Jira issue, always search for existing issues with similar titles or descriptions to avoid duplicates. Confirm with the user if a potential duplicate is found.

Database & Migrations

  • Do not assume database migrations have been applied in local environments. Always verify migration state before proceeding.
  • Check .env files for available connection strings before claiming they don’t exist.

Prerequisites

Required Tools

  • Node.js ≥22.0.0
  • pnpm ≥10.0.0 (npm install -g pnpm@10.30.1)
  • Rust (latest stable, edition 2024) with rustup component add clippy rustfmt
  • uv (brew install uv on macOS, or https://docs.astral.sh/uv/) — Python package manager for python-sidecar
  • gitleaks (brew install gitleaks on macOS) — required by pre-commit hook
  • dprint (brew install dprint on macOS) — Markdown formatter (table alignment, line wrapping)

Platform-Specific Dependencies

macOS: Xcode Command Line Tools (xcode-select --install)

Linux (Debian/Ubuntu):

Terminal window
sudo apt-get install -y libwebkit2gtk-4.1-dev \
libappindicator3-dev librsvg2-dev patchelf libssl-dev libgtk-3-dev

Build & Development Commands

Terminal window
# Development
pnpm dev # Start all packages via Turbo
pnpm desktop:dev # Start desktop app only (Vite + Tauri)
# Build
pnpm build # Build all packages
pnpm desktop:build # Build desktop app
# Type Generation (Rust -> TypeScript)
pnpm generate:types # Required before dev/build/typecheck
# Linting & Formatting
pnpm lint # oxlint for TypeScript
pnpm typecheck # TypeScript type checking
cargo clippy # Rust linting
cargo fmt # Rust formatting
dprint check # Markdown formatting check
dprint fmt # Markdown auto-format
# Pre-commit Quality Gate (automatic via husky)
# - gitleaks secret scanning (only hook — formatting/linting removed)
# Quality Gate (manual, scoped to changed files vs main)
./tools/precheck.sh # Diff vs main (check only)
./tools/precheck.sh --fix # Auto-fix formatting/linting, then check
./tools/precheck.sh --base dev # Diff vs specific ref
./tools/precheck.sh --no-test # Skip cargo test
./tools/precheck.sh --full # Full workspace (all crates, all tests)
# Testing
pnpm test # All tests via Turbo
cargo test # Rust tests only
# Reset App Data
./tools/dev/reset-app-data.sh # Clear all app data (interactive)
./tools/dev/reset-app-data.sh --force # Clear without confirmation

Architecture

Polyglot modular monolith with Clean Architecture. For the complete architecture reference including file paths, layer breakdown, and system map, see apps/codex/src/content/docs/architecture/overview.mdx.

Key Directories

DirectoryPurpose
crates/domain/Pure business entities, no external dependencies
crates/application/Use cases + service trait abstractions
crates/commands/Transport-agnostic command layer (validation, error sanitization)
crates/infrastructure/Concrete implementations (sqlite, onnx, supabase, llm, agent-core, etc.)
apps/desktop/src-tauri/Tauri framework layer (commands, DI wiring, MCP server)
apps/desktop/src-react/React frontend (TypeScript, TipTap editor, Zustand state)
apps/codex/Codex documentation site (Astro)
apps/http-bridge/HTTP bridge for QA testing (Axum REST)
apps/python-sidecar/Python sidecar (DSPy, LLM pipeline)
packages/contracts/Generated Rust→TypeScript types (Specta)
apps/web/Marketing website (Astro + Cloudflare)
tests/core/Integration tests (real SQLite)
tests/e2e/End-to-end tests via HTTP bridge

Layer Dependencies

Dependencies flow inward: Framework → Infrastructure → Application → Domain. Separate crates enforce this at compile time.

Documentation Split

LocationContent
apps/codex/src/content/docs/Permanent architecture docs — system docs, data flows, domain rules
docs/Developer process docs — ADRs, solutions, how-tos, tutorials, reference

Loro CRDT Editor Integration

The editor uses loro-crdt and loro-prosemirror (npm) to bind TipTap to a LoroDoc. The LoroSync TipTap extension (apps/desktop/src-react/lib/loro-sync/) registers LoroSyncPlugin (bidirectional ProseMirror ↔ Loro sync) and LoroUndoPlugin (Loro-backed undo/redo that persists across sessions). On save, both the LoroDoc snapshot bytes and materialized markdown text are sent to the backend.

Glossary

TermDefinition
aggregate rootDDD concept: top-level entity that owns a cluster of related domain objects and coordinates access
BLOBBinary Large Object; raw byte storage in SQLite columns
bounded contextDDD concept: logical boundary within which a particular domain model applies consistently
CapabilityPermission enum variant representing a specific action a user/agent can perform (19 variants)
CDPChrome DevTools Protocol; browser automation and debugging interface
CRDTConflict-free Replicated Data Type; enables concurrent editing without coordination
DSPyOffline prompt optimization framework for LLM pipelines
FTS5SQLite Full-Text Search extension version 5
Loro/LoroDocCRDT library for block content; LoroDoc is a document instance
LWWLast-Writer-Wins; conflict resolution strategy for metadata sync
MCPModel Context Protocol; standardized agent integration interface
nextestcargo-nextest; fast Rust test runner with per-test process isolation
oxlintFast JavaScript/TypeScript linter used for all TypeScript linting
PermissionGuardUnforgeable proof-of-authorization token; module-private constructor ensures only CapabilityResolver can issue
PostgRESTREST API layer for PostgreSQL; used by Supabase for auto-generated APIs
ProseMirrorToolkit for building rich text editors; underlies TipTap
RigRust crate for multi-provider LLM abstraction
RLSRow Level Security; PostgreSQL feature for per-row access control
rmcpRust MCP SDK crate for building MCP servers and clients
RRFReciprocal Rank Fusion; algorithm for merging ranked search results
sccacheShared compilation cache for Rust; speeds up CI builds
SpectaRust-to-TypeScript type generation library
TipTapProseMirror-based rich text editor framework used for the editor
Turbo/TurborepoMonorepo build orchestrator; runs tasks across packages with caching
WALWrite-Ahead Logging; SQLite journaling mode enabling concurrent reads
WriteEffectCoordinatorSide-effect dispatch pipeline that coordinates sync queue, embedding, and UI events after writes
ZustandLightweight React state management library

Document Hierarchy (Authority Order)

When conflicts arise between documents, defer to sources in this order:

PriorityDocumentRole
1README.mdCanonical product vision and positioning
2Domain RulesBusiness invariants (constraints)
3Development GuideMethodology (how, not what)

Principle: Vision constrains requirements. Requirements constrain implementation. Domain rules are invariants at all levels.

Development Methodology

See docs/guides/development-guide.md for full details.

Vertical Slicing

All features are implemented end-to-end through layers, not layer-by-layer:

  1. Domain (Rust entity/validation)
  2. Application (Rust use case + service traits)
  3. Infrastructure (storage implementation)
  4. Framework (Tauri command)
  5. Frontend (React component)

Rule: If you can’t demo it, you haven’t finished it.

File-Per-Use-Case Pattern

crates/application/src/page/
├── mod.rs # Re-exports
├── services.rs # PageRepository trait + errors
├── get.rs # GetPageUseCase
├── create.rs # CreatePageUseCase
└── update.rs # UpdatePageUseCase

Type Generation Pipeline

Rust structs -> Specta -> TypeScript types in packages/contracts/generated/

Run pnpm generate:types after modifying Rust types.

Domain Rules (Enforced in Rust)

See apps/codex/src/content/docs/architecture/domain-rules.mdx for full details.

RuleSummary
Min 1 block per pageCreating page atomically creates initial block
No cyclesCannot move page to become descendant of itself
Cascade deletionDeleting page deletes all descendants
Workspace scopingAll entities belong to exactly one workspace
Flat workspacesNo nested workspaces
Block-workspace inheritBlocks inherit workspace through page

Testing Strategy

See docs/guides/development-guide.md#testing-strategy for full details.

  • Domain layer: Pure unit tests, 100% coverage goal
  • Application layer: Unit tests with mocked repos, >90% coverage
  • Infrastructure: Unit tests with temp dirs, >80% coverage
  • Integration tests (tests/core/): Real use cases wired to real SQLite — cargo test -p core-tests
  • Frontend integration (apps/desktop/tests/): Playwright tests with mocked Tauri backend
  • End-to-end (tests/e2e/): End-to-end tests via HTTP bridge using Playwright Test Agents — pnpm test:e2e

Test naming: test_[what]_[condition]_[expected]

Test File Organization

Tests use the sibling tests.rs submodule pattern:

  • Source file contains #[cfg(test)] mod tests; (declaration, no body)
  • Tests live in sibling tests.rs with use super::*;
  • foo.rsfoo/tests.rs; mod.rs → sibling tests.rs
  • Inline mod tests { } acceptable only for files < 200 LOC with simple tests
  • Shared test helpers go in test_helpers.rs when substantial and reused

Key Technical Decisions

  • Storage: SQLite database per workspace (inklings.db) with FTS5 for search. Block content stored as LoroDoc BLOBs for CRDT history; materialized text kept alongside for FTS indexing.
  • Loro CRDT: Block content uses Loro CRDTs (loro Rust crate, loro-crdt/loro-prosemirror npm). Enables operation-level history, cross-session undo/redo, and multi-device sync.
  • Import: External markdown files imported via MarkdownImporter, wiki-links converted
  • Links: Wiki-style [[Page Name]] with backlink tracking
  • Versioning: Event log + CRDT content history + named bookmarks (git-backed checkpoint system removed)
  • Embedding model: Auto-downloaded from HuggingFace on first workspace open (~585 MB). Background tokio::spawn with streaming progress via Tauri events (embedding-model:download-progress). SHA-256 verified. Controlled by semantic_search_enabled setting (default true). model_downloader.rs in src-tauri. Dev script (tools/dev/download-embedding-model.sh) still available for CI/dev.

Development Environment

The app uses environment-aware paths to isolate dev/test data from production:

EnvironmentWorkspacesSettings File
Dev{project}/.data/workspaces/{project}/.data/settings.json
Production~/Inklings/Workspaces/~/Library/Application Support/Inklings/settings.json

Detection logic (in apps/desktop/src-tauri/src/paths.rs): debug builds (pnpm desktop:dev) → dev mode, release builds (pnpm desktop:build) → production mode.

The .data/ directory is git-ignored and can be cleared with ./tools/dev/reset-app-data.sh.

Was this page helpful?