@kitelev/exocortex-cli 16.80.1 → 16.80.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +507 -783
  2. package/dist/index.js +3 -3
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,904 +1,724 @@
1
- # @exocortex/cli
1
+ # @kitelev/exocortex-cli
2
2
 
3
- Command-line interface for Exocortex knowledge management system. Manage tasks, projects, and planning from the terminal without needing Obsidian.
3
+ Command-line interface for the Exocortex knowledge management system. Query and mutate an Obsidian vault as an RDF knowledge graph from the terminal no Obsidian required.
4
4
 
5
- ## API Stability
5
+ ## Installation
6
6
 
7
- **Current Version: 0.1.x (Stable API)**
7
+ ```bash
8
+ npm install -g @kitelev/exocortex-cli
9
+ ```
8
10
 
9
- This CLI follows [Semantic Versioning](https://semver.org/). The commands documented below are considered **stable** and covered by versioning guarantees.
11
+ Or run directly with npx (recommended always resolves the published version):
10
12
 
11
- **Documentation:**
13
+ ```bash
14
+ npx @kitelev/exocortex-cli <command> [options]
15
+ ```
12
16
 
13
- - [CLI API Reference](docs/CLI_API_REFERENCE.md) - Formal command signatures and options
14
- - [Versioning Policy](VERSIONING.md) - What constitutes breaking changes
15
- - [SPARQL Guide](docs/SPARQL_GUIDE.md) - Complete query reference
16
- - [SPARQL Cookbook](docs/SPARQL_COOKBOOK.md) - Real-world query examples
17
- - [Ontology Reference](docs/ONTOLOGY_REFERENCE.md) - Available predicates
17
+ The installed binary is named `exocortex-cli`. All examples below use the npx form.
18
18
 
19
- **For MCP Integration:**
19
+ ## CLI v16 Surface
20
20
 
21
- - Pin to `^0.1.0` for stable API access
22
- - Use exit codes for status (not console messages)
23
- - Use `--format json` for machine-readable output
21
+ Since v16.0 (RFC 8e83442b) the CLI follows a Unix-style surface built around **five core verbs** — `find`, `apply`, `query`, `index`, `validate` — plus auxiliary commands retained from v15.
24
22
 
25
- ## Installation
23
+ The following v15 verbs were **removed**: `batch`, `batch-repair`, `command`, `dyncommand`, `exoql`, `convert`, `sparql` (deprecated alias).
26
24
 
27
- ```bash
28
- npm install -g @exocortex/cli
29
- ```
25
+ | Removed verb | v16 replacement |
26
+ | --- | --- |
27
+ | `sparql query` / `exoql` | `query` (top-level) |
28
+ | `sparql index` | `index` (top-level) |
29
+ | `command <name> <path>` | `apply <cmd> [path]` — semantics live in vault-defined `exocmd__Command` assets |
30
+ | `dyncommand list` | `find --class exocmd__Command` |
31
+ | `dyncommand exec` | `apply` with `--dry-run` / `--yes` / `--input` |
32
+ | `batch` / `batch-repair` | pipe `find` output into `apply` (multi-target stdin) |
33
+ | `convert` | `query` with a CONSTRUCT query and `--format ntriples` |
30
34
 
31
- Or use directly with npx:
35
+ **Documentation:**
32
36
 
33
- ```bash
34
- npx @exocortex/cli [command]
35
- ```
37
+ - [CLI API Reference](docs/CLI_API_REFERENCE.md) — pointer to this README plus exit codes and JSON response contract
38
+ - [Versioning Policy](VERSIONING.md)
39
+ - [SPARQL Guide](docs/SPARQL_GUIDE.md) — complete query reference
40
+ - [SPARQL Cookbook](docs/SPARQL_COOKBOOK.md) — real-world query examples
41
+ - [Ontology Reference](docs/ONTOLOGY_REFERENCE.md) — available predicates
42
+
43
+ ## Command Overview
44
+
45
+ | Command | Purpose |
46
+ | --- | --- |
47
+ | [`find`](#find) | Select vault assets via SPARQL or class filter; prints file paths one per line |
48
+ | [`apply`](#apply) | Apply a vault-defined `exocmd__Command` to one or more assets |
49
+ | [`query`](#query) | Execute a SPARQL query against the vault |
50
+ | [`index`](#index) | Build or refresh the persistent triple cache |
51
+ | [`validate`](#validate) | Validate vault files: `iri`, `schema`, `frontmatter` |
52
+ | [`ask`](#ask) | Natural-language question (Russian or English) → SPARQL |
53
+ | [`classes`](#classes) | List vault classes or describe one class |
54
+ | [`create`](#create) | Create a new vault asset with auto-generated UUID and frontmatter |
55
+ | [`resolve`](#resolve) | Resolve a UUID (full or partial) to a file path |
56
+ | [`watch`](#watch) | Watch the vault for file changes; emit NDJSON events |
57
+ | [`workflow`](#workflow) | List / show / validate workflow definitions |
58
+ | [`archive`](#archive) | Bulk-move archived assets to an archive vault (+ verify / cascade / stats) |
59
+ | [`unarchive`](#unarchive) | Restore a single asset from the archive vault by UUID |
60
+ | [`backfill`](#backfill) | Concept backfill tools for aiKnow assets (`suggest`, `orphan-terms`) |
61
+ | [`recover`](#recover) | Detect and recover orphaned claude-child tmux sessions |
62
+ | [`daemon`](#daemon) | Manage the ValidatorDaemon background process |
63
+ | [`migrate-relcolset-to-exolayout`](#migrate-relcolset-to-exolayout) | Generate `exo__Layout` pairs from `ui__RelationColumnSet` configs |
64
+ | [`audit`](#audit) | Regression-pattern audits (`grounding-type-literal-form`, `co-location`) |
65
+ | [`apply-profile`](#apply-profile) | Apply an `exo__Profile` (mount-state filesystem mutation) |
66
+ | [`bootstrap`](#bootstrap) | Bootstrap a vault with the SDK floor AssetSpace |
67
+ | [`assetspace-add`](#assetspace-add) | Add a single AssetSpace to a vault by GitHub URL |
68
+ | [`experimental`](#experimental) | Opt-in experimental features (`rest-push`) |
36
69
 
37
- ## Usage
70
+ ---
38
71
 
39
- ```bash
40
- exocortex --help
41
- ```
72
+ ## Core Verbs
42
73
 
43
- ### SPARQL Query
74
+ ### find
44
75
 
45
- Execute SPARQL queries against your Obsidian vault as an RDF knowledge graph.
76
+ Find vault assets via SPARQL outputs vault-relative file paths one per line on stdout. Designed to compose with `xargs`, `apply`, or any other Unix tool.
46
77
 
47
78
  ```bash
48
- exocortex sparql query "SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 10" --vault ~/vault
79
+ npx @kitelev/exocortex-cli find --class ems__Task --vault ~/vault
49
80
  ```
50
81
 
51
82
  **Options:**
52
83
 
53
- - `<query>` - SPARQL query string or path to .sparql file **[required]**
54
- - `--vault <path>` - Path to Obsidian vault (default: current directory)
55
- - `--format <type>` - Output format: `table` (default), `json`, `csv`
56
- - `--explain` - Show optimized query plan (for debugging)
57
- - `--stats` - Show execution statistics (load time, query time, results count)
58
- - `--no-optimize` - Disable query optimization
84
+ | Option | Default | Description |
85
+ | --- | --- | --- |
86
+ | `--vault <path>` | cwd | Path to Obsidian vault |
87
+ | `--also <path>` | | Additional vault to include (repeatable) |
88
+ | `--sparql <query>` | | SPARQL SELECT query (must bind `?path`) |
89
+ | `--class <value>` | — | Filter by class label via the vault's `find__Alias` asset labelled `class` (e.g. `ems__Task`) |
90
+
91
+ Exactly one of `--sparql` or `--class` is required; they are mutually exclusive. `--class` requires a `find__Alias` asset with `exo__Asset_label: class` in the vault.
59
92
 
60
93
  **Examples:**
61
94
 
62
95
  ```bash
63
- # Find all tasks
64
- exocortex sparql query \
65
- "PREFIX exo: <https://exocortex.my/ontology/exo#>
66
- PREFIX ems: <https://exocortex.my/ontology/ems#>
67
- SELECT ?task ?label
68
- WHERE {
69
- ?task exo:Instance_class ems:Task .
70
- ?task exo:Asset_label ?label .
71
- }" \
72
- --vault ~/vault
73
-
74
- # Query from file
75
- exocortex sparql query queries/my-query.sparql --vault ~/vault
76
-
77
- # JSON output for automation
78
- exocortex sparql query "SELECT ?s ?p ?o WHERE { ?s ?p ?o }" \
79
- --vault ~/vault \
80
- --format json > results.json
96
+ # All tasks, raw SPARQL form
97
+ npx @kitelev/exocortex-cli find --vault ~/vault --sparql "
98
+ SELECT ?path WHERE {
99
+ ?s exo:Instance_class ems:Task .
100
+ BIND(?s AS ?path)
101
+ }"
81
102
 
82
- # Show query plan and stats
83
- exocortex sparql query "SELECT ?task WHERE { ?task exo:Instance_class ems:Task }" \
84
- --vault ~/vault \
85
- --explain \
86
- --stats
103
+ # Compose with apply: archive every matching asset
104
+ npx @kitelev/exocortex-cli find --class ems__Task --vault ~/vault \
105
+ | npx @kitelev/exocortex-cli apply <archive-command-uuid> --vault ~/vault --yes
87
106
  ```
88
107
 
89
- **Sample Output (Table Format):**
90
-
91
- ```
92
- 📦 Loading vault: /Users/you/vault...
93
- ✅ Loaded 1,234 triples in 45ms
108
+ ### apply
94
109
 
95
- 🔍 Parsing SPARQL query...
96
- 🔄 Translating to algebra...
97
- 🎯 Executing query...
98
- ✅ Found 5 result(s) in 12ms
110
+ Apply a vault-defined `exocmd__Command` to one or more vault assets. The command's semantics (precondition SPARQL ASK + grounding) live entirely in RDF assets in the vault.
99
111
 
100
- ┌────────────────────────────────────────────────────────────┐
101
- ?label │ ?effort │
102
- ├────────────────────────────┼───────────────────────────────┤
103
- │ "Implement SPARQL Engine" │ "240" │
104
- │ "Write Documentation" │ "120" │
105
- │ "Design Architecture" │ "180" │
106
- └────────────────────────────────────────────────────────────┘
112
+ ```bash
113
+ npx @kitelev/exocortex-cli apply <cmd> [path] [options]
107
114
  ```
108
115
 
109
- ### RDF Convert (Vault Dump)
116
+ **Arguments:**
110
117
 
111
- Dump the entire vault graph as Turtle, N-Triples, or JSON-LD for backup,
112
- offline analysis, or feeding external SHACL/RDF validators.
113
-
114
- ```bash
115
- exocortex convert --format turtle --out vault.ttl --vault ~/vault
116
- ```
118
+ | Argument | Description |
119
+ | --- | --- |
120
+ | `<cmd>` | UUID of an `exocmd__Command` asset, or its `exocmd__Command_cliName` slug |
121
+ | `[path]` | Vault-relative path to the target asset; omit to read paths from stdin (one per line) |
117
122
 
118
123
  **Options:**
119
124
 
120
- - `--format <type>` Serialization format: `turtle` (default), `ntriples`, `jsonld`
121
- - `--out <path>` Write to file (omit to print to stdout)
122
- - `--filter <class>` Keep only instances of a class (e.g. `ems__Task`, `ems:Task`, or full IRI)
123
- - `--vault <path>` Path to Obsidian vault (default: current directory)
125
+ | Option | Default | Description |
126
+ | --- | --- | --- |
127
+ | `--vault <path>` | cwd | Path to Obsidian vault |
128
+ | `--dry-run` | off | Evaluate precondition and preview; do not write |
129
+ | `--yes` | off | Skip destructive-command confirmation |
130
+ | `--input <json>` | — | JSON object forwarded to `service_call` groundings as `userInput` |
131
+ | `--seed <uuid>` | — | Deterministic UID seed for test/replay |
132
+ | `--frozen-clock <iso>` | — | Freeze clock to an ISO timestamp for test/replay |
133
+
134
+ **Behavior:**
135
+
136
+ - The precondition is evaluated per target; a non-passing ASK aborts before the grounding runs.
137
+ - Commands marked `exocmd__Command_destructive: true` refuse to run without `--dry-run` or `--yes`.
138
+ - Multi-target runs (stdin) use continue-on-error semantics and print a `N/M` summary; the exit code is `5` if any target failed.
124
139
 
125
140
  **Examples:**
126
141
 
127
142
  ```bash
128
- # Dump full vault as Turtle
129
- exocortex convert --format turtle --out vault.ttl --vault ~/vault
143
+ # Single target
144
+ npx @kitelev/exocortex-cli apply 6e050240-58e9-4695-9dce-d73fc32cc1d7 \
145
+ "tasks/abc-123.md" --vault ~/vault
130
146
 
131
- # Dump to stdout, pipe through external tool
132
- exocortex convert --format ntriples --vault ~/vault | wc -l
147
+ # Preview without writing
148
+ npx @kitelev/exocortex-cli apply <uuid> "tasks/abc-123.md" --dry-run --vault ~/vault
133
149
 
134
- # JSON-LD with @context for known namespaces
135
- exocortex convert --format jsonld --out vault.jsonld --vault ~/vault
150
+ # Pass userInput to a service_call grounding
151
+ npx @kitelev/exocortex-cli apply <uuid> "daily/2026-05-02.md" \
152
+ --input '{"label":"Lunch — vegetable soup"}' --vault ~/vault
136
153
 
137
- # Subset: only ems__Task instances
138
- exocortex convert --format turtle --filter ems__Task --out tasks.ttl --vault ~/vault
154
+ # Bulk: pipe a find selection through apply
155
+ npx @kitelev/exocortex-cli find --class ems__Task --vault ~/vault \
156
+ | npx @kitelev/exocortex-cli apply <uuid> --vault ~/vault
139
157
  ```
140
158
 
141
- **Use cases:**
159
+ ### query
142
160
 
143
- - Backup / snapshot of the vault graph at a point in time.
144
- - Offline analysis with Apache Jena, Protégé, or other RDF tooling.
145
- - Feeding external SHACL engines (e.g. `shacl-engine`, `rdf-validate-shacl`)
146
- for validation outside the plugin.
147
- - Diffing two `.ttl` snapshots to surface graph drift between runs.
148
-
149
- ### Universal Asset Creation
150
-
151
- Create any vault asset with a single command. Auto-generates UUID, timestamp, frontmatter, resolves class names, and validates wikilinks.
161
+ Execute a SPARQL query against the vault. Supports SELECT, ASK, and CONSTRUCT forms.
152
162
 
153
163
  ```bash
154
- # Create a permanent note
155
- exocortex create --class ztlk__PermanentNote --label "My Note" --vault ~/vault
156
-
157
- # With custom properties
158
- exocortex create --class ztlk__PermanentNote \
159
- --label "My Note" \
160
- --property "ztlk__Note_developedFrom=[[uuid|Source Note]]" \
161
- --vault ~/vault
162
-
163
- # With body content
164
- exocortex create --class ztlk__PermanentNote \
165
- --label "My Note" \
166
- --body "# Content\n\nBody text here." \
167
- --vault ~/vault
164
+ npx @kitelev/exocortex-cli query "SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 10" --vault ~/vault
165
+ ```
168
166
 
169
- # Body from file
170
- exocortex create --class ztlk__PermanentNote \
171
- --label "My Note" \
172
- --body-file /tmp/content.md \
173
- --vault ~/vault
167
+ **Arguments:**
174
168
 
175
- # Body from stdin
176
- echo "# Content" | exocortex create --class ztlk__PermanentNote \
177
- --label "My Note" \
178
- --body - \
179
- --vault ~/vault
169
+ | Argument | Description |
170
+ | --- | --- |
171
+ | `[query]` | SPARQL query string or path to a `.sparql` file (optional if `--template` is used) |
180
172
 
181
- # Dry run (preview without writing)
182
- exocortex create --class ztlk__PermanentNote --label "Test" --dry-run --vault ~/vault
173
+ **Options:**
183
174
 
184
- # With aliases
185
- exocortex create --class ztlk__PermanentNote \
186
- --label "My Note" \
187
- --aliases "Alias 1" "Alias 2" \
188
- --vault ~/vault
175
+ | Option | Default | Description |
176
+ | --- | --- | --- |
177
+ | `--vault <path>` | cwd | Path to Obsidian vault |
178
+ | `--also <path>` | | Additional vault to include in the query (repeatable) |
179
+ | `--format <type>` | `table` | Output format: `table`, `json`, `csv`, `ntriples` |
180
+ | `--output <type>` | `text` | Response format: `text` or `json` (for MCP tools) |
181
+ | `--timeout <duration>` | `30s` | Query timeout (e.g. `30s`, `5000ms`); env fallback `EXOCORTEX_SPARQL_TIMEOUT` |
182
+ | `--dry-run` | off | Validate query syntax without executing (no vault loading) |
183
+ | `--explain` | off | Show the optimized query plan |
184
+ | `--stats` | off | Show execution statistics |
185
+ | `--no-optimize` | — | Disable query optimization |
186
+ | `--use-cache` | off | Use the persistent triple cache (faster vault loading) |
187
+ | `--cache-ttl <seconds>` | `300` | Query result cache TTL in seconds |
188
+ | `--no-cache` | — | Bypass the query result cache |
189
+ | `--template <name>` | — | Use a predefined query template |
190
+ | `--param <params>` | — | Template parameters (`key=value,key2=value2`) |
191
+ | `--strict` | off | Fail on unresolved label-form wikilinks in property paths (sets `EXOCORTEX_SPARQL_STRICT=1`) |
192
+
193
+ **Built-in templates:** `tasks-by-date`, `tasks-by-status`, `projects-active`, `concepts-by-domain`, `sleep-analysis`.
189
194
 
190
- # Skip wikilink validation
191
- exocortex create --class ztlk__PermanentNote \
192
- --label "My Note" \
193
- --property "prop=[[uuid|Label]]" \
194
- --skip-wikilink-validation \
195
- --vault ~/vault
196
- ```
195
+ **Examples:**
197
196
 
198
- **Options:**
197
+ ```bash
198
+ # Find all tasks
199
+ npx @kitelev/exocortex-cli query \
200
+ "PREFIX exo: <https://exocortex.my/ontology/exo#>
201
+ PREFIX ems: <https://exocortex.my/ontology/ems#>
202
+ SELECT ?task ?label WHERE {
203
+ ?task exo:Instance_class ems:Task .
204
+ ?task exo:Asset_label ?label .
205
+ }" --vault ~/vault
199
206
 
200
- - `--class <name>` - Class short name (e.g. `ztlk__PermanentNote`) or UUID **[required]**
201
- - `--label <text>` - Human-readable label **[required]**
202
- - `--vault <path>` - Path to Obsidian vault (default: current directory)
203
- - `--aliases <names...>` - Additional aliases
204
- - `--property <key=value>` - Property key-value pairs (repeatable)
205
- - `--body <text>` - Markdown body content (use `-` for stdin)
206
- - `--body-file <path>` - Read body from file
207
- - `--dry-run` - Preview frontmatter without writing
208
- - `--created-by <uuid>` - Creator UUID (default: ExoAssistant)
209
- - `--timezone <tz>` - Timezone for timestamps (default: Asia/Almaty)
210
- - `--skip-wikilink-validation` - Skip wikilink existence checks
207
+ # Cross-vault query (repeatable --also)
208
+ npx @kitelev/exocortex-cli query "SELECT ?s WHERE { ?s ?p ?o }" \
209
+ --vault ~/vault --also ~/vault-archive
211
210
 
212
- **Output (JSON to stdout):**
211
+ # Template with parameters
212
+ npx @kitelev/exocortex-cli query --template tasks-by-date --param date=2026-01-15 --vault ~/vault
213
213
 
214
- ```json
215
- {
216
- "uuid": "generated-uuid",
217
- "path": "01 Inbox/generated-uuid.md",
218
- "label": "My Note"
219
- }
214
+ # Graph dump (CONSTRUCT) as N-Triples
215
+ npx @kitelev/exocortex-cli query "CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }" \
216
+ --format ntriples --vault ~/vault > vault.nt
220
217
  ```
221
218
 
222
- ### Command Execution
219
+ ### index
223
220
 
224
- Execute plugin commands on single assets. All commands follow the pattern:
221
+ Build or refresh the persistent triple cache used by `--use-cache` consumers. The cache lives at `<vault>/.exocortex/cache/triples.json`.
225
222
 
226
223
  ```bash
227
- exocortex command <command-name> <filepath> [options]
224
+ npx @kitelev/exocortex-cli index --vault ~/vault --stats
228
225
  ```
229
226
 
230
- **Common Options:**
227
+ **Options:**
231
228
 
232
- - `--vault <path>` - Path to Obsidian vault (default: current directory)
233
- - `--dry-run` - Preview changes without modifying files
229
+ | Option | Default | Description |
230
+ | --- | --- | --- |
231
+ | `--vault <path>` | cwd | Path to Obsidian vault |
232
+ | `--also <path>` | — | Additional vault to include in the combined index (repeatable) |
233
+ | `--output <type>` | `text` | Response format: `text` or `json` |
234
+ | `--stats` | off | Show cache statistics after building |
235
+ | `--force` | off | Force rebuild even if the cache is valid |
236
+ | `--strict` | off | Fail on the first invalid IRI instead of skipping |
237
+ | `--no-inference` | — | Disable RDFS `subClassOf` inference materialization |
234
238
 
235
- See [CLI API Reference](docs/CLI_API_REFERENCE.md) for complete command documentation.
239
+ ### validate
236
240
 
237
- #### Status Commands
241
+ Validate vault files. Parent command with three subcommands.
238
242
 
239
243
  ```bash
240
- # Start a task (ToDo → Doing)
241
- exocortex command start "tasks/my-task.md" --vault ~/vault
242
-
243
- # Complete a task (Doing → Done)
244
- exocortex command complete "tasks/my-task.md" --vault ~/vault
245
-
246
- # Move to backlog
247
- exocortex command move-to-backlog "tasks/defer-task.md" --vault ~/vault
248
-
249
- # Move to ToDo
250
- exocortex command move-to-todo "tasks/ready-task.md" --vault ~/vault
251
-
252
- # Trash a task
253
- exocortex command trash "tasks/obsolete-task.md" --vault ~/vault
254
-
255
- # Archive a task
256
- exocortex command archive "tasks/old-task.md" --vault ~/vault
244
+ npx @kitelev/exocortex-cli validate <iri|schema|frontmatter> [options]
257
245
  ```
258
246
 
259
- #### Creation Commands
247
+ #### validate iri
260
248
 
261
- ```bash
262
- # Create a new task
263
- exocortex command create-task "tasks/new-task.md" \
264
- --label "Implement feature X" \
265
- --area "areas/product" \
266
- --vault ~/vault
249
+ Check vault files for IRI issues (spaces, special characters) without building the cache. Exits `1` if issues are found.
267
250
 
268
- # Create a new meeting
269
- exocortex command create-meeting "meetings/standup.md" \
270
- --label "Daily Standup $(date +%Y-%m-%d)" \
271
- --prototype "prototypes/standup-template" \
272
- --vault ~/vault
251
+ | Option | Default | Description |
252
+ | --- | --- | --- |
253
+ | `--vault <path>` | cwd | Path to Obsidian vault |
254
+ | `--output <type>` | `text` | Response format: `text` or `json` |
273
255
 
274
- # Create a new project
275
- exocortex command create-project "projects/website-redesign.md" \
276
- --label "Website Redesign Q1 2026" \
277
- --vault ~/vault
256
+ #### validate schema
278
257
 
279
- # Create a new area
280
- exocortex command create-area "areas/product.md" \
281
- --label "Product Development" \
282
- --vault ~/vault
283
- ```
258
+ Check frontmatter properties against the ontology (schema linting), or run SHACL-lite shapes validation with `--shapes-mode`. Exits `1` if violations are found.
284
259
 
285
- #### Property Commands
260
+ | Option | Default | Description |
261
+ | --- | --- | --- |
262
+ | `--vault <path>` | cwd | Path to Obsidian vault |
263
+ | `--also <path>` | — | Additional vault merged into the validation graph (repeatable; disables `--use-cache`) |
264
+ | `--output <type>` | `text` | Response format: `text` or `json` |
265
+ | `--staged` | off | Only validate git-staged `.md` files (for pre-commit hooks) |
266
+ | `--use-cache` | off | Use the persistent triple cache (ignored when `--also` is set) |
267
+ | `--shapes-mode` | off | Run SHACL-lite shapes validation instead of schema linting |
268
+ | `--format <type>` | `text` | Shapes-mode output format: `text`, `json`, `earl` |
269
+ | `--class <iri>` | — | Only validate assets whose `exo__Instance_class` matches this IRI/slug |
286
270
 
287
271
  ```bash
288
- # Rename file to match its UID
289
- exocortex command rename-to-uid "tasks/My Task Name.md" --vault ~/vault
290
-
291
- # Update asset label
292
- exocortex command update-label "tasks/task.md" --label "New Label" --vault ~/vault
272
+ # Strict SHACL-lite validation of the whole vault
273
+ npx @kitelev/exocortex-cli validate schema --shapes-mode --vault ~/vault
293
274
 
294
- # Schedule task for a date
295
- exocortex command schedule "tasks/feature.md" --date "2025-12-15" --vault ~/vault
296
-
297
- # Set deadline
298
- exocortex command set-deadline "tasks/feature.md" --date "2025-12-31" --vault ~/vault
275
+ # Pre-commit: lint only staged files
276
+ npx @kitelev/exocortex-cli validate schema --staged --vault ~/vault
299
277
  ```
300
278
 
301
- ### Dynamic Commands (RFC-009)
279
+ #### validate frontmatter
302
280
 
303
- Execute **vault-defined commands** through a single generic interpreter. Any
304
- `exocmd:Command` asset in the vault — defined entirely in RDF (precondition +
305
- grounding + bindings) — can be invoked from CLI, Telegram bot, plugin button,
306
- or `cron`, without writing TypeScript.
281
+ Check vault frontmatter for missing/empty properties and malformed IRIs.
307
282
 
308
- This is the **killer feature** of Exocortex: a uniform runtime for vault-defined
309
- commands across plugin / CLI / scripts / Claude sessions. Source of truth is
310
- the RDF graph in your vault, not hardcoded TS logic. Architectural contract:
311
- RFC-009 (Dynamic Command System) and the umbrella RFC
312
- `94e520da-c6f7-48af-944c-51298d68da45` for the production-ready roadmap.
313
- Working command definitions live in
314
- [`docs/examples/rfc-009/`](../../docs/examples/rfc-009/).
283
+ | Option | Default | Description |
284
+ | --- | --- | --- |
285
+ | `--vault <path>` | cwd | Path to Obsidian vault |
286
+ | `--output <type>` | `text` | Response format: `text` or `json` |
287
+ | `--staged` | off | Only validate git-staged `.md` files |
315
288
 
316
- #### Subcommands
289
+ ---
317
290
 
318
- | Subcommand | Purpose |
319
- |------------|---------|
320
- | `dyncommand list` | Discover all `exocmd:Command` assets in vault |
321
- | `dyncommand show <uid>` | Show full details: precondition, grounding, bindings |
322
- | `dyncommand exec <uid> --target <path>` | Execute the command on a target asset |
323
- | `dyncommand validate` | Validate all command definitions; surface duplicate UIDs |
291
+ ## Auxiliary Commands
324
292
 
325
- ```bash
326
- # 1. Discover what commands the vault defines
327
- exocortex dyncommand list --vault ~/vault
293
+ ### ask
328
294
 
329
- # 2. Filter to commands applicable to a specific asset
330
- exocortex dyncommand list --target obsidian://vault/tasks/abc-123.md --vault ~/vault
295
+ Ask a question in natural language (Russian or English) about your vault. Converts the question to SPARQL and executes it.
331
296
 
332
- # 3. Inspect a command (precondition SPARQL ASK + grounding)
333
- exocortex dyncommand show 6e050240-58e9-4695-9dce-d73fc32cc1d7 --vault ~/vault
297
+ ```bash
298
+ npx @kitelev/exocortex-cli ask "активные проекты" --vault ~/vault
299
+ npx @kitelev/exocortex-cli ask "what tasks are due today" --show-query --vault ~/vault
300
+ ```
334
301
 
335
- # 4. Execute (precondition is evaluated; non-passing ASK aborts before grounding)
336
- exocortex dyncommand exec 6e050240-58e9-4695-9dce-d73fc32cc1d7 \
337
- --target tasks/abc-123.md \
338
- --vault ~/vault
302
+ | Option | Default | Description |
303
+ | --- | --- | --- |
304
+ | `--vault <path>` | cwd | Path to Obsidian vault |
305
+ | `--format <type>` | `table` | Output format: `table` or `json` |
306
+ | `--output <type>` | `text` | Response format: `text` or `json` (for MCP tools) |
307
+ | `--show-query` | off | Show the generated SPARQL query |
308
+ | `--explain` | off | Show an explanation of the query conversion |
339
309
 
340
- # 5. Preview without writing
341
- exocortex dyncommand exec <uid> --target tasks/abc-123.md --dry-run --vault ~/vault
310
+ ### classes
342
311
 
343
- # 6. Pass userInput to a service_call grounding
344
- exocortex dyncommand exec <uid> \
345
- --target daily/2026-05-02.md \
346
- --input '{"label":"Lunch — vegetable soup"}' \
347
- --vault ~/vault
312
+ List all classes in the vault, or show details of one class. Alias: `describe-class`.
348
313
 
349
- # 7. Validate vault-wide command definitions
350
- exocortex dyncommand validate --vault ~/vault --output json
314
+ ```bash
315
+ npx @kitelev/exocortex-cli classes --vault ~/vault
316
+ npx @kitelev/exocortex-cli classes ems__Task --vault ~/vault
351
317
  ```
352
318
 
353
- **Common options for all subcommands:**
354
-
355
- - `--vault <path>` Path to Obsidian vault (default: current directory)
356
- - `--output <text|json>` Response format (default: `text`)
319
+ | Argument / Option | Default | Description |
320
+ | --- | --- | --- |
321
+ | `[class-name]` || Optional class name to show details (e.g. `ems__Task`) |
322
+ | `--vault <path>` | cwd | Path to Obsidian vault |
323
+ | `--format <type>` | `table` | Output format: `table` or `json` |
324
+ | `--output <type>` | `text` | Response format: `text` or `json` (for MCP tools) |
325
+ | `--use-cache` | off | Use the persistent cache (faster for repeated queries) |
357
326
 
358
- **Additional options for `exec`:**
327
+ ### create
359
328
 
360
- - `--target <filepath>` Path to target asset, relative to vault **[required]**
361
- - `--dry-run` — Evaluate precondition + print grounding plan; do not mutate files
362
- - `--input <json>` — JSON object forwarded to `service_call` groundings as `userInput`
329
+ Create a new vault asset with auto-generated UUID, timestamps, and frontmatter. Resolves class short names to UUIDs and validates wikilinks in property values. New assets are written to the vault's `01 Inbox/` folder as `<uuid>.md`. On success a JSON object `{uuid, path, label}` is printed to stdout.
363
330
 
364
- **Exit codes (exec / validate):**
331
+ ```bash
332
+ npx @kitelev/exocortex-cli create --class ztlk__PermanentNote --label "My Note" --vault ~/vault
333
+ ```
334
+
335
+ | Option | Default | Description |
336
+ | --- | --- | --- |
337
+ | `--class <name>` | **required** | Class short name (e.g. `ztlk__PermanentNote`) or UUID |
338
+ | `--label <text>` | **required** | Human-readable label for the asset |
339
+ | `--vault <path>` | cwd | Path to Obsidian vault |
340
+ | `--aliases <names...>` | — | Additional aliases for the asset |
341
+ | `--property <key=value...>` | — | Property key-value pairs (repeatable) |
342
+ | `--body <text>` | — | Markdown body content (use `-` to read from stdin) |
343
+ | `--body-file <path>` | — | Read body content from a file |
344
+ | `--dry-run` | off | Preview the exact file content (stderr) without writing |
345
+ | `--created-by <uuid>` | — | Creator UUID |
346
+ | `--timezone <tz>` | `Asia/Almaty` | Timezone for timestamps |
347
+ | `--skip-wikilink-validation` | off | Skip wikilink existence validation |
365
348
 
366
- - `0` — Success (executed or precondition passed in dry-run)
367
- - `1` Operation failed (precondition not satisfied, grounding error)
368
- - `2` File not found (target or vault)
369
- - `3` — Invalid arguments (missing `--target`, malformed `--input`)
349
+ ```bash
350
+ # With custom properties and body from stdin
351
+ echo "# Content" | npx @kitelev/exocortex-cli create \
352
+ --class ztlk__PermanentNote \
353
+ --label "My Note" \
354
+ --property "ztlk__Note_developedFrom=[[<uuid>]]" \
355
+ --body - \
356
+ --vault ~/vault
357
+ ```
370
358
 
371
- #### Example 1 — Telegram bot: complete a task by UID
359
+ ### resolve
372
360
 
373
- A Telegram bot routes the user phrase «закрой задачу abc-123» to a single
374
- `dyncommand exec` invocation. The bot does **not** know what "complete" means —
375
- the semantics live entirely in the vault command asset (e.g.
376
- `ems__Effort_status` transition `Doing → Done` plus `endTimestamp`):
361
+ Resolve a UUID (full or partial, minimum 4 hex characters) to a file path. Exits `1` if the UUID is not found.
377
362
 
378
363
  ```bash
379
- TASK_UID="abc-123"
380
- COMPLETE_CMD_UID="6e050240-58e9-4695-9dce-d73fc32cc1d7" # from dyncommand list
381
-
382
- exocortex dyncommand exec "$COMPLETE_CMD_UID" \
383
- --target "tasks/${TASK_UID}.md" \
384
- --vault ~/vault \
385
- --output json
364
+ npx @kitelev/exocortex-cli resolve a1b2c3d4-e5f6-7890-abcd-ef1234567890 --vault ~/vault
365
+ npx @kitelev/exocortex-cli resolve a1b2 --partial --format path --vault ~/vault
386
366
  ```
387
367
 
388
- Why this matters: adding a new vault-defined command (e.g. «отправить в backlog»,
389
- «rollback to ToDo») requires **zero bot code changes** — only a new
390
- `exocmd:Command` asset in the vault. This is Homoiconicity Q1 in practice
391
- (see RFC `c78cc5c8-076c-4509-9e22-6f0257c51df4`).
368
+ | Argument / Option | Default | Description |
369
+ | --- | --- | --- |
370
+ | `<uuid>` | **required** | Full or partial UUID to resolve |
371
+ | `--vault <path>` | cwd | Path to Obsidian vault |
372
+ | `--format <type>` | `uri` | Output format: `uri`, `path`, or `json` |
373
+ | `--output <type>` | `text` | Response format: `text` or `json` (for MCP tools) |
374
+ | `--partial` | off | Match partial UUIDs (returns all matches) |
392
375
 
393
- #### Example 2 — CLI / Claude session: bulk-apply a command across a class
376
+ ### watch
394
377
 
395
- A Claude session needs to mark every `ems__Task` resolved in 2025 as archived.
396
- Discover the command UID once, then loop over targets selected by SPARQL:
378
+ Watch the vault for file changes and emit NDJSON events on stdout (one JSON object per line). Startup messages go to stderr. SIGINT/SIGTERM shut down gracefully with exit code `0`.
397
379
 
398
380
  ```bash
399
- ARCHIVE_CMD_UID=$(exocortex dyncommand list --vault ~/vault --output json \
400
- | jq -r '.data[] | select(.label == "Archive Asset") | .uid')
401
-
402
- exocortex sparql query \
403
- "PREFIX ems: <https://exocortex.my/ontology/ems#>
404
- SELECT ?path WHERE {
405
- ?s a ems:Task ;
406
- ems:Effort_status ems:EffortStatusDone ;
407
- ems:Effort_endTimestamp ?ts .
408
- FILTER(STRSTARTS(STR(?ts), '2025'))
409
- BIND(STRAFTER(STR(?s), 'obsidian://vault/') AS ?path)
410
- }" \
411
- --vault ~/vault --format json \
412
- | jq -r '.results.bindings[].path.value' \
413
- | while read -r path; do
414
- exocortex dyncommand exec "$ARCHIVE_CMD_UID" \
415
- --target "$path" \
416
- --vault ~/vault \
417
- --output json
418
- done
419
- ```
420
-
421
- The same `ARCHIVE_CMD_UID` works from a UI button (plugin), Telegram message,
422
- or scheduled job — one definition, many runtimes.
423
-
424
- #### Example 3 — `cron`: daily Lunch instance from a prototype
425
-
426
- Production server runs `lunch-tracker.sh` at 13:00 every day. The script
427
- materializes a fresh `Lunch` instance from a vault prototype using the generic
428
- `Create Instance` command (a `create_instance` grounding):
429
-
430
- ```bash
431
- #!/usr/bin/env bash
432
- # lunch-tracker.sh — cron entry: 0 13 * * * /opt/exocortex/lunch-tracker.sh
433
- set -euo pipefail
434
-
435
- VAULT="$HOME/vault"
436
- DAILY="daily/$(date +%Y-%m-%d).md"
437
- CREATE_INSTANCE_CMD="1abe7877-a462-4bd5-9bd8-1f75fe7f50aa" # Start Lunch (RFC 94e520da § Phase 7)
438
-
439
- npx @kitelev/exocortex-cli dyncommand exec "$CREATE_INSTANCE_CMD" \
440
- --target "$DAILY" \
441
- --input "{\"label\":\"Lunch — $(date +%Y-%m-%d)\"}" \
442
- --vault "$VAULT" \
443
- --output json
381
+ npx @kitelev/exocortex-cli watch --vault ~/vault --asset-type ems__Task | jq -c 'select(.type == "modify")'
444
382
  ```
445
383
 
446
- If the command, its precondition, or its grounding ever change in the vault,
447
- the cron job picks up the new behavior automatically — no redeploy.
384
+ | Option | Default | Description |
385
+ | --- | --- | --- |
386
+ | `--vault <path>` | cwd | Path to Obsidian vault |
387
+ | `--pattern <glob>` | — | Glob pattern to filter files (e.g. `*.md`, `tasks/**`) |
388
+ | `--asset-type <type>` | — | Filter by asset type from frontmatter (e.g. `ems__Task`) |
389
+ | `--debounce <ms>` | `100` | Per-file debounce interval in milliseconds |
448
390
 
449
- A drop-in deployable version of this script with crontab fragment, nightly
450
- verifier, install instructions, and a 7-day soak protocol — lives in
451
- [`examples/production-cron/`](../../examples/production-cron/) (RFC
452
- `94e520da` § Phase 5).
391
+ Event shape: `{type: "create"|"modify"|"delete", path, relativePath, timestamp, assetType?}`. Watcher errors are emitted to stdout as structured JSON error events.
453
392
 
454
- #### Telegram bot integration (Phase 7 migration)
393
+ ### workflow
455
394
 
456
- > **Migration target (RFC `94e520da` § Phase 7, T7.1):** Telegram bot Claude
457
- > subprocess **must** invoke `dyncommand exec <uid>` rather than legacy
458
- > `command start <path>`.
459
-
460
- The legacy `exocortex command start <path-to-asset>` (`Doing` transition by
461
- file path) is **deprecated** as part of the Phase 7 sunset of the hardcoded
462
- plugin-command CLI surface. Equivalent vault-defined behaviour now lives
463
- behind a stable command UID:
395
+ Manage custom workflow definitions stored in the vault.
464
396
 
465
397
  ```bash
466
- # NEW canonical path vault-defined command, stable UID, runtime-agnostic:
467
- LUNCH_CMD="1abe7877-a462-4bd5-9bd8-1f75fe7f50aa" # "Start Lunch" command
468
- TODAY_DAILY="03 Knowledge/daily/$(date +%Y-%m-%d).md"
469
-
470
- exocortex dyncommand exec "$LUNCH_CMD" \
471
- --target "$TODAY_DAILY" \
472
- --vault ~/vault \
473
- --output json
474
-
475
- # ⚠️ LEGACY (still works until Phase 7.3 sunset, ≥ 2 minor releases out):
476
- # exocortex command start "tasks/<lunch-task-uid>.md" --vault ~/vault
398
+ npx @kitelev/exocortex-cli workflow list --vault ~/vault
399
+ npx @kitelev/exocortex-cli workflow show <uid> --vault ~/vault
400
+ npx @kitelev/exocortex-cli workflow validate <uid> --vault ~/vault
477
401
  ```
478
402
 
479
- **What the bot subprocess Claude does:**
480
-
481
- 1. Receives user phrase (e.g. «начать обедать»).
482
- 2. Resolves the phrase to a vault `exocmd:Command` asset by `exo__Asset_label`
483
- or `aliases:` (the `Start Lunch` command above carries `aliases: [начать
484
- обедать]` so direct lookup works).
485
- 3. Invokes `dyncommand exec <uid> --target <today-daily-note> --vault $VAULT`.
486
- 4. Surfaces the JSON `successMessage` back to the user.
487
-
488
- **Why this is a real migration, not a rename:**
403
+ | Subcommand | Description |
404
+ | --- | --- |
405
+ | `list` | List all workflow definitions in the vault |
406
+ | `show <uid>` | Show details of a workflow definition |
407
+ | `validate <uid>` | Validate a workflow definition |
489
408
 
490
- - Adding a new bot phrase (e.g. «закрой задачу», «отправь в backlog») requires
491
- **zero bot or CLI code changes** — only a new vault `exocmd:Command` asset.
492
- - The same UID drives plugin UI buttons, CLI invocations, cron jobs, and
493
- Telegram routing. One definition, every runtime.
494
- - Backward compat: the legacy `command start` path keeps working through
495
- Phase 7.2 (deprecation warning) and Phase 7.3 (sunset), so existing bot
496
- configurations roll over without user-visible regression (RFC § R4).
409
+ All subcommands accept `--vault <path>` (default: cwd) and `--output text|json` (default: `text`).
497
410
 
498
- **Verification:**
411
+ ### archive
499
412
 
500
- ```bash
501
- # 1. Confirm command exists and precondition compiles:
502
- exocortex dyncommand show 1abe7877-a462-4bd5-9bd8-1f75fe7f50aa --vault ~/vault
503
-
504
- # 2. Dry-run on today's daily note (no writes):
505
- exocortex dyncommand exec 1abe7877-a462-4bd5-9bd8-1f75fe7f50aa \
506
- --target "03 Knowledge/daily/$(date +%Y-%m-%d).md" \
507
- --dry-run --vault ~/vault --output json
508
- ```
509
-
510
- The canonical `Start Lunch` command lives at
511
- `03 Knowledge/exocmd/status/1abe7877-a462-4bd5-9bd8-1f75fe7f50aa.md` in the
512
- vault; its grounding (`93e4a830-0911-4589-91f2-49ac0acdb4d2`) is a
513
- `service_call createAsset` materialising a fresh `ems__Task` instance from
514
- the Lunch `TaskPrototype` (`4b571141-5fc3-4ddd-8f07-ca681fc8410a`).
515
-
516
- #### Troubleshooting
517
-
518
- - **`Precondition not satisfied`** — run `dyncommand show <uid>` to read the
519
- SPARQL ASK; verify with `sparql query` that the target asset matches the
520
- pattern. Common cause: target IRI mismatch (CLI ↔ plugin parity, RFC-027 in
521
- progress) or an unset frontmatter property the precondition requires.
522
- - **`Command with UID "..." not found`** — `dyncommand list` returns 0 on
523
- UUID-wikilink-only vaults if the discovery index is stale; rebuild the
524
- vault cache or pass `--target <iri>` to bypass class filtering.
525
- - **Service `…` not implemented in CLI runtime** — the grounding uses a
526
- `service_call` that is plugin-only (Phase 1 hard-fails such calls instead
527
- of silently succeeding). Run from the plugin, or implement the service in
528
- `@kitelev/exocortex-services`.
529
- - **`dyncommand show` and `exec` disagree** — almost always a duplicate
530
- `exo__Asset_uid`; run `dyncommand validate --output json` and grep for
531
- `duplicateUids`. RCA: `docs/RCA_DYNCOMMAND_SHOW_VS_EXEC.md`.
532
-
533
- ## Workflow Examples
534
-
535
- ### Morning Planning
413
+ Archive assets from the active vault to a separate archive vault. Checks cross-references before moving so no links break. Four modes: default archival (requires `--class` and `--year`), `--verify`, `--cascade`, `--stats`. Result JSON is printed to stdout.
536
414
 
537
415
  ```bash
538
- # Schedule tasks for today
539
- exocortex command schedule "tasks/task1.md" --date "$(date +%Y-%m-%d)" --vault ~/vault
540
- exocortex command schedule "tasks/task2.md" --date "$(date +%Y-%m-%d)" --vault ~/vault
541
-
542
- # Move them to ToDo
543
- exocortex command move-to-todo "tasks/task1.md" --vault ~/vault
544
- exocortex command move-to-todo "tasks/task2.md" --vault ~/vault
545
- ```
546
-
547
- ### Creating Tasks from Project
416
+ npx @kitelev/exocortex-cli archive \
417
+ --vault ~/vault --archive-vault ~/vault-archive \
418
+ --class ems__Task,ems__Meeting --year 2025
419
+ ```
420
+
421
+ | Option | Default | Description |
422
+ | --- | --- | --- |
423
+ | `--vault <path>` | **required** | Path to the active vault |
424
+ | `--archive-vault <path>` | **required** | Path to the archive vault |
425
+ | `--class <names>` | — | Comma-separated class short names or UUIDs (required for archival mode) |
426
+ | `--year <year>` | — | Filter by resolution/end timestamp year (required for archival mode) |
427
+ | `--dry-run` | off | Preview without writing files |
428
+ | `--no-referenced` | — | Negation flag for the reference check (assets referenced by active files are skipped by default) |
429
+ | `--verify` | off | Verify archive integrity instead of archiving (read-only; exits `1` on issues) |
430
+ | `--cascade` | off | Iteratively resolve archived-to-archived chains (no `--class`/`--year` needed) |
431
+ | `--stats` | off | Print archive vault statistics by class and year (read-only) |
548
432
 
549
433
  ```bash
550
- # Create multiple tasks for a project
551
- exocortex command create-task "tasks/update-homepage.md" \
552
- --label "Update homepage" \
553
- --parent "projects/website-redesign" \
554
- --vault ~/vault
434
+ # Verify integrity (read-only)
435
+ npx @kitelev/exocortex-cli archive --verify --vault ~/vault --archive-vault ~/vault-archive
555
436
 
556
- exocortex command create-task "tasks/redesign-nav.md" \
557
- --label "Redesign navigation" \
558
- --parent "projects/website-redesign" \
559
- --vault ~/vault
437
+ # Resolve archived-to-archived dependency chains after a bulk run
438
+ npx @kitelev/exocortex-cli archive --cascade --vault ~/vault --archive-vault ~/vault-archive
560
439
 
561
- exocortex command create-task "tasks/test-mobile.md" \
562
- --label "Test on mobile" \
563
- --parent "projects/website-redesign" \
564
- --vault ~/vault
440
+ # Archive vault statistics
441
+ npx @kitelev/exocortex-cli archive --stats --vault ~/vault --archive-vault ~/vault-archive
565
442
  ```
566
443
 
567
- ### Weekly Review Workflow
444
+ ### unarchive
445
+
446
+ Restore a single asset from the archive vault back to the active vault (reverse of `archive`). The restored file lands in `<active-vault>/03 Knowledge/inbox/`.
568
447
 
569
448
  ```bash
570
- # Create this week's review meeting
571
- exocortex command create-meeting "meetings/weekly-review-$(date +%Y-%m-%d).md" \
572
- --label "Weekly Review $(date +%Y-%m-%d)" \
573
- --prototype "prototypes/weekly-review-template" \
574
- --vault ~/vault
449
+ npx @kitelev/exocortex-cli unarchive \
450
+ --uuid ca0d0001-1111-2222-3333-444455556666 \
451
+ --vault ~/vault --archive-vault ~/vault-archive
575
452
  ```
576
453
 
577
- ### Task Lifecycle
454
+ | Option | Default | Description |
455
+ | --- | --- | --- |
456
+ | `--uuid <uuid>` | **required** | UUID of the asset to restore |
457
+ | `--vault <path>` | **required** | Path to the active vault |
458
+ | `--archive-vault <path>` | **required** | Path to the archive vault |
459
+ | `--dry-run` | off | Preview without writing files |
578
460
 
579
- ```bash
580
- # 1. Create task
581
- exocortex command create-task "tasks/feature.md" --label "Implement feature" --vault ~/vault
461
+ ### backfill
582
462
 
583
- # 2. Move to ToDo when ready
584
- exocortex command move-to-todo "tasks/feature.md" --vault ~/vault
463
+ Concept backfill tools for aiKnow assets. Parent command with two subcommands.
585
464
 
586
- # 3. Start working
587
- exocortex command start "tasks/feature.md" --vault ~/vault
465
+ #### backfill suggest
588
466
 
589
- # 4. Complete when done
590
- exocortex command complete "tasks/feature.md" --vault ~/vault
467
+ Suggest concept backfill candidates for aiKnow assets, written as JSONL.
591
468
 
592
- # 5. Mark as archived
593
- exocortex command archive "tasks/feature.md" --vault ~/vault
594
- ```
469
+ | Option | Default | Description |
470
+ | --- | --- | --- |
471
+ | `--aiKnow-dir <path>` | **required** | Path to the aiKnow assets directory |
472
+ | `--vault <path>` | — | Path to Obsidian vault (for finding concepts) |
473
+ | `--output <path>` | `~/.cache/exocortex/backfill-candidates.jsonl` | Output JSONL path |
474
+ | `--auto-threshold <number>` | `0.8` | Auto-approve confidence threshold |
475
+ | `--frequency-cap <number>` | `100` | Skip concepts with ≥N existing stamps in the aiKnow dir |
476
+ | `--dry-run` | on | Output JSONL but do not write to the vault (default mode) |
595
477
 
596
- ### Archive Lifecycle
478
+ #### backfill orphan-terms
597
479
 
598
- ```bash
599
- # 1. Mark completed tasks as archived (sets archived: true)
600
- exocortex command archive "tasks/old-task.md" --vault ~/vault
480
+ Extract high-frequency terms from aiKnow assets that have no matching `ims__Concept`.
601
481
 
602
- # 2. Bulk move archived tasks to archive vault
603
- npx @kitelev/exocortex-cli archive \
604
- --vault ~/vault \
605
- --archive-vault ~/vault-archive \
606
- --class ems__Task --year 2025
482
+ | Option | Default | Description |
483
+ | --- | --- | --- |
484
+ | `--aiKnow-dir <path>` | **required** | Path to the aiKnow assets directory |
485
+ | `--vault <path>` | — | Path to Obsidian vault (for finding concepts) |
486
+ | `--top <number>` | `20` | Number of top orphan terms to return |
607
487
 
608
- # 3. Resolve dependency chains
609
- npx @kitelev/exocortex-cli archive --cascade \
610
- --vault ~/vault \
611
- --archive-vault ~/vault-archive
612
-
613
- # 4. Verify integrity
614
- npx @kitelev/exocortex-cli archive --verify \
615
- --vault ~/vault \
616
- --archive-vault ~/vault-archive
617
-
618
- # 5. Restore if needed
619
- npx @kitelev/exocortex-cli unarchive \
620
- --uuid <asset-uuid> \
621
- --vault ~/vault \
622
- --archive-vault ~/vault-archive
623
- ```
488
+ ### recover
624
489
 
625
- ### Batch Operations
626
-
627
- Execute multiple operations in a single CLI invocation for better performance:
490
+ Detect and recover orphaned `claude-child` tmux sessions. A session is orphaned when its corresponding vault task is not in Doing status. Default mode is dry-run.
628
491
 
629
492
  ```bash
630
- # Execute batch from JSON input
631
- exocortex batch --input '[
632
- {"command":"start","filepath":"tasks/task1.md"},
633
- {"command":"complete","filepath":"tasks/task2.md"},
634
- {"command":"trash","filepath":"tasks/task3.md"}
635
- ]' --vault ~/vault
493
+ npx @kitelev/exocortex-cli recover --vault ~/vault-2025
494
+ npx @kitelev/exocortex-cli recover --apply --vault ~/vault-2025
495
+ ```
636
496
 
637
- # Execute batch from file
638
- exocortex batch --file operations.json --vault ~/vault
497
+ | Option | Default | Description |
498
+ | --- | --- | --- |
499
+ | `--vault <path>` | `$EXOCORTEX_VAULT` or `~/vault-2025` | Path to Obsidian vault |
500
+ | `--dry-run` | — | List orphans without applying changes (default behavior) |
501
+ | `--apply` | off | Apply recovery: set Failed + kill the tmux session |
639
502
 
640
- # Atomic mode (all-or-nothing - rollback on any failure)
641
- exocortex batch --file operations.json --vault ~/vault --atomic
503
+ ### daemon
642
504
 
643
- # Dry run (preview without modifying files)
644
- exocortex batch --input '[{"command":"start","filepath":"task.md"}]' --vault ~/vault --dry-run
505
+ Manage the ValidatorDaemon background process (long-running, Unix socket).
645
506
 
646
- # JSON output for MCP integration
647
- exocortex batch --file operations.json --vault ~/vault --format json
507
+ ```bash
508
+ npx @kitelev/exocortex-cli daemon start
648
509
  ```
649
510
 
650
- **Batch Options:**
511
+ | Subcommand | Option | Default | Description |
512
+ | --- | --- | --- | --- |
513
+ | `start` | `--socket <path>` | `~/.cache/exocortex/validator.sock` | Unix socket path |
514
+ | `start` | `--idle-timeout <seconds>` | `300` | Exit after N seconds of inactivity |
651
515
 
652
- - `--input <json>` - JSON array of operations to execute
653
- - `--file <path>` - Path to JSON file containing operations
654
- - `--atomic` - All-or-nothing execution (rollback on any failure)
655
- - `--dry-run` - Preview changes without modifying files
656
- - `--format <type>` - Output format: `text` (default), `json`
657
- - `--vault <path>` - Path to Obsidian vault (default: current directory)
516
+ ### migrate-relcolset-to-exolayout
658
517
 
659
- **Operation Format:**
518
+ Generate `exo__Layout` + `exo__BacklinksTableBlock` pairs from existing `ui__RelationColumnSet` configs. Dry-run by default; pass `--apply` to write.
660
519
 
661
- ```json
662
- {
663
- "command": "start", // Command name (required)
664
- "filepath": "tasks/task.md", // File path (required)
665
- "options": {
666
- // Optional command parameters
667
- "label": "New Label",
668
- "date": "2025-12-15"
669
- }
670
- }
520
+ ```bash
521
+ npx @kitelev/exocortex-cli migrate-relcolset-to-exolayout --vault ~/vault # dry-run
522
+ npx @kitelev/exocortex-cli migrate-relcolset-to-exolayout --vault ~/vault --apply
671
523
  ```
672
524
 
673
- **Supported Commands:**
525
+ | Option | Default | Description |
526
+ | --- | --- | --- |
527
+ | `--vault <path>` | **required** | Path to the source vault |
528
+ | `--out-dir <path>` | `exo-layout-migrated` | Vault-relative folder where generated files land on `--apply` |
529
+ | `--apply` | off | Write generated files to the vault (default: dry-run, prints to stderr) |
530
+ | `--json` | off | Emit the migration report as JSON to stdout |
674
531
 
675
- - `start` - Start task (ToDo → Doing)
676
- - `complete` - Complete task (Doing → Done)
677
- - `trash` - Trash task
678
- - `archive` - Archive task
679
- - `move-to-backlog` - Move to Backlog
680
- - `move-to-analysis` - Move to Analysis
681
- - `move-to-todo` - Move to ToDo
682
- - `update-label` - Update label (requires `options.label`)
683
- - `schedule` - Schedule task (requires `options.date`)
684
- - `set-deadline` - Set deadline (requires `options.date`)
532
+ ---
685
533
 
686
- **Performance Benefits:**
534
+ ## Vault Management Commands
687
535
 
688
- - Single process execution (no repeated Node.js startup overhead)
689
- - Vault loaded once for all operations
690
- - Batch of 10 operations is ~10x faster than 10 separate CLI calls
536
+ ### audit
691
537
 
692
- **MCP Integration Example:**
538
+ Audit the vault for regression patterns. Parent command with two subcommands.
693
539
 
694
- ```json
695
- {
696
- "success": true,
697
- "data": {
698
- "success": true,
699
- "total": 3,
700
- "succeeded": 3,
701
- "failed": 0,
702
- "results": [
703
- {
704
- "success": true,
705
- "command": "start",
706
- "filepath": "task1.md",
707
- "action": "Started task"
708
- },
709
- {
710
- "success": true,
711
- "command": "complete",
712
- "filepath": "task2.md",
713
- "action": "Completed task"
714
- },
715
- {
716
- "success": true,
717
- "command": "trash",
718
- "filepath": "task3.md",
719
- "action": "Trashed task"
720
- }
721
- ],
722
- "durationMs": 45,
723
- "atomic": false
724
- },
725
- "meta": {
726
- "durationMs": 45,
727
- "itemCount": 3
728
- }
729
- }
730
- ```
540
+ #### audit grounding-type-literal-form
731
541
 
732
- ### Archive Management
542
+ Detect any `exocmd__Grounding_type` in literal-string form (not wikilink) in vault frontmatter.
733
543
 
734
- Manage the lifecycle of assets between active and archive vaults. The archive system ensures zero broken links by checking references before moving files.
544
+ ```bash
545
+ npx @kitelev/exocortex-cli audit grounding-type-literal-form --vault ~/vault
546
+ ```
735
547
 
736
- #### Archive Assets
548
+ #### audit co-location
737
549
 
738
- Move completed/archived assets from active vault to a separate archive vault:
550
+ Detect asset–ontology co-location violations: any asset not located in the folder of its `exo__Asset_isDefinedBy` ontology file. Fail-open with skip accounting — exits `0` when there are no violations (skips are still reported), `1` when one or more violations exist.
739
551
 
740
552
  ```bash
741
- # Archive all ems__Task from 2025
742
- npx @kitelev/exocortex-cli archive \
743
- --vault ~/vault \
744
- --archive-vault ~/vault-archive \
745
- --class ems__Task \
746
- --year 2025
747
-
748
- # Archive multiple classes
749
- npx @kitelev/exocortex-cli archive \
750
- --vault ~/vault \
751
- --archive-vault ~/vault-archive \
752
- --class ems__Task,ems__Meeting \
753
- --year 2025
754
-
755
- # Dry run — preview without moving files
756
- npx @kitelev/exocortex-cli archive --dry-run \
757
- --vault ~/vault \
758
- --archive-vault ~/vault-archive \
759
- --class ems__Task \
760
- --year 2025
553
+ npx @kitelev/exocortex-cli audit co-location --vault ~/vault
761
554
  ```
762
555
 
763
- **Archive Options:**
556
+ Both subcommands: `--vault <path>` (**required**), `--output text|json` (default: `text`).
764
557
 
765
- - `--vault <path>` - Path to the active vault **[required]**
766
- - `--archive-vault <path>` - Path to the archive vault **[required]**
767
- - `--class <names>` - Comma-separated class short names or UUIDs (e.g. `ems__Task,ems__Meeting`) **[required for archive mode]**
768
- - `--year <year>` - Filter by resolution/end timestamp year (e.g. `2025`) **[required for archive mode]**
769
- - `--dry-run` - Preview without writing files
770
- - `--no-referenced` - Skip assets that are still referenced by active (non-archived) files **(default behavior)**. Pass `--referenced` to include them anyway.
558
+ ### apply-profile
771
559
 
772
- **Exit codes:**
560
+ Apply the specified `exo__Profile` (mount-state filesystem mutation): materialize the profile's effective AssetSpace set and tear down the rest. Requires `--yes` in headless mode — without it the command prints the plan decision and exits `0` without mutating.
773
561
 
774
- - `0` — Success (assets archived or dry-run preview completed)
775
- - `1` Error (invalid options, vault not found, missing required flags)
562
+ ```bash
563
+ npx @kitelev/exocortex-cli apply-profile <profile-uid> --vault ~/vault --yes --verbose
564
+ ```
776
565
 
777
- **What archive does:**
566
+ | Argument / Option | Default | Description |
567
+ | --- | --- | --- |
568
+ | `<profile-uid>` | **required** | Target Profile UID |
569
+ | `--vault <path>` | **required** | Path to Obsidian vault |
570
+ | `--yes` | off | Confirm apply (headless safety override) |
571
+ | `--verbose` | off | Print the plan summary to stderr before deciding |
572
+ | `--ref <branch>` | `main` | Git ref to pull when materializing AssetSpaces |
573
+ | `--token <pat>` | — | GitHub PAT for private-repo materialization (or env `GITHUB_TOKEN` / `GH_TOKEN`) |
778
574
 
779
- 1. Scans active vault for assets matching class + year with `archived: true` in frontmatter
780
- 2. Checks cross-references — blocks assets still referenced by active (non-archived) files
781
- 3. Creates archive ontology files (e.g. `!ems_archive.md`) if needed
782
- 4. Updates `exo__Asset_isDefinedBy` to point to archive ontology
783
- 5. Moves files to archive vault, deletes from active vault
575
+ Refuses (exit `5`) when profile resolution is degraded or the plan would strip the TS-floor AssetSpaces. Use `find --class exo__Profile` to list available profiles.
784
576
 
785
- #### Verify Archive Integrity
577
+ ### bootstrap
786
578
 
787
- Check for broken cross-vault links and missing ontologies (read-only):
579
+ Bootstrap a vault with the SDK floor AssetSpace (`exo`). Pulls tarballs from public GitHub repos, extracts to `assetspaces/`, and writes `.gitmodules`. Only `--exo` is required; `--exocmd` (the optional UI-command library) is opt-in.
788
580
 
789
581
  ```bash
790
- npx @kitelev/exocortex-cli archive --verify \
791
- --vault ~/vault \
792
- --archive-vault ~/vault-archive
582
+ npx @kitelev/exocortex-cli bootstrap \
583
+ --vault ~/new-vault \
584
+ --exo https://github.com/kitelev/exoas-exo \
585
+ --exocmd https://github.com/kitelev/exoas-exocmd
793
586
  ```
794
587
 
795
- Returns exit code 0 if healthy, 1 if issues found. JSON output includes `broken_links`, `missing_ontologies`, and vault `stats`.
588
+ | Option | Default | Description |
589
+ | --- | --- | --- |
590
+ | `--vault <path>` | **required** | Path to the target vault |
591
+ | `--exo <url>` | **required** | Public GitHub URL of the exo TBox AssetSpace |
592
+ | `--exocmd <url>` | — | Optional GitHub URL of the exocmd UI-command AssetSpace; omit for a bare SDK/headless vault |
593
+ | `--ref <branch>` | `main` | Branch ref to pull from |
594
+ | `--token <pat>` | — | GitHub PAT for private repos (or env `GITHUB_TOKEN` / `GH_TOKEN`) |
595
+ | `--json` | off | Emit result as JSON |
796
596
 
797
- #### Cascade Archive
597
+ ### assetspace-add
798
598
 
799
- Iteratively resolve archived-to-archived dependency chains. Useful after bulk archival when some assets were blocked because they referenced other archived assets:
599
+ Add a single AssetSpace to an existing vault by public GitHub URL. Pulls a tarball, extracts to `assetspaces/<folder>/`, and updates `.gitmodules`. The default folder name is derived from the URL (`exoas-pmbok` → `pmbok`).
800
600
 
801
601
  ```bash
802
- # Cascade resolve (moves all unblocked archived assets)
803
- npx @kitelev/exocortex-cli archive --cascade \
602
+ npx @kitelev/exocortex-cli assetspace-add \
804
603
  --vault ~/vault \
805
- --archive-vault ~/vault-archive
806
-
807
- # Preview cascade
808
- npx @kitelev/exocortex-cli archive --cascade --dry-run \
809
- --vault ~/vault \
810
- --archive-vault ~/vault-archive
604
+ --url https://github.com/kitelev/exoas-pmbok-ontology
811
605
  ```
812
606
 
813
- No `--class` or `--year` needed cascade processes all eligible archived assets.
607
+ | Option | Default | Description |
608
+ | --- | --- | --- |
609
+ | `--vault <path>` | **required** | Path to the target vault |
610
+ | `--url <url>` | **required** | Public GitHub URL of the AssetSpace |
611
+ | `--folder <name>` | URL-derived | Local folder name under `assetspaces/` |
612
+ | `--ref <branch>` | `main` | Branch ref to pull from |
613
+ | `--token <pat>` | — | GitHub PAT for private repos (or env `GITHUB_TOKEN` / `GH_TOKEN`) |
614
+ | `--json` | off | Emit result as JSON |
814
615
 
815
- #### Unarchive (Restore) Assets
616
+ ### experimental
816
617
 
817
- Restore a single asset from archive vault back to active vault:
618
+ Opt-in experimental features. Unstable may change or be removed.
818
619
 
819
- ```bash
820
- # Restore asset by UUID
821
- npx @kitelev/exocortex-cli unarchive \
822
- --uuid ca0d0001-1111-2222-3333-444455556666 \
823
- --vault ~/vault \
824
- --archive-vault ~/vault-archive
620
+ #### experimental rest-push
825
621
 
826
- # Dry run preview without restoring
827
- npx @kitelev/exocortex-cli unarchive --dry-run \
828
- --uuid ca0d0001-1111-2222-3333-444455556666 \
829
- --vault ~/vault \
830
- --archive-vault ~/vault-archive
831
- ```
622
+ Commit and push a file to a GitHub repo via the pure REST Git Data API (no `git` binary). Gated behind `EXOCORTEX_EXPERIMENTAL_REST_PUSH=1` or `--experimental`.
832
623
 
833
- **Unarchive Options:**
624
+ ```bash
625
+ EXOCORTEX_EXPERIMENTAL_REST_PUSH=1 npx @kitelev/exocortex-cli experimental rest-push \
626
+ --repo kitelev/some-repo \
627
+ --file notes/hello.md \
628
+ --content "hello" \
629
+ --message "docs: add hello note" \
630
+ --token-from-gh
631
+ ```
632
+
633
+ | Option | Default | Description |
634
+ | --- | --- | --- |
635
+ | `--repo <owner/repo>` | **required** | Target repo as `owner/repo` |
636
+ | `--branch <branch>` | `main` | Branch to commit on |
637
+ | `--file <repoPath>` | **required** | Path within the repo to write |
638
+ | `--content <text>` | — | Inline file content |
639
+ | `--content-file <localPath>` | — | Read file content from a local path |
640
+ | `--message <msg>` | **required** | Commit message |
641
+ | `--token-from-gh` | off | Resolve PAT via `gh auth token` |
642
+ | `--token <pat>` | — | GitHub PAT (or env `GITHUB_TOKEN` / `GH_TOKEN`); prefer `--token-from-gh` |
643
+ | `--experimental` | off | Opt in (alternative to `EXOCORTEX_EXPERIMENTAL_REST_PUSH=1`) |
644
+ | `--api-base <url>` | `https://api.github.com` | GitHub API base URL |
645
+ | `--json` | off | Emit result as JSON |
834
646
 
835
- - `--uuid <uuid>` - UUID of the asset to restore **[required]**
836
- - `--vault <path>` - Path to the active vault **[required]**
837
- - `--archive-vault <path>` - Path to the archive vault **[required]**
838
- - `--dry-run` - Preview without writing files
647
+ ---
648
+
649
+ ## Exit Codes
839
650
 
840
- **Exit codes:**
651
+ All commands use standardized exit codes following Unix conventions (`src/utils/ExitCodes.ts`):
841
652
 
842
- - `0` Success (asset restored or dry-run preview completed)
843
- - `1` Error (UUID not found in archive vault, invalid UUID format, vault not found)
653
+ | Code | Constant | Description |
654
+ | --- | --- | --- |
655
+ | `0` | `SUCCESS` | Command completed successfully |
656
+ | `1` | `GENERAL_ERROR` | General error (catch-all) |
657
+ | `2` | `INVALID_ARGUMENTS` | Invalid command-line arguments or options |
658
+ | `3` | `FILE_NOT_FOUND` | File or directory not found |
659
+ | `4` | `PERMISSION_DENIED` | Permission denied (file system access) |
660
+ | `5` | `OPERATION_FAILED` | Command execution failed (business logic error) |
661
+ | `6` | `INVALID_STATE_TRANSITION` | Invalid asset state transition |
662
+ | `7` | `TRANSACTION_FAILED` | Atomic operation could not complete |
663
+ | `8` | `CONCURRENT_MODIFICATION` | File changed during operation |
844
664
 
845
- **What unarchive does:**
665
+ Validation commands (`validate iri`, `validate schema`, `audit co-location`, `archive --verify`) exit `1` when issues/violations are found, for CI/pre-commit integration.
846
666
 
847
- 1. Finds asset by UUID in archive vault (direct filename match, then frontmatter scan)
848
- 2. Updates `exo__Asset_isDefinedBy` from archive ontology back to active ontology
849
- 3. Moves file to `<active-vault>/03 Knowledge/inbox/`
850
- 4. Preserves `archived: true` in frontmatter (user decides whether to remove it)
667
+ ## Structured JSON Responses
851
668
 
852
- **Output (JSON to stdout):**
669
+ Commands that accept `--output json` (e.g. `query`, `ask`, `classes`, `resolve`, `index`, `validate`, `workflow`, `audit`) emit a structured response envelope for MCP tools and automation:
853
670
 
854
671
  ```json
855
672
  {
856
673
  "success": true,
857
- "uuid": "ca0d0001-...",
858
- "movedTo": "03 Knowledge/inbox/ca0d0001-....md",
859
- "isDefinedBy": "[[!ems|EMS Ontology]]"
674
+ "data": { },
675
+ "meta": { "durationMs": 45, "itemCount": 3 }
676
+ }
677
+ ```
678
+
679
+ On error:
680
+
681
+ ```json
682
+ {
683
+ "success": false,
684
+ "error": {
685
+ "code": "VALIDATION_FILE_NOT_FOUND",
686
+ "category": "validation",
687
+ "message": "File not found: tasks/missing.md",
688
+ "exitCode": 3,
689
+ "recovery": { "message": "...", "suggestion": "..." }
690
+ }
860
691
  }
861
692
  ```
862
693
 
694
+ Error categories: `validation`, `permission`, `state`, `internal`. The full `ErrorCode` enum and response interfaces live in `src/responses/StructuredResponse.ts`; see [CLI API Reference](docs/CLI_API_REFERENCE.md) for the code tables.
695
+
863
696
  ## Architecture
864
697
 
865
- The CLI uses `exocortex` for business logic and implements a Node.js file system adapter:
698
+ The CLI is an ESM package (`"type": "module"`) that consumes the `exocortex` core package (RDF, SPARQL, services) through Node.js adapters:
866
699
 
867
700
  ```
868
- exocortex-cli/
701
+ packages/cli/
869
702
  ├── src/
870
- │ ├── index.ts - Main CLI entry point
871
- │ ├── adapters/
872
- │ └── NodeFsAdapter.ts - Node.js file system implementation
873
- └── commands/
874
- ├── create-task.ts
875
- ├── create-instance.ts
876
- ├── status.ts
877
- └── plan.ts
878
- └── dist/ - Compiled output
879
- ```
880
-
881
- ## Features
882
-
883
- - **SPARQL Query Engine** - Execute SPARQL 1.1 queries against vault as RDF knowledge graph
884
- - BGP (Basic Graph Pattern) execution with variable bindings
885
- - Query optimization (filter push-down, join reordering)
886
- - Multiple output formats (table, JSON, CSV)
887
- - Query plan visualization (--explain flag)
888
- - Performance statistics (--stats flag)
889
- - **File System Operations** - Read/write markdown files with frontmatter
890
- - **Task Creation** - Generate tasks from areas, projects, and prototypes
891
- - **Instance Creation** - Create instances from prototypes
892
- - **Status Management** - Update task status through workflow
893
- - **Planning** - Assign tasks to specific days
894
- - **Frontmatter Support** - Full YAML frontmatter parsing and manipulation
895
- - **Archive Management** - Bulk archive/unarchive assets between vaults with integrity verification
896
- - **Progress Indicators** - Spinners and colored output for better UX
703
+ │ ├── index.ts - Commander program: registers all commands
704
+ │ ├── adapters/ - FileSystemVaultAdapter, NodeFsAdapter
705
+ ├── commands/ - One module per command (find, apply, sparql-query, ...)
706
+ ├── services/ - CLI-side services (class resolution, archive, profile apply)
707
+ ├── cache/ - Persistent triple cache (.exocortex/cache/triples.json)
708
+ ├── templates/ - Built-in SPARQL query templates
709
+ └── utils/ - ErrorHandler, ExitCodes, prefix injection
710
+ └── dist/ - Bundled output (esbuild)
711
+ ```
712
+
713
+ ## Requirements
714
+
715
+ - Node.js >= 18.0.0
716
+ - A vault with Exocortex-compatible markdown files (YAML frontmatter with `exo__*` properties)
897
717
 
898
718
  ## Development
899
719
 
900
720
  ```bash
901
- # Install dependencies
721
+ # Install dependencies (run from the monorepo root)
902
722
  npm install
903
723
 
904
724
  # Build
@@ -911,102 +731,6 @@ node dist/index.js --help
911
731
  npm run dev
912
732
  ```
913
733
 
914
- ## Requirements
915
-
916
- - Node.js >= 18.0.0
917
- - A vault with Exocortex-compatible markdown files
918
-
919
- ## Vault Structure
920
-
921
- Your vault should follow Exocortex conventions:
922
-
923
- ```
924
- vault/
925
- ├── areas/
926
- │ ├── work.md
927
- │ └── personal.md
928
- ├── projects/
929
- │ └── website-redesign.md
930
- ├── tasks/
931
- │ ├── abc-123.md
932
- │ └── def-456.md
933
- └── prototypes/
934
- ├── weekly-review.md
935
- └── standup.md
936
- ```
937
-
938
- Each file should have YAML frontmatter with Exocortex properties:
939
-
940
- ```yaml
941
- ---
942
- exo__Asset_isDefinedBy: my-ontology
943
- exo__Asset_uid: abc-123
944
- exo__Instance_class:
945
- - "[[ems__Task]]"
946
- ems__Effort_status: "[[ems__EffortStatusDraft]]"
947
- ---
948
- ```
949
-
950
- ## Roadmap
951
-
952
- ### Implemented Commands
953
-
954
- **SPARQL Query:**
955
-
956
- - `exocortex sparql query` - Execute SPARQL queries against vault
957
-
958
- **Status Transitions:**
959
-
960
- - `exocortex command start` - Start effort (ToDo → Doing)
961
- - `exocortex command complete` - Complete effort (Doing → Done)
962
- - `exocortex command trash` - Trash effort
963
- - `exocortex command archive` - Archive effort
964
- - `exocortex command move-to-backlog` - Move to Backlog
965
- - `exocortex command move-to-analysis` - Move to Analysis
966
- - `exocortex command move-to-todo` - Move to ToDo
967
-
968
- **Universal Asset Creation:**
969
-
970
- - `exocortex create` - Create any asset with auto UUID, frontmatter, and wikilink validation
971
-
972
- **Asset Creation (legacy):**
973
-
974
- - `exocortex command create-task` - Create new task
975
- - `exocortex command create-meeting` - Create new meeting
976
- - `exocortex command create-project` - Create new project
977
- - `exocortex command create-area` - Create new area
978
-
979
- **Property Mutations:**
980
-
981
- - `exocortex command rename-to-uid` - Rename file to match UID
982
- - `exocortex command update-label` - Update asset label
983
- - `exocortex command schedule` - Set planned start date
984
- - `exocortex command set-deadline` - Set planned end date
985
-
986
- **Dynamic Commands (RFC-009):**
987
-
988
- - `exocortex dyncommand list` - Discover vault-defined `exocmd:Command` assets
989
- - `exocortex dyncommand show` - Show precondition / grounding / bindings for a command
990
- - `exocortex dyncommand exec` - Execute vault-defined command on a target asset
991
- - `exocortex dyncommand validate` - Validate command definitions; flag duplicate UIDs
992
-
993
- **Batch Operations:**
994
-
995
- - `exocortex batch` - Execute multiple operations in single invocation
996
-
997
- **Archive Management:**
998
-
999
- - `exocortex archive` - Bulk archive assets by class and year (with `--dry-run`, `--verify`, `--cascade`)
1000
- - `exocortex unarchive` - Restore single asset from archive vault by UUID (with `--dry-run`)
1001
-
1002
- ### Planned Commands
1003
-
1004
- - `exocortex command rollback-status` - Rollback to previous status
1005
- - `exocortex command shift-schedule` - Shift planned date forward/backward
1006
- - `exocortex list tasks` - List all tasks (with filters)
1007
- - `exocortex list today` - List today's scheduled tasks
1008
- - `exocortex report weekly` - Generate weekly effort report
1009
-
1010
734
  ## License
1011
735
 
1012
736
  MIT