Skip to content
Documentation GitHub
Getting Started

Getting Started

Status: Current Reference epics: INK-833, INK-837 ADRs: ADR-016, ADR-017

This is the entry page of the Codex. Two audiences land here:

  1. Worldbuilders reading the Codex to understand the product. You want to know what Inklings is as a system — what the world model is, how the World Agent participates, what the primitives are — before reading any implementation page.
  2. Contributors setting up the codebase. You want to clone, build, and run the app.

Both paths are below. Start with whichever matches you. The worldbuilder path is first because everything else in the Codex assumes that framing.


Inklings is a local-first workspace for building and maintaining a world. A workspace is a world: an authored body of connected content that the author owns, and that an embedded World Agent inhabits as a resident — not as a service the author talks to from the outside.

The shape of that world is described by a small set of primitives:

  • World Agent — the resident participant. One workspace, one world, one agent. It reads and writes through the same primitives the worldbuilder does, bound by the same capability system.
  • Zones — every piece of content lives in one of three zones: private (yours alone), candidate (proposed, not yet part of the canonical world), or canonical (accepted into the world). Zones are invisible to the casual reader; the agent’s behavior differs by zone.
  • Provenance — two stored axes (origin, lifecycle) and two derived signals (weight, standing) that describe where a piece of content came from and how settled it is.
  • Derivation links — explicit relations recording that one piece of content was derived from another. Feeds into standing.
  • Deviation records — first-class records of the moments where new content conflicts with existing canonical content. Not validation errors; part of the world’s state.
  • Retroactive revision — the flag-and-review mechanism for pulling old canonical content back under scrutiny when later content contradicts it. Not an automatic rewrite.
  • Submit boundary — the single domain mechanism every write flows through. Origin and lifecycle are stamped here; derivation and deviation side effects fire here.
  • Sandbox execution — the Wasmtime-sandboxed CPython executor, reached through MCP as a capability. Explicitly not the agent runtime.

The canonical entry into this surface is systems/world/index. If you are reading the Codex to learn the product, start there and follow the links.

systems/world/worked-example walks a fiction author building a magic system end-to-end through every primitive above. Each primitive page links back to the relevant section of that example. If a primitive page feels abstract, jump to the worked example and read its anchor.

The World Agent runs in a Python sidecar on LangGraph. It participates in the workspace through the same capability-scoped surfaces the human worldbuilder uses, through MCP. It does not have its own filesystem, its own memory layer outside the workspace, or its own boundary around the domain. Its memory tiers, skill subsystem, and scheduling hooks are all described in systems/agent — read those after you have read systems/world/, since they describe how the agent participates rather than what the world is.

  • systems/world/ — canonical primitives of the world model. Read first.
  • systems/agent/ — how the agent participates in those primitives.
  • systems/platform/ — cross-cutting platform services (event log, permissions, task runner, sidecar security, etc.).
  • systems/content/ — content primitives (pages, blocks, tags, import, etc.).
  • architecture/ — domain rules, entity catalog, database schema, identifier strategy, data flows.
  • specifications/ + e2e-specs/ — behavioral specs that double as the test suite’s source material.
  • Development Guides — contributor-facing how-tos pulled from docs/guides/, docs/solutions/, docs/reference/.

ADRs live at the repo root under docs/ADR/ and are referenced inline in prose.


Everything below is the codebase-level setup for contributors. Skip it if you are reading for product understanding.

Install all required tools before cloning.

Node.js >=22.0.0

Terminal window
node --version # must be v22+

Install via nvm or nodejs.org.

pnpm >=10.0.0

Terminal window
pnpm --version # must be v10+
npm install -g pnpm@10.30.1

Rust (latest stable)

Terminal window
rustc --version

Install via rustup.rs, then add required components:

Terminal window
rustup component add clippy rustfmt

gitleaks — required by pre-commit hook

Terminal window
gitleaks version
brew install gitleaks # macOS

dprint — Markdown formatter (table alignment, line wrapping)

Terminal window
dprint --version
brew install dprint # macOS

uv — Python package manager (required for apps/python-sidecar/)

Terminal window
uv --version
brew install uv # macOS (or https://docs.astral.sh/uv/)

macOS

Terminal window
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
Terminal window
git clone https://github.com/MasterCodeYoda/inklings.git
cd inklings
pnpm install
Terminal window
pnpm generate:types

This runs Specta to generate TypeScript types from Rust structs into packages/contracts/generated/. Run this before dev, build, or typecheck — without it, TypeScript will not find the generated types.

The Python sidecar hosts the World Agent runtime (LangGraph) and the sandboxed CPython executor. If you work on either, install the sidecar’s Python dependencies:

Terminal window
cd apps/python-sidecar
uv sync --group dev
cd ../..

This is only needed for sidecar development and testing. The desktop app uses a pre-built binary in production.

Terminal window
pnpm desktop:dev

This starts Vite (React frontend) and Tauri (Rust backend) together. On first run, Cargo compiles all Rust crates — expect a few minutes.

Terminal window
cargo test # Rust unit + integration tests
pnpm test # All tests via Turbo (includes frontend)

All tests should pass before you start making changes.

If you work on the LLM or agent subsystems, you can run the LLM integration tests against a local Ollama installation:

Terminal window
# macOS
brew install ollama
ollama pull nemotron-3-nano:30b # default model for integration tests
ollama serve # starts the server on localhost:11434

Then run the ignored tests:

Terminal window
cargo test -p core-tests --test llm_integration -- --ignored

Tests that cannot reach Ollama skip automatically — they never fail a clean CI run.

The app uses environment-aware paths so dev data never touches your real Inklings data:

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

Dev mode activates automatically for debug builds (pnpm desktop:dev). Release builds (pnpm desktop:build) use production paths.

To reset all dev app data:

Terminal window
./tools/dev/reset-app-data.sh # interactive
./tools/dev/reset-app-data.sh --force # skip confirmation
Terminal window
# Development
pnpm dev # All packages via Turbo
pnpm desktop:dev # Desktop app only (Vite + Tauri)
# Build
pnpm build # All packages
pnpm desktop:build # Desktop app only
# Types (run after modifying Rust structs)
pnpm generate:types
# Linting
pnpm lint # oxlint (TypeScript)
pnpm typecheck # TypeScript type checking
cargo clippy # Rust linting
cargo fmt # Rust formatting
# Testing
pnpm test # All tests
cargo test # Rust only
cargo test -p core-tests # Real SQLite integration tests

Polyglot modular monolith following Clean Architecture. Dependencies flow inward — enforced at compile time via separate crates:

Framework (src-tauri)
→ Infrastructure (sqlite, import)
→ Application (use cases + service traits)
→ Domain (pure entities)

The Python sidecar sits beside the Rust core as a separate process, reached via narrow IPC. The sidecar hosts the LangGraph-based World Agent runtime and the Wasmtime sandbox executor (see systems/world/sandbox-execution). The sidecar is not a second application layer — all domain writes route through the submit boundary on the Rust side.

See CONTRIBUTING.md for the full directory layout and development workflow.

PathWhat lives there
crates/domain/Pure business entities (no external deps)
crates/application/Use cases + repository traits
crates/infrastructure/sqlite/SQLite storage implementations
apps/desktop/src-react/React frontend (TypeScript)
apps/desktop/src-tauri/Tauri commands + app wiring
apps/python-sidecar/LangGraph World Agent runtime + sandbox executor host
packages/contracts/generated/Auto-generated Rust→TS types (do not edit)
tests/core/Real use cases wired to real SQLite
tests/e2e/Playwright tests; specs double as Codex behavioral docs

If you plan to work on cloud features (auth, sync, analytics), copy the environment template:

Terminal window
cp .env.example .env

Edit .env with your Supabase credentials.

  • CONTRIBUTING.md — full architecture overview, build reference, and development workflow.
  • Development guide — vertical slicing methodology, commit discipline, testing strategy.
  • Architecture — Domain Rules — business invariants enforced in Rust.
  • Voice guide — World Agent naming conventions, worldbuilder-audience tone, cross-link conventions used throughout the Codex.
  • Why we rebuilt — release-companion explainer for why the agent runtime, skill system, and provenance model were rebuilt.

On first workspace open, the app auto-downloads the embedding model (~585 MB) from HuggingFace. Download progress is streamed via Tauri events (embedding-model:download-progress). The model is SHA-256 verified before use. Semantic search is enabled by default (semantic_search_enabled setting). A dev script is also available for pre-downloading in CI or local dev:

Terminal window
./tools/dev/download-embedding-model.sh

The project uses oxlint for TypeScript linting. Run pnpm lint from the repo root to check for violations.

See the Clippy Idioms Catalog for common patterns and fixes.

”Database version is newer than app version”

Section titled “”Database version is newer than app version””

The workspace was created by a newer build. Update your local build or reset dev data:

Terminal window
./tools/dev/reset-app-data.sh --force

Was this page helpful?