Cheatsheet
Full command reference. Extracted from crates/onde-cli/src/cli.rs.
Binary: onde. Typed graph knowledge base. Terminal-native. Agent-first.
onde init
Create workspace from marketplace distro template.
onde init -t <distro> # short flag
onde init --template <distro> # long flag
onde init --list # browse available distros
onde init --search <query> # search by name, category, description
onde init --local <path> # load custom local distro
onde init -t <name> --dry-run # preview. no disk writes.
onde init -t <name> --force # init in non-empty workspace
What it creates: .onde/schema.md, SOUL.md, directory structure, starter nodes, journal/.
Fails if workspace non-empty (without --force). Idempotent. No overwrite.
See marketplace documentation for full spec: distro manifest, registry, publishing, lifecycle.
onde distro
Distro lifecycle management. Compare, upgrade, publish.
onde distro list # alias for onde init --list
onde distro check # compare workspace schema vs distro origin
onde distro diff # show schema diff vs latest distro version
onde distro upgrade --dry-run # preview merge of new fields
onde distro upgrade # merge new fields into existing schema
onde distro publish <path> # publish local distro to registry
onde distro publish --private <path> # private distro. invite-only.
Upgrade = merge new types/edges. Never deletes. Never overwrites nodes. Conflict = manual resolve.
onde lint
Validate + auto-generate + sync journal + materialize. Core command. Every workflow starts here.
onde lint # full pipeline
onde lint --watch # file watcher with debounce
onde lint --dry-run # preview, no writes
onde lint --fix # apply all auto-fixes
onde lint --syntax # syntax check only
onde lint --soft # warnings not errors
onde lint --no-materialize # skip MD rewrite
onde lint --diagnose # verbose pipeline debugging
onde lint --no-progress # hide progress bar
onde lint --progress # force progress bar
onde lint --fix-ids # auto-generate missing IDs only
onde lint --fix-mirrors # sync mirror nodes only
onde lint --continue-on-error # write valid files, report failures
onde lint --stage=parse # stop after parse
onde lint --stage=validate # stop after validate
onde lint --stage=materialize # stop after materialize
onde lint --no-query # skip embedded queries
onde lint --query-only # only refresh embedded queries
onde lint --clear-cache # force clear query result cache
Pipeline: parse → diff → merge → [validate, token-count] → auto-fix → [mirror-sync, query-refresh] → materialize.
onde find <type>
Query nodes by type + filters. Read-only. Loads head.bin directly.
onde find task # all tasks
onde find task --status BLOCKED # filter
onde find task --status BLOCKED --sort priority # sort
onde find task --group-by status # group
onde find task --group-by status --order "BLOCKED,DOING" # custom group order
onde find task --sort deadline --format md # format output
onde find task --format standard # standard node format
onde find task --format md-dense # dense outline
onde find task --format table # terminal table
onde find task --format json # JSON output
onde find task --format csv # CSV export
onde find task --format mermaid # mermaid diagram
onde find task --format dot # Graphviz DOT
onde find task --format tsv # tab-separated
onde find task --format lines # one line per node
onde find task --format tree # tree view
onde find task --no-group # flat, no grouping
onde find task --no-sort # raw insertion order
onde find task --as-of 2026-04-05T12:00 # point-in-time query
onde find task --changed-between 2026-04-01 2026-04-07 # time-range scan
onde find task --in apr5 # query within saved view
onde find task --fields id,title,status # select columns
onde find task --fields "ID:id,Task:title" # rename columns
onde find task --no-body # exclude body text
onde find task --no-links # exclude [[links]]
onde find task --cols "id,title,status" # column layout for dense
onde find task --meta # HTML comment metadata
onde find task --agg count # aggregation
onde find task --agg "avg priority" # average aggregation
onde find task --agg "count, avg priority, sum points" # multi-agg
onde find task --filter status BLOCKED # generic filter
onde find task --limit 10 # limit results
onde find task --offset 20 # skip results
onde find task --case-sensitive # case-sensitive string sort
onde find task --dense-title "My Title" # custom dense heading
onde find task --edge-keys "depends,assigned" # edge keys as arrays in JSON
onde find task --graph-name "MyGraph" # DOT graph name
onde find task --output results.json # output to file
onde find task --output "report.html:html" # output with format override
onde find task --output-config batch.yaml # batch output from YAML
onde find task --direction TD # graph direction (LR/TD/RL)
onde find task --edge-labels # show edge labels in graph
onde find task --node-props "status,priority" # show node props in graph
Schema defaults apply when no flags given (@sort, @group, @default-display).
onde q <query>
Query DSL. Pipes. Variables. Multi-hop. Negation. Set operations.
onde q 'task | group by status | count'
onde q 'task[status=BLOCKED] >depends> task[status=TODO]'
onde q 'person <owns< task[status=TODO] | group by person | count'
onde q 'task NOT >depends> task'
onde q '$p = person <owns< task[status=TODO]'
Flags mirror find: --format, --output (single file only), --stream, --as-of, --no-body, --meta, --fields, --no-links, --cols, --direction, --edge-labels, --node-props, --edge-keys, --dense-title, --graph-name.
onde deps <id>
Outgoing depends edges. Depth-limited traversal.
onde deps task-882
onde deps task-882 --depth 3
onde deps task-882 --as-of 2026-04-05
onde deps task-882 --in apr5
onde deps task-882 --format mermaid
onde deps task-882 --output deps.md
onde deps task-882 --direction TD
onde deps task-882 --edge-labels
onde deps task-882 --node-props "status,priority"
onde deps task-882 --graph-name "Deps"
onde deps task-882 --edge-keys "depends,assigned"
Follows only depends edges.
onde depended-by <id>
Incoming depends edges. Reverse of deps.
onde depended-by task-882
onde depended-by task-882 --depth 3
onde depended-by task-882 --as-of 2026-04-05
onde depended-by task-882 --in apr5
onde depended-by task-882 --format mermaid
onde depended-by task-882 --output rev.md
Same flags as deps.
onde ancestors <id>
Full upstream tree. Follows ALL edge types.
onde ancestors task-882
onde ancestors task-882 --depth 5
onde ancestors task-882 --as-of T
onde ancestors task-882 --in viewname
onde ancestors task-882 --format tree
Same flags as deps.
onde descendants <id>
Full downstream tree. Follows ALL edge types.
onde descendants task-882
onde descendants task-882 --depth 5
Same flags as deps.
onde path <from> <to>
Shortest path between two nodes. Follows ALL edge types.
onde path task-882 task-895
onde path task-882 task-895 --as-of T
onde path task-882 task-895 --in viewname
onde path task-882 task-895 --format mermaid
Same flags as deps.
onde impact <id>
All nodes reachable from target. Follows ALL edge types.
onde impact task-882
onde impact task-882 --as-of T
onde impact task-882 --in viewname
onde impact task-882 --format tree
Same flags as deps.
onde stats
Aggregate statistics. Read-only.
onde stats # all types
onde stats --by status # group by property
onde stats --project alpha # filter by project
onde stats task # specific type
onde stats --format json # output format
onde stats --output stats.json # output to file
onde diff
Graph-level diff when journal exists (shows node/edge changes). Falls back to file diff for non-onde repos (unified text diff of .md files).
onde diff # uncommitted changes (MD vs journal)
onde diff HEAD~3 HEAD # diff between git refs
onde diff --view apr5 --vs apr7 # diff two saved views
onde types
List node types. Show type metadata.
onde types # all types
onde types --orphans # types with zero instances
onde organize
Reformat, sort, group, split, merge, move files. gofmt for knowledge graphs.
onde organize # reformat workspace
onde organize --watch # auto-format on save
onde organize --split # split multi-node files
onde organize --merge # merge single-node files
onde organize --dirs # move to schema dirs
onde organize --rename # apply naming conventions
onde organize --dry-run # preview
onde organize --diff # show changes
onde organize --group-by status # group nodes
onde organize --sort priority # sort nodes
onde organize --format dense # output format
onde organize --into output/ # output directory
onde organize --naming kebab # naming pattern
onde organize --remove-sources # remove original after merge
onde organize --type task # specific node type
onde organize --output result.md # output to file
onde organize --force # overwrite existing
onde organize --debounce-ms 500 # watcher debounce
onde organize path/to/file.md # specific paths
onde organize tasks/ decisions/ # specific directories
onde organize "**/*.md" # glob pattern
onde relink
Convert link modes. Audit link distribution.
onde relink --to id # all links → ID mode
onde relink --to title # all links → title mode
onde relink --to path # all links → full path mode
onde relink --to relative # all links → relative path mode
onde relink --scope workspace # entire workspace (default)
onde relink --scope file --scope-value tasks/active.md
onde relink --scope directory --scope-value tasks/
onde relink --scope type --scope-value task
onde relink --audit # stats only, no changes
onde relink --dry-run # preview changes
onde materialize
Rebuild MD files from journal. Full or partial.
onde materialize # rebuild all MD from journal
onde materialize --type task # rebuild only task files
onde materialize --dry-run # preview
onde materialize --format dense # force dense output
onde materialize --check # verify MD matches journal (no writes)
onde journal
Journal management subcommands.
onde journal status # health, agent stats, op count
onde journal show task-882 # op history for a node
onde journal verify # check ops.md integrity
onde journal compact # snapshot + archive (history preserved)
onde journal compact --keep 100 # retain last 100 ops in fresh ops.md
onde snapshot
Snapshot management subcommands.
onde snapshot export # full graph state as JSON
onde snapshot export --format json # export snapshot as JSON
onde snapshot export > snap.json # save to file
onde snapshot diff <a> <b> # graph diff between two snapshots
onde schema
Schema management subcommands.
onde schema # show current schema
onde schema --json # JSON output
onde schema extract # infer schema from existing nodes
onde schema show # display parsed schema
onde schema diff # diff schema vs graph
onde schema dirs # show directory rules
onde schema dirs --suggest # suggest directory layout
onde migrate
Schema version migration.
onde migrate --from 5 --to 6 # migrate directives v5 → v6
onde migrate --from 5 --to 6 --dry-run
onde git
Git integration subcommands. Thin wrappers. Stages only onde files.
onde git commit # generate message from ops, stage, commit
onde git status # changes in .onde/ + staged workspace .md files
onde git push # git push
onde git log # git log with onde messages (last 20, oneline)
onde git log --oneline # oneline format (default)
onde git log --oneline=false # full format via --oneline=false
onde git log --full # full (medium) format instead of oneline
onde git log --count 50 # show last 50 entries (default: 20)
onde tree
File tree view. Directory structure.
onde tree # workspace tree
onde tree tasks/ # specific path
onde tree --by type # group by node type
onde tree --over-budget # show files over token budget
onde tree --depth 3 # max depth
onde tree --format json # output format
onde history <id>
Full change timeline for a node.
onde history task-882 # timeline output
onde history task-882 --format timeline
onde history --graph task-882 # evolving relationship diagram
onde history task-882 --from 2026-04-01 --to 2026-04-07
onde history task-882 --graph --from T1 --to T2
onde temporal
Temporal index management subcommands.
onde temporal init # create .onde/temporal/ and .onde/snapshots/
onde temporal index # show temporal index status
onde temporal stats # coverage, segment count, snapshot count
onde temporal rebuild # full index + snapshot rebuild
onde temporal backfill # populate temporal index from journal ops
onde temporal gc # garbage-collect unreferenced objects
onde temporal gc --dry-run # preview GC
onde temporal changed-between 2026-04-01 2026-04-07 # nodes modified in range
onde view
Read-only temporal views. No persistence. No side effects.
onde view --at 2026-04-05T12:00 --name apr5 # create named view
onde view --list # list active views
Query within views via --in flag on find/deps/ancestors/etc.
onde dashboard
Team dashboard. Aggregated task + decision view.
onde dashboard # full dashboard
onde dashboard --team frontend # filter by team
onde dashboard --format md # output format
onde dashboard --output dash.md # output to file
onde dashboard --no-group # disable grouping
onde dashboard --limit 10 # max decisions
onde dashboard --offset 5 # skip decisions
onde restore
Revert graph to past state. Write operation. Creates forward-moving ops.
onde restore --at 2026-04-05T12:00 --reason "Reverting broken migration"
Embedded Query Syntax (onde::)
Inline queries in markdown. Auto-refreshed by onde lint.
onde:: <command or query> [--fields ...] [--format ...] [--with ...]
onde:: find task --status BLOCKED --sort priority
onde:: q 'task | group by status | count'
onde:: task[status=BLOCKED] >depends> task[status=TODO]
onde:: deps task-882
onde:: impact task-882 --format tree
onde:: path task-882 task-895
Supported flags: --fields, --format, --with, --max-eager-depth, --max-depth, --group-by.
Formats: list (default), dense, table, tree, cards, timeline, nested, mermaid, csv, json.
Bidirectional when --fields specified. Edit result → source updates → cascade.
Output Formats
| Format | Flag | Description |
|---|---|---|
| Standard | --format standard | Full node output |
| Dense outline | --format md-dense | TOON pipe-delimited |
| Markdown | --format md | Grouped markdown |
| Table | --format table | Terminal grid |
| JSON | --format json | JSON + JSON lines |
| CSV | --format csv | Comma-separated |
| TSV | --format tsv | Tab-separated |
| Lines | --format lines | One line per node |
| Mermaid | --format mermaid | Mermaid diagram |
| DOT | --format dot | Graphviz DOT |
| Tree | --format tree | Hierarchical tree |
| SVG | --format svg | SVG diagram |
| HTML | --format html | (not yet implemented) |
Common Flags (shared across commands)
| Flag | Available On | Description |
|---|---|---|
--as-of T | find, q, deps, depended-by, ancestors, descendants, path, impact | Point-in-time query |
--in VIEW | find, deps, depended-by, ancestors, descendants, path, impact | Query within saved view |
--format F | find, q, deps, depended-by, ancestors, descendants, path, impact, stats, organize, tree | Output format |
--output PATH | find, q, deps, depended-by, ancestors, descendants, path, impact, stats, dashboard | Output to file |
--direction D | find, q, deps, depended-by, ancestors, descendants, path, impact | Graph direction (LR/TD/RL) |
--edge-labels | find, q, deps, depended-by, ancestors, descendants, path, impact | Show edge labels |
--node-props | find, q, deps, depended-by, ancestors, descendants, path, impact | Show node properties in graph |
--graph-name | find, q, deps, depended-by, ancestors, descendants, path, impact | DOT graph name |
--edge-keys | find, q, deps, depended-by, ancestors, descendants, path, impact | Edge keys as JSON arrays |
--depth N | deps, depended-by, ancestors, descendants, tree | Traversal/tree depth |
--dry-run | lint, organize, relink, materialize, migrate, temporal gc, init | Preview, no writes |
Command Pipeline Map
| Command | Mutates? | Pipeline |
|---|---|---|
onde init | Yes | Fetch distro → validate manifest → create schema + SOUL.md + dirs + nodes + journal |
onde distro | Mixed | check/diff = read-only; upgrade/publish = mutates schema or registry |
onde lint | Yes | Parse → diff → merge → validate → auto-fix → materialize |
onde find | No | Load head → query → output |
onde q | No | Load head → DSL eval → output |
onde deps/depended-by/ancestors/descendants/path/impact | No | Load head → traverse → output |
onde stats | No | Load head → aggregate → output |
onde diff | No | Load head → compare → graph diff |
onde types | No | Load head → list types |
onde organize | Yes | Load head → sort/group → materialize |
onde relink | Yes | Load head → rewrite links → diff → materialize |
onde materialize | Yes | Load head → write MD |
onde journal | Yes | Journal ops (status/show = read-only) |
onde snapshot | Yes | Export/diff snapshots |
onde schema | No | Parse/display schema |
onde migrate | Yes | Convert directives |
onde git | Yes | Git operations |
onde tree | No | Directory listing |
onde history | No | Journal scan → timeline |
onde temporal | Yes | Index management |
onde view | No | In-memory temporal view |
onde dashboard | No | Aggregate queries → output |
onde restore | Yes | Create forward ops to revert |
Terminal DSL Cheatsheet — Agent Navigation Toolkit
Raw terminal tools for navigating, querying, transforming onde markdown files. Use when onde binary unavailable, scripting bulk ops, or exploring repo structure directly. Caveman style: terse, no fluff.
grep — Find Patterns in MD Files
Find all node IDs of a given type:
rg 'type:: task' doc/ tasks/ --no-filename -l # files containing task nodes
rg 'id:: task-' doc/ tasks/ --no-filename # all task IDs
rg '^id::' doc/ tasks/ -n # all IDs with line numbers
Find nodes by property value:
rg 'status:: BLOCKED' tasks/ --no-filename -l # files with blocked tasks
rg 'status:: (TODO|DOING)' tasks/ --no-filename # regex match multiple values
rg 'priority:: A' tasks/ -n # high priority with line numbers
rg 'assigned:: \[\[sarah-chen\]\]' tasks/ # edge to specific node
Find edges and link targets:
rg '\[\[.*\]\]' tasks/ --no-filename -n # all wiki-links with locations
rg 'depends::' tasks/ --no-filename -n # depends edges
rg 'blocks::' tasks/ --no-filename -n # blocks edges
rg '\{.*:.*\}' tasks/ --no-filename -n # edge properties in braces
rg 'depends:: \[\[.*\]\].*\{' tasks/ # depends edges with properties
Find dense outline blocks:
rg ':: task\[' doc/ tasks/ -n # dense headers with type
rg '^\s*- .*|' tasks/ -n # pipe-delimited dense rows
rg ':: task\[\d+\]' doc/ tasks/ # dense headers with count hint
rg '@sort:' doc/ tasks/ -n # sort directives
rg '@group:' doc/ tasks/ -n # group directives
rg 'by .*::' tasks/ -n # group-by clauses
Find schema definitions:
rg '^### ' schema.md -n # all schema sections
rg 'edge\(' schema.md -n # edge properties in schema
rg '@default\(' schema.md -n # default generators
rg '@inverse\(' schema.md -n # inverse declarations
rg '@required' schema.md -n # required fields
rg '@mirror-' schema.md -n # mirror directives
rg '\*\*/:.*ignore' schema.md -n # ignored directories
Find embedded queries:
rg 'onde::' doc/ tasks/ -n # all embedded queries
rg 'onde::.*BLOCKED' tasks/ -n # queries filtering blocked
rg 'onde::.*group by' tasks/ -n # aggregation queries
Find headings as node titles (Mode 1):
rg '^## ' doc/ tasks/ -n # all H2 headings (node titles)
rg '^## .*::' doc/ tasks/ -n # headings with type declaration
rg '^### ' doc/ tasks/ -n # H3 sub-headings
Cross-file search with context:
rg 'status:: BLOCKED' tasks/ -C 2 # 2 lines context around match
rg 'id:: task-882' . -n # find specific node anywhere
rg 'task-882' . --type md -n # any mention of this ID
rg -l 'task-882' . --type md # files mentioning this ID
sed — Transform MD Files In-Place
Replace property values across files:
# Change status BLOCKED → TODO in all task files
sed -i 's/^status:: BLOCKED$/status:: TODO/' tasks/*.md
# Change priority A → B in specific file
sed -i 's/^priority:: A$/priority:: B/' tasks/fix-token-refresh.md
# Replace assigned person across workspace
sed -i 's/assigned:: \[\[sarah-chen\]\]/assigned:: \[\[mike-walker\]\]/' tasks/*.md
Rename edge type across all files:
# Rename depends → requires
sed -i 's/^depends::/requires::/' tasks/*.md doc/*.md
sed -i 's/>depends>/>requires>/g' tasks/*.md doc/*.md # in embedded queries
sed -i 's/<depends</<requires</g' tasks/*.md doc/*.md # reverse traversal
sed -i 's/{depends:/{requires:/g' tasks/*.md doc/*.md # edge properties in braces
Add missing property to nodes:
# Add points:: 0 after deadline line if missing
sed -i '/^deadline::/a points:: 0' tasks/*.md
# Add description:: after id:: line
sed -i '/^id:: task-/a description:: ' tasks/*.md
# Insert property after specific line in single file
sed -i '/^status::/a urgency:: low' tasks/fix-token-refresh.md
Delete property from all files:
# Remove deprecated property
sed -i '/^urgency::/d' tasks/*.md
# Remove all blank description lines
sed -i '/^description::$/d' tasks/*.md
Transform heading + type line:
# Add type declaration to heading-only nodes
sed -i 's/^## \(.*\)$/## \1\ntype:: note/' notes/*.md
# Change node type from note to decision
sed -i 's/^type:: note$/type:: decision/' decisions/*.md
Fix link format:
# Convert title links to ID links (manual single-file)
sed -i 's/\[\[sarah-chen\]\]/[[person-042]]/' tasks/fix-token-refresh.md
# Remove broken links (orphan targets)
sed -i '/depends:: \[\[task-999\]\]/d' tasks/*.md
# Convert path links to relative
sed -i 's|blocks:: \[\[/tasks/\(.*\)\]\]|blocks:: [[./\1]]|' tasks/*.md
Update dense outline rows:
# Change status column (3rd column) in dense rows
sed -i 's/^\(\s*-\s*[^|]*|[^|]*|\s*\)BLOCKED/\1TODO/' tasks/sprint-backlog.md
# Replace person in 4th column of dense rows
sed -i 's/|\s*\[\[sarah-chen\]\]\s*|/|[[mike-walker]]|/' tasks/active-tasks.md
# Add edge property to last column of dense row
sed -i 's/|\s*task-890\s*$/| task-890 {critical: true}/' tasks/sprint-backlog.md
Update schema directives:
# Bump schema version
sed -i 's/^version: \d$/version: 7/' schema.md
# Add new enum value to existing enum
sed -i '/^values: TODO DOING DONE/a values: TODO DOING DONE REVIEW' schema.md
# Change ID default strategy
sed -i 's/@default(counter(prefix: "task", pad: 3))/@default(kebab)/' schema.md
Multi-line sed (GNU):
# Swap two property lines
sed -i '/^status::/{n;s/^priority::/TEMP_PROP/;h;s/^.*$/NEW_PRIORITY/;x;G;s/TEMP_PROP\n/status::/;s/NEW_PRIORITY/priority::/;}' tasks/*.md
# Delete everything between two markers (inclusive)
sed -i '/^## Temp Section$/,/^---$/d' scratch/*.md
awk — Parse Dense Pipe Rows
Extract columns from TOON dense outline (pipe-delimited):
# Column indices from header: {id title status priority}
# Print only ID and status (cols 1,3 after stripping dash prefix)
awk -F'|' '/^ *-/{gsub(/^[ \t-]+/,"",$1); gsub(/ /,"",$1); print $1, "|", $3}' tasks/sprint-backlog.md
# Count rows per group (by status)
awk -F'|' '/^ *-/{
for(i=1;i<=NF;i++){
gsub(/^[ \t-]+/,"",$i);
gsub(/ +$/,"",$i)
};
status[$3]++
} END {
for(s in status) print s, status[s]
}' tasks/sprint-backlog.md
# Filter dense rows where status is BLOCKED
awk -F'|' '/^ *-/ && $3 ~ /BLOCKED/ {print}' tasks/sprint-backlog.md
# Extract node IDs from dense rows
awk -F'|' '/^ *-/{gsub(/^[ \t-]+/,"",$1); gsub(/ +$/,"",$1); print $1}' tasks/active-tasks.md
# Find dense rows with edge properties (contains { })
awk -F'|' '/{/{print NR": "$0}' tasks/*.md
Parse Mode 1 properties:
# Extract all property key-value pairs from a node file
awk '/^[a-z_]+::/{print}' tasks/fix-token-refresh.md
# Get specific property value
awk -F':: ' '/^status::/{print $2}' tasks/fix-token-refresh.md
# Extract edge targets (wiki-links)
awk -F':: ' '/depends::|assigned::|blocks::/{print $2}' tasks/fix-token-refresh.md
# Extract heading (node title)
awk -F'# ' '/^## /{print $2; exit}' tasks/fix-token-refresh.md
Aggregate across files:
# Count nodes per type across workspace
rg '^type:: ' doc/ tasks/ people/ decisions/ -o | sort | uniq -c | sort -rn
# Count total task nodes
rg -c '^type:: task$' doc/ tasks/ 2>/dev/null | awk -F: '{s+=$NF}END{print s}'
# List all unique IDs in workspace
rg '^id:: ' . --type md -o | sort -u
Combinations — Pipelines
Grep + sed: find then transform:
# Find all BLOCKED tasks, change to IN_PROGRESS
rg -l 'status:: BLOCKED' tasks/ | xargs sed -i 's/^status:: BLOCKED$/status:: IN_PROGRESS/'
# Find files linking to deleted node, remove those links
rg -l '\[\[task-999\]\]' tasks/ | xargs sed -i '/\[\[task-999\]\]/d'
# Find all task files missing points property, add it
rg -L 'points::' tasks/ | xargs sed -i '/^deadline::/a points:: 0'
Find + awk: query then extract:
# List all task IDs with BLOCKED status (property-based files)
rg -l 'type:: task' tasks/ | xargs awk '/^status:: BLOCKED/{f=FILENAME} /^id::/{if(f==FILENAME) print $2}'
# Extract all dense row IDs from a specific file
awk -F'|' '/^ *-/{gsub(/^[ \t-]+| +$/,"",$1); print $1}' tasks/sprint-backlog.md
# Count nodes by type from all MD files
rg '^type:: ' . --type md -o | awk '{count[$2]++} END{for(t in count) print count[t], t}' | sort -rn
rg + sed + sort: bulk rename:
# Rename all references from old ID to new ID
rg -l 'task-001' tasks/ doc/ | xargs sed -i 's/task-001/task-1001/g'
# Rename edge type everywhere
rg -l 'depends::' tasks/ doc/ | xargs sed -i 's/depends::/requires::/g'
rg -l '>depends>' tasks/ doc/ | xargs sed -i 's/>depends>/>requires>/g'
rg -l '<depends<' tasks/ doc/ | xargs sed -i 's/<depends</<requires</g'
find + xargs: file-level ops:
# Find all MD files modified in last 24h, show node types
find . -name '*.md' -mtime -1 -not -path './.onde/*' | xargs rg '^type:: ' -o
# Count properties per file
find tasks/ -name '*.md' | while read f; do echo "$f: $(rg -c ':: ' "$f")"; done
# Find largest MD files by line count
find tasks/ -name '*.md' -exec wc -l {} + | sort -rn | head -20
rg + sort + uniq: analytics:
# Most common property names
rg '^[a-z_]+::' . --type md -o | sort | uniq -c | sort -rn | head -20
# Most linked nodes
rg '\[\[([a-z]+-[0-9]+)\]\]' . --type md -o | sort | uniq -c | sort -rn | head -20
# Files with most wiki-links
rg -c '\[\[' . --type md | sort -t: -k2 -rn | head -20
# Enumerate all unique node types
rg '^type:: ' . --type md -o | sort -u
sed multi-step (using temp file for complex transforms):
# Swap two property values: rename field AND rewire edges
for f in $(rg -l '^type:: task$' tasks/); do
sed -i \
-e 's/^severity:: P0$/severity:: P1/' \
-e 's/^priority:: A$/priority:: B/' \
-e 's/\[\[sarah-chen\]\]/[[mike-walker]]/g' \
"$f"
done
Complex Cases
Extract graph structure from markdown into adjacency list:
# Build adjacency list: source -> target (edge type)
awk '
/^[a-z_]+:: \[\[.*\]\]/{
split($0, a, ":: ")
split(a[2], b, "[[")
split(b[2], c, "]]")
edge=a[1]; target=c[1]
if(edge && target) print edge, target
}
' tasks/*.md doc/*.md | sort -u
Migrate property format (e.g., date normalization):
# Normalize all date properties to ISO 8601
sed -i 's/^deadline:: \([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\)$/deadline:: \1T00:00:00Z/' tasks/*.md
sed -i 's/^decided_at:: \([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\)$/decided_at:: \1T00:00:00Z/' decisions/*.md
Split a multi-node dense file into individual Mode 1 files:
awk '
/^## /{ if(id) {close(fname); id=""} }
/^id::/{ id=$2; gsub(/ /,"",id); fname="tasks/"id".md"; print "---" > fname; print "type:: task" >> fname; print "id:: "id >> fname }
/^[a-z_]+::/{ if(id) print $0 >> fname }
' tasks/sprint-backlog.md
Find orphan links (targets that don’t exist as files or IDs):
# Extract all link targets
rg -o '\[\[([^\]]+)\]\]' tasks/ doc/ --no-filename | sed 's/\[\[\(.*\)\]\]/\1/' | sort -u > /tmp/links.txt
# Extract all IDs
rg -o '^id:: (.+)' . --type md --no-filename | awk '{print $2}' | sort -u > /tmp/ids.txt
# Find links with no matching ID
comm -23 /tmp/links.txt /tmp/ids.txt
Convert Mode 2 dense rows to Mode 1 files:
awk -F'|' '
/^## /{ heading=$0; gsub(/^## /,"",heading) }
/^ *-/{
gsub(/^[ \t-]+/,"",$1); gsub(/ +$/,"",$1);
id=$1; gsub(/ +$/,"",id);
fname="tasks/"id".md";
print "## "heading > fname;
print "type:: task" >> fname;
print "id:: "id >> fname;
close(fname)
}
' tasks/sprint-backlog.md
Detect schema violations without onde:
# Find required property missing (status field absent in task files)
rg -l '^type:: task$' tasks/ | while read f; do
rg -q '^status::' "$f" || echo "MISSING status: $f"
done
# Find enum violations (status not in allowed set)
rg '^status::' tasks/ -o | grep -v 'status:: \(TODO\|DOING\|DONE\|BLOCKED\|CANCELLED\)$'
# Find dense count mismatch
awk '/:: task\[([0-9]+)\]/{match($0,/\[([0-9]+)\]/,m); expected=m[1]; count=0}
/^ *-/{count++}
/^$/{if(expected>0 && count!=expected) print "COUNT MISMATCH: expected "expected" got "count}' tasks/*.md
Audit workspace health:
# Count files per directory
find tasks/ people/ decisions/ -name '*.md' | sed 's|/[^/]*$||' | sort | uniq -c
# Files with no type declaration (potentially invalid)
rg -L '^type:: ' . --type md | grep -v '.onde/' | grep -v 'readme.md' | grep -v 'schema.md'
# Files with no id (valid for dense-only, suspicious for Mode 1)
rg -L '^id:: ' . --type md | grep -v '.onde/'
# Total token estimate (rough: 1 token ~ 4 chars)
find . -name '*.md' -not -path './.onde/*' -exec cat {} + | wc -c | awk '{print int($1/4), "tokens (estimate)"}'
Bulk property rename across schema + files:
# Step 1: rename in schema.md
sed -i 's/^assigned:/assignee:/' schema.md
sed -i 's/@inverse(owns)/@inverse(owned)/' schema.md
# Step 2: rename in all MD node files
rg -l '^assigned::' tasks/ | xargs sed -i 's/^assigned::/assignee::/'
# Step 3: rename in embedded queries
rg -l '>assigned>' tasks/ doc/ | xargs sed -i 's/>assigned>/>assignee>/g'
rg -l '<assigned<' tasks/ doc/ | xargs sed -i 's/<assigned</<assignee</g'
# Step 4: rename in edge type definitions
sed -i 's/^assigned:/assignee:/' schema.md
Generate TOC from markdown structure:
awk '/^## /{level=2; gsub(/^#+ /,""); printf "%*s%s\n", (level-2)*2, "", $0}
/^### /{level=3; gsub(/^#+ /,""); printf "%*s%s\n", (level-2)*2, "", $0}' doc/cli-cmd.md
Extract frontmatter from schema:
awk '/^---$/{if(reading) reading=0; else reading=1; next} reading{print}' schema.md
Batch-file property injection from CSV mapping:
# CSV: id,new_status
# tasks.csv: task-882,IN_PROGRESS
while IFS=, read -r id status; do
file=$(rg -l "^id:: $id$" tasks/ 2>/dev/null | head -1)
[ -n "$file" ] && sed -i "s/^status:: .*/status:: $status/" "$file"
done < tasks.csv
Mirror node template expansion (manual):
# Given mirror regex, expand template for matched nodes
rg -o '(?<=task-)\d+' tasks/*.md | sort -u | while read num; do
id="task-$num"
title=$(awk -F':: ' -v id="$id" '$2==id{found=1} found && /^## /{print $2; exit}' tasks/*.md)
status=$(rg "^status:: " tasks/$id.md -o | awk '{print $2}')
echo "**${title}** \`${id}\` · ${status}"
done