stitchkit 0.122.1 → 0.123.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 (201) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/dist/agent-runtime/deferred-tool-search.d.ts.map +1 -1
  3. package/dist/agent-runtime/deferred-tool-types.d.ts.map +1 -1
  4. package/dist/browser/client.d.ts.map +1 -1
  5. package/dist/browser/contract-identity.d.ts +21 -0
  6. package/dist/browser/contract-identity.d.ts.map +1 -0
  7. package/dist/browser/unknown-operation.d.ts +3 -0
  8. package/dist/browser/unknown-operation.d.ts.map +1 -0
  9. package/dist/contract/define.d.ts +6 -2
  10. package/dist/contract/define.d.ts.map +1 -1
  11. package/dist/contract/endpoint-capabilities.d.ts.map +1 -1
  12. package/dist/contract/errors.d.ts +4 -0
  13. package/dist/contract/errors.d.ts.map +1 -1
  14. package/dist/contract/fingerprint.d.ts +51 -0
  15. package/dist/contract/fingerprint.d.ts.map +1 -0
  16. package/dist/contract/identity.d.ts +21 -0
  17. package/dist/contract/identity.d.ts.map +1 -0
  18. package/dist/contract/stream.d.ts +32 -0
  19. package/dist/contract/stream.d.ts.map +1 -1
  20. package/dist/entrypoints/agent-runtime/browser.js +2 -2
  21. package/dist/entrypoints/agent-runtime/coding-tools.js +11 -11
  22. package/dist/entrypoints/agent-runtime/harness.js +12 -12
  23. package/dist/entrypoints/agent-runtime/openrouter.js +1 -1
  24. package/dist/entrypoints/agent-runtime/realtime.js +2 -2
  25. package/dist/entrypoints/agent-runtime/sandbox.js +11 -11
  26. package/dist/entrypoints/agent-runtime/sqlite/bun.js +15 -15
  27. package/dist/entrypoints/agent-runtime/sqlite/node.js +15 -15
  28. package/dist/entrypoints/agent-runtime/testing.js +15 -15
  29. package/dist/entrypoints/agent-runtime.js +26 -25
  30. package/dist/entrypoints/application/diagnostic-journal.js +5 -5
  31. package/dist/entrypoints/application/directory-inbox.js +5 -5
  32. package/dist/entrypoints/application/grammy.js +1 -1
  33. package/dist/entrypoints/application.js +7 -7
  34. package/dist/entrypoints/cli/publish.js +5 -5
  35. package/dist/entrypoints/cli.d.ts +1 -1
  36. package/dist/entrypoints/cli.d.ts.map +1 -1
  37. package/dist/entrypoints/cli.js +20 -17
  38. package/dist/entrypoints/contract.d.ts +2 -0
  39. package/dist/entrypoints/contract.d.ts.map +1 -1
  40. package/dist/entrypoints/contract.js +11 -5
  41. package/dist/entrypoints/files/packaging.d.ts +1 -0
  42. package/dist/entrypoints/files/packaging.d.ts.map +1 -1
  43. package/dist/entrypoints/files/packaging.js +230 -61
  44. package/dist/entrypoints/files.js +5 -5
  45. package/dist/entrypoints/geo.js +3 -3
  46. package/dist/entrypoints/http.js +3 -3
  47. package/dist/entrypoints/index.d.ts +1 -0
  48. package/dist/entrypoints/index.d.ts.map +1 -1
  49. package/dist/entrypoints/index.js +45 -24
  50. package/dist/entrypoints/live.js +2 -2
  51. package/dist/entrypoints/node.js +11 -11
  52. package/dist/entrypoints/observability.js +4 -4
  53. package/dist/entrypoints/primitives.js +1 -1
  54. package/dist/entrypoints/process/owner-loss.js +2 -2
  55. package/dist/entrypoints/process.d.ts +6 -1
  56. package/dist/entrypoints/process.d.ts.map +1 -1
  57. package/dist/entrypoints/process.js +370 -9
  58. package/dist/entrypoints/react.js +2 -2
  59. package/dist/entrypoints/realtime.js +3 -3
  60. package/dist/entrypoints/remote.js +20 -10
  61. package/dist/entrypoints/server.d.ts +1 -0
  62. package/dist/entrypoints/server.d.ts.map +1 -1
  63. package/dist/entrypoints/server.js +56 -20
  64. package/dist/entrypoints/telegram/screens.js +4 -4
  65. package/dist/entrypoints/telegram.js +6 -6
  66. package/dist/entrypoints/testing.js +10 -10
  67. package/dist/entrypoints/tools/agent.js +9 -9
  68. package/dist/entrypoints/tools/connections.js +7 -7
  69. package/dist/entrypoints/tools/contract.js +1 -1
  70. package/dist/entrypoints/tools/invoker.js +7 -7
  71. package/dist/entrypoints/tools/mcp.js +9 -9
  72. package/dist/entrypoints/tools/toolkit.js +15 -14
  73. package/dist/entrypoints/tools.js +17 -17
  74. package/dist/entrypoints/tracking/contract.js +2 -2
  75. package/dist/entrypoints/tracking.js +1 -1
  76. package/dist/files/client-artifact.d.ts +75 -0
  77. package/dist/files/client-artifact.d.ts.map +1 -0
  78. package/dist/{index-am1h8c9v.js → index-0d3sm0m9.js} +5 -5
  79. package/dist/{index-72xtvcvr.js → index-0ndz5r8z.js} +1 -1
  80. package/dist/index-0v9xb8pz.js +66 -0
  81. package/dist/{index-qcn84byh.js → index-0w0hxp7n.js} +4 -0
  82. package/dist/{index-3za04re9.js → index-1c945ten.js} +1 -1
  83. package/dist/{index-r6v4mc67.js → index-1d7s7da0.js} +1 -1
  84. package/dist/{index-zsvzhjtk.js → index-20hn8pbh.js} +1 -1
  85. package/dist/{index-f6pw75e1.js → index-2x2ch0bt.js} +2 -2
  86. package/dist/{index-61hve0ez.js → index-303qne11.js} +1 -1
  87. package/dist/{index-g149e9pk.js → index-3bzk2645.js} +1 -1
  88. package/dist/index-45dyex0j.js +119 -0
  89. package/dist/{index-nwm3ww60.js → index-64b2dxqz.js} +1 -1
  90. package/dist/{index-aqwg2dm5.js → index-6k47xdtt.js} +2 -2
  91. package/dist/index-7q05ag0z.js +10 -0
  92. package/dist/{index-kz9734jc.js → index-96yjwwgf.js} +6 -5
  93. package/dist/{index-ff39f9dr.js → index-993vtv1w.js} +3 -3
  94. package/dist/{index-4jpykzvw.js → index-99nnsz39.js} +2 -2
  95. package/dist/{index-pfvde2fz.js → index-9ypczvpj.js} +1 -1
  96. package/dist/{index-qch1vcaa.js → index-a7ebd769.js} +2 -2
  97. package/dist/{index-98hv3sba.js → index-aw6kx2e6.js} +1 -1
  98. package/dist/{index-yj6saztf.js → index-bz9cmnqq.js} +96 -14
  99. package/dist/{index-mtwh9hyp.js → index-cjzaj7ev.js} +1 -1
  100. package/dist/{index-gtx3eknx.js → index-dv7pa9w6.js} +2 -2
  101. package/dist/{index-sa99p98w.js → index-eabx6qjh.js} +3 -3
  102. package/dist/{index-8yxgcyt6.js → index-egg0yp2j.js} +1 -1
  103. package/dist/{index-h1j71dr1.js → index-enkc9pem.js} +1 -1
  104. package/dist/{index-aqmadanx.js → index-fa53vygr.js} +2 -2
  105. package/dist/{index-e6c2spsd.js → index-fpwbskp2.js} +1 -1
  106. package/dist/{index-m8a44e64.js → index-ftk3838x.js} +1 -1
  107. package/dist/{index-j95jp7ee.js → index-gdqawggb.js} +1 -1
  108. package/dist/{index-9dyd8xzf.js → index-hkw233vx.js} +2 -2
  109. package/dist/{index-9jfdm5tg.js → index-hkxgennw.js} +7 -1
  110. package/dist/{index-qaqxdbxf.js → index-j8rda9n6.js} +7 -7
  111. package/dist/{index-4tyt1qya.js → index-jc5xgkpk.js} +2 -2
  112. package/dist/{index-s9a0fjh3.js → index-kffm4r8w.js} +1 -1
  113. package/dist/{index-5w6t91ze.js → index-m8ddk770.js} +1 -1
  114. package/dist/{index-2fc1k9k2.js → index-mdyhr36s.js} +32 -122
  115. package/dist/{index-r7a7r7ha.js → index-mfntvj58.js} +6 -3
  116. package/dist/{index-gq3fnq3f.js → index-n90tkkcv.js} +2 -2
  117. package/dist/{index-k42ckyzx.js → index-ndjzbt2v.js} +2 -2
  118. package/dist/{index-ycqhyars.js → index-qc7tq0za.js} +3 -3
  119. package/dist/{index-9frf01t9.js → index-r0xr7y4m.js} +1 -1
  120. package/dist/{index-s3yxw6kt.js → index-s512scra.js} +9 -7
  121. package/dist/{index-1h2zv8rx.js → index-sqc6ezrb.js} +41 -1
  122. package/dist/{index-2bqf0a74.js → index-sqkttz7z.js} +1 -1
  123. package/dist/{index-rbzq0q16.js → index-t8jz0e20.js} +1 -1
  124. package/dist/{index-8ryydawp.js → index-tt3ej8r3.js} +1 -1
  125. package/dist/{index-x4p3kw1p.js → index-tynna0n4.js} +6 -6
  126. package/dist/{index-72r9k0av.js → index-v62cpkx3.js} +1 -1
  127. package/dist/{index-10rg78vf.js → index-v8xm2s9v.js} +2 -2
  128. package/dist/{index-y6ye582c.js → index-w0wy05gr.js} +10 -10
  129. package/dist/{index-kw1ws0cs.js → index-w3nv6kr8.js} +1 -1
  130. package/dist/{index-eeahxwvg.js → index-ww3gss55.js} +1 -1
  131. package/dist/{index-6j15ktag.js → index-wzqd6pen.js} +1 -1
  132. package/dist/{index-aswegq1r.js → index-xjb131sc.js} +367 -131
  133. package/dist/{index-1fyea34p.js → index-yebkpytc.js} +5 -5
  134. package/dist/{index-bgcwxhxh.js → index-yfpt7sxr.js} +24 -46
  135. package/dist/{index-69t14s4a.js → index-yt1gg11x.js} +3 -2
  136. package/dist/{index-jk29rwkr.js → index-zfncctjp.js} +1 -1
  137. package/dist/internal/stable-digest.d.ts +5 -0
  138. package/dist/internal/stable-digest.d.ts.map +1 -1
  139. package/dist/internal/typed.d.ts +2 -0
  140. package/dist/internal/typed.d.ts.map +1 -1
  141. package/dist/process/operation-child.d.ts +38 -0
  142. package/dist/process/operation-child.d.ts.map +1 -0
  143. package/dist/process/operation-wire.d.ts +68 -0
  144. package/dist/process/operation-wire.d.ts.map +1 -0
  145. package/dist/process/operation.d.ts +74 -0
  146. package/dist/process/operation.d.ts.map +1 -0
  147. package/dist/server/contract-identity.d.ts +10 -0
  148. package/dist/server/contract-identity.d.ts.map +1 -0
  149. package/dist/server/contract-stream.d.ts.map +1 -1
  150. package/dist/server/endpoint-response.d.ts.map +1 -1
  151. package/dist/server/error-hook.d.ts +1 -0
  152. package/dist/server/error-hook.d.ts.map +1 -1
  153. package/dist/tools/cli/args-route.d.ts.map +1 -1
  154. package/dist/tools/cli/args-tokens.d.ts.map +1 -1
  155. package/dist/tools/cli/command.d.ts +39 -18
  156. package/dist/tools/cli/command.d.ts.map +1 -1
  157. package/dist/tools/cli/format.d.ts.map +1 -1
  158. package/dist/tools/cli/help.d.ts.map +1 -1
  159. package/dist/tools/cli/invoke.d.ts +3 -1
  160. package/dist/tools/cli/invoke.d.ts.map +1 -1
  161. package/dist/tools/cli/io.d.ts +6 -0
  162. package/dist/tools/cli/io.d.ts.map +1 -1
  163. package/dist/tools/cli/managed-surface.d.ts +2 -0
  164. package/dist/tools/cli/managed-surface.d.ts.map +1 -1
  165. package/dist/tools/cli/policy.d.ts +14 -0
  166. package/dist/tools/cli/policy.d.ts.map +1 -1
  167. package/dist/tools/cli/run-managed.d.ts.map +1 -1
  168. package/dist/tools/cli/run-native.d.ts.map +1 -1
  169. package/dist/tools/cli/run-stream.d.ts +23 -0
  170. package/dist/tools/cli/run-stream.d.ts.map +1 -0
  171. package/dist/tools/cli/session.d.ts +8 -0
  172. package/dist/tools/cli/session.d.ts.map +1 -1
  173. package/dist/tools/cli/stream-surface.d.ts +17 -0
  174. package/dist/tools/cli/stream-surface.d.ts.map +1 -0
  175. package/dist/tools/execute.d.ts +7 -1
  176. package/dist/tools/execute.d.ts.map +1 -1
  177. package/dist/tools/invoker.d.ts.map +1 -1
  178. package/dist/tools/remote.d.ts.map +1 -1
  179. package/llms/agent-runtime.2.txt +632 -745
  180. package/llms/agent-runtime.3.txt +733 -492
  181. package/llms/agent-runtime.4.txt +521 -88
  182. package/llms/agent-runtime.5.txt +114 -0
  183. package/llms/agent-runtime.txt +4 -655
  184. package/llms/cli.2.txt +56 -1
  185. package/llms/cli.txt +68 -1
  186. package/llms/contract.txt +4 -1
  187. package/llms/files-packaging.txt +10 -0
  188. package/llms/process.2.txt +75 -1
  189. package/llms/process.txt +59 -25
  190. package/llms/server.4.txt +8 -4
  191. package/llms/server.5.txt +1 -0
  192. package/llms/stitchkit.2.txt +74 -0
  193. package/llms/stitchkit.txt +5 -5
  194. package/llms/tools.txt +1 -1
  195. package/llms/{upgrading-0.106.0-0.122.0.txt → upgrading-0.106.0-0.123.0.txt} +50 -3
  196. package/llms/upgrading.txt +1 -1
  197. package/llms-full.txt +384 -14
  198. package/llms.txt +8 -8
  199. package/package.json +1 -1
  200. package/dist/index-h2fhjqy7.js +0 -19
  201. package/dist/index-m5m9rmvt.js +0 -44
@@ -1,45 +1,53 @@
1
1
  import {
2
2
  validateDeclaredOutput
3
- } from "./index-k42ckyzx.js";
3
+ } from "./index-ndjzbt2v.js";
4
4
  import {
5
5
  jsonSchemaObjectCoercionMembers
6
6
  } from "./index-dsa676h8.js";
7
7
  import {
8
8
  coerceJsonArgs2
9
- } from "./index-rbzq0q16.js";
9
+ } from "./index-t8jz0e20.js";
10
10
  import {
11
+ toJsonSchema,
11
12
  jsonSchemaFields
12
13
  } from "./index-ct75c3at.js";
13
14
  import {
15
+ toolSurfaceOutputSchema,
14
16
  objectShapeKeys,
17
+ mergeSchemas,
18
+ toToolName,
15
19
  assertUniqueToolName,
16
20
  buildToolPresentationSchema
17
- } from "./index-x4p3kw1p.js";
21
+ } from "./index-tynna0n4.js";
18
22
  import {
19
23
  toolResultFromError,
20
24
  toolErrorFromResult
21
- } from "./index-s3yxw6kt.js";
25
+ } from "./index-s512scra.js";
22
26
  import {
23
27
  createToolRunner,
24
28
  formatToolError
25
- } from "./index-ycqhyars.js";
29
+ } from "./index-qc7tq0za.js";
26
30
  import {
27
31
  isRepeatableRead
28
32
  } from "./index-332d0m9g.js";
33
+ import {
34
+ readContractStreamItems,
35
+ contractStreamLifetimeExceeded
36
+ } from "./index-0v9xb8pz.js";
29
37
  import {
30
38
  writeContainedFile
31
- } from "./index-aqmadanx.js";
39
+ } from "./index-fa53vygr.js";
32
40
  import {
33
41
  openPinnedDirectory,
34
42
  isSafeEntryName,
35
43
  containedEntryMetadata
36
- } from "./index-eeahxwvg.js";
44
+ } from "./index-ww3gss55.js";
37
45
  import {
38
46
  pollUntil
39
47
  } from "./index-bph35vpy.js";
40
48
  import {
41
49
  collectToolSurface
42
- } from "./index-ff39f9dr.js";
50
+ } from "./index-993vtv1w.js";
43
51
  import {
44
52
  fetchGuarded,
45
53
  readCapped
@@ -57,32 +65,108 @@ import {
57
65
  import {
58
66
  AppError2,
59
67
  STITCH_ERROR_STATUS2
60
- } from "./index-qcn84byh.js";
68
+ } from "./index-0w0hxp7n.js";
61
69
  import {
62
- isRecord
63
- } from "./index-9jfdm5tg.js";
70
+ isRecord,
71
+ isAsyncIterable
72
+ } from "./index-hkxgennw.js";
73
+
74
+ // src/tools/cli/format.ts
75
+ var DEFAULT_EXIT_CODES2 = {
76
+ VALIDATION_ERROR: 1,
77
+ BAD_REQUEST: 1,
78
+ UNAUTHORIZED: 2,
79
+ FORBIDDEN: 3,
80
+ NOT_FOUND: 4,
81
+ UNKNOWN_OPERATION: 4,
82
+ CONFLICT: 5,
83
+ RATE_LIMITED: 6,
84
+ TIMEOUT: 7,
85
+ REQUEST_ABORTED: 130,
86
+ REQUEST_TIMEOUT: 7,
87
+ CONNECTION_TIMEOUT: 7,
88
+ STREAM_LIFETIME_EXCEEDED: 7,
89
+ CONNECTION_RESPONSE_TOO_LARGE: 1,
90
+ CONNECTION_REQUEST_FAILED: 1,
91
+ UPSTREAM_TOOL_ERROR: 1,
92
+ WAIT_FAILED: 1,
93
+ CLI_COMMAND_UNAVAILABLE: 1,
94
+ CLI_PRESENTATION_FAILED: 8,
95
+ INTERNAL_SERVER_ERROR: 1
96
+ };
97
+ function cliExitCode2(result, exitCodes) {
98
+ if (result.ok)
99
+ return 0;
100
+ const codes = { ...DEFAULT_EXIT_CODES2, ...exitCodes };
101
+ return Object.hasOwn(codes, result.code) ? codes[result.code] ?? 1 : 1;
102
+ }
103
+ function emitResult2(result, writers, opts) {
104
+ if (result.ok) {
105
+ if (result.data === undefined)
106
+ return 0;
107
+ const text = opts.json ? JSON.stringify(result.data) : JSON.stringify(result.data, null, 2);
108
+ writers.stdout(`${text}
109
+ `);
110
+ return 0;
111
+ }
112
+ const error = formatToolError(result, opts.toolName, opts.errorHint);
113
+ const text = opts.json ? JSON.stringify(error) : JSON.stringify(error, null, 2);
114
+ writers.stderr(`${text}
115
+ `);
116
+ return cliExitCode2(result, opts.exitCodes);
117
+ }
118
+ function presentationFailureHint(repeatable, printed) {
119
+ if (repeatable) {
120
+ return "The result was not printed: this command only reads. Repeat it with a corrected view.";
121
+ }
122
+ return printed ? "The complete, unformatted result is on stdout. Do not repeat the command to recover its result." : "The command returned no result. Do not repeat it.";
123
+ }
124
+ function emitPresentationFailure(result, failure, writers, opts) {
125
+ const printed = !opts.repeatable && result.data !== undefined;
126
+ if (printed)
127
+ emitResult2(result, writers, opts);
128
+ return emitResult2({
129
+ ok: false,
130
+ code: "CLI_PRESENTATION_FAILED",
131
+ retryable: false,
132
+ details: {
133
+ message: "The command completed successfully, but its result presentation failed.",
134
+ command: opts.toolName,
135
+ operationSucceeded: true,
136
+ resultOnStdout: printed,
137
+ cause: formatToolError(failure)
138
+ },
139
+ hint: presentationFailureHint(opts.repeatable, printed)
140
+ }, writers, { json: opts.json, toolName: opts.toolName, exitCodes: opts.exitCodes });
141
+ }
64
142
 
65
143
  // src/tools/cli/command.ts
144
+ function defineCliResult2(output, policy) {
145
+ return { ...policy, output };
146
+ }
66
147
  function defineCliCommand2(definition) {
67
148
  return definition;
68
149
  }
69
150
  function cliCommandReturnsResult(definition) {
70
151
  return definition.output !== undefined;
71
152
  }
72
- function cliCommandSuccessExitCode(definition, data) {
73
- const successExitCode = definition.exitCode?.(data) ?? 0;
153
+ function cliCommandSuccessExitCode(policy, data) {
154
+ const successExitCode = policy?.exitCode?.(data) ?? 0;
74
155
  if (!Number.isSafeInteger(successExitCode) || successExitCode < 0 || successExitCode > 255) {
75
156
  throw new Error("CLI success exit code must be an integer from 0 to 255");
76
157
  }
77
158
  return successExitCode;
78
159
  }
79
- function prepareCliCommandEmission(definition, result, options) {
80
- if (!result.ok || definition.output === undefined) {
160
+ function cliCommandResultPolicy(definition) {
161
+ return cliCommandReturnsResult(definition) ? definition : undefined;
162
+ }
163
+ function prepareCliCommandEmission(policy, result, options) {
164
+ if (!result.ok || policy === undefined) {
81
165
  return { result, successExitCode: 0 };
82
166
  }
83
167
  let successExitCode;
84
168
  try {
85
- successExitCode = cliCommandSuccessExitCode(definition, result.data);
169
+ successExitCode = cliCommandSuccessExitCode(policy, result.data);
86
170
  } catch (error) {
87
171
  return {
88
172
  result: toolResultFromError(new Error("CLI result policy failed", { cause: error })),
@@ -90,9 +174,9 @@ function prepareCliCommandEmission(definition, result, options) {
90
174
  };
91
175
  }
92
176
  try {
93
- if (definition.present === undefined)
177
+ if (policy.present === undefined)
94
178
  return { result, successExitCode };
95
- const presentation = definition.present({ result: result.data, options });
179
+ const presentation = policy.present({ result: result.data, options });
96
180
  if (typeof presentation !== "string") {
97
181
  throw new Error("CLI result presenter must return a string");
98
182
  }
@@ -105,6 +189,18 @@ function prepareCliCommandEmission(definition, result, options) {
105
189
  };
106
190
  }
107
191
  }
192
+ function emitCliCommandResult(policy, result, options, writers, emit) {
193
+ const emission = prepareCliCommandEmission(policy, result, options);
194
+ if (emission.result.ok && emission.presentationFailure !== undefined) {
195
+ return emitPresentationFailure(emission.result, emission.presentationFailure, writers, emit);
196
+ }
197
+ if (emission.result.ok && emission.presentation !== undefined) {
198
+ writers.stdout(emission.presentation);
199
+ return emission.successExitCode;
200
+ }
201
+ const emitted = emitResult2(emission.result, writers, emit);
202
+ return emission.result.ok ? emission.successExitCode : emitted;
203
+ }
108
204
  function cliCommandPresentationSchema(definition) {
109
205
  return buildToolPresentationSchema({
110
206
  inputSchema: definition.input,
@@ -146,73 +242,6 @@ async function executeCliCommand(definition, rawArgs, options, writers, coerceJs
146
242
  }
147
243
  }
148
244
 
149
- // src/tools/cli/format.ts
150
- var DEFAULT_EXIT_CODES2 = {
151
- VALIDATION_ERROR: 1,
152
- BAD_REQUEST: 1,
153
- UNAUTHORIZED: 2,
154
- FORBIDDEN: 3,
155
- NOT_FOUND: 4,
156
- CONFLICT: 5,
157
- RATE_LIMITED: 6,
158
- TIMEOUT: 7,
159
- REQUEST_ABORTED: 130,
160
- REQUEST_TIMEOUT: 7,
161
- CONNECTION_TIMEOUT: 7,
162
- CONNECTION_RESPONSE_TOO_LARGE: 1,
163
- CONNECTION_REQUEST_FAILED: 1,
164
- UPSTREAM_TOOL_ERROR: 1,
165
- WAIT_FAILED: 1,
166
- CLI_COMMAND_UNAVAILABLE: 1,
167
- CLI_PRESENTATION_FAILED: 8,
168
- INTERNAL_SERVER_ERROR: 1
169
- };
170
- function cliExitCode2(result, exitCodes) {
171
- if (result.ok)
172
- return 0;
173
- const codes = { ...DEFAULT_EXIT_CODES2, ...exitCodes };
174
- return Object.hasOwn(codes, result.code) ? codes[result.code] ?? 1 : 1;
175
- }
176
- function emitResult2(result, writers, opts) {
177
- if (result.ok) {
178
- if (result.data === undefined)
179
- return 0;
180
- const text = opts.json ? JSON.stringify(result.data) : JSON.stringify(result.data, null, 2);
181
- writers.stdout(`${text}
182
- `);
183
- return 0;
184
- }
185
- const error = formatToolError(result, opts.toolName, opts.errorHint);
186
- const text = opts.json ? JSON.stringify(error) : JSON.stringify(error, null, 2);
187
- writers.stderr(`${text}
188
- `);
189
- return cliExitCode2(result, opts.exitCodes);
190
- }
191
- function presentationFailureHint(repeatable, printed) {
192
- if (repeatable) {
193
- return "The result was not printed: this command only reads. Repeat it with a corrected view.";
194
- }
195
- return printed ? "The complete, unformatted result is on stdout. Do not repeat the command to recover its result." : "The command returned no result. Do not repeat it.";
196
- }
197
- function emitPresentationFailure(result, failure, writers, opts) {
198
- const printed = !opts.repeatable && result.data !== undefined;
199
- if (printed)
200
- emitResult2(result, writers, opts);
201
- return emitResult2({
202
- ok: false,
203
- code: "CLI_PRESENTATION_FAILED",
204
- retryable: false,
205
- details: {
206
- message: "The command completed successfully, but its result presentation failed.",
207
- command: opts.toolName,
208
- operationSucceeded: true,
209
- resultOnStdout: printed,
210
- cause: formatToolError(failure)
211
- },
212
- hint: presentationFailureHint(opts.repeatable, printed)
213
- }, writers, { json: opts.json, toolName: opts.toolName, exitCodes: opts.exitCodes });
214
- }
215
-
216
245
  // src/tools/cli/args-fields.ts
217
246
  import { z } from "zod";
218
247
 
@@ -575,6 +604,9 @@ function resolvePositionals(command, descriptor, configured) {
575
604
  }
576
605
  return [...configured];
577
606
  }
607
+ function cliResultPolicy(config, command) {
608
+ return config.results && Object.hasOwn(config.results, command) ? config.results[command] : undefined;
609
+ }
578
610
  function applyCliPresentationPolicy(command, descriptor, config) {
579
611
  const base = { ...descriptor, aliases: new Map };
580
612
  const configuredAliases = config.optionAliases && Object.hasOwn(config.optionAliases, command) ? config.optionAliases[command] : undefined;
@@ -588,7 +620,8 @@ function applyCliPresentationPolicy(command, descriptor, config) {
588
620
  function assertCliPoliciesResolved(commands, config) {
589
621
  const configuredNames = new Set([
590
622
  ...Object.keys(config.optionAliases ?? {}),
591
- ...Object.keys(config.positionals ?? {})
623
+ ...Object.keys(config.positionals ?? {}),
624
+ ...Object.keys(config.results ?? {})
592
625
  ]);
593
626
  if (config.defaultCommand !== undefined)
594
627
  configuredNames.add(config.defaultCommand);
@@ -599,6 +632,33 @@ function assertCliPoliciesResolved(commands, config) {
599
632
  }
600
633
  }
601
634
 
635
+ // src/tools/cli/stream-surface.ts
636
+ function collectCliStreams(services) {
637
+ const streams = new Map;
638
+ for (const service of services) {
639
+ for (const [methodName, method] of Object.entries(service.methods)) {
640
+ if (method.stream === undefined || !method.expose?.includes("CLI"))
641
+ continue;
642
+ const name = toToolName(service.name, methodName);
643
+ streams.set(name, {
644
+ descriptor: method.stream,
645
+ tool: {
646
+ method,
647
+ name,
648
+ argumentSchema: mergeSchemas(method.paramsSchema, method.inputSchema),
649
+ presentationSchema: buildToolPresentationSchema({
650
+ paramsSchema: method.paramsSchema,
651
+ inputSchema: method.inputSchema,
652
+ unrepresentable: "any"
653
+ }),
654
+ shouldExtend: false
655
+ }
656
+ });
657
+ }
658
+ }
659
+ return streams;
660
+ }
661
+
602
662
  // src/tools/cli/invoke.ts
603
663
  function parseCliGlobals(schema, globals) {
604
664
  if (!schema)
@@ -657,8 +717,8 @@ async function createCliInvoker2(config, globals) {
657
717
  if (!tool) {
658
718
  return cliInvocationResult2({
659
719
  ok: false,
660
- code: "NOT_FOUND",
661
- details: { message: `Unknown command "${command}"` }
720
+ code: "UNKNOWN_OPERATION",
721
+ details: { message: `Unknown command "${command}"`, operation: command }
662
722
  }, command, config);
663
723
  }
664
724
  let result;
@@ -667,10 +727,19 @@ async function createCliInvoker2(config, globals) {
667
727
  } catch (error) {
668
728
  result = toolResultFromError(error);
669
729
  }
670
- return cliInvocationResult2(result, command, config);
730
+ return withSuccessExitCode(cliInvocationResult2(result, command, config), cliResultPolicy(config, command), result, command, config);
671
731
  }
672
732
  };
673
733
  }
734
+ function withSuccessExitCode(invocation, policy, result, command, config) {
735
+ if (!result.ok || policy === undefined)
736
+ return invocation;
737
+ try {
738
+ return { ...invocation, exitCode: cliCommandSuccessExitCode(policy, result.data) };
739
+ } catch (error) {
740
+ return cliInvocationResult2(toolResultFromError(new Error("CLI result policy failed", { cause: error })), command, config);
741
+ }
742
+ }
674
743
  var IN_PROCESS_RUN_OPTIONS = Object.freeze({
675
744
  json: false,
676
745
  wait: false,
@@ -689,17 +758,7 @@ async function runNativeCommand(definition, args, config, globals) {
689
758
  err += text;
690
759
  }
691
760
  }, config.coerceJsonArgs ?? true, globals);
692
- let invocation = cliInvocationResult2(result, definition.name, config);
693
- if (invocation.ok) {
694
- try {
695
- invocation = {
696
- ...invocation,
697
- exitCode: cliCommandSuccessExitCode(definition, result.ok ? result.data : undefined)
698
- };
699
- } catch (error) {
700
- invocation = cliInvocationResult2(toolResultFromError(error), definition.name, config);
701
- }
702
- }
761
+ const invocation = withSuccessExitCode(cliInvocationResult2(result, definition.name, config), cliCommandResultPolicy(definition), result, definition.name, config);
703
762
  if (out === "" && err === "")
704
763
  return invocation;
705
764
  return {
@@ -727,14 +786,38 @@ function buildCliSurface(config, auth, nativeHelp, applicationGlobalNames, shape
727
786
  help.set(mountable.name, descriptor);
728
787
  }
729
788
  }
789
+ const streams = collectCliStreams(services);
790
+ for (const [name, stream] of streams) {
791
+ const descriptor = applyCliPresentationPolicy(name, {
792
+ ...managedCliDescriptor(stream.tool),
793
+ outputSchema: stream.descriptor.item,
794
+ stream: true
795
+ }, config);
796
+ const issue = shapeIssue?.(name, descriptor, help.has(name), config.passthrough?.[name], applicationGlobalNames);
797
+ if (issue !== undefined)
798
+ throw new Error(issue);
799
+ help.set(name, descriptor);
800
+ }
730
801
  assertCliPoliciesResolved(help, config);
731
- return { tools, help };
802
+ for (const [name, policy] of Object.entries(config.results ?? {})) {
803
+ if (!tools.has(name) && !streams.has(name)) {
804
+ throw new Error(`[stitchkit] CLI result policy "${name}" targets a command that is not managed; a native command declares present and exitCode on defineCliCommand`);
805
+ }
806
+ if (policy.output !== undefined && policy.output !== help.get(name)?.outputSchema) {
807
+ throw new Error(`[stitchkit] CLI result policy "${name}" is typed against a schema that is not the one the command answers with; pass the command's own output schema to defineCliResult`);
808
+ }
809
+ if (streams.has(name) && policy.exitCode !== undefined) {
810
+ throw new Error(`[stitchkit] CLI result policy "${name}" declares exitCode for a stream command; a stream has no single result to classify`);
811
+ }
812
+ }
813
+ return { tools, streams, help };
732
814
  }
733
815
  function managedCliDescriptor(tool) {
734
816
  return {
735
817
  description: tool.method.desc,
736
818
  argumentSchema: tool.argumentSchema,
737
- presentationSchema: tool.presentationSchema
819
+ presentationSchema: tool.presentationSchema,
820
+ outputSchema: toolSurfaceOutputSchema(tool.method)
738
821
  };
739
822
  }
740
823
 
@@ -786,6 +869,9 @@ function readPipedStdin(input = process.stdin) {
786
869
  }
787
870
 
788
871
  // src/tools/cli/io.ts
872
+ function isReaderGone(error) {
873
+ return isRecord(error) && (error.code === "EPIPE" || error.code === "ERR_STREAM_DESTROYED");
874
+ }
789
875
  function createCliIo(config) {
790
876
  let pendingWrite;
791
877
  let writeFailed = false;
@@ -796,6 +882,8 @@ function createCliIo(config) {
796
882
  try {
797
883
  offset += writeSync(fd, bytes, offset, bytes.length - offset);
798
884
  } catch (error) {
885
+ if (fd === 1 && isReaderGone(error))
886
+ throw error;
799
887
  if (isRecord(error) && error.code === "EAGAIN") {
800
888
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 1);
801
889
  continue;
@@ -813,7 +901,24 @@ function createCliIo(config) {
813
901
  }
814
902
  }
815
903
  };
816
- const stdout = config.stdout ?? ((text) => writeFd(1, text));
904
+ const writeStdout = config.stdout ?? ((text) => writeFd(1, text));
905
+ let readerGone = false;
906
+ const stdoutWhileOpen = (text) => {
907
+ if (readerGone)
908
+ return false;
909
+ try {
910
+ writeStdout(text);
911
+ return true;
912
+ } catch (error) {
913
+ if (!isReaderGone(error))
914
+ throw error;
915
+ readerGone = true;
916
+ return false;
917
+ }
918
+ };
919
+ const stdout = (text) => {
920
+ stdoutWhileOpen(text);
921
+ };
817
922
  const stderr = config.stderr ?? ((text) => writeFd(2, text));
818
923
  const exit = config.exit ?? ((code) => {
819
924
  if (pendingWrite === undefined)
@@ -822,7 +927,7 @@ function createCliIo(config) {
822
927
  pendingWrite.then(() => process.exit(writeFailed ? 1 : code));
823
928
  });
824
929
  const readStdin = config.stdin ?? readPipedStdin;
825
- return { stdout, stderr, exit, readStdin };
930
+ return { stdout, stdoutWhileOpen, stderr, exit, readStdin };
826
931
  }
827
932
 
828
933
  // src/tools/cli/download.ts
@@ -900,6 +1005,7 @@ var GLOBAL_OPTIONS = [
900
1005
  ["--output-dir <dir>", "Download result media into a directory"],
901
1006
  ["--quiet", "Suppress non-essential stderr output"],
902
1007
  ["--dry-run", "Print the resolved call without executing it"],
1008
+ ["--schema", "Print the JSON Schema of a command input and output"],
903
1009
  ["--help, -h", "Show help for a command"],
904
1010
  ["--help <text>", "List only the commands matching a substring"],
905
1011
  ["--count-by <field>", "Count records per distinct value of a field"],
@@ -1105,7 +1211,15 @@ function isOptionToken(token) {
1105
1211
  function looksLikeOption(token) {
1106
1212
  return token.startsWith("--") || /^-[A-Za-z]/.test(token);
1107
1213
  }
1108
- var BOOL_OPTIONS = new Set(["json", "wait", "quiet", "dry-run", "help", "ascending"]);
1214
+ var BOOL_OPTIONS = new Set([
1215
+ "json",
1216
+ "wait",
1217
+ "quiet",
1218
+ "dry-run",
1219
+ "help",
1220
+ "schema",
1221
+ "ascending"
1222
+ ]);
1109
1223
  var VIEW_OPTIONS = new Set(["count-by", "sum", "by", "top", "table", "sort"]);
1110
1224
  var VALUE_OPTIONS = new Set(["wait-timeout", "output-dir", ...VIEW_OPTIONS]);
1111
1225
  var RESERVED_CLI_OPTIONS = new Set([...BOOL_OPTIONS, ...VALUE_OPTIONS]);
@@ -1291,8 +1405,8 @@ async function buildManagedSurface(session, typedGlobals, forExecution) {
1291
1405
  };
1292
1406
  }
1293
1407
  }
1294
- const { tools, help } = buildCliSurface(config, auth, nativeHelp, applicationGlobalNames, commandShapeIssue);
1295
- return { resolved: true, auth, help, tools };
1408
+ const { tools, streams, help } = buildCliSurface(config, auth, nativeHelp, applicationGlobalNames, commandShapeIssue);
1409
+ return { resolved: true, auth, help, tools, streams };
1296
1410
  }
1297
1411
 
1298
1412
  // src/tools/cli/args.ts
@@ -1416,6 +1530,8 @@ function readCliTokens(argv, fields, fieldFor, config) {
1416
1530
  options.quiet = enabled;
1417
1531
  else if (name === "ascending")
1418
1532
  ascending = enabled;
1533
+ else if (name === "schema")
1534
+ continue;
1419
1535
  else
1420
1536
  options.help = options.help || enabled;
1421
1537
  continue;
@@ -1790,7 +1906,8 @@ function nativeDescriptor(definition) {
1790
1906
  return {
1791
1907
  description: definition.description,
1792
1908
  argumentSchema: definition.input,
1793
- presentationSchema: cliCommandPresentationSchema(definition)
1909
+ presentationSchema: cliCommandPresentationSchema(definition),
1910
+ outputSchema: definition.output
1794
1911
  };
1795
1912
  }
1796
1913
  function createCliSession(config, io) {
@@ -1859,12 +1976,14 @@ function resolveCliRoute(session, argv) {
1859
1976
  return;
1860
1977
  }
1861
1978
  const beforeSeparator = commandArgv.indexOf("--") === -1 ? commandArgv : commandArgv.slice(0, commandArgv.indexOf("--"));
1862
- const helpRequested = beforeSeparator.some((token) => {
1863
- if (token === "--help" || token === "-h")
1979
+ const asked = (name) => beforeSeparator.some((token) => {
1980
+ if (token === `--${name}` || name === "help" && token === "-h")
1864
1981
  return true;
1865
1982
  const option = classifyLongOptionToken(token);
1866
- return option?.name === "help" && option.value !== undefined && isReservedBoolWord(option.value) && parseReservedBool("help", option.value);
1983
+ return option?.name === name && option.value !== undefined && isReservedBoolWord(option.value) && parseReservedBool(name, option.value);
1867
1984
  });
1985
+ const helpRequested = asked("help");
1986
+ const schemaRequested = !helpRequested && asked("schema");
1868
1987
  return {
1869
1988
  globals,
1870
1989
  typedGlobals,
@@ -1872,9 +1991,20 @@ function resolveCliRoute(session, argv) {
1872
1991
  command,
1873
1992
  commandArgv,
1874
1993
  beforeSeparator,
1875
- helpRequested
1994
+ helpRequested,
1995
+ schemaRequested
1876
1996
  };
1877
1997
  }
1998
+ function renderCommandSchema(command, descriptor) {
1999
+ return `${JSON.stringify({
2000
+ command,
2001
+ input: descriptor.presentationSchema,
2002
+ ...descriptor.outputSchema !== undefined && {
2003
+ [descriptor.stream ? "item" : "output"]: toJsonSchema(descriptor.outputSchema, "output", "any", "draft-07")
2004
+ }
2005
+ })}
2006
+ `;
2007
+ }
1878
2008
  function emitOptionsFor(config, json, toolName) {
1879
2009
  return {
1880
2010
  json,
@@ -1884,6 +2014,106 @@ function emitOptionsFor(config, json, toolName) {
1884
2014
  };
1885
2015
  }
1886
2016
 
2017
+ // src/tools/cli/run-stream.ts
2018
+ async function runStreamCommand(session, route, managed, stream, { toolArgs, options }) {
2019
+ const { config } = session;
2020
+ const { stdout, stderr, exit } = session.io;
2021
+ const command = stream.tool.name;
2022
+ if (options.wait || options.outputDir !== undefined || options.view !== undefined) {
2023
+ stderr(`--wait, --output-dir and aggregate views do not apply to stream command "${command}"
2024
+ `);
2025
+ return exit(2);
2026
+ }
2027
+ const abort = new AbortController;
2028
+ let cancelled = false;
2029
+ const cancel = () => {
2030
+ cancelled = true;
2031
+ abort.abort(config.signal?.reason);
2032
+ };
2033
+ if (config.signal?.aborted)
2034
+ cancel();
2035
+ else
2036
+ config.signal?.addEventListener("abort", cancel, { once: true });
2037
+ const runTool = createToolRunner({
2038
+ source: "cli",
2039
+ toolSurface: true,
2040
+ context: { ...config.context?.(managed.auth, route.typedGlobals), signal: abort.signal },
2041
+ hooks: config.hooks,
2042
+ lifecycle: config.lifecycle,
2043
+ coerceJsonArgs: config.coerceJsonArgs
2044
+ });
2045
+ let opened;
2046
+ try {
2047
+ opened = await runTool(stream.tool, toolArgs);
2048
+ } catch (error) {
2049
+ opened = toolResultFromError(error);
2050
+ }
2051
+ const policy = cliResultPolicy(config, command);
2052
+ let outcome;
2053
+ if (!opened.ok)
2054
+ outcome = opened;
2055
+ else if (!isAsyncIterable(opened.data)) {
2056
+ outcome = toolResultFromError(new Error(`Stream command "${command}" handler did not return an async iterable`));
2057
+ } else {
2058
+ outcome = await printStreamItems(opened.data, stream, abort, () => cancelled, (item) => session.io.stdoutWhileOpen(streamLine(command, item, policy, options)));
2059
+ }
2060
+ config.signal?.removeEventListener("abort", cancel);
2061
+ if (outcome === "completed" || outcome === "reader-gone")
2062
+ return exit(0);
2063
+ if (outcome === "cancelled" || cancelled) {
2064
+ return exit(cliExitCode2({ ok: false, code: "REQUEST_ABORTED" }, config.exitCodes));
2065
+ }
2066
+ return exit(emitResult2(outcome, { stdout, stderr }, emitOptionsFor(config, options.json, command)));
2067
+ }
2068
+ function streamLine(command, item, policy, options) {
2069
+ if (policy?.present === undefined)
2070
+ return `${JSON.stringify(item)}
2071
+ `;
2072
+ let line;
2073
+ try {
2074
+ line = policy.present({ result: item, options });
2075
+ if (typeof line !== "string")
2076
+ throw new Error("CLI result presenter must return a string");
2077
+ } catch (error) {
2078
+ throw new AppError2("CLI_PRESENTATION_FAILED", {
2079
+ message: "A stream item was produced, but its presentation failed.",
2080
+ status: 500,
2081
+ details: { command, cause: formatToolError(toolResultFromError(error)) }
2082
+ });
2083
+ }
2084
+ return line;
2085
+ }
2086
+ async function printStreamItems(source, { descriptor }, abort, wasCancelled, write) {
2087
+ const iterator = source[Symbol.asyncIterator]();
2088
+ let lifetimeExpired = false;
2089
+ const lifetime = descriptor.lifetimeMs === undefined ? undefined : setTimeout(() => {
2090
+ lifetimeExpired = true;
2091
+ abort.abort(new Error("Stream lifetime expired"));
2092
+ }, descriptor.lifetimeMs);
2093
+ lifetime?.unref?.();
2094
+ try {
2095
+ for await (const { item } of readContractStreamItems(iterator, descriptor, abort.signal)) {
2096
+ if (!write(item))
2097
+ return "reader-gone";
2098
+ }
2099
+ return "completed";
2100
+ } catch (error) {
2101
+ if (wasCancelled())
2102
+ return "cancelled";
2103
+ if (lifetimeExpired) {
2104
+ return toolResultFromError(contractStreamLifetimeExceeded());
2105
+ }
2106
+ return toolResultFromError(error);
2107
+ } finally {
2108
+ if (lifetime !== undefined)
2109
+ clearTimeout(lifetime);
2110
+ abort.abort();
2111
+ Promise.resolve().then(() => iterator.return?.(undefined)).catch(() => {
2112
+ return;
2113
+ });
2114
+ }
2115
+ }
2116
+
1887
2117
  // src/tools/cli/unavailable.ts
1888
2118
  function unavailableCommand(reason) {
1889
2119
  return toolResultFromError(new AppError2("CLI_COMMAND_UNAVAILABLE", {
@@ -2148,9 +2378,9 @@ async function pollUntilDone2(params) {
2148
2378
  async function runManagedInvocation(session, route) {
2149
2379
  const { config } = session;
2150
2380
  const { stdout, stderr, exit } = session.io;
2151
- const { command, helpRequested, beforeSeparator } = route;
2381
+ const { command, helpRequested, schemaRequested, beforeSeparator } = route;
2152
2382
  const topLevelHelp = route.route.topLevelHelp || command === undefined || command === "help" || command === "--help" || command === "-h" || command.startsWith("--help=") && !isReservedBoolWord(command.slice("--help=".length));
2153
- const managed = await buildManagedSurface(session, route.typedGlobals, !topLevelHelp && !helpRequested);
2383
+ const managed = await buildManagedSurface(session, route.typedGlobals, !topLevelHelp && !helpRequested && !schemaRequested);
2154
2384
  if (topLevelHelp)
2155
2385
  return respondTopLevelHelp(session, route, managed);
2156
2386
  if (!managed.resolved) {
@@ -2196,11 +2426,16 @@ async function runManagedCommand(session, route, command, managed) {
2196
2426
  stdout(renderCommandHelp(config.name, command, descriptor, applicationOptions));
2197
2427
  return exit(0);
2198
2428
  }
2429
+ if (route.schemaRequested) {
2430
+ stdout(renderCommandSchema(command, descriptor));
2431
+ return exit(0);
2432
+ }
2199
2433
  if (descriptor.unavailableReason !== undefined) {
2200
2434
  return exit(emitResult2(unavailableCommand(descriptor.unavailableReason), { stdout, stderr }, emitOptionsFor(config, unavailableCommandJson(route.commandArgv), command)));
2201
2435
  }
2436
+ const stream = managed.streams.get(command);
2202
2437
  const tool = managed.tools.get(command);
2203
- if (!tool)
2438
+ if (!tool && !stream)
2204
2439
  throw new Error("[stitchkit] managed CLI executable invariant failed");
2205
2440
  const prepared = await prepareInvocation(command, route.commandArgv, descriptor, config, readStdin);
2206
2441
  if (!prepared.ok) {
@@ -2233,6 +2468,10 @@ async function runManagedCommand(session, route, command, managed) {
2233
2468
  `);
2234
2469
  return exit(0);
2235
2470
  }
2471
+ if (stream)
2472
+ return runStreamCommand(session, route, managed, stream, { toolArgs, options });
2473
+ if (!tool)
2474
+ throw new Error("[stitchkit] managed CLI executable invariant failed");
2236
2475
  const result = await executeManagedTool(session, route, command, managed, tool, {
2237
2476
  toolArgs,
2238
2477
  options
@@ -2269,8 +2508,11 @@ async function executeManagedTool(session, route, command, managed, tool, { tool
2269
2508
  if (!pollTool) {
2270
2509
  return {
2271
2510
  ok: false,
2272
- code: "NOT_FOUND",
2273
- details: { message: `--wait: no command "${toolName}" to poll` }
2511
+ code: "UNKNOWN_OPERATION",
2512
+ details: {
2513
+ message: `--wait: no command "${toolName}" to poll`,
2514
+ operation: toolName
2515
+ }
2274
2516
  };
2275
2517
  }
2276
2518
  return runTool(pollTool, args);
@@ -2314,7 +2556,8 @@ async function emitManagedResult(session, command, initial, options, repeatable)
2314
2556
  }
2315
2557
  result = { ...result, data: viewed.data };
2316
2558
  }
2317
- const exitCode = emitResult2(result, { stdout, stderr }, emitOptionsFor(config, options.json, command));
2559
+ const policy = options.view === undefined && !options.wait ? cliResultPolicy(config, command) : undefined;
2560
+ const exitCode = emitCliCommandResult(policy, result, options, { stdout, stderr }, { ...emitOptionsFor(config, options.json, command), repeatable });
2318
2561
  return exit(downloadsOk ? exitCode : 1);
2319
2562
  }
2320
2563
 
@@ -2330,6 +2573,10 @@ async function runNativeCommand2(session, route, command, native) {
2330
2573
  stdout(renderCommandHelp(config.name, command, descriptor, applicationOptions));
2331
2574
  return exit(0);
2332
2575
  }
2576
+ if (route.schemaRequested) {
2577
+ stdout(renderCommandSchema(command, descriptor));
2578
+ return exit(0);
2579
+ }
2333
2580
  const prepared = await prepareInvocation(command, commandArgv, descriptor, config, readStdin);
2334
2581
  if (!prepared.ok) {
2335
2582
  stderr(`${prepared.message}
@@ -2362,18 +2609,7 @@ async function runNativeCommand2(session, route, command, native) {
2362
2609
  return exit(0);
2363
2610
  }
2364
2611
  const result = await executeCliCommand(native, toolArgs, options, { stdout, stderr }, config.coerceJsonArgs ?? true, globals);
2365
- const emission = prepareCliCommandEmission(native, result, options);
2366
- if (emission.result.ok && emission.presentationFailure !== undefined) {
2367
- return exit(emitPresentationFailure(emission.result, emission.presentationFailure, { stdout, stderr }, { ...emitOptionsFor(config, options.json, command), repeatable: false }));
2368
- }
2369
- let emittedExitCode;
2370
- if (emission.result.ok && emission.presentation !== undefined) {
2371
- stdout(emission.presentation);
2372
- emittedExitCode = 0;
2373
- } else {
2374
- emittedExitCode = emitResult2(emission.result, { stdout, stderr }, emitOptionsFor(config, options.json, command));
2375
- }
2376
- return exit(emission.result.ok ? emission.successExitCode : emittedExitCode);
2612
+ return exit(emitCliCommandResult(cliCommandResultPolicy(native), result, options, { stdout, stderr }, { ...emitOptionsFor(config, options.json, command), repeatable: false }));
2377
2613
  }
2378
2614
 
2379
2615
  // src/tools/cli/create-cli.ts
@@ -2395,4 +2631,4 @@ async function createCli2(config) {
2395
2631
  return runManagedInvocation(session, route);
2396
2632
  }
2397
2633
 
2398
- export { defineCliCommand2, DEFAULT_EXIT_CODES2, cliExitCode2, emitResult2, CliArgumentError2, cliInvocationResult2, createCliInvoker2, routeCliArgv2, parseCliArgs2, extractCliGlobalOptions2, renderCliView2, pollUntilDone2, createCli2 };
2634
+ export { DEFAULT_EXIT_CODES2, cliExitCode2, emitResult2, defineCliResult2, defineCliCommand2, CliArgumentError2, cliInvocationResult2, createCliInvoker2, routeCliArgv2, parseCliArgs2, extractCliGlobalOptions2, renderCliView2, pollUntilDone2, createCli2 };