@saasontools/strauss-kb 0.1.15 → 0.1.17

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/ARCHITECTURE.md CHANGED
@@ -84,11 +84,28 @@ from Zod, and `strauss-kb schema` is the contract.
84
84
  A fresh stamp is a baseline nobody has checked, so only a run where every
85
85
  checkable anchor already matched appends `verified[]`.
86
86
 
87
- The v1 resolver is regex-based, biased so a wrong answer loses to no answer: a
88
- span short of the code it claims hashes as stable while that code moves. It
89
- ranks by shape, scopes a dotted symbol to its parent, captures by brace depth or
90
- Python indentation, and returns `null` otherwise. A pure `AnchorResolver`
91
- interface admits a tree-sitter replacement.
87
+ Symbols resolve through tree-sitter first: a WASM parser per language, each
88
+ grammar's own upstream `queries/tags.scm` over definition sites, and the
89
+ definition node's range as the span. A dotted symbol matches the definition whose enclosing chain
90
+ matches; a bare name matching two is `symbol-ambiguous`. Only declarations are
91
+ captured: a symbol appearing solely in a call is no match.
92
+
93
+ The chain is tree-sitter, then regex, then a whole-file hash. A resolver that
94
+ parsed the file answers for it unless it defines no such symbol at all — tags
95
+ queries capture functions and types, not constants, aliases or fields — so
96
+ `symbol-not-found` continues down the chain and the anchor records whichever
97
+ resolver answered. `symbol-ambiguous` and `resolver-unavailable` stop it:
98
+ picking one of two definitions by text search, or swapping a precise span for a
99
+ heuristic one when a grammar will not load, is how a wrong span comes to hash
100
+ as `match`. A grammar that will not load is a finding, never a throw.
101
+
102
+ Grammars download on first use, sha256-pinned by `grammars/manifest.json` and
103
+ cached under `~/.strauss/grammars`; the reasoning is in the
104
+ [specification](https://saasontools.github.io/strauss-agent-tools/specification#symbol-resolution).
105
+
106
+ Each anchor records the resolver that stamped it. A hash only the previous
107
+ resolver reproduces is `drifted`, reason `resolver-changed`. Trees are cached
108
+ per content hash, grammars load once per process.
92
109
 
93
110
  Repository identity is normalised and compared, not parsed: an invented format
94
111
  would reject correct values from unseen hosts.
package/README.md CHANGED
@@ -206,17 +206,18 @@ Why a lock was rejected: [ARCHITECTURE.md](./ARCHITECTURE.md).
206
206
 
207
207
  An anchor names where a record attaches in the code: a `file`, optionally a
208
208
  `symbol` — symbolic, because a line number written mid-change is wrong by the
209
- end of it. Five optional fields extend it:
209
+ end of it. Six optional fields extend it:
210
210
 
211
211
  | Field | Meaning |
212
212
  | ------------- | ------------------------------------------------------------------------------------- |
213
213
  | `hash` | `sha256:<hex>` over the anchored text, algorithm-prefixed. |
214
214
  | `lines` | Line count the hash covered. |
215
215
  | `resolved_at` | When the anchor last resolved. |
216
+ | `resolver` | Which resolver produced the hash: `tree-sitter` or `regex`. |
216
217
  | `repo` | Which repository — remote URL or short name. Absent means this base's own repository. |
217
218
  | `ref` | Git rev the evidence was taken at. |
218
219
 
219
- `hash`, `lines`, and `resolved_at` are **measured** — a resolution pass stamps
220
+ `hash`, `lines`, `resolved_at`, and `resolver` are **measured** — a resolution pass stamps
220
221
  them; `repo` and `ref` are **author-owned identity** and a resolution pass
221
222
  never writes them.
222
223
 
@@ -246,8 +247,17 @@ carries a hash; unstamped anchors and unreachable remotes never fail.
246
247
  A fully clean run — every anchor checked and `match`, none stamped this run —
247
248
  appends a `verified[]` event.
248
249
 
249
- Symbol resolution is a v1 heuristic; ties and unclosed blocks return
250
- `unresolved`.
250
+ Symbols resolve tree-sitter first the 20 language packs that have both a
251
+ grammar and a definitions query, pinned together by `pnpm grammars pin` from
252
+ `grammars/packs.json` and proved at pin time — then the regex heuristic for
253
+ other extensions and for symbols the tags query does not define (constants,
254
+ type aliases, class fields), then a
255
+ whole-file hash when the anchor names no symbol; an ambiguous match or an
256
+ unloadable grammar returns `unresolved` rather than falling through to a guess. Neither half of a pack is published with the
257
+ package: grammar and query both download on first use, sha256-pinned against
258
+ `grammars/manifest.json`, and are cached under `~/.strauss/grammars`. A hash the old resolver still reproduces and
259
+ the new one does not is `drifted` with reason `resolver-changed` — accept it
260
+ with `--rebaseline`.
251
261
 
252
262
  Drift also surfaces on read: `kb_load` and `kb_query` attach a
253
263
  `{ kind: "drifted" }` warning — or `{ kind: "unchecked" }` for a foreign anchor
@@ -408,8 +418,8 @@ Worked flows:
408
418
 
409
419
  **Placement is cache economics.** `load`'s output belongs in the stable
410
420
  prefix — system prompt or first turn; `query` and `pack` results belong at
411
- the tail. `digest` is the base's content stamp: a change-notification hook
412
- and `kb_stamp` (SAA-719) compare it to detect change, not the model. A
421
+ the tail. `digest` is the base's content stamp: `kb_stamp` and the opt-in
422
+ reload hook compare it to detect change, not the model. A
413
423
  prompt cache matches a byte-for-byte prefix, so one volatile result ahead of
414
424
  a stable load prices the base at full rate thereafter. Mechanism and digest
415
425
  caveats: <https://saasontools.github.io/strauss-agent-tools/mcp-reference>.
@@ -451,6 +461,11 @@ carry no numbers:
451
461
  }
452
462
  ```
453
463
 
464
+ A pinned base can also change mid-session — a `git pull`, a sub-agent's write.
465
+ `strauss-kb stamp` reports each pinned base's content digest. Comparing it for
466
+ you is opt-in, see the
467
+ [plugin README](../../plugins/strauss-kb/README.md#opt-in-workspace-hooks).
468
+
454
469
  `sync-instructions <file>` keeps that block between
455
470
  `<!-- strauss-kb:begin/end -->` sentinels in AGENTS.md or CLAUDE.md; it is
456
471
  idempotent, and covers runtimes without a reliable post-compaction hook.
@@ -458,15 +473,16 @@ idempotent, and covers runtimes without a reliable post-compaction hook.
458
473
  What each runtime gets (configs in the
459
474
  [plugin's adapters](../../plugins/strauss-kb/adapters/)):
460
475
 
461
- | Layer | Claude Code | Codex CLI | Antigravity CLI |
462
- | ------------------------- | ------------------ | ------------------------------------------- | -------------------------- |
463
- | MCP tool descriptions | ✓ | ✓ | ✓ |
464
- | Session-start injection | SessionStart hook | SessionStart hook | PreInvocation, per turn |
465
- | Post-compact re-injection | ✓ `compact` source | ✓ client-side; instruction-only when hosted | moot — injected every turn |
466
- | File-read blocking | opt-in PreToolUse | (shell is the side door) | opt-in PreToolUse, JSON |
467
- | Manual-edit validation | opt-in PostToolUse | ✗ | |
468
- | Generated-file edit guard | opt-in PreToolUse | ✗ | ✗ |
469
- | Instruction file | CLAUDE.md | AGENTS.md | AGENTS.md + rules/ |
476
+ | Layer | Claude Code | Codex CLI | Antigravity CLI |
477
+ | ------------------------- | -------------------------------- | ------------------------------------------- | -------------------------- |
478
+ | MCP tool descriptions | ✓ | ✓ | ✓ |
479
+ | Session-start injection | SessionStart hook | SessionStart hook | PreInvocation, per turn |
480
+ | Post-compact re-injection | ✓ `compact` source | ✓ client-side; instruction-only when hosted | moot — injected every turn |
481
+ | Reload after a pull | opt-in PostToolUse, SubagentStop | opt-in PostToolUse on `shell` | moot injected every turn |
482
+ | File-read blocking | opt-in PreToolUse | ✗ (shell is the side door) | opt-in PreToolUse, JSON |
483
+ | Manual-edit validation | opt-in PostToolUse | ✗ | ✗ |
484
+ | Generated-file edit guard | opt-in PreToolUse | | ✗ |
485
+ | Instruction file | CLAUDE.md | AGENTS.md | AGENTS.md + rules/ |
470
486
 
471
487
  Never read record files directly — read through the tools; a raw read bypasses
472
488
  standing, and a superseded record reads exactly like a current one. Enforce it
@@ -4,13 +4,17 @@ import {
4
4
  KB_DIR,
5
5
  KbStore,
6
6
  VERSION
7
- } from "./chunk-KNIUBCZY.js";
7
+ } from "./chunk-ZKIQOBHT.js";
8
8
 
9
9
  // src/cli.ts
10
10
  import { join } from "path";
11
11
  async function runKbCli(argv) {
12
12
  const { flags, literal } = takeLiteral(argv);
13
- const { bundle, rest: withFlags } = takeBundle(flags);
13
+ const {
14
+ bundle,
15
+ explicit: bundleExplicit,
16
+ rest: withFlags
17
+ } = takeBundle(flags);
14
18
  const name = withFlags[0] ?? "";
15
19
  if (!name || name === "-h" || name === "--help") {
16
20
  process.stdout.write(usage());
@@ -31,7 +35,7 @@ async function runKbCli(argv) {
31
35
  ...json ? withFlags.filter((argument) => argument !== "--json") : withFlags,
32
36
  ...literal
33
37
  ];
34
- const raw = await command.fromArgv(rest, bundle, readStdin);
38
+ const raw = await command.fromArgv(rest, bundle, readStdin, bundleExplicit);
35
39
  const parsed = command.input.safeParse(raw);
36
40
  if (!parsed.success) {
37
41
  die(
@@ -53,6 +57,7 @@ async function runKbCli(argv) {
53
57
  if (command.failsWhen?.(result, parsed.data)) process.exitCode = 1;
54
58
  if (result === "") return;
55
59
  const text = command.render && !json ? command.render(result) : typeof result === "string" ? result : JSON.stringify(result, null, 2);
60
+ if (text === "") return;
56
61
  process.stdout.write(text.endsWith("\n") ? text : `${text}
57
62
  `);
58
63
  }
@@ -64,11 +69,15 @@ function takeLiteral(argv) {
64
69
  function takeBundle(argv) {
65
70
  const at = argv.indexOf("--bundle");
66
71
  if (at === -1) {
67
- return { bundle: join(process.cwd(), KB_DIR), rest: argv };
72
+ return { bundle: join(process.cwd(), KB_DIR), explicit: false, rest: argv };
68
73
  }
69
74
  const bundle = argv[at + 1];
70
75
  if (!bundle) die("--bundle requires a path");
71
- return { bundle, rest: [...argv.slice(0, at), ...argv.slice(at + 2)] };
76
+ return {
77
+ bundle,
78
+ explicit: true,
79
+ rest: [...argv.slice(0, at), ...argv.slice(at + 2)]
80
+ };
72
81
  }
73
82
  function readStdin() {
74
83
  return new Promise((resolve, reject) => {
@@ -112,4 +121,4 @@ function usage() {
112
121
  export {
113
122
  runKbCli
114
123
  };
115
- //# sourceMappingURL=chunk-MK7GU4DX.js.map
124
+ //# sourceMappingURL=chunk-RMJUGTAQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["/**\n * strauss-kb — a knowledge base's command line.\n *\n * A dispatcher over `KB_COMMANDS`, which the MCP server also projects. Nothing\n * command-specific lives here beyond turning argv into the object both\n * surfaces pass.\n */\nimport { join } from \"node:path\";\nimport { KB_COMMANDS, KB_COMMANDS_BY_NAME } from \"./commands/index.js\";\nimport { KB_DIR, KbStore } from \"./kb-store.js\";\nimport { VERSION } from \"./version.js\";\n\nexport async function runKbCli(argv: string[]): Promise<void> {\n const { flags, literal } = takeLiteral(argv);\n const {\n bundle,\n explicit: bundleExplicit,\n rest: withFlags,\n } = takeBundle(flags);\n const name = withFlags[0] ?? \"\";\n\n if (!name || name === \"-h\" || name === \"--help\") {\n process.stdout.write(usage());\n return;\n }\n\n // The plugin in front of this CLI updates from a marketplace while the CLI\n // updates from npm, and neither prompts for the other. Answering \"which one\n // is installed\" is what makes that skew diagnosable instead of mysterious.\n if (name === \"--version\" || name === \"-v\") {\n process.stdout.write(`${VERSION}\\n`);\n return;\n }\n\n const command = KB_COMMANDS_BY_NAME.get(name);\n if (!command) die(`unknown command ${name}`);\n\n // Output shape, not an argument: stripped before the command sees argv, so a\n // positional adapter never has to know the flag exists. Refused rather than\n // ignored where a command has only one form — a flag that silently does\n // nothing teaches a caller that it worked.\n const json = withFlags.includes(\"--json\");\n if (json && !command.render) {\n die(`${name} takes no --json: its result is already the machine shape`);\n }\n const rest = [\n ...(json\n ? withFlags.filter((argument) => argument !== \"--json\")\n : withFlags),\n ...literal,\n ];\n\n const raw = await command.fromArgv(rest, bundle, readStdin, bundleExplicit);\n const parsed = command.input.safeParse(raw);\n if (!parsed.success) {\n die(\n `${name}: ${parsed.error.issues\n .map((issue) => `${issue.path.join(\".\") || \"(root)\"}: ${issue.message}`)\n .join(\"; \")}`,\n );\n }\n\n const store = new KbStore({\n warn: (entry) => process.stderr.write(`${JSON.stringify(entry)}\\n`),\n });\n const result = await command.run(\n {\n store,\n actor: process.env.STRAUSS_KB_ACTOR ?? \"unknown\",\n now: () => new Date().toISOString(),\n },\n parsed.data,\n );\n\n // A check reporting a problem succeeded as a command and failed as a check;\n // the command says which, rather than the dispatcher knowing their names.\n if (command.failsWhen?.(result, parsed.data)) process.exitCode = 1;\n // An empty string is deliberate silence — `context` with nothing pinned\n // runs from hooks at every session start, and even a bare newline is noise\n // injected into a fresh context.\n if (result === \"\") return;\n const text =\n command.render && !json\n ? command.render(result)\n : typeof result === \"string\"\n ? result\n : JSON.stringify(result, null, 2);\n // A renderer may also have nothing to say — `stamp --since` when no base\n // moved is silence, and even a bare newline is noise in a hook's output.\n if (text === \"\") return;\n process.stdout.write(text.endsWith(\"\\n\") ? text : `${text}\\n`);\n}\n\n/**\n * Everything after a bare `--` is text, never flags.\n *\n * Several verbs end in free prose — `no-decision`, `answer`, `query` — and a\n * reason that happens to contain `--json` or `--bundle` would otherwise lose a\n * word to the flag scan, or two. The sentinel is the usual escape, and the\n * token itself is dropped while the order of everything else is kept, so the\n * positional adapters still index the same way.\n */\nfunction takeLiteral(argv: string[]): { flags: string[]; literal: string[] } {\n const at = argv.indexOf(\"--\");\n if (at === -1) return { flags: argv, literal: [] };\n return { flags: argv.slice(0, at), literal: argv.slice(at + 1) };\n}\n\n/**\n * `--bundle` addresses a base directly; without it the command works on the\n * one under the current directory. A base belongs to whatever prompted it, so\n * the default cannot be the only option.\n */\nfunction takeBundle(argv: string[]): {\n bundle: string;\n explicit: boolean;\n rest: string[];\n} {\n const at = argv.indexOf(\"--bundle\");\n if (at === -1) {\n return { bundle: join(process.cwd(), KB_DIR), explicit: false, rest: argv };\n }\n const bundle = argv[at + 1];\n if (!bundle) die(\"--bundle requires a path\");\n return {\n bundle,\n explicit: true,\n rest: [...argv.slice(0, at), ...argv.slice(at + 2)],\n };\n}\n\nfunction readStdin(): Promise<string> {\n return new Promise((resolve, reject) => {\n let text = \"\";\n process.stdin.setEncoding(\"utf8\");\n process.stdin.on(\"data\", (chunk) => (text += chunk));\n process.stdin.on(\"end\", () => resolve(text));\n process.stdin.on(\"error\", reject);\n });\n}\n\nfunction die(message: string): never {\n process.stderr.write(`strauss-kb: error: ${message}\\n`);\n process.exit(1);\n}\n\n/** First sentence, capped — the full text is what an MCP client shows. */\nfunction summarise(description: string): string {\n const first = description.split(\"\\n\")[0] ?? \"\";\n const sentence = first.includes(\". \")\n ? `${first.slice(0, first.indexOf(\". \"))}.`\n : first;\n return sentence.length > 78 ? `${sentence.slice(0, 75)}…` : sentence;\n}\n\nfunction usage(): string {\n const width = Math.max(...KB_COMMANDS.map((command) => command.usage.length));\n return [\n \"strauss-kb — knowledge base commands\",\n \"\",\n \"Usage: strauss-kb [--bundle PATH] <command> [args]\",\n \"\",\n ...KB_COMMANDS.map(\n (command) =>\n ` ${command.usage.padEnd(width)} ${summarise(command.description)}`,\n ),\n \"\",\n ` --bundle PATH defaults to ./${KB_DIR}`,\n \" --json the machine shape, where a command prints a table\",\n \" -- everything after it is text, not flags\",\n \" --version the installed package version\",\n \" STRAUSS_KB_ACTOR names the writer in the log\",\n \"\",\n ].join(\"\\n\");\n}\n"],"mappings":"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","names":[]}
@@ -2,7 +2,7 @@ import {
2
2
  KB_COMMANDS,
3
3
  KbStore,
4
4
  VERSION
5
- } from "./chunk-KNIUBCZY.js";
5
+ } from "./chunk-ZKIQOBHT.js";
6
6
 
7
7
  // src/mcp.ts
8
8
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -46,4 +46,4 @@ export {
46
46
  createKbMcpServer,
47
47
  runKbMcpServer
48
48
  };
49
- //# sourceMappingURL=chunk-LACCRB2Y.js.map
49
+ //# sourceMappingURL=chunk-SA3A2SPY.js.map