@williamthorsen/kb 0.8.0 → 0.8.1
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 +66 -82
- package/bin/kb.js +2 -4
- package/dist/esm/check/check.d.ts +9 -17
- package/dist/esm/check/enumerate.d.ts +12 -15
- package/dist/esm/check/glob-segments.d.ts +1 -1
- package/dist/esm/check/resolve-foreign-stores.d.ts +9 -8
- package/dist/esm/cli/commands/check.d.ts +4 -10
- package/dist/esm/cli/commands/check.js +2 -2
- package/dist/esm/cli/commands/create.d.ts +3 -7
- package/dist/esm/cli/commands/create.js +1 -1
- package/dist/esm/cli/commands/scaffold.d.ts +5 -9
- package/dist/esm/cli/commands/scaffold.js +5 -5
- package/dist/esm/cli/commands/set-default.d.ts +1 -5
- package/dist/esm/cli/commands/set-default.js +1 -1
- package/dist/esm/cli/commands/taxonomy.d.ts +5 -10
- package/dist/esm/cli/commands/taxonomy.js +10 -9
- package/dist/esm/cli/format.d.ts +8 -10
- package/dist/esm/cli/resolve-store.d.ts +8 -8
- package/dist/esm/cli/run.d.ts +4 -6
- package/dist/esm/cli/run.js +1 -1
- package/dist/esm/cli/select-kb-prompt.d.ts +6 -5
- package/dist/esm/cli/select-kb-prompt.js +1 -1
- package/dist/esm/cli/targeting/resolve-changed-paths.d.ts +3 -3
- package/dist/esm/cli/targeting/select-notes.d.ts +2 -2
- package/dist/esm/config/config-schema.d.ts +10 -9
- package/dist/esm/config/kb-loader-error.d.ts +3 -3
- package/dist/esm/config/load-config.d.ts +2 -2
- package/dist/esm/config/load-config.js +1 -1
- package/dist/esm/config/note-scope.d.ts +7 -7
- package/dist/esm/create/create.d.ts +8 -8
- package/dist/esm/discovery/kb-registry-schema.d.ts +0 -2
- package/dist/esm/discovery/load-registry.d.ts +7 -9
- package/dist/esm/discovery/load-registry.js +1 -1
- package/dist/esm/discovery/register-store.d.ts +3 -4
- package/dist/esm/discovery/register-store.js +2 -2
- package/dist/esm/discovery/registry-document.d.ts +2 -2
- package/dist/esm/discovery/set-default-kb.d.ts +5 -5
- package/dist/esm/discovery/set-default-kb.js +3 -3
- package/dist/esm/filesystem/exists.d.ts +4 -4
- package/dist/esm/frontmatter/parse-note.d.ts +3 -3
- package/dist/esm/git/list-git-scope.d.ts +6 -6
- package/dist/esm/git/run-git.d.ts +2 -2
- package/dist/esm/layout/store-layout.d.ts +5 -5
- package/dist/esm/lints/paths.d.ts +1 -1
- package/dist/esm/lints/paths.js +1 -1
- package/dist/esm/lints/tag-alias.d.ts +1 -1
- package/dist/esm/lints/tag-alias.js +1 -1
- package/dist/esm/lints/taxonomy.d.ts +9 -8
- package/dist/esm/lints/taxonomy.js +2 -2
- package/dist/esm/note-io/field-validators.d.ts +1 -1
- package/dist/esm/note-io/read-note.d.ts +2 -2
- package/dist/esm/note-io/write-note.d.ts +3 -6
- package/dist/esm/records/event.d.ts +3 -3
- package/dist/esm/scaffold/render-seeds.d.ts +3 -3
- package/dist/esm/scaffold/render-seeds.js +2 -2
- package/dist/esm/scaffold/scaffold.d.ts +7 -8
- package/dist/esm/tags/load-aliases.d.ts +3 -4
- package/dist/esm/taxonomy/domain-paths.d.ts +6 -6
- package/dist/esm/taxonomy/load-taxonomy.d.ts +3 -3
- package/dist/esm/taxonomy/load-taxonomy.js +2 -2
- package/dist/esm/taxonomy/taxonomy-schema.d.ts +5 -6
- package/dist/esm/taxonomy/write-taxonomy.d.ts +7 -8
- package/dist/esm/type-guards.d.ts +1 -1
- package/dist/esm/types.d.ts +6 -9
- package/dist/esm/vault-integrity/build-vault-index.d.ts +3 -4
- package/dist/esm/vault-integrity/check-vault-integrity.d.ts +13 -13
- package/dist/esm/vault-integrity/check-vault-integrity.js +1 -1
- package/dist/esm/vault-integrity/wikilink-parse.d.ts +21 -16
- package/package.json +5 -5
|
@@ -11,11 +11,11 @@ export const CHECK_HELP = `Usage: kb check [paths...] [options]
|
|
|
11
11
|
Validate notes in a knowledge base against its tag aliases and cross-note
|
|
12
12
|
link and path rules. With no path arguments, every note is checked.
|
|
13
13
|
Cross-note rules always resolve against the whole store; a [[store:Target]]
|
|
14
|
-
link resolves against the store its prefix
|
|
14
|
+
link resolves against the store named by its prefix in the kb.yaml registry.
|
|
15
15
|
|
|
16
16
|
Targeting (mutually exclusive):
|
|
17
17
|
[paths...] Check only the notes matching the given glob patterns, files,
|
|
18
|
-
or directories. Quote globs so kb expands them itself. A
|
|
18
|
+
or directories. Quote globs so that kb expands them itself. A
|
|
19
19
|
directory checks every note beneath it. A path that matches no
|
|
20
20
|
note is a usage error unless it names a real non-note.
|
|
21
21
|
--vs <ref> Check only the notes changed between the working tree and the
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { SelectKbPrompt } from '../select-kb-prompt.js';
|
|
2
2
|
import type { CommandOutput } from './check.js';
|
|
3
|
-
|
|
4
|
-
export declare const CREATE_HELP = "Usage: kb create [options]\n\nScaffold a new knowledge base in the current directory and register it in the user-global kb.yaml registry.\n\nRegistering leaves the registry's entries in alphabetical order, preserving its comments and formatting.\n\nWhen the registry has no default knowledge base, the new store becomes the default.\nIf other knowledge bases are already registered, you are prompted to choose one (or set it later with \"kb set-default\").\n\nCreates:\n .editorconfig editor and formatter settings (width, indent, line endings)\n .kb/config.yaml check configuration (commented; defaults apply)\n .kb/tag-aliases.yaml tag-alias map (empty)\n .prettierrc.yaml formatting configuration (commented)\n content/, content/events/\n\nOptions:\n --description <text> Description for the registry entry; cannot be combined with --no-register.\n --name <name> Registry name for the store. Defaults to the directory name.\n --no-register Scaffold without writing the kb.yaml registry entry.\n -h, --help Show this help.\n\nExit codes:\n 0 store created\n 2 usage error, an existing .kb/ in the directory, or an already-registered name\n";
|
|
3
|
+
export declare const CREATE_HELP = "Usage: kb create [options]\n\nScaffold a new knowledge base in the current directory and register it in the user-global kb.yaml registry.\n\nRegistering leaves the registry's entries in alphabetical order, preserving its comments and formatting.\n\nWhen the registry has no default knowledge base, the new store becomes the default.\nIf other knowledge bases are already registered, the command prompts for a choice (or \"kb set-default\" sets one later).\n\nCreates:\n .editorconfig editor and formatter settings (width, indent, line endings)\n .kb/config.yaml check configuration (commented; defaults apply)\n .kb/tag-aliases.yaml tag-alias map (empty)\n .prettierrc.yaml formatting configuration (commented)\n content/, content/events/\n\nOptions:\n --description <text> Description for the registry entry; cannot be combined with --no-register.\n --name <name> Registry name for the store. Defaults to the directory name.\n --no-register Scaffold without writing the kb.yaml registry entry.\n -h, --help Show this help.\n\nExit codes:\n 0 store created\n 2 usage error, an existing .kb/ in the directory, or an already-registered name\n";
|
|
5
4
|
/**
|
|
6
5
|
* Runs `kb create`: parses options, scaffolds a store in `cwd`, and (unless `--no-register`) registers it in the
|
|
7
|
-
* user-global `~/.agents/kb.yaml`. After registering, it ensures a default knowledge base:
|
|
6
|
+
* user-global `~/.agents/kb.yaml`. After registering, it ensures a default knowledge base: The new store becomes the
|
|
8
7
|
* default when none is set and it is the only KB; when other KBs already exist with no default, it delegates to
|
|
9
8
|
* `kb set-default`'s picker (or, with no `selectKb` on a non-interactive stdin, points the user there). A precondition
|
|
10
|
-
* failure from `create`
|
|
9
|
+
* failure from `create` (an existing `.kb/` or an already-registered name) maps to exit 2; a genuine I/O error
|
|
11
10
|
* propagates to the caller.
|
|
12
11
|
*/
|
|
13
12
|
export declare function runCreate(input: {
|
|
@@ -16,15 +15,12 @@ export declare function runCreate(input: {
|
|
|
16
15
|
home?: string;
|
|
17
16
|
selectKb?: SelectKbPrompt;
|
|
18
17
|
}): Promise<CommandOutput>;
|
|
19
|
-
/** Parsed `kb create` options. */
|
|
20
18
|
interface CreateOptions {
|
|
21
19
|
/** Description from `--description`, or `null` to write the entry without one. */
|
|
22
20
|
description: string | null;
|
|
23
21
|
/** Explicit registry name from `--name`, or `null` to default to the directory name. */
|
|
24
22
|
name: string | null;
|
|
25
|
-
/** Whether `--no-register` was supplied. */
|
|
26
23
|
noRegister: boolean;
|
|
27
|
-
/** Whether `--help`/`-h` was supplied. */
|
|
28
24
|
help: boolean;
|
|
29
25
|
}
|
|
30
26
|
/**
|
|
@@ -11,7 +11,7 @@ Scaffold a new knowledge base in the current directory and register it in the us
|
|
|
11
11
|
Registering leaves the registry's entries in alphabetical order, preserving its comments and formatting.
|
|
12
12
|
|
|
13
13
|
When the registry has no default knowledge base, the new store becomes the default.
|
|
14
|
-
If other knowledge bases are already registered,
|
|
14
|
+
If other knowledge bases are already registered, the command prompts for a choice (or "kb set-default" sets one later).
|
|
15
15
|
|
|
16
16
|
Creates:
|
|
17
17
|
.editorconfig editor and formatter settings (width, indent, line endings)
|
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
import type { CommandOutput } from './check.js';
|
|
2
|
-
|
|
3
|
-
export declare const SCAFFOLD_HELP = "Usage: kb scaffold [options]\n\nWrite into an existing knowledge base any canonical file that it lacks, so a store\ncreated before a given file existed can acquire it. An existing file is left\nuntouched unless --force is given.\n\nWrites:\n .editorconfig editor and formatter settings (width, indent, line endings)\n .kb/config.yaml check configuration (commented; defaults apply)\n .kb/tag-aliases.yaml tag-alias map (empty)\n .prettierrc.yaml formatting configuration (commented)\n content/, content/events/\n\n.kb/taxonomy.yaml is not part of this set: \"kb taxonomy init\" derives it from\nthe notes that the store already holds. Use \"kb create\" to make a new store.\n\nOptions:\n --force Replace an existing canonical file with a fresh seed. A\n directory has no content to replace and is left as it is.\n --kb <name> Use the named store from the kb.yaml registry. Without it, the\n nearest ancestor .kb/ directory is used.\n -h, --help Show this help.\n\nExit codes:\n 0 every canonical file is present, whether it was written or already there\n 2 usage error, unresolvable store, a store marked readonly in kb.yaml, or a\n resolved path holding no .kb/\n";
|
|
2
|
+
export declare const SCAFFOLD_HELP = "Usage: kb scaffold [options]\n\nWrite into an existing knowledge base any canonical file that it lacks, so that\na store created before a given file existed can acquire it. An existing file is\nleft untouched unless --force is given.\n\nWrites:\n .editorconfig editor and formatter settings (width, indent, line endings)\n .kb/config.yaml check configuration (commented; defaults apply)\n .kb/tag-aliases.yaml tag-alias map (empty)\n .prettierrc.yaml formatting configuration (commented)\n content/, content/events/\n\n.kb/taxonomy.yaml is not part of this set: \"kb taxonomy init\" derives it from\nthe notes that the store already contains. Use \"kb create\" to make a new store.\n\nOptions:\n --force Replace an existing canonical file with a fresh seed. A\n directory has no content to replace and is left as it is.\n --kb <name> Use the named store from the kb.yaml registry. Without it, the\n nearest ancestor .kb/ directory is used.\n -h, --help Show this help.\n\nExit codes:\n 0 every canonical file is present, whether it was written or already there\n 2 usage error, unresolvable store, a store marked readonly in kb.yaml, or a\n resolved path containing no .kb/\n";
|
|
4
3
|
/**
|
|
5
|
-
* Runs `kb scaffold`: parses options, resolves the store, and writes the canonical files it lacks.
|
|
4
|
+
* Runs `kb scaffold`: parses options, resolves the store, and writes the canonical files that it lacks.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* A store that the registry marks `readonly` is refused. A resolved path containing no `.kb/` is refused too: The
|
|
7
|
+
* command back-fills a store rather than creating one, and a registry entry names a path without proving a store is
|
|
8
|
+
* there.
|
|
10
9
|
*/
|
|
11
10
|
export declare function runScaffold(input: {
|
|
12
11
|
argv: readonly string[];
|
|
13
12
|
cwd: string;
|
|
14
13
|
home?: string;
|
|
15
14
|
}): Promise<CommandOutput>;
|
|
16
|
-
/** Parsed `kb scaffold` options. */
|
|
17
15
|
interface ScaffoldOptions {
|
|
18
|
-
/** Whether `--force` was supplied. */
|
|
19
16
|
force: boolean;
|
|
20
|
-
/** Whether `--help`/`-h` was supplied. */
|
|
21
17
|
help: boolean;
|
|
22
18
|
/** Explicit store name from `--kb`, or `null` for ancestor-walk discovery. */
|
|
23
19
|
kb: string | null;
|
|
@@ -6,9 +6,9 @@ import { takeInlineValue, takeValue } from "../parse-flag-value.js";
|
|
|
6
6
|
import { resolveStore } from "../resolve-store.js";
|
|
7
7
|
export const SCAFFOLD_HELP = `Usage: kb scaffold [options]
|
|
8
8
|
|
|
9
|
-
Write into an existing knowledge base any canonical file that it lacks, so
|
|
10
|
-
created before a given file existed can acquire it. An existing file is
|
|
11
|
-
untouched unless --force is given.
|
|
9
|
+
Write into an existing knowledge base any canonical file that it lacks, so that
|
|
10
|
+
a store created before a given file existed can acquire it. An existing file is
|
|
11
|
+
left untouched unless --force is given.
|
|
12
12
|
|
|
13
13
|
Writes:
|
|
14
14
|
.editorconfig editor and formatter settings (width, indent, line endings)
|
|
@@ -18,7 +18,7 @@ Writes:
|
|
|
18
18
|
content/, content/events/
|
|
19
19
|
|
|
20
20
|
.kb/taxonomy.yaml is not part of this set: "kb taxonomy init" derives it from
|
|
21
|
-
the notes that the store already
|
|
21
|
+
the notes that the store already contains. Use "kb create" to make a new store.
|
|
22
22
|
|
|
23
23
|
Options:
|
|
24
24
|
--force Replace an existing canonical file with a fresh seed. A
|
|
@@ -30,7 +30,7 @@ Options:
|
|
|
30
30
|
Exit codes:
|
|
31
31
|
0 every canonical file is present, whether it was written or already there
|
|
32
32
|
2 usage error, unresolvable store, a store marked readonly in kb.yaml, or a
|
|
33
|
-
resolved path
|
|
33
|
+
resolved path containing no ${KB_DIR}/
|
|
34
34
|
`;
|
|
35
35
|
export async function runScaffold(input) {
|
|
36
36
|
let options;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { SelectKbPrompt } from '../select-kb-prompt.js';
|
|
2
2
|
import type { CommandOutput } from './check.js';
|
|
3
|
-
|
|
4
|
-
export declare const SET_DEFAULT_HELP = "Usage: kb set-default [name] [options]\n\nSet, clear, or interactively choose the user-global default knowledge base \u2014\nthe top-level default_kb pointer in ~/.agents/kb.yaml.\n\n kb set-default <name> Set default_kb to the named registered KB.\n kb set-default --none Clear default_kb.\n kb set-default List the registered KBs and prompt for a choice\n (including a \"(none)\" option to clear).\n\nOptions:\n --none Clear the default knowledge base.\n -h, --help Show this help.\n\nExit codes:\n 0 default set or cleared, or the selection was cancelled\n 2 usage error, an unregistered name, no registered KBs, or no name supplied\n when stdin is not interactive\n";
|
|
3
|
+
export declare const SET_DEFAULT_HELP = "Usage: kb set-default [name] [options]\n\nSet, clear, or interactively choose the user-global default knowledge base:\nthe top-level default_kb pointer in ~/.agents/kb.yaml.\n\n kb set-default <name> Set default_kb to the named registered KB.\n kb set-default --none Clear default_kb.\n kb set-default List the registered KBs and prompt for a choice\n (including a \"(none)\" option to clear).\n\nOptions:\n --none Clear the default knowledge base.\n -h, --help Show this help.\n\nExit codes:\n 0 default set or cleared, or the selection was cancelled\n 2 usage error, an unregistered name, no registered KBs, or no name supplied\n when stdin is not interactive\n";
|
|
5
4
|
/**
|
|
6
5
|
* Runs `kb set-default`: sets, clears, or interactively selects the user-global `default_kb`. Resolution reads the
|
|
7
6
|
* user-global registry only (no project overlay), so the chosen default resolves in every project context. The picker
|
|
@@ -13,13 +12,10 @@ export declare function runSetDefault(input: {
|
|
|
13
12
|
home?: string;
|
|
14
13
|
selectKb?: SelectKbPrompt;
|
|
15
14
|
}): Promise<CommandOutput>;
|
|
16
|
-
/** Parsed `kb set-default` options. */
|
|
17
15
|
interface SetDefaultOptions {
|
|
18
16
|
/** The positional KB name, or `null` when none was supplied (interactive form). */
|
|
19
17
|
name: string | null;
|
|
20
|
-
/** Whether `--none` was supplied. */
|
|
21
18
|
none: boolean;
|
|
22
|
-
/** Whether `--help`/`-h` was supplied. */
|
|
23
19
|
help: boolean;
|
|
24
20
|
}
|
|
25
21
|
/**
|
|
@@ -5,7 +5,7 @@ import { tryLoadKbRegistry } from "../../discovery/load-registry.js";
|
|
|
5
5
|
import { clearDefaultKb, setDefaultKb } from "../../discovery/set-default-kb.js";
|
|
6
6
|
export const SET_DEFAULT_HELP = `Usage: kb set-default [name] [options]
|
|
7
7
|
|
|
8
|
-
Set, clear, or interactively choose the user-global default knowledge base
|
|
8
|
+
Set, clear, or interactively choose the user-global default knowledge base:
|
|
9
9
|
the top-level default_kb pointer in ~/.agents/kb.yaml.
|
|
10
10
|
|
|
11
11
|
kb set-default <name> Set default_kb to the named registered KB.
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { CommandOutput } from './check.js';
|
|
2
|
-
|
|
3
|
-
export declare const TAXONOMY_HELP = "Usage: kb taxonomy init [options]\n\nDerive a starting taxonomy from the notes a knowledge base already holds, so a\ntaxonomy can be introduced to a populated store without every folder reporting\nas undeclared. Every folder holding notes is declared, along with each of its\nancestors, under \"provisional:\" with no description: the command cannot invent\ndescriptions, and provisional already means \"declared, not yet reviewed\".\n\nOptions:\n --kb <name> Use the named store from the kb.yaml registry. Without it, the\n nearest ancestor .kb/ directory is used.\n --merge Add only the domains an existing taxonomy does not declare.\n Without it, a store that already has a taxonomy is left\n untouched.\n -h, --help Show this help.\n\nExit codes:\n 0 the taxonomy was written, or already declared every derived domain\n 2 usage error, unresolvable store, a store marked readonly in kb.yaml,\n malformed config or taxonomy, or an existing taxonomy without --merge\n";
|
|
2
|
+
export declare const TAXONOMY_HELP = "Usage: kb taxonomy init [options]\n\nDerive a starting taxonomy from the notes that a knowledge base already\ncontains, so that a taxonomy can be introduced to a populated store without\nevery folder reporting as undeclared. Every folder containing notes is\ndeclared, along with each of its ancestors, under \"provisional:\" with no\ndescription: The command cannot invent descriptions, and provisional already\nmeans \"declared, not yet reviewed\".\n\nOptions:\n --kb <name> Use the named store from the kb.yaml registry. Without it, the\n nearest ancestor .kb/ directory is used.\n --merge Add only the domains that an existing taxonomy does not\n declare. Without it, a store that already has a taxonomy is\n left untouched.\n -h, --help Show this help.\n\nExit codes:\n 0 the taxonomy was written, or already declared every derived domain\n 2 usage error, unresolvable store, a store marked readonly in kb.yaml,\n malformed config or taxonomy, or an existing taxonomy without --merge\n";
|
|
4
3
|
/**
|
|
5
|
-
* Runs `kb taxonomy`: parses options, resolves the store, derives the domains its notes
|
|
4
|
+
* Runs `kb taxonomy`: parses options, resolves the store, derives the domains implied by its notes, and declares them.
|
|
6
5
|
*
|
|
7
|
-
* The derivation reads the same enumeration `kb check
|
|
8
|
-
* taxonomy drift. A store the registry marks `readonly` is refused
|
|
9
|
-
* `.kb/config.yaml` or `.kb/taxonomy.yaml
|
|
6
|
+
* The derivation reads the same enumeration as `kb check`, so a store back-filled by this command reports no
|
|
7
|
+
* taxonomy drift. A store that the registry marks `readonly` is refused. The loaders throw a `KbLoaderError` for a
|
|
8
|
+
* malformed `.kb/config.yaml` or `.kb/taxonomy.yaml`, and the command maps that error to exit 2; any other error
|
|
10
9
|
* propagates to the caller as a real crash.
|
|
11
10
|
*/
|
|
12
11
|
export declare function runTaxonomy(input: {
|
|
@@ -14,15 +13,11 @@ export declare function runTaxonomy(input: {
|
|
|
14
13
|
cwd: string;
|
|
15
14
|
home?: string;
|
|
16
15
|
}): Promise<CommandOutput>;
|
|
17
|
-
/** Parsed `kb taxonomy` options. */
|
|
18
16
|
interface TaxonomyOptions {
|
|
19
|
-
/** The subcommand to run, or `null` when none was given. */
|
|
20
17
|
subcommand: 'init' | null;
|
|
21
18
|
/** Explicit store name from `--kb`, or `null` for ancestor-walk discovery. */
|
|
22
19
|
kb: string | null;
|
|
23
|
-
/** Whether `--merge` was supplied. */
|
|
24
20
|
merge: boolean;
|
|
25
|
-
/** Whether `--help`/`-h` was supplied. */
|
|
26
21
|
help: boolean;
|
|
27
22
|
}
|
|
28
23
|
/**
|
|
@@ -10,18 +10,19 @@ import { takeInlineValue, takeValue } from "../parse-flag-value.js";
|
|
|
10
10
|
import { resolveStore } from "../resolve-store.js";
|
|
11
11
|
export const TAXONOMY_HELP = `Usage: kb taxonomy init [options]
|
|
12
12
|
|
|
13
|
-
Derive a starting taxonomy from the notes a knowledge base already
|
|
14
|
-
taxonomy can be introduced to a populated store without
|
|
15
|
-
as undeclared. Every folder
|
|
16
|
-
ancestors, under "provisional:" with no
|
|
17
|
-
|
|
13
|
+
Derive a starting taxonomy from the notes that a knowledge base already
|
|
14
|
+
contains, so that a taxonomy can be introduced to a populated store without
|
|
15
|
+
every folder reporting as undeclared. Every folder containing notes is
|
|
16
|
+
declared, along with each of its ancestors, under "provisional:" with no
|
|
17
|
+
description: The command cannot invent descriptions, and provisional already
|
|
18
|
+
means "declared, not yet reviewed".
|
|
18
19
|
|
|
19
20
|
Options:
|
|
20
21
|
--kb <name> Use the named store from the kb.yaml registry. Without it, the
|
|
21
22
|
nearest ancestor .kb/ directory is used.
|
|
22
|
-
--merge Add only the domains an existing taxonomy does not
|
|
23
|
-
Without it, a store that already has a taxonomy is
|
|
24
|
-
untouched.
|
|
23
|
+
--merge Add only the domains that an existing taxonomy does not
|
|
24
|
+
declare. Without it, a store that already has a taxonomy is
|
|
25
|
+
left untouched.
|
|
25
26
|
-h, --help Show this help.
|
|
26
27
|
|
|
27
28
|
Exit codes:
|
|
@@ -117,7 +118,7 @@ async function initTaxonomy(input) {
|
|
|
117
118
|
const notes = await enumerateNotes({ kbRoot: kbRoot.path, config });
|
|
118
119
|
const domains = deriveDomains(notes.map((note) => note.relativePath));
|
|
119
120
|
if (domains.length === 0) {
|
|
120
|
-
return { exitCode: 0, stdout: `no assertion folders
|
|
121
|
+
return { exitCode: 0, stdout: `no assertion folders contain notes; ${TAXONOMY_FILE} not written\n`, stderr: '' };
|
|
121
122
|
}
|
|
122
123
|
const { added } = await writeTaxonomy({
|
|
123
124
|
kbRoot,
|
package/dist/esm/cli/format.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Finding } from '../types.js';
|
|
2
|
-
/** A resolved store's identity,
|
|
2
|
+
/** A resolved store's identity, shown in both human and JSON output. */
|
|
3
3
|
export interface StoreRef {
|
|
4
4
|
/** The store's display name, or `null` for a `.kb/`-discovered store with no registry entry. */
|
|
5
5
|
name: string | null;
|
|
@@ -10,23 +10,21 @@ export interface StoreRef {
|
|
|
10
10
|
export interface CheckSummary {
|
|
11
11
|
/** Notes enumerated and checked. */
|
|
12
12
|
notes: number;
|
|
13
|
-
/** Total findings. */
|
|
14
13
|
total: number;
|
|
15
|
-
/** Findings with `severity: 'error'`. */
|
|
16
14
|
errors: number;
|
|
17
|
-
/** Findings with `severity: 'warning'`. */
|
|
18
15
|
warnings: number;
|
|
19
16
|
}
|
|
20
17
|
/** Which selection produced a report, controlling the wording of the zero-match line. */
|
|
21
18
|
export type CheckScope = 'vault' | 'patterns' | 'vs';
|
|
22
19
|
/**
|
|
23
|
-
* Renders the default human output. Findings are grouped by file in
|
|
24
|
-
* `<severity> <rule> (line N): message`. A clean run (notes checked, no findings) prints
|
|
25
|
-
* checked)`; a run that checked nothing prints a zero-match line worded for its `scope` (naming
|
|
26
|
-
* a whole-vault run, and a scope-appropriate line for a targeted one) without the `✓`, since no
|
|
20
|
+
* Renders the default human output. Findings are grouped by file, in the order in which each file first appears, each
|
|
21
|
+
* line reading `<severity> <rule> (line N): message`. A clean run (notes checked, no findings) prints
|
|
22
|
+
* `✓ no findings (N notes checked)`; a run that checked nothing prints a zero-match line worded for its `scope` (naming
|
|
23
|
+
* the config targets for a whole-vault run, and a scope-appropriate line for a targeted one) without the `✓`, since no
|
|
24
|
+
* check ran.
|
|
27
25
|
*
|
|
28
|
-
* A run can check no notes and still
|
|
29
|
-
* zero-match line then heads the report instead of replacing it:
|
|
26
|
+
* A run can check no notes and still include vault-scoped findings, which describe the store rather than any note. The
|
|
27
|
+
* zero-match line then heads the report instead of replacing it: It explains why no note was checked, and the findings
|
|
30
28
|
* follow.
|
|
31
29
|
*/
|
|
32
30
|
export declare function formatHuman(input: {
|
|
@@ -9,15 +9,15 @@ export type ResolveStoreOutcome = {
|
|
|
9
9
|
message: string;
|
|
10
10
|
};
|
|
11
11
|
/**
|
|
12
|
-
* Resolves the store a command runs
|
|
13
|
-
* (`tryLoadKbRegistry` with `projectDir: cwd`, so project-local `.agents/kb.yaml` entries
|
|
14
|
-
*
|
|
15
|
-
* fails for exit 2.
|
|
12
|
+
* Resolves the store against which a command runs. An explicit `--kb <name>` is looked up in the merged registry
|
|
13
|
+
* (`tryLoadKbRegistry` with `projectDir: cwd`, so the registry includes project-local `.agents/kb.yaml` entries as
|
|
14
|
+
* well as user-global ones); without a flag, the nearest ancestor `.kb/` directory is used. An unknown `--kb` name or
|
|
15
|
+
* a missing `.kb/` fails for exit 2.
|
|
16
16
|
*
|
|
17
|
-
* The registry's `readonly` flag is reported rather than enforced:
|
|
18
|
-
* and a read-only command ignores it. It is kept off {@link StoreRef}, which
|
|
19
|
-
* discovered store is cross-referenced against the registry by path, so a vault marked readonly is reported
|
|
20
|
-
* however it was named; one with no registry entry has no metadata to consult and is reported writable.
|
|
17
|
+
* The registry's `readonly` flag is reported rather than enforced: A command that writes into the store refuses on it,
|
|
18
|
+
* and a read-only command ignores it. It is kept off {@link StoreRef}, which contains the identity that a report
|
|
19
|
+
* renders. A discovered store is cross-referenced against the registry by path, so a vault marked readonly is reported
|
|
20
|
+
* as such however it was named; one with no registry entry has no metadata to consult and is reported writable.
|
|
21
21
|
*/
|
|
22
22
|
export declare function resolveStore(input: {
|
|
23
23
|
explicitKb: string | null;
|
package/dist/esm/cli/run.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { type CommandOutput } from './commands/check.js';
|
|
2
2
|
import type { SelectKbPrompt } from './select-kb-prompt.js';
|
|
3
|
-
|
|
4
|
-
export declare const HELP = "Usage: kb <command> [options]\n\nCommands:\n check Validate a knowledge base, optionally scoped to selected notes.\n create Scaffold a new knowledge base and register it in the kb.yaml registry.\n scaffold Write into an existing knowledge base any canonical file that it lacks.\n set-default Set, clear, or choose the default knowledge base.\n taxonomy Derive a knowledge base's taxonomy from the notes it already holds.\n\nRun \"kb <command> --help\" for command options.\n";
|
|
3
|
+
export declare const HELP = "Usage: kb <command> [options]\n\nCommands:\n check Validate a knowledge base, optionally scoped to selected notes.\n create Scaffold a new knowledge base and register it in the kb.yaml registry.\n scaffold Write into an existing knowledge base any canonical file that it lacks.\n set-default Set, clear, or choose the default knowledge base.\n taxonomy Derive a knowledge base's taxonomy from the notes that it already contains.\n\nRun \"kb <command> --help\" for command options.\n";
|
|
5
4
|
/**
|
|
6
5
|
* Dispatches a `kb` subcommand and returns its {@link CommandOutput} without touching `process`, so tests drive the
|
|
7
|
-
* command directly.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* default-KB prompt; `cli/index.ts` supplies it only when stdin is a TTY.
|
|
6
|
+
* command directly. A bare invocation or `--help`/`-h` prints top-level usage (exit 0), and an unknown command prints
|
|
7
|
+
* usage to stderr (exit 2). The optional `selectKb` picker is forwarded to `set-default`'s interactive form and to
|
|
8
|
+
* `create`'s ambiguous default-KB prompt.
|
|
11
9
|
*/
|
|
12
10
|
export declare function run(input: {
|
|
13
11
|
argv: readonly string[];
|
package/dist/esm/cli/run.js
CHANGED
|
@@ -10,7 +10,7 @@ Commands:
|
|
|
10
10
|
create Scaffold a new knowledge base and register it in the kb.yaml registry.
|
|
11
11
|
scaffold Write into an existing knowledge base any canonical file that it lacks.
|
|
12
12
|
set-default Set, clear, or choose the default knowledge base.
|
|
13
|
-
taxonomy Derive a knowledge base's taxonomy from the notes it already
|
|
13
|
+
taxonomy Derive a knowledge base's taxonomy from the notes that it already contains.
|
|
14
14
|
|
|
15
15
|
Run "kb <command> --help" for command options.
|
|
16
16
|
`;
|
|
@@ -9,8 +9,9 @@ export type SelectKbChoice = {
|
|
|
9
9
|
kind: 'cancel';
|
|
10
10
|
};
|
|
11
11
|
/**
|
|
12
|
-
* Presents the registered KBs and resolves the user's choice.
|
|
13
|
-
* stays free of terminal I/O and remains directly testable; the real implementation is
|
|
12
|
+
* Presents the registered KBs and resolves the user's choice. A command takes it as an injected dependency, so that the
|
|
13
|
+
* command stays free of terminal I/O and remains directly testable; the real implementation is
|
|
14
|
+
* {@link readlineSelectKbPrompt}.
|
|
14
15
|
*/
|
|
15
16
|
export type SelectKbPrompt = (input: {
|
|
16
17
|
entries: readonly KbRegistryEntry[];
|
|
@@ -18,7 +19,8 @@ export type SelectKbPrompt = (input: {
|
|
|
18
19
|
}) => Promise<SelectKbChoice>;
|
|
19
20
|
/**
|
|
20
21
|
* Renders the numbered selection list: each registered KB (marking the current default) followed by a trailing
|
|
21
|
-
* `(none)` option numbered `entries.length + 1`. When no default is set,
|
|
22
|
+
* `(none)` option numbered `entries.length + 1`. When no default is set, the current marker appears on `(none)`
|
|
23
|
+
* instead.
|
|
22
24
|
*/
|
|
23
25
|
export declare function formatKbSelection(entries: readonly KbRegistryEntry[], currentDefaultName?: string): string;
|
|
24
26
|
/**
|
|
@@ -28,7 +30,6 @@ export declare function formatKbSelection(entries: readonly KbRegistryEntry[], c
|
|
|
28
30
|
export declare function parseSelection(answer: string, kbCount: number): SelectKbChoice | null;
|
|
29
31
|
/**
|
|
30
32
|
* A readline-backed {@link SelectKbPrompt}: it prints the selection list, reads a line, and re-prompts until the answer
|
|
31
|
-
* resolves to a choice.
|
|
32
|
-
* TTY, and other commands (e.g. `kb create`) can reuse it for their own interactive default-KB selection.
|
|
33
|
+
* resolves to a choice.
|
|
33
34
|
*/
|
|
34
35
|
export declare const readlineSelectKbPrompt: SelectKbPrompt;
|
|
@@ -7,7 +7,7 @@ export function formatKbSelection(entries, currentDefaultName) {
|
|
|
7
7
|
lines.push(` ${String(index + 1)}) ${entry.name}${suffix}`);
|
|
8
8
|
}
|
|
9
9
|
const noneSuffix = currentDefaultName === undefined ? ' (current)' : '';
|
|
10
|
-
lines.push(` ${String(entries.length + 1)}) (none)
|
|
10
|
+
lines.push(` ${String(entries.length + 1)}) (none): no default${noneSuffix}`);
|
|
11
11
|
return `${lines.join('\n')}\n`;
|
|
12
12
|
}
|
|
13
13
|
export function parseSelection(answer, kbCount) {
|
|
@@ -11,9 +11,9 @@ export type ChangedPathsResult = {
|
|
|
11
11
|
*
|
|
12
12
|
* The change set is `git diff` of the working tree against `merge-base(ref, HEAD)` with `--diff-filter=AMR`, so it
|
|
13
13
|
* follows renames (reporting the destination), includes uncommitted edits to tracked files, and excludes deletions.
|
|
14
|
-
*
|
|
15
|
-
* when the store is the repository root, correct when it is nested. A git failure (unknown ref, not a
|
|
16
|
-
* returns `{ ok: false }` for the caller to
|
|
14
|
+
* Because git emits toplevel-relative paths and resolves symlinks, the function rebases each path onto the real store
|
|
15
|
+
* root: a no-op when the store is the repository root, correct when it is nested. A git failure (unknown ref, not a
|
|
16
|
+
* repository) returns `{ ok: false }` for the caller to report as a usage error rather than throwing.
|
|
17
17
|
*/
|
|
18
18
|
export declare function resolveChangedPaths(input: {
|
|
19
19
|
storeRoot: string;
|
|
@@ -3,7 +3,7 @@ import type { EnumeratedNote } from '../../check/enumerate.js';
|
|
|
3
3
|
export interface SelectionResult {
|
|
4
4
|
/** Notes matched by at least one pattern, in enumeration order, deduplicated. */
|
|
5
5
|
selected: EnumeratedNote[];
|
|
6
|
-
/** Patterns that matched no validatable note and are backed by no real on-disk path
|
|
6
|
+
/** Patterns that matched no validatable note and are backed by no real on-disk path: likely typos. */
|
|
7
7
|
unmatched: string[];
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
@@ -14,7 +14,7 @@ export interface SelectionResult {
|
|
|
14
14
|
* `targets`/`exclude` filtering is inherited and a quoted glob behaves the same as a shell-expanded one. A bare
|
|
15
15
|
* directory expands to its subtree. A pattern matching no note is reported in `unmatched` unless a real on-disk path
|
|
16
16
|
* backs it (a non-validatable file such as a README, an excluded subtree, or an empty directory), in which case it is
|
|
17
|
-
* dropped silently
|
|
17
|
+
* dropped silently, which distinguishes a typo from a legitimately out-of-scope target.
|
|
18
18
|
*/
|
|
19
19
|
export declare function selectNotes(input: {
|
|
20
20
|
notes: readonly EnumeratedNote[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
/**
|
|
3
|
-
* The on-disk `.kb/config.yaml` shape. Every field is optional so a file may override only the key it cares
|
|
4
|
-
* absent field falls back to {@link defaultKbConfig}.
|
|
3
|
+
* The on-disk `.kb/config.yaml` shape. Every field is optional so that a file may override only the key that it cares
|
|
4
|
+
* about; an absent field falls back to {@link defaultKbConfig}.
|
|
5
5
|
*/
|
|
6
6
|
export declare const configFileShape: z.ZodObject<{
|
|
7
7
|
targets: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -12,21 +12,20 @@ export declare const configFileShape: z.ZodObject<{
|
|
|
12
12
|
}>>;
|
|
13
13
|
}, z.core.$strip>;
|
|
14
14
|
/**
|
|
15
|
-
* The configuration applied when `.kb/config.yaml` is absent or omits a field.
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* a store that has not declared itself never widens what may link into it.
|
|
15
|
+
* The configuration applied when `.kb/config.yaml` is absent or omits a field. The default exclude names `node_modules`
|
|
16
|
+
* alone, because `createNoteScopeMatcher` already excludes dot-directories. Visibility defaults to the safer of the two
|
|
17
|
+
* values, so a store that has not declared itself never widens what may link into it.
|
|
19
18
|
*/
|
|
20
19
|
export declare const defaultKbConfig: KbConfig;
|
|
21
20
|
/**
|
|
22
21
|
* Whether a link from a store of `source` visibility may resolve into one of `target` visibility. A link never
|
|
23
|
-
* increases disclosure:
|
|
22
|
+
* increases disclosure: It may point at a store as shareable as its own or more so, never at a less shareable one.
|
|
24
23
|
*/
|
|
25
24
|
export declare function isAtLeastAsShareable(input: {
|
|
26
25
|
source: StoreVisibility;
|
|
27
26
|
target: StoreVisibility;
|
|
28
27
|
}): boolean;
|
|
29
|
-
/** The effective check configuration
|
|
28
|
+
/** The effective check configuration, in which a default fills every field that `.kb/config.yaml` omits. */
|
|
30
29
|
export interface KbConfig {
|
|
31
30
|
/** Glob patterns (slash-separated, kbRoot-relative) selecting which notes `check` enumerates. */
|
|
32
31
|
targets: readonly string[];
|
|
@@ -35,5 +34,7 @@ export interface KbConfig {
|
|
|
35
34
|
/** How widely the store is published, which decides what may link into it. */
|
|
36
35
|
visibility: StoreVisibility;
|
|
37
36
|
}
|
|
38
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* How widely a store is published: `shared` is available to collaborators through a remote, `private` to nobody else.
|
|
39
|
+
*/
|
|
39
40
|
export type StoreVisibility = NonNullable<z.infer<typeof configFileShape>['visibility']>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The typed error thrown by the KB
|
|
3
|
-
* wrong types. The `kind` discriminant lets a caller distinguish a recoverable
|
|
2
|
+
* The typed error thrown by the loaders and writers of a KB's YAML files on a structural defect, such as malformed YAML
|
|
3
|
+
* or wrong types. The `kind` discriminant lets a caller distinguish a recoverable defect in such a file from any other
|
|
4
4
|
* throw (an enumeration or detection crash) without matching on message text or relying on `instanceof` surviving a
|
|
5
5
|
* bundle boundary.
|
|
6
6
|
*/
|
|
7
7
|
export declare class KbLoaderError extends Error {
|
|
8
|
-
/** Discriminant for narrow catch boundaries; survives serialization and bundling unlike `instanceof`. */
|
|
9
8
|
readonly kind: "KbLoaderError";
|
|
9
|
+
/** Names the error after its class. */
|
|
10
10
|
constructor(message: string, options?: ErrorOptions);
|
|
11
11
|
}
|
|
12
12
|
/** Type guard narrowing an unknown throw to a {@link KbLoaderError} via its `kind` discriminant. */
|
|
@@ -4,8 +4,8 @@ import { type KbConfig } from './config-schema.js';
|
|
|
4
4
|
* Loads the effective check configuration for a KB root. Returns {@link defaultKbConfig} verbatim when no
|
|
5
5
|
* `.kb/config.yaml` exists; a file present but omitting a field inherits that field's default.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Structural defects (malformed YAML, wrong types) throw a {@link KbLoaderError} naming the file. I/O errors other than
|
|
8
|
+
* a missing file propagate.
|
|
9
9
|
*/
|
|
10
10
|
export declare function loadKbConfig(input: {
|
|
11
11
|
kbRoot: KbRoot;
|
|
@@ -27,7 +27,7 @@ export async function loadKbConfig(input) {
|
|
|
27
27
|
}
|
|
28
28
|
const result = configFileShape.safeParse(parsed ?? {});
|
|
29
29
|
if (!result.success) {
|
|
30
|
-
throw new KbLoaderError(`${path}: invalid config.yaml
|
|
30
|
+
throw new KbLoaderError(`${path}: invalid config.yaml: ${result.error.issues[0]?.message ?? 'unknown error'}`);
|
|
31
31
|
}
|
|
32
32
|
return {
|
|
33
33
|
targets: result.data.targets ?? defaultKbConfig.targets,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { KbConfig } from './config-schema.js';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* The note-membership predicates defined by a {@link KbConfig}, all matching KB-root-relative, slash-separated paths.
|
|
4
|
+
*/
|
|
3
5
|
export interface NoteScopeMatcher {
|
|
4
6
|
/** True when the path matches a `targets` glob. */
|
|
5
7
|
isTarget(relativePath: string): boolean;
|
|
@@ -9,12 +11,10 @@ export interface NoteScopeMatcher {
|
|
|
9
11
|
isNote(relativePath: string): boolean;
|
|
10
12
|
}
|
|
11
13
|
/**
|
|
12
|
-
* Builds the note-membership predicates for a KB config
|
|
13
|
-
* `
|
|
14
|
-
*
|
|
14
|
+
* Builds the note-membership predicates for a KB config, the single definition of "a note". Both axes match with
|
|
15
|
+
* `picomatch`'s `dot:false`, so dot-directories (`.kb`, `.git`, `.agents`) are excluded implicitly without naming them
|
|
16
|
+
* in `exclude`.
|
|
15
17
|
*
|
|
16
|
-
* The
|
|
17
|
-
* during the walk, and `kb-retrieve` constrains ripgrep with `--glob '*.md'`. Keeping it out of `isNote` lets this
|
|
18
|
-
* matcher govern `targets`/`exclude` alone, the one place the two tools previously disagreed.
|
|
18
|
+
* The matcher applies `targets` and `exclude` alone: Each caller applies its own `.md` extension gate.
|
|
19
19
|
*/
|
|
20
20
|
export declare function createNoteScopeMatcher(config: KbConfig): NoteScopeMatcher;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* What `create` did about the registry's `default_kb` pointer when registering a store:
|
|
3
|
-
* `set
|
|
4
|
-
* `unchanged
|
|
5
|
-
* `needs-selection
|
|
3
|
+
* - `set`: It was unset and the new store was the only KB, so the store became the default.
|
|
4
|
+
* - `unchanged`: A default was already set and left untouched.
|
|
5
|
+
* - `needs-selection`: It was unset but other KBs exist; the caller should prompt for a choice.
|
|
6
6
|
*/
|
|
7
7
|
export type DefaultKbOutcome = 'set' | 'unchanged' | 'needs-selection';
|
|
8
8
|
/** A successfully created store and a record of what was written. */
|
|
@@ -13,7 +13,6 @@ export interface CreatedStore {
|
|
|
13
13
|
storePath: string;
|
|
14
14
|
/** The description written into the registry entry; absent when none was supplied. */
|
|
15
15
|
description?: string;
|
|
16
|
-
/** Whether the store was registered in the kb.yaml registry. */
|
|
17
16
|
registered: boolean;
|
|
18
17
|
/** Store-relative paths created by the scaffold. */
|
|
19
18
|
created: readonly string[];
|
|
@@ -21,7 +20,7 @@ export interface CreatedStore {
|
|
|
21
20
|
defaultKb?: DefaultKbOutcome;
|
|
22
21
|
}
|
|
23
22
|
/**
|
|
24
|
-
* Inputs for {@link create}. `registryPath` and `description` belong to the registering form alone:
|
|
23
|
+
* Inputs for {@link create}. `registryPath` and `description` belong to the registering form alone: A description is
|
|
25
24
|
* only ever written into a registry entry, so supplying one without registering is a type error rather than a value
|
|
26
25
|
* that would be silently discarded.
|
|
27
26
|
*/
|
|
@@ -46,8 +45,9 @@ export type CreateOutcome = {
|
|
|
46
45
|
};
|
|
47
46
|
/**
|
|
48
47
|
* Scaffolds a new knowledge-base store in `targetDir` and, unless `register` is false, registers it in the kb.yaml
|
|
49
|
-
* registry. Both preconditions
|
|
50
|
-
* before anything is written
|
|
51
|
-
*
|
|
48
|
+
* registry. Both preconditions, an existing `.kb/` and (when registering) an already-registered name, are checked
|
|
49
|
+
* before anything is written. A precondition failure leaves the filesystem untouched. A name collision that the
|
|
50
|
+
* registry writer detects only at write time also returns `name-registered`, after the scaffold is written. Genuine
|
|
51
|
+
* I/O failures propagate.
|
|
52
52
|
*/
|
|
53
53
|
export declare function create(input: CreateInput): Promise<CreateOutcome>;
|
|
@@ -14,7 +14,5 @@ export declare const kbRegistryFileSchema: z.ZodObject<{
|
|
|
14
14
|
readonly: z.ZodOptional<z.ZodBoolean>;
|
|
15
15
|
}, z.core.$strip>>>;
|
|
16
16
|
}, z.core.$strip>;
|
|
17
|
-
/** The validated on-disk entry shape. */
|
|
18
17
|
export type KbRegistryFileEntry = z.infer<typeof kbRegistryFileEntrySchema>;
|
|
19
|
-
/** The validated on-disk file shape. */
|
|
20
18
|
export type KbRegistryFile = z.infer<typeof kbRegistryFileSchema>;
|