@cavelang/cli 0.32.2 → 0.33.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.
Files changed (44) hide show
  1. package/README.md +8 -7
  2. package/dist/internal/connect/main.d.ts.map +1 -1
  3. package/dist/internal/connect/main.js +8 -6
  4. package/dist/internal/connect/main.js.map +1 -1
  5. package/dist/internal/connect/template.d.ts +9 -2
  6. package/dist/internal/connect/template.d.ts.map +1 -1
  7. package/dist/internal/connect/template.js +36 -5
  8. package/dist/internal/connect/template.js.map +1 -1
  9. package/dist/internal/loop/demo.d.ts.map +1 -1
  10. package/dist/internal/loop/demo.js +2 -1
  11. package/dist/internal/loop/demo.js.map +1 -1
  12. package/dist/internal/mcp/guide.js +3 -3
  13. package/dist/internal/mcp/guide.js.map +1 -1
  14. package/dist/internal/mcp/tools.d.ts.map +1 -1
  15. package/dist/internal/mcp/tools.js +39 -10
  16. package/dist/internal/mcp/tools.js.map +1 -1
  17. package/dist/internal/view/report.d.ts.map +1 -1
  18. package/dist/internal/view/report.js +6 -1
  19. package/dist/internal/view/report.js.map +1 -1
  20. package/dist/src/cli.d.ts +14 -5
  21. package/dist/src/cli.d.ts.map +1 -1
  22. package/dist/src/cli.js +157 -17
  23. package/dist/src/cli.js.map +1 -1
  24. package/dist/src/commands.d.ts +3 -0
  25. package/dist/src/commands.d.ts.map +1 -1
  26. package/dist/src/commands.js +1 -0
  27. package/dist/src/commands.js.map +1 -1
  28. package/dist/src/dispatch.d.ts.map +1 -1
  29. package/dist/src/dispatch.js +3 -1
  30. package/dist/src/dispatch.js.map +1 -1
  31. package/dist/src/doctor.d.ts +1 -0
  32. package/dist/src/doctor.d.ts.map +1 -1
  33. package/dist/src/doctor.js +16 -3
  34. package/dist/src/doctor.js.map +1 -1
  35. package/dist/src/index.d.ts +2 -2
  36. package/dist/src/index.d.ts.map +1 -1
  37. package/dist/src/index.js +2 -2
  38. package/dist/src/index.js.map +1 -1
  39. package/package.json +21 -21
  40. package/src/cli.ts +160 -19
  41. package/src/commands.ts +1 -0
  42. package/src/dispatch.ts +3 -1
  43. package/src/doctor.ts +16 -3
  44. package/src/index.ts +2 -2
package/src/cli.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 SQLite snapshot
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,11 +39,11 @@ import { readFileSync, readSync, statSync, writeFileSync } from 'node:fs'
38
39
  import { resolve } from 'node:path'
39
40
  import { parseArgs } from 'node:util'
40
41
  import { Version } from '@cavelang/core'
41
- import { parseDocument } from '@cavelang/parser'
42
+ import { parseDocument, Token } from '@cavelang/parser'
42
43
  import { Registry, standardRegistry } from '@cavelang/canonical'
43
44
  import { Sensitivity, backup as backupStore, defaultDbPath, open, restoreBackup, verifyBackup } from '@cavelang/store'
44
45
  import type { Store } from '@cavelang/store'
45
- import { defaultLimit as defaultQueryLimit, page as caveQueryPage } from '@cavelang/query'
46
+ import { defaultLimit as defaultQueryLimit, maxLimit as maxQueryLimit, page as caveQueryPage } from '@cavelang/query'
46
47
  import {
47
48
  check as caveCheck, defaultMinScore, defaultStaleDays, gatedIngest, judgePrompt, parseJudgeReply,
48
49
  generateClient, suggestAliases, writeSuggestions
@@ -115,13 +116,14 @@ Usage:
115
116
  cave add [--db <path>] [file...] ingest into a store [--strict] [--check] [--no-prelude] [--no-src]
116
117
  cave import [--db <path>] [file...] restore/merge from CAVE text (add without @src: stamping)
117
118
  cave query [--db <path>] <pattern> run a bounded CAVE-Q page [--limit <n>] [--cursor <token>] [--json]
119
+ cave search [--db <path>] <terms..> full-text search over claims and comments (FTS5) [--raw] [--limit <n>] [--json]
118
120
  cave resolve [--db <path>] contested facts + winners (spec §26) [--aliases] [--policy] [--json]
119
121
  cave derive [--db <path>] [rules.cave..] declare + fire rules (spec §24) [--dry-run] [--full] [--list] [--retract <rule>]
120
122
  cave act [--db <path>] <name> [p=v...] execute an action (spec §25) [--dry-run] [--no-check] [--hooks <file>]
121
123
  cave act --declare [file...] declare actions from a CAVE document; --list / --retract <name> manage them
122
124
  cave automate [--db <path>] event-driven loop (spec §29): new claims fire rules/actions/hooks/agent prompts [--once]
123
125
  cave check [--db <path>] knowledge health report (spec §20) [--stale <days>] [--json]
124
- cave backup [--db <path>] --out <file> exact verified SQLite snapshot [--force]
126
+ cave backup [--db <path>] --out <file> exact verified store snapshot [--force]
125
127
  cave restore <snapshot> --db <path> verify and atomically restore an exact snapshot [--force]
126
128
  cave generate [--db <path>] generate a typed client from EXPECTS [--out <file>] [--version <n>]
127
129
  cave suggest-alias [--db <path>] propose same-entity ALIAS candidates (spec §27) [--min <s>] [--agent] [--write]
@@ -278,7 +280,9 @@ Options:
278
280
 
279
281
  Patterns are claim triples with ?variables and optional metadata filters
280
282
  (spec §12). A second positional starting with WHERE filters on conf,
281
- value or tx.
283
+ value or tx. A binding line carries the matched claim's comment
284
+ (?x = value ; comment), so evidence written next to a claim travels
285
+ with the answer; fully bound patterns print the raw line, comment included.
282
286
 
283
287
  Examples:
284
288
  cave query '?x USES jwt'
@@ -292,6 +296,39 @@ Examples:
292
296
  cave query --db k.db 'service HAS owner: ?who' --resolve
293
297
  cave query --db k.db '?x ?verb ?y @production' --json`,
294
298
 
299
+ search: `cave search — full-text search over claims and comments (spec §13.2)
300
+
301
+ Usage:
302
+ cave search [--db <path>] <terms...> [--raw] [--limit <n>] [--json] [--no-prelude]
303
+
304
+ Options:
305
+ ${dbHelp}
306
+ --raw treat the terms as FTS5 MATCH syntax: AND / OR / NOT,
307
+ NEAR(a b), prefix* and column filters such as
308
+ comment:heap or subject:auth
309
+ --limit <n> matches to print (default ${defaultQueryLimit}, maximum ${maxQueryLimit})
310
+ --json emit a versioned cave.search/v1 JSON object whose matches
311
+ are cave.claim/v1 records
312
+ --no-prelude open the store without the standard verb registry
313
+
314
+ Searches the full-text index the store maintains over every claim:
315
+ subject, verb, object, attribute name, value text, comment, and the raw
316
+ line as written (so tags, contexts, and inverse spellings match too).
317
+ Terms are one literal phrase by default — safe for hyphenated names such
318
+ as token-expiry, which raw FTS5 syntax would read as a column filter.
319
+ Tokens split on punctuation, so heap-dump also matches "heap dump" and
320
+ auth/middleware matches auth middleware. Results are newest first, one
321
+ raw line each, comments included; retracted and superseded rows stay
322
+ searchable (spec §9.6), so pair a hit with cave query or cave export
323
+ --current when currency matters.
324
+
325
+ Examples:
326
+ cave search 'heap dump'
327
+ cave search --db k.db token-expiry
328
+ cave search --db k.db --raw 'comment:heap AND subject:auth'
329
+ cave search --db k.db --raw 'jwt OR oauth*' --limit 20
330
+ cave search --db k.db 'rotated weekly' --json`,
331
+
295
332
  resolve: `cave resolve — contested facts and their winners (spec §26)
296
333
 
297
334
  Usage:
@@ -434,7 +471,7 @@ Examples:
434
471
  cave check --db k.db --stale 30
435
472
  cave check --db k.db --json | jq '.violations'`,
436
473
 
437
- backup: `cave backup — exact, verified SQLite snapshot (spec §13.2.2)
474
+ backup: `cave backup — exact, verified store snapshot (spec §13.2.2)
438
475
 
439
476
  Usage:
440
477
  cave backup [--db <path>] --out <file> [--force]
@@ -456,7 +493,7 @@ Examples:
456
493
  cave backup --db k.db --out backups/k.db
457
494
  cave backup --verify backups/k.db --sha256 <hex>`,
458
495
 
459
- restore: `cave restore — verify and atomically restore an exact SQLite snapshot (spec §13.2.2)
496
+ restore: `cave restore — verify and atomically restore an exact store snapshot (spec §13.2.2)
460
497
 
461
498
  Usage:
462
499
  cave restore <snapshot> --db <path> [--force] [--sha256 <hex>]
@@ -712,7 +749,19 @@ topic → fix over a small in-memory store.`,
712
749
  version: `cave version — print the cave version
713
750
 
714
751
  Usage:
715
- cave version`
752
+ cave version`,
753
+
754
+ help: `cave help — the overview, or one command's options and examples
755
+
756
+ Usage:
757
+ cave help
758
+ cave help <command>
759
+
760
+ Every command answers --help with the same text as cave help <command>.
761
+
762
+ Examples:
763
+ cave help query
764
+ cave help serve`
716
765
  }
717
766
 
718
767
  const readStdin = (): string => {
@@ -908,7 +957,14 @@ export const queryCommand = (argv: readonly string[]): Output => {
908
957
  .join(' ')
909
958
  // A fully bound pattern has no bindings to print; transitive matches
910
959
  // additionally carry no row — confirm with the pattern itself.
911
- const line = bindings !== '' ? bindings : match.claim?.claim.raw ?? pattern.split('\n')[0]!
960
+ // Bindings carry the matched claim's comment so the evidence written
961
+ // next to a claim travels with the answer; raw lines already do. A
962
+ // multi-line comment (§6.4) opens above the binding line, as it does
963
+ // above a claim.
964
+ const comment = match.claim?.claim.comment
965
+ const line = bindings !== '' ?
966
+ comment === undefined ? bindings : Token.joinComment(`${bindings} `, comment) :
967
+ match.claim?.claim.raw ?? pattern.split('\n')[0]!
912
968
  // An interpolated trajectory shows its value at the anchor
913
969
  // (spec §32.4) — bindings already carry it in the value slot.
914
970
  return match.at !== undefined && bindings === '' ?
@@ -923,6 +979,66 @@ export const queryCommand = (argv: readonly string[]): Output => {
923
979
  }
924
980
  }
925
981
 
982
+ export const searchFormat = 'cave.search' as const
983
+ export const searchVersion = 1 as const
984
+
985
+ /**
986
+ * `cave search` — the store's FTS5 index (spec §13.2) from the shell:
987
+ * one literal phrase by default, raw MATCH syntax on request, newest
988
+ * matches first. Lines print as written, so comments come along.
989
+ */
990
+ export const searchCommand = (argv: readonly string[]): Output => {
991
+ const { values, positionals } = parseArgs({
992
+ args: [...argv],
993
+ options: {
994
+ db: { type: 'string' },
995
+ raw: { type: 'boolean' },
996
+ limit: { type: 'string' },
997
+ json: { type: 'boolean' },
998
+ 'no-prelude': { type: 'boolean' }
999
+ },
1000
+ allowPositionals: true
1001
+ })
1002
+ const query = positionals.join(' ').trim()
1003
+ if (query === '') {
1004
+ return fail('cave search: search terms are required\n')
1005
+ }
1006
+ const limit = values.limit === undefined ? defaultQueryLimit : Number(values.limit)
1007
+ if (!Number.isInteger(limit) || limit < 1 || limit > maxQueryLimit) {
1008
+ return fail(`cave search: --limit must be an integer from 1 to ${maxQueryLimit}\n`)
1009
+ }
1010
+ const store = open(values.db ?? defaultDbPath(), values['no-prelude'] === true ? { registry: Registry.empty } : {})
1011
+ try {
1012
+ const raw = values.raw === true
1013
+ const found = store.search(query, { raw, limit: limit + 1 })
1014
+ const matches = found.slice(0, limit)
1015
+ const truncated = found.length > limit
1016
+ if (values.json === true) {
1017
+ return ok(`${JSON.stringify({
1018
+ format: searchFormat,
1019
+ version: searchVersion,
1020
+ query,
1021
+ raw,
1022
+ limit,
1023
+ truncated,
1024
+ matches: matches.map(row => store.recordOf(row))
1025
+ }, undefined, 2)}\n`)
1026
+ }
1027
+ if (matches.length === 0) {
1028
+ return ok('no matches\n')
1029
+ }
1030
+ const lines = matches.map(row => row.raw_line)
1031
+ if (truncated) {
1032
+ lines.push(`more matches beyond ${limit}; raise --limit`)
1033
+ }
1034
+ return ok(`${lines.join('\n')}\n`)
1035
+ } catch (error) {
1036
+ return fail(`${error instanceof Error ? error.message : String(error)}\n`)
1037
+ } finally {
1038
+ store.close()
1039
+ }
1040
+ }
1041
+
926
1042
  /**
927
1043
  * `cave resolve` — the human view of contradiction resolution (spec §26.4):
928
1044
  * contested facts with their candidates ranked as the policy sees them,
@@ -1299,7 +1415,7 @@ const snapshotLine = (
1299
1415
  `${action} exact backup (${snapshot.rows} row(s), schema v${snapshot.schemaVersion}, ` +
1300
1416
  `${snapshot.bytes} bytes, sha256:${snapshot.sha256}) at ${snapshot.path}\n`
1301
1417
 
1302
- /** `cave backup` — create or verify an exact SQLite snapshot (§13.2.2). */
1418
+ /** `cave backup` — create or verify an exact store snapshot (§13.2.2). */
1303
1419
  export const backupCommand = (argv: readonly string[]): Output => {
1304
1420
  const { values } = parseArgs({
1305
1421
  args: [...argv],
@@ -1717,9 +1833,11 @@ export const reconstructCommand = async (
1717
1833
  ),
1718
1834
  positionals
1719
1835
  )
1836
+ // The trace is a documentary comment block: the blank line after it
1837
+ // keeps it off the first claim when the output is added back (§6.4).
1720
1838
  const lines = [
1721
- ...values.trace === true ?
1722
- result.trace.map(step => `; ${step.step}. ${step.cue.entity} @ ${step.cue.score.toFixed(2)} +${step.collected} claim(s)`) :
1839
+ ...values.trace === true && result.trace.length > 0 ?
1840
+ [...result.trace.map(step => `; ${step.step}. ${step.cue.entity} @ ${step.cue.score.toFixed(2)} +${step.collected} claim(s)`), ''] :
1723
1841
  [],
1724
1842
  ...result.claims.map(claim => emitClaim(claim))
1725
1843
  ]
@@ -1732,15 +1850,36 @@ export const reconstructCommand = async (
1732
1850
  }
1733
1851
  }
1734
1852
 
1735
- export const demoCommand = (): Output =>
1736
- ok(`${Demo.run().lines.join('\n')}\n`)
1853
+ /**
1854
+ * Positional arguments of a command that declares no options: an unknown
1855
+ * option throws, which the dispatcher reports as an ordinary problem
1856
+ * (status 1).
1857
+ */
1858
+ const positionalsOf = (argv: readonly string[]): readonly string[] =>
1859
+ parseArgs({ args: [...argv], options: {}, allowPositionals: true }).positionals
1860
+
1861
+ /** The usage error (status 2) for more positionals than a command takes. */
1862
+ const surplusPositionals = (command: string, positionals: readonly string[], max: number): Output | undefined =>
1863
+ positionals.length > max ? fail(`cave ${command}: unexpected positional arguments\n`, 2) : undefined
1737
1864
 
1738
- export const versionCommand = (): Output =>
1739
- ok(`${Version.current()}\n`)
1865
+ export const demoCommand = (argv: readonly string[] = []): Output => {
1866
+ const problem = surplusPositionals('demo', positionalsOf(argv), 0)
1867
+ if (problem !== undefined) return problem
1868
+ return ok(`${Demo.run().lines.join('\n')}\n`)
1869
+ }
1870
+
1871
+ export const versionCommand = (argv: readonly string[] = []): Output => {
1872
+ const problem = surplusPositionals('version', positionalsOf(argv), 0)
1873
+ if (problem !== undefined) return problem
1874
+ return ok(`${Version.current()}\n`)
1875
+ }
1740
1876
 
1741
1877
  /** `cave help [command]` — the overview, or one command's help text. */
1742
1878
  export const helpCommand = (argv: readonly string[]): Output => {
1743
- const [topic] = argv
1879
+ const positionals = positionalsOf(argv)
1880
+ const problem = surplusPositionals('help', positionals, 1)
1881
+ if (problem !== undefined) return problem
1882
+ const [topic] = positionals
1744
1883
  if (topic === undefined) {
1745
1884
  return ok(`${usage}\n`)
1746
1885
  }
@@ -1772,6 +1911,8 @@ export const cave = (argv: readonly string[]): Output => {
1772
1911
  return importCommand(rest)
1773
1912
  case 'query':
1774
1913
  return queryCommand(rest)
1914
+ case 'search':
1915
+ return searchCommand(rest)
1775
1916
  case 'resolve':
1776
1917
  return resolveCommand(rest)
1777
1918
  case 'derive':
@@ -1795,11 +1936,11 @@ export const cave = (argv: readonly string[]): Output => {
1795
1936
  case 'doctor':
1796
1937
  return doctorCommand(rest)
1797
1938
  case 'demo':
1798
- return demoCommand()
1939
+ return demoCommand(rest)
1799
1940
  case 'version':
1800
1941
  case '--version':
1801
1942
  case '-v':
1802
- return versionCommand()
1943
+ return versionCommand(rest)
1803
1944
  case 'help':
1804
1945
  return helpCommand(rest)
1805
1946
  case undefined:
package/src/commands.ts CHANGED
@@ -19,6 +19,7 @@ export const commandRegistry = [
19
19
  { name: 'add', importantOptions: ['--strict', '--check', '--no-prelude', '--no-src'] },
20
20
  { name: 'import', importantOptions: ['--strict', '--no-prelude'] },
21
21
  { name: 'query', importantOptions: ['--json', '--limit', '--cursor', '--all', '--aliases', '--as-of', '--at', '--resolve', '--no-prelude'] },
22
+ { name: 'search', importantOptions: ['--raw', '--limit', '--json', '--no-prelude'] },
22
23
  { name: 'resolve', importantOptions: ['--aliases', '--policy', '--json', '--no-prelude'] },
23
24
  { name: 'derive', importantOptions: ['--dry-run', '--full', '--aliases', '--min-conf', '--max-passes', '--list', '--retract', '--json', '--no-prelude'] },
24
25
  { name: 'act', importantOptions: ['--declare', '--list', '--retract', '--dry-run', '--no-check', '--aliases', '--hooks', '--json', '--no-prelude'] },
package/src/dispatch.ts CHANGED
@@ -22,8 +22,10 @@ const processRuntime = (): CommandRuntime => ({
22
22
 
23
23
  const delegatedHelp = new Set<string>(delegatedCommandNames)
24
24
 
25
+ // Exactly `help <delegated command>` becomes `<command> --help`; anything
26
+ // longer stays with `cave help`, which rejects the surplus as a usage error.
25
27
  const normalizedArgs = (raw: readonly string[]): readonly string[] =>
26
- raw[0] === 'help' && raw[1] !== undefined && delegatedHelp.has(raw[1]) ? [raw[1], '--help'] : raw
28
+ raw.length === 2 && raw[0] === 'help' && delegatedHelp.has(raw[1]!) ? [raw[1]!, '--help'] : raw
27
29
 
28
30
  const write = (runtime: CommandRuntime, output: Output): number => {
29
31
  if (output.out !== '') runtime.stdout.write(output.out)
package/src/doctor.ts CHANGED
@@ -53,6 +53,7 @@ export type DoctorOutput = {
53
53
  }
54
54
 
55
55
  const requiredNode = '22.18.0'
56
+ const supportedNodeRange = '^22.18.0 || ^24.0.0 || ^26.0.0'
56
57
 
57
58
  const versionParts = (value: string): readonly [number, number, number] | undefined => {
58
59
  const match = /^(\d+)\.(\d+)\.(\d+)/.exec(value)
@@ -74,6 +75,18 @@ const atLeast = (actual: string, required: string): boolean => {
74
75
  return true
75
76
  }
76
77
 
78
+ // Only stable releases are supported: a nightly or release-candidate build such
79
+ // as `26.0.0-nightly20260829` or `24.0.0-rc.1` carries the numeric prefix of a
80
+ // supported line but satisfies neither the engine range nor the CI matrix.
81
+ const stableVersion = /^\d+\.\d+\.\d+$/
82
+
83
+ export const isSupportedNodeVersion = (value: string): boolean => {
84
+ if (!stableVersion.test(value)) return false
85
+ const major = versionParts(value)?.[0]
86
+ if (major === 22) return atLeast(value, requiredNode)
87
+ return major === 24 || major === 26
88
+ }
89
+
77
90
  const check = (
78
91
  id: string,
79
92
  status: DoctorStatus,
@@ -82,10 +95,10 @@ const check = (
82
95
  ): DoctorCheck => ({ id, status, summary, ...remediation === undefined ? {} : { remediation } })
83
96
 
84
97
  const nodeCheck = (): DoctorCheck =>
85
- atLeast(process.versions.node, requiredNode) ?
86
- check('runtime.node', 'pass', `Node ${process.versions.node} satisfies >=${requiredNode}`) :
98
+ isSupportedNodeVersion(process.versions.node) ?
99
+ check('runtime.node', 'pass', `Node ${process.versions.node} satisfies ${supportedNodeRange}`) :
87
100
  check('runtime.node', 'fail', `Node ${process.versions.node} is unsupported`,
88
- `Install Node ${requiredNode} or newer and rerun cave doctor.`)
101
+ `Install Node ${requiredNode}+, Node 24, or Node 26 and rerun cave doctor.`)
89
102
 
90
103
  const sqliteCheck = (): DoctorCheck => {
91
104
  let db: SqliteDatabase | undefined
package/src/index.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  /**
2
- * `@cavelang/cli` — the `cave` command (parse / add / query / resolve / derive / act / check / suggest-alias / sync / export / report / reconstruct / demo).
2
+ * `@cavelang/cli` — the `cave` command (parse / add / query / search / resolve / derive / act / check / suggest-alias / sync / export / report / reconstruct / demo).
3
3
  * Programmatic access to the same implementations lives here; `dispatch`
4
4
  * and `runCli` expose the shared awaited command lifecycle.
5
5
  */
6
6
 
7
- export { actCommand, addCommand, backupCommand, cave, checkCommand, commandHelp, demoCommand, deriveCommand, exportCommand, generateCommand, helpCommand, highlightCommand, importCommand, parseCommand, queryCommand, reconstructCommand, reportCommand, resolveCommand, restoreCommand, suggestAliasCommand, syncCommand, usage, versionCommand } from './cli.ts'
7
+ export { actCommand, addCommand, backupCommand, cave, checkCommand, commandHelp, demoCommand, deriveCommand, exportCommand, generateCommand, helpCommand, highlightCommand, importCommand, parseCommand, queryCommand, reconstructCommand, reportCommand, resolveCommand, restoreCommand, searchCommand, suggestAliasCommand, syncCommand, usage, versionCommand } from './cli.ts'
8
8
  export { dispatch, runCli } from './dispatch.ts'
9
9
  export type { CommandRuntime } from './dispatch.ts'
10
10
  export { commandRegistry } from './commands.ts'