@apnex/network-adapter 0.1.2 → 0.1.5

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 (86) hide show
  1. package/dist/build-info.json +6 -0
  2. package/dist/file-logger.d.ts +42 -0
  3. package/dist/file-logger.js +122 -0
  4. package/dist/file-logger.js.map +1 -0
  5. package/dist/index.d.ts +37 -13
  6. package/dist/index.js +42 -15
  7. package/dist/index.js.map +1 -1
  8. package/dist/kernel/adapter-config.d.ts +47 -0
  9. package/dist/kernel/adapter-config.js +90 -0
  10. package/dist/kernel/adapter-config.js.map +1 -0
  11. package/dist/kernel/agent-client.d.ts +25 -20
  12. package/dist/kernel/build-identity.d.ts +24 -0
  13. package/dist/kernel/build-identity.js +45 -0
  14. package/dist/kernel/build-identity.js.map +1 -0
  15. package/dist/kernel/event-router.d.ts +22 -1
  16. package/dist/kernel/event-router.js +45 -7
  17. package/dist/kernel/event-router.js.map +1 -1
  18. package/dist/kernel/handshake.d.ts +40 -4
  19. package/dist/kernel/handshake.js +46 -7
  20. package/dist/kernel/handshake.js.map +1 -1
  21. package/dist/kernel/harness-manifest.d.ts +51 -0
  22. package/dist/kernel/harness-manifest.js +96 -0
  23. package/dist/kernel/harness-manifest.js.map +1 -0
  24. package/dist/kernel/liveness-signal.d.ts +35 -0
  25. package/dist/kernel/liveness-signal.js +61 -0
  26. package/dist/kernel/liveness-signal.js.map +1 -0
  27. package/dist/kernel/liveness-watchdog.d.ts +78 -0
  28. package/dist/kernel/liveness-watchdog.js +115 -0
  29. package/dist/kernel/liveness-watchdog.js.map +1 -0
  30. package/dist/kernel/mcp-agent-client.d.ts +2 -2
  31. package/dist/kernel/mcp-agent-client.js +49 -3
  32. package/dist/kernel/mcp-agent-client.js.map +1 -1
  33. package/dist/kernel/poll-backstop.d.ts +93 -4
  34. package/dist/kernel/poll-backstop.js +193 -25
  35. package/dist/kernel/poll-backstop.js.map +1 -1
  36. package/dist/kernel/state-sync.d.ts +2 -13
  37. package/dist/kernel/state-sync.js.map +1 -1
  38. package/dist/notification-log.d.ts +8 -0
  39. package/dist/notification-log.js +10 -0
  40. package/dist/notification-log.js.map +1 -1
  41. package/dist/observability.d.ts +24 -0
  42. package/dist/observability.js +52 -0
  43. package/dist/observability.js.map +1 -0
  44. package/dist/prompt-format.js +82 -9
  45. package/dist/prompt-format.js.map +1 -1
  46. package/dist/tool-manager/catalog/health-revision.d.ts +43 -0
  47. package/dist/tool-manager/catalog/health-revision.js +61 -0
  48. package/dist/tool-manager/catalog/health-revision.js.map +1 -0
  49. package/dist/tool-manager/{tool-catalog-cache.d.ts → catalog/tool-catalog-cache.d.ts} +39 -19
  50. package/dist/tool-manager/{tool-catalog-cache.js → catalog/tool-catalog-cache.js} +53 -26
  51. package/dist/tool-manager/catalog/tool-catalog-cache.js.map +1 -0
  52. package/dist/tool-manager/catalog/tool-surface-reconciler.d.ts +93 -0
  53. package/dist/tool-manager/catalog/tool-surface-reconciler.js +101 -0
  54. package/dist/tool-manager/catalog/tool-surface-reconciler.js.map +1 -0
  55. package/dist/tool-manager/contracts.d.ts +91 -0
  56. package/dist/tool-manager/contracts.js +20 -0
  57. package/dist/tool-manager/contracts.js.map +1 -0
  58. package/dist/tool-manager/dispatch/dispatch.d.ts +77 -0
  59. package/dist/tool-manager/dispatch/dispatch.js +170 -0
  60. package/dist/tool-manager/dispatch/dispatch.js.map +1 -0
  61. package/dist/tool-manager/dispatch/tool-call-policy.d.ts +32 -0
  62. package/dist/tool-manager/dispatch/tool-call-policy.js +56 -0
  63. package/dist/tool-manager/dispatch/tool-call-policy.js.map +1 -0
  64. package/dist/tool-manager/{dispatcher.d.ts → orchestrator/dispatcher.d.ts} +110 -31
  65. package/dist/tool-manager/orchestrator/dispatcher.js +559 -0
  66. package/dist/tool-manager/orchestrator/dispatcher.js.map +1 -0
  67. package/dist/tool-manager/work-protocol/claimable-digest-tracker.d.ts +60 -0
  68. package/dist/tool-manager/work-protocol/claimable-digest-tracker.js +66 -0
  69. package/dist/tool-manager/work-protocol/claimable-digest-tracker.js.map +1 -0
  70. package/dist/tool-manager/work-protocol/work-lease-tracker.d.ts +59 -0
  71. package/dist/tool-manager/work-protocol/work-lease-tracker.js +134 -0
  72. package/dist/tool-manager/work-protocol/work-lease-tracker.js.map +1 -0
  73. package/dist/wire/mcp-transport.d.ts +1 -1
  74. package/dist/wire/mcp-transport.js +31 -7
  75. package/dist/wire/mcp-transport.js.map +1 -1
  76. package/dist/wire/slot-gate.d.ts +40 -0
  77. package/dist/wire/slot-gate.js +61 -0
  78. package/dist/wire/slot-gate.js.map +1 -0
  79. package/dist/wire/transport.d.ts +18 -0
  80. package/package.json +6 -3
  81. package/dist/kernel/instance.d.ts +0 -40
  82. package/dist/kernel/instance.js +0 -79
  83. package/dist/kernel/instance.js.map +0 -1
  84. package/dist/tool-manager/dispatcher.js +0 -379
  85. package/dist/tool-manager/dispatcher.js.map +0 -1
  86. package/dist/tool-manager/tool-catalog-cache.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-format.js","sourceRoot":"","sources":["../src/prompt-format.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompt-format.js","sourceRoot":"","sources":["../src/prompt-format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * health-revision.ts — the Hub /health `toolSurfaceRevision` fetcher,
3
+ * hoisted to the kernel (idea-355 SLICE-1T).
4
+ *
5
+ * This is the network mechanism the bug-180 `ToolSurfaceReconciler` injects as
6
+ * its `fetchLiveRevision` dependency: resolve the Hub's live tool-surface
7
+ * revision (an opaque ETag served on /health since bug-114) over plain HTTP,
8
+ * independent of the MCP transport.
9
+ *
10
+ * Previously this lived inline in each shim (the claude shim's
11
+ * `fetchLiveToolSurfaceRevision`). Hoisting it single-homes the network
12
+ * mechanism so both shims share ONE implementation. The factory is PURE — it
13
+ * holds no module state and carries NO cache side-effect: callers that want a
14
+ * cached-revision marker (the claude shim's `cachedToolSurfaceRevision`) wrap
15
+ * the returned function and apply the side-effect on a non-null result.
16
+ *
17
+ * Contract:
18
+ * - derive `healthUrl` by replacing a trailing `/mcp` (optionally with a
19
+ * further path) on `hubUrl` with `/health`;
20
+ * - fetch it (global `fetch` only — opencode bundles via esbuild with no
21
+ * node_modules, so no node-fetch/undici);
22
+ * - return `json.toolSurfaceRevision` when it is a non-empty string;
23
+ * - return null on `!res.ok`, a missing/empty/non-string field, or any throw
24
+ * (never reject — the reconciler treats null as "unknown, trust the cache"
25
+ * and never emits a spurious list_changed).
26
+ */
27
+ export interface FetchLiveToolSurfaceRevisionOptions {
28
+ /** The Hub MCP URL (…/mcp). The /health URL is derived from it. */
29
+ hubUrl: string;
30
+ /**
31
+ * Fetch implementation. Defaults to the global `fetch`. Injectable so the
32
+ * factory is unit-testable without a live Hub.
33
+ */
34
+ fetch?: typeof globalThis.fetch;
35
+ /** Diagnostic logger. No-op default. */
36
+ log?: (msg: string) => void;
37
+ }
38
+ /**
39
+ * Build a pure `fetchLiveRevision` function for the bug-180
40
+ * `ToolSurfaceReconciler`. Resolves the Hub's live /health
41
+ * `toolSurfaceRevision`, or null on any failure (never rejects).
42
+ */
43
+ export declare function makeFetchLiveToolSurfaceRevision(opts: FetchLiveToolSurfaceRevisionOptions): () => Promise<string | null>;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * health-revision.ts — the Hub /health `toolSurfaceRevision` fetcher,
3
+ * hoisted to the kernel (idea-355 SLICE-1T).
4
+ *
5
+ * This is the network mechanism the bug-180 `ToolSurfaceReconciler` injects as
6
+ * its `fetchLiveRevision` dependency: resolve the Hub's live tool-surface
7
+ * revision (an opaque ETag served on /health since bug-114) over plain HTTP,
8
+ * independent of the MCP transport.
9
+ *
10
+ * Previously this lived inline in each shim (the claude shim's
11
+ * `fetchLiveToolSurfaceRevision`). Hoisting it single-homes the network
12
+ * mechanism so both shims share ONE implementation. The factory is PURE — it
13
+ * holds no module state and carries NO cache side-effect: callers that want a
14
+ * cached-revision marker (the claude shim's `cachedToolSurfaceRevision`) wrap
15
+ * the returned function and apply the side-effect on a non-null result.
16
+ *
17
+ * Contract:
18
+ * - derive `healthUrl` by replacing a trailing `/mcp` (optionally with a
19
+ * further path) on `hubUrl` with `/health`;
20
+ * - fetch it (global `fetch` only — opencode bundles via esbuild with no
21
+ * node_modules, so no node-fetch/undici);
22
+ * - return `json.toolSurfaceRevision` when it is a non-empty string;
23
+ * - return null on `!res.ok`, a missing/empty/non-string field, or any throw
24
+ * (never reject — the reconciler treats null as "unknown, trust the cache"
25
+ * and never emits a spurious list_changed).
26
+ */
27
+ /**
28
+ * Build a pure `fetchLiveRevision` function for the bug-180
29
+ * `ToolSurfaceReconciler`. Resolves the Hub's live /health
30
+ * `toolSurfaceRevision`, or null on any failure (never rejects).
31
+ */
32
+ export function makeFetchLiveToolSurfaceRevision(opts) {
33
+ const log = opts.log ?? (() => { });
34
+ const doFetch = opts.fetch ?? globalThis.fetch;
35
+ const healthUrl = opts.hubUrl.replace(/\/mcp(\/.*)?$/, "/health");
36
+ return async () => {
37
+ try {
38
+ const res = await doFetch(healthUrl);
39
+ if (!res.ok) {
40
+ log(`[Cache] /health fetch returned status ${res.status} — cache invalidation will trust existing cache`);
41
+ return null;
42
+ }
43
+ const json = (await res.json());
44
+ if (typeof json.version === "string") {
45
+ log(`[Cache] Hub version: ${json.version}`);
46
+ }
47
+ if (typeof json.toolSurfaceRevision === "string" &&
48
+ json.toolSurfaceRevision !== "") {
49
+ log(`[Cache] Tool-surface revision resolved: ${json.toolSurfaceRevision}`);
50
+ return json.toolSurfaceRevision;
51
+ }
52
+ log(`[Cache] /health returned no toolSurfaceRevision field — cache invalidation will trust existing cache`);
53
+ return null;
54
+ }
55
+ catch (err) {
56
+ log(`[Cache] /health fetch failed (non-fatal): ${err?.message ?? String(err)}`);
57
+ return null;
58
+ }
59
+ };
60
+ }
61
+ //# sourceMappingURL=health-revision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-revision.js","sourceRoot":"","sources":["../../../src/tool-manager/catalog/health-revision.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAcH;;;;GAIG;AACH,MAAM,UAAU,gCAAgC,CAC9C,IAAyC;IAEzC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;IAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;IAElE,OAAO,KAAK,IAA4B,EAAE;QACxC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;YACrC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,GAAG,CACD,yCAAyC,GAAG,CAAC,MAAM,iDAAiD,CACrG,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAG7B,CAAC;YACF,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACrC,GAAG,CAAC,wBAAwB,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9C,CAAC;YACD,IACE,OAAO,IAAI,CAAC,mBAAmB,KAAK,QAAQ;gBAC5C,IAAI,CAAC,mBAAmB,KAAK,EAAE,EAC/B,CAAC;gBACD,GAAG,CAAC,2CAA2C,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;gBAC3E,OAAO,IAAI,CAAC,mBAAmB,CAAC;YAClC,CAAC;YACD,GAAG,CACD,sGAAsG,CACvG,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,6CAA8C,GAAa,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC3F,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -10,16 +10,20 @@
10
10
  *
11
11
  * Storage: $WORK_DIR/.ois/tool-catalog.json
12
12
  * {
13
- * schemaVersion: 1,
14
- * hubVersion: "1.0.0",
13
+ * schemaVersion: 2,
14
+ * toolSurfaceRevision: "a1b2c3d4e5f6a7b8",
15
15
  * fetchedAt: "2026-04-22T...Z",
16
16
  * catalog: [...]
17
17
  * }
18
18
  *
19
- * Invalidation: Hub-version mismatch only. No TTL — the catalog is
20
- * static between Hub deploys; TTL would add noise without correctness
21
- * value. Schema-version mismatch on read returns null (cache treated
22
- * as invalid; future schema evolution bumps CATALOG_SCHEMA_VERSION).
19
+ * Invalidation: tool-surface-revision mismatch (bug-114). The cache is
20
+ * keyed off a Hub-owned ETag (`/health` `toolSurfaceRevision`) that
21
+ * tracks the actual tool surface added/removed tools, description or
22
+ * schema changes rather than `hubVersion`, which was a hardcoded
23
+ * `"1.0.0"` literal that never changed (so the cache never invalidated).
24
+ * No TTL — the revision detects drift directly. Schema-version mismatch
25
+ * on read returns null (cache treated as invalid; schema evolution bumps
26
+ * CATALOG_SCHEMA_VERSION).
23
27
  *
24
28
  * Atomicity: writeCache uses tmp-file + rename so partial writes on
25
29
  * crash don't corrupt the cache. Parse errors on read also return
@@ -29,7 +33,10 @@
29
33
  * the primary flow):
30
34
  * - missing file: readCache returns null
31
35
  * - parse error: readCache returns null + logs
32
- * - schema-version mismatch: readCache returns null
36
+ * - schema-version mismatch: readCache returns null + logs +
37
+ * unlinks the stale file (bug-114
38
+ * fallback-gap hardening — forces clean
39
+ * rebuild on next bootstrap)
33
40
  * - $WORK_DIR readonly: writeCache logs + no-ops
34
41
  * - disk full: writeCache logs + no-ops
35
42
  */
@@ -37,8 +44,14 @@
37
44
  * Bumping CATALOG_SCHEMA_VERSION forces all existing cache files to
38
45
  * be treated as invalid + re-bootstrapped. Use when changing the
39
46
  * cache file shape.
47
+ *
48
+ * 1 → 2 (bug-114): `hubVersion` field replaced by `toolSurfaceRevision`.
49
+ * The bump is the state-migration step — every on-disk cache written in
50
+ * the v1 (`hubVersion`) shape fails the read-time schema check, returns
51
+ * null, and re-bootstraps. Free retroactive cleanup of the whole fleet's
52
+ * stale caches.
40
53
  */
41
- export declare const CATALOG_SCHEMA_VERSION = 1;
54
+ export declare const CATALOG_SCHEMA_VERSION = 2;
42
55
  /**
43
56
  * MCP tool catalog entry shape. Kept loose (`unknown[]`) since the
44
57
  * cache is opaque storage; the dispatcher hands the catalog back to
@@ -47,7 +60,12 @@ export declare const CATALOG_SCHEMA_VERSION = 1;
47
60
  export type ToolCatalog = unknown[];
48
61
  export interface CachedCatalog {
49
62
  schemaVersion: number;
50
- hubVersion: string;
63
+ /**
64
+ * bug-114 — the Hub-owned tool-surface ETag seen at fetch-time
65
+ * (`/health` `toolSurfaceRevision`). The cache is valid while this
66
+ * matches the live revision; treated as opaque (record-then-compare).
67
+ */
68
+ toolSurfaceRevision: string;
51
69
  fetchedAt: string;
52
70
  catalog: ToolCatalog;
53
71
  }
@@ -66,20 +84,22 @@ export declare function readCache(workDir: string, log?: (msg: string) => void):
66
84
  * intact OR the new cache fully landed. Best-effort: failures log
67
85
  * and return; the caller's primary flow continues.
68
86
  */
69
- export declare function writeCache(workDir: string, catalog: ToolCatalog, hubVersion: string, log?: (msg: string) => void): void;
87
+ export declare function writeCache(workDir: string, catalog: ToolCatalog, toolSurfaceRevision: string, log?: (msg: string) => void): void;
70
88
  /**
71
- * Check cache validity against the current Hub version.
89
+ * Check cache validity against the current Hub tool-surface revision.
72
90
  *
73
91
  * Two semantics:
74
- * - currentHubVersion is a non-empty string: strict equality vs
75
- * cached.hubVersion. Mismatch → invalid → caller re-bootstraps.
76
- * - currentHubVersion is null/undefined/empty: caller doesn't know
77
- * the current Hub version yet (e.g. /health fetch in flight at
78
- * startup). Trust the cache (probe-friendly default) worst
79
- * case is serving a stale catalog ONCE until the next /health
80
- * fetch completes and a real session refreshes the cache.
92
+ * - currentRevision is a non-empty string: strict equality vs
93
+ * cached.toolSurfaceRevision. Mismatch → invalid → caller
94
+ * re-bootstraps.
95
+ * - currentRevision is null/undefined/empty: caller doesn't know the
96
+ * current revision yet (e.g. /health fetch in flight at startup, or
97
+ * an old Hub that doesn't return the field). Trust the cache
98
+ * (probe-friendly default) worst case is serving a stale catalog
99
+ * ONCE until the next /health fetch completes and a real session
100
+ * refreshes the cache.
81
101
  *
82
102
  * Schema-version check is enforced inside readCache, so isCacheValid
83
103
  * never sees a wrong-schema cached object.
84
104
  */
85
- export declare function isCacheValid(cached: CachedCatalog, currentHubVersion: string | null | undefined): boolean;
105
+ export declare function isCacheValid(cached: CachedCatalog, currentRevision: string | null | undefined): boolean;
@@ -10,16 +10,20 @@
10
10
  *
11
11
  * Storage: $WORK_DIR/.ois/tool-catalog.json
12
12
  * {
13
- * schemaVersion: 1,
14
- * hubVersion: "1.0.0",
13
+ * schemaVersion: 2,
14
+ * toolSurfaceRevision: "a1b2c3d4e5f6a7b8",
15
15
  * fetchedAt: "2026-04-22T...Z",
16
16
  * catalog: [...]
17
17
  * }
18
18
  *
19
- * Invalidation: Hub-version mismatch only. No TTL — the catalog is
20
- * static between Hub deploys; TTL would add noise without correctness
21
- * value. Schema-version mismatch on read returns null (cache treated
22
- * as invalid; future schema evolution bumps CATALOG_SCHEMA_VERSION).
19
+ * Invalidation: tool-surface-revision mismatch (bug-114). The cache is
20
+ * keyed off a Hub-owned ETag (`/health` `toolSurfaceRevision`) that
21
+ * tracks the actual tool surface added/removed tools, description or
22
+ * schema changes rather than `hubVersion`, which was a hardcoded
23
+ * `"1.0.0"` literal that never changed (so the cache never invalidated).
24
+ * No TTL — the revision detects drift directly. Schema-version mismatch
25
+ * on read returns null (cache treated as invalid; schema evolution bumps
26
+ * CATALOG_SCHEMA_VERSION).
23
27
  *
24
28
  * Atomicity: writeCache uses tmp-file + rename so partial writes on
25
29
  * crash don't corrupt the cache. Parse errors on read also return
@@ -29,7 +33,10 @@
29
33
  * the primary flow):
30
34
  * - missing file: readCache returns null
31
35
  * - parse error: readCache returns null + logs
32
- * - schema-version mismatch: readCache returns null
36
+ * - schema-version mismatch: readCache returns null + logs +
37
+ * unlinks the stale file (bug-114
38
+ * fallback-gap hardening — forces clean
39
+ * rebuild on next bootstrap)
33
40
  * - $WORK_DIR readonly: writeCache logs + no-ops
34
41
  * - disk full: writeCache logs + no-ops
35
42
  */
@@ -39,8 +46,14 @@ import { join, dirname } from "node:path";
39
46
  * Bumping CATALOG_SCHEMA_VERSION forces all existing cache files to
40
47
  * be treated as invalid + re-bootstrapped. Use when changing the
41
48
  * cache file shape.
49
+ *
50
+ * 1 → 2 (bug-114): `hubVersion` field replaced by `toolSurfaceRevision`.
51
+ * The bump is the state-migration step — every on-disk cache written in
52
+ * the v1 (`hubVersion`) shape fails the read-time schema check, returns
53
+ * null, and re-bootstraps. Free retroactive cleanup of the whole fleet's
54
+ * stale caches.
42
55
  */
43
- export const CATALOG_SCHEMA_VERSION = 1;
56
+ export const CATALOG_SCHEMA_VERSION = 2;
44
57
  /** Compute the canonical cache path for a given WORK_DIR. */
45
58
  export function cachePathFor(workDir) {
46
59
  return join(workDir, ".ois", "tool-catalog.json");
@@ -60,15 +73,27 @@ export function readCache(workDir, log) {
60
73
  const parsed = JSON.parse(raw);
61
74
  if (typeof parsed.schemaVersion !== "number" ||
62
75
  parsed.schemaVersion !== CATALOG_SCHEMA_VERSION ||
63
- typeof parsed.hubVersion !== "string" ||
76
+ typeof parsed.toolSurfaceRevision !== "string" ||
64
77
  typeof parsed.fetchedAt !== "string" ||
65
78
  !Array.isArray(parsed.catalog)) {
66
- log?.(`[tool-catalog-cache] readCache: cache invalid (schema/shape mismatch) at ${path}`);
79
+ log?.(`[tool-catalog-cache] readCache: cache invalid (schema/shape mismatch) at ${path} — unlinking to force clean rebuild`);
80
+ // bug-114 fallback-gap hardening (2026-05-26): unlink the stale
81
+ // file so the next bootstrap doesn't repeatedly read-then-discard
82
+ // it. Without this, every cold-start after a
83
+ // CATALOG_SCHEMA_VERSION bump re-encounters the same stale file
84
+ // until operator intervention. Best-effort; primary flow tolerates
85
+ // unlink failures.
86
+ try {
87
+ unlinkSync(path);
88
+ }
89
+ catch (unlinkErr) {
90
+ log?.(`[tool-catalog-cache] readCache: unlink failed (non-fatal): ${unlinkErr.message ?? unlinkErr}`);
91
+ }
67
92
  return null;
68
93
  }
69
94
  return {
70
95
  schemaVersion: parsed.schemaVersion,
71
- hubVersion: parsed.hubVersion,
96
+ toolSurfaceRevision: parsed.toolSurfaceRevision,
72
97
  fetchedAt: parsed.fetchedAt,
73
98
  catalog: parsed.catalog,
74
99
  };
@@ -84,12 +109,12 @@ export function readCache(workDir, log) {
84
109
  * intact OR the new cache fully landed. Best-effort: failures log
85
110
  * and return; the caller's primary flow continues.
86
111
  */
87
- export function writeCache(workDir, catalog, hubVersion, log) {
112
+ export function writeCache(workDir, catalog, toolSurfaceRevision, log) {
88
113
  const path = cachePathFor(workDir);
89
114
  const tmpPath = `${path}.tmp.${process.pid}`;
90
115
  const body = {
91
116
  schemaVersion: CATALOG_SCHEMA_VERSION,
92
- hubVersion,
117
+ toolSurfaceRevision,
93
118
  fetchedAt: new Date().toISOString(),
94
119
  catalog,
95
120
  };
@@ -112,26 +137,28 @@ export function writeCache(workDir, catalog, hubVersion, log) {
112
137
  }
113
138
  }
114
139
  /**
115
- * Check cache validity against the current Hub version.
140
+ * Check cache validity against the current Hub tool-surface revision.
116
141
  *
117
142
  * Two semantics:
118
- * - currentHubVersion is a non-empty string: strict equality vs
119
- * cached.hubVersion. Mismatch → invalid → caller re-bootstraps.
120
- * - currentHubVersion is null/undefined/empty: caller doesn't know
121
- * the current Hub version yet (e.g. /health fetch in flight at
122
- * startup). Trust the cache (probe-friendly default) worst
123
- * case is serving a stale catalog ONCE until the next /health
124
- * fetch completes and a real session refreshes the cache.
143
+ * - currentRevision is a non-empty string: strict equality vs
144
+ * cached.toolSurfaceRevision. Mismatch → invalid → caller
145
+ * re-bootstraps.
146
+ * - currentRevision is null/undefined/empty: caller doesn't know the
147
+ * current revision yet (e.g. /health fetch in flight at startup, or
148
+ * an old Hub that doesn't return the field). Trust the cache
149
+ * (probe-friendly default) worst case is serving a stale catalog
150
+ * ONCE until the next /health fetch completes and a real session
151
+ * refreshes the cache.
125
152
  *
126
153
  * Schema-version check is enforced inside readCache, so isCacheValid
127
154
  * never sees a wrong-schema cached object.
128
155
  */
129
- export function isCacheValid(cached, currentHubVersion) {
130
- if (currentHubVersion === null ||
131
- currentHubVersion === undefined ||
132
- currentHubVersion === "") {
156
+ export function isCacheValid(cached, currentRevision) {
157
+ if (currentRevision === null ||
158
+ currentRevision === undefined ||
159
+ currentRevision === "") {
133
160
  return true;
134
161
  }
135
- return cached.hubVersion === currentHubVersion;
162
+ return cached.toolSurfaceRevision === currentRevision;
136
163
  }
137
164
  //# sourceMappingURL=tool-catalog-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-catalog-cache.js","sourceRoot":"","sources":["../../../src/tool-manager/catalog/tool-catalog-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EACL,YAAY,EACZ,aAAa,EACb,UAAU,EACV,UAAU,EACV,SAAS,EACT,UAAU,GACX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAqBxC,6DAA6D;AAC7D,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,OAAO,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,mBAAmB,CAAC,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CACvB,OAAe,EACf,GAA2B;IAE3B,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA2B,CAAC;QACzD,IACE,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ;YACxC,MAAM,CAAC,aAAa,KAAK,sBAAsB;YAC/C,OAAO,MAAM,CAAC,mBAAmB,KAAK,QAAQ;YAC9C,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;YACpC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAC9B,CAAC;YACD,GAAG,EAAE,CACH,4EAA4E,IAAI,qCAAqC,CACtH,CAAC;YACF,gEAAgE;YAChE,kEAAkE;YAClE,6CAA6C;YAC7C,gEAAgE;YAChE,mEAAmE;YACnE,mBAAmB;YACnB,IAAI,CAAC;gBACH,UAAU,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;YAAC,OAAO,SAAS,EAAE,CAAC;gBACnB,GAAG,EAAE,CACH,8DAA+D,SAAmB,CAAC,OAAO,IAAI,SAAS,EAAE,CAC1G,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO;YACL,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;YAC/C,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,EAAE,CACH,kDAAkD,IAAI,KAAM,GAAa,CAAC,OAAO,IAAI,GAAG,EAAE,CAC3F,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CACxB,OAAe,EACf,OAAoB,EACpB,mBAA2B,EAC3B,GAA2B;IAE3B,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,GAAG,IAAI,QAAQ,OAAO,CAAC,GAAG,EAAE,CAAC;IAC7C,MAAM,IAAI,GAAkB;QAC1B,aAAa,EAAE,sBAAsB;QACrC,mBAAmB;QACnB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,OAAO;KACR,CAAC;IACF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QACnE,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,EAAE,CACH,8CAA8C,IAAI,KAAM,GAAa,CAAC,OAAO,IAAI,GAAG,qCAAqC,CAC1H,CAAC;QACF,IAAI,CAAC;YACH,IAAI,UAAU,CAAC,OAAO,CAAC;gBAAE,UAAU,CAAC,OAAO,CAAC,CAAC;QAC/C,CAAC;QAAC,MAAM,CAAC;YACP,YAAY;QACd,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAqB,EACrB,eAA0C;IAE1C,IACE,eAAe,KAAK,IAAI;QACxB,eAAe,KAAK,SAAS;QAC7B,eAAe,KAAK,EAAE,EACtB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC,mBAAmB,KAAK,eAAe,CAAC;AACxD,CAAC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * tool-surface-reconciler.ts — declared-vs-applied reconcile for the Hub
3
+ * MCP tool surface (bug-180 / FR-21).
4
+ *
5
+ * Problem this closes: the host (e.g. Claude Code) enumerates `tools/list`
6
+ * ONCE at startup. On the pre-identity probe path the dispatcher serves the
7
+ * persisted on-disk catalog (tool-catalog-cache). When a Hub redeploy changes
8
+ * the tool surface, the in-memory catalog the host holds goes stale and
9
+ * nothing re-enumerates it — neither a client hard-reset nor /reload-plugins,
10
+ * because the long-lived proxy process never re-fetches and the redeploy emits
11
+ * no in-life `notifications/tools/list_changed` to already-connected hosts.
12
+ *
13
+ * The fix treats tool-surface delivery as a reconcile, mirroring the storage
14
+ * substrate's SchemaDef-reconciler:
15
+ * - desired-state = the Hub's tool surface, versioned by `toolSurfaceRevision`
16
+ * (a deterministic hash of the registered tool set, served
17
+ * on /health; Hub-side since bug-114).
18
+ * - applied-state = the revision the host most recently enumerated.
19
+ * - watch/notify = MCP `notifications/tools/list_changed` (the Hub already
20
+ * advertises `tools.listChanged: true`).
21
+ *
22
+ * On drift between applied and desired, emit `list_changed`; the host re-calls
23
+ * `tools/list` and — identity now resolved — the dispatcher serves the live
24
+ * surface (it skips the probe-cache path once identityReady is true).
25
+ *
26
+ * This class owns ONLY the reconcile decision + the applied-revision marker.
27
+ * All I/O is injected so it is unit-testable without a live Hub:
28
+ * - fetchLiveRevision: resolve the Hub's current /health `toolSurfaceRevision`
29
+ * (null on fetch failure / a Hub that doesn't return the field).
30
+ * - readServedRevision: the revision the host's startup enumeration was
31
+ * served from — the on-disk cache's `toolSurfaceRevision` (null when no
32
+ * cache exists, i.e. a fresh install that bootstrapped live).
33
+ * - emitListChanged: emit `notifications/tools/list_changed` to the host.
34
+ *
35
+ * Two trigger points share one `reconcile()`:
36
+ * - L1 (primary): on the shim's `identityReady` event — catches the
37
+ * redeploy-then-reconnect case that caused bug-180.
38
+ * - L2 (backstop): on the existing PollBackstop heartbeat cadence — catches
39
+ * a redeploy WHILE a session stays connected (no reconnect, so no fresh
40
+ * identityReady).
41
+ *
42
+ * The applied-revision baseline is established on the first successful
43
+ * reconcile (whichever trigger fires first), seeded from the on-disk cache so
44
+ * a stale-cache-vs-live delta is detected even if L2 races ahead of L1.
45
+ */
46
+ export interface ToolSurfaceReconcilerDeps {
47
+ /**
48
+ * Resolve the Hub's live tool-surface revision (the /health
49
+ * `toolSurfaceRevision` ETag). Returns null when the fetch fails or the Hub
50
+ * doesn't return the field — the reconcile then no-ops (fail-safe: never
51
+ * emit a spurious `list_changed` on an unknown live state).
52
+ */
53
+ fetchLiveRevision: () => Promise<string | null>;
54
+ /**
55
+ * The revision the host's current tool view was enumerated from — the
56
+ * on-disk cache's `toolSurfaceRevision`. Used to seed the applied-state
57
+ * baseline on the first reconcile (the pre-identity probe served this).
58
+ * null when no cache exists (fresh install bootstrapped live → no drift).
59
+ */
60
+ readServedRevision: () => string | null;
61
+ /** Emit `notifications/tools/list_changed` to the host. */
62
+ emitListChanged: () => void;
63
+ /** Diagnostic logger. No-op default. */
64
+ log?: (msg: string) => void;
65
+ }
66
+ export interface ReconcileOutcome {
67
+ /** True iff a drift was detected and `list_changed` was emitted this pass. */
68
+ emitted: boolean;
69
+ /** The live revision resolved this pass (null on fetch failure). */
70
+ live: string | null;
71
+ }
72
+ export declare class ToolSurfaceReconciler {
73
+ private readonly deps;
74
+ /**
75
+ * The revision the host is believed to currently have applied. null until
76
+ * the first successful reconcile establishes the baseline.
77
+ */
78
+ private appliedRevision;
79
+ private readonly log;
80
+ constructor(deps: ToolSurfaceReconcilerDeps);
81
+ /** Test/diagnostic accessor for the current applied-state marker. */
82
+ getAppliedRevision(): string | null;
83
+ /**
84
+ * One reconcile pass. Idempotent and safe to call from either trigger:
85
+ * 1. Resolve the live revision; no-op on unknown (fetch failed).
86
+ * 2. On first pass, seed the applied baseline from the on-disk cache
87
+ * (what the host's startup probe served) — or from live if no cache.
88
+ * 3. On applied-vs-live drift, emit `list_changed` + advance the baseline.
89
+ *
90
+ * @param reason short label for logs (e.g. "identityReady", "heartbeat").
91
+ */
92
+ reconcile(reason?: string): Promise<ReconcileOutcome>;
93
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * tool-surface-reconciler.ts — declared-vs-applied reconcile for the Hub
3
+ * MCP tool surface (bug-180 / FR-21).
4
+ *
5
+ * Problem this closes: the host (e.g. Claude Code) enumerates `tools/list`
6
+ * ONCE at startup. On the pre-identity probe path the dispatcher serves the
7
+ * persisted on-disk catalog (tool-catalog-cache). When a Hub redeploy changes
8
+ * the tool surface, the in-memory catalog the host holds goes stale and
9
+ * nothing re-enumerates it — neither a client hard-reset nor /reload-plugins,
10
+ * because the long-lived proxy process never re-fetches and the redeploy emits
11
+ * no in-life `notifications/tools/list_changed` to already-connected hosts.
12
+ *
13
+ * The fix treats tool-surface delivery as a reconcile, mirroring the storage
14
+ * substrate's SchemaDef-reconciler:
15
+ * - desired-state = the Hub's tool surface, versioned by `toolSurfaceRevision`
16
+ * (a deterministic hash of the registered tool set, served
17
+ * on /health; Hub-side since bug-114).
18
+ * - applied-state = the revision the host most recently enumerated.
19
+ * - watch/notify = MCP `notifications/tools/list_changed` (the Hub already
20
+ * advertises `tools.listChanged: true`).
21
+ *
22
+ * On drift between applied and desired, emit `list_changed`; the host re-calls
23
+ * `tools/list` and — identity now resolved — the dispatcher serves the live
24
+ * surface (it skips the probe-cache path once identityReady is true).
25
+ *
26
+ * This class owns ONLY the reconcile decision + the applied-revision marker.
27
+ * All I/O is injected so it is unit-testable without a live Hub:
28
+ * - fetchLiveRevision: resolve the Hub's current /health `toolSurfaceRevision`
29
+ * (null on fetch failure / a Hub that doesn't return the field).
30
+ * - readServedRevision: the revision the host's startup enumeration was
31
+ * served from — the on-disk cache's `toolSurfaceRevision` (null when no
32
+ * cache exists, i.e. a fresh install that bootstrapped live).
33
+ * - emitListChanged: emit `notifications/tools/list_changed` to the host.
34
+ *
35
+ * Two trigger points share one `reconcile()`:
36
+ * - L1 (primary): on the shim's `identityReady` event — catches the
37
+ * redeploy-then-reconnect case that caused bug-180.
38
+ * - L2 (backstop): on the existing PollBackstop heartbeat cadence — catches
39
+ * a redeploy WHILE a session stays connected (no reconnect, so no fresh
40
+ * identityReady).
41
+ *
42
+ * The applied-revision baseline is established on the first successful
43
+ * reconcile (whichever trigger fires first), seeded from the on-disk cache so
44
+ * a stale-cache-vs-live delta is detected even if L2 races ahead of L1.
45
+ */
46
+ export class ToolSurfaceReconciler {
47
+ deps;
48
+ /**
49
+ * The revision the host is believed to currently have applied. null until
50
+ * the first successful reconcile establishes the baseline.
51
+ */
52
+ appliedRevision = null;
53
+ log;
54
+ constructor(deps) {
55
+ this.deps = deps;
56
+ this.log = deps.log ?? (() => { });
57
+ }
58
+ /** Test/diagnostic accessor for the current applied-state marker. */
59
+ getAppliedRevision() {
60
+ return this.appliedRevision;
61
+ }
62
+ /**
63
+ * One reconcile pass. Idempotent and safe to call from either trigger:
64
+ * 1. Resolve the live revision; no-op on unknown (fetch failed).
65
+ * 2. On first pass, seed the applied baseline from the on-disk cache
66
+ * (what the host's startup probe served) — or from live if no cache.
67
+ * 3. On applied-vs-live drift, emit `list_changed` + advance the baseline.
68
+ *
69
+ * @param reason short label for logs (e.g. "identityReady", "heartbeat").
70
+ */
71
+ async reconcile(reason = "reconcile") {
72
+ const live = await this.deps.fetchLiveRevision();
73
+ if (live === null) {
74
+ this.log(`[tool-surface-reconcile] ${reason}: live revision unknown — skipping (cache trusted)`);
75
+ return { emitted: false, live: null };
76
+ }
77
+ // Establish the applied-state baseline on the first successful pass. Prefer
78
+ // the on-disk cache revision (the surface the pre-identity probe served);
79
+ // fall back to live when no cache exists (fresh install already enumerated
80
+ // live, so there is nothing to reconcile against).
81
+ if (this.appliedRevision === null) {
82
+ const served = this.deps.readServedRevision();
83
+ this.appliedRevision = served ?? live;
84
+ this.log(`[tool-surface-reconcile] ${reason}: baseline applied=${this.appliedRevision} (served=${served ?? "none"}, live=${live})`);
85
+ }
86
+ if (live !== this.appliedRevision) {
87
+ this.log(`[tool-surface-reconcile] ${reason}: drift applied=${this.appliedRevision} → live=${live} — emitting tools/list_changed`);
88
+ try {
89
+ this.deps.emitListChanged();
90
+ }
91
+ catch (err) {
92
+ // Never let a host-emit failure escape the reconcile loop.
93
+ this.log(`[tool-surface-reconcile] ${reason}: emitListChanged threw (non-fatal): ${err?.message ?? String(err)}`);
94
+ }
95
+ this.appliedRevision = live;
96
+ return { emitted: true, live };
97
+ }
98
+ return { emitted: false, live };
99
+ }
100
+ }
101
+ //# sourceMappingURL=tool-surface-reconciler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-surface-reconciler.js","sourceRoot":"","sources":["../../../src/tool-manager/catalog/tool-surface-reconciler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAiCH,MAAM,OAAO,qBAAqB;IAQH;IAP7B;;;OAGG;IACK,eAAe,GAAkB,IAAI,CAAC;IAC7B,GAAG,CAAwB;IAE5C,YAA6B,IAA+B;QAA/B,SAAI,GAAJ,IAAI,CAA2B;QAC1D,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,qEAAqE;IACrE,kBAAkB;QAChB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,WAAW;QAClC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACjD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,IAAI,CAAC,GAAG,CACN,4BAA4B,MAAM,oDAAoD,CACvF,CAAC;YACF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACxC,CAAC;QAED,4EAA4E;QAC5E,0EAA0E;QAC1E,2EAA2E;QAC3E,mDAAmD;QACnD,IAAI,IAAI,CAAC,eAAe,KAAK,IAAI,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC9C,IAAI,CAAC,eAAe,GAAG,MAAM,IAAI,IAAI,CAAC;YACtC,IAAI,CAAC,GAAG,CACN,4BAA4B,MAAM,sBAAsB,IAAI,CAAC,eAAe,YAAY,MAAM,IAAI,MAAM,UAAU,IAAI,GAAG,CAC1H,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,KAAK,IAAI,CAAC,eAAe,EAAE,CAAC;YAClC,IAAI,CAAC,GAAG,CACN,4BAA4B,MAAM,mBAAmB,IAAI,CAAC,eAAe,WAAW,IAAI,gCAAgC,CACzH,CAAC;YACF,IAAI,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAC9B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,2DAA2D;gBAC3D,IAAI,CAAC,GAAG,CACN,4BAA4B,MAAM,wCAAyC,GAAa,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CACnH,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAC5B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACjC,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAClC,CAAC;CACF"}