@settlemint/dalp-cli 3.1.32-main.42342404882 → 3.1.32-main.42350939226

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.
@@ -2079,7 +2079,7 @@
2079
2079
  "name": "Prefer",
2080
2080
  "in": "header",
2081
2081
  "required": false,
2082
- "description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting.",
2082
+ "description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
2083
2083
  "type": "string",
2084
2084
  "enum": null,
2085
2085
  "pattern": null,
@@ -2808,6 +2808,58 @@
2808
2808
  }
2809
2809
  ]
2810
2810
  },
2811
+ "addons/tradingVenue/orderPlacementRead": {
2812
+ "name": "addons/tradingVenue/orderPlacementRead",
2813
+ "method": "GET",
2814
+ "url": "/api/v2/addons/trading-venues/{venueAddress}/order-placements/{orderId}",
2815
+ "summary": null,
2816
+ "description": null,
2817
+ "help": "addons/tradingVenue/orderPlacementRead",
2818
+ "tags": [
2819
+ "Trading venue"
2820
+ ],
2821
+ "pathParams": [
2822
+ {
2823
+ "name": "venueAddress",
2824
+ "in": "path",
2825
+ "required": true,
2826
+ "description": "A valid Ethereum address (42 characters, starting with 0x)",
2827
+ "type": "string",
2828
+ "enum": null,
2829
+ "pattern": "^0x[a-fA-F0-9]{40}$",
2830
+ "examples": [
2831
+ "0x71C7656EC7ab88b098defB751B7401B5f6d8976F"
2832
+ ],
2833
+ "fields": []
2834
+ },
2835
+ {
2836
+ "name": "orderId",
2837
+ "in": "path",
2838
+ "required": true,
2839
+ "description": "Trading Venue order identifier",
2840
+ "type": "string",
2841
+ "enum": null,
2842
+ "pattern": null,
2843
+ "examples": [],
2844
+ "fields": []
2845
+ }
2846
+ ],
2847
+ "queryParams": [],
2848
+ "headerParams": [],
2849
+ "requestBodyDescription": null,
2850
+ "hasRequestBody": false,
2851
+ "bodyIsComplex": false,
2852
+ "bodyFields": [],
2853
+ "examples": [
2854
+ {
2855
+ "description": "addons/tradingVenue/orderPlacementRead",
2856
+ "path": {
2857
+ "venueAddress": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
2858
+ "orderId": "<orderId>"
2859
+ }
2860
+ }
2861
+ ]
2862
+ },
2811
2863
  "addons/tradingVenue/orderRead": {
2812
2864
  "name": "addons/tradingVenue/orderRead",
2813
2865
  "method": "GET",
@@ -2982,6 +3034,17 @@
2982
3034
  "pattern": null,
2983
3035
  "examples": [],
2984
3036
  "fields": []
3037
+ },
3038
+ {
3039
+ "name": "Prefer",
3040
+ "in": "header",
3041
+ "required": false,
3042
+ "description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
3043
+ "type": "string",
3044
+ "enum": null,
3045
+ "pattern": null,
3046
+ "examples": [],
3047
+ "fields": []
2985
3048
  }
2986
3049
  ],
2987
3050
  "requestBodyDescription": null,
@@ -3068,6 +3131,17 @@
3068
3131
  "pattern": null,
3069
3132
  "examples": [],
3070
3133
  "fields": []
3134
+ },
3135
+ {
3136
+ "name": "Prefer",
3137
+ "in": "header",
3138
+ "required": false,
3139
+ "description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
3140
+ "type": "string",
3141
+ "enum": null,
3142
+ "pattern": null,
3143
+ "examples": [],
3144
+ "fields": []
3071
3145
  }
3072
3146
  ],
3073
3147
  "requestBodyDescription": null,
@@ -3456,6 +3530,17 @@
3456
3530
  "pattern": null,
3457
3531
  "examples": [],
3458
3532
  "fields": []
3533
+ },
3534
+ {
3535
+ "name": "Prefer",
3536
+ "in": "header",
3537
+ "required": false,
3538
+ "description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
3539
+ "type": "string",
3540
+ "enum": null,
3541
+ "pattern": null,
3542
+ "examples": [],
3543
+ "fields": []
3459
3544
  }
3460
3545
  ],
3461
3546
  "requestBodyDescription": "A signed intent is placed as signed. An intent without maker and signature is signed by the caller's custody wallet inside this request, under the request's one wallet verification, and may name expiryDate instead of expiry.",
@@ -4030,6 +4115,17 @@
4030
4115
  "pattern": null,
4031
4116
  "examples": [],
4032
4117
  "fields": []
4118
+ },
4119
+ {
4120
+ "name": "Prefer",
4121
+ "in": "header",
4122
+ "required": false,
4123
+ "description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
4124
+ "type": "string",
4125
+ "enum": null,
4126
+ "pattern": null,
4127
+ "examples": [],
4128
+ "fields": []
4033
4129
  }
4034
4130
  ],
4035
4131
  "requestBodyDescription": null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@settlemint/dalp-cli",
3
- "version": "3.1.32-main.42342404882",
3
+ "version": "3.1.32-main.42350939226",
4
4
  "private": false,
5
5
  "description": "CLI for the Digital Asset Lifecycle Platform — manage tokens, identities, compliance, and more from the command line.",
6
6
  "homepage": "https://settlemint.com",
@@ -50,14 +50,14 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@modelcontextprotocol/server": "2.0.0-alpha.4",
53
- "@settlemint/dalp-sdk": "3.1.32-main.42342404882",
53
+ "@settlemint/dalp-sdk": "3.1.32-main.42350939226",
54
54
  "incur": "0.7.1",
55
55
  "zod": "4.6.7"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@arethetypeswrong/cli": "0.18.5",
59
- "@testkit/effect-bun-test": "3.1.32-main.42342404882",
60
- "@tools/typescript-config": "3.1.32-main.42342404882",
59
+ "@testkit/effect-bun-test": "3.1.32-main.42350939226",
60
+ "@tools/typescript-config": "3.1.32-main.42350939226",
61
61
  "@types/bun": "1.4.4",
62
62
  "publint": "0.3.25"
63
63
  },
@@ -442,7 +442,7 @@ export const loginCommand = Cli.create("login", {
442
442
  commands: [
443
443
  { command: "whoami", description: "View current user" },
444
444
  { command: "org switch", description: "Save the key's organization as active" },
445
- { command: "tokens list", description: "List tokens" },
445
+ { command: "get tokens index", description: "List tokens" },
446
446
  ],
447
447
  },
448
448
  }
@@ -2079,7 +2079,7 @@
2079
2079
  "name": "Prefer",
2080
2080
  "in": "header",
2081
2081
  "required": false,
2082
- "description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting.",
2082
+ "description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
2083
2083
  "type": "string",
2084
2084
  "enum": null,
2085
2085
  "pattern": null,
@@ -2808,6 +2808,58 @@
2808
2808
  }
2809
2809
  ]
2810
2810
  },
2811
+ "addons/tradingVenue/orderPlacementRead": {
2812
+ "name": "addons/tradingVenue/orderPlacementRead",
2813
+ "method": "GET",
2814
+ "url": "/api/v2/addons/trading-venues/{venueAddress}/order-placements/{orderId}",
2815
+ "summary": null,
2816
+ "description": null,
2817
+ "help": "addons/tradingVenue/orderPlacementRead",
2818
+ "tags": [
2819
+ "Trading venue"
2820
+ ],
2821
+ "pathParams": [
2822
+ {
2823
+ "name": "venueAddress",
2824
+ "in": "path",
2825
+ "required": true,
2826
+ "description": "A valid Ethereum address (42 characters, starting with 0x)",
2827
+ "type": "string",
2828
+ "enum": null,
2829
+ "pattern": "^0x[a-fA-F0-9]{40}$",
2830
+ "examples": [
2831
+ "0x71C7656EC7ab88b098defB751B7401B5f6d8976F"
2832
+ ],
2833
+ "fields": []
2834
+ },
2835
+ {
2836
+ "name": "orderId",
2837
+ "in": "path",
2838
+ "required": true,
2839
+ "description": "Trading Venue order identifier",
2840
+ "type": "string",
2841
+ "enum": null,
2842
+ "pattern": null,
2843
+ "examples": [],
2844
+ "fields": []
2845
+ }
2846
+ ],
2847
+ "queryParams": [],
2848
+ "headerParams": [],
2849
+ "requestBodyDescription": null,
2850
+ "hasRequestBody": false,
2851
+ "bodyIsComplex": false,
2852
+ "bodyFields": [],
2853
+ "examples": [
2854
+ {
2855
+ "description": "addons/tradingVenue/orderPlacementRead",
2856
+ "path": {
2857
+ "venueAddress": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
2858
+ "orderId": "<orderId>"
2859
+ }
2860
+ }
2861
+ ]
2862
+ },
2811
2863
  "addons/tradingVenue/orderRead": {
2812
2864
  "name": "addons/tradingVenue/orderRead",
2813
2865
  "method": "GET",
@@ -2982,6 +3034,17 @@
2982
3034
  "pattern": null,
2983
3035
  "examples": [],
2984
3036
  "fields": []
3037
+ },
3038
+ {
3039
+ "name": "Prefer",
3040
+ "in": "header",
3041
+ "required": false,
3042
+ "description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
3043
+ "type": "string",
3044
+ "enum": null,
3045
+ "pattern": null,
3046
+ "examples": [],
3047
+ "fields": []
2985
3048
  }
2986
3049
  ],
2987
3050
  "requestBodyDescription": null,
@@ -3068,6 +3131,17 @@
3068
3131
  "pattern": null,
3069
3132
  "examples": [],
3070
3133
  "fields": []
3134
+ },
3135
+ {
3136
+ "name": "Prefer",
3137
+ "in": "header",
3138
+ "required": false,
3139
+ "description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
3140
+ "type": "string",
3141
+ "enum": null,
3142
+ "pattern": null,
3143
+ "examples": [],
3144
+ "fields": []
3071
3145
  }
3072
3146
  ],
3073
3147
  "requestBodyDescription": null,
@@ -3456,6 +3530,17 @@
3456
3530
  "pattern": null,
3457
3531
  "examples": [],
3458
3532
  "fields": []
3533
+ },
3534
+ {
3535
+ "name": "Prefer",
3536
+ "in": "header",
3537
+ "required": false,
3538
+ "description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
3539
+ "type": "string",
3540
+ "enum": null,
3541
+ "pattern": null,
3542
+ "examples": [],
3543
+ "fields": []
3459
3544
  }
3460
3545
  ],
3461
3546
  "requestBodyDescription": "A signed intent is placed as signed. An intent without maker and signature is signed by the caller's custody wallet inside this request, under the request's one wallet verification, and may name expiryDate instead of expiry.",
@@ -4030,6 +4115,17 @@
4030
4115
  "pattern": null,
4031
4116
  "examples": [],
4032
4117
  "fields": []
4118
+ },
4119
+ {
4120
+ "name": "Prefer",
4121
+ "in": "header",
4122
+ "required": false,
4123
+ "description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
4124
+ "type": "string",
4125
+ "enum": null,
4126
+ "pattern": null,
4127
+ "examples": [],
4128
+ "fields": []
4033
4129
  }
4034
4130
  ],
4035
4131
  "requestBodyDescription": null,
@@ -1,5 +1,5 @@
1
1
  import { z } from "incur";
2
- import { commandPathForUrl } from "@settlemint/dalp-sdk/routes";
2
+ import { cliCommandFor, routeTable } from "@settlemint/dalp-sdk/routes";
3
3
 
4
4
  export interface CliCtaCommandObject {
5
5
  readonly command: string;
@@ -78,10 +78,49 @@ function parseHref(href: string): { pathname: string; searchParams: URLSearchPar
78
78
  }
79
79
  }
80
80
 
81
- export function mapApiHrefToCliCommand(
82
- href: string,
83
- method = "GET"
84
- ): { readonly command: string; readonly options?: Readonly<Record<string, string>> } | undefined {
81
+ const API_PREFIX = /^\/api(?:\/v2)?(?=\/)/u;
82
+ const BRACKETED_KEY = /^([^[\]]+)\[([^\]]+)\]$/u;
83
+
84
+ const readRoutes = Object.entries(routeTable.routes).flatMap(([routeId, row]) =>
85
+ row === undefined || row.method.toUpperCase() !== "GET"
86
+ ? []
87
+ : [{ routeId, segments: row.path.split("/").filter((segment) => segment.length > 0) }]
88
+ );
89
+
90
+ const isParameterSegment = (segment: string): boolean =>
91
+ (segment.startsWith("{") && segment.endsWith("}")) || segment.startsWith(":");
92
+
93
+ function matchReadRoute(
94
+ pathname: string
95
+ ): { readonly routeId: string; readonly params: Record<string, string> } | undefined {
96
+ const hrefSegments = pathname
97
+ .replace(API_PREFIX, "")
98
+ .split("/")
99
+ .filter((segment) => segment.length > 0);
100
+ let best: { routeId: string; params: Record<string, string>; statics: number } | undefined;
101
+ for (const { routeId, segments } of readRoutes) {
102
+ if (segments.length !== hrefSegments.length) {
103
+ continue;
104
+ }
105
+ const params: Record<string, string> = {};
106
+ let statics = 0;
107
+ const matches = segments.every((segment, index) => {
108
+ const actual = hrefSegments[index]!;
109
+ if (!isParameterSegment(segment)) {
110
+ statics += 1;
111
+ return segment === actual;
112
+ }
113
+ params[segment.startsWith(":") ? segment.slice(1) : segment.slice(1, -1)] = decodeURIComponent(actual);
114
+ return true;
115
+ });
116
+ if (matches && (best === undefined || statics > best.statics)) {
117
+ best = { routeId, params, statics };
118
+ }
119
+ }
120
+ return best;
121
+ }
122
+
123
+ export function mapApiHrefToCliCommand(href: string): { readonly command: string } | undefined {
85
124
  const parsed = parseHref(href);
86
125
  if (parsed === undefined) {
87
126
  return undefined;
@@ -90,19 +129,23 @@ export function mapApiHrefToCliCommand(
90
129
  if (!(pathname.includes("/api/v2/") || pathname.startsWith("/api/"))) {
91
130
  return undefined;
92
131
  }
93
- const path = commandPathForUrl(method, pathname);
94
- if (path.length === 0) {
132
+ const route = matchReadRoute(pathname);
133
+ if (route === undefined) {
95
134
  return undefined;
96
135
  }
97
- const options: Record<string, string> = {};
136
+ const query: Record<string, string | Record<string, string>> = {};
98
137
  for (const [key, value] of searchParams.entries()) {
99
- const optionKey = key.includes("[") ? key : key;
100
- options[optionKey] = value;
138
+ const bracketed = BRACKETED_KEY.exec(key);
139
+ if (bracketed === null) {
140
+ query[key] = value;
141
+ continue;
142
+ }
143
+ const [, name, member] = bracketed;
144
+ const nested = query[name!];
145
+ query[name!] = { ...(typeof nested === "object" ? nested : {}), [member!]: value };
101
146
  }
102
- return {
103
- command: path.join(" "),
104
- ...(Object.keys(options).length > 0 ? { options } : {}),
105
- };
147
+ const command = cliCommandFor(route.routeId, { params: route.params, query });
148
+ return command === null ? undefined : { command: command.text };
106
149
  }
107
150
 
108
151
  export function commandsFromLinks(links: ResourceLinks | undefined): Array<CliCtaCommandObject> {
@@ -126,14 +169,12 @@ export function commandsFromLinks(links: ResourceLinks | undefined): Array<CliCt
126
169
  if (mapped === undefined) {
127
170
  continue;
128
171
  }
129
- const signature = `${mapped.command}|${JSON.stringify(mapped.options ?? {})}`;
130
- if (seen.has(signature)) {
172
+ if (seen.has(mapped.command)) {
131
173
  continue;
132
174
  }
133
- seen.add(signature);
175
+ seen.add(mapped.command);
134
176
  commands.push({
135
177
  command: mapped.command,
136
- ...(mapped.options === undefined ? {} : { options: mapped.options }),
137
178
  description: REL_DESCRIPTION[rel] ?? `Follow ${rel} link`,
138
179
  });
139
180
  }
@@ -222,15 +222,17 @@ function mcpMetadataFor(ops: ReadonlyArray<OperationDescriptor>) {
222
222
  function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
223
223
  const primary = pickPrimaryOp(ops);
224
224
  const { surface } = primary;
225
- const hasListSibling = ops.some((op) => op.pathSchema === undefined);
226
- const makePathOptional = hasListSibling && ops.length > 1;
225
+ const optionalPathParams = new Set(
226
+ surface.pathParams
227
+ .map((param) => param.name)
228
+ .filter((name) => ops.some((op) => !op.surface.pathParams.some((param) => param.name === name)))
229
+ );
227
230
  const mutation = ops.some((op) => isMutationMethod(op.method));
228
231
 
229
- const pathSchema = ops.map((op) => op.pathSchema).find((schema) => schema !== undefined);
230
232
  const querySchema = ops.map((op) => op.querySchema).find((schema) => schema !== undefined);
231
233
  const bodySchema = ops.map((op) => op.bodySchema).find((schema) => schema !== undefined);
232
234
 
233
- const argsSchema = buildArgsFromSdkPath(pathSchema ?? primary.pathSchema, surface, makePathOptional);
235
+ const argsSchema = buildArgsFromSdkPath(primary.pathSchema, surface, optionalPathParams);
234
236
  const optionsSchema = buildOptionsFromSdk(querySchema, bodySchema, surface, {
235
237
  ...(mutation
236
238
  ? {
@@ -172,7 +172,7 @@ function formatSurfaceDescribe(
172
172
  export function buildArgsFromSdkPath(
173
173
  pathSchema: ZodTypeAny | undefined,
174
174
  surface: SurfaceOperation | undefined,
175
- makeOptional: boolean
175
+ optionalNames: ReadonlySet<string>
176
176
  ): z.ZodObject<ZodShape> | undefined {
177
177
  const shape = objectShape(pathSchema);
178
178
  if (shape === undefined || Object.keys(shape).length === 0) {
@@ -181,7 +181,7 @@ export function buildArgsFromSdkPath(
181
181
  const out: ZodShape = {};
182
182
  for (const [name, fieldSchema] of Object.entries(shape)) {
183
183
  const described = asCliField(fieldSchema, openApiFieldDescription(surface, "path", name));
184
- out[name] = makeOptional ? described.optional() : described;
184
+ out[name] = optionalNames.has(name) ? described.optional() : described;
185
185
  }
186
186
  return z.object(out);
187
187
  }