@cavelang/cli 0.3.0 → 0.5.0

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 CHANGED
@@ -7,30 +7,36 @@ TypeScript sources via Node's type stripping; no build step.
7
7
  $ echo 'auth USES jwt @ 90%' | pnpm exec cave parse
8
8
  ok: 1 claim
9
9
 
10
- $ pnpm exec cave add notes.cave --db knowledge.db
10
+ $ pnpm exec cave add --db knowledge.db notes.cave
11
11
  added 12 claim(s), 3 edge(s)
12
12
 
13
- $ pnpm exec cave query '?x USES jwt' --db knowledge.db
13
+ $ pnpm exec cave query --db knowledge.db '?x USES jwt'
14
14
  ?x = auth/middleware
15
15
  ?x = api/gateway
16
16
 
17
- $ pnpm exec cave query '?cause CAUSE app/crash' 'WHERE conf >= 0.7' --db knowledge.db
17
+ $ pnpm exec cave query --db knowledge.db '?cause CAUSE app/crash' 'WHERE conf >= 0.7'
18
18
  $ pnpm exec cave export --db knowledge.db --current
19
19
  $ pnpm exec cave demo
20
20
  ```
21
21
 
22
22
  ## Commands
23
23
 
24
+ Every command answers `--help` with its options and examples (also
25
+ `cave help <command>`). `--db` is optional everywhere: it defaults to
26
+ `$CAVE_DB`, or `cave.db` in the current directory.
27
+
24
28
  | Command | Flags | Behavior |
25
29
  |---|---|---|
26
- | `parse [file]` | `--json` | Lint (stdin by default). Exit 1 when diagnostics exist; `--json` dumps the AST document. |
27
- | `add [file…] --db p` | `--strict`, `--no-prelude` | Ingest. Lenient by default (problems on stderr, valid lines land); `--strict` rolls back on any problem; `--no-prelude` starts from an empty registry instead of the standard §5.5 pairs. |
28
- | `import [file…] --db p` | `--strict`, `--no-prelude` | Restore/merge a database from CAVE text — same operation as `add`, because canonical text *is* the interchange format. |
29
- | `query <pattern…> --db p` | `--json`, `--all`, `--no-prelude` | CAVE-Q. Extra positionals join as lines, so `WHERE` filters ride as separate arguments. Bindings print as `?x = value`; fully bound patterns print the matched raw line (or the pattern itself for transitive matches, which carry no row). `--no-prelude` aligns the read-time registry with a store written via `add --no-prelude`. |
30
- | `export --db p` | `--out <file>`, `--current`, `--no-prelude` | Canonical CAVE text — all rows in tx order, or current beliefs only. Stdout by default; `--out` writes a file and reports the claim count. |
31
- | `mcp --db p` | `--no-prelude` | Serve the engine as an MCP server on stdio (see [`@cavelang/mcp`](../mcp)) — tools for add/query/search/about/neighbors/reconstruct/export/lint, with the §22 spec card as server instructions. |
32
- | `ingest <globs/urls…> --db p` | see `cave ingest --help` | LLM-driven ingestion of files and web pages (fetched and readability-extracted) through any headless agent (see [`@cavelang/ingest`](../ingest)): batching, instructions markdown, hybrid knowledge context, MCP or stdout agents, incremental digests, `--plan` NDJSON for SDK drivers. |
30
+ | `parse [file…]` | `--json` | Lint (stdin by default). Exit 1 when diagnostics exist; `--json` dumps the AST document. |
31
+ | `add [--db p] [file…]` | `--strict`, `--no-prelude` | Ingest. Lenient by default (problems on stderr, valid lines land); `--strict` rolls back on any problem; `--no-prelude` starts from an empty registry instead of the standard §5.5 pairs. |
32
+ | `import [--db p] [file…]` | `--strict`, `--no-prelude` | Restore/merge a database from CAVE text — same operation as `add`, because canonical text *is* the interchange format. |
33
+ | `query [--db p] <pattern…>` | `--json`, `--all`, `--no-prelude` | CAVE-Q. Extra positionals join as lines, so `WHERE` filters ride as separate arguments. Bindings print as `?x = value`; fully bound patterns print the matched raw line (or the pattern itself for transitive matches, which carry no row). `--no-prelude` aligns the read-time registry with a store written via `add --no-prelude`. |
34
+ | `export [--db p]` | `--out <file>`, `--current`, `--no-prelude` | Canonical CAVE text — all rows in tx order, or current beliefs only. Stdout by default; `--out` writes a file and reports the claim count. |
35
+ | `mcp [--db p]` | `--no-prelude` | Serve the engine as an MCP server on stdio (see [`@cavelang/mcp`](../mcp)) — tools for add/query/search/about/neighbors/reconstruct/export/lint, with the §22 spec card as server instructions. |
36
+ | `ingest [--db p] <globs/urls…>` | see `cave ingest --help` | LLM-driven ingestion of files and web pages (fetched and readability-extracted) through any headless agent (see [`@cavelang/ingest`](../ingest)): batching, instructions markdown, hybrid knowledge context, MCP or stdout agents, incremental digests, `--plan` NDJSON for SDK drivers. |
33
37
  | `demo` | | The cave-loop multi-hop recovery demo (§18). |
38
+ | `version` | | Print the cave version. |
39
+ | `help [command]` | | The overview, or one command's options and examples. |
34
40
 
35
41
  ## Text backup / interchange
36
42
 
@@ -38,7 +44,7 @@ $ pnpm exec cave demo
38
44
  $ cave export --db knowledge.db --out backup.cave
39
45
  exported 812 claim(s) to backup.cave
40
46
 
41
- $ cave import backup.cave --db restored.db
47
+ $ cave import --db restored.db backup.cave
42
48
  added 812 claim(s), 37 edge(s)
43
49
  ```
44
50
 
package/dist/src/cli.d.ts CHANGED
@@ -6,21 +6,32 @@
6
6
  * Commands:
7
7
  *
8
8
  * - `cave parse [file]` — lint / dump the AST (`--json`)
9
- * - `cave add [file…] --db <path>` — ingest into a store (`--strict`)
10
- * - `cave query '<pattern>' --db <path>` — CAVE-Q (`--json`, `--all`)
11
- * - `cave export --db <path>` — canonical text out (`--current`)
9
+ * - `cave highlight [file]` — ANSI syntax colors (async, routed in `main.ts`)
10
+ * - `cave add [--db <path>] [file…]` — ingest into a store (`--strict`)
11
+ * - `cave query [--db <path>] '<pattern>'` — CAVE-Q (`--json`, `--all`)
12
+ * - `cave export [--db <path>]` — canonical text out (`--current`)
12
13
  * - `cave demo` — the cave-loop multi-hop recovery demo
13
14
  * - `cave version` — print the cave version
15
+ * - `cave help [command]` — overview, or one command's help
14
16
  *
15
- * `file` defaults to stdin (`-`).
17
+ * `file` defaults to stdin (`-`); `--db` defaults to `$CAVE_DB`, then
18
+ * `cave.db`. Every command answers `--help` with options and examples.
16
19
  */
17
20
  export type Output = {
18
21
  readonly code: number;
19
22
  readonly out: string;
20
23
  readonly err: string;
21
24
  };
22
- export declare const usage = "cave \u2014 Compressed Atomic Verb Expressions\n\nUsage:\n cave parse [file] [--json] lint CAVE text (stdin when no file)\n cave add [file...] --db <path> ingest into a store [--strict] [--no-prelude]\n cave import [file...] --db <path> restore/merge a database from CAVE text (same as add)\n cave query <pattern> --db <path> run a CAVE-Q pattern [--json] [--all] [--no-prelude]\n cave export --db <path> [--out <file>] emit canonical CAVE text [--current] [--no-prelude]\n cave mcp --db <path> serve the engine as an MCP server on stdio [--no-prelude]\n cave ingest <globs/urls...> --db <path> LLM-driven ingestion of files and web pages (cave ingest --help)\n cave demo run the cave-loop reconstruction demo\n cave version print the cave version\n cave help this text\n\nThe spec lives in the .claude/skills/ directory at the repository root\n(section index in README.md).";
25
+ export declare const usage = "cave \u2014 Compressed Atomic Verb Expressions\n\nUsage:\n cave parse [file...] [--json] lint CAVE text (stdin when no file)\n cave highlight [file...] print CAVE text with ANSI syntax colors\n cave add [--db <path>] [file...] ingest into a store [--strict] [--no-prelude]\n cave import [--db <path>] [file...] restore/merge from CAVE text (same as add)\n cave query [--db <path>] <pattern> run a CAVE-Q pattern [--json] [--all] [--no-prelude]\n cave export [--db <path>] [--out <file>] emit canonical CAVE text [--current] [--no-prelude]\n cave mcp [--db <path>] serve the engine as an MCP server on stdio [--no-prelude]\n cave ingest [--db <path>] <globs/urls..> LLM-driven ingestion of files and web pages\n cave demo run the cave-loop reconstruction demo\n cave version print the cave version\n cave help [command] this text, or one command's options and examples\n\nEvery command answers --help. --db defaults to $CAVE_DB, or cave.db in\nthe current directory. The spec lives in the .claude/skills/ directory at\nthe repository root (section index in README.md).";
26
+ /** Per-command help, printed for \`cave <command> --help\` and \`cave help <command>\`. */
27
+ export declare const commandHelp: Record<string, string>;
23
28
  export declare const parseCommand: (argv: readonly string[]) => Output;
29
+ /**
30
+ * `cave highlight` — ANSI syntax colors from the tree-sitter grammar's own
31
+ * highlight query. Async (the grammar WASM loads on first use), so `main.ts`
32
+ * routes it separately, like `mcp` and `ingest`.
33
+ */
34
+ export declare const highlightCommand: (argv: readonly string[]) => Promise<Output>;
24
35
  export declare const addCommand: (argv: readonly string[]) => Output;
25
36
  /**
26
37
  * `cave import` — restore/merge a knowledge database from CAVE text files.
@@ -37,6 +48,8 @@ export declare const queryCommand: (argv: readonly string[]) => Output;
37
48
  export declare const exportCommand: (argv: readonly string[]) => Output;
38
49
  export declare const demoCommand: () => Output;
39
50
  export declare const versionCommand: () => Output;
51
+ /** `cave help [command]` — the overview, or one command's help text. */
52
+ export declare const helpCommand: (argv: readonly string[]) => Output;
40
53
  /** Dispatches one invocation. */
41
54
  export declare const cave: (argv: readonly string[]) => Output;
42
55
  //# sourceMappingURL=cli.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAYH,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB,CAAA;AAQD,eAAO,MAAM,KAAK,+/BAeY,CAAA;AAO9B,eAAO,MAAM,YAAY,GAAI,MAAM,SAAS,MAAM,EAAE,KAAG,MAyBtD,CAAA;AAkCD,eAAO,MAAM,UAAU,SAhCwB,SAAS,MAAM,EAAE,KAAG,MAgCrB,CAAA;AAE9C;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,SA5CqB,SAAS,MAAM,EAAE,KAAG,MA4Cf,CAAA;AAEpD,eAAO,MAAM,YAAY,GAAI,MAAM,SAAS,MAAM,EAAE,KAAG,MAyCtD,CAAA;AAED,eAAO,MAAM,aAAa,GAAI,MAAM,SAAS,MAAM,EAAE,KAAG,MA0BvD,CAAA;AAED,eAAO,MAAM,WAAW,QAAO,MACS,CAAA;AAmBxC,eAAO,MAAM,cAAc,QAAO,MACL,CAAA;AAE7B,iCAAiC;AACjC,eAAO,MAAM,IAAI,GAAI,MAAM,SAAS,MAAM,EAAE,KAAG,MAgC9C,CAAA"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAWH,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB,CAAA;AAQD,eAAO,MAAM,KAAK,2sCAiBgC,CAAA;AAIlD,2FAA2F;AAC3F,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAsH9C,CAAA;AAOD,eAAO,MAAM,YAAY,GAAI,MAAM,SAAS,MAAM,EAAE,KAAG,MAyBtD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAU,MAAM,SAAS,MAAM,EAAE,KAAG,OAAO,CAAC,MAAM,CAM9E,CAAA;AA+BD,eAAO,MAAM,UAAU,SA7BwB,SAAS,MAAM,EAAE,KAAG,MA6BrB,CAAA;AAE9C;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,SAzCqB,SAAS,MAAM,EAAE,KAAG,MAyCf,CAAA;AAEpD,eAAO,MAAM,YAAY,GAAI,MAAM,SAAS,MAAM,EAAE,KAAG,MAsCtD,CAAA;AAED,eAAO,MAAM,aAAa,GAAI,MAAM,SAAS,MAAM,EAAE,KAAG,MAuBvD,CAAA;AAED,eAAO,MAAM,WAAW,QAAO,MACS,CAAA;AAExC,eAAO,MAAM,cAAc,QAAO,MACJ,CAAA;AAE9B,wEAAwE;AACxE,eAAO,MAAM,WAAW,GAAI,MAAM,SAAS,MAAM,EAAE,KAAG,MAcrD,CAAA;AAED,iCAAiC;AACjC,eAAO,MAAM,IAAI,GAAI,MAAM,SAAS,MAAM,EAAE,KAAG,MAqC9C,CAAA"}
package/dist/src/cli.js CHANGED
@@ -6,21 +6,23 @@
6
6
  * Commands:
7
7
  *
8
8
  * - `cave parse [file]` — lint / dump the AST (`--json`)
9
- * - `cave add [file…] --db <path>` — ingest into a store (`--strict`)
10
- * - `cave query '<pattern>' --db <path>` — CAVE-Q (`--json`, `--all`)
11
- * - `cave export --db <path>` — canonical text out (`--current`)
9
+ * - `cave highlight [file]` — ANSI syntax colors (async, routed in `main.ts`)
10
+ * - `cave add [--db <path>] [file…]` — ingest into a store (`--strict`)
11
+ * - `cave query [--db <path>] '<pattern>'` — CAVE-Q (`--json`, `--all`)
12
+ * - `cave export [--db <path>]` — canonical text out (`--current`)
12
13
  * - `cave demo` — the cave-loop multi-hop recovery demo
13
14
  * - `cave version` — print the cave version
15
+ * - `cave help [command]` — overview, or one command's help
14
16
  *
15
- * `file` defaults to stdin (`-`).
17
+ * `file` defaults to stdin (`-`); `--db` defaults to `$CAVE_DB`, then
18
+ * `cave.db`. Every command answers `--help` with options and examples.
16
19
  */
17
- import { existsSync, readFileSync, writeFileSync } from 'node:fs';
18
- import { dirname, join } from 'node:path';
19
- import { fileURLToPath } from 'node:url';
20
+ import { readFileSync, writeFileSync } from 'node:fs';
20
21
  import { parseArgs } from 'node:util';
22
+ import { Version } from '@cavelang/core';
21
23
  import { parseDocument } from '@cavelang/parser';
22
24
  import { Registry, standardRegistry } from '@cavelang/canonical';
23
- import { open } from '@cavelang/store';
25
+ import { defaultDbPath, open } from '@cavelang/store';
24
26
  import { query as caveQuery } from '@cavelang/query';
25
27
  import { Demo } from '@cavelang/loop';
26
28
  const ok = (out) => ({ code: 0, out, err: '' });
@@ -28,19 +30,135 @@ const fail = (err, code = 1) => ({ code, out: '', err });
28
30
  export const usage = `cave — Compressed Atomic Verb Expressions
29
31
 
30
32
  Usage:
31
- cave parse [file] [--json] lint CAVE text (stdin when no file)
32
- cave add [file...] --db <path> ingest into a store [--strict] [--no-prelude]
33
- cave import [file...] --db <path> restore/merge a database from CAVE text (same as add)
34
- cave query <pattern> --db <path> run a CAVE-Q pattern [--json] [--all] [--no-prelude]
35
- cave export --db <path> [--out <file>] emit canonical CAVE text [--current] [--no-prelude]
36
- cave mcp --db <path> serve the engine as an MCP server on stdio [--no-prelude]
37
- cave ingest <globs/urls...> --db <path> LLM-driven ingestion of files and web pages (cave ingest --help)
38
- cave demo run the cave-loop reconstruction demo
39
- cave version print the cave version
40
- cave help this text
41
-
42
- The spec lives in the .claude/skills/ directory at the repository root
43
- (section index in README.md).`;
33
+ cave parse [file...] [--json] lint CAVE text (stdin when no file)
34
+ cave highlight [file...] print CAVE text with ANSI syntax colors
35
+ cave add [--db <path>] [file...] ingest into a store [--strict] [--no-prelude]
36
+ cave import [--db <path>] [file...] restore/merge from CAVE text (same as add)
37
+ cave query [--db <path>] <pattern> run a CAVE-Q pattern [--json] [--all] [--no-prelude]
38
+ cave export [--db <path>] [--out <file>] emit canonical CAVE text [--current] [--no-prelude]
39
+ cave mcp [--db <path>] serve the engine as an MCP server on stdio [--no-prelude]
40
+ cave ingest [--db <path>] <globs/urls..> LLM-driven ingestion of files and web pages
41
+ cave demo run the cave-loop reconstruction demo
42
+ cave version print the cave version
43
+ cave help [command] this text, or one command's options and examples
44
+
45
+ Every command answers --help. --db defaults to $CAVE_DB, or cave.db in
46
+ the current directory. The spec lives in the .claude/skills/ directory at
47
+ the repository root (section index in README.md).`;
48
+ const dbHelp = `--db <path> database file (default: $CAVE_DB, or cave.db)`;
49
+ /** Per-command help, printed for \`cave <command> --help\` and \`cave help <command>\`. */
50
+ export const commandHelp = {
51
+ parse: `cave parse — lint CAVE text, or dump the parsed document
52
+
53
+ Usage:
54
+ cave parse [file...] [--json]
55
+
56
+ Options:
57
+ --json dump the parsed document as JSON instead of a summary
58
+
59
+ Reads stdin when no file (or \`-\`) is given. Exits 1 when the text has
60
+ diagnostics, printing them one per line to stderr.
61
+
62
+ Examples:
63
+ cave parse notes.cave
64
+ echo 'auth USES jwt @ 90%' | cave parse
65
+ cave parse notes.cave --json | jq '.lines[0]'`,
66
+ highlight: `cave highlight — print CAVE text with ANSI syntax colors
67
+
68
+ Usage:
69
+ cave highlight [file...]
70
+
71
+ Reads stdin when no file (or \`-\`) is given. Colors come from the
72
+ tree-sitter grammar's highlight query (@cavelang/tree-sitter-cave), the
73
+ same source editors use. Output always carries ANSI codes — pipe through
74
+ \`less -R\` to page. \`cave export\` colors its output the same way when
75
+ stdout is a terminal (disable with NO_COLOR).
76
+
77
+ Examples:
78
+ cave highlight notes.cave
79
+ echo 'auth USES jwt @ 90%' | cave highlight
80
+ cave highlight notes.cave | less -R`,
81
+ add: `cave add — ingest CAVE text into a knowledge database
82
+
83
+ Usage:
84
+ cave add [--db <path>] [file...] [--strict] [--no-prelude]
85
+
86
+ Options:
87
+ ${dbHelp}
88
+ --strict reject the whole ingest on any problem
89
+ --no-prelude open the store without the standard verb registry
90
+
91
+ Reads stdin when no file (or \`-\`) is given.
92
+
93
+ Examples:
94
+ cave add --db k.db notes.cave
95
+ echo 'auth USES jwt @ 90%' | cave add
96
+ cave add --db k.db --strict reviewed.cave`,
97
+ import: `cave import — restore/merge a database from CAVE text (same as add)
98
+
99
+ Usage:
100
+ cave import [--db <path>] [file...] [--strict] [--no-prelude]
101
+
102
+ Options:
103
+ ${dbHelp}
104
+ --strict reject the whole import on any problem
105
+ --no-prelude open the store without the standard verb registry
106
+
107
+ Canonical CAVE text is the interchange format (spec §2.2): importing a
108
+ file written by \`cave export\` replays its claims append-only, preserving
109
+ the belief series, qualifier edges and in-band declarations.
110
+
111
+ Examples:
112
+ cave export --db old.db --out backup.cave
113
+ cave import --db new.db backup.cave`,
114
+ query: `cave query — run a CAVE-Q pattern against a store
115
+
116
+ Usage:
117
+ cave query [--db <path>] <pattern> [WHERE <filter>] [--json] [--all] [--no-prelude]
118
+
119
+ Options:
120
+ ${dbHelp}
121
+ --json emit matches as JSON
122
+ --all match all beliefs, not just current ones
123
+ --no-prelude open the store without the standard verb registry
124
+
125
+ Patterns are claim triples with ?variables and optional metadata filters
126
+ (spec §12). A second positional starting with WHERE filters on conf,
127
+ value or tx.
128
+
129
+ Examples:
130
+ cave query '?x USES jwt'
131
+ cave query --db k.db '?x HAS bug: ?bug #security'
132
+ cave query --db k.db '?cause CAUSE app/crash' 'WHERE conf >= 0.5'
133
+ cave query --db k.db 'terrier EXTENDS+ animal'
134
+ cave query --db k.db '?x ?verb ?y @production' --json`,
135
+ export: `cave export — emit canonical CAVE text from a store
136
+
137
+ Usage:
138
+ cave export [--db <path>] [--out <file>] [--current] [--no-prelude]
139
+
140
+ Options:
141
+ ${dbHelp}
142
+ --out <file> write to a file instead of stdout
143
+ --current current beliefs only (skip superseded rows)
144
+ --no-prelude open the store without the standard verb registry
145
+
146
+ Examples:
147
+ cave export --db k.db
148
+ cave export --db k.db --out backup.cave
149
+ cave export --db k.db --current --out snapshot.cave`,
150
+ demo: `cave demo — run the cave-loop multi-hop reconstruction demo
151
+
152
+ Usage:
153
+ cave demo
154
+
155
+ Narrates the spec §18 recovery: seed cues expand symptom → cause →
156
+ topic → fix over a small in-memory store.`,
157
+ version: `cave version — print the cave version
158
+
159
+ Usage:
160
+ cave version`
161
+ };
44
162
  const readInput = (files) => files.length === 0 || (files.length === 1 && files[0] === '-') ?
45
163
  readFileSync(0, 'utf8') :
46
164
  files.map(file => readFileSync(file, 'utf8')).join('\n');
@@ -70,6 +188,18 @@ export const parseCommand = (argv) => {
70
188
  .join('\n');
71
189
  return { code: 1, out: `${summary}\n`, err: `${problems}\n` };
72
190
  };
191
+ /**
192
+ * `cave highlight` — ANSI syntax colors from the tree-sitter grammar's own
193
+ * highlight query. Async (the grammar WASM loads on first use), so `main.ts`
194
+ * routes it separately, like `mcp` and `ingest`.
195
+ */
196
+ export const highlightCommand = async (argv) => {
197
+ const { positionals } = parseArgs({ args: [...argv], options: {}, allowPositionals: true });
198
+ const input = readInput(positionals);
199
+ const { highlighter } = await import('@cavelang/highlight');
200
+ const { ansi } = await highlighter();
201
+ return ok(ansi(input));
202
+ };
73
203
  const ingestCommand = (name) => (argv) => {
74
204
  const { values, positionals } = parseArgs({
75
205
  args: [...argv],
@@ -80,11 +210,8 @@ const ingestCommand = (name) => (argv) => {
80
210
  },
81
211
  allowPositionals: true
82
212
  });
83
- if (values.db === undefined) {
84
- return fail(`cave ${name}: --db <path> is required\n`);
85
- }
86
213
  const input = readInput(positionals);
87
- const store = open(values.db, values['no-prelude'] === true ? { registry: Registry.empty } : {});
214
+ const store = open(values.db ?? defaultDbPath(), values['no-prelude'] === true ? { registry: Registry.empty } : {});
88
215
  try {
89
216
  const result = store.ingest(input, { strict: values.strict === true });
90
217
  const problems = result.problems
@@ -126,14 +253,11 @@ export const queryCommand = (argv) => {
126
253
  },
127
254
  allowPositionals: true
128
255
  });
129
- if (values.db === undefined) {
130
- return fail('cave query: --db <path> is required\n');
131
- }
132
256
  if (positionals.length === 0) {
133
257
  return fail('cave query: a pattern is required (spec §12.1)\n');
134
258
  }
135
259
  const pattern = positionals.join('\n');
136
- const store = open(values.db, values['no-prelude'] === true ? { registry: Registry.empty } : {});
260
+ const store = open(values.db ?? defaultDbPath(), values['no-prelude'] === true ? { registry: Registry.empty } : {});
137
261
  try {
138
262
  const matches = caveQuery(store, pattern, { all: values.all === true });
139
263
  if (values.json === true) {
@@ -170,10 +294,7 @@ export const exportCommand = (argv) => {
170
294
  },
171
295
  allowPositionals: false
172
296
  });
173
- if (values.db === undefined) {
174
- return fail('cave export: --db <path> is required\n');
175
- }
176
- const store = open(values.db, values['no-prelude'] === true ? { registry: Registry.empty } : {});
297
+ const store = open(values.db ?? defaultDbPath(), values['no-prelude'] === true ? { registry: Registry.empty } : {});
177
298
  try {
178
299
  const text = store.exportText({ current: values.current === true });
179
300
  if (values.out === undefined) {
@@ -188,28 +309,33 @@ export const exportCommand = (argv) => {
188
309
  }
189
310
  };
190
311
  export const demoCommand = () => ok(`${Demo.run().lines.join('\n')}\n`);
191
- /**
192
- * The CLI runs from `src/` in development and `dist/src/` when published,
193
- * so find our package.json by walking up from this module — the nearest
194
- * one is always the @cavelang/cli manifest.
195
- */
196
- const packageVersion = () => {
197
- for (let dir = dirname(fileURLToPath(import.meta.url));; dir = dirname(dir)) {
198
- const candidate = join(dir, 'package.json');
199
- if (existsSync(candidate)) {
200
- return JSON.parse(readFileSync(candidate, 'utf8')).version;
201
- }
202
- if (dir === dirname(dir)) {
203
- return 'unknown';
204
- }
312
+ export const versionCommand = () => ok(`${Version.current()}\n`);
313
+ /** `cave help [command]` — the overview, or one command's help text. */
314
+ export const helpCommand = (argv) => {
315
+ const [topic] = argv;
316
+ if (topic === undefined) {
317
+ return ok(`${usage}\n`);
318
+ }
319
+ const text = commandHelp[topic === 'q' ? 'query' : topic];
320
+ if (text !== undefined) {
321
+ return ok(`${text}\n`);
322
+ }
323
+ // mcp and ingest own their help (main.ts forwards `help X` to `X --help`).
324
+ if (topic === 'mcp' || topic === 'ingest') {
325
+ return ok(`see: cave ${topic} --help\n`);
205
326
  }
327
+ return fail(`cave help: unknown command ${JSON.stringify(topic)}\n\n${usage}\n`, 2);
206
328
  };
207
- export const versionCommand = () => ok(`${packageVersion()}\n`);
208
329
  /** Dispatches one invocation. */
209
330
  export const cave = (argv) => {
210
331
  const [command, ...rest] = argv;
332
+ const canonical = command === 'q' ? 'query' : command;
211
333
  try {
212
- switch (command) {
334
+ if (canonical !== undefined && canonical in commandHelp &&
335
+ (rest.includes('--help') || rest.includes('-h'))) {
336
+ return ok(`${commandHelp[canonical]}\n`);
337
+ }
338
+ switch (canonical) {
213
339
  case 'parse':
214
340
  return parseCommand(rest);
215
341
  case 'add':
@@ -217,7 +343,6 @@ export const cave = (argv) => {
217
343
  case 'import':
218
344
  return importCommand(rest);
219
345
  case 'query':
220
- case 'q':
221
346
  return queryCommand(rest);
222
347
  case 'export':
223
348
  return exportCommand(rest);
@@ -227,8 +352,9 @@ export const cave = (argv) => {
227
352
  case '--version':
228
353
  case '-v':
229
354
  return versionCommand();
230
- case undefined:
231
355
  case 'help':
356
+ return helpCommand(rest);
357
+ case undefined:
232
358
  case '--help':
233
359
  case '-h':
234
360
  return ok(`${usage}\n`);
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,6 @@
2
2
  * `@cavelang/cli` — the `cave` command (parse / add / query / export / demo).
3
3
  * Programmatic access to the same implementations lives here.
4
4
  */
5
- export { addCommand, cave, demoCommand, exportCommand, importCommand, parseCommand, queryCommand, usage, versionCommand } from './cli.ts';
5
+ export { addCommand, cave, commandHelp, demoCommand, exportCommand, helpCommand, highlightCommand, importCommand, parseCommand, queryCommand, usage, versionCommand } from './cli.ts';
6
6
  export type { Output } from './cli.ts';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AACzI,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AACrL,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA"}
package/dist/src/index.js CHANGED
@@ -2,5 +2,5 @@
2
2
  * `@cavelang/cli` — the `cave` command (parse / add / query / export / demo).
3
3
  * Programmatic access to the same implementations lives here.
4
4
  */
5
- export { addCommand, cave, demoCommand, exportCommand, importCommand, parseCommand, queryCommand, usage, versionCommand } from "./cli.js";
5
+ export { addCommand, cave, commandHelp, demoCommand, exportCommand, helpCommand, highlightCommand, importCommand, parseCommand, queryCommand, usage, versionCommand } from "./cli.js";
6
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA"}
package/dist/src/main.js CHANGED
@@ -1,7 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  /** `cave` binary entry point — see `cli.ts` for the command implementations. */
3
- import { cave } from "./cli.js";
4
- const argv = process.argv.slice(2);
3
+ import { cave, highlightCommand } from "./cli.js";
4
+ const write = (code, out, err) => {
5
+ if (out !== '') {
6
+ process.stdout.write(out);
7
+ }
8
+ if (err !== '') {
9
+ process.stderr.write(err);
10
+ }
11
+ process.exitCode = code;
12
+ };
13
+ // mcp and ingest own their help text, so `cave help X` becomes `cave X --help`.
14
+ const raw = process.argv.slice(2);
15
+ const argv = raw[0] === 'help' && (raw[1] === 'mcp' || raw[1] === 'ingest') ?
16
+ [raw[1], '--help'] :
17
+ raw;
5
18
  if (argv[0] === 'mcp') {
6
19
  // Long-running: serves MCP on stdio until the client disconnects.
7
20
  const { runMcp } = await import('@cavelang/mcp');
@@ -12,14 +25,23 @@ else if (argv[0] === 'ingest') {
12
25
  const { runIngest } = await import('@cavelang/ingest');
13
26
  process.exitCode = await runIngest(argv.slice(1));
14
27
  }
28
+ else if (argv[0] === 'highlight' && !argv.includes('--help') && !argv.includes('-h')) {
29
+ // Async (grammar WASM loads on first use); --help stays on the sync path.
30
+ const { code, out, err } = await highlightCommand(argv.slice(1));
31
+ write(code, out, err);
32
+ }
15
33
  else {
16
34
  const { code, out, err } = cave(argv);
17
- if (out !== '') {
18
- process.stdout.write(out);
35
+ // Canonical CAVE text going to a terminal gets syntax colors from the same
36
+ // grammar query `cave highlight` uses; piping or NO_COLOR keeps bytes clean.
37
+ const colorize = code === 0 && argv[0] === 'export' && !argv.includes('--out') &&
38
+ out !== '' && process.stdout.isTTY === true && process.env['NO_COLOR'] === undefined;
39
+ if (colorize) {
40
+ const { highlighter } = await import('@cavelang/highlight');
41
+ write(code, (await highlighter()).ansi(out), err);
19
42
  }
20
- if (err !== '') {
21
- process.stderr.write(err);
43
+ else {
44
+ write(code, out, err);
22
45
  }
23
- process.exitCode = code;
24
46
  }
25
47
  //# sourceMappingURL=main.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":";AACA,gFAAgF;AAEhF,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AAE/B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AAClC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;IACtB,kEAAkE;IAClE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;IAChD,OAAO,CAAC,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AAChD,CAAC;KAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;IAChC,2DAA2D;IAC3D,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;IACtD,OAAO,CAAC,QAAQ,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AACnD,CAAC;KAAM,CAAC;IACN,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAA;IACrC,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC3B,CAAC;IACD,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC3B,CAAC;IACD,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAA;AACzB,CAAC"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":";AACA,gFAAgF;AAEhF,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAEjD,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,GAAW,EAAE,GAAW,EAAQ,EAAE;IAC7D,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC3B,CAAC;IACD,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC3B,CAAC;IACD,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAA;AACzB,CAAC,CAAA;AAED,gFAAgF;AAChF,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACjC,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC;IAC3E,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;IACpB,GAAG,CAAA;AACL,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;IACtB,kEAAkE;IAClE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;IAChD,OAAO,CAAC,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AAChD,CAAC;KAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;IAChC,2DAA2D;IAC3D,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;IACtD,OAAO,CAAC,QAAQ,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AACnD,CAAC;KAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACvF,0EAA0E;IAC1E,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IAChE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AACvB,CAAC;KAAM,CAAC;IACN,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAA;IACrC,2EAA2E;IAC3E,6EAA6E;IAC7E,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QAC5E,GAAG,KAAK,EAAE,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,SAAS,CAAA;IACtF,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAA;QAC3D,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;IACnD,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IACvB,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cavelang/cli",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "description": "cave — CLI for parsing, storing, querying and exporting CAVE knowledge.",
6
6
  "license": "CC0-1.0",
@@ -39,14 +39,15 @@
39
39
  "access": "public"
40
40
  },
41
41
  "dependencies": {
42
- "@cavelang/canonical": "0.3.0",
43
- "@cavelang/ingest": "0.3.0",
44
- "@cavelang/core": "0.3.0",
45
- "@cavelang/mcp": "0.3.0",
46
- "@cavelang/query": "0.3.0",
47
- "@cavelang/loop": "0.3.0",
48
- "@cavelang/parser": "0.3.0",
49
- "@cavelang/store": "0.3.0"
42
+ "@cavelang/canonical": "0.5.0",
43
+ "@cavelang/core": "0.5.0",
44
+ "@cavelang/ingest": "0.5.0",
45
+ "@cavelang/highlight": "0.5.0",
46
+ "@cavelang/loop": "0.5.0",
47
+ "@cavelang/mcp": "0.5.0",
48
+ "@cavelang/parser": "0.5.0",
49
+ "@cavelang/query": "0.5.0",
50
+ "@cavelang/store": "0.5.0"
50
51
  },
51
52
  "scripts": {
52
53
  "build": "tsc -b",
package/src/cli.ts CHANGED
@@ -6,22 +6,24 @@
6
6
  * Commands:
7
7
  *
8
8
  * - `cave parse [file]` — lint / dump the AST (`--json`)
9
- * - `cave add [file…] --db <path>` — ingest into a store (`--strict`)
10
- * - `cave query '<pattern>' --db <path>` — CAVE-Q (`--json`, `--all`)
11
- * - `cave export --db <path>` — canonical text out (`--current`)
9
+ * - `cave highlight [file]` — ANSI syntax colors (async, routed in `main.ts`)
10
+ * - `cave add [--db <path>] [file…]` — ingest into a store (`--strict`)
11
+ * - `cave query [--db <path>] '<pattern>'` — CAVE-Q (`--json`, `--all`)
12
+ * - `cave export [--db <path>]` — canonical text out (`--current`)
12
13
  * - `cave demo` — the cave-loop multi-hop recovery demo
13
14
  * - `cave version` — print the cave version
15
+ * - `cave help [command]` — overview, or one command's help
14
16
  *
15
- * `file` defaults to stdin (`-`).
17
+ * `file` defaults to stdin (`-`); `--db` defaults to `$CAVE_DB`, then
18
+ * `cave.db`. Every command answers `--help` with options and examples.
16
19
  */
17
20
 
18
- import { existsSync, readFileSync, writeFileSync } from 'node:fs'
19
- import { dirname, join } from 'node:path'
20
- import { fileURLToPath } from 'node:url'
21
+ import { readFileSync, writeFileSync } from 'node:fs'
21
22
  import { parseArgs } from 'node:util'
23
+ import { Version } from '@cavelang/core'
22
24
  import { parseDocument } from '@cavelang/parser'
23
25
  import { Registry, standardRegistry } from '@cavelang/canonical'
24
- import { open } from '@cavelang/store'
26
+ import { defaultDbPath, open } from '@cavelang/store'
25
27
  import { query as caveQuery } from '@cavelang/query'
26
28
  import { Demo } from '@cavelang/loop'
27
29
 
@@ -40,19 +42,144 @@ const fail = (err: string, code = 1): Output =>
40
42
  export const usage = `cave — Compressed Atomic Verb Expressions
41
43
 
42
44
  Usage:
43
- cave parse [file] [--json] lint CAVE text (stdin when no file)
44
- cave add [file...] --db <path> ingest into a store [--strict] [--no-prelude]
45
- cave import [file...] --db <path> restore/merge a database from CAVE text (same as add)
46
- cave query <pattern> --db <path> run a CAVE-Q pattern [--json] [--all] [--no-prelude]
47
- cave export --db <path> [--out <file>] emit canonical CAVE text [--current] [--no-prelude]
48
- cave mcp --db <path> serve the engine as an MCP server on stdio [--no-prelude]
49
- cave ingest <globs/urls...> --db <path> LLM-driven ingestion of files and web pages (cave ingest --help)
50
- cave demo run the cave-loop reconstruction demo
51
- cave version print the cave version
52
- cave help this text
53
-
54
- The spec lives in the .claude/skills/ directory at the repository root
55
- (section index in README.md).`
45
+ cave parse [file...] [--json] lint CAVE text (stdin when no file)
46
+ cave highlight [file...] print CAVE text with ANSI syntax colors
47
+ cave add [--db <path>] [file...] ingest into a store [--strict] [--no-prelude]
48
+ cave import [--db <path>] [file...] restore/merge from CAVE text (same as add)
49
+ cave query [--db <path>] <pattern> run a CAVE-Q pattern [--json] [--all] [--no-prelude]
50
+ cave export [--db <path>] [--out <file>] emit canonical CAVE text [--current] [--no-prelude]
51
+ cave mcp [--db <path>] serve the engine as an MCP server on stdio [--no-prelude]
52
+ cave ingest [--db <path>] <globs/urls..> LLM-driven ingestion of files and web pages
53
+ cave demo run the cave-loop reconstruction demo
54
+ cave version print the cave version
55
+ cave help [command] this text, or one command's options and examples
56
+
57
+ Every command answers --help. --db defaults to $CAVE_DB, or cave.db in
58
+ the current directory. The spec lives in the .claude/skills/ directory at
59
+ the repository root (section index in README.md).`
60
+
61
+ const dbHelp = `--db <path> database file (default: $CAVE_DB, or cave.db)`
62
+
63
+ /** Per-command help, printed for \`cave <command> --help\` and \`cave help <command>\`. */
64
+ export const commandHelp: Record<string, string> = {
65
+ parse: `cave parse — lint CAVE text, or dump the parsed document
66
+
67
+ Usage:
68
+ cave parse [file...] [--json]
69
+
70
+ Options:
71
+ --json dump the parsed document as JSON instead of a summary
72
+
73
+ Reads stdin when no file (or \`-\`) is given. Exits 1 when the text has
74
+ diagnostics, printing them one per line to stderr.
75
+
76
+ Examples:
77
+ cave parse notes.cave
78
+ echo 'auth USES jwt @ 90%' | cave parse
79
+ cave parse notes.cave --json | jq '.lines[0]'`,
80
+
81
+ highlight: `cave highlight — print CAVE text with ANSI syntax colors
82
+
83
+ Usage:
84
+ cave highlight [file...]
85
+
86
+ Reads stdin when no file (or \`-\`) is given. Colors come from the
87
+ tree-sitter grammar's highlight query (@cavelang/tree-sitter-cave), the
88
+ same source editors use. Output always carries ANSI codes — pipe through
89
+ \`less -R\` to page. \`cave export\` colors its output the same way when
90
+ stdout is a terminal (disable with NO_COLOR).
91
+
92
+ Examples:
93
+ cave highlight notes.cave
94
+ echo 'auth USES jwt @ 90%' | cave highlight
95
+ cave highlight notes.cave | less -R`,
96
+
97
+ add: `cave add — ingest CAVE text into a knowledge database
98
+
99
+ Usage:
100
+ cave add [--db <path>] [file...] [--strict] [--no-prelude]
101
+
102
+ Options:
103
+ ${dbHelp}
104
+ --strict reject the whole ingest on any problem
105
+ --no-prelude open the store without the standard verb registry
106
+
107
+ Reads stdin when no file (or \`-\`) is given.
108
+
109
+ Examples:
110
+ cave add --db k.db notes.cave
111
+ echo 'auth USES jwt @ 90%' | cave add
112
+ cave add --db k.db --strict reviewed.cave`,
113
+
114
+ import: `cave import — restore/merge a database from CAVE text (same as add)
115
+
116
+ Usage:
117
+ cave import [--db <path>] [file...] [--strict] [--no-prelude]
118
+
119
+ Options:
120
+ ${dbHelp}
121
+ --strict reject the whole import on any problem
122
+ --no-prelude open the store without the standard verb registry
123
+
124
+ Canonical CAVE text is the interchange format (spec §2.2): importing a
125
+ file written by \`cave export\` replays its claims append-only, preserving
126
+ the belief series, qualifier edges and in-band declarations.
127
+
128
+ Examples:
129
+ cave export --db old.db --out backup.cave
130
+ cave import --db new.db backup.cave`,
131
+
132
+ query: `cave query — run a CAVE-Q pattern against a store
133
+
134
+ Usage:
135
+ cave query [--db <path>] <pattern> [WHERE <filter>] [--json] [--all] [--no-prelude]
136
+
137
+ Options:
138
+ ${dbHelp}
139
+ --json emit matches as JSON
140
+ --all match all beliefs, not just current ones
141
+ --no-prelude open the store without the standard verb registry
142
+
143
+ Patterns are claim triples with ?variables and optional metadata filters
144
+ (spec §12). A second positional starting with WHERE filters on conf,
145
+ value or tx.
146
+
147
+ Examples:
148
+ cave query '?x USES jwt'
149
+ cave query --db k.db '?x HAS bug: ?bug #security'
150
+ cave query --db k.db '?cause CAUSE app/crash' 'WHERE conf >= 0.5'
151
+ cave query --db k.db 'terrier EXTENDS+ animal'
152
+ cave query --db k.db '?x ?verb ?y @production' --json`,
153
+
154
+ export: `cave export — emit canonical CAVE text from a store
155
+
156
+ Usage:
157
+ cave export [--db <path>] [--out <file>] [--current] [--no-prelude]
158
+
159
+ Options:
160
+ ${dbHelp}
161
+ --out <file> write to a file instead of stdout
162
+ --current current beliefs only (skip superseded rows)
163
+ --no-prelude open the store without the standard verb registry
164
+
165
+ Examples:
166
+ cave export --db k.db
167
+ cave export --db k.db --out backup.cave
168
+ cave export --db k.db --current --out snapshot.cave`,
169
+
170
+ demo: `cave demo — run the cave-loop multi-hop reconstruction demo
171
+
172
+ Usage:
173
+ cave demo
174
+
175
+ Narrates the spec §18 recovery: seed cues expand symptom → cause →
176
+ topic → fix over a small in-memory store.`,
177
+
178
+ version: `cave version — print the cave version
179
+
180
+ Usage:
181
+ cave version`
182
+ }
56
183
 
57
184
  const readInput = (files: readonly string[]): string =>
58
185
  files.length === 0 || (files.length === 1 && files[0] === '-') ?
@@ -86,6 +213,19 @@ export const parseCommand = (argv: readonly string[]): Output => {
86
213
  return { code: 1, out: `${summary}\n`, err: `${problems}\n` }
87
214
  }
88
215
 
216
+ /**
217
+ * `cave highlight` — ANSI syntax colors from the tree-sitter grammar's own
218
+ * highlight query. Async (the grammar WASM loads on first use), so `main.ts`
219
+ * routes it separately, like `mcp` and `ingest`.
220
+ */
221
+ export const highlightCommand = async (argv: readonly string[]): Promise<Output> => {
222
+ const { positionals } = parseArgs({ args: [...argv], options: {}, allowPositionals: true })
223
+ const input = readInput(positionals)
224
+ const { highlighter } = await import('@cavelang/highlight')
225
+ const { ansi } = await highlighter()
226
+ return ok(ansi(input))
227
+ }
228
+
89
229
  const ingestCommand = (name: string) => (argv: readonly string[]): Output => {
90
230
  const { values, positionals } = parseArgs({
91
231
  args: [...argv],
@@ -96,11 +236,8 @@ const ingestCommand = (name: string) => (argv: readonly string[]): Output => {
96
236
  },
97
237
  allowPositionals: true
98
238
  })
99
- if (values.db === undefined) {
100
- return fail(`cave ${name}: --db <path> is required\n`)
101
- }
102
239
  const input = readInput(positionals)
103
- const store = open(values.db, values['no-prelude'] === true ? { registry: Registry.empty } : {})
240
+ const store = open(values.db ?? defaultDbPath(), values['no-prelude'] === true ? { registry: Registry.empty } : {})
104
241
  try {
105
242
  const result = store.ingest(input, { strict: values.strict === true })
106
243
  const problems = result.problems
@@ -143,14 +280,11 @@ export const queryCommand = (argv: readonly string[]): Output => {
143
280
  },
144
281
  allowPositionals: true
145
282
  })
146
- if (values.db === undefined) {
147
- return fail('cave query: --db <path> is required\n')
148
- }
149
283
  if (positionals.length === 0) {
150
284
  return fail('cave query: a pattern is required (spec §12.1)\n')
151
285
  }
152
286
  const pattern = positionals.join('\n')
153
- const store = open(values.db, values['no-prelude'] === true ? { registry: Registry.empty } : {})
287
+ const store = open(values.db ?? defaultDbPath(), values['no-prelude'] === true ? { registry: Registry.empty } : {})
154
288
  try {
155
289
  const matches = caveQuery(store, pattern, { all: values.all === true })
156
290
  if (values.json === true) {
@@ -186,10 +320,7 @@ export const exportCommand = (argv: readonly string[]): Output => {
186
320
  },
187
321
  allowPositionals: false
188
322
  })
189
- if (values.db === undefined) {
190
- return fail('cave export: --db <path> is required\n')
191
- }
192
- const store = open(values.db, values['no-prelude'] === true ? { registry: Registry.empty } : {})
323
+ const store = open(values.db ?? defaultDbPath(), values['no-prelude'] === true ? { registry: Registry.empty } : {})
193
324
  try {
194
325
  const text = store.exportText({ current: values.current === true })
195
326
  if (values.out === undefined) {
@@ -206,31 +337,36 @@ export const exportCommand = (argv: readonly string[]): Output => {
206
337
  export const demoCommand = (): Output =>
207
338
  ok(`${Demo.run().lines.join('\n')}\n`)
208
339
 
209
- /**
210
- * The CLI runs from `src/` in development and `dist/src/` when published,
211
- * so find our package.json by walking up from this module — the nearest
212
- * one is always the @cavelang/cli manifest.
213
- */
214
- const packageVersion = (): string => {
215
- for (let dir = dirname(fileURLToPath(import.meta.url)); ; dir = dirname(dir)) {
216
- const candidate = join(dir, 'package.json')
217
- if (existsSync(candidate)) {
218
- return (JSON.parse(readFileSync(candidate, 'utf8')) as { version: string }).version
219
- }
220
- if (dir === dirname(dir)) {
221
- return 'unknown'
222
- }
340
+ export const versionCommand = (): Output =>
341
+ ok(`${Version.current()}\n`)
342
+
343
+ /** `cave help [command]` — the overview, or one command's help text. */
344
+ export const helpCommand = (argv: readonly string[]): Output => {
345
+ const [topic] = argv
346
+ if (topic === undefined) {
347
+ return ok(`${usage}\n`)
348
+ }
349
+ const text = commandHelp[topic === 'q' ? 'query' : topic]
350
+ if (text !== undefined) {
351
+ return ok(`${text}\n`)
223
352
  }
353
+ // mcp and ingest own their help (main.ts forwards `help X` to `X --help`).
354
+ if (topic === 'mcp' || topic === 'ingest') {
355
+ return ok(`see: cave ${topic} --help\n`)
356
+ }
357
+ return fail(`cave help: unknown command ${JSON.stringify(topic)}\n\n${usage}\n`, 2)
224
358
  }
225
359
 
226
- export const versionCommand = (): Output =>
227
- ok(`${packageVersion()}\n`)
228
-
229
360
  /** Dispatches one invocation. */
230
361
  export const cave = (argv: readonly string[]): Output => {
231
362
  const [command, ...rest] = argv
363
+ const canonical = command === 'q' ? 'query' : command
232
364
  try {
233
- switch (command) {
365
+ if (canonical !== undefined && canonical in commandHelp &&
366
+ (rest.includes('--help') || rest.includes('-h'))) {
367
+ return ok(`${commandHelp[canonical]}\n`)
368
+ }
369
+ switch (canonical) {
234
370
  case 'parse':
235
371
  return parseCommand(rest)
236
372
  case 'add':
@@ -238,7 +374,6 @@ export const cave = (argv: readonly string[]): Output => {
238
374
  case 'import':
239
375
  return importCommand(rest)
240
376
  case 'query':
241
- case 'q':
242
377
  return queryCommand(rest)
243
378
  case 'export':
244
379
  return exportCommand(rest)
@@ -248,8 +383,9 @@ export const cave = (argv: readonly string[]): Output => {
248
383
  case '--version':
249
384
  case '-v':
250
385
  return versionCommand()
251
- case undefined:
252
386
  case 'help':
387
+ return helpCommand(rest)
388
+ case undefined:
253
389
  case '--help':
254
390
  case '-h':
255
391
  return ok(`${usage}\n`)
package/src/index.ts CHANGED
@@ -3,5 +3,5 @@
3
3
  * Programmatic access to the same implementations lives here.
4
4
  */
5
5
 
6
- export { addCommand, cave, demoCommand, exportCommand, importCommand, parseCommand, queryCommand, usage, versionCommand } from './cli.ts'
6
+ export { addCommand, cave, commandHelp, demoCommand, exportCommand, helpCommand, highlightCommand, importCommand, parseCommand, queryCommand, usage, versionCommand } from './cli.ts'
7
7
  export type { Output } from './cli.ts'
package/src/main.ts CHANGED
@@ -1,9 +1,23 @@
1
1
  #!/usr/bin/env node
2
2
  /** `cave` binary entry point — see `cli.ts` for the command implementations. */
3
3
 
4
- import { cave } from './cli.ts'
4
+ import { cave, highlightCommand } from './cli.ts'
5
5
 
6
- const argv = process.argv.slice(2)
6
+ const write = (code: number, out: string, err: string): void => {
7
+ if (out !== '') {
8
+ process.stdout.write(out)
9
+ }
10
+ if (err !== '') {
11
+ process.stderr.write(err)
12
+ }
13
+ process.exitCode = code
14
+ }
15
+
16
+ // mcp and ingest own their help text, so `cave help X` becomes `cave X --help`.
17
+ const raw = process.argv.slice(2)
18
+ const argv = raw[0] === 'help' && (raw[1] === 'mcp' || raw[1] === 'ingest') ?
19
+ [raw[1], '--help'] :
20
+ raw
7
21
  if (argv[0] === 'mcp') {
8
22
  // Long-running: serves MCP on stdio until the client disconnects.
9
23
  const { runMcp } = await import('@cavelang/mcp')
@@ -12,13 +26,20 @@ if (argv[0] === 'mcp') {
12
26
  // Long-running: drives an LLM agent over batches of files.
13
27
  const { runIngest } = await import('@cavelang/ingest')
14
28
  process.exitCode = await runIngest(argv.slice(1))
29
+ } else if (argv[0] === 'highlight' && !argv.includes('--help') && !argv.includes('-h')) {
30
+ // Async (grammar WASM loads on first use); --help stays on the sync path.
31
+ const { code, out, err } = await highlightCommand(argv.slice(1))
32
+ write(code, out, err)
15
33
  } else {
16
34
  const { code, out, err } = cave(argv)
17
- if (out !== '') {
18
- process.stdout.write(out)
35
+ // Canonical CAVE text going to a terminal gets syntax colors from the same
36
+ // grammar query `cave highlight` uses; piping or NO_COLOR keeps bytes clean.
37
+ const colorize = code === 0 && argv[0] === 'export' && !argv.includes('--out') &&
38
+ out !== '' && process.stdout.isTTY === true && process.env['NO_COLOR'] === undefined
39
+ if (colorize) {
40
+ const { highlighter } = await import('@cavelang/highlight')
41
+ write(code, (await highlighter()).ansi(out), err)
42
+ } else {
43
+ write(code, out, err)
19
44
  }
20
- if (err !== '') {
21
- process.stderr.write(err)
22
- }
23
- process.exitCode = code
24
45
  }
package/License.md DELETED
@@ -1,6 +0,0 @@
1
- # CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
2
-
3
- To the extent possible under law, the authors listed in [Authors.md](./Authors.md) have waived all copyright and related or neighboring rights to this software and associated documentation files (the "Software").
4
-
5
- For more information, please see:
6
- https://creativecommons.org/publicdomain/zero/1.0/