stitchkit 0.54.0 → 0.55.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 (100) hide show
  1. package/README.md +4 -1
  2. package/dist/browser/socket-io.d.ts +11 -1
  3. package/dist/browser/socket-io.d.ts.map +1 -1
  4. package/dist/cli.js +14 -9
  5. package/dist/contract/file-ref.d.ts +13 -0
  6. package/dist/contract/file-ref.d.ts.map +1 -0
  7. package/dist/contract/index.d.ts +1 -0
  8. package/dist/contract/index.d.ts.map +1 -1
  9. package/dist/contract/index.js +21 -17
  10. package/dist/files/boundary.d.ts +52 -0
  11. package/dist/files/boundary.d.ts.map +1 -0
  12. package/dist/files.d.ts +3 -0
  13. package/dist/files.d.ts.map +1 -0
  14. package/dist/files.js +16 -0
  15. package/dist/{index-7vb44hy8.js → index-0gv7k0ra.js} +127 -92
  16. package/dist/index-1bx83sw4.js +4 -0
  17. package/dist/index-1k16zv57.js +269 -0
  18. package/dist/index-6k1937bx.js +20 -0
  19. package/dist/{index-bmnhqtya.js → index-7eq9va6e.js} +1 -4
  20. package/dist/{index-yxpe3phd.js → index-cby4ar3v.js} +1 -18
  21. package/dist/index-h60df7rj.js +110 -0
  22. package/dist/{index-yez419px.js → index-js7yexng.js} +19 -6
  23. package/dist/index-k4dftwf7.js +66 -0
  24. package/dist/{index-z7761jk2.js → index-npye5kt7.js} +16 -22
  25. package/dist/{index-b15rtha1.js → index-pzc32v75.js} +61 -3
  26. package/dist/{index-e1es808r.js → index-qh4xevf5.js} +1 -1
  27. package/dist/{index-gvha32jh.js → index-qx84bqzk.js} +2 -2
  28. package/dist/{index-pfqjb5xy.js → index-rgd18hx3.js} +23 -5
  29. package/dist/index-sbdmyz75.js +18 -0
  30. package/dist/{index-173tvqcp.js → index-v4bbq3p4.js} +9 -114
  31. package/dist/index.js +162 -35
  32. package/dist/node.js +30 -27
  33. package/dist/observability/index.js +28 -25
  34. package/dist/react.js +2 -2
  35. package/dist/realtime/contract.d.ts +9 -0
  36. package/dist/realtime/contract.d.ts.map +1 -1
  37. package/dist/realtime/index.d.ts +2 -1
  38. package/dist/realtime/index.d.ts.map +1 -1
  39. package/dist/realtime/request.d.ts +21 -0
  40. package/dist/realtime/request.d.ts.map +1 -0
  41. package/dist/realtime/socket.d.ts +3 -0
  42. package/dist/realtime/socket.d.ts.map +1 -1
  43. package/dist/remote.d.ts +9 -0
  44. package/dist/remote.d.ts.map +1 -0
  45. package/dist/remote.js +79 -0
  46. package/dist/server/context-contribution.d.ts +10 -0
  47. package/dist/server/context-contribution.d.ts.map +1 -0
  48. package/dist/server/context.d.ts.map +1 -1
  49. package/dist/server/index.d.ts +2 -1
  50. package/dist/server/index.d.ts.map +1 -1
  51. package/dist/server/index.js +133 -88
  52. package/dist/server/lifecycle.d.ts +4 -0
  53. package/dist/server/lifecycle.d.ts.map +1 -0
  54. package/dist/server/middleware/auth.d.ts +35 -7
  55. package/dist/server/middleware/auth.d.ts.map +1 -1
  56. package/dist/server/types.d.ts +1 -1
  57. package/dist/server/types.d.ts.map +1 -1
  58. package/dist/testing/surface-conformance.d.ts +47 -0
  59. package/dist/testing/surface-conformance.d.ts.map +1 -0
  60. package/dist/testing/surface-manifest.d.ts +156 -0
  61. package/dist/testing/surface-manifest.d.ts.map +1 -0
  62. package/dist/testing.d.ts +2 -0
  63. package/dist/testing.d.ts.map +1 -1
  64. package/dist/testing.js +366 -3
  65. package/dist/tools/agent.d.ts.map +1 -1
  66. package/dist/tools/async-operation.d.ts +168 -0
  67. package/dist/tools/async-operation.d.ts.map +1 -0
  68. package/dist/tools/cli-args.d.ts +1 -1
  69. package/dist/tools/cli-args.d.ts.map +1 -1
  70. package/dist/tools/cli-format.d.ts +2 -2
  71. package/dist/tools/cli-format.d.ts.map +1 -1
  72. package/dist/tools/cli-wait.d.ts +11 -2
  73. package/dist/tools/cli-wait.d.ts.map +1 -1
  74. package/dist/tools/cli.d.ts +2 -0
  75. package/dist/tools/cli.d.ts.map +1 -1
  76. package/dist/tools/define-download-tool.d.ts +6 -5
  77. package/dist/tools/define-download-tool.d.ts.map +1 -1
  78. package/dist/tools/define-upload-tool.d.ts +3 -1
  79. package/dist/tools/define-upload-tool.d.ts.map +1 -1
  80. package/dist/tools/define-wait-tool.d.ts +1 -1
  81. package/dist/tools/define-wait-tool.d.ts.map +1 -1
  82. package/dist/tools/download-core.d.ts +5 -10
  83. package/dist/tools/download-core.d.ts.map +1 -1
  84. package/dist/tools/lifecycle.d.ts +4 -0
  85. package/dist/tools/lifecycle.d.ts.map +1 -0
  86. package/dist/tools/mount-download.d.ts +5 -4
  87. package/dist/tools/mount-download.d.ts.map +1 -1
  88. package/dist/tools/mount-upload.d.ts +4 -2
  89. package/dist/tools/mount-upload.d.ts.map +1 -1
  90. package/dist/tools/upload-core.d.ts +3 -2
  91. package/dist/tools/upload-core.d.ts.map +1 -1
  92. package/dist/tools/view-file.d.ts +4 -3
  93. package/dist/tools/view-file.d.ts.map +1 -1
  94. package/dist/tools/wait-core.d.ts +6 -1
  95. package/dist/tools/wait-core.d.ts.map +1 -1
  96. package/dist/tools.d.ts +3 -2
  97. package/dist/tools.d.ts.map +1 -1
  98. package/dist/tools.js +385 -244
  99. package/llms-full.txt +417 -27
  100. package/package.json +10 -2
package/README.md CHANGED
@@ -85,9 +85,12 @@ Server code imports server entrypoints:
85
85
  import { createServer, createHandler, implement } from 'stitchkit/server'
86
86
  import { createSocketIOServer, createAuthHook } from 'stitchkit/server'
87
87
  import { createMcpHandler, mountAgent } from 'stitchkit/tools'
88
+ import { implementRemote } from 'stitchkit/remote'
88
89
  ```
89
90
 
90
- The root `stitchkit` entrypoint is browser-safe. Server and tool code live behind `stitchkit/server` and `stitchkit/tools`.
91
+ The root `stitchkit` entrypoint is browser-safe. Server, tool and peer-free
92
+ remote-proxy code live behind `stitchkit/server`, `stitchkit/tools` and
93
+ `stitchkit/remote` respectively.
91
94
 
92
95
  ## Quick Start
93
96
 
@@ -22,7 +22,8 @@
22
22
  */
23
23
  import type { EventsMap } from '@socket.io/component-emitter';
24
24
  import type { StitchLogger } from '../logger';
25
- import type { RealtimeContract, RealtimeEventRegistry, RealtimeRejectedEventHook } from '../realtime/contract';
25
+ import type { RealtimeAcknowledgedEvent, RealtimeAcknowledgement, RealtimeContract, RealtimeEventRegistry, RealtimeRejectedEventHook, RealtimeRequestArguments } from '../realtime/contract';
26
+ import { type RealtimeRequestOptions } from '../realtime/request';
26
27
  import { type ValidatedRealtimeSocket } from '../realtime/socket';
27
28
  /**
28
29
  * Socket.IO event map — `{ event: (...args) => void }`. Aliases Socket.IO's
@@ -143,6 +144,11 @@ export interface SocketIOClient<TServerEvents extends SocketEventMap, TClientEve
143
144
  * of an unordered backlog of stale emits.
144
145
  */
145
146
  emit<E extends keyof TClientEvents & string>(event: E, ...args: Parameters<TClientEvents[E]>): boolean;
147
+ /**
148
+ * Low-level native Socket.IO acknowledgement request. Contract-aware callers
149
+ * should use `createRealtimeClient().request()`, which validates both sides.
150
+ */
151
+ emitWithAck(event: string, args: unknown[], options: RealtimeRequestOptions): Promise<unknown>;
146
152
  /**
147
153
  * Subscribe to connection up/down changes. Returns an unsubscribe. On a
148
154
  * disconnect the listener also receives the Socket.IO **reason** (e.g.
@@ -156,6 +162,10 @@ export interface RealtimeClient<TServerToClient extends RealtimeEventRegistry, T
156
162
  connect(): void;
157
163
  disconnect(): void;
158
164
  readonly connected: boolean;
165
+ request<TEvent extends RealtimeAcknowledgedEvent<TClientToServer>>(event: TEvent, ...args: [
166
+ ...RealtimeRequestArguments<TClientToServer[TEvent]>,
167
+ options: RealtimeRequestOptions
168
+ ]): Promise<RealtimeAcknowledgement<TClientToServer[TEvent]>>;
159
169
  onConnectionChange(listener: (connected: boolean, reason?: string) => void): () => void;
160
170
  }
161
171
  export interface RealtimeClientOptions<TServerToClient extends RealtimeEventRegistry> extends SocketIOClientConfig<{
@@ -1 +1 @@
1
- {"version":3,"file":"socket-io.d.ts","sourceRoot":"","sources":["../../src/browser/socket-io.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EACV,gBAAgB,EAChB,qBAAqB,EACrB,yBAAyB,EAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,oBAAoB,CAAC;AA0D5B;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC;AAEvC,MAAM,WAAW,oBAAoB,CAAC,aAAa,SAAS,cAAc,GAAG,cAAc;IACzF,qDAAqD;IACrD,GAAG,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,IAAI,CAAC,EACD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACvE,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IAClD;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,2EAA2E;IAC3E,UAAU,CAAC,EAAE,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IAC5C,iDAAiD;IACjD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,uDAAuD;IACvD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mDAAmD;IACnD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;;;;;OAcG;IACH,2BAA2B,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC7C;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC;IAC7C;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACzF;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,EAAE,CAAA;KAAE,KAAK,IAAI,CAAC;CACvE;AAED,MAAM,WAAW,cAAc,CAC7B,aAAa,SAAS,cAAc,EACpC,aAAa,SAAS,cAAc;IAEpC,6DAA6D;IAC7D,OAAO,IAAI,IAAI,CAAC;IAChB,+CAA+C;IAC/C,UAAU,IAAI,IAAI,CAAC;IACnB,qDAAqD;IACrD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B;;;;OAIG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,aAAa,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC;IAC5F;;;;;;;;OAQG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,aAAa,GAAG,MAAM,EACzC,KAAK,EAAE,CAAC,EACR,GAAG,IAAI,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GACpC,OAAO,CAAC;IACX;;;;;;OAMG;IACH,kBAAkB,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACzF;AAED,MAAM,WAAW,cAAc,CAC7B,eAAe,SAAS,qBAAqB,EAC7C,eAAe,SAAS,qBAAqB,CAC7C,SAAQ,uBAAuB,CAAC,eAAe,EAAE,eAAe,CAAC;IACjE,OAAO,IAAI,IAAI,CAAC;IAChB,UAAU,IAAI,IAAI,CAAC;IACnB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,kBAAkB,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACzF;AAED,MAAM,WAAW,qBAAqB,CAAC,eAAe,SAAS,qBAAqB,CAClF,SAAQ,oBAAoB,CAAC;KAC1B,MAAM,IAAI,MAAM,eAAe,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI;CAChE,CAAC;IACF,UAAU,CAAC,EAAE,yBAAyB,CAAC;IACvC,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,wBAAgB,oBAAoB,CAClC,KAAK,CAAC,eAAe,SAAS,qBAAqB,EACnD,KAAK,CAAC,eAAe,SAAS,qBAAqB,EAEnD,QAAQ,EAAE,gBAAgB,CAAC,eAAe,EAAE,eAAe,CAAC,EAC5D,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,EAAE,qBAAqB,CAAC,eAAe,CAAC,GACxE,cAAc,CAAC,eAAe,EAAE,eAAe,CAAC,CAiClD;AAED,wBAAgB,oBAAoB,CAClC,aAAa,SAAS,cAAc,EACpC,aAAa,SAAS,cAAc,EACpC,MAAM,EAAE,oBAAoB,CAAC,aAAa,CAAC,GAAG,cAAc,CAAC,aAAa,EAAE,aAAa,CAAC,CAuL3F"}
1
+ {"version":3,"file":"socket-io.d.ts","sourceRoot":"","sources":["../../src/browser/socket-io.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -5,15 +5,20 @@ import {
5
5
  emitResult,
6
6
  parseCliArgs,
7
7
  pollUntilDone
8
- } from "./index-7vb44hy8.js";
9
- import"./index-yxpe3phd.js";
10
- import"./index-173tvqcp.js";
11
- import"./index-bmnhqtya.js";
8
+ } from "./index-0gv7k0ra.js";
9
+ import"./index-sbdmyz75.js";
10
+ import"./index-k4dftwf7.js";
11
+ import"./index-cby4ar3v.js";
12
+ import"./index-v4bbq3p4.js";
13
+ import"./index-h60df7rj.js";
14
+ import"./index-6k1937bx.js";
15
+ import"./index-7eq9va6e.js";
16
+ import"./index-1bx83sw4.js";
12
17
  export {
13
- pollUntilDone,
14
- parseCliArgs,
15
- emitResult,
16
- defineCliCommand,
18
+ DEFAULT_EXIT_CODES,
17
19
  createCli,
18
- DEFAULT_EXIT_CODES
20
+ defineCliCommand,
21
+ emitResult,
22
+ parseCliArgs,
23
+ pollUntilDone
19
24
  };
@@ -0,0 +1,13 @@
1
+ import { z } from 'zod';
2
+ /** Canonical POSIX-style path relative to a managed file boundary. */
3
+ export declare const ManagedFilePathSchema: z.ZodString;
4
+ /** Transport-safe identity and metadata for a file owned by a managed boundary. */
5
+ export declare const ManagedFileRefSchema: z.ZodObject<{
6
+ path: z.ZodString;
7
+ size: z.ZodNumber;
8
+ mediaType: z.ZodOptional<z.ZodString>;
9
+ name: z.ZodOptional<z.ZodString>;
10
+ }, z.core.$strip>;
11
+ export type ManagedFilePath = z.infer<typeof ManagedFilePathSchema>;
12
+ export type ManagedFileRef = z.infer<typeof ManagedFileRefSchema>;
13
+ //# sourceMappingURL=file-ref.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-ref.d.ts","sourceRoot":"","sources":["../../src/contract/file-ref.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,sEAAsE;AACtE,eAAO,MAAM,qBAAqB,aAE6C,CAAC;AAEhF,mFAAmF;AACnF,eAAO,MAAM,oBAAoB;;;;;iBAK/B,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACpE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
@@ -2,5 +2,6 @@ export { ALL_TRANSPORTS, type BodyHttpSuccessStatus, type ClientRequestOptions,
2
2
  export { AppError, appError, badRequest, conflict, type ErrorEnvelope, forbidden, isStitchErrorCode, notFound, rateLimited, STITCH_ERROR_STATUS, type StitchErrorCode, unauthorized, } from './errors';
3
3
  export { type DefinedAppError, type DefinedErrors, defineErrors, type ErrorDefinition, type ErrorDefinitions, type ErrorDetailsOutput, type ErrorDetailsSchema, type ErrorFactories, type ErrorFactory, type ErrorFactoryArguments, type FrozenErrorDefinitions, } from './errors-factory';
4
4
  export { type ContractFactoryConfig, type ContractFactoryToolExposure, createContractFactory, type ExplicitScopedDefineContract, type ExplicitToolExposureEndpoints, type FactoryScopedEndpoint, type ScopedContractDef, type ScopedDefineContract, } from './factory';
5
+ export { type ManagedFilePath, ManagedFilePathSchema, type ManagedFileRef, ManagedFileRefSchema, } from './file-ref';
5
6
  export { decodeCursor, encodeCursor, type Paginated, paginatedSchema, } from './pagination';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contract/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,KAAK,aAAa,EAClB,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,KAAK,eAAe,EACpB,YAAY,GACb,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,YAAY,EACZ,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,qBAAqB,EACrB,KAAK,4BAA4B,EACjC,KAAK,6BAA6B,EAClC,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,KAAK,SAAS,EACd,eAAe,GAChB,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contract/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,KAAK,aAAa,EAClB,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,KAAK,eAAe,EACpB,YAAY,GACb,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,YAAY,EACZ,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,qBAAqB,EACrB,KAAK,4BAA4B,EACjC,KAAK,6BAA6B,EAClC,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,KAAK,eAAe,EACpB,qBAAqB,EACrB,KAAK,cAAc,EACnB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,KAAK,SAAS,EACd,eAAe,GAChB,MAAM,cAAc,CAAC"}
@@ -1,6 +1,8 @@
1
1
  import {
2
2
  ALL_TRANSPORTS,
3
3
  AppError,
4
+ ManagedFilePathSchema,
5
+ ManagedFileRefSchema,
4
6
  STITCH_ERROR_STATUS,
5
7
  appError,
6
8
  badRequest,
@@ -16,24 +18,26 @@ import {
16
18
  paginatedSchema,
17
19
  rateLimited,
18
20
  unauthorized
19
- } from "../index-pfqjb5xy.js";
21
+ } from "../index-rgd18hx3.js";
20
22
  import"../index-tss6bk5c.js";
21
23
  export {
22
- unauthorized,
23
- rateLimited,
24
- paginatedSchema,
25
- notFound,
26
- isStitchErrorCode,
27
- forbidden,
28
- encodeCursor,
29
- defineErrors,
30
- defineContract,
31
- decodeCursor,
32
- createContractFactory,
33
- conflict,
34
- badRequest,
35
- appError,
36
- STITCH_ERROR_STATUS,
24
+ ALL_TRANSPORTS,
37
25
  AppError,
38
- ALL_TRANSPORTS
26
+ ManagedFilePathSchema,
27
+ ManagedFileRefSchema,
28
+ STITCH_ERROR_STATUS,
29
+ appError,
30
+ badRequest,
31
+ conflict,
32
+ createContractFactory,
33
+ decodeCursor,
34
+ defineContract,
35
+ defineErrors,
36
+ encodeCursor,
37
+ forbidden,
38
+ isStitchErrorCode,
39
+ notFound,
40
+ paginatedSchema,
41
+ rateLimited,
42
+ unauthorized
39
43
  };
@@ -0,0 +1,52 @@
1
+ import { type ManagedFileRef } from '../contract/file-ref';
2
+ export type ManagedFileErrorCode = 'FILE_INVALID_PATH' | 'FILE_NOT_FOUND' | 'FILE_NOT_REGULAR' | 'FILE_OUTSIDE_ROOT' | 'FILE_TOO_LARGE' | 'FILE_EXISTS' | 'FILE_INSPECTION_REJECTED' | 'FILE_IO_ERROR';
3
+ export declare class ManagedFileError extends Error {
4
+ readonly code: ManagedFileErrorCode;
5
+ constructor(code: ManagedFileErrorCode, message: string, options?: ErrorOptions);
6
+ }
7
+ export interface ManagedFileInspectionInput {
8
+ prefix: Uint8Array;
9
+ declaredMediaType?: string;
10
+ name: string;
11
+ }
12
+ export interface ManagedFileInspection {
13
+ mediaType?: string;
14
+ name?: string;
15
+ }
16
+ export type ManagedFileInspector = (input: ManagedFileInspectionInput) => ManagedFileInspection | Promise<ManagedFileInspection>;
17
+ export interface ManagedFileBoundaryConfig {
18
+ /** Existing directory owned exclusively by the application or trusted OS actor. */
19
+ root: string;
20
+ maxReadBytes?: number;
21
+ maxWriteBytes?: number;
22
+ inspectionBytes?: number;
23
+ inspect?: ManagedFileInspector;
24
+ onCleanupError?: (error: unknown) => void;
25
+ }
26
+ export interface ManagedFileReadOptions {
27
+ maxBytes?: number;
28
+ signal?: AbortSignal;
29
+ }
30
+ export interface ManagedFileWriteOptions {
31
+ replace?: boolean;
32
+ durable?: boolean;
33
+ maxBytes?: number;
34
+ mediaType?: string;
35
+ name?: string;
36
+ signal?: AbortSignal;
37
+ }
38
+ export interface ManagedFileSource {
39
+ ref: ManagedFileRef;
40
+ bytes: Uint8Array;
41
+ }
42
+ export interface ManagedFileBoundary {
43
+ read(path: string, options?: ManagedFileReadOptions): Promise<ManagedFileSource>;
44
+ write(path: string, source: Uint8Array | ReadableStream<Uint8Array>, options?: ManagedFileWriteOptions): Promise<ManagedFileRef>;
45
+ }
46
+ /**
47
+ * Bind one existing application-owned directory as a portable Node/Bun file boundary.
48
+ * Concurrent replacement by another filesystem actor is intentionally outside this
49
+ * portable threat model; use OS-specific descriptor-relative isolation for that case.
50
+ */
51
+ export declare function createManagedFileBoundary(config: ManagedFileBoundaryConfig): Promise<ManagedFileBoundary>;
52
+ //# sourceMappingURL=boundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boundary.d.ts","sourceRoot":"","sources":["../../src/files/boundary.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,sBAAsB,CAAC;AAO9B,MAAM,MAAM,oBAAoB,GAC5B,mBAAmB,GACnB,gBAAgB,GAChB,kBAAkB,GAClB,mBAAmB,GACnB,gBAAgB,GAChB,aAAa,GACb,0BAA0B,GAC1B,eAAe,CAAC;AAEpB,qBAAa,gBAAiB,SAAQ,KAAK;aAEvB,IAAI,EAAE,oBAAoB;IAD5C,YACkB,IAAI,EAAE,oBAAoB,EAC1C,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,YAAY,EAIvB;CACF;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,UAAU,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,oBAAoB,GAAG,CACjC,KAAK,EAAE,0BAA0B,KAC9B,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAE5D,MAAM,WAAW,yBAAyB;IACxC,mFAAmF;IACnF,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,cAAc,CAAC;IACpB,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACjF,KAAK,CACH,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,GAAG,cAAc,CAAC,UAAU,CAAC,EAC/C,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,cAAc,CAAC,CAAC;CAC5B;AAyID;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,mBAAmB,CAAC,CAqJ9B"}
@@ -0,0 +1,3 @@
1
+ export { type ManagedFilePath, ManagedFilePathSchema, type ManagedFileRef, ManagedFileRefSchema, } from './contract/file-ref';
2
+ export { createManagedFileBoundary, type ManagedFileBoundary, type ManagedFileBoundaryConfig, ManagedFileError, type ManagedFileErrorCode, type ManagedFileInspection, type ManagedFileInspectionInput, type ManagedFileInspector, type ManagedFileReadOptions, type ManagedFileSource, type ManagedFileWriteOptions, } from './files/boundary';
3
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EACpB,qBAAqB,EACrB,KAAK,cAAc,EACnB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,gBAAgB,EAChB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAC/B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,kBAAkB,CAAC"}
package/dist/files.js ADDED
@@ -0,0 +1,16 @@
1
+ import {
2
+ ManagedFileError,
3
+ createManagedFileBoundary
4
+ } from "./index-1k16zv57.js";
5
+ import"./index-sbdmyz75.js";
6
+ import {
7
+ ManagedFilePathSchema,
8
+ ManagedFileRefSchema
9
+ } from "./index-6k1937bx.js";
10
+ import"./index-1bx83sw4.js";
11
+ export {
12
+ ManagedFileError,
13
+ ManagedFilePathSchema,
14
+ ManagedFileRefSchema,
15
+ createManagedFileBoundary
16
+ };
@@ -1,23 +1,33 @@
1
1
  import {
2
- isWithinDir,
2
+ isWithinDir
3
+ } from "./index-sbdmyz75.js";
4
+ import {
5
+ assertToolName,
6
+ assertUniqueToolName,
7
+ hasUsableChars,
8
+ toToolName
9
+ } from "./index-k4dftwf7.js";
10
+ import {
3
11
  jsonSchemaFields,
4
12
  toJsonSchema
5
- } from "./index-yxpe3phd.js";
13
+ } from "./index-cby4ar3v.js";
6
14
  import {
7
- AppError,
8
- STITCH_ERROR_STATUS,
9
15
  formatZodError,
10
16
  getRequestContext,
11
- isStitchErrorCode,
12
- isUnsafeKey,
13
17
  normalizeError,
14
18
  runWithRequestContext,
15
- safeJsonParse,
16
19
  validateDeclaredOutput
17
- } from "./index-173tvqcp.js";
20
+ } from "./index-v4bbq3p4.js";
21
+ import {
22
+ AppError,
23
+ STITCH_ERROR_STATUS,
24
+ isStitchErrorCode,
25
+ isUnsafeKey,
26
+ safeJsonParse
27
+ } from "./index-h60df7rj.js";
18
28
  import {
19
29
  isRecord
20
- } from "./index-bmnhqtya.js";
30
+ } from "./index-7eq9va6e.js";
21
31
 
22
32
  // src/tools/coerce.ts
23
33
  import { z } from "zod";
@@ -769,71 +779,6 @@ async function runToolMethod(method, toolName, rawArgs, context, hooks, lifecycl
769
779
  }
770
780
  }
771
781
 
772
- // src/tools/names.ts
773
- var SINGULAR_EXCEPTIONS = new Set([
774
- "analytics",
775
- "status",
776
- "stats",
777
- "settings",
778
- "media",
779
- "progress",
780
- "news"
781
- ]);
782
- var TOOL_NAME_RE = /^[a-zA-Z0-9_-]{1,64}$/;
783
- function normalizeService(value) {
784
- return value.replace(/[^a-zA-Z0-9_]/g, "_");
785
- }
786
- function normalizeMethod(value) {
787
- return value.replace(/[^a-zA-Z0-9_-]/g, "_");
788
- }
789
- function singularize(name) {
790
- if (SINGULAR_EXCEPTIONS.has(name))
791
- return name;
792
- if (name.endsWith("ies"))
793
- return `${name.slice(0, -3)}y`;
794
- if (name.endsWith("s") && !name.endsWith("ss"))
795
- return name.slice(0, -1);
796
- return name;
797
- }
798
- function singularizeTail(name) {
799
- const cut = name.lastIndexOf("_");
800
- if (cut === -1)
801
- return singularize(name);
802
- return `${name.slice(0, cut + 1)}${singularize(name.slice(cut + 1))}`;
803
- }
804
- function hasUsableChars(value) {
805
- return /[a-zA-Z0-9]/.test(value);
806
- }
807
- function assertToolName(name, serviceName, key) {
808
- const where = `service "${serviceName}", method "${key}"`;
809
- if (!TOOL_NAME_RE.test(name)) {
810
- const why = name.length > 64 ? `is ${name.length} characters (max 64) — set an explicit \`toolName\`` : "must match [a-zA-Z0-9_-]";
811
- throw new Error(`Tool name "${name}" (${where}) ${why}`);
812
- }
813
- }
814
- function toToolName(serviceName, methodName) {
815
- const normalized = normalizeService(serviceName);
816
- const singular = singularizeTail(normalized);
817
- const method = normalizeMethod(methodName);
818
- if (method === "list")
819
- return `list_${normalized}`;
820
- if (method === "get")
821
- return `get_${singular}`;
822
- if (method === "create")
823
- return `create_${singular}`;
824
- if (method === "update")
825
- return `update_${singular}`;
826
- if (method === "delete")
827
- return `delete_${singular}`;
828
- const snake = method.replace(/([A-Z])/g, "_$1").toLowerCase();
829
- return `${snake}_${singular}`.replace(/^_/, "");
830
- }
831
- function assertUniqueToolName(name, taken, surface) {
832
- if (taken) {
833
- throw new Error(`Duplicate ${surface} "${name}" across mounted operations`);
834
- }
835
- }
836
-
837
782
  // src/tools/presentation.ts
838
783
  import { z as z3 } from "zod";
839
784
  function withoutDialect(schema) {
@@ -1494,19 +1439,21 @@ var DEFAULT_EXIT_CODES = {
1494
1439
  CONFLICT: 5,
1495
1440
  RATE_LIMITED: 6,
1496
1441
  TIMEOUT: 7,
1442
+ WAIT_FAILED: 1,
1497
1443
  INTERNAL_SERVER_ERROR: 1
1498
1444
  };
1499
1445
  function emitResult(result, writers, opts) {
1500
1446
  if (result.ok) {
1501
1447
  if (result.data === undefined)
1502
1448
  return 0;
1503
- const text = opts.json ? JSON.stringify(result.data) : JSON.stringify(result.data, null, 2);
1504
- writers.stdout(`${text}
1449
+ const text2 = opts.json ? JSON.stringify(result.data) : JSON.stringify(result.data, null, 2);
1450
+ writers.stdout(`${text2}
1505
1451
  `);
1506
1452
  return 0;
1507
1453
  }
1508
1454
  const error = formatToolError(result, opts.toolName, opts.errorHint);
1509
- writers.stderr(`${JSON.stringify(error, null, 2)}
1455
+ const text = opts.json ? JSON.stringify(error) : JSON.stringify(error, null, 2);
1456
+ writers.stderr(`${text}
1510
1457
  `);
1511
1458
  const codes = opts.exitCodes ?? DEFAULT_EXIT_CODES;
1512
1459
  return codes[result.code] ?? 1;
@@ -1515,6 +1462,13 @@ function emitResult(result, writers, opts) {
1515
1462
  // src/tools/wait-core.ts
1516
1463
  var DEFAULT_BACKOFF = [2, 3, 5, 5, 8, 10];
1517
1464
  var DEFAULT_TIMEOUT = 600;
1465
+
1466
+ class WaitTimeoutError extends Error {
1467
+ constructor() {
1468
+ super("wait deadline elapsed before the first snapshot");
1469
+ this.name = "WaitTimeoutError";
1470
+ }
1471
+ }
1518
1472
  var defaultSleep = (ms, signal) => {
1519
1473
  signal?.throwIfAborted();
1520
1474
  return new Promise((resolve, reject) => {
@@ -1544,52 +1498,104 @@ async function pollUntil(params) {
1544
1498
  const lastBackoff = backoff[backoff.length - 1] ?? 5;
1545
1499
  const timeoutSec = params.timeoutSec ?? DEFAULT_TIMEOUT;
1546
1500
  const sleep = params.sleepFn ?? defaultSleep;
1547
- const startedAt = Date.now();
1501
+ const now = params.nowFn ?? (() => performance.now());
1502
+ const startedAt = now();
1503
+ const deadline = startedAt + timeoutSec * 1000;
1504
+ let last;
1548
1505
  for (let attempt = 0;; attempt++) {
1549
1506
  params.signal?.throwIfAborted();
1550
- const state = await params.poll();
1507
+ const remainingBeforePoll = Math.max(0, deadline - now());
1508
+ if (remainingBeforePoll === 0 && last) {
1509
+ return { state: last.state, timedOut: true };
1510
+ }
1511
+ const deadlineController = new AbortController;
1512
+ const onCallerAbort = () => deadlineController.abort(params.signal?.reason);
1513
+ params.signal?.addEventListener("abort", onCallerAbort, { once: true });
1514
+ const deadlineTimer = setTimeout(() => deadlineController.abort(new WaitTimeoutError), remainingBeforePoll);
1515
+ deadlineTimer.unref?.();
1516
+ let state;
1517
+ try {
1518
+ state = await params.poll(deadlineController.signal);
1519
+ } catch (error) {
1520
+ if (params.signal?.aborted)
1521
+ throw params.signal.reason ?? error;
1522
+ if (deadlineController.signal.aborted && now() >= deadline) {
1523
+ if (last)
1524
+ return { state: last.state, timedOut: true };
1525
+ throw new WaitTimeoutError;
1526
+ }
1527
+ throw error;
1528
+ } finally {
1529
+ clearTimeout(deadlineTimer);
1530
+ params.signal?.removeEventListener("abort", onCallerAbort);
1531
+ }
1551
1532
  params.signal?.throwIfAborted();
1533
+ last = { state };
1552
1534
  if (params.done(state))
1553
1535
  return { state, timedOut: false };
1554
- const elapsedSec = (Date.now() - startedAt) / 1000;
1536
+ const elapsedMs = now() - startedAt;
1537
+ const elapsedSec = elapsedMs / 1000;
1555
1538
  params.onTick?.(attempt + 1, elapsedSec);
1556
1539
  if (elapsedSec >= timeoutSec)
1557
1540
  return { state, timedOut: true };
1558
1541
  const waitSec = backoff[Math.min(attempt, backoff.length - 1)] ?? lastBackoff;
1559
- await sleep(waitSec * 1000, params.signal);
1542
+ await sleep(Math.min(waitSec * 1000, Math.max(0, deadline - now())), params.signal);
1560
1543
  }
1561
1544
  }
1562
1545
  function runWaitOperation(params) {
1563
1546
  return pollUntil({
1564
- poll: () => params.poll(params.input, params.signal),
1547
+ poll: (signal) => params.poll(params.input, signal),
1565
1548
  done: params.done,
1566
1549
  backoff: params.backoff,
1567
1550
  timeoutSec: params.timeoutSec,
1568
1551
  sleepFn: params.sleepFn,
1569
1552
  onTick: params.onTick,
1570
- signal: params.signal
1553
+ signal: params.signal,
1554
+ nowFn: params.nowFn
1571
1555
  });
1572
1556
  }
1573
1557
 
1574
1558
  // src/tools/cli-wait.ts
1575
1559
  var DEFAULT_TIMEOUT2 = 600;
1560
+ function waitFailure(tool, result) {
1561
+ return {
1562
+ ok: false,
1563
+ code: "WAIT_FAILED",
1564
+ details: {
1565
+ message: `"${tool}" reached a terminal failed state`,
1566
+ result
1567
+ }
1568
+ };
1569
+ }
1576
1570
  async function pollUntilDone(params) {
1577
1571
  const { initial, wait, call } = params;
1578
1572
  if (!initial.ok)
1579
1573
  return initial;
1574
+ if (wait.failed?.(initial.data))
1575
+ return waitFailure(wait.tool, initial.data);
1580
1576
  if (wait.done(initial.data))
1581
1577
  return initial;
1582
1578
  const pollArgs = wait.poll(initial.data);
1583
1579
  if (!pollArgs)
1584
1580
  return initial;
1585
1581
  const timeoutSec = params.timeoutSec ?? wait.timeout ?? DEFAULT_TIMEOUT2;
1582
+ let failedState;
1586
1583
  const { state, timedOut } = await pollUntil({
1587
1584
  poll: () => call(wait.tool, pollArgs),
1588
- done: (result) => !result.ok || wait.done(result.data),
1585
+ done: (result) => {
1586
+ if (!result.ok)
1587
+ return true;
1588
+ if (wait.failed?.(result.data)) {
1589
+ failedState = result;
1590
+ return true;
1591
+ }
1592
+ return wait.done(result.data);
1593
+ },
1589
1594
  backoff: wait.backoff,
1590
1595
  timeoutSec,
1591
1596
  sleepFn: params.sleepFn,
1592
- onTick: params.onTick
1597
+ onTick: params.onTick,
1598
+ signal: params.signal
1593
1599
  });
1594
1600
  if (timedOut) {
1595
1601
  return {
@@ -1598,6 +1604,8 @@ async function pollUntilDone(params) {
1598
1604
  details: { message: `Timed out after ${timeoutSec}s waiting for "${wait.tool}"` }
1599
1605
  };
1600
1606
  }
1607
+ if (state === failedState && state.ok)
1608
+ return waitFailure(wait.tool, state.data);
1601
1609
  return state;
1602
1610
  }
1603
1611
 
@@ -1961,7 +1969,7 @@ function collectToolSurface({
1961
1969
 
1962
1970
  // src/tools/cli.ts
1963
1971
  var GLOBAL_OPTIONS = [
1964
- ["--json", "Emit raw JSON on stdout (for piping / scripts)"],
1972
+ ["--json", "Emit compact success/error JSON records (for scripts)"],
1965
1973
  ["--wait", "Block-poll an async result to a terminal state"],
1966
1974
  ["--wait-timeout <s>", "Override the --wait timeout in seconds"],
1967
1975
  ["--output-dir <dir>", "Download result media into a directory"],
@@ -2058,15 +2066,41 @@ function renderTopHelp(name, version, commands) {
2058
2066
  `;
2059
2067
  }
2060
2068
  function renderCommandHelp(name, command, descriptor) {
2061
- const lines = [descriptor.description, "", `Usage: ${name} ${command} [args] [--flags]`, ""];
2062
2069
  const fields = jsonSchemaFields(descriptor.presentationSchema);
2070
+ const fieldsByName = new Map(fields.map((field) => [field.name, field]));
2071
+ const positionals = [];
2072
+ for (const [fieldName, info] of describeSchemaFields(descriptor.argumentSchema)) {
2073
+ if (info.kind === "boolean")
2074
+ continue;
2075
+ const field = fieldsByName.get(fieldName);
2076
+ if (field)
2077
+ positionals.push(field);
2078
+ }
2079
+ const positionalSyntax = new Map(positionals.map((field) => [
2080
+ field.name,
2081
+ field.required ? `<${field.name}>` : `[${field.name}]`
2082
+ ]));
2083
+ const usage = [
2084
+ `Usage: ${name} ${command}`,
2085
+ ...positionals.map((field) => positionalSyntax.get(field.name) ?? field.name),
2086
+ "[--flags]"
2087
+ ].join(" ");
2088
+ const lines = [descriptor.description, "", usage, ""];
2063
2089
  if (fields.length > 0) {
2064
2090
  lines.push("Arguments:");
2065
- const width = Math.max(...fields.map((f) => f.name.length));
2091
+ const labels = new Map(fields.map((field) => {
2092
+ const positional = positionalSyntax.get(field.name);
2093
+ return [
2094
+ field.name,
2095
+ positional ? `${positional} | --${field.name}` : `--${field.name}`
2096
+ ];
2097
+ }));
2098
+ const width = Math.max(...fields.map((field) => labels.get(field.name)?.length ?? 0));
2066
2099
  for (const f of fields) {
2067
2100
  const req = f.required ? " (required)" : "";
2068
2101
  const desc = f.description ? ` — ${f.description}` : "";
2069
- lines.push(` --${padRight(f.name, width)} <${typeLabel(f.schema)}>${req}${desc}`);
2102
+ const label = labels.get(f.name) ?? `--${f.name}`;
2103
+ lines.push(` ${padRight(label, width)} <${typeLabel(f.schema)}>${req}${desc}`);
2070
2104
  }
2071
2105
  lines.push("");
2072
2106
  }
@@ -2302,7 +2336,7 @@ async function createCli(config) {
2302
2336
  }
2303
2337
  const runTool = createToolRunner({
2304
2338
  source: "cli",
2305
- context: config.context?.(managed.auth),
2339
+ context: { ...config.context?.(managed.auth), signal: config.signal },
2306
2340
  hooks: config.hooks,
2307
2341
  lifecycle: config.lifecycle,
2308
2342
  errorHint: config.errorHint,
@@ -2332,7 +2366,8 @@ async function createCli(config) {
2332
2366
  },
2333
2367
  timeoutSec: options.waitTimeout,
2334
2368
  onTick: options.quiet ? undefined : (attempt) => stderr(`waiting… (poll ${attempt})
2335
- `)
2369
+ `),
2370
+ signal: config.signal
2336
2371
  });
2337
2372
  }
2338
2373
  let downloadsOk = true;
@@ -2348,4 +2383,4 @@ async function createCli(config) {
2348
2383
  return exit(downloadsOk ? exitCode : 1);
2349
2384
  }
2350
2385
 
2351
- export { coerceJsonArgs, toolResultFromError, toolErrorFromResult, executeToolMethod, assertToolName, assertUniqueToolName, flattenToolJsonSchema, buildToolPresentationSchema, isObjectPresentationSchema, presentationMetadata, collectTools, createToolRunner, formatToolError, defineRuntimeTool, createRuntimeToolFactory, collectToolSurface, fetchGuarded, fetchPinnedDocument, readCapped, writeDownload, parseCliArgs, defineCliCommand, DEFAULT_EXIT_CODES, emitResult, runWaitOperation, pollUntilDone, createCli };
2386
+ export { coerceJsonArgs, toolResultFromError, toolErrorFromResult, executeToolMethod, flattenToolJsonSchema, buildToolPresentationSchema, isObjectPresentationSchema, presentationMetadata, collectTools, createToolRunner, formatToolError, defineRuntimeTool, createRuntimeToolFactory, collectToolSurface, WaitTimeoutError, runWaitOperation, fetchGuarded, fetchPinnedDocument, readCapped, parseCliArgs, defineCliCommand, DEFAULT_EXIT_CODES, emitResult, pollUntilDone, createCli };
@@ -0,0 +1,4 @@
1
+ import { createRequire } from "node:module";
2
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
3
+
4
+ export { __require };