stitchkit 0.0.1 → 0.1.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 (113) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +373 -4
  3. package/dist/browser/client.d.ts +30 -0
  4. package/dist/browser/client.d.ts.map +1 -0
  5. package/dist/browser/http.d.ts +77 -0
  6. package/dist/browser/http.d.ts.map +1 -0
  7. package/dist/browser/socket-io.d.ts +69 -0
  8. package/dist/browser/socket-io.d.ts.map +1 -0
  9. package/dist/browser/stream.d.ts +2 -0
  10. package/dist/browser/stream.d.ts.map +1 -0
  11. package/dist/contract/define.d.ts +94 -0
  12. package/dist/contract/define.d.ts.map +1 -0
  13. package/dist/contract/errors.d.ts +46 -0
  14. package/dist/contract/errors.d.ts.map +1 -0
  15. package/dist/contract/index.d.ts +4 -0
  16. package/dist/contract/index.d.ts.map +1 -0
  17. package/dist/contract/index.js +26 -0
  18. package/dist/contract/pagination.d.ts +19 -0
  19. package/dist/contract/pagination.d.ts.map +1 -0
  20. package/dist/index-5sxnvwb1.js +368 -0
  21. package/dist/index-7wfkbvss.js +92 -0
  22. package/dist/index-809wc1tt.js +18 -0
  23. package/dist/index-gfzn1n4n.js +29 -0
  24. package/dist/index-ke4mx4ea.js +38 -0
  25. package/dist/index-n7bmdwmz.js +68 -0
  26. package/dist/index.d.ts +7 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +111 -0
  29. package/dist/internal/errors.d.ts +5 -0
  30. package/dist/internal/errors.d.ts.map +1 -0
  31. package/dist/internal/typed.d.ts +9 -0
  32. package/dist/internal/typed.d.ts.map +1 -0
  33. package/dist/observability/audit.d.ts +32 -0
  34. package/dist/observability/audit.d.ts.map +1 -0
  35. package/dist/observability/context.d.ts +60 -0
  36. package/dist/observability/context.d.ts.map +1 -0
  37. package/dist/observability/event.d.ts +49 -0
  38. package/dist/observability/event.d.ts.map +1 -0
  39. package/dist/observability/index.d.ts +14 -0
  40. package/dist/observability/index.d.ts.map +1 -0
  41. package/dist/observability/index.js +266 -0
  42. package/dist/observability/sanitize.d.ts +42 -0
  43. package/dist/observability/sanitize.d.ts.map +1 -0
  44. package/dist/observability/trace.d.ts +42 -0
  45. package/dist/observability/trace.d.ts.map +1 -0
  46. package/dist/react/cache-bridge.d.ts +53 -0
  47. package/dist/react/cache-bridge.d.ts.map +1 -0
  48. package/dist/react/cursor-query.d.ts +37 -0
  49. package/dist/react/cursor-query.d.ts.map +1 -0
  50. package/dist/react.d.ts +3 -0
  51. package/dist/react.d.ts.map +1 -0
  52. package/dist/react.js +52 -0
  53. package/dist/server/cache.d.ts +15 -0
  54. package/dist/server/cache.d.ts.map +1 -0
  55. package/dist/server/context.d.ts +9 -0
  56. package/dist/server/context.d.ts.map +1 -0
  57. package/dist/server/create.d.ts +4 -0
  58. package/dist/server/create.d.ts.map +1 -0
  59. package/dist/server/event-bus.d.ts +24 -0
  60. package/dist/server/event-bus.d.ts.map +1 -0
  61. package/dist/server/implement.d.ts +16 -0
  62. package/dist/server/implement.d.ts.map +1 -0
  63. package/dist/server/index.d.ts +17 -0
  64. package/dist/server/index.d.ts.map +1 -0
  65. package/dist/server/index.js +965 -0
  66. package/dist/server/logger.d.ts +21 -0
  67. package/dist/server/logger.d.ts.map +1 -0
  68. package/dist/server/middleware/auth.d.ts +50 -0
  69. package/dist/server/middleware/auth.d.ts.map +1 -0
  70. package/dist/server/middleware/cookies.d.ts +34 -0
  71. package/dist/server/middleware/cookies.d.ts.map +1 -0
  72. package/dist/server/middleware/cors.d.ts +9 -0
  73. package/dist/server/middleware/cors.d.ts.map +1 -0
  74. package/dist/server/multipart.d.ts +14 -0
  75. package/dist/server/multipart.d.ts.map +1 -0
  76. package/dist/server/rate-limit.d.ts +17 -0
  77. package/dist/server/rate-limit.d.ts.map +1 -0
  78. package/dist/server/request.d.ts +22 -0
  79. package/dist/server/request.d.ts.map +1 -0
  80. package/dist/server/router.d.ts +42 -0
  81. package/dist/server/router.d.ts.map +1 -0
  82. package/dist/server/socket-io.d.ts +42 -0
  83. package/dist/server/socket-io.d.ts.map +1 -0
  84. package/dist/server/stream.d.ts +18 -0
  85. package/dist/server/stream.d.ts.map +1 -0
  86. package/dist/server/swept-map.d.ts +22 -0
  87. package/dist/server/swept-map.d.ts.map +1 -0
  88. package/dist/server/types.d.ts +124 -0
  89. package/dist/server/types.d.ts.map +1 -0
  90. package/dist/tools/agent.d.ts +14 -0
  91. package/dist/tools/agent.d.ts.map +1 -0
  92. package/dist/tools/execute.d.ts +21 -0
  93. package/dist/tools/execute.d.ts.map +1 -0
  94. package/dist/tools/mcp-handler.d.ts +21 -0
  95. package/dist/tools/mcp-handler.d.ts.map +1 -0
  96. package/dist/tools/mcp-stdio.d.ts +25 -0
  97. package/dist/tools/mcp-stdio.d.ts.map +1 -0
  98. package/dist/tools/mcp.d.ts +42 -0
  99. package/dist/tools/mcp.d.ts.map +1 -0
  100. package/dist/tools/mount.d.ts +61 -0
  101. package/dist/tools/mount.d.ts.map +1 -0
  102. package/dist/tools/names.d.ts +2 -0
  103. package/dist/tools/names.d.ts.map +1 -0
  104. package/dist/tools/remote.d.ts +22 -0
  105. package/dist/tools/remote.d.ts.map +1 -0
  106. package/dist/tools/schema.d.ts +4 -0
  107. package/dist/tools/schema.d.ts.map +1 -0
  108. package/dist/tools/view-file.d.ts +57 -0
  109. package/dist/tools/view-file.d.ts.map +1 -0
  110. package/dist/tools.d.ts +8 -0
  111. package/dist/tools.d.ts.map +1 -0
  112. package/dist/tools.js +654 -0
  113. package/package.json +136 -4
@@ -0,0 +1,21 @@
1
+ export declare function elapsedMs(startTime: bigint): number;
2
+ /** Map an HTTP status to a log level. */
3
+ export declare function levelForStatus(status: number): 'error' | 'warn' | 'info';
4
+ /** The structured fields shared by every completed-request log line. */
5
+ export declare function buildLogFields(method: string, path: string, status: number, durationMs: number, traceId: string): {
6
+ traceId: string;
7
+ method: string;
8
+ path: string;
9
+ status: number;
10
+ durationMs: number;
11
+ };
12
+ export interface RequestLog {
13
+ traceId: string;
14
+ startTime: bigint;
15
+ }
16
+ export declare function shouldLog(pathname: string, method: string): boolean;
17
+ /** Open the timing window for a request. Development prints a `→` line. */
18
+ export declare function logIncoming(req: Request, pathname: string, traceId: string): RequestLog;
19
+ /** 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
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,50 @@
1
+ import type { RuntimeContext } from '../../contract';
2
+ import type { MethodDef } from '../types';
3
+ export interface JwtPayload {
4
+ [key: string]: unknown;
5
+ }
6
+ export declare function verifyJwt(token: string, secret: string): Promise<JwtPayload>;
7
+ export declare function extractToken(req: Request, cookieName?: string): string | null;
8
+ /**
9
+ * Per-scope access predicate. `endpoint.scope` selects which rule applies:
10
+ * - `'public'` — always pass (identity attached if present).
11
+ * - `'authenticated'` — any resolved identity passes.
12
+ * - function — custom check; gets the identity and the full context
13
+ * (so it can read `ctx.pathParams` for resource-scoped access). May be
14
+ * async — resource-scoped checks usually need a DB lookup.
15
+ */
16
+ export type AuthRule<TIdentity> = 'public' | 'authenticated' | ((identity: Awaited<TIdentity>, ctx: RuntimeContext) => boolean | Promise<boolean>);
17
+ export interface AuthHookConfig<TIdentity> {
18
+ /** Resolve the request identity — cookie / bearer + DB lookup. */
19
+ resolve: (ctx: RuntimeContext) => Promise<TIdentity | null>;
20
+ /** Access rule per scope; `endpoint.scope` is the key. */
21
+ rules: Record<string, AuthRule<TIdentity>>;
22
+ /** Scope applied when an endpoint declares none. */
23
+ defaultScope?: string;
24
+ /** Write the resolved identity onto the context for handlers. */
25
+ inject?: (ctx: RuntimeContext, identity: Awaited<TIdentity> | null) => void;
26
+ /** Thrown when the scope needs an identity and there is none. */
27
+ onAnonymous?: () => never;
28
+ /** Thrown when an identity is present but the rule rejects it. */
29
+ onForbidden?: () => never;
30
+ }
31
+ export type AuthHook = (ctx: RuntimeContext, endpoint: MethodDef) => Promise<void>;
32
+ /**
33
+ * Build a `beforeHandle` hook that enforces `endpoint.scope`.
34
+ *
35
+ * Identity resolution and the scope vocabulary stay in the project; the
36
+ * project annotates its `rules` object with `satisfies Record<MyScope, …>` to
37
+ * keep scope coverage exhaustive.
38
+ */
39
+ export declare function createAuthHook<TIdentity>(config: AuthHookConfig<TIdentity>): AuthHook;
40
+ /**
41
+ * Bearer-token identity resolver — the MCP / API-key counterpart of the
42
+ * cookie session hook. Strips `Authorization: Bearer <token>` and hands the
43
+ * raw token (plus the request, for IP / user-agent) to the project lookup.
44
+ */
45
+ export interface BearerResolverConfig<TIdentity> {
46
+ /** Resolve a raw token to identity. Return `null` for unknown / revoked. */
47
+ lookup: (token: string, req: Request) => Promise<TIdentity | null>;
48
+ }
49
+ export declare function createBearerResolver<TIdentity>(config: BearerResolverConfig<TIdentity>): (req: Request) => Promise<TIdentity | null>;
50
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,34 @@
1
+ export declare function parseCookies(header: string | null): Record<string, string>;
2
+ export interface CookieOptions {
3
+ maxAge?: number;
4
+ path?: string;
5
+ domain?: string;
6
+ secure?: boolean;
7
+ httpOnly?: boolean;
8
+ sameSite?: 'Strict' | 'Lax' | 'None';
9
+ }
10
+ export declare function serializeCookie(name: string, value: string, opts?: CookieOptions): string;
11
+ /** A cookie's name + options bundled into a typed read/set/clear handle. */
12
+ export interface CookieDef {
13
+ /** Read this cookie's value from a request (`undefined` if absent). */
14
+ get(req: Request): string | undefined;
15
+ /** Build a `Set-Cookie` header value for `value` with the baked-in options. */
16
+ set(value: string): string;
17
+ /** Build a `Set-Cookie` header value that clears the cookie. */
18
+ clear(): string;
19
+ }
20
+ /**
21
+ * Bundle a cookie's name + options into a typed handle — define it once,
22
+ * then `get` / `set` / `clear` without repeating the config at every call site.
23
+ *
24
+ * ```ts
25
+ * const session = defineCookie({ name: 'sid', httpOnly: true, path: '/' });
26
+ * session.get(req); // string | undefined
27
+ * session.set('abc123'); // → Set-Cookie value
28
+ * session.clear(); // → Set-Cookie value (Max-Age=0)
29
+ * ```
30
+ */
31
+ export declare function defineCookie(config: CookieOptions & {
32
+ name: string;
33
+ }): CookieDef;
34
+ //# sourceMappingURL=cookies.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,9 @@
1
+ export interface CorsConfig {
2
+ origin?: string | string[];
3
+ credentials?: boolean;
4
+ methods?: string;
5
+ headers?: string;
6
+ }
7
+ export declare function corsHeaders(config: CorsConfig, requestOrigin?: string | null): Record<string, string>;
8
+ export declare function corsPreflightResponse(config: CorsConfig, req: Request): Response;
9
+ //# sourceMappingURL=cors.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,14 @@
1
+ import type { ZodType } from 'zod';
2
+ /** A parsed multipart request — the uploaded `file` and the validated `fields`. */
3
+ export interface MultipartResult {
4
+ file: File;
5
+ fields: Record<string, unknown>;
6
+ }
7
+ /**
8
+ * Parse a `multipart/form-data` request — extract the file at `fileField` and
9
+ * the remaining fields (each JSON-decoded, then validated by `fieldsSchema`
10
+ * when given). Rejects with a 400 if the file is missing or the upload exceeds
11
+ * `maxBytes` (default 25 MB).
12
+ */
13
+ export declare function parseMultipart(req: Request, fileField: string, fieldsSchema?: ZodType<unknown>, maxBytes?: number): Promise<MultipartResult>;
14
+ //# sourceMappingURL=multipart.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,17 @@
1
+ /** Token-bucket limit — at most `max` requests per `window` seconds. */
2
+ export interface RateLimitConfig {
3
+ window: number;
4
+ max: number;
5
+ }
6
+ /**
7
+ * In-memory token-bucket rate limiter. `check(key, config)` consumes a token
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.
11
+ */
12
+ export declare function createRateLimiter(): {
13
+ destroy: () => void;
14
+ check(key: string, config: RateLimitConfig): boolean;
15
+ remaining(key: string, config: RateLimitConfig): number;
16
+ };
17
+ //# sourceMappingURL=rate-limit.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * HTTP request helpers — header parsing, client identification, trace ids.
3
+ * Pure `Request → value` functions; no framework state.
4
+ */
5
+ /** Compact, time-sortable id — base36 timestamp + base36 random, ~14 chars. */
6
+ export declare function generateTraceId(): string;
7
+ /**
8
+ * Trace id for a request: a trusted inbound `x-request-id` / `x-trace-id`
9
+ * header (set by the edge proxy) when present and sane, else a fresh one.
10
+ * Shared by the router, the logger and any consumer that wants the same id.
11
+ */
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;
15
+ /** Client identity — IP + user-agent. The one place projects derive both. */
16
+ export declare function getClientInfo(req: Request): {
17
+ ipAddress?: string;
18
+ userAgent?: string;
19
+ };
20
+ /** Flatten a URL query string — repeated keys collapse to arrays. */
21
+ export declare function parseQueryParams(url: URL): Record<string, string | string[]>;
22
+ //# sourceMappingURL=request.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,42 @@
1
+ import type { LifecycleHooks, MethodDef, RawRoute, ServiceDef } from './types';
2
+ /** A service mounted under a path prefix, carrying optional group hooks. */
3
+ export interface NormalizedGroup {
4
+ prefix: string;
5
+ service: ServiceDef;
6
+ hooks?: LifecycleHooks;
7
+ }
8
+ interface RouteEntry {
9
+ method: MethodDef;
10
+ service: ServiceDef;
11
+ pattern: string;
12
+ segments: string[];
13
+ groupHooks?: LifecycleHooks;
14
+ }
15
+ /** Compiled route table — HTTP method → entries (param routes sorted last). */
16
+ export type RouteMap = Map<string, RouteEntry[]>;
17
+ export interface RouteMatch {
18
+ method: MethodDef;
19
+ service: ServiceDef;
20
+ pathParams: Record<string, string>;
21
+ groupHooks?: LifecycleHooks;
22
+ }
23
+ export declare function buildRouteMap(groups: NormalizedGroup[]): RouteMap;
24
+ export declare function matchRoute(routeMap: RouteMap, httpMethod: string, pathname: string): RouteMatch | null;
25
+ /**
26
+ * HTTP methods that have a route matching `pathname` — for a `405` `Allow`
27
+ * header when the path exists but not under the requested method.
28
+ */
29
+ export declare function allowedMethods(routeMap: RouteMap, pathname: string): string[];
30
+ /** Startup guard — throws when two routes collapse to the same shape. */
31
+ export declare function validateRoutes(routeMap: RouteMap): void;
32
+ export declare function matchRawRoute(rawRoutes: RawRoute[], httpMethod: string, pathname: string): {
33
+ route: RawRoute;
34
+ params: Record<string, string>;
35
+ } | null;
36
+ /**
37
+ * Build a `RawRoute` that serves files from `dir` under `prefix`.
38
+ * Rejects path traversal (`..`); 404 for a missing file.
39
+ */
40
+ export declare function staticRoute(prefix: string, dir: string): RawRoute;
41
+ export {};
42
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Socket.IO server setup — the family WebSocket server boilerplate.
3
+ *
4
+ * Every project repeats the same wiring: `new SocketIOServer(...)`, a
5
+ * `@socket.io/bun-engine` instance, `io.bind(engine)`, `engine.handler()` for
6
+ * the `Bun.serve` `websocket` field, and an `/socket.io/*` route delegating to
7
+ * `engine.handleRequest`. `createSocketIOServer` is exactly that wiring.
8
+ *
9
+ * Connection handlers, rooms and handshake auth stay in the project — they are
10
+ * domain logic. This helper owns only the transport plumbing: it returns the
11
+ * typed `io` to attach handlers to, the `websocket` handler for `Bun.serve`,
12
+ * and a ready-made `route` to drop into `createServer({ rawRoutes })`.
13
+ */
14
+ import { Server as BunEngine } from '@socket.io/bun-engine';
15
+ import { Server as SocketIOServer } from 'socket.io';
16
+ import type { SocketEventMap } from '../browser/socket-io';
17
+ import type { RawRoute } from './types';
18
+ export interface SocketIOServerConfig {
19
+ /** CORS — the browser origin(s) allowed to open a socket. */
20
+ cors: {
21
+ origin: string | string[];
22
+ credentials?: boolean;
23
+ };
24
+ /** Socket.IO endpoint path. Default `/socket.io/`. */
25
+ path?: string;
26
+ /** Transports offered to clients. Default `['websocket', 'polling']`. */
27
+ transports?: Array<'websocket' | 'polling'>;
28
+ /** Heartbeat: ms without a pong before the connection is dropped. Default `20000`. */
29
+ pingTimeout?: number;
30
+ /** Heartbeat: ms between pings. Default `10000`. */
31
+ pingInterval?: number;
32
+ }
33
+ export interface SocketIOServerHandle<TServerEvents extends SocketEventMap, TClientEvents extends SocketEventMap> {
34
+ /** The typed Socket.IO server — attach `io.on('connection', ...)` handlers. */
35
+ io: SocketIOServer<TClientEvents, TServerEvents>;
36
+ /** WebSocket handler for `Bun.serve({ websocket })`. */
37
+ websocket: ReturnType<BunEngine['handler']>['websocket'];
38
+ /** Ready `/socket.io/*` route — drop into `createServer({ rawRoutes })`. */
39
+ route: RawRoute;
40
+ }
41
+ export declare function createSocketIOServer<TServerEvents extends SocketEventMap, TClientEvents extends SocketEventMap>(config: SocketIOServerConfig): SocketIOServerHandle<TServerEvents, TClientEvents>;
42
+ //# sourceMappingURL=socket-io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socket-io.d.ts","sourceRoot":"","sources":["../../src/server/socket-io.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,WAAW,oBAAoB;IACnC,6DAA6D;IAC7D,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3D,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,UAAU,CAAC,EAAE,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IAC5C,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB,CACnC,aAAa,SAAS,cAAc,EACpC,aAAa,SAAS,cAAc;IAEpC,+EAA+E;IAC/E,EAAE,EAAE,cAAc,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IACjD,wDAAwD;IACxD,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACzD,4EAA4E;IAC5E,KAAK,EAAE,QAAQ,CAAC;CACjB;AAED,wBAAgB,oBAAoB,CAClC,aAAa,SAAS,cAAc,EACpC,aAAa,SAAS,cAAc,EACpC,MAAM,EAAE,oBAAoB,GAAG,oBAAoB,CAAC,aAAa,EAAE,aAAa,CAAC,CAqClF"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Turn an async generator into a Server-Sent Events `Response` — each yielded
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.
5
+ */
6
+ export declare function streamSSE(generator: AsyncGenerator<unknown>): Response;
7
+ /** Options for `parseSSE`. */
8
+ export interface ParseSSEOptions {
9
+ /** Called for a `data:` line that is not valid JSON — the alternative to throwing. */
10
+ onParseError?: (raw: string, error: Error) => void;
11
+ }
12
+ /**
13
+ * Parse a Server-Sent Events `Response` body into an async generator of JSON
14
+ * values — the client counterpart of `streamSSE`. Stops at the `[DONE]`
15
+ * sentinel; the stream lock is released on every exit path.
16
+ */
17
+ export declare function parseSSE<T>(response: Response, options?: ParseSSEOptions): AsyncGenerator<T>;
18
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * A string-keyed `Map` with a background sweep that evicts expired entries.
3
+ * The shared scaffold behind `createCache` and `createRateLimiter` — they
4
+ * differ only in the expiry predicate and the sweep interval.
5
+ */
6
+ /** Config for `createSweptMap`. */
7
+ export interface SweptMapOptions<V> {
8
+ /** Sweep interval, in milliseconds. */
9
+ intervalMs: number;
10
+ /** `true` for an entry that should be evicted — `now` is `Date.now()`. */
11
+ isExpired: (value: V, now: number) => boolean;
12
+ }
13
+ /** A swept map — its backing store plus a teardown. */
14
+ export interface SweptMap<V> {
15
+ /** The backing map — read and written directly by the owner. */
16
+ store: Map<string, V>;
17
+ /** Stop the sweep timer and clear the map. */
18
+ destroy: () => void;
19
+ }
20
+ /** Build a `Map` that evicts expired entries on a background timer. */
21
+ export declare function createSweptMap<V>(options: SweptMapOptions<V>): SweptMap<V>;
22
+ //# sourceMappingURL=swept-map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swept-map.d.ts","sourceRoot":"","sources":["../../src/server/swept-map.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,mCAAmC;AACnC,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CAC/C;AAED,uDAAuD;AACvD,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,gEAAgE;IAChE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACtB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAmB1E"}
@@ -0,0 +1,124 @@
1
+ import type { ZodType } from 'zod';
2
+ import type { EndpointDef, HandlerContext, HttpMethod, RuntimeContext, Transport } from '../contract';
3
+ import type { CorsConfig } from './middleware/cors';
4
+ type Prop<T, K extends string> = K extends keyof T ? T[K] : undefined;
5
+ type InferParams<E> = Prop<E, 'params'> extends ZodType<infer P> ? P : undefined;
6
+ type InferInput<E> = Prop<E, 'input'> extends ZodType<infer I> ? I : undefined;
7
+ type InferOutput<E> = Prop<E, 'output'> extends ZodType<infer O> ? O : never;
8
+ export type Handlers<C extends Record<string, EndpointDef>, TCtx extends RuntimeContext = HandlerContext> = {
9
+ [K in keyof C]: (ctx: TCtx & {
10
+ params: InferParams<C[K]>;
11
+ input: InferInput<C[K]>;
12
+ }) => Prop<C[K], 'output'> extends ZodType ? Promise<InferOutput<C[K]>> | InferOutput<C[K]> : void | Promise<void>;
13
+ };
14
+ export interface MethodDef<TParams = unknown, TInput = unknown, TOutput = unknown> {
15
+ method: HttpMethod;
16
+ path: string;
17
+ desc: string;
18
+ toolName?: string;
19
+ expose?: readonly Transport[];
20
+ scope?: string;
21
+ paramsSchema?: ZodType<TParams>;
22
+ inputSchema?: ZodType<TInput>;
23
+ outputSchema?: ZodType<TOutput>;
24
+ multipart?: string;
25
+ handler: (ctx: RuntimeContext) => Promise<TOutput> | TOutput;
26
+ }
27
+ export interface ServiceDef {
28
+ name: string;
29
+ prefix: string;
30
+ scope: string;
31
+ methods: Record<string, MethodDef<unknown, unknown, unknown>>;
32
+ }
33
+ export interface LifecycleHooks {
34
+ onRequest?: (req: Request) => undefined | Response | Promise<undefined | Response>;
35
+ beforeHandle?: (ctx: RuntimeContext, endpoint: MethodDef) => void | Promise<void>;
36
+ afterHandle?: (ctx: RuntimeContext, result: unknown, endpoint: MethodDef) => unknown | Promise<unknown>;
37
+ onError?: (ctx: RuntimeContext, error: unknown, endpoint?: MethodDef) => Response | Promise<Response> | undefined;
38
+ }
39
+ export interface RouteGroup {
40
+ pathPrefix?: string;
41
+ services: ServiceDef[];
42
+ hooks?: LifecycleHooks;
43
+ }
44
+ /**
45
+ * A non-contract HTTP route — for things that cannot be a clean JSON
46
+ * request/response contract: auth bootstrap (cookies, OAuth redirects),
47
+ * external webhooks (signature/IP verification), static files, socket.io.
48
+ *
49
+ * Matched in the same router as contract routes (shared CORS / `onRequest`),
50
+ * but the handler is raw `Request → Response` — no schema parsing and no
51
+ * `beforeHandle` auth gate; the route authorizes itself.
52
+ */
53
+ /** The concrete `Bun.serve` server instance, passed through to raw handlers. */
54
+ export type BunServer = ReturnType<typeof Bun.serve>;
55
+ /** Context passed to a `RawRoute` handler alongside the raw `Request`. */
56
+ export interface RawRouteContext {
57
+ /** Matched `:param` path segments — empty object for exact / wildcard paths. */
58
+ params: Record<string, string>;
59
+ /**
60
+ * The `Bun.serve` instance — needed for connection upgrades (e.g. WebSocket).
61
+ * Absent when the handler runs via the bare `createHandler` fetch.
62
+ */
63
+ server?: BunServer;
64
+ }
65
+ export interface RawRoute {
66
+ method: HttpMethod | 'ALL';
67
+ /** Exact path, `:param` segments, or a trailing `/*` prefix wildcard. */
68
+ path: string;
69
+ /**
70
+ * Raw handler — a standard `Request → Response` fetch handler plus a routing
71
+ * `ctx` (matched path params, the server). Errors thrown here are caught by
72
+ * the router and run through `hooks.onError` — same shape as contract errors.
73
+ */
74
+ handler: (req: Request, ctx: RawRouteContext) => Response | Promise<Response>;
75
+ }
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
+ export interface StitchLogger {
88
+ info(msg: string, data?: Record<string, unknown>): void;
89
+ warn(msg: string, data?: Record<string, unknown>): void;
90
+ error(msg: string, data?: Record<string, unknown>): void;
91
+ debug(msg: string, data?: Record<string, unknown>): void;
92
+ }
93
+ export interface ServerConfig {
94
+ services?: ServiceDef[];
95
+ groups?: RouteGroup[];
96
+ /** Non-contract routes — auth, webhooks, static, socket.io. */
97
+ rawRoutes?: RawRoute[];
98
+ port?: number;
99
+ hostname?: string;
100
+ cors?: CorsConfig;
101
+ hooks?: LifecycleHooks;
102
+ logging?: boolean | StitchLogger;
103
+ /**
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.
108
+ */
109
+ traceId?: (req: Request) => string;
110
+ routes?: BunRoutes;
111
+ websocket?: BunWebSocketHandlers;
112
+ development?: BunDevelopmentOptions;
113
+ bun?: ServerPassthrough;
114
+ }
115
+ export type StitchServeOptions = ServerPassthrough & {
116
+ port: number;
117
+ hostname?: string;
118
+ routes?: BunRoutes;
119
+ websocket?: BunWebSocketHandlers;
120
+ development?: BunDevelopmentOptions;
121
+ fetch(req: Request): Promise<Response>;
122
+ };
123
+ export {};
124
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { ToolSet } from 'ai';
2
+ import type { ServiceDef } from '../server/types';
3
+ import type { ToolCallHooks } from './execute';
4
+ import { type ToolExtend } from './mount';
5
+ export interface AgentContext {
6
+ [key: string]: unknown;
7
+ }
8
+ export interface AgentMountConfig {
9
+ context?: AgentContext;
10
+ hooks?: ToolCallHooks;
11
+ extend?: ToolExtend;
12
+ }
13
+ export declare function mountAgent(service: ServiceDef, config?: AgentMountConfig): ToolSet;
14
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,21 @@
1
+ import type { TransportSource } from '../contract';
2
+ import type { MethodDef } from '../server/types';
3
+ export type ToolResult = {
4
+ ok: true;
5
+ data: unknown;
6
+ } | {
7
+ ok: false;
8
+ code: string;
9
+ details?: unknown;
10
+ hint?: string;
11
+ };
12
+ export interface ToolCallContext {
13
+ source: TransportSource;
14
+ [key: string]: unknown;
15
+ }
16
+ export interface ToolCallHooks {
17
+ beforeToolCall?: (toolName: string, args: Record<string, unknown>, context: ToolCallContext) => void | Promise<void>;
18
+ afterToolCall?: (toolName: string, args: Record<string, unknown>, result: ToolResult, durationMs: number, context: ToolCallContext) => void | Promise<void>;
19
+ }
20
+ export declare function executeToolMethod(method: MethodDef<unknown, unknown, unknown>, toolName: string, rawArgs: Record<string, unknown>, context: ToolCallContext, hooks?: ToolCallHooks): Promise<ToolResult>;
21
+ //# sourceMappingURL=execute.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,21 @@
1
+ import { type McpServerBuildConfig } from './mcp';
2
+ export interface McpHandlerConfig<TAuth> extends McpServerBuildConfig<TAuth> {
3
+ /** Resolve an incoming request to an identity. Return `null` → 401. */
4
+ auth: (req: Request) => TAuth | null | Promise<TAuth | null>;
5
+ }
6
+ /**
7
+ * Build a Streamable-HTTP MCP request handler (`Request → Response`).
8
+ *
9
+ * Owns the entire MCP server lifecycle — SSE event store, per-session
10
+ * transports, the `McpServer` instances — so the consuming app never imports
11
+ * `@modelcontextprotocol/sdk` itself. The app only declares WHAT to expose:
12
+ * how to authenticate and which contract services. MCP tools come from
13
+ * contracts; native multimodal tools attach via `nativeTools`.
14
+ *
15
+ * The server itself is built by the transport-neutral `buildMcpServer` — the
16
+ * same core used by `createStdioMcpServer`.
17
+ *
18
+ * Mount the returned handler in your server's fetch router (e.g. under `/mcp`).
19
+ */
20
+ export declare function createMcpHandler<TAuth>(config: McpHandlerConfig<TAuth>): (req: Request) => Promise<Response>;
21
+ //# sourceMappingURL=mcp-handler.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,25 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { type McpServerBuildConfig } from './mcp';
3
+ /**
4
+ * Config for a stdio MCP server. Unlike the HTTP handler, a stdio server is a
5
+ * single process serving one client — identity is resolved ONCE at startup
6
+ * (from an env var / CLI arg), not per request.
7
+ */
8
+ export interface StdioMcpServerConfig<TAuth> extends McpServerBuildConfig<TAuth> {
9
+ /** Identity for the single stdio session — a value or a promise of one. */
10
+ auth: TAuth | Promise<TAuth>;
11
+ }
12
+ /**
13
+ * Build an MCP server and connect it over stdio — the server runs as a
14
+ * subprocess of the MCP client, on the client's machine, so it can reach the
15
+ * client's local filesystem.
16
+ *
17
+ * Same contract pipeline as `createMcpHandler` (`buildMcpServer`); only the
18
+ * transport differs. For a local CLI: resolve the identity from `process.env`
19
+ * and pass it as `auth`.
20
+ *
21
+ * Note: stdout is reserved for the JSON-RPC stream — the caller MUST keep all
22
+ * logging on stderr (`console.error`), never `console.log`.
23
+ */
24
+ export declare function createStdioMcpServer<TAuth>(config: StdioMcpServerConfig<TAuth>): Promise<McpServer>;
25
+ //# sourceMappingURL=mcp-stdio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-stdio.d.ts","sourceRoot":"","sources":["../../src/tools/mcp-stdio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAkB,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAElE;;;;GAIG;AACH,MAAM,WAAW,oBAAoB,CAAC,KAAK,CAAE,SAAQ,oBAAoB,CAAC,KAAK,CAAC;IAC9E,2EAA2E;IAC3E,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;CAC9B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAC9C,MAAM,EAAE,oBAAoB,CAAC,KAAK,CAAC,GAClC,OAAO,CAAC,SAAS,CAAC,CAKpB"}