@beacon-build/sdk 1.49.6 → 1.49.8

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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @beacon-build/sdk Changelog
2
2
 
3
+ ## 1.49.8
4
+
5
+ ### Patch Changes
6
+
7
+ - 4f655b0: fix(B710): bound the boot/refresh Argus JWT mint with a timeout (default 30s) and instrument startMcpServer's register() window with start/duration/failure logging + crash handlers — a hung network mint could otherwise block server.connect() indefinitely, past a client-side MCP readiness gate, with no diagnostic reaching our own logs.
8
+ - Updated dependencies [4fd1229]
9
+ - Updated dependencies [92640b1]
10
+ - Updated dependencies [daf2282]
11
+ - Updated dependencies [908e5be]
12
+ - @beacon-build/core@1.49.8
13
+
14
+ ## 1.49.7
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies [2f35eff]
19
+ - Updated dependencies [fcc6190]
20
+ - Updated dependencies [c9d1f3f]
21
+ - @beacon-build/core@1.49.7
22
+
3
23
  ## 1.49.6
4
24
 
5
25
  ### Patch Changes
@@ -24,6 +24,21 @@
24
24
  * error only) rather than an import of that type — `sdk` has no dependency on
25
25
  * `@beacon-build/logger` today, and every caller's real logger already satisfies this
26
26
  * shape, so no new dependency edge is needed for typing either.
27
+ *
28
+ * B710: an MCP server calls `createServices()` (→ this boot mint) from INSIDE its
29
+ * `register()` step, which `startMcpServer` (`@beacon-build/mcp-core/bootstrap`) always
30
+ * `await`s BEFORE `server.connect(transport)` — the point at which the process can answer
31
+ * the client's `initialize`/`tools/list` handshake at all. Before this fix, `mintAtBoot`
32
+ * awaited `mintFn()` with NO bound: a slow or hung network call (the API/local daemon
33
+ * still booting, e.g. racing a Claude Desktop restart) blocked `register()` — and so
34
+ * `connect()` — for as long as the network stayed unresponsive, with nothing in our own
35
+ * logs to explain why. Observed live: the MCP client's own readiness gate ("Not ready
36
+ * after 60 seconds; the sessions waiting for it started without it") reporting the server
37
+ * disconnected. `timeoutMs` (default `DEFAULT_MINT_TIMEOUT_MS`) bounds every mint call so a
38
+ * hang becomes the SAME loud, fast, already-tested fail-fast/keep-current behavior instead
39
+ * of an unbounded wait — the boot mint fails within a fixed, predictable window well short
40
+ * of a 60s external readiness gate, and a stalled scheduled refresh no longer holds its
41
+ * timer callback open indefinitely either.
27
42
  */
28
43
  export interface RotatingJwtLog {
29
44
  info(message: string, context?: Record<string, unknown>): void;
@@ -36,17 +51,26 @@ export interface JwtMintResult {
36
51
  token: string;
37
52
  logContext?: Record<string, unknown>;
38
53
  }
54
+ /** B710: default bound on a single mint call (boot or scheduled refresh) — well short of
55
+ * the 60s external MCP-client readiness gate observed live, leaving headroom for the rest
56
+ * of `register()`/`connect()` to run inside that same window. */
57
+ export declare const DEFAULT_MINT_TIMEOUT_MS = 30000;
39
58
  export interface RotatingJwtProviderOptions {
40
59
  /** Interval between scheduled refreshes, ms. Convention: HALF the token's TTL, so a
41
60
  * single failed refresh still leaves the current token valid for the rest of its
42
61
  * window — one transient mint blip never causes an outage. */
43
62
  refreshMs: number;
44
63
  log: RotatingJwtLog;
64
+ /** B710: bound on a single mint call (boot or scheduled refresh) — a mint that neither
65
+ * resolves nor rejects within this window is treated as a failure (same fail-fast /
66
+ * keep-current handling as any other mint error). Defaults to
67
+ * `DEFAULT_MINT_TIMEOUT_MS`. */
68
+ timeoutMs?: number;
45
69
  }
46
70
  /**
47
71
  * Mint `mintFn` once at boot (fail-fast on failure — exits the process), then keep the
48
72
  * token rotating for the life of a long-running daemon on an unref'd timer. Returns a
49
73
  * PROVIDER — re-read per request — never a captured string.
50
74
  */
51
- export declare function createRotatingJwtProvider(mintFn: () => Promise<JwtMintResult>, { refreshMs, log }: RotatingJwtProviderOptions): Promise<() => string>;
75
+ export declare function createRotatingJwtProvider(mintFn: () => Promise<JwtMintResult>, { refreshMs, log, timeoutMs }: RotatingJwtProviderOptions): Promise<() => string>;
52
76
  //# sourceMappingURL=rotating-jwt-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rotating-jwt-provider.d.ts","sourceRoot":"","sources":["../../src/auth/rotating-jwt-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,WAAW,cAAc;IAC3B,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC9D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAClE;AAED;;iFAEiF;AACjF,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACvC;AAED,MAAM,WAAW,0BAA0B;IACvC;;mEAE+D;IAC/D,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,cAAc,CAAA;CACtB;AAkBD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC3C,MAAM,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,EACpC,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,0BAA0B,GAC/C,OAAO,CAAC,MAAM,MAAM,CAAC,CAsBvB"}
1
+ {"version":3,"file":"rotating-jwt-provider.d.ts","sourceRoot":"","sources":["../../src/auth/rotating-jwt-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,MAAM,WAAW,cAAc;IAC3B,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC9D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAClE;AAED;;iFAEiF;AACjF,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACvC;AAED;;kEAEkE;AAClE,eAAO,MAAM,uBAAuB,QAAS,CAAA;AAE7C,MAAM,WAAW,0BAA0B;IACvC;;mEAE+D;IAC/D,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,cAAc,CAAA;IACnB;;;qCAGiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;CACrB;AA+CD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC3C,MAAM,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,EACpC,EAAE,SAAS,EAAE,GAAG,EAAE,SAAmC,EAAE,EAAE,0BAA0B,GACpF,OAAO,CAAC,MAAM,MAAM,CAAC,CAsBvB"}
@@ -24,10 +24,50 @@
24
24
  * error only) rather than an import of that type — `sdk` has no dependency on
25
25
  * `@beacon-build/logger` today, and every caller's real logger already satisfies this
26
26
  * shape, so no new dependency edge is needed for typing either.
27
+ *
28
+ * B710: an MCP server calls `createServices()` (→ this boot mint) from INSIDE its
29
+ * `register()` step, which `startMcpServer` (`@beacon-build/mcp-core/bootstrap`) always
30
+ * `await`s BEFORE `server.connect(transport)` — the point at which the process can answer
31
+ * the client's `initialize`/`tools/list` handshake at all. Before this fix, `mintAtBoot`
32
+ * awaited `mintFn()` with NO bound: a slow or hung network call (the API/local daemon
33
+ * still booting, e.g. racing a Claude Desktop restart) blocked `register()` — and so
34
+ * `connect()` — for as long as the network stayed unresponsive, with nothing in our own
35
+ * logs to explain why. Observed live: the MCP client's own readiness gate ("Not ready
36
+ * after 60 seconds; the sessions waiting for it started without it") reporting the server
37
+ * disconnected. `timeoutMs` (default `DEFAULT_MINT_TIMEOUT_MS`) bounds every mint call so a
38
+ * hang becomes the SAME loud, fast, already-tested fail-fast/keep-current behavior instead
39
+ * of an unbounded wait — the boot mint fails within a fixed, predictable window well short
40
+ * of a 60s external readiness gate, and a stalled scheduled refresh no longer holds its
41
+ * timer callback open indefinitely either.
42
+ */
43
+ /** B710: default bound on a single mint call (boot or scheduled refresh) — well short of
44
+ * the 60s external MCP-client readiness gate observed live, leaving headroom for the rest
45
+ * of `register()`/`connect()` to run inside that same window. */
46
+ export const DEFAULT_MINT_TIMEOUT_MS = 30_000;
47
+ /**
48
+ * B710: race `mintFn()` against a timer so a hung network call can never block its caller
49
+ * past `timeoutMs`. The timer is cleared on either outcome (settle-first wins) and never
50
+ * holds the event loop open (`unref()`) — this is a bound on OUR wait, not a cancellation
51
+ * of the underlying call.
27
52
  */
28
- async function mintAtBoot(mintFn, log) {
53
+ function withMintTimeout(mintFn, timeoutMs) {
54
+ return new Promise((resolve, reject) => {
55
+ const timer = setTimeout(() => {
56
+ reject(new Error(`JWT mint timed out after ${timeoutMs}ms`));
57
+ }, timeoutMs);
58
+ timer.unref();
59
+ mintFn().then((result) => {
60
+ clearTimeout(timer);
61
+ resolve(result);
62
+ }, (err) => {
63
+ clearTimeout(timer);
64
+ reject(err);
65
+ });
66
+ });
67
+ }
68
+ async function mintAtBoot(mintFn, log, timeoutMs) {
29
69
  try {
30
- const { token, logContext } = await mintFn();
70
+ const { token, logContext } = await withMintTimeout(mintFn, timeoutMs);
31
71
  log.info('minted rotating JWT at boot', logContext);
32
72
  return token;
33
73
  }
@@ -43,12 +83,12 @@ async function mintAtBoot(mintFn, log) {
43
83
  * token rotating for the life of a long-running daemon on an unref'd timer. Returns a
44
84
  * PROVIDER — re-read per request — never a captured string.
45
85
  */
46
- export async function createRotatingJwtProvider(mintFn, { refreshMs, log }) {
47
- let current = await mintAtBoot(mintFn, log);
86
+ export async function createRotatingJwtProvider(mintFn, { refreshMs, log, timeoutMs = DEFAULT_MINT_TIMEOUT_MS }) {
87
+ let current = await mintAtBoot(mintFn, log, timeoutMs);
48
88
  const timer = setInterval(() => {
49
89
  void (async () => {
50
90
  try {
51
- const { token, logContext } = await mintFn();
91
+ const { token, logContext } = await withMintTimeout(mintFn, timeoutMs);
52
92
  current = token;
53
93
  log.info('refreshed rotating JWT (scheduled)', logContext);
54
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"rotating-jwt-provider.js","sourceRoot":"","sources":["../../src/auth/rotating-jwt-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAuBH,KAAK,UAAU,UAAU,CACrB,MAAoC,EACpC,GAAmB;IAEnB,IAAI,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,EAAE,CAAA;QAC5C,GAAG,CAAC,IAAI,CAAC,6BAA6B,EAAE,UAAU,CAAC,CAAA;QACnD,OAAO,KAAK,CAAA;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,GAAG,CAAC,KAAK,CAAC,+BAA+B,EAAE;YACvC,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SAC1D,CAAC,CAAA;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC3C,MAAoC,EACpC,EAAE,SAAS,EAAE,GAAG,EAA8B;IAE9C,IAAI,OAAO,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAE3C,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QAC3B,KAAK,CAAC,KAAK,IAAI,EAAE;YACb,IAAI,CAAC;gBACD,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,EAAE,CAAA;gBAC5C,OAAO,GAAG,KAAK,CAAA;gBACf,GAAG,CAAC,IAAI,CAAC,oCAAoC,EAAE,UAAU,CAAC,CAAA;YAC9D,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACX,uEAAuE;gBACvE,0EAA0E;gBAC1E,mDAAmD;gBACnD,GAAG,CAAC,KAAK,CAAC,+CAA+C,EAAE;oBACvD,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBAC1D,CAAC,CAAA;YACN,CAAC;QACL,CAAC,CAAC,EAAE,CAAA;IACR,CAAC,EAAE,SAAS,CAAC,CAAA;IACb,KAAK,CAAC,KAAK,EAAE,CAAA;IAEb,OAAO,GAAG,EAAE,CAAC,OAAO,CAAA;AACxB,CAAC"}
1
+ {"version":3,"file":"rotating-jwt-provider.js","sourceRoot":"","sources":["../../src/auth/rotating-jwt-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAeH;;kEAEkE;AAClE,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAA;AAe7C;;;;;GAKG;AACH,SAAS,eAAe,CACpB,MAAoC,EACpC,SAAiB;IAEjB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC1B,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,SAAS,IAAI,CAAC,CAAC,CAAA;QAChE,CAAC,EAAE,SAAS,CAAC,CAAA;QACb,KAAK,CAAC,KAAK,EAAE,CAAA;QACb,MAAM,EAAE,CAAC,IAAI,CACT,CAAC,MAAM,EAAE,EAAE;YACP,YAAY,CAAC,KAAK,CAAC,CAAA;YACnB,OAAO,CAAC,MAAM,CAAC,CAAA;QACnB,CAAC,EACD,CAAC,GAAG,EAAE,EAAE;YACJ,YAAY,CAAC,KAAK,CAAC,CAAA;YACnB,MAAM,CAAC,GAAG,CAAC,CAAA;QACf,CAAC,CACJ,CAAA;IACL,CAAC,CAAC,CAAA;AACN,CAAC;AAED,KAAK,UAAU,UAAU,CACrB,MAAoC,EACpC,GAAmB,EACnB,SAAiB;IAEjB,IAAI,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;QACtE,GAAG,CAAC,IAAI,CAAC,6BAA6B,EAAE,UAAU,CAAC,CAAA;QACnD,OAAO,KAAK,CAAA;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,GAAG,CAAC,KAAK,CAAC,+BAA+B,EAAE;YACvC,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SAC1D,CAAC,CAAA;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC3C,MAAoC,EACpC,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,uBAAuB,EAA8B;IAEnF,IAAI,OAAO,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,CAAC,CAAA;IAEtD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QAC3B,KAAK,CAAC,KAAK,IAAI,EAAE;YACb,IAAI,CAAC;gBACD,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;gBACtE,OAAO,GAAG,KAAK,CAAA;gBACf,GAAG,CAAC,IAAI,CAAC,oCAAoC,EAAE,UAAU,CAAC,CAAA;YAC9D,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACX,uEAAuE;gBACvE,0EAA0E;gBAC1E,mDAAmD;gBACnD,GAAG,CAAC,KAAK,CAAC,+CAA+C,EAAE;oBACvD,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBAC1D,CAAC,CAAA;YACN,CAAC;QACL,CAAC,CAAC,EAAE,CAAA;IACR,CAAC,EAAE,SAAS,CAAC,CAAA;IACb,KAAK,CAAC,KAAK,EAAE,CAAA;IAEb,OAAO,GAAG,EAAE,CAAC,OAAO,CAAA;AACxB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beacon-build/sdk",
3
- "version": "1.49.6",
3
+ "version": "1.49.8",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -26,7 +26,7 @@
26
26
  "@types/react": "^19.2.0",
27
27
  "@types/react-dom": "^19.2.0",
28
28
  "event-source-polyfill": "^1.0.31",
29
- "@beacon-build/core": "1.49.6"
29
+ "@beacon-build/core": "1.49.8"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@testing-library/react": "^16.3.2",