@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.
Files changed (69) hide show
  1. package/README.md +66 -82
  2. package/bin/kb.js +2 -4
  3. package/dist/esm/check/check.d.ts +9 -17
  4. package/dist/esm/check/enumerate.d.ts +12 -15
  5. package/dist/esm/check/glob-segments.d.ts +1 -1
  6. package/dist/esm/check/resolve-foreign-stores.d.ts +9 -8
  7. package/dist/esm/cli/commands/check.d.ts +4 -10
  8. package/dist/esm/cli/commands/check.js +2 -2
  9. package/dist/esm/cli/commands/create.d.ts +3 -7
  10. package/dist/esm/cli/commands/create.js +1 -1
  11. package/dist/esm/cli/commands/scaffold.d.ts +5 -9
  12. package/dist/esm/cli/commands/scaffold.js +5 -5
  13. package/dist/esm/cli/commands/set-default.d.ts +1 -5
  14. package/dist/esm/cli/commands/set-default.js +1 -1
  15. package/dist/esm/cli/commands/taxonomy.d.ts +5 -10
  16. package/dist/esm/cli/commands/taxonomy.js +10 -9
  17. package/dist/esm/cli/format.d.ts +8 -10
  18. package/dist/esm/cli/resolve-store.d.ts +8 -8
  19. package/dist/esm/cli/run.d.ts +4 -6
  20. package/dist/esm/cli/run.js +1 -1
  21. package/dist/esm/cli/select-kb-prompt.d.ts +6 -5
  22. package/dist/esm/cli/select-kb-prompt.js +1 -1
  23. package/dist/esm/cli/targeting/resolve-changed-paths.d.ts +3 -3
  24. package/dist/esm/cli/targeting/select-notes.d.ts +2 -2
  25. package/dist/esm/config/config-schema.d.ts +10 -9
  26. package/dist/esm/config/kb-loader-error.d.ts +3 -3
  27. package/dist/esm/config/load-config.d.ts +2 -2
  28. package/dist/esm/config/load-config.js +1 -1
  29. package/dist/esm/config/note-scope.d.ts +7 -7
  30. package/dist/esm/create/create.d.ts +8 -8
  31. package/dist/esm/discovery/kb-registry-schema.d.ts +0 -2
  32. package/dist/esm/discovery/load-registry.d.ts +7 -9
  33. package/dist/esm/discovery/load-registry.js +1 -1
  34. package/dist/esm/discovery/register-store.d.ts +3 -4
  35. package/dist/esm/discovery/register-store.js +2 -2
  36. package/dist/esm/discovery/registry-document.d.ts +2 -2
  37. package/dist/esm/discovery/set-default-kb.d.ts +5 -5
  38. package/dist/esm/discovery/set-default-kb.js +3 -3
  39. package/dist/esm/filesystem/exists.d.ts +4 -4
  40. package/dist/esm/frontmatter/parse-note.d.ts +3 -3
  41. package/dist/esm/git/list-git-scope.d.ts +6 -6
  42. package/dist/esm/git/run-git.d.ts +2 -2
  43. package/dist/esm/layout/store-layout.d.ts +5 -5
  44. package/dist/esm/lints/paths.d.ts +1 -1
  45. package/dist/esm/lints/paths.js +1 -1
  46. package/dist/esm/lints/tag-alias.d.ts +1 -1
  47. package/dist/esm/lints/tag-alias.js +1 -1
  48. package/dist/esm/lints/taxonomy.d.ts +9 -8
  49. package/dist/esm/lints/taxonomy.js +2 -2
  50. package/dist/esm/note-io/field-validators.d.ts +1 -1
  51. package/dist/esm/note-io/read-note.d.ts +2 -2
  52. package/dist/esm/note-io/write-note.d.ts +3 -6
  53. package/dist/esm/records/event.d.ts +3 -3
  54. package/dist/esm/scaffold/render-seeds.d.ts +3 -3
  55. package/dist/esm/scaffold/render-seeds.js +2 -2
  56. package/dist/esm/scaffold/scaffold.d.ts +7 -8
  57. package/dist/esm/tags/load-aliases.d.ts +3 -4
  58. package/dist/esm/taxonomy/domain-paths.d.ts +6 -6
  59. package/dist/esm/taxonomy/load-taxonomy.d.ts +3 -3
  60. package/dist/esm/taxonomy/load-taxonomy.js +2 -2
  61. package/dist/esm/taxonomy/taxonomy-schema.d.ts +5 -6
  62. package/dist/esm/taxonomy/write-taxonomy.d.ts +7 -8
  63. package/dist/esm/type-guards.d.ts +1 -1
  64. package/dist/esm/types.d.ts +6 -9
  65. package/dist/esm/vault-integrity/build-vault-index.d.ts +3 -4
  66. package/dist/esm/vault-integrity/check-vault-integrity.d.ts +13 -13
  67. package/dist/esm/vault-integrity/check-vault-integrity.js +1 -1
  68. package/dist/esm/vault-integrity/wikilink-parse.d.ts +21 -16
  69. 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 names in the kb.yaml registry.
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
- /** Usage text for `kb create`. */
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: the new store becomes the
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` an existing `.kb/` or an already-registered name maps to exit 2; a genuine I/O error
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, you are prompted to choose one (or set it later with "kb set-default").
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
- /** Usage text for `kb scaffold`. */
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
- * Store resolution matches `kb check`. A store the registry marks `readonly` is refused, as `kb taxonomy init` does.
8
- * A resolved path holding no `.kb/` is refused too: the command back-fills a store rather than creating one, and a
9
- * registry entry names a path without proving a store is there.
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 a store
10
- created before a given file existed can acquire it. An existing file is left
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 holds. Use "kb create" to make a new store.
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 holding no ${KB_DIR}/
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
- /** Usage text for `kb set-default`. */
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
- /** Usage text for `kb taxonomy`. */
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 imply, and declares them.
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` does, so a store back-filled by this command reports no
8
- * taxonomy drift. A store the registry marks `readonly` is refused, matching `kb-curate --apply`. A malformed
9
- * `.kb/config.yaml` or `.kb/taxonomy.yaml` surfaces as a `KbLoaderError` and maps to exit 2; any other error
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 holds, so a
14
- taxonomy can be introduced to a populated store without every folder reporting
15
- as undeclared. Every folder holding notes is declared, along with each of its
16
- ancestors, under "provisional:" with no description: the command cannot invent
17
- descriptions, and provisional already means "declared, not yet reviewed".
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 declare.
23
- Without it, a store that already has a taxonomy is left
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 hold notes; ${TAXONOMY_FILE} not written\n`, stderr: '' };
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,
@@ -1,5 +1,5 @@
1
1
  import type { Finding } from '../types.js';
2
- /** A resolved store's identity, surfaced in both human and JSON output. */
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 path order, each line reading
24
- * `<severity> <rule> (line N): message`. A clean run (notes checked, no findings) prints `✓ no findings (N notes
25
- * checked)`; a run that checked nothing prints a zero-match line worded for its `scope` (naming the config targets for
26
- * a whole-vault run, and a scope-appropriate line for a targeted one) without the `✓`, since no check ran.
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 carry vault-scoped findings, which describe the store rather than any note. The
29
- * zero-match line then heads the report instead of replacing it: it explains why no note was checked, and the findings
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 against. An explicit `--kb <name>` is looked up in the merged registry
13
- * (`tryLoadKbRegistry` with `projectDir: cwd`, so project-local `.agents/kb.yaml` entries join the user-global
14
- * registry); without a flag, the nearest ancestor `.kb/` directory is used. An unknown `--kb` name or a missing `.kb/`
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: 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 carries the identity a report renders. A
19
- * discovered store is cross-referenced against the registry by path, so a vault marked readonly is reported as such
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;
@@ -1,13 +1,11 @@
1
1
  import { type CommandOutput } from './commands/check.js';
2
2
  import type { SelectKbPrompt } from './select-kb-prompt.js';
3
- /** Top-level usage text for the `kb` bin. */
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. `check`, `create`, `scaffold`, `set-default`, and `taxonomy` are the subcommands; a bare
8
- * invocation or `--help`/`-h` prints top-level usage (exit 0), and an unknown command prints usage to stderr (exit 2).
9
- * The optional `selectKb` picker is forwarded to `set-default`'s interactive form and to `create`'s ambiguous
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[];
@@ -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 holds.
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. Injected into `runSetDefault` so the dispatcher itself
13
- * stays free of terminal I/O and remains directly testable; the real implementation is {@link readlineSelectKbPrompt}.
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, `(none)` carries the current marker instead.
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. This is the feature's sole interactive seam — `cli/index.ts` supplies it only when stdin is a
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) no default${noneSuffix}`);
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
- * Git emits toplevel-relative paths and resolves symlinks, so each path is rebased onto the real store root — a no-op
15
- * when the store is the repository root, correct when it is nested. A git failure (unknown ref, not a repository)
16
- * returns `{ ok: false }` for the caller to surface as a usage error rather than throwing.
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 likely typos. */
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 distinguishing a typo from a legitimately out-of-scope target.
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 about; an
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. Targets the `content/`-scoped layout
16
- * the owner's stores use; with `picomatch` `dot:false`, dot-directories (`.kb`, `.git`, `.agents`) are excluded
17
- * implicitly, so the default exclude only names `node_modules`. Visibility defaults to the safer of the two values, so
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: it may point at a store as shareable as its own or more so, never at a less shareable one.
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: the glob target set, the glob exclude set, and the store's visibility. */
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
- /** How widely a store is published: `shared` reaches collaborators through a remote, `private` reaches nobody else. */
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 loaders (`loadKbConfig`, `loadAliases`) on a structural defect: malformed YAML or
3
- * wrong types. The `kind` discriminant lets a caller distinguish a recoverable config or alias defect from any other
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
- * Mirrors {@link loadAliases}: a single plain-object input, structural defects (malformed YAML, wrong types) throw a
8
- * {@link KbLoaderError} naming the file. I/O errors other than a missing file propagate.
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 ${result.error.issues[0]?.message ?? 'unknown error'}`);
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
- /** The note-membership predicates a {@link KbConfig} defines, all matching KB-root-relative, slash-separated paths. */
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 the single definition of "a note" shared by
13
- * `enumerateNotes` (which `kb check`/`kb-curate` drive) and `kb-retrieve`. Both axes match with `picomatch`'s
14
- * `dot:false`, so dot-directories (`.kb`, `.git`, `.agents`) are excluded implicitly without naming them in `exclude`.
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 `.md` extension gate is deliberately left to the caller: `enumerateNotes` applies its own `.endsWith('.md')`
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` 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, so the caller should prompt for a choice.
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: a description is
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 an existing `.kb/`, and (when registering) an already-registered name are checked
50
- * before anything is written, so a precondition failure leaves the filesystem untouched. Genuine I/O failures
51
- * propagate.
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>;