stitchkit 0.1.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 (84) hide show
  1. package/README.md +10 -7
  2. package/dist/browser/http.d.ts +5 -0
  3. package/dist/browser/http.d.ts.map +1 -1
  4. package/dist/contract/define.d.ts.map +1 -1
  5. package/dist/contract/errors.d.ts +4 -3
  6. package/dist/contract/errors.d.ts.map +1 -1
  7. package/dist/contract/index.js +1 -1
  8. package/dist/{index-gfzn1n4n.js → index-0t460v7k.js} +13 -5
  9. package/dist/{index-n7bmdwmz.js → index-4b1j82gp.js} +8 -4
  10. package/dist/{index-5sxnvwb1.js → index-4kz3aqpx.js} +2 -2
  11. package/dist/index-dpj1jcys.js +677 -0
  12. package/dist/{index-7wfkbvss.js → index-kckky6zw.js} +6 -2
  13. package/dist/index-kzfs85xp.js +9 -0
  14. package/dist/index-mwmpw6j1.js +60 -0
  15. package/dist/index-q6ja2qwq.js +7 -0
  16. package/dist/index.js +4 -3
  17. package/dist/internal/errors.d.ts +13 -1
  18. package/dist/internal/errors.d.ts.map +1 -1
  19. package/dist/internal/safe-json.d.ts +19 -0
  20. package/dist/internal/safe-json.d.ts.map +1 -0
  21. package/dist/internal/within-dir.d.ts +7 -0
  22. package/dist/internal/within-dir.d.ts.map +1 -0
  23. package/dist/node.d.ts +4 -0
  24. package/dist/node.d.ts.map +1 -0
  25. package/dist/node.js +29 -0
  26. package/dist/observability/context.d.ts +9 -1
  27. package/dist/observability/context.d.ts.map +1 -1
  28. package/dist/observability/index.js +35 -15
  29. package/dist/observability/sanitize.d.ts.map +1 -1
  30. package/dist/server/context.d.ts +3 -2
  31. package/dist/server/context.d.ts.map +1 -1
  32. package/dist/server/create.d.ts +3 -3
  33. package/dist/server/create.d.ts.map +1 -1
  34. package/dist/server/event-bus.d.ts +10 -1
  35. package/dist/server/event-bus.d.ts.map +1 -1
  36. package/dist/server/index.d.ts +2 -2
  37. package/dist/server/index.d.ts.map +1 -1
  38. package/dist/server/index.js +94 -606
  39. package/dist/server/logger.d.ts +5 -4
  40. package/dist/server/logger.d.ts.map +1 -1
  41. package/dist/server/middleware/auth.d.ts +24 -1
  42. package/dist/server/middleware/auth.d.ts.map +1 -1
  43. package/dist/server/middleware/cookies.d.ts.map +1 -1
  44. package/dist/server/middleware/cors.d.ts +7 -0
  45. package/dist/server/middleware/cors.d.ts.map +1 -1
  46. package/dist/server/multipart.d.ts +2 -1
  47. package/dist/server/multipart.d.ts.map +1 -1
  48. package/dist/server/node.d.ts +12 -0
  49. package/dist/server/node.d.ts.map +1 -0
  50. package/dist/server/rate-limit.d.ts +7 -2
  51. package/dist/server/rate-limit.d.ts.map +1 -1
  52. package/dist/server/request.d.ts +27 -4
  53. package/dist/server/request.d.ts.map +1 -1
  54. package/dist/server/router.d.ts +4 -2
  55. package/dist/server/router.d.ts.map +1 -1
  56. package/dist/server/stream.d.ts +3 -1
  57. package/dist/server/stream.d.ts.map +1 -1
  58. package/dist/server/types.d.ts +35 -20
  59. package/dist/server/types.d.ts.map +1 -1
  60. package/dist/tools/agent.d.ts +15 -2
  61. package/dist/tools/agent.d.ts.map +1 -1
  62. package/dist/tools/coerce.d.ts +12 -0
  63. package/dist/tools/coerce.d.ts.map +1 -0
  64. package/dist/tools/execute.d.ts +26 -2
  65. package/dist/tools/execute.d.ts.map +1 -1
  66. package/dist/tools/flatten.d.ts +15 -0
  67. package/dist/tools/flatten.d.ts.map +1 -0
  68. package/dist/tools/json-schema.d.ts +18 -0
  69. package/dist/tools/json-schema.d.ts.map +1 -0
  70. package/dist/tools/manifest.d.ts +17 -0
  71. package/dist/tools/manifest.d.ts.map +1 -0
  72. package/dist/tools/mcp-handler.d.ts.map +1 -1
  73. package/dist/tools/mcp.d.ts +53 -3
  74. package/dist/tools/mcp.d.ts.map +1 -1
  75. package/dist/tools/mount.d.ts +18 -6
  76. package/dist/tools/mount.d.ts.map +1 -1
  77. package/dist/tools/schema.d.ts +19 -2
  78. package/dist/tools/schema.d.ts.map +1 -1
  79. package/dist/tools/view-file.d.ts.map +1 -1
  80. package/dist/tools.d.ts +6 -2
  81. package/dist/tools.d.ts.map +1 -1
  82. package/dist/tools.js +415 -185
  83. package/package.json +15 -4
  84. package/dist/index-ke4mx4ea.js +0 -38
@@ -1,4 +1,5 @@
1
- export declare function elapsedMs(startTime: bigint): number;
1
+ /** Elapsed milliseconds since a `performance.now()` mark. */
2
+ export declare function elapsedMs(startTime: number): number;
2
3
  /** Map an HTTP status to a log level. */
3
4
  export declare function levelForStatus(status: number): 'error' | 'warn' | 'info';
4
5
  /** The structured fields shared by every completed-request log line. */
@@ -11,11 +12,11 @@ export declare function buildLogFields(method: string, path: string, status: num
11
12
  };
12
13
  export interface RequestLog {
13
14
  traceId: string;
14
- startTime: bigint;
15
+ startTime: number;
15
16
  }
16
17
  export declare function shouldLog(pathname: string, method: string): boolean;
17
18
  /** Open the timing window for a request. Development prints a `→` line. */
18
- export declare function logIncoming(req: Request, pathname: string, traceId: string): RequestLog;
19
+ export declare function logIncoming(req: Request, pathname: string, traceId: string, ipAddress?: string): RequestLog;
19
20
  /** Close a request. Development: `←` line. Production: one structured JSON line. */
20
- export declare function logOutgoing(req: Request, pathname: string, status: number, log: RequestLog): void;
21
+ export declare function logOutgoing(req: Request, pathname: string, status: number, log: RequestLog, ipAddress?: string): void;
21
22
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/server/logger.ts"],"names":[],"mappings":"AA0CA,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,yCAAyC;AACzC,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAIxE;AAED,wEAAwE;AACxE,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAEvF;AA0BD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAGnE;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CASvF;AAED,oFAAoF;AACpF,wBAAgB,WAAW,CACzB,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,UAAU,GACd,IAAI,CAoBN"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/server/logger.ts"],"names":[],"mappings":"AAwCA,6DAA6D;AAC7D,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnD;AAQD,yCAAyC;AACzC,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAIxE;AAED,wEAAwE;AACxE,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAEvF;AA0BD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAGnE;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CACzB,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,UAAU,CASZ;AAED,oFAAoF;AACpF,wBAAgB,WAAW,CACzB,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,UAAU,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,IAAI,CAoBN"}
@@ -3,7 +3,16 @@ import type { MethodDef } from '../types';
3
3
  export interface JwtPayload {
4
4
  [key: string]: unknown;
5
5
  }
6
- export declare function verifyJwt(token: string, secret: string): Promise<JwtPayload>;
6
+ /** Tuning for `verifyJwt`. */
7
+ export interface VerifyJwtOptions {
8
+ /** Clock-skew tolerance for `exp` / `nbf`, in seconds. Default `60`. */
9
+ leewaySeconds?: number;
10
+ /** Required `iss` claim — the token is rejected on mismatch. */
11
+ issuer?: string;
12
+ /** Required `aud` claim — the token is rejected if it does not carry it. */
13
+ audience?: string;
14
+ }
15
+ export declare function verifyJwt(token: string, secret: string, options?: VerifyJwtOptions): Promise<JwtPayload>;
7
16
  export declare function extractToken(req: Request, cookieName?: string): string | null;
8
17
  /**
9
18
  * Per-scope access predicate. `endpoint.scope` selects which rule applies:
@@ -17,6 +26,14 @@ export type AuthRule<TIdentity> = 'public' | 'authenticated' | ((identity: Await
17
26
  export interface AuthHookConfig<TIdentity> {
18
27
  /** Resolve the request identity — cookie / bearer + DB lookup. */
19
28
  resolve: (ctx: RuntimeContext) => Promise<TIdentity | null>;
29
+ /**
30
+ * Resolve identity on a non-HTTP context (a tool call) where there is no
31
+ * `req`. The transport (MCP / agent) has already authenticated the caller;
32
+ * this locates the identity it injected into `ctx` (via `buildMcpServer`'s
33
+ * `context`). Without it, a scoped tool call with no `req` **fails closed**
34
+ * — the scope rule sees no identity and `onAnonymous` rejects the call.
35
+ */
36
+ resolveFromContext?: (ctx: RuntimeContext) => TIdentity | null | Promise<TIdentity | null>;
20
37
  /** Access rule per scope; `endpoint.scope` is the key. */
21
38
  rules: Record<string, AuthRule<TIdentity>>;
22
39
  /** Scope applied when an endpoint declares none. */
@@ -35,6 +52,12 @@ export type AuthHook = (ctx: RuntimeContext, endpoint: MethodDef) => Promise<voi
35
52
  * Identity resolution and the scope vocabulary stay in the project; the
36
53
  * project annotates its `rules` object with `satisfies Record<MyScope, …>` to
37
54
  * keep scope coverage exhaustive.
55
+ *
56
+ * The hook runs on both surfaces: as `createServer`'s `beforeHandle` (HTTP) and
57
+ * as a tool mount's `lifecycle.beforeHandle` (MCP / agent). On HTTP it resolves
58
+ * identity from `ctx.req` via `resolve`; on a tool call — where there is no
59
+ * `req` — it uses `resolveFromContext`. If `resolveFromContext` is omitted, a
60
+ * scoped tool call has no identity and **fails closed** (never silently passes).
38
61
  */
39
62
  export declare function createAuthHook<TIdentity>(config: AuthHookConfig<TIdentity>): AuthHook;
40
63
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/server/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG1C,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AASD,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA4ClF;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU7E;AAUD;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,CAAC,SAAS,IAC1B,QAAQ,GACR,eAAe,GACf,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,cAAc,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;AAExF,MAAM,WAAW,cAAc,CAAC,SAAS;IACvC,kEAAkE;IAClE,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC5D,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3C,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5E,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,KAAK,CAAC;IAC1B,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,KAAK,CAAC;CAC3B;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,CAAC,SAAS,CAAC,GAAG,QAAQ,CAuBrF;AAID;;;;GAIG;AACH,MAAM,WAAW,oBAAoB,CAAC,SAAS;IAC7C,4EAA4E;IAC5E,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;CACpE;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAC5C,MAAM,EAAE,oBAAoB,CAAC,SAAS,CAAC,GACtC,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAM7C"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/server/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAIrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG1C,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,8BAA8B;AAC9B,MAAM,WAAW,gBAAgB;IAC/B,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAiBD,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,UAAU,CAAC,CAgErB;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU7E;AAUD;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,CAAC,SAAS,IAC1B,QAAQ,GACR,eAAe,GACf,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,cAAc,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;AAExF,MAAM,WAAW,cAAc,CAAC,SAAS;IACvC,kEAAkE;IAClE,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC5D;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC3F,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3C,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5E,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,KAAK,CAAC;IAC1B,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,KAAK,CAAC;CAC3B;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnF;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,CAAC,SAAS,CAAC,GAAG,QAAQ,CAgCrF;AAID;;;;GAIG;AACH,MAAM,WAAW,oBAAoB,CAAC,SAAS;IAC7C,4EAA4E;IAC5E,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;CACpE;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAC5C,MAAM,EAAE,oBAAoB,CAAC,SAAS,CAAC,GACtC,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAM7C"}
@@ -1 +1 @@
1
- {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../../src/server/middleware/cookies.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAc1E;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;CACtC;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,aAAkB,GACvB,MAAM,CASR;AAED,4EAA4E;AAC5E,MAAM,WAAW,SAAS;IACxB,uEAAuE;IACvE,GAAG,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IACtC,+EAA+E;IAC/E,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,gEAAgE;IAChE,KAAK,IAAI,MAAM,CAAC;CACjB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAahF"}
1
+ {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../../src/server/middleware/cookies.ts"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkB1E;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;CACtC;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,aAAkB,GACvB,MAAM,CASR;AAED,4EAA4E;AAC5E,MAAM,WAAW,SAAS;IACxB,uEAAuE;IACvE,GAAG,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IACtC,+EAA+E;IAC/E,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,gEAAgE;IAChE,KAAK,IAAI,MAAM,CAAC;CACjB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAahF"}
@@ -4,6 +4,13 @@ export interface CorsConfig {
4
4
  methods?: string;
5
5
  headers?: string;
6
6
  }
7
+ /**
8
+ * Reject an unsafe CORS config at construction. `credentials: true` with a
9
+ * wildcard origin would reflect *any* caller's `Origin` with
10
+ * `Allow-Credentials: true` — every site could make authenticated cross-origin
11
+ * requests. Credentials require an explicit origin allow-list.
12
+ */
13
+ export declare function assertCorsConfig(config: CorsConfig): void;
7
14
  export declare function corsHeaders(config: CorsConfig, requestOrigin?: string | null): Record<string, string>;
8
15
  export declare function corsPreflightResponse(config: CorsConfig, req: Request): Response;
9
16
  //# sourceMappingURL=cors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../../src/server/middleware/cors.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,UAAU,EAClB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAC5B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmCxB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,GAAG,QAAQ,CAKhF"}
1
+ {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../../src/server/middleware/cors.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAOzD;AAoBD,wBAAgB,WAAW,CACzB,MAAM,EAAE,UAAU,EAClB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAC5B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAsBxB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,GAAG,QAAQ,CAKhF"}
@@ -2,7 +2,8 @@ import type { ZodType } from 'zod';
2
2
  /** A parsed multipart request — the uploaded `file` and the validated `fields`. */
3
3
  export interface MultipartResult {
4
4
  file: File;
5
- fields: Record<string, unknown>;
5
+ /** Validated when a `fieldsSchema` was given, else the raw decoded fields. */
6
+ fields: unknown;
6
7
  }
7
8
  /**
8
9
  * Parse a `multipart/form-data` request — extract the file at `fileField` and
@@ -1 +1 @@
1
- {"version":3,"file":"multipart.d.ts","sourceRoot":"","sources":["../../src/server/multipart.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAGnC,mFAAmF;AACnF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAKD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,EAC/B,QAAQ,SAA2B,GAClC,OAAO,CAAC,eAAe,CAAC,CAkC1B"}
1
+ {"version":3,"file":"multipart.d.ts","sourceRoot":"","sources":["../../src/server/multipart.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAInC,mFAAmF;AACnF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,IAAI,CAAC;IACX,8EAA8E;IAC9E,MAAM,EAAE,OAAO,CAAC;CACjB;AA0CD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,EAC/B,QAAQ,SAA2B,GAClC,OAAO,CAAC,eAAe,CAAC,CA6B1B"}
@@ -0,0 +1,12 @@
1
+ import type { HandlerConfig } from './types';
2
+ export interface NodeServerConfig extends HandlerConfig {
3
+ port?: number;
4
+ hostname?: string;
5
+ }
6
+ export interface NodeServerHandle {
7
+ url: string;
8
+ port: number;
9
+ close(closeActive?: boolean): Promise<void>;
10
+ }
11
+ export declare function serveNode(config: NodeServerConfig): Promise<NodeServerHandle>;
12
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/server/node.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAgBnF"}
@@ -6,8 +6,13 @@ export interface RateLimitConfig {
6
6
  /**
7
7
  * In-memory token-bucket rate limiter. `check(key, config)` consumes a token
8
8
  * and returns whether the request is allowed; `remaining(key, config)` reports
9
- * the count without consuming. Idle keys are swept on a 60-second timer;
10
- * `destroy()` stops it.
9
+ * the count without consuming. Idle keys are swept on a 60-second timer and the
10
+ * map is capped at `MAX_BUCKETS` (least-recently-used eviction); `destroy()`
11
+ * stops the timer.
12
+ *
13
+ * `config` is per-call — reusing one `key` with two different configs lets
14
+ * whichever call created the bucket fix its `max` / `window`. Key a bucket to
15
+ * one config (one limiter per limit) if that matters.
11
16
  */
12
17
  export declare function createRateLimiter(): {
13
18
  destroy: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/server/rate-limit.ts"],"names":[],"mappings":"AAOA,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AASD;;;;;GAKG;AACH,wBAAgB,iBAAiB;;eAQlB,MAAM,UAAU,eAAe,GAAG,OAAO;mBAiBrC,MAAM,UAAU,eAAe,GAAG,MAAM;EAO1D"}
1
+ {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/server/rate-limit.ts"],"names":[],"mappings":"AAOA,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAeD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB;;eAQlB,MAAM,UAAU,eAAe,GAAG,OAAO;mBA6BrC,MAAM,UAAU,eAAe,GAAG,MAAM;EAO1D"}
@@ -2,7 +2,7 @@
2
2
  * HTTP request helpers — header parsing, client identification, trace ids.
3
3
  * Pure `Request → value` functions; no framework state.
4
4
  */
5
- /** Compact, time-sortable id — base36 timestamp + base36 random, ~14 chars. */
5
+ /** Compact, time-sortable id — base36 timestamp + a cryptographic suffix. */
6
6
  export declare function generateTraceId(): string;
7
7
  /**
8
8
  * Trace id for a request: a trusted inbound `x-request-id` / `x-trace-id`
@@ -10,10 +10,33 @@ export declare function generateTraceId(): string;
10
10
  * Shared by the router, the logger and any consumer that wants the same id.
11
11
  */
12
12
  export declare function resolveTraceId(req: Request): string;
13
- /** Client IP from `x-forwarded-for` / `x-real-ip` (IPv4-mapped prefix stripped). */
14
- export declare function extractIp(req: Request): string;
13
+ /**
14
+ * Resolve the real socket peer IP from the runtime — unspoofable, unlike a
15
+ * header. On Bun the server resolves it (`server.requestIP`); on Node / Deno
16
+ * the `srvx` adapter attaches `.ip` to the request. `undefined` when neither
17
+ * is available (the bare `createHandler` fetch with no server).
18
+ */
19
+ export declare function resolveSocketIp(req: Request, server: unknown): string | undefined;
20
+ /** Options for `extractIp` / `getClientInfo`. */
21
+ export interface ClientIpOptions {
22
+ /**
23
+ * Trust `x-forwarded-for` / `x-real-ip` for the client IP. Enable only behind
24
+ * a proxy that overwrites them — they are client-controllable. Default
25
+ * `false`: the real socket IP (`socketIp`) is used instead.
26
+ */
27
+ trustProxy?: boolean;
28
+ /** The real socket peer IP — see `resolveSocketIp`. */
29
+ socketIp?: string;
30
+ }
31
+ /**
32
+ * The client IP for a request. With `trustProxy`, the `x-forwarded-for` /
33
+ * `x-real-ip` client wins (the server sits behind a proxy that rewrites them);
34
+ * otherwise the real, unspoofable socket peer (`socketIp`) is used. Returns
35
+ * `''` when nothing is known.
36
+ */
37
+ export declare function extractIp(req: Request, options?: ClientIpOptions): string;
15
38
  /** Client identity — IP + user-agent. The one place projects derive both. */
16
- export declare function getClientInfo(req: Request): {
39
+ export declare function getClientInfo(req: Request, options?: ClientIpOptions): {
17
40
  ipAddress?: string;
18
41
  userAgent?: string;
19
42
  };
@@ -1 +1 @@
1
- {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/server/request.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,+EAA+E;AAC/E,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CASnD;AAED,oFAAoF;AACpF,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAM9C;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAKA;AAED,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAQ5E"}
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/server/request.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,6EAA6E;AAC7E,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CASnD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAejF;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,CAQ7E;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAC3B,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE,eAAoB,GAC5B;IACD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAKA;AAED,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAU5E"}
@@ -34,8 +34,10 @@ export declare function matchRawRoute(rawRoutes: RawRoute[], httpMethod: string,
34
34
  params: Record<string, string>;
35
35
  } | null;
36
36
  /**
37
- * Build a `RawRoute` that serves files from `dir` under `prefix`.
38
- * Rejects path traversal (`..`); 404 for a missing file.
37
+ * Build a `RawRoute` that serves files from `dir` under `prefix`. Basic by
38
+ * design — no Range, no conditional requests; put a CDN in front for those.
39
+ * Rejects path traversal (including the percent-encoded form); 404 for a
40
+ * missing file. Uses `node:fs`, so it runs on both Bun and Node.
39
41
  */
40
42
  export declare function staticRoute(prefix: string, dir: string): RawRoute;
41
43
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE/E,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,UAAU,CAAC;IACpB,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB;AAED,UAAU,UAAU;IAClB,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAED,+EAA+E;AAC/E,MAAM,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAqCD,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,QAAQ,CAmCjE;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,UAAU,GAAG,IAAI,CAmBnB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAc7E;AAED,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAiBvD;AAID,wBAAgB,aAAa,CAC3B,SAAS,EAAE,QAAQ,EAAE,EACrB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,CAyB5D;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,CAuBjE"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE/E,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,UAAU,CAAC;IACpB,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB;AAED,UAAU,UAAU;IAClB,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAED,+EAA+E;AAC/E,MAAM,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAqCD,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,QAAQ,CAmCjE;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,UAAU,GAAG,IAAI,CAmBnB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAc7E;AAED,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAiBvD;AAID,wBAAgB,aAAa,CAC3B,SAAS,EAAE,QAAQ,EAAE,EACrB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,CAyB5D;AAoBD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,CAmCjE"}
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * Turn an async generator into a Server-Sent Events `Response` — each yielded
3
3
  * value is one JSON `data:` event, the stream ends with a `[DONE]` sentinel,
4
- * and a thrown error is emitted as a final `{ error }` event.
4
+ * and a thrown error is emitted as a final error event. The error is
5
+ * normalised (`normalizeError`) so an internal failure never leaks its raw
6
+ * message into the stream.
5
7
  */
6
8
  export declare function streamSSE(generator: AsyncGenerator<unknown>): Response;
7
9
  /** Options for `parseSSE`. */
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/server/stream.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,QAAQ,CA2BtE;AAED,8BAA8B;AAC9B,MAAM,WAAW,eAAe;IAC9B,sFAAsF;IACtF,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACpD;AAED;;;;GAIG;AACH,wBAAuB,QAAQ,CAAC,CAAC,EAC/B,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,eAAe,GACxB,cAAc,CAAC,CAAC,CAAC,CAkCnB"}
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/server/stream.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,QAAQ,CA2BtE;AAED,8BAA8B;AAC9B,MAAM,WAAW,eAAe;IAC9B,sFAAsF;IACtF,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACpD;AAED;;;;GAIG;AACH,wBAAuB,QAAQ,CAAC,CAAC,EAC/B,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,eAAe,GACxB,cAAc,CAAC,CAAC,CAAC,CAmCnB"}
@@ -61,6 +61,11 @@ export interface RawRouteContext {
61
61
  * Absent when the handler runs via the bare `createHandler` fetch.
62
62
  */
63
63
  server?: BunServer;
64
+ /**
65
+ * Client IP — the real socket peer, or the `x-forwarded-for` client when
66
+ * `trustProxy` is set. Resolved by the framework; never spoofable by default.
67
+ */
68
+ ipAddress?: string;
64
69
  }
65
70
  export interface RawRoute {
66
71
  method: HttpMethod | 'ALL';
@@ -73,40 +78,50 @@ export interface RawRoute {
73
78
  */
74
79
  handler: (req: Request, ctx: RawRouteContext) => Response | Promise<Response>;
75
80
  }
76
- type BunServeOptions = Parameters<typeof Bun.serve>[0];
77
- type BunWebSocketHandlers = BunServeOptions extends {
78
- websocket?: infer T;
79
- } ? T : never;
80
- type BunRoutes = BunServeOptions extends {
81
- routes?: infer T;
82
- } ? T : never;
83
- type BunDevelopmentOptions = BunServeOptions extends {
84
- development?: infer T;
85
- } ? T : never;
86
- export type ServerPassthrough = Omit<BunServeOptions, 'fetch' | 'port' | 'hostname' | 'unix' | 'routes' | 'websocket' | 'development'>;
87
81
  export interface StitchLogger {
88
82
  info(msg: string, data?: Record<string, unknown>): void;
89
83
  warn(msg: string, data?: Record<string, unknown>): void;
90
84
  error(msg: string, data?: Record<string, unknown>): void;
91
85
  debug(msg: string, data?: Record<string, unknown>): void;
92
86
  }
93
- export interface ServerConfig {
87
+ /**
88
+ * Runtime-neutral handler config — everything `createHandler` needs.
89
+ * No Bun globals, no Bun types. This is the portability seam.
90
+ */
91
+ export interface HandlerConfig {
94
92
  services?: ServiceDef[];
95
93
  groups?: RouteGroup[];
96
- /** Non-contract routes — auth, webhooks, static, socket.io. */
97
94
  rawRoutes?: RawRoute[];
98
- port?: number;
99
- hostname?: string;
100
95
  cors?: CorsConfig;
101
96
  hooks?: LifecycleHooks;
102
97
  logging?: boolean | StitchLogger;
98
+ traceId?: (req: Request) => string;
103
99
  /**
104
- * Resolve the per-request trace id. Default: a trusted `x-request-id` /
105
- * `x-trace-id` header, else a generated id. Override to reuse an id the
106
- * project already owns (e.g. an `AsyncLocalStorage` request context) so
107
- * request logs and application logs share one id.
100
+ * Trust the `x-forwarded-for` / `x-real-ip` headers for the client IP.
101
+ * These are client-controllable — enable only when the server runs behind a
102
+ * proxy that overwrites them. Default `false`: the IP a spoofable header
103
+ * carries never reaches `ctx.ipAddress`, a rate-limit key or an audit row.
108
104
  */
109
- traceId?: (req: Request) => string;
105
+ trustProxy?: boolean;
106
+ }
107
+ type BunServeOptions = Parameters<typeof Bun.serve>[0];
108
+ type BunWebSocketHandlers = BunServeOptions extends {
109
+ websocket?: infer T;
110
+ } ? T : never;
111
+ type BunRoutes = BunServeOptions extends {
112
+ routes?: infer T;
113
+ } ? T : never;
114
+ type BunDevelopmentOptions = BunServeOptions extends {
115
+ development?: infer T;
116
+ } ? T : never;
117
+ export type ServerPassthrough = Omit<BunServeOptions, 'fetch' | 'port' | 'hostname' | 'unix' | 'routes' | 'websocket' | 'development'>;
118
+ /**
119
+ * Full config for `createServer` — extends `HandlerConfig` with Bun-specific
120
+ * options (`Bun.serve` routes, websocket, development, passthrough).
121
+ */
122
+ export interface BunServerConfig extends HandlerConfig {
123
+ port?: number;
124
+ hostname?: string;
110
125
  routes?: BunRoutes;
111
126
  websocket?: BunWebSocketHandlers;
112
127
  development?: BunDevelopmentOptions;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,27 @@
1
1
  import type { ToolSet } from 'ai';
2
2
  import type { ServiceDef } from '../server/types';
3
- import type { ToolCallHooks } from './execute';
3
+ import { type ToolCallHooks, type ToolLifecycle } from './execute';
4
4
  import { type ToolExtend } from './mount';
5
5
  export interface AgentContext {
6
6
  [key: string]: unknown;
7
7
  }
8
8
  export interface AgentMountConfig {
9
9
  context?: AgentContext;
10
+ /** Tool-call observability hooks. */
10
11
  hooks?: ToolCallHooks;
12
+ /**
13
+ * Auth / scope gate and result transform for every tool call — the tool-side
14
+ * twin of `createServer`'s `beforeHandle` / `afterHandle`. Without it an
15
+ * agent tool call bypasses the auth a `createServer` `beforeHandle` enforces.
16
+ */
17
+ lifecycle?: ToolLifecycle;
11
18
  extend?: ToolExtend;
19
+ /** Coerce JSON-stringified arrays/objects in tool arguments. Default: true. */
20
+ coerceJsonArgs?: boolean;
21
+ /** Flatten discriminated union inputs into a single object. Default: false. */
22
+ flattenUnionInput?: boolean;
23
+ /** Global error hint injected into every failed tool result. */
24
+ errorHint?: (toolName: string, errorCode: string) => string | null;
12
25
  }
13
- export declare function mountAgent(service: ServiceDef, config?: AgentMountConfig): ToolSet;
26
+ export declare function mountAgent(services: ServiceDef | ServiceDef[], config?: AgentMountConfig): ToolSet;
14
27
  //# sourceMappingURL=agent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/tools/agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAGlC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAmD,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAM3F,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,GAAE,gBAAqB,GAAG,OAAO,CA0BtF"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/tools/agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAGlC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAuB,MAAM,WAAW,CAAC;AACxF,OAAO,EAAmD,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAE3F,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,qCAAqC;IACrC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB;;;;OAIG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,+EAA+E;IAC/E,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gEAAgE;IAChE,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACpE;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,UAAU,GAAG,UAAU,EAAE,EACnC,MAAM,GAAE,gBAAqB,GAC5B,OAAO,CAyCT"}
@@ -0,0 +1,12 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Coerce JSON-stringified array/object arguments — an LLM sometimes
4
+ * double-serializes a nested value (sends `"[1,2]"` instead of `[1,2]`).
5
+ *
6
+ * Only fields the schema declares as an array/object are touched, and only
7
+ * when the incoming value is a string. The transform operates on the
8
+ * **arguments**, never the schema — so the advertised tool schema stays
9
+ * exactly the contract schema (correct types, correct `required`).
10
+ */
11
+ export declare function coerceJsonArgs(args: Record<string, unknown>, schema: z.ZodType | undefined): Record<string, unknown>;
12
+ //# sourceMappingURL=coerce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coerce.d.ts","sourceRoot":"","sources":["../../src/tools/coerce.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBxB;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,GAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBzB"}
@@ -1,4 +1,4 @@
1
- import type { TransportSource } from '../contract';
1
+ import type { RuntimeContext, TransportSource } from '../contract';
2
2
  import type { MethodDef } from '../server/types';
3
3
  export type ToolResult = {
4
4
  ok: true;
@@ -17,5 +17,29 @@ export interface ToolCallHooks {
17
17
  beforeToolCall?: (toolName: string, args: Record<string, unknown>, context: ToolCallContext) => void | Promise<void>;
18
18
  afterToolCall?: (toolName: string, args: Record<string, unknown>, result: ToolResult, durationMs: number, context: ToolCallContext) => void | Promise<void>;
19
19
  }
20
- export declare function executeToolMethod(method: MethodDef<unknown, unknown, unknown>, toolName: string, rawArgs: Record<string, unknown>, context: ToolCallContext, hooks?: ToolCallHooks): Promise<ToolResult>;
20
+ /**
21
+ * The tool-side twin of the HTTP server's `beforeHandle` / `afterHandle`. A
22
+ * tool call runs the same handler an HTTP request would — `ToolLifecycle` makes
23
+ * it run the same gate. Pass a `createAuthHook` result as `beforeHandle` here
24
+ * and tools are scope-guarded exactly as HTTP routes are; without it a tool
25
+ * call bypasses the auth a `createServer` `beforeHandle` enforces.
26
+ *
27
+ * Structurally a subset of `LifecycleHooks` — the same hook object used for
28
+ * `createServer({ hooks })` is assignable here.
29
+ */
30
+ export interface ToolLifecycle {
31
+ /** Auth / scope gate — throw to reject the call. */
32
+ beforeHandle?: (ctx: RuntimeContext, endpoint: MethodDef) => void | Promise<void>;
33
+ /** Transform the handler result before it is returned. */
34
+ afterHandle?: (ctx: RuntimeContext, result: unknown, endpoint: MethodDef) => unknown | Promise<unknown>;
35
+ }
36
+ /**
37
+ * Normalise any thrown value into a failed `ToolResult` — the one place an
38
+ * `AppError` becomes a tool error. Shared by `executeToolMethod` and both
39
+ * transport mounts so every tool error has one shape.
40
+ */
41
+ export declare function toolResultFromError(err: unknown): Extract<ToolResult, {
42
+ ok: false;
43
+ }>;
44
+ export declare function executeToolMethod(method: MethodDef<unknown, unknown, unknown>, toolName: string, rawArgs: Record<string, unknown>, context: ToolCallContext, hooks?: ToolCallHooks, lifecycle?: ToolLifecycle, coerceJson?: boolean): Promise<ToolResult>;
21
45
  //# sourceMappingURL=execute.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/tools/execute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,MAAM,UAAU,GAClB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC3B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,eAAe,CAAC;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,CAAC,EAAE,CACf,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,eAAe,KACrB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,aAAa,CAAC,EAAE,CACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,eAAe,KACrB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAC5C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,EAAE,eAAe,EACxB,KAAK,CAAC,EAAE,aAAa,GACpB,OAAO,CAAC,UAAU,CAAC,CAwDrB"}
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/tools/execute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,MAAM,UAAU,GAClB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC3B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,eAAe,CAAC;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,CAAC,EAAE,CACf,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,eAAe,KACrB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,aAAa,CAAC,EAAE,CACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,eAAe,KACrB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B,oDAAoD;IACpD,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF,0DAA0D;IAC1D,WAAW,CAAC,EAAE,CACZ,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,SAAS,KAChB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACjC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,EAAE;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC,CAQpF;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAC5C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,EAAE,eAAe,EACxB,KAAK,CAAC,EAAE,aAAa,EACrB,SAAS,CAAC,EAAE,aAAa,EACzB,UAAU,UAAQ,GACjB,OAAO,CAAC,UAAU,CAAC,CA8GrB"}
@@ -0,0 +1,15 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Flatten a `ZodDiscriminatedUnion` into a single `ZodObject` for LLM
4
+ * transports that cannot represent `oneOf` (MCP).
5
+ *
6
+ * The discriminator becomes a `z.enum(...)` of all variant values; fields
7
+ * from each variant become optional with a `.describe()` hint indicating
8
+ * which variant requires them.
9
+ *
10
+ * **Lossy:** per-variant field requiredness is replaced with optional +
11
+ * description hint. The original union remains the validation schema in
12
+ * `executeToolMethod` — this is the advertised schema only.
13
+ */
14
+ export declare function flattenDiscriminatedUnion(union: z.ZodDiscriminatedUnion): z.ZodObject<z.ZodRawShape>;
15
+ //# sourceMappingURL=flatten.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flatten.d.ts","sourceRoot":"","sources":["../../src/tools/flatten.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,CAAC,CAAC,qBAAqB,GAC7B,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAkD5B"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The single Zod → JSON Schema conversion point for the tools layer.
3
+ *
4
+ * MCP and agent both ultimately turn a contract schema into JSON Schema. This
5
+ * is the one place stitchkit converts — with the options that match what the
6
+ * transport SDKs emit, so a build-time validity probe tests the same thing the
7
+ * SDK will later emit, not a divergent code path.
8
+ */
9
+ import { z } from 'zod';
10
+ /** Conversion direction — `input` for tool arguments, `output` for results. */
11
+ export type JsonSchemaIo = 'input' | 'output';
12
+ /**
13
+ * Convert a Zod schema to JSON Schema. Throws on a construct JSON Schema cannot
14
+ * represent (`z.date()`, `z.bigint()`, `z.map()`, …). The caller decides what
15
+ * to do with that failure — see `onIncompatibleSchema`.
16
+ */
17
+ export declare function toJsonSchema(schema: z.ZodType, io: JsonSchemaIo): Record<string, unknown>;
18
+ //# sourceMappingURL=json-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-schema.d.ts","sourceRoot":"","sources":["../../src/tools/json-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,+EAA+E;AAC/E,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE9C;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOzF"}
@@ -0,0 +1,17 @@
1
+ import type { MountableTool } from './mount';
2
+ export interface ToolManifestEntry {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: Record<string, unknown>;
6
+ }
7
+ /**
8
+ * Build a searchable manifest from collected tools — name, description and
9
+ * JSON Schema for each. Use it to power a `tool_search` native tool: the app
10
+ * decides the search algorithm and the unlock mechanism.
11
+ *
12
+ * A tool whose schema cannot be represented as JSON Schema still appears —
13
+ * with an empty `inputSchema` — so it stays discoverable by name / description
14
+ * rather than crashing the whole manifest.
15
+ */
16
+ export declare function buildToolManifest(tools: MountableTool[]): ToolManifestEntry[];
17
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/tools/manifest.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,iBAAiB,EAAE,CAU7E"}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-handler.d.ts","sourceRoot":"","sources":["../../src/tools/mcp-handler.ts"],"names":[],"mappings":"AASA,OAAO,EAAkB,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAyDlE,MAAM,WAAW,gBAAgB,CAAC,KAAK,CAAE,SAAQ,oBAAoB,CAAC,KAAK,CAAC;IAC1E,uEAAuE;IACvE,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;CAC9D;AAYD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EACpC,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAC9B,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAuDrC"}
1
+ {"version":3,"file":"mcp-handler.d.ts","sourceRoot":"","sources":["../../src/tools/mcp-handler.ts"],"names":[],"mappings":"AASA,OAAO,EAAkB,KAAK,oBAAoB,EAAsB,MAAM,OAAO,CAAC;AAqEtF,MAAM,WAAW,gBAAgB,CAAC,KAAK,CAAE,SAAQ,oBAAoB,CAAC,KAAK,CAAC;IAC1E,uEAAuE;IACvE,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;CAC9D;AAYD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EACpC,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAC9B,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAuFrC"}