Skip to content

DEMO — the full loop in exact commands

Everything below runs from the repo root on Linux/macOS with stable Rust. outcrop = target/debug/outcrop; build it once:

cargo build -p outcrop-cli
alias outcrop="$PWD/target/debug/outcrop"

1. Seed a corpus

The deterministic OKF v0.2 sample bundle is committed at fixtures/corpus (regenerable byte-identically with cargo run -p corpus-gen). Work on a copy:

cp -r fixtures/corpus /tmp/bundle
outcrop --root /tmp/bundle init --yes

--yes skips the confirmation init shows before importing an existing, non-empty directory into a new workspace; drop it to see the prompt when running this interactively (a plain outcrop --root /tmp/bundle init also works unattended, since the prompt only appears at a real terminal).

2. Query

outcrop --root /tmp/bundle query "SELECT count(*) AS n FROM projects"
outcrop --root /tmp/bundle query "SELECT name, status, priority FROM projects WHERE status = 'active' LIMIT 5"
outcrop --root /tmp/bundle query "SELECT _path, score FROM search('watcher debounce') LIMIT 3"
outcrop --root /tmp/bundle query "SELECT source, target, depth FROM neighbors('projects/project-aurora', 2) LIMIT 10"
outcrop --root /tmp/bundle query "SELECT section_overview FROM projects WHERE _path = 'projects/project-basalt.md'"

3. Edit in Obsidian (or any external editor) → change is detected

Simulate an external editor touching a file directly:

sed -i '' -e 's/^team: research$/team: platform/' /tmp/bundle/people/guido-milner.md 2>/dev/null \
  || sed -i 's/^team: research$/team: platform/' /tmp/bundle/people/guido-milner.md
outcrop --root /tmp/bundle pending          # shows: modified people/guido-milner.md
outcrop --root /tmp/bundle adopt -m "Guido moved to platform"
outcrop --root /tmp/bundle query "SELECT team FROM people WHERE _path = 'people/guido-milner.md'"

External edits are first-class: pending surfaces them, adopt records them in History, discard restores the committed state byte-identically. (The embedded file watcher does the same detection live inside the server — external writes never lock anyone out and never corrupt.)

4. Create a scenario and diverge

outcrop --root /tmp/bundle scenario create reorg-draft
outcrop --root /tmp/bundle set projects/project-aurora.md status=paused --scenario reorg-draft -m "Pause Aurora in draft"
outcrop --root /tmp/bundle set projects/project-aurora.md status=done -m "Aurora shipped on main"
outcrop --root /tmp/bundle scenario diff reorg-draft   # field-level: status active->paused vs main

Snapshot isolation, visibly:

outcrop --root /tmp/bundle query "SELECT status FROM projects WHERE name = 'Project Aurora'" --scenario reorg-draft   # paused
outcrop --root /tmp/bundle query "SELECT status FROM projects WHERE name = 'Project Aurora'"                          # done

5. Propose a merge, hit a conflict, resolve it

outcrop --root /tmp/bundle merge reorg-draft
# -> 1 conflict: projects/project-aurora.md field `status` (mine: done, theirs: paused); exit 1
outcrop --root /tmp/bundle merge reorg-draft --keep 'projects/project-aurora.md:status=mine'
outcrop --root /tmp/bundle query "SELECT status FROM projects WHERE name = 'Project Aurora'"   # done (kept mine)
outcrop --root /tmp/bundle history

Edits to different fields of the same record auto-merge with no conflict. A merge whose result violates a folder schema still completes — the records land on the needs-attention list instead (constraints flag, never corrupt).

6. Constraint tools

outcrop --root /tmp/bundle validate            # all 11 planted corpus violations, grouped
outcrop --root /tmp/bundle validate projects   # 5 violations; exit code 1
outcrop --root /tmp/bundle set projects/project-basalt.md status=bogus -m nope
# -> blocked by folder policy (projects/_schema.yaml: policy: block); file untouched; exit 1

7. Snapshots and restore

outcrop --root /tmp/bundle snapshot before-experiments
outcrop --root /tmp/bundle set projects/project-basalt.md priority=1 -m "Experiment"
outcrop --root /tmp/bundle get projects/project-basalt.md --snapshot before-experiments   # old value, no checkout
outcrop --root /tmp/bundle history      # copy an ENTRY_ID
outcrop --root /tmp/bundle restore <ENTRY_ID>   # restores as a new History entry

8. MCP (agents)

outcrop --root /tmp/bundle mcp

Speak newline-delimited JSON-RPC on stdio (protocol 2024-11-05), e.g.:

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"demo","version":"0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"query","arguments":{"sql":"SELECT count(*) FROM notes"}}}

Or register it with Claude Code (.mcp.json):

{"mcpServers": {"outcrop": {"command": "/path/to/outcrop", "args": ["--root", "/tmp/bundle", "mcp"]}}}

The scripted end-to-end session used to verify this (query → scenario → upsert → isolation check → diff → merge → validate) is recorded in RUNLOG.md.

9. The engine + macOS canvas

No server to start — the canvas spawns-or-adopts the shared engine for the bundle over a Unix socket (docs/ENGINE.md). On a Mac (needs Xcode toolchain; see clients/apple/README.md for the one-time protoc generation step):

cargo build -p outcrop-cli --release
export OUTCROP_BIN="$PWD/target/release/outcrop"
export OUTCROP_ROOT=/tmp/bundle
cd clients/apple && swift run OutcropCanvas

outcrop --root /tmp/bundle engine status shows the engine the canvas started (version, uptime, attached clients); it lingers briefly after the canvas quits, then goes away on its own. outcrop engine stop retires it early. TCP (outcrop serve --grpc <addr>) remains an explicit opt-in for remote use.

Add a query card and a graph card, then flip the scenario picker between main and reorg-draft — every card re-renders against the selected scenario: same canvas, two data states, side by side.

Record card (authoring v1)

Toolbar → Add Record Card → ⏎ loads projects/project-aurora.md → Edit → change status to paused → Save → card shows Saved; re-run a query card to see the new value. Set status to bogus → Save → the card explains the block (the projects folder's rules) and keeps your edits. Flip the scenario picker → the card re-loads that scenario's version of the record.

Canvas UI (refined)

In the canvas: ⌘E toggles the Explorer; search the bundle from the sidebar and click a hit to open its record card; ⌘1/⌘2/⌘3 (or the right-edge palette) add cards at the visible center; drag a card (no jump-to-cursor, lands on top); pinch or ⌘+/⌘−/⌘0 to zoom; ⌘S saves — watch "Saved just now" in the toolbar.

Canvas unit tests: cd clients/apple && swift test (run the protoc generation step first — see clients/apple/README.md).

Coming: the on-demand engine

The manual serve --grpc step above is being replaced by a shared on-demand engine (see docs/ENGINE.md): any client — canvas, MCP, CLI — finds or starts one engine per bundle over a Unix socket, and it winds itself down ~45s after the last client leaves. outcrop engine status will show who's attached.