@cavelang/cli 0.32.3 → 0.34.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 +16 -3
- package/dist/internal/automate/main.d.ts.map +1 -1
- package/dist/internal/automate/main.js +7 -2
- package/dist/internal/automate/main.js.map +1 -1
- package/dist/internal/connect/main.d.ts.map +1 -1
- package/dist/internal/connect/main.js +16 -10
- package/dist/internal/connect/main.js.map +1 -1
- package/dist/internal/connect/template.d.ts +9 -2
- package/dist/internal/connect/template.d.ts.map +1 -1
- package/dist/internal/connect/template.js +36 -5
- package/dist/internal/connect/template.js.map +1 -1
- package/dist/internal/ingest/main.d.ts.map +1 -1
- package/dist/internal/ingest/main.js +18 -2
- package/dist/internal/ingest/main.js.map +1 -1
- package/dist/internal/loop/demo.d.ts.map +1 -1
- package/dist/internal/loop/demo.js +2 -1
- package/dist/internal/loop/demo.js.map +1 -1
- package/dist/internal/mcp/guide.js +3 -3
- package/dist/internal/mcp/guide.js.map +1 -1
- package/dist/internal/mcp/main.d.ts +1 -1
- package/dist/internal/mcp/main.d.ts.map +1 -1
- package/dist/internal/mcp/main.js +13 -3
- package/dist/internal/mcp/main.js.map +1 -1
- package/dist/internal/mcp/tools.d.ts.map +1 -1
- package/dist/internal/mcp/tools.js +39 -10
- package/dist/internal/mcp/tools.js.map +1 -1
- package/dist/internal/sync/sync.d.ts +2 -3
- package/dist/internal/sync/sync.d.ts.map +1 -1
- package/dist/internal/sync/sync.js +3 -15
- package/dist/internal/sync/sync.js.map +1 -1
- package/dist/internal/view/main.js +3 -3
- package/dist/internal/view/main.js.map +1 -1
- package/dist/internal/view/report.d.ts.map +1 -1
- package/dist/internal/view/report.js +6 -1
- package/dist/internal/view/report.js.map +1 -1
- package/dist/src/cli.d.ts +14 -5
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +224 -34
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands.d.ts +3 -0
- package/dist/src/commands.d.ts.map +1 -1
- package/dist/src/commands.js +1 -0
- package/dist/src/commands.js.map +1 -1
- package/dist/src/dispatch.d.ts.map +1 -1
- package/dist/src/dispatch.js +3 -1
- package/dist/src/dispatch.js.map +1 -1
- package/dist/src/doctor.js +1 -1
- package/dist/src/doctor.js.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -2
- package/dist/src/index.js.map +1 -1
- package/package.json +19 -19
- package/src/cli.ts +232 -37
- package/src/commands.ts +1 -0
- package/src/dispatch.ts +3 -1
- package/src/doctor.ts +1 -1
- package/src/index.ts +2 -2
package/dist/src/cli.d.ts
CHANGED
|
@@ -9,12 +9,13 @@
|
|
|
9
9
|
* - `cave highlight [file]` — ANSI syntax colors (async)
|
|
10
10
|
* - `cave add [--db <path>] [file…]` — ingest into a store (`--strict`, `--check`)
|
|
11
11
|
* - `cave query [--db <path>] '<pattern>'` — CAVE-Q (`--json`, `--all`, `--aliases`, `--as-of`, `--resolve`)
|
|
12
|
+
* - `cave search [--db <path>] <terms..>` — FTS5 full-text search over claims and comments (`--raw`, `--limit`, `--json`)
|
|
12
13
|
* - `cave resolve [--db <path>]` — contested facts under the §26 policy (`--aliases`, `--policy`, `--json`)
|
|
13
14
|
* - `cave derive [--db <path>] [rules.cave…]` — fire rules (`--dry-run`, `--full`, `--list`, `--retract`)
|
|
14
15
|
* - `cave act [--db <path>] <name> [param=value…]` — execute an action (spec §25; `--declare`, `--list`, `--retract`)
|
|
15
16
|
* - `cave automate [--db <path>]` — the event-driven loop (spec §29; async)
|
|
16
17
|
* - `cave check [--db <path>]` — knowledge health report (`--stale`, `--json`)
|
|
17
|
-
* - `cave backup [--db <path>] --out <path>` — exact verified
|
|
18
|
+
* - `cave backup [--db <path>] --out <path>` — exact verified store snapshot
|
|
18
19
|
* - `cave restore <snapshot> --db <path>` — verify and atomically restore a snapshot
|
|
19
20
|
* - `cave generate [--db <path>]` — versioned TypeScript client from EXPECTS declarations
|
|
20
21
|
* - `cave suggest-alias [--db <path>]` — same-entity candidates (spec §27; async)
|
|
@@ -38,7 +39,7 @@ export type Output = {
|
|
|
38
39
|
readonly out: string;
|
|
39
40
|
readonly err: string;
|
|
40
41
|
};
|
|
41
|
-
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] [--check] [--no-prelude] [--no-src]\n cave import [--db <path>] [file...] restore/merge from CAVE text (add without @src: stamping)\n cave query [--db <path>] <pattern> run a bounded CAVE-Q page [--limit <n>] [--cursor <token>] [--json]\n cave resolve [--db <path>] contested facts + winners (spec \u00A726) [--aliases] [--policy] [--json]\n cave derive [--db <path>] [rules.cave..] declare + fire rules (spec \u00A724) [--dry-run] [--full] [--list] [--retract <rule>]\n cave act [--db <path>] <name> [p=v...] execute an action (spec \u00A725) [--dry-run] [--no-check] [--hooks <file>]\n cave act --declare [file...] declare actions from a CAVE document; --list / --retract <name> manage them\n cave automate [--db <path>] event-driven loop (spec \u00A729): new claims fire rules/actions/hooks/agent prompts [--once]\n cave check [--db <path>] knowledge health report (spec \u00A720) [--stale <days>] [--json]\n cave backup [--db <path>] --out <file> exact verified
|
|
42
|
+
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] [--check] [--no-prelude] [--no-src]\n cave import [--db <path>] [file...] restore/merge from CAVE text (add without @src: stamping)\n cave query [--db <path>] <pattern> run a bounded CAVE-Q page [--limit <n>] [--cursor <token>] [--json]\n cave search [--db <path>] <terms..> full-text search over claims and comments (FTS5) [--raw] [--limit <n>] [--json]\n cave resolve [--db <path>] contested facts + winners (spec \u00A726) [--aliases] [--policy] [--json]\n cave derive [--db <path>] [rules.cave..] declare + fire rules (spec \u00A724) [--dry-run] [--full] [--list] [--retract <rule>]\n cave act [--db <path>] <name> [p=v...] execute an action (spec \u00A725) [--dry-run] [--no-check] [--hooks <file>]\n cave act --declare [file...] declare actions from a CAVE document; --list / --retract <name> manage them\n cave automate [--db <path>] event-driven loop (spec \u00A729): new claims fire rules/actions/hooks/agent prompts [--once]\n cave check [--db <path>] knowledge health report (spec \u00A720) [--stale <days>] [--json]\n cave backup [--db <path>] --out <file> exact verified store snapshot [--force]\n cave restore <snapshot> --db <path> verify and atomically restore an exact snapshot [--force]\n cave generate [--db <path>] generate a typed client from EXPECTS [--out <file>] [--version <n>]\n cave suggest-alias [--db <path>] propose same-entity ALIAS candidates (spec \u00A727) [--min <s>] [--agent] [--write]\n cave sync [--db <path>] <source> merge another store by row identity (spec \u00A728) [--dry-run] [--as] [--into]\n cave export [--db <path>] [--out <file>] emit filtered canonical CAVE text [--max-sensitivity <level>]\n cave serve [--db <path>] browse a filtered store (spec \u00A730) [--max-sensitivity <level>]\n cave report [--db <path>] [template...] render filtered cited markdown (spec \u00A731) [--max-sensitivity <level>]\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 eval <suite..> --agent '<command>' golden-fixture extraction/query/reconstruction evals\n cave connect <source> --map <file> deterministic structured ingestion (CSV/JSON/SQLite/URL, spec \u00A723)\n cave reconstruct [--db <path>] <seed..> reconstruct memory from seed cues (spec \u00A718) [--agent] [--query] [--trace]\n cave doctor [--db <path>] diagnose runtime, installation, and store health [--hooks <file>] [--json]\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, and names a SQLite store or a CAVE text file: text\nreplays into an in-memory store for commands that only read (writes refuse\nit), and a read never creates a missing database. The spec lives in the .claude/skills/ directory at\nthe repository root (section index in README.md).";
|
|
42
43
|
/** Per-command help, printed for \`cave <command> --help\` and \`cave help <command>\`. */
|
|
43
44
|
export declare const commandHelp: Record<string, string>;
|
|
44
45
|
export declare const parseCommand: (argv: readonly string[]) => Output;
|
|
@@ -62,6 +63,14 @@ export declare const addCommand: (argv: readonly string[]) => Output;
|
|
|
62
63
|
*/
|
|
63
64
|
export declare const importCommand: (argv: readonly string[]) => Output;
|
|
64
65
|
export declare const queryCommand: (argv: readonly string[]) => Output;
|
|
66
|
+
export declare const searchFormat: "cave.search";
|
|
67
|
+
export declare const searchVersion: 1;
|
|
68
|
+
/**
|
|
69
|
+
* `cave search` — the store's FTS5 index (spec §13.2) from the shell:
|
|
70
|
+
* one literal phrase by default, raw MATCH syntax on request, newest
|
|
71
|
+
* matches first. Lines print as written, so comments come along.
|
|
72
|
+
*/
|
|
73
|
+
export declare const searchCommand: (argv: readonly string[]) => Output;
|
|
65
74
|
/**
|
|
66
75
|
* `cave resolve` — the human view of contradiction resolution (spec §26.4):
|
|
67
76
|
* contested facts with their candidates ranked as the policy sees them,
|
|
@@ -71,7 +80,7 @@ export declare const resolveCommand: (argv: readonly string[]) => Output;
|
|
|
71
80
|
export declare const deriveCommand: (argv: readonly string[]) => Output;
|
|
72
81
|
export declare const actCommand: (argv: readonly string[]) => Output;
|
|
73
82
|
export declare const checkCommand: (argv: readonly string[]) => Output;
|
|
74
|
-
/** `cave backup` — create or verify an exact
|
|
83
|
+
/** `cave backup` — create or verify an exact store snapshot (§13.2.2). */
|
|
75
84
|
export declare const backupCommand: (argv: readonly string[]) => Output;
|
|
76
85
|
/** `cave restore` — verify and atomically restore an exact snapshot (§13.2.2). */
|
|
77
86
|
export declare const restoreCommand: (argv: readonly string[]) => Output;
|
|
@@ -109,8 +118,8 @@ export declare const generateCommand: (argv: readonly string[]) => Output;
|
|
|
109
118
|
export declare const reconstructCommand: (argv: readonly string[], runtime?: {
|
|
110
119
|
readonly signal?: AbortSignal;
|
|
111
120
|
}) => Promise<Output>;
|
|
112
|
-
export declare const demoCommand: () => Output;
|
|
113
|
-
export declare const versionCommand: () => Output;
|
|
121
|
+
export declare const demoCommand: (argv?: readonly string[]) => Output;
|
|
122
|
+
export declare const versionCommand: (argv?: readonly string[]) => Output;
|
|
114
123
|
/** `cave help [command]` — the overview, or one command's help text. */
|
|
115
124
|
export declare const helpCommand: (argv: readonly string[]) => Output;
|
|
116
125
|
/** Dispatches one invocation. */
|
package/dist/src/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/src/cli.js
CHANGED
|
@@ -9,12 +9,13 @@
|
|
|
9
9
|
* - `cave highlight [file]` — ANSI syntax colors (async)
|
|
10
10
|
* - `cave add [--db <path>] [file…]` — ingest into a store (`--strict`, `--check`)
|
|
11
11
|
* - `cave query [--db <path>] '<pattern>'` — CAVE-Q (`--json`, `--all`, `--aliases`, `--as-of`, `--resolve`)
|
|
12
|
+
* - `cave search [--db <path>] <terms..>` — FTS5 full-text search over claims and comments (`--raw`, `--limit`, `--json`)
|
|
12
13
|
* - `cave resolve [--db <path>]` — contested facts under the §26 policy (`--aliases`, `--policy`, `--json`)
|
|
13
14
|
* - `cave derive [--db <path>] [rules.cave…]` — fire rules (`--dry-run`, `--full`, `--list`, `--retract`)
|
|
14
15
|
* - `cave act [--db <path>] <name> [param=value…]` — execute an action (spec §25; `--declare`, `--list`, `--retract`)
|
|
15
16
|
* - `cave automate [--db <path>]` — the event-driven loop (spec §29; async)
|
|
16
17
|
* - `cave check [--db <path>]` — knowledge health report (`--stale`, `--json`)
|
|
17
|
-
* - `cave backup [--db <path>] --out <path>` — exact verified
|
|
18
|
+
* - `cave backup [--db <path>] --out <path>` — exact verified store snapshot
|
|
18
19
|
* - `cave restore <snapshot> --db <path>` — verify and atomically restore a snapshot
|
|
19
20
|
* - `cave generate [--db <path>]` — versioned TypeScript client from EXPECTS declarations
|
|
20
21
|
* - `cave suggest-alias [--db <path>]` — same-entity candidates (spec §27; async)
|
|
@@ -37,10 +38,10 @@ import { readFileSync, readSync, statSync, writeFileSync } from 'node:fs';
|
|
|
37
38
|
import { resolve } from 'node:path';
|
|
38
39
|
import { parseArgs } from 'node:util';
|
|
39
40
|
import { Version } from '@cavelang/core';
|
|
40
|
-
import { parseDocument } from '@cavelang/parser';
|
|
41
|
+
import { parseDocument, Token } from '@cavelang/parser';
|
|
41
42
|
import { Registry, standardRegistry } from '@cavelang/canonical';
|
|
42
|
-
import { Sensitivity, backup as backupStore, defaultDbPath,
|
|
43
|
-
import { defaultLimit as defaultQueryLimit, page as caveQueryPage } from '@cavelang/query';
|
|
43
|
+
import { LocateError, Sensitivity, backup as backupStore, defaultDbPath, openAt, restoreBackup, verifyBackup } from '@cavelang/store';
|
|
44
|
+
import { defaultLimit as defaultQueryLimit, maxLimit as maxQueryLimit, page as caveQueryPage } from '@cavelang/query';
|
|
44
45
|
import { check as caveCheck, defaultMinScore, defaultStaleDays, gatedIngest, judgePrompt, parseJudgeReply, generateClient, suggestAliases, writeSuggestions } from '@cavelang/cli/shape';
|
|
45
46
|
import { declareRules, defaultMaxPasses, defaultMinConf, derive, listRules, retractRule } from '@cavelang/cli/rules';
|
|
46
47
|
import { act, declareActions, listActions, retractAction } from '@cavelang/cli/act';
|
|
@@ -88,13 +89,14 @@ Usage:
|
|
|
88
89
|
cave add [--db <path>] [file...] ingest into a store [--strict] [--check] [--no-prelude] [--no-src]
|
|
89
90
|
cave import [--db <path>] [file...] restore/merge from CAVE text (add without @src: stamping)
|
|
90
91
|
cave query [--db <path>] <pattern> run a bounded CAVE-Q page [--limit <n>] [--cursor <token>] [--json]
|
|
92
|
+
cave search [--db <path>] <terms..> full-text search over claims and comments (FTS5) [--raw] [--limit <n>] [--json]
|
|
91
93
|
cave resolve [--db <path>] contested facts + winners (spec §26) [--aliases] [--policy] [--json]
|
|
92
94
|
cave derive [--db <path>] [rules.cave..] declare + fire rules (spec §24) [--dry-run] [--full] [--list] [--retract <rule>]
|
|
93
95
|
cave act [--db <path>] <name> [p=v...] execute an action (spec §25) [--dry-run] [--no-check] [--hooks <file>]
|
|
94
96
|
cave act --declare [file...] declare actions from a CAVE document; --list / --retract <name> manage them
|
|
95
97
|
cave automate [--db <path>] event-driven loop (spec §29): new claims fire rules/actions/hooks/agent prompts [--once]
|
|
96
98
|
cave check [--db <path>] knowledge health report (spec §20) [--stale <days>] [--json]
|
|
97
|
-
cave backup [--db <path>] --out <file> exact verified
|
|
99
|
+
cave backup [--db <path>] --out <file> exact verified store snapshot [--force]
|
|
98
100
|
cave restore <snapshot> --db <path> verify and atomically restore an exact snapshot [--force]
|
|
99
101
|
cave generate [--db <path>] generate a typed client from EXPECTS [--out <file>] [--version <n>]
|
|
100
102
|
cave suggest-alias [--db <path>] propose same-entity ALIAS candidates (spec §27) [--min <s>] [--agent] [--write]
|
|
@@ -113,9 +115,11 @@ Usage:
|
|
|
113
115
|
cave help [command] this text, or one command's options and examples
|
|
114
116
|
|
|
115
117
|
Every command answers --help. --db defaults to $CAVE_DB, or cave.db in
|
|
116
|
-
the current directory
|
|
118
|
+
the current directory, and names a SQLite store or a CAVE text file: text
|
|
119
|
+
replays into an in-memory store for commands that only read (writes refuse
|
|
120
|
+
it), and a read never creates a missing database. The spec lives in the .claude/skills/ directory at
|
|
117
121
|
the repository root (section index in README.md).`;
|
|
118
|
-
const dbHelp = `--db <path>
|
|
122
|
+
const dbHelp = `--db <path> store: a SQLite file, or CAVE text read into memory (default: $CAVE_DB, or cave.db)`;
|
|
119
123
|
/** Per-command help, printed for \`cave <command> --help\` and \`cave help <command>\`. */
|
|
120
124
|
export const commandHelp = {
|
|
121
125
|
doctor: `cave doctor — diagnose runtime, installation, and store health
|
|
@@ -244,10 +248,13 @@ Options:
|
|
|
244
248
|
|
|
245
249
|
Patterns are claim triples with ?variables and optional metadata filters
|
|
246
250
|
(spec §12). A second positional starting with WHERE filters on conf,
|
|
247
|
-
value or tx.
|
|
251
|
+
value or tx. A binding line carries the matched claim's comment
|
|
252
|
+
(?x = value ; comment), so evidence written next to a claim travels
|
|
253
|
+
with the answer; fully bound patterns print the raw line, comment included.
|
|
248
254
|
|
|
249
255
|
Examples:
|
|
250
256
|
cave query '?x USES jwt'
|
|
257
|
+
cave query --db notes.cave '?x USES jwt'
|
|
251
258
|
cave query --db k.db '?x HAS bug: ?bug #security'
|
|
252
259
|
cave query --db k.db '?cause CAUSE app/crash' 'WHERE conf >= 0.5'
|
|
253
260
|
cave query --db k.db 'terrier EXTENDS+ animal'
|
|
@@ -257,6 +264,38 @@ Examples:
|
|
|
257
264
|
cave query --db k.db 'alice WORKS-AT ?org' --at 2021
|
|
258
265
|
cave query --db k.db 'service HAS owner: ?who' --resolve
|
|
259
266
|
cave query --db k.db '?x ?verb ?y @production' --json`,
|
|
267
|
+
search: `cave search — full-text search over claims and comments (spec §13.2)
|
|
268
|
+
|
|
269
|
+
Usage:
|
|
270
|
+
cave search [--db <path>] <terms...> [--raw] [--limit <n>] [--json] [--no-prelude]
|
|
271
|
+
|
|
272
|
+
Options:
|
|
273
|
+
${dbHelp}
|
|
274
|
+
--raw treat the terms as FTS5 MATCH syntax: AND / OR / NOT,
|
|
275
|
+
NEAR(a b), prefix* and column filters such as
|
|
276
|
+
comment:heap or subject:auth
|
|
277
|
+
--limit <n> matches to print (default ${defaultQueryLimit}, maximum ${maxQueryLimit})
|
|
278
|
+
--json emit a versioned cave.search/v1 JSON object whose matches
|
|
279
|
+
are cave.claim/v1 records
|
|
280
|
+
--no-prelude open the store without the standard verb registry
|
|
281
|
+
|
|
282
|
+
Searches the full-text index the store maintains over every claim:
|
|
283
|
+
subject, verb, object, attribute name, value text, comment, and the raw
|
|
284
|
+
line as written (so tags, contexts, and inverse spellings match too).
|
|
285
|
+
Terms are one literal phrase by default — safe for hyphenated names such
|
|
286
|
+
as token-expiry, which raw FTS5 syntax would read as a column filter.
|
|
287
|
+
Tokens split on punctuation, so heap-dump also matches "heap dump" and
|
|
288
|
+
auth/middleware matches auth middleware. Results are newest first, one
|
|
289
|
+
raw line each, comments included; retracted and superseded rows stay
|
|
290
|
+
searchable (spec §9.6), so pair a hit with cave query or cave export
|
|
291
|
+
--current when currency matters.
|
|
292
|
+
|
|
293
|
+
Examples:
|
|
294
|
+
cave search 'heap dump'
|
|
295
|
+
cave search --db k.db token-expiry
|
|
296
|
+
cave search --db k.db --raw 'comment:heap AND subject:auth'
|
|
297
|
+
cave search --db k.db --raw 'jwt OR oauth*' --limit 20
|
|
298
|
+
cave search --db k.db 'rotated weekly' --json`,
|
|
260
299
|
resolve: `cave resolve — contested facts and their winners (spec §26)
|
|
261
300
|
|
|
262
301
|
Usage:
|
|
@@ -395,7 +434,7 @@ Examples:
|
|
|
395
434
|
cave check --db k.db
|
|
396
435
|
cave check --db k.db --stale 30
|
|
397
436
|
cave check --db k.db --json | jq '.violations'`,
|
|
398
|
-
backup: `cave backup — exact, verified
|
|
437
|
+
backup: `cave backup — exact, verified store snapshot (spec §13.2.2)
|
|
399
438
|
|
|
400
439
|
Usage:
|
|
401
440
|
cave backup [--db <path>] --out <file> [--force]
|
|
@@ -416,7 +455,7 @@ the restore verification token.
|
|
|
416
455
|
Examples:
|
|
417
456
|
cave backup --db k.db --out backups/k.db
|
|
418
457
|
cave backup --verify backups/k.db --sha256 <hex>`,
|
|
419
|
-
restore: `cave restore — verify and atomically restore an exact
|
|
458
|
+
restore: `cave restore — verify and atomically restore an exact store snapshot (spec §13.2.2)
|
|
420
459
|
|
|
421
460
|
Usage:
|
|
422
461
|
cave restore <snapshot> --db <path> [--force] [--sha256 <hex>]
|
|
@@ -664,7 +703,18 @@ topic → fix over a small in-memory store.`,
|
|
|
664
703
|
version: `cave version — print the cave version
|
|
665
704
|
|
|
666
705
|
Usage:
|
|
667
|
-
cave version
|
|
706
|
+
cave version`,
|
|
707
|
+
help: `cave help — the overview, or one command's options and examples
|
|
708
|
+
|
|
709
|
+
Usage:
|
|
710
|
+
cave help
|
|
711
|
+
cave help <command>
|
|
712
|
+
|
|
713
|
+
Every command answers --help with the same text as cave help <command>.
|
|
714
|
+
|
|
715
|
+
Examples:
|
|
716
|
+
cave help query
|
|
717
|
+
cave help serve`
|
|
668
718
|
};
|
|
669
719
|
const readStdin = () => {
|
|
670
720
|
const chunks = [];
|
|
@@ -686,6 +736,19 @@ const readStdin = () => {
|
|
|
686
736
|
}
|
|
687
737
|
}
|
|
688
738
|
};
|
|
739
|
+
/**
|
|
740
|
+
* Opens the store `--db` names (spec §13.7): a SQLite file, or a CAVE text
|
|
741
|
+
* file replayed into memory. `read` never creates, migrates, or changes a
|
|
742
|
+
* file — a missing path is an error, not an empty database; `scratch` is a
|
|
743
|
+
* dry run that appends inside a rolled-back transaction, so it may write
|
|
744
|
+
* but creates and migrates nothing; `write` creates a missing SQLite store,
|
|
745
|
+
* migrates an older one, and refuses text files with the materialization
|
|
746
|
+
* hint.
|
|
747
|
+
*/
|
|
748
|
+
const openDb = (values, intent) => openAt(values.db ?? defaultDbPath(), {
|
|
749
|
+
intent,
|
|
750
|
+
...values['no-prelude'] === true ? { registry: Registry.empty } : {}
|
|
751
|
+
});
|
|
689
752
|
const readInput = (files) => files.length === 0 || (files.length === 1 && files[0] === '-') ?
|
|
690
753
|
readStdin() :
|
|
691
754
|
files.map(file => readFileSync(file, 'utf8')).join('\n');
|
|
@@ -762,7 +825,7 @@ const ingestCommand = (name) => (argv) => {
|
|
|
762
825
|
allowPositionals: true
|
|
763
826
|
});
|
|
764
827
|
const input = readInput(positionals);
|
|
765
|
-
const store =
|
|
828
|
+
const store = openDb(values, 'write');
|
|
766
829
|
try {
|
|
767
830
|
const options = {
|
|
768
831
|
strict: values.strict === true,
|
|
@@ -828,7 +891,7 @@ export const queryCommand = (argv) => {
|
|
|
828
891
|
return fail('cave query: a pattern is required (spec §12.1)\n');
|
|
829
892
|
}
|
|
830
893
|
const pattern = positionals.join('\n');
|
|
831
|
-
const store =
|
|
894
|
+
const store = openDb(values, 'read');
|
|
832
895
|
try {
|
|
833
896
|
const limit = values.limit === undefined ? defaultQueryLimit : Number(values.limit);
|
|
834
897
|
const result = caveQueryPage(store, pattern, {
|
|
@@ -853,7 +916,14 @@ export const queryCommand = (argv) => {
|
|
|
853
916
|
.join(' ');
|
|
854
917
|
// A fully bound pattern has no bindings to print; transitive matches
|
|
855
918
|
// additionally carry no row — confirm with the pattern itself.
|
|
856
|
-
|
|
919
|
+
// Bindings carry the matched claim's comment so the evidence written
|
|
920
|
+
// next to a claim travels with the answer; raw lines already do. A
|
|
921
|
+
// multi-line comment (§6.4) opens above the binding line, as it does
|
|
922
|
+
// above a claim.
|
|
923
|
+
const comment = match.claim?.claim.comment;
|
|
924
|
+
const line = bindings !== '' ?
|
|
925
|
+
comment === undefined ? bindings : Token.joinComment(`${bindings} `, comment) :
|
|
926
|
+
match.claim?.claim.raw ?? pattern.split('\n')[0];
|
|
857
927
|
// An interpolated trajectory shows its value at the anchor
|
|
858
928
|
// (spec §32.4) — bindings already carry it in the value slot.
|
|
859
929
|
return match.at !== undefined && bindings === '' ?
|
|
@@ -869,6 +939,66 @@ export const queryCommand = (argv) => {
|
|
|
869
939
|
store.close();
|
|
870
940
|
}
|
|
871
941
|
};
|
|
942
|
+
export const searchFormat = 'cave.search';
|
|
943
|
+
export const searchVersion = 1;
|
|
944
|
+
/**
|
|
945
|
+
* `cave search` — the store's FTS5 index (spec §13.2) from the shell:
|
|
946
|
+
* one literal phrase by default, raw MATCH syntax on request, newest
|
|
947
|
+
* matches first. Lines print as written, so comments come along.
|
|
948
|
+
*/
|
|
949
|
+
export const searchCommand = (argv) => {
|
|
950
|
+
const { values, positionals } = parseArgs({
|
|
951
|
+
args: [...argv],
|
|
952
|
+
options: {
|
|
953
|
+
db: { type: 'string' },
|
|
954
|
+
raw: { type: 'boolean' },
|
|
955
|
+
limit: { type: 'string' },
|
|
956
|
+
json: { type: 'boolean' },
|
|
957
|
+
'no-prelude': { type: 'boolean' }
|
|
958
|
+
},
|
|
959
|
+
allowPositionals: true
|
|
960
|
+
});
|
|
961
|
+
const query = positionals.join(' ').trim();
|
|
962
|
+
if (query === '') {
|
|
963
|
+
return fail('cave search: search terms are required\n');
|
|
964
|
+
}
|
|
965
|
+
const limit = values.limit === undefined ? defaultQueryLimit : Number(values.limit);
|
|
966
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > maxQueryLimit) {
|
|
967
|
+
return fail(`cave search: --limit must be an integer from 1 to ${maxQueryLimit}\n`);
|
|
968
|
+
}
|
|
969
|
+
const store = openDb(values, 'read');
|
|
970
|
+
try {
|
|
971
|
+
const raw = values.raw === true;
|
|
972
|
+
const found = store.search(query, { raw, limit: limit + 1 });
|
|
973
|
+
const matches = found.slice(0, limit);
|
|
974
|
+
const truncated = found.length > limit;
|
|
975
|
+
if (values.json === true) {
|
|
976
|
+
return ok(`${JSON.stringify({
|
|
977
|
+
format: searchFormat,
|
|
978
|
+
version: searchVersion,
|
|
979
|
+
query,
|
|
980
|
+
raw,
|
|
981
|
+
limit,
|
|
982
|
+
truncated,
|
|
983
|
+
matches: matches.map(row => store.recordOf(row))
|
|
984
|
+
}, undefined, 2)}\n`);
|
|
985
|
+
}
|
|
986
|
+
if (matches.length === 0) {
|
|
987
|
+
return ok('no matches\n');
|
|
988
|
+
}
|
|
989
|
+
const lines = matches.map(row => row.raw_line);
|
|
990
|
+
if (truncated) {
|
|
991
|
+
lines.push(`more matches beyond ${limit}; raise --limit`);
|
|
992
|
+
}
|
|
993
|
+
return ok(`${lines.join('\n')}\n`);
|
|
994
|
+
}
|
|
995
|
+
catch (error) {
|
|
996
|
+
return fail(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
997
|
+
}
|
|
998
|
+
finally {
|
|
999
|
+
store.close();
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
872
1002
|
/**
|
|
873
1003
|
* `cave resolve` — the human view of contradiction resolution (spec §26.4):
|
|
874
1004
|
* contested facts with their candidates ranked as the policy sees them,
|
|
@@ -887,7 +1017,7 @@ export const resolveCommand = (argv) => {
|
|
|
887
1017
|
allowPositionals: false
|
|
888
1018
|
});
|
|
889
1019
|
const percent = (value) => `${Math.round(value * 1000) / 10}%`;
|
|
890
|
-
const store =
|
|
1020
|
+
const store = openDb(values, 'read');
|
|
891
1021
|
try {
|
|
892
1022
|
if (values.policy === true) {
|
|
893
1023
|
const policy = store.resolutionPolicy();
|
|
@@ -949,7 +1079,11 @@ export const deriveCommand = (argv) => {
|
|
|
949
1079
|
if (maxPasses !== undefined && (!Number.isInteger(maxPasses) || maxPasses < 1)) {
|
|
950
1080
|
return fail(`cave derive: --max-passes expects a positive integer, got ${JSON.stringify(values['max-passes'])}\n`);
|
|
951
1081
|
}
|
|
952
|
-
|
|
1082
|
+
// The intent follows the branch order below: listing reads, retracting
|
|
1083
|
+
// writes, a dry run appends inside a rolled-back transaction.
|
|
1084
|
+
const store = openDb(values, values.list === true ? 'read' :
|
|
1085
|
+
values.retract !== undefined ? 'write' :
|
|
1086
|
+
values['dry-run'] === true ? 'scratch' : 'write');
|
|
953
1087
|
try {
|
|
954
1088
|
if (values.list === true) {
|
|
955
1089
|
const rules = listRules(store);
|
|
@@ -1103,7 +1237,13 @@ export const actCommand = (argv) => {
|
|
|
1103
1237
|
},
|
|
1104
1238
|
allowPositionals: true
|
|
1105
1239
|
});
|
|
1106
|
-
|
|
1240
|
+
// The intent follows the branch order below: declaring and retracting
|
|
1241
|
+
// write, listing reads, a dry-run execution appends inside a rolled-back
|
|
1242
|
+
// transaction.
|
|
1243
|
+
const store = openDb(values, values.declare === true ? 'write' :
|
|
1244
|
+
values.list === true ? 'read' :
|
|
1245
|
+
values.retract !== undefined ? 'write' :
|
|
1246
|
+
values['dry-run'] === true ? 'scratch' : 'write');
|
|
1107
1247
|
try {
|
|
1108
1248
|
if (values.declare === true) {
|
|
1109
1249
|
const declaration = declareActions(store, readInput(positionals));
|
|
@@ -1221,7 +1361,7 @@ export const checkCommand = (argv) => {
|
|
|
1221
1361
|
if (!Number.isFinite(staleDays) || staleDays < 0) {
|
|
1222
1362
|
return fail(`cave check: --stale expects a non-negative number of days, got ${JSON.stringify(values.stale)}\n`);
|
|
1223
1363
|
}
|
|
1224
|
-
const store =
|
|
1364
|
+
const store = openDb(values, 'read');
|
|
1225
1365
|
try {
|
|
1226
1366
|
const report = caveCheck(store, { staleDays });
|
|
1227
1367
|
const out = values.json === true ?
|
|
@@ -1236,7 +1376,7 @@ export const checkCommand = (argv) => {
|
|
|
1236
1376
|
};
|
|
1237
1377
|
const snapshotLine = (action, snapshot) => `${action} exact backup (${snapshot.rows} row(s), schema v${snapshot.schemaVersion}, ` +
|
|
1238
1378
|
`${snapshot.bytes} bytes, sha256:${snapshot.sha256}) at ${snapshot.path}\n`;
|
|
1239
|
-
/** `cave backup` — create or verify an exact
|
|
1379
|
+
/** `cave backup` — create or verify an exact store snapshot (§13.2.2). */
|
|
1240
1380
|
export const backupCommand = (argv) => {
|
|
1241
1381
|
const { values } = parseArgs({
|
|
1242
1382
|
args: [...argv],
|
|
@@ -1265,7 +1405,15 @@ export const backupCommand = (argv) => {
|
|
|
1265
1405
|
if (values.out === undefined) {
|
|
1266
1406
|
return fail('cave backup: --out <file> is required\n');
|
|
1267
1407
|
}
|
|
1268
|
-
const
|
|
1408
|
+
const dbPath = values.db ?? defaultDbPath();
|
|
1409
|
+
// A text store is replayed into memory, so the backup API cannot see that
|
|
1410
|
+
// the destination aliases the source: refuse before the file could be
|
|
1411
|
+
// replaced by a SQLite snapshot of itself (a SQLite source is covered by
|
|
1412
|
+
// the API's own check).
|
|
1413
|
+
if (sameFile(dbPath, values.out)) {
|
|
1414
|
+
return fail(`cave backup: --out '${values.out}' is the source database — refusing to overwrite it\n`);
|
|
1415
|
+
}
|
|
1416
|
+
const store = openAt(dbPath, { intent: 'read' });
|
|
1269
1417
|
try {
|
|
1270
1418
|
return ok(snapshotLine('created', backupStore(store, values.out, { force: values.force === true })));
|
|
1271
1419
|
}
|
|
@@ -1346,7 +1494,7 @@ export const suggestAliasCommand = async (argv, runtime = {}) => {
|
|
|
1346
1494
|
if (timeoutSeconds !== undefined && (!Number.isFinite(timeoutSeconds) || timeoutSeconds <= 0)) {
|
|
1347
1495
|
return fail(`cave suggest-alias: --timeout must be a positive number of seconds, got '${values.timeout}'\n`);
|
|
1348
1496
|
}
|
|
1349
|
-
const store =
|
|
1497
|
+
const store = openDb(values, values.write === true ? 'write' : 'read');
|
|
1350
1498
|
try {
|
|
1351
1499
|
let suggestions = suggestAliases(store, { minScore, ...limit === undefined ? {} : { limit } });
|
|
1352
1500
|
if (values.agent !== undefined && suggestions.length > 0) {
|
|
@@ -1402,7 +1550,7 @@ export const syncCommand = (argv) => {
|
|
|
1402
1550
|
return fail('cave sync: exactly one source is required — a CAVE store file, ;@-annotated text, or - for stdin (spec §28.5)\n');
|
|
1403
1551
|
}
|
|
1404
1552
|
const dbPath = values.db ?? defaultDbPath();
|
|
1405
|
-
const store =
|
|
1553
|
+
const store = openDb(values, values['dry-run'] === true ? 'scratch' : 'write');
|
|
1406
1554
|
try {
|
|
1407
1555
|
const options = {
|
|
1408
1556
|
into: values.into === undefined ? labelOf(dbPath) : sanitizeLabel(values.into),
|
|
@@ -1464,7 +1612,10 @@ export const reportCommand = (argv) => {
|
|
|
1464
1612
|
if (maximum === undefined) {
|
|
1465
1613
|
return fail(`cave report: --max-sensitivity expects ${Sensitivity.levels.join(', ')}, got ${JSON.stringify(values['max-sensitivity'])}\n`);
|
|
1466
1614
|
}
|
|
1467
|
-
|
|
1615
|
+
if (values.out !== undefined && sameFile(values.db ?? defaultDbPath(), values.out)) {
|
|
1616
|
+
return fail(`cave report: --out '${values.out}' is the source database — refusing to overwrite it\n`);
|
|
1617
|
+
}
|
|
1618
|
+
const store = openDb(values, 'read');
|
|
1468
1619
|
try {
|
|
1469
1620
|
const rendered = caveReport(store, template, {
|
|
1470
1621
|
aliases: values.aliases === true,
|
|
@@ -1533,7 +1684,7 @@ export const exportCommand = (argv) => {
|
|
|
1533
1684
|
if (values.out !== undefined && sameFile(db, values.out)) {
|
|
1534
1685
|
return fail(`cave export: --out '${values.out}' is the source database — refusing to overwrite it\n`);
|
|
1535
1686
|
}
|
|
1536
|
-
const store =
|
|
1687
|
+
const store = openDb(values, 'read');
|
|
1537
1688
|
try {
|
|
1538
1689
|
const text = store.exportText({ current: values.current === true, tx: values.tx === true, maxSensitivity: maximum });
|
|
1539
1690
|
if (values.out === undefined) {
|
|
@@ -1573,7 +1724,7 @@ export const generateCommand = (argv) => {
|
|
|
1573
1724
|
if (values.out !== undefined && sameFile(db, values.out)) {
|
|
1574
1725
|
return fail(`cave generate: --out '${values.out}' is the source database — refusing to overwrite it\n`);
|
|
1575
1726
|
}
|
|
1576
|
-
const store =
|
|
1727
|
+
const store = openDb(values, 'read');
|
|
1577
1728
|
try {
|
|
1578
1729
|
const generated = generateClient(store, version === undefined ? {} : { version });
|
|
1579
1730
|
if (!generated.ok) {
|
|
@@ -1636,7 +1787,7 @@ export const reconstructCommand = async (argv, runtime = {}) => {
|
|
|
1636
1787
|
if (timeoutSeconds !== undefined && (!Number.isFinite(timeoutSeconds) || timeoutSeconds <= 0)) {
|
|
1637
1788
|
return fail(`cave reconstruct: --timeout must be a positive number of seconds, got '${values.timeout}'\n`);
|
|
1638
1789
|
}
|
|
1639
|
-
const store =
|
|
1790
|
+
const store = openDb(values, 'read');
|
|
1640
1791
|
try {
|
|
1641
1792
|
const graph = sqliteStore(store);
|
|
1642
1793
|
const result = values.agent === undefined ?
|
|
@@ -1645,9 +1796,11 @@ export const reconstructCommand = async (argv, runtime = {}) => {
|
|
|
1645
1796
|
...timeoutSeconds === undefined ? {} : { timeoutSeconds },
|
|
1646
1797
|
...runtime.signal === undefined ? {} : { signal: runtime.signal }
|
|
1647
1798
|
}), { ...values.query === undefined ? {} : { query: values.query }, ...budgets }), positionals);
|
|
1799
|
+
// The trace is a documentary comment block: the blank line after it
|
|
1800
|
+
// keeps it off the first claim when the output is added back (§6.4).
|
|
1648
1801
|
const lines = [
|
|
1649
|
-
...values.trace === true ?
|
|
1650
|
-
result.trace.map(step => `; ${step.step}. ${step.cue.entity} @ ${step.cue.score.toFixed(2)} +${step.collected} claim(s)`) :
|
|
1802
|
+
...values.trace === true && result.trace.length > 0 ?
|
|
1803
|
+
[...result.trace.map(step => `; ${step.step}. ${step.cue.entity} @ ${step.cue.score.toFixed(2)} +${step.collected} claim(s)`), ''] :
|
|
1651
1804
|
[],
|
|
1652
1805
|
...result.claims.map(claim => emitClaim(claim))
|
|
1653
1806
|
];
|
|
@@ -1661,11 +1814,33 @@ export const reconstructCommand = async (argv, runtime = {}) => {
|
|
|
1661
1814
|
return fail(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
1662
1815
|
}
|
|
1663
1816
|
};
|
|
1664
|
-
|
|
1665
|
-
|
|
1817
|
+
/**
|
|
1818
|
+
* Positional arguments of a command that declares no options: an unknown
|
|
1819
|
+
* option throws, which the dispatcher reports as an ordinary problem
|
|
1820
|
+
* (status 1).
|
|
1821
|
+
*/
|
|
1822
|
+
const positionalsOf = (argv) => parseArgs({ args: [...argv], options: {}, allowPositionals: true }).positionals;
|
|
1823
|
+
/** The usage error (status 2) for more positionals than a command takes. */
|
|
1824
|
+
const surplusPositionals = (command, positionals, max) => positionals.length > max ? fail(`cave ${command}: unexpected positional arguments\n`, 2) : undefined;
|
|
1825
|
+
export const demoCommand = (argv = []) => {
|
|
1826
|
+
const problem = surplusPositionals('demo', positionalsOf(argv), 0);
|
|
1827
|
+
if (problem !== undefined)
|
|
1828
|
+
return problem;
|
|
1829
|
+
return ok(`${Demo.run().lines.join('\n')}\n`);
|
|
1830
|
+
};
|
|
1831
|
+
export const versionCommand = (argv = []) => {
|
|
1832
|
+
const problem = surplusPositionals('version', positionalsOf(argv), 0);
|
|
1833
|
+
if (problem !== undefined)
|
|
1834
|
+
return problem;
|
|
1835
|
+
return ok(`${Version.current()}\n`);
|
|
1836
|
+
};
|
|
1666
1837
|
/** `cave help [command]` — the overview, or one command's help text. */
|
|
1667
1838
|
export const helpCommand = (argv) => {
|
|
1668
|
-
const
|
|
1839
|
+
const positionals = positionalsOf(argv);
|
|
1840
|
+
const problem = surplusPositionals('help', positionals, 1);
|
|
1841
|
+
if (problem !== undefined)
|
|
1842
|
+
return problem;
|
|
1843
|
+
const [topic] = positionals;
|
|
1669
1844
|
if (topic === undefined) {
|
|
1670
1845
|
return ok(`${usage}\n`);
|
|
1671
1846
|
}
|
|
@@ -1687,6 +1862,19 @@ export const cave = (argv) => {
|
|
|
1687
1862
|
(rest.includes('--help') || rest.includes('-h'))) {
|
|
1688
1863
|
return ok(`${commandHelp[canonical]}\n`);
|
|
1689
1864
|
}
|
|
1865
|
+
try {
|
|
1866
|
+
return run(canonical, rest);
|
|
1867
|
+
}
|
|
1868
|
+
catch (error) {
|
|
1869
|
+
// A --db path that is not what the command needs (spec §13.7) is a
|
|
1870
|
+
// usage failure, reported the way dispatch reports thrown errors.
|
|
1871
|
+
if (error instanceof LocateError) {
|
|
1872
|
+
return fail(`cave ${canonical}: ${error.message}\n`);
|
|
1873
|
+
}
|
|
1874
|
+
throw error;
|
|
1875
|
+
}
|
|
1876
|
+
};
|
|
1877
|
+
const run = (canonical, rest) => {
|
|
1690
1878
|
switch (canonical) {
|
|
1691
1879
|
case 'parse':
|
|
1692
1880
|
return parseCommand(rest);
|
|
@@ -1696,6 +1884,8 @@ export const cave = (argv) => {
|
|
|
1696
1884
|
return importCommand(rest);
|
|
1697
1885
|
case 'query':
|
|
1698
1886
|
return queryCommand(rest);
|
|
1887
|
+
case 'search':
|
|
1888
|
+
return searchCommand(rest);
|
|
1699
1889
|
case 'resolve':
|
|
1700
1890
|
return resolveCommand(rest);
|
|
1701
1891
|
case 'derive':
|
|
@@ -1719,11 +1909,11 @@ export const cave = (argv) => {
|
|
|
1719
1909
|
case 'doctor':
|
|
1720
1910
|
return doctorCommand(rest);
|
|
1721
1911
|
case 'demo':
|
|
1722
|
-
return demoCommand();
|
|
1912
|
+
return demoCommand(rest);
|
|
1723
1913
|
case 'version':
|
|
1724
1914
|
case '--version':
|
|
1725
1915
|
case '-v':
|
|
1726
|
-
return versionCommand();
|
|
1916
|
+
return versionCommand(rest);
|
|
1727
1917
|
case 'help':
|
|
1728
1918
|
return helpCommand(rest);
|
|
1729
1919
|
case undefined:
|
|
@@ -1731,7 +1921,7 @@ export const cave = (argv) => {
|
|
|
1731
1921
|
case '-h':
|
|
1732
1922
|
return ok(`${usage}\n`);
|
|
1733
1923
|
default:
|
|
1734
|
-
return fail(`cave: unknown command ${JSON.stringify(
|
|
1924
|
+
return fail(`cave: unknown command ${JSON.stringify(canonical)}\n\n${usage}\n`, 2);
|
|
1735
1925
|
}
|
|
1736
1926
|
};
|
|
1737
1927
|
//# sourceMappingURL=cli.js.map
|