@spikedpunch/mast 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/MAST_SPEC.md +169 -44
  2. package/README.md +86 -11
  3. package/assets/skill.md +49 -10
  4. package/dist/ast/types.d.ts +137 -1
  5. package/dist/ast/types.d.ts.map +1 -1
  6. package/dist/cli/query.d.ts +40 -1
  7. package/dist/cli/query.d.ts.map +1 -1
  8. package/dist/cli/query.js +36 -2
  9. package/dist/cli/query.js.map +1 -1
  10. package/dist/cli/search-cmd.d.ts +6 -1
  11. package/dist/cli/search-cmd.d.ts.map +1 -1
  12. package/dist/cli/search-cmd.js +9 -2
  13. package/dist/cli/search-cmd.js.map +1 -1
  14. package/dist/cli/serve.d.ts +6 -1
  15. package/dist/cli/serve.d.ts.map +1 -1
  16. package/dist/cli/serve.js +14 -4
  17. package/dist/cli/serve.js.map +1 -1
  18. package/dist/cli/status.d.ts +15 -0
  19. package/dist/cli/status.d.ts.map +1 -1
  20. package/dist/cli/status.js +32 -6
  21. package/dist/cli/status.js.map +1 -1
  22. package/dist/indexer/freshness.d.ts +10 -0
  23. package/dist/indexer/freshness.d.ts.map +1 -1
  24. package/dist/indexer/freshness.js +7 -1
  25. package/dist/indexer/freshness.js.map +1 -1
  26. package/dist/indexer/import-resolver.js +28 -16
  27. package/dist/indexer/import-resolver.js.map +1 -1
  28. package/dist/indexer/index.d.ts +38 -3
  29. package/dist/indexer/index.d.ts.map +1 -1
  30. package/dist/indexer/index.js +47 -4
  31. package/dist/indexer/index.js.map +1 -1
  32. package/dist/indexer/watcher.d.ts +16 -0
  33. package/dist/indexer/watcher.d.ts.map +1 -1
  34. package/dist/indexer/watcher.js +8 -0
  35. package/dist/indexer/watcher.js.map +1 -1
  36. package/dist/mcp/context.d.ts +16 -0
  37. package/dist/mcp/context.d.ts.map +1 -1
  38. package/dist/mcp/freshness-probe.d.ts +82 -0
  39. package/dist/mcp/freshness-probe.d.ts.map +1 -0
  40. package/dist/mcp/freshness-probe.js +111 -0
  41. package/dist/mcp/freshness-probe.js.map +1 -0
  42. package/dist/mcp/server.d.ts +46 -3
  43. package/dist/mcp/server.d.ts.map +1 -1
  44. package/dist/mcp/server.js +65 -3
  45. package/dist/mcp/server.js.map +1 -1
  46. package/dist/mcp/tools/_helpers.d.ts +40 -0
  47. package/dist/mcp/tools/_helpers.d.ts.map +1 -1
  48. package/dist/mcp/tools/_helpers.js +27 -0
  49. package/dist/mcp/tools/_helpers.js.map +1 -1
  50. package/dist/mcp/tools/callers.d.ts.map +1 -1
  51. package/dist/mcp/tools/callers.js +6 -1
  52. package/dist/mcp/tools/callers.js.map +1 -1
  53. package/dist/mcp/tools/dependencies.d.ts.map +1 -1
  54. package/dist/mcp/tools/dependencies.js +2 -1
  55. package/dist/mcp/tools/dependencies.js.map +1 -1
  56. package/dist/mcp/tools/exports.d.ts.map +1 -1
  57. package/dist/mcp/tools/exports.js +2 -1
  58. package/dist/mcp/tools/exports.js.map +1 -1
  59. package/dist/mcp/tools/implementors.d.ts.map +1 -1
  60. package/dist/mcp/tools/implementors.js +2 -1
  61. package/dist/mcp/tools/implementors.js.map +1 -1
  62. package/dist/mcp/tools/project-skeleton.d.ts.map +1 -1
  63. package/dist/mcp/tools/project-skeleton.js +2 -1
  64. package/dist/mcp/tools/project-skeleton.js.map +1 -1
  65. package/dist/mcp/tools/reindex.d.ts.map +1 -1
  66. package/dist/mcp/tools/reindex.js +3 -0
  67. package/dist/mcp/tools/reindex.js.map +1 -1
  68. package/dist/mcp/tools/rename-impact.d.ts.map +1 -1
  69. package/dist/mcp/tools/rename-impact.js +4 -1
  70. package/dist/mcp/tools/rename-impact.js.map +1 -1
  71. package/dist/mcp/tools/search.d.ts.map +1 -1
  72. package/dist/mcp/tools/search.js +13 -2
  73. package/dist/mcp/tools/search.js.map +1 -1
  74. package/dist/mcp/tools/signature.d.ts.map +1 -1
  75. package/dist/mcp/tools/signature.js +2 -1
  76. package/dist/mcp/tools/signature.js.map +1 -1
  77. package/dist/mcp/tools/status.d.ts.map +1 -1
  78. package/dist/mcp/tools/status.js +8 -2
  79. package/dist/mcp/tools/status.js.map +1 -1
  80. package/package.json +4 -2
@@ -1,6 +1,7 @@
1
1
  import type { Db } from '../graph/db.js';
2
2
  import type { ChunkStore } from '../store/sqliteChunkStore.js';
3
3
  import type { ResolvedConfig } from '../store/config.js';
4
+ import type { FreshnessProbe } from './freshness-probe.js';
4
5
  /**
5
6
  * Shared state injected into every MCP tool handler at registration time.
6
7
  *
@@ -19,5 +20,20 @@ export interface AppContext {
19
20
  readonly config: ResolvedConfig;
20
21
  /** Stable identifier for this MCP server session (used in metrics). */
21
22
  readonly sessionId: string;
23
+ /**
24
+ * Cached "is the index missing files?" signal, read by `mast_search` to warn
25
+ * that a result set may be incomplete.
26
+ *
27
+ * Optional, and absent is a real configuration rather than an oversight: the
28
+ * probe amortises one project walk across a TTL, which only pays off in a
29
+ * long-lived process. `mast serve` wires one (mcp/server.ts); the one-shot
30
+ * CLI query path (cli/query.ts) deliberately does not, because a single
31
+ * search there would pay the whole walk to answer a question it can answer
32
+ * outright with `mast search --reindex`.
33
+ *
34
+ * Absent, or reporting `null`, means *unknown* — surfaces render that as
35
+ * silence, never as zero.
36
+ */
37
+ readonly freshness?: FreshnessProbe;
22
38
  }
23
39
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/mcp/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAMzD;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;IAChB;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,uEAAuE;IACvE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/mcp/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAM3D;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;IAChB;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,uEAAuE;IACvE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAC;CACrC"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * A cached, non-blocking answer to "is the index missing files?".
3
+ *
4
+ * `mast_search` needs this to warn a caller that a zero-hit result may mean
5
+ * "not indexed" rather than "not present" — the severity-zero failure this
6
+ * package is built around. What it cannot do is pay for it *at scale*, and the
7
+ * cost is worth stating with its corpus attached, because it inverts:
8
+ *
9
+ * - This repository, 213 files walked (medians, measured 2026-09-03):
10
+ * `fusedSearch` 15.3 ms, `measureFreshness` 7.6 ms. The walk is CHEAPER
11
+ * than the search. On a tree this size the probe buys nothing.
12
+ * - A 14k-file monorepo: `measureFreshness` ~183 ms (measured 2026-09-02).
13
+ *
14
+ * That is the whole argument, and it is about scaling, not about a ratio.
15
+ * `measureFreshness` is O(files in the tree) and a search is O(matches), so the
16
+ * walk overtakes the query as the tree grows and then keeps going. The probe
17
+ * exists for the trees where that has already happened.
18
+ *
19
+ * So the probe inverts it. `peekUnindexed` returns the last-known count
20
+ * synchronously and schedules a refresh behind the caller when the value has
21
+ * aged past the TTL. The first search of a session gets `null` — unknown, no
22
+ * warning — and every later one gets an answer that is at most `ttlMs` old.
23
+ * `server.ts` primes it at startup so that window is usually already closed.
24
+ *
25
+ * The cost is amortised, NOT eliminated, and it is worth being exact about
26
+ * which: `measureFreshness` -> `walkProject` globs asynchronously but then
27
+ * `statSync`s every hit in a synchronous loop, so a refresh occupies the event
28
+ * loop for part of its duration. A search that lands mid-refresh can be
29
+ * delayed by that much. One such window per `ttlMs`, rather than one walk per
30
+ * search, is the whole of the improvement — do not read "background" as
31
+ * "free".
32
+ *
33
+ * Deliberately NOT a reindex: no `structure.lock` is taken and nothing is
34
+ * written, so the probe cannot contend with a concurrent `runIndex` or with
35
+ * another reader (E7 measured 35-88.5% JIT failure under reader-vs-reader
36
+ * contention). It reads, it counts, it reports.
37
+ */
38
+ import type { Db } from '../graph/db.js';
39
+ import type { ResolvedConfig } from '../store/config.js';
40
+ import { type IndexFreshness } from '../indexer/freshness.js';
41
+ /** How long a measurement stays authoritative before the next peek refreshes it. */
42
+ export declare const DEFAULT_FRESHNESS_TTL_MS = 30000;
43
+ export interface FreshnessProbe {
44
+ /**
45
+ * Files on disk that the index has never seen, as of the last completed
46
+ * measurement — or `null` when none has completed yet.
47
+ *
48
+ * Never blocks, never throws, never awaits. May schedule a background
49
+ * refresh as a side effect. `null` means *unknown*, which callers must
50
+ * render as silence rather than as zero.
51
+ */
52
+ peekUnindexed(): number | null;
53
+ /**
54
+ * Discard the cached value and re-measure on the next peek.
55
+ *
56
+ * Called after this process reindexes: the previous count is not merely old,
57
+ * it is wrong in the direction that produces a false warning about files
58
+ * that were just indexed. A measurement already in flight is *superseded* —
59
+ * it is allowed to finish, and its result is discarded rather than cached,
60
+ * because it was reading the pre-reindex tree.
61
+ */
62
+ invalidate(): void;
63
+ /** Start a measurement now if none is in flight. Used to prime at startup. */
64
+ refresh(): void;
65
+ /**
66
+ * Resolves when the in-flight measurement settles — success or failure.
67
+ *
68
+ * Settling is not the same as caching a value: a measurement superseded by
69
+ * `invalidate()` settles with its result discarded, leaving `peekUnindexed`
70
+ * at `null` until the next peek starts a clean one.
71
+ */
72
+ settled(): Promise<void>;
73
+ }
74
+ export interface FreshnessProbeOptions {
75
+ readonly ttlMs?: number;
76
+ /** Injected for tests (§4.4); production reads the real clock. */
77
+ readonly now?: () => number;
78
+ /** Injected for tests (§4.4); production walks the project. */
79
+ readonly measure?: (config: ResolvedConfig, db: Db) => Promise<IndexFreshness>;
80
+ }
81
+ export declare function createFreshnessProbe(config: ResolvedConfig, db: Db, options?: FreshnessProbeOptions): FreshnessProbe;
82
+ //# sourceMappingURL=freshness-probe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freshness-probe.d.ts","sourceRoot":"","sources":["../../src/mcp/freshness-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEhF,oFAAoF;AACpF,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC7B;;;;;;;OAOG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI,CAAC;IAE/B;;;;;;;;OAQG;IACH,UAAU,IAAI,IAAI,CAAC;IAEnB,8EAA8E;IAC9E,OAAO,IAAI,IAAI,CAAC;IAEhB;;;;;;OAMG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,kEAAkE;IAClE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CAChF;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,EACtB,EAAE,EAAE,EAAE,EACN,OAAO,GAAE,qBAA0B,GAClC,cAAc,CAuEhB"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * A cached, non-blocking answer to "is the index missing files?".
3
+ *
4
+ * `mast_search` needs this to warn a caller that a zero-hit result may mean
5
+ * "not indexed" rather than "not present" — the severity-zero failure this
6
+ * package is built around. What it cannot do is pay for it *at scale*, and the
7
+ * cost is worth stating with its corpus attached, because it inverts:
8
+ *
9
+ * - This repository, 213 files walked (medians, measured 2026-09-03):
10
+ * `fusedSearch` 15.3 ms, `measureFreshness` 7.6 ms. The walk is CHEAPER
11
+ * than the search. On a tree this size the probe buys nothing.
12
+ * - A 14k-file monorepo: `measureFreshness` ~183 ms (measured 2026-09-02).
13
+ *
14
+ * That is the whole argument, and it is about scaling, not about a ratio.
15
+ * `measureFreshness` is O(files in the tree) and a search is O(matches), so the
16
+ * walk overtakes the query as the tree grows and then keeps going. The probe
17
+ * exists for the trees where that has already happened.
18
+ *
19
+ * So the probe inverts it. `peekUnindexed` returns the last-known count
20
+ * synchronously and schedules a refresh behind the caller when the value has
21
+ * aged past the TTL. The first search of a session gets `null` — unknown, no
22
+ * warning — and every later one gets an answer that is at most `ttlMs` old.
23
+ * `server.ts` primes it at startup so that window is usually already closed.
24
+ *
25
+ * The cost is amortised, NOT eliminated, and it is worth being exact about
26
+ * which: `measureFreshness` -> `walkProject` globs asynchronously but then
27
+ * `statSync`s every hit in a synchronous loop, so a refresh occupies the event
28
+ * loop for part of its duration. A search that lands mid-refresh can be
29
+ * delayed by that much. One such window per `ttlMs`, rather than one walk per
30
+ * search, is the whole of the improvement — do not read "background" as
31
+ * "free".
32
+ *
33
+ * Deliberately NOT a reindex: no `structure.lock` is taken and nothing is
34
+ * written, so the probe cannot contend with a concurrent `runIndex` or with
35
+ * another reader (E7 measured 35-88.5% JIT failure under reader-vs-reader
36
+ * contention). It reads, it counts, it reports.
37
+ */
38
+ import { measureFreshness } from '../indexer/freshness.js';
39
+ /** How long a measurement stays authoritative before the next peek refreshes it. */
40
+ export const DEFAULT_FRESHNESS_TTL_MS = 30_000;
41
+ export function createFreshnessProbe(config, db, options = {}) {
42
+ const ttlMs = options.ttlMs ?? DEFAULT_FRESHNESS_TTL_MS;
43
+ const now = options.now ?? Date.now;
44
+ const measure = options.measure ?? measureFreshness;
45
+ let unindexed = null;
46
+ /** `null` = never measured or invalidated; otherwise the clock at settlement. */
47
+ let settledAt = null;
48
+ let inFlight = null;
49
+ /**
50
+ * Bumped by `invalidate()`. A measurement that started under an older
51
+ * generation was reading a tree this process has since reindexed, so its
52
+ * count is not merely old — it is wrong in the exact direction that warns
53
+ * about files that now ARE indexed. Gating on the generation is what makes
54
+ * `invalidate()` mean "discard", rather than "discard unless a walk happens
55
+ * to be in flight, in which case adopt its stale answer and stamp it fresh
56
+ * for a full TTL".
57
+ */
58
+ let generation = 0;
59
+ function refresh() {
60
+ // Still coalesced across generations: a superseded walk is left to finish
61
+ // and its result dropped, rather than disowned and replaced immediately.
62
+ // Disowning would let one walk per `invalidate()` run concurrently, and
63
+ // `measureFreshness` holds the event loop in a synchronous `statSync` loop
64
+ // (see the header) — under a watch-driven edit loop that is worse than the
65
+ // laziness. The cache is left `null` (unknown -> silence, never a wrong
66
+ // warning) and the next peek starts a clean measurement.
67
+ if (inFlight !== null)
68
+ return;
69
+ const startedAt = generation;
70
+ inFlight = measure(config, db)
71
+ .then((result) => {
72
+ if (startedAt !== generation)
73
+ return;
74
+ unindexed = result.unindexed;
75
+ })
76
+ .catch(() => {
77
+ // Swallowed by contract: a failed walk (a directory removed mid-walk, a
78
+ // permission error) must not reject into a search handler or replace a
79
+ // good answer with a wrong one. The last value stands and the stamp
80
+ // below backs the retry off by a full TTL rather than re-walking on
81
+ // every peek.
82
+ })
83
+ .finally(() => {
84
+ inFlight = null;
85
+ // A superseded walk must NOT stamp the cache fresh. Leaving `settledAt`
86
+ // null keeps the value expired, so the next peek re-measures instead of
87
+ // serving `null` for a full TTL.
88
+ if (startedAt !== generation)
89
+ return;
90
+ settledAt = now();
91
+ });
92
+ }
93
+ return {
94
+ peekUnindexed() {
95
+ const isExpired = settledAt === null || now() - settledAt >= ttlMs;
96
+ if (isExpired)
97
+ refresh();
98
+ return unindexed;
99
+ },
100
+ invalidate() {
101
+ unindexed = null;
102
+ settledAt = null;
103
+ generation += 1;
104
+ },
105
+ refresh,
106
+ async settled() {
107
+ await inFlight;
108
+ },
109
+ };
110
+ }
111
+ //# sourceMappingURL=freshness-probe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freshness-probe.js","sourceRoot":"","sources":["../../src/mcp/freshness-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAIH,OAAO,EAAE,gBAAgB,EAAuB,MAAM,yBAAyB,CAAC;AAEhF,oFAAoF;AACpF,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC;AA6C/C,MAAM,UAAU,oBAAoB,CAClC,MAAsB,EACtB,EAAM,EACN,UAAiC,EAAE;IAEnC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,wBAAwB,CAAC;IACxD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,gBAAgB,CAAC;IAEpD,IAAI,SAAS,GAAkB,IAAI,CAAC;IACpC,iFAAiF;IACjF,IAAI,SAAS,GAAkB,IAAI,CAAC;IACpC,IAAI,QAAQ,GAAyB,IAAI,CAAC;IAC1C;;;;;;;;OAQG;IACH,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,SAAS,OAAO;QACd,0EAA0E;QAC1E,yEAAyE;QACzE,wEAAwE;QACxE,2EAA2E;QAC3E,2EAA2E;QAC3E,wEAAwE;QACxE,yDAAyD;QACzD,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO;QAC9B,MAAM,SAAS,GAAG,UAAU,CAAC;QAC7B,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;aAC3B,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;YACf,IAAI,SAAS,KAAK,UAAU;gBAAE,OAAO;YACrC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAC/B,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE;YACV,wEAAwE;YACxE,uEAAuE;YACvE,oEAAoE;YACpE,oEAAoE;YACpE,cAAc;QAChB,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,QAAQ,GAAG,IAAI,CAAC;YAChB,wEAAwE;YACxE,wEAAwE;YACxE,iCAAiC;YACjC,IAAI,SAAS,KAAK,UAAU;gBAAE,OAAO;YACrC,SAAS,GAAG,GAAG,EAAE,CAAC;QACpB,CAAC,CAAC,CAAC;IACP,CAAC;IAED,OAAO;QACL,aAAa;YACX,MAAM,SAAS,GAAG,SAAS,KAAK,IAAI,IAAI,GAAG,EAAE,GAAG,SAAS,IAAI,KAAK,CAAC;YACnE,IAAI,SAAS;gBAAE,OAAO,EAAE,CAAC;YACzB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,UAAU;YACR,SAAS,GAAG,IAAI,CAAC;YACjB,SAAS,GAAG,IAAI,CAAC;YACjB,UAAU,IAAI,CAAC,CAAC;QAClB,CAAC;QAED,OAAO;QAEP,KAAK,CAAC,OAAO;YACX,MAAM,QAAQ,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import type { ResolvedConfig } from '../store/config.js';
2
+ import { type FreshnessProbe } from './freshness-probe.js';
2
3
  /**
3
4
  * Thrown by {@link assertServableIndex} when `mast serve --no-startup-reindex`
4
5
  * targets a state directory that has never completed an index run. Extends
@@ -33,14 +34,56 @@ export declare class NeverIndexedError extends Error {
33
34
  export declare function assertServableIndex(config: ResolvedConfig, options: {
34
35
  readonly noStartupReindex?: boolean;
35
36
  }): void;
37
+ /**
38
+ * Run an incremental/full index pass and then correct the cached freshness
39
+ * count, which that pass has just made wrong.
40
+ *
41
+ * Extracted from `serve` because the ordering here is the whole contract and it
42
+ * was previously expressed three times in three closures, one of which got it
43
+ * wrong (D060): the invalidate must be in a `finally`. A reindex that FAILS is
44
+ * the case where the cached count is most likely to be stale and most costly to
45
+ * keep — the watcher only fired because files on disk changed, and `runIndex`
46
+ * losing `structure.lock` to a concurrent writer is an ordinary outcome, not an
47
+ * exceptional one. Invalidating only on success leaves `mast_search` reporting
48
+ * a pre-change count as authoritative for a full TTL, and after
49
+ * `maxConsecutiveFailures` the watcher drops the batch, so nothing retries.
50
+ *
51
+ * Errors propagate deliberately. `WatchScheduler` needs the rejection to
52
+ * requeue the batch, and the startup path wants to warn on its own terms; a
53
+ * function that both corrects the cache and swallows the failure would give
54
+ * neither caller what it needs.
55
+ *
56
+ * @param prime `true` measures immediately (startup, so the first search of the
57
+ * session has a real answer instead of `null`); `false` leaves the next
58
+ * `peekUnindexed` to schedule it, which is right for a watch batch that may
59
+ * be one of many in a burst.
60
+ */
61
+ export declare function reindexAndRemeasure(config: ResolvedConfig, freshness: FreshnessProbe, options: {
62
+ readonly incremental: boolean;
63
+ readonly prime?: boolean;
64
+ /** §4.4 DI seam: tests drive the failure path without standing up a writer. */
65
+ readonly runIndexFn?: (config: ResolvedConfig, opts: {
66
+ incremental: boolean;
67
+ }) => Promise<unknown>;
68
+ }): Promise<void>;
36
69
  export interface ServeOptions {
37
70
  readonly config: ResolvedConfig;
38
71
  /** Skip the startup incremental reindex (not recommended). */
39
72
  readonly noStartupReindex?: boolean;
40
73
  /**
41
- * Watch source files and incrementally reindex on change (§11.4). Opt-in,
42
- * for interactive (non-container) use — the SDD container relies on the
43
- * startup ladder instead.
74
+ * Watch source files and incrementally reindex on change (§11.4).
75
+ *
76
+ * **Defaults to on** (`undefined` means watch). It was opt-in until
77
+ * 2026-09-03, on the theory that the startup ladder plus JIT staleness kept
78
+ * reads correct. Measurement said otherwise: JIT only re-parses files the
79
+ * index already knows, so a file CREATED during a session is invisible to
80
+ * every read tool until something reindexes — and nothing does. A watcher is
81
+ * the only mechanism here that closes that window without a per-query cost.
82
+ * Watcher construction failures degrade to serving without it, so the
83
+ * default cannot make the server fail to start.
84
+ *
85
+ * Set `false` (CLI `--no-watch`) for container or batch use, where the tree
86
+ * does not change under the server and the fd cost is not worth paying.
44
87
  */
45
88
  readonly watch?: boolean;
46
89
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAczD;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;CAAG;AAiC/C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE;IAAE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/C,IAAI,CASN;AAMD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,wBAAsB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA2FhE"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAOzD,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAQjF;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;CAAG;AAiC/C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE;IAAE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/C,IAAI,CASN;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE;IACP,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE;QAAE,WAAW,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACpG,GACA,OAAO,CAAC,IAAI,CAAC,CAQf;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,wBAAsB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAmHhE"}
@@ -8,6 +8,7 @@ import { SqliteChunkStore } from '../store/sqliteChunkStore.js';
8
8
  import { runIndex, loadIndexMeta } from '../indexer/index.js';
9
9
  import { startWatchMode } from '../indexer/watcher.js';
10
10
  import { bootstrapState } from './startup.js';
11
+ import { createFreshnessProbe } from './freshness-probe.js';
11
12
  import { registerAllTools } from './register-tools.js';
12
13
  // ---------------------------------------------------------------------------
13
14
  // M6 Part A (eval/GITNEXUS_COMPARISON.md §13.8 item 4): refuse to serve only
@@ -85,6 +86,44 @@ export function assertServableIndex(config, options) {
85
86
  'query would return {"results":[]} forever, indistinguishable from "symbol doesn\'t exist". ' +
86
87
  'Run `mast init` or `mast index` against this state directory first, or drop --no-startup-reindex.');
87
88
  }
89
+ // ---------------------------------------------------------------------------
90
+ // Startup ladder (§7.4)
91
+ // ---------------------------------------------------------------------------
92
+ /**
93
+ * Run an incremental/full index pass and then correct the cached freshness
94
+ * count, which that pass has just made wrong.
95
+ *
96
+ * Extracted from `serve` because the ordering here is the whole contract and it
97
+ * was previously expressed three times in three closures, one of which got it
98
+ * wrong (D060): the invalidate must be in a `finally`. A reindex that FAILS is
99
+ * the case where the cached count is most likely to be stale and most costly to
100
+ * keep — the watcher only fired because files on disk changed, and `runIndex`
101
+ * losing `structure.lock` to a concurrent writer is an ordinary outcome, not an
102
+ * exceptional one. Invalidating only on success leaves `mast_search` reporting
103
+ * a pre-change count as authoritative for a full TTL, and after
104
+ * `maxConsecutiveFailures` the watcher drops the batch, so nothing retries.
105
+ *
106
+ * Errors propagate deliberately. `WatchScheduler` needs the rejection to
107
+ * requeue the batch, and the startup path wants to warn on its own terms; a
108
+ * function that both corrects the cache and swallows the failure would give
109
+ * neither caller what it needs.
110
+ *
111
+ * @param prime `true` measures immediately (startup, so the first search of the
112
+ * session has a real answer instead of `null`); `false` leaves the next
113
+ * `peekUnindexed` to schedule it, which is right for a watch batch that may
114
+ * be one of many in a burst.
115
+ */
116
+ export async function reindexAndRemeasure(config, freshness, options) {
117
+ const run = options.runIndexFn ?? runIndex;
118
+ try {
119
+ await run(config, { incremental: options.incremental });
120
+ }
121
+ finally {
122
+ freshness.invalidate();
123
+ if (options.prime === true)
124
+ freshness.refresh();
125
+ }
126
+ }
88
127
  /**
89
128
  * Run the MAST MCP server.
90
129
  *
@@ -112,11 +151,17 @@ export async function serve(options) {
112
151
  // tool below already uses.
113
152
  const chunkStore = new SqliteChunkStore(db);
114
153
  // ── Step 3: open MCP transport and register tools ─────────────────────────
154
+ // Freshness signal for `mast_search`'s `unindexed_files` warning. Created
155
+ // before the tools are registered because handlers capture `ctx` at
156
+ // registration; primed below so the first search of a session already has a
157
+ // real answer rather than `null`.
158
+ const freshness = createFreshnessProbe(config, db);
115
159
  const ctx = {
116
160
  db,
117
161
  chunkStore,
118
162
  config,
119
163
  sessionId: randomUUID(),
164
+ freshness,
120
165
  };
121
166
  const server = new McpServer({ name: 'mast', version: '0.1.0' });
122
167
  registerAllTools(server, ctx);
@@ -128,7 +173,7 @@ export async function serve(options) {
128
173
  // mast_reindex). JIT staleness handling (§9.0) already guarantees read
129
174
  // correctness; watch mode only keeps the FTS/graph index fresh between reads.
130
175
  const startWatchIfRequested = () => {
131
- if (options.watch !== true)
176
+ if (options.watch === false)
132
177
  return;
133
178
  let watchHandle = null;
134
179
  try {
@@ -136,9 +181,19 @@ export async function serve(options) {
136
181
  config,
137
182
  runBatch: async (paths) => {
138
183
  process.stderr.write(`[mast] watch: reindexing after ${paths.length} change(s)\n`);
139
- await runIndex(config, { incremental: true });
184
+ // Not primed: a burst of saves produces a burst of batches, and the
185
+ // next `peekUnindexed` will schedule one measurement for all of them.
186
+ await reindexAndRemeasure(config, freshness, { incremental: true });
140
187
  },
141
188
  onWarn: (message) => process.stderr.write(`${message}\n`),
189
+ // The success path now announces itself, because the failure path
190
+ // always did: `startWatchMode`'s EMFILE degradation writes a warning,
191
+ // so before this line silence meant "watching", "not watching yet" and
192
+ // "watcher failed to start" alike, and an operator could not tell which
193
+ // (D061). Emitted once, after chokidar's initial scan — files created
194
+ // before it are treated as pre-existing and fire no event, so this is
195
+ // the point from which a change is guaranteed to be seen.
196
+ onReady: () => process.stderr.write('[mast] watch: watching for changes\n'),
142
197
  });
143
198
  }
144
199
  catch (err) {
@@ -161,12 +216,19 @@ export async function serve(options) {
161
216
  };
162
217
  // ── Step 4: background reindex ────────────────────────────────────────────
163
218
  if (options.noStartupReindex) {
219
+ // No reindex is coming, so measure the drift the user has chosen to keep.
220
+ freshness.refresh();
164
221
  startWatchIfRequested();
165
222
  return;
166
223
  }
167
224
  void (async () => {
168
225
  try {
169
- await runIndex(config, { incremental: !needsFullReindex });
226
+ // Measured AFTER the reindex, in the same background task: a probe run
227
+ // before it would race the indexer and cache a count that the very next
228
+ // moment invalidates. On the failure path the correction is the more
229
+ // important half — the index is behind and nothing else will say so —
230
+ // which is why it lives in `reindexAndRemeasure`'s `finally`.
231
+ await reindexAndRemeasure(config, freshness, { incremental: !needsFullReindex, prime: true });
170
232
  }
171
233
  catch (err) {
172
234
  process.stderr.write(`[mast] startup indexing failed: ${String(err)}\n`);
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,46 @@ export { collectPotentialMatches, collectPotentialMatchCandidates, type ChunkByI
16
16
  * pays nothing extra per call.
17
17
  */
18
18
  export declare function isIndexEmpty(ctx: AppContext): Promise<boolean>;
19
+ /**
20
+ * How exhaustive a tool's answer claims to be. This is what decides whether a
21
+ * partial index is worth mentioning alongside a *non-empty* result, and the two
22
+ * cases are genuinely different claims rather than a style choice.
23
+ *
24
+ * - `exhaustive-set` — the answer is "these are the ones there are"
25
+ * (`mast_callers`, `mast_rename_impact`, `mast_implementors`, `mast_search`,
26
+ * `mast_project_skeleton`). A **non-empty** answer is the dangerous one here:
27
+ * "3 verified callers" computed over a corpus missing forty files is what
28
+ * drives a delete, and it reads exactly like a complete answer.
29
+ * - `named-lookup` — the answer is about one thing the caller named
30
+ * (`mast_signature`, `mast_exports`, `mast_dependencies`). If it was found,
31
+ * the answer is correct however much else is unindexed; only *not finding* it
32
+ * is ambiguous between "absent" and "never indexed".
33
+ */
34
+ export type CompletenessClaim = 'exhaustive-set' | 'named-lookup';
35
+ /**
36
+ * The partial-index warning (D054), for every tool that returns a primary
37
+ * result set — not just `mast_search`, which had it first only because that is
38
+ * where it was written.
39
+ *
40
+ * The severity zero: a caller reads an empty or thin answer, concludes "it
41
+ * isn't there", and edits or deletes code that is in fact referenced from a
42
+ * file the index never saw. `index_empty` covers the all-or-nothing case; this
43
+ * covers the far commoner partial one, where the index is populated and merely
44
+ * behind.
45
+ *
46
+ * Free to call. `peekUnindexed` reads a TTL-cached count synchronously and
47
+ * never awaits a walk (see `mcp/freshness-probe.ts`), so unlike `isIndexEmpty`
48
+ * this costs nothing on a populated response and needs no empty-path guard for
49
+ * performance — only for meaning.
50
+ *
51
+ * `null` from the probe means *no measurement has landed yet*, which is
52
+ * unknown, not zero. Both render as an omitted field, but they are kept
53
+ * distinct here because the next reader to add a branch would otherwise inherit
54
+ * "unknown means clean" — the exact conflation this signal exists to prevent.
55
+ */
56
+ export declare function unindexedFilesField(ctx: AppContext, claim: CompletenessClaim, isEmpty: boolean): {
57
+ readonly unindexed_files?: number;
58
+ };
19
59
  /** Extract the first JSDoc comment block from chunk content, if present. */
20
60
  export declare function extractDoc(content: string): string | null;
21
61
  export { globToRegex } from '../../indexer/walker.js';
@@ -1 +1 @@
1
- {"version":3,"file":"_helpers.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAA0B,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEpF,sGAAsG;AACtG,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AASzE,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,8BAA8B,EACnC,KAAK,sBAAsB,GAC5B,MAAM,mCAAmC,CAAC;AAM3C;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAEpE;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGzD;AAID,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,EAAE,EACN,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC,CAQ/B"}
1
+ {"version":3,"file":"_helpers.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAA0B,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEpF,sGAAsG;AACtG,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AASzE,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,8BAA8B,EACnC,KAAK,sBAAsB,GAC5B,MAAM,mCAAmC,CAAC;AAM3C;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAEpE;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,GAAG,cAAc,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,OAAO,GACf;IAAE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CAIvC;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGzD;AAID,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,EAAE,EACN,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC,CAQ/B"}
@@ -25,6 +25,33 @@ export { collectPotentialMatches, collectPotentialMatchCandidates, } from '../..
25
25
  export async function isIndexEmpty(ctx) {
26
26
  return (await ctx.chunkStore.chunkCount()) === 0;
27
27
  }
28
+ /**
29
+ * The partial-index warning (D054), for every tool that returns a primary
30
+ * result set — not just `mast_search`, which had it first only because that is
31
+ * where it was written.
32
+ *
33
+ * The severity zero: a caller reads an empty or thin answer, concludes "it
34
+ * isn't there", and edits or deletes code that is in fact referenced from a
35
+ * file the index never saw. `index_empty` covers the all-or-nothing case; this
36
+ * covers the far commoner partial one, where the index is populated and merely
37
+ * behind.
38
+ *
39
+ * Free to call. `peekUnindexed` reads a TTL-cached count synchronously and
40
+ * never awaits a walk (see `mcp/freshness-probe.ts`), so unlike `isIndexEmpty`
41
+ * this costs nothing on a populated response and needs no empty-path guard for
42
+ * performance — only for meaning.
43
+ *
44
+ * `null` from the probe means *no measurement has landed yet*, which is
45
+ * unknown, not zero. Both render as an omitted field, but they are kept
46
+ * distinct here because the next reader to add a branch would otherwise inherit
47
+ * "unknown means clean" — the exact conflation this signal exists to prevent.
48
+ */
49
+ export function unindexedFilesField(ctx, claim, isEmpty) {
50
+ if (claim === 'named-lookup' && !isEmpty)
51
+ return {};
52
+ const unindexed = ctx.freshness?.peekUnindexed() ?? null;
53
+ return unindexed !== null && unindexed > 0 ? { unindexed_files: unindexed } : {};
54
+ }
28
55
  /** Extract the first JSDoc comment block from chunk content, if present. */
29
56
  export function extractDoc(content) {
30
57
  const match = /\/\*\*([\s\S]*?)\*\//.exec(content);
@@ -1 +1 @@
1
- {"version":3,"file":"_helpers.js","sourceRoot":"","sources":["../../../src/mcp/tools/_helpers.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAA6B,MAAM,iBAAiB,CAAC;AAEpF,sGAAsG;AACtG,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE,mEAAmE;AACnE,6EAA6E;AAC7E,yEAAyE;AACzE,oEAAoE;AACpE,sEAAsE;AACtE,4EAA4E;AAC5E,yDAAyD;AACzD,OAAO,EACL,uBAAuB,EACvB,+BAA+B,GAKhC,MAAM,mCAAmC,CAAC;AAE3C,8EAA8E;AAC9E,4EAA4E;AAC5E,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAe;IAChD,OAAO,CAAC,MAAM,GAAG,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC;AACnD,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnD,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC;AAED,+EAA+E;AAC/E,kFAAkF;AAClF,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,EAAM,EACN,MAAsB,EACtB,QAAgB;IAEhB,MAAM,GAAG,GAAG,MAAM,EAAE;SACjB,UAAU,CAAC,OAAO,CAAC;SACnB,MAAM,CAAC,OAAO,CAAC;SACf,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC;SAC5B,gBAAgB,EAAE,CAAC;IACtB,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAChE,OAAO,sBAAsB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;AACjE,CAAC;AAED,8EAA8E;AAC9E,uEAAuE;AACvE,6EAA6E;AAC7E,yEAAyE;AACzE,uDAAuD"}
1
+ {"version":3,"file":"_helpers.js","sourceRoot":"","sources":["../../../src/mcp/tools/_helpers.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAA6B,MAAM,iBAAiB,CAAC;AAEpF,sGAAsG;AACtG,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE,mEAAmE;AACnE,6EAA6E;AAC7E,yEAAyE;AACzE,oEAAoE;AACpE,sEAAsE;AACtE,4EAA4E;AAC5E,yDAAyD;AACzD,OAAO,EACL,uBAAuB,EACvB,+BAA+B,GAKhC,MAAM,mCAAmC,CAAC;AAE3C,8EAA8E;AAC9E,4EAA4E;AAC5E,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAe;IAChD,OAAO,CAAC,MAAM,GAAG,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC;AACnD,CAAC;AAmBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAe,EACf,KAAwB,EACxB,OAAgB;IAEhB,IAAI,KAAK,KAAK,cAAc,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACpD,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,EAAE,aAAa,EAAE,IAAI,IAAI,CAAC;IACzD,OAAO,SAAS,KAAK,IAAI,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACnF,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnD,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC;AAED,+EAA+E;AAC/E,kFAAkF;AAClF,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,EAAM,EACN,MAAsB,EACtB,QAAgB;IAEhB,MAAM,GAAG,GAAG,MAAM,EAAE;SACjB,UAAU,CAAC,OAAO,CAAC;SACnB,MAAM,CAAC,OAAO,CAAC;SACf,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC;SAC5B,gBAAgB,EAAE,CAAC;IACtB,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAChE,OAAO,sBAAsB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;AACjE,CAAC;AAED,8EAA8E;AAC9E,uEAAuE;AACvE,6EAA6E;AAC7E,yEAAyE;AACzE,uDAAuD"}
@@ -1 +1 @@
1
- {"version":3,"file":"callers.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/callers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAYhD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CA2H5E"}
1
+ {"version":3,"file":"callers.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/callers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAYhD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAgI5E"}
@@ -2,7 +2,7 @@ import { z } from 'zod';
2
2
  import { buildToolStats, recordToolCall, buildArgsJson, buildResultsJson } from '../../telemetry/metrics.js';
3
3
  import { countTokens, estimateFullFileBound } from '../../telemetry/tokenizer.js';
4
4
  import { querySymbolByName, queryVerifiedCallers } from '../../graph/queries.js';
5
- import { jitRefreshFile, collectPotentialMatches, isIndexEmpty } from './_helpers.js';
5
+ import { jitRefreshFile, collectPotentialMatches, isIndexEmpty, unindexedFilesField } from './_helpers.js';
6
6
  export function registerCallersTool(server, ctx) {
7
7
  server.tool('mast_callers', 'Call sites of a named symbol, partitioned into verified (graph-resolved) and potential (identifier-FTS) sets. Always check both sets — the graph only covers statically-linked call sites. Verified entries with resolution "checker" were proven by the opt-in `mast index --checker` TypeScript pass; the same pass drops non-call-site / wrong-declaration noise out of potential_matches (summary.checker_classified_* report how many).', {
8
8
  symbol: z.string().describe('Symbol name whose callers to find'),
@@ -33,6 +33,7 @@ export function registerCallersTool(server, ctx) {
33
33
  // §9.0 TOCTOU policy: omitted when false, never present-and-false.
34
34
  ...(fileBusy ? { file_busy_returning_stale_cache: true } : {}),
35
35
  ...indexEmptyField,
36
+ ...unindexedFilesField(ctx, 'exhaustive-set', true),
36
37
  summary: {
37
38
  verified_count: 0,
38
39
  potential_count: 0,
@@ -85,6 +86,10 @@ export function registerCallersTool(server, ctx) {
85
86
  // §9.0 TOCTOU policy: omitted when false, never present-and-false.
86
87
  ...(fileBusy ? { file_busy_returning_stale_cache: true } : {}),
87
88
  ...indexEmptyField,
89
+ // Always, not only when empty: "3 verified callers" over a corpus
90
+ // missing forty files reads exactly like a complete answer, and is the
91
+ // one that gets acted on.
92
+ ...unindexedFilesField(ctx, 'exhaustive-set', false),
88
93
  summary: {
89
94
  verified_count: verified_callers.length,
90
95
  potential_count: potential_matches.length,
@@ -1 +1 @@
1
- {"version":3,"file":"callers.js","sourceRoot":"","sources":["../../../src/mcp/tools/callers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"callers.js","sourceRoot":"","sources":["../../../src/mcp/tools/callers.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/dependencies.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAOhD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAsCjF"}
1
+ {"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/dependencies.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAOhD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAuCjF"}