@kitelev/exocortex-cli 16.80.1 → 16.80.2
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.
- package/README.md +507 -783
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,904 +1,724 @@
|
|
|
1
|
-
# @exocortex
|
|
1
|
+
# @kitelev/exocortex-cli
|
|
2
2
|
|
|
3
|
-
Command-line interface for Exocortex knowledge management system.
|
|
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
|
-
##
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @kitelev/exocortex-cli
|
|
9
|
+
```
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
Or run directly with npx (recommended — always resolves the published version):
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
```bash
|
|
14
|
+
npx @kitelev/exocortex-cli <command> [options]
|
|
15
|
+
```
|
|
12
16
|
|
|
13
|
-
|
|
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
|
-
|
|
19
|
+
## CLI v16 Surface
|
|
20
20
|
|
|
21
|
-
-
|
|
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
|
-
|
|
23
|
+
The following v15 verbs were **removed**: `batch`, `batch-repair`, `command`, `dyncommand`, `exoql`, `convert`, `sparql` (deprecated alias).
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
35
|
+
**Documentation:**
|
|
32
36
|
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
70
|
+
---
|
|
38
71
|
|
|
39
|
-
|
|
40
|
-
exocortex --help
|
|
41
|
-
```
|
|
72
|
+
## Core Verbs
|
|
42
73
|
|
|
43
|
-
###
|
|
74
|
+
### find
|
|
44
75
|
|
|
45
|
-
|
|
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
|
|
79
|
+
npx @kitelev/exocortex-cli find --class ems__Task --vault ~/vault
|
|
49
80
|
```
|
|
50
81
|
|
|
51
82
|
**Options:**
|
|
52
83
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
#
|
|
64
|
-
exocortex sparql
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
#
|
|
83
|
-
exocortex
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
```
|
|
92
|
-
📦 Loading vault: /Users/you/vault...
|
|
93
|
-
✅ Loaded 1,234 triples in 45ms
|
|
108
|
+
### apply
|
|
94
109
|
|
|
95
|
-
|
|
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
|
-
|
|
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
|
-
|
|
116
|
+
**Arguments:**
|
|
110
117
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
-
#
|
|
129
|
-
exocortex
|
|
143
|
+
# Single target
|
|
144
|
+
npx @kitelev/exocortex-cli apply 6e050240-58e9-4695-9dce-d73fc32cc1d7 \
|
|
145
|
+
"tasks/abc-123.md" --vault ~/vault
|
|
130
146
|
|
|
131
|
-
#
|
|
132
|
-
exocortex
|
|
147
|
+
# Preview without writing
|
|
148
|
+
npx @kitelev/exocortex-cli apply <uuid> "tasks/abc-123.md" --dry-run --vault ~/vault
|
|
133
149
|
|
|
134
|
-
#
|
|
135
|
-
exocortex
|
|
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
|
-
#
|
|
138
|
-
exocortex
|
|
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
|
-
|
|
159
|
+
### query
|
|
142
160
|
|
|
143
|
-
|
|
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
|
-
|
|
155
|
-
|
|
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
|
-
|
|
170
|
-
exocortex create --class ztlk__PermanentNote \
|
|
171
|
-
--label "My Note" \
|
|
172
|
-
--body-file /tmp/content.md \
|
|
173
|
-
--vault ~/vault
|
|
167
|
+
**Arguments:**
|
|
174
168
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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
|
-
|
|
182
|
-
exocortex create --class ztlk__PermanentNote --label "Test" --dry-run --vault ~/vault
|
|
173
|
+
**Options:**
|
|
183
174
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
201
|
-
-
|
|
202
|
-
|
|
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
|
-
|
|
211
|
+
# Template with parameters
|
|
212
|
+
npx @kitelev/exocortex-cli query --template tasks-by-date --param date=2026-01-15 --vault ~/vault
|
|
213
213
|
|
|
214
|
-
|
|
215
|
-
{
|
|
216
|
-
|
|
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
|
-
###
|
|
219
|
+
### index
|
|
223
220
|
|
|
224
|
-
|
|
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
|
|
224
|
+
npx @kitelev/exocortex-cli index --vault ~/vault --stats
|
|
228
225
|
```
|
|
229
226
|
|
|
230
|
-
**
|
|
227
|
+
**Options:**
|
|
231
228
|
|
|
232
|
-
|
|
233
|
-
|
|
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
|
-
|
|
239
|
+
### validate
|
|
236
240
|
|
|
237
|
-
|
|
241
|
+
Validate vault files. Parent command with three subcommands.
|
|
238
242
|
|
|
239
243
|
```bash
|
|
240
|
-
|
|
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
|
-
####
|
|
247
|
+
#### validate iri
|
|
260
248
|
|
|
261
|
-
|
|
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
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
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
|
-
|
|
275
|
-
exocortex command create-project "projects/website-redesign.md" \
|
|
276
|
-
--label "Website Redesign Q1 2026" \
|
|
277
|
-
--vault ~/vault
|
|
256
|
+
#### validate schema
|
|
278
257
|
|
|
279
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
289
|
-
exocortex
|
|
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
|
-
#
|
|
295
|
-
exocortex
|
|
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
|
-
|
|
279
|
+
#### validate frontmatter
|
|
302
280
|
|
|
303
|
-
|
|
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
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
`
|
|
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
|
-
|
|
289
|
+
---
|
|
317
290
|
|
|
318
|
-
|
|
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
|
-
|
|
326
|
-
# 1. Discover what commands the vault defines
|
|
327
|
-
exocortex dyncommand list --vault ~/vault
|
|
293
|
+
### ask
|
|
328
294
|
|
|
329
|
-
|
|
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
|
-
|
|
333
|
-
exocortex
|
|
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
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
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
|
-
|
|
341
|
-
exocortex dyncommand exec <uid> --target tasks/abc-123.md --dry-run --vault ~/vault
|
|
310
|
+
### classes
|
|
342
311
|
|
|
343
|
-
|
|
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
|
-
|
|
350
|
-
exocortex
|
|
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
|
-
|
|
354
|
-
|
|
355
|
-
-
|
|
356
|
-
|
|
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
|
-
|
|
327
|
+
### create
|
|
359
328
|
|
|
360
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
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
|
-
|
|
359
|
+
### resolve
|
|
372
360
|
|
|
373
|
-
|
|
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
|
-
|
|
380
|
-
|
|
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
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
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
|
-
|
|
376
|
+
### watch
|
|
394
377
|
|
|
395
|
-
|
|
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
|
-
|
|
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
|
-
|
|
447
|
-
|
|
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
|
-
|
|
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
|
-
|
|
393
|
+
### workflow
|
|
455
394
|
|
|
456
|
-
|
|
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
|
-
|
|
467
|
-
|
|
468
|
-
|
|
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
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
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
|
-
|
|
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
|
-
|
|
411
|
+
### archive
|
|
499
412
|
|
|
500
|
-
|
|
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
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
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
|
-
#
|
|
551
|
-
exocortex
|
|
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
|
-
|
|
557
|
-
|
|
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
|
-
|
|
562
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
571
|
-
|
|
572
|
-
--
|
|
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
|
-
|
|
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
|
-
|
|
580
|
-
# 1. Create task
|
|
581
|
-
exocortex command create-task "tasks/feature.md" --label "Implement feature" --vault ~/vault
|
|
461
|
+
### backfill
|
|
582
462
|
|
|
583
|
-
|
|
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
|
-
|
|
587
|
-
exocortex command start "tasks/feature.md" --vault ~/vault
|
|
465
|
+
#### backfill suggest
|
|
588
466
|
|
|
589
|
-
|
|
590
|
-
exocortex command complete "tasks/feature.md" --vault ~/vault
|
|
467
|
+
Suggest concept backfill candidates for aiKnow assets, written as JSONL.
|
|
591
468
|
|
|
592
|
-
|
|
593
|
-
|
|
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
|
-
|
|
478
|
+
#### backfill orphan-terms
|
|
597
479
|
|
|
598
|
-
|
|
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
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
631
|
-
exocortex
|
|
632
|
-
|
|
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
|
-
|
|
638
|
-
|
|
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
|
-
|
|
641
|
-
exocortex batch --file operations.json --vault ~/vault --atomic
|
|
503
|
+
### daemon
|
|
642
504
|
|
|
643
|
-
|
|
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
|
-
|
|
647
|
-
exocortex
|
|
507
|
+
```bash
|
|
508
|
+
npx @kitelev/exocortex-cli daemon start
|
|
648
509
|
```
|
|
649
510
|
|
|
650
|
-
|
|
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
|
-
|
|
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
|
-
|
|
518
|
+
Generate `exo__Layout` + `exo__BacklinksTableBlock` pairs from existing `ui__RelationColumnSet` configs. Dry-run by default; pass `--apply` to write.
|
|
660
519
|
|
|
661
|
-
```
|
|
662
|
-
|
|
663
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
534
|
+
## Vault Management Commands
|
|
687
535
|
|
|
688
|
-
|
|
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
|
-
|
|
538
|
+
Audit the vault for regression patterns. Parent command with two subcommands.
|
|
693
539
|
|
|
694
|
-
|
|
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
|
-
|
|
542
|
+
Detect any `exocmd__Grounding_type` in literal-string form (not wikilink) in vault frontmatter.
|
|
733
543
|
|
|
734
|
-
|
|
544
|
+
```bash
|
|
545
|
+
npx @kitelev/exocortex-cli audit grounding-type-literal-form --vault ~/vault
|
|
546
|
+
```
|
|
735
547
|
|
|
736
|
-
####
|
|
548
|
+
#### audit co-location
|
|
737
549
|
|
|
738
|
-
|
|
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
|
-
|
|
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
|
-
**
|
|
556
|
+
Both subcommands: `--vault <path>` (**required**), `--output text|json` (default: `text`).
|
|
764
557
|
|
|
765
|
-
|
|
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
|
-
|
|
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
|
-
|
|
775
|
-
-
|
|
562
|
+
```bash
|
|
563
|
+
npx @kitelev/exocortex-cli apply-profile <profile-uid> --vault ~/vault --yes --verbose
|
|
564
|
+
```
|
|
776
565
|
|
|
777
|
-
|
|
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
|
-
|
|
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
|
-
|
|
577
|
+
### bootstrap
|
|
786
578
|
|
|
787
|
-
|
|
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
|
|
791
|
-
--vault ~/vault \
|
|
792
|
-
--
|
|
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
|
-
|
|
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
|
-
|
|
597
|
+
### assetspace-add
|
|
798
598
|
|
|
799
|
-
|
|
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
|
-
|
|
803
|
-
npx @kitelev/exocortex-cli archive --cascade \
|
|
602
|
+
npx @kitelev/exocortex-cli assetspace-add \
|
|
804
603
|
--vault ~/vault \
|
|
805
|
-
--
|
|
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
|
-
|
|
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
|
-
|
|
616
|
+
### experimental
|
|
816
617
|
|
|
817
|
-
|
|
618
|
+
Opt-in experimental features. Unstable — may change or be removed.
|
|
818
619
|
|
|
819
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
- `--dry-run` - Preview without writing files
|
|
647
|
+
---
|
|
648
|
+
|
|
649
|
+
## Exit Codes
|
|
839
650
|
|
|
840
|
-
|
|
651
|
+
All commands use standardized exit codes following Unix conventions (`src/utils/ExitCodes.ts`):
|
|
841
652
|
|
|
842
|
-
|
|
843
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
"
|
|
858
|
-
"
|
|
859
|
-
|
|
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
|
|
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
|
-
|
|
701
|
+
packages/cli/
|
|
869
702
|
├── src/
|
|
870
|
-
│ ├── index.ts
|
|
871
|
-
│ ├── adapters/
|
|
872
|
-
│
|
|
873
|
-
│
|
|
874
|
-
│
|
|
875
|
-
│
|
|
876
|
-
│
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
-
|
|
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
|