sim 2.1.8-preview.98.1 → 2.1.8
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.
- package/README.md +16 -1
- package/dist/index.js +229 -113
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -220,11 +220,26 @@ will consume the result, and `text` for tab-separated shell output:
|
|
|
220
220
|
|
|
221
221
|
```bash
|
|
222
222
|
sim workflows list --output json
|
|
223
|
-
sim logs list --output json | jq -r '.[].runId'
|
|
223
|
+
sim logs list --output json | jq -r '.data[].runId'
|
|
224
224
|
SIM_OUTPUT=yaml sim tables get <tableId>
|
|
225
225
|
sim configure --set-output json
|
|
226
226
|
```
|
|
227
227
|
|
|
228
|
+
Paginated lists return `{ "data": [...], "nextCursor": "..." }` in JSON and YAML.
|
|
229
|
+
`nextCursor` is `null` when no pages remain. Resource lists and directory `ls`
|
|
230
|
+
fetch every page by default; use `--limit N` to cap them. Table rows (including
|
|
231
|
+
queries), logs, audit/billing events, workflow runs/versions, and knowledge
|
|
232
|
+
documents/chunks keep a default limit of 100. Use `--limit 0` to fetch every page
|
|
233
|
+
of those datasets, or pass the returned `nextCursor` to `--cursor` to continue
|
|
234
|
+
with another bounded result. Keep the same resource, filters, and sort order
|
|
235
|
+
when resuming; stop when `nextCursor` is `null`. Results accumulate in memory
|
|
236
|
+
before printing, so large datasets need an explicit limit or filter.
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
sim tables rows list <tableId> --limit 100 --output json
|
|
240
|
+
sim tables rows list <tableId> --limit 100 --cursor "$nextCursor" --output json
|
|
241
|
+
```
|
|
242
|
+
|
|
228
243
|
JSON-valued options accept inline JSON, a file prefixed with `@`, or stdin with
|
|
229
244
|
`@-`:
|
|
230
245
|
|
package/dist/index.js
CHANGED
|
@@ -4460,6 +4460,22 @@ function toApiError(url, status, contentType, raw) {
|
|
|
4460
4460
|
function truncate(value, max) {
|
|
4461
4461
|
return value.length <= max ? value : `${value.slice(0, max)}…`;
|
|
4462
4462
|
}
|
|
4463
|
+
function transportErrorMessage(error) {
|
|
4464
|
+
const messages = [];
|
|
4465
|
+
const seen = new Set;
|
|
4466
|
+
let current = error;
|
|
4467
|
+
while (current && typeof current === "object" && messages.length < 4 && !seen.has(current)) {
|
|
4468
|
+
seen.add(current);
|
|
4469
|
+
const candidate = current;
|
|
4470
|
+
const message = typeof candidate.message === "string" ? truncate(candidate.message.replace(/\s+/g, " ").trim(), 300) : "";
|
|
4471
|
+
const code = typeof candidate.code === "string" ? candidate.code : "";
|
|
4472
|
+
const detail = `${message}${code && !message.includes(code) ? ` (${code})` : ""}`;
|
|
4473
|
+
if (detail && messages.at(-1) !== detail)
|
|
4474
|
+
messages.push(detail);
|
|
4475
|
+
current = candidate.cause;
|
|
4476
|
+
}
|
|
4477
|
+
return messages.join(": ") || "Unknown network error";
|
|
4478
|
+
}
|
|
4463
4479
|
function namesKeyScopeRefusal(error) {
|
|
4464
4480
|
if (typeof error.code === "string" && KEY_SCOPE_REFUSALS.has(error.code))
|
|
4465
4481
|
return true;
|
|
@@ -4683,7 +4699,7 @@ class SimClient {
|
|
|
4683
4699
|
if (timeout?.aborted) {
|
|
4684
4700
|
throw new SimApiError(`${url} did not answer within ${timeoutMs / 1000}s. ${RAISE_TIMEOUT_HINT}`, 0);
|
|
4685
4701
|
}
|
|
4686
|
-
throw new SimApiError(`Could not reach ${this.profile.endpoint}: ${cause
|
|
4702
|
+
throw new SimApiError(`Could not reach ${this.profile.endpoint}: ${transportErrorMessage(cause)}`, 0);
|
|
4687
4703
|
}
|
|
4688
4704
|
if (trace)
|
|
4689
4705
|
traceRequest(method, url, response.status, startedAt);
|
|
@@ -4747,15 +4763,21 @@ function pageProgress() {
|
|
|
4747
4763
|
}
|
|
4748
4764
|
};
|
|
4749
4765
|
}
|
|
4750
|
-
|
|
4751
|
-
|
|
4766
|
+
function assertCursorAdvances(cursor, seenCursors) {
|
|
4767
|
+
if (cursor === null)
|
|
4768
|
+
return;
|
|
4769
|
+
if (seenCursors.has(cursor)) {
|
|
4770
|
+
throw new SimApiError("The API returned a repeated pagination cursor; cannot continue.", 0);
|
|
4771
|
+
}
|
|
4772
|
+
seenCursors.add(cursor);
|
|
4752
4773
|
}
|
|
4753
|
-
async function
|
|
4774
|
+
async function requestAllPages(client, path, options) {
|
|
4754
4775
|
const { query, pageSize, limit: requestedLimit, ...requestOptions } = options;
|
|
4755
4776
|
const limit = requestedLimit ?? Number.POSITIVE_INFINITY;
|
|
4756
4777
|
if (limit <= 0)
|
|
4757
|
-
return
|
|
4778
|
+
return [];
|
|
4758
4779
|
const items = [];
|
|
4780
|
+
const seenCursors = new Set;
|
|
4759
4781
|
const progress = pageProgress();
|
|
4760
4782
|
let cursor = null;
|
|
4761
4783
|
try {
|
|
@@ -4768,6 +4790,7 @@ async function requestPages(client, path, options) {
|
|
|
4768
4790
|
cursor
|
|
4769
4791
|
}
|
|
4770
4792
|
});
|
|
4793
|
+
assertCursorAdvances(page.nextCursor, seenCursors);
|
|
4771
4794
|
items.push(...page.data);
|
|
4772
4795
|
cursor = page.nextCursor;
|
|
4773
4796
|
if (cursor && items.length < limit)
|
|
@@ -4776,7 +4799,7 @@ async function requestPages(client, path, options) {
|
|
|
4776
4799
|
} finally {
|
|
4777
4800
|
progress.finish();
|
|
4778
4801
|
}
|
|
4779
|
-
return
|
|
4802
|
+
return items.slice(0, limit);
|
|
4780
4803
|
}
|
|
4781
4804
|
function resolvePath(template, params = {}) {
|
|
4782
4805
|
return template.replace(/\[([^\]]+)\]/g, (_match, key) => {
|
|
@@ -8700,6 +8723,7 @@ var V2_OPERATIONS = {
|
|
|
8700
8723
|
pathParamDocs: { workflowId: "Unique workflow identifier." },
|
|
8701
8724
|
responseMode: "json",
|
|
8702
8725
|
summary: "Apply Workflow Operations",
|
|
8726
|
+
workspaceKeyUnsupported: true,
|
|
8703
8727
|
query: {
|
|
8704
8728
|
dryRun: {
|
|
8705
8729
|
kind: "boolean",
|
|
@@ -8788,7 +8812,7 @@ var V2_OPERATIONS = {
|
|
|
8788
8812
|
},
|
|
8789
8813
|
folderPaths: {
|
|
8790
8814
|
kind: "string",
|
|
8791
|
-
describe: "
|
|
8815
|
+
describe: "Comma-separated folder paths whose contents are included recursively. Up to 100 paths; resolved files share the 100-file download limit. Unknown paths are rejected."
|
|
8792
8816
|
}
|
|
8793
8817
|
}
|
|
8794
8818
|
},
|
|
@@ -9447,7 +9471,7 @@ var V2_OPERATIONS = {
|
|
|
9447
9471
|
kind: "enum",
|
|
9448
9472
|
values: ["streamable-http"],
|
|
9449
9473
|
default: "streamable-http",
|
|
9450
|
-
describe: "Transport
|
|
9474
|
+
describe: "Transport protocol. Defaults to `streamable-http` on creation."
|
|
9451
9475
|
},
|
|
9452
9476
|
url: {
|
|
9453
9477
|
kind: "string",
|
|
@@ -9466,17 +9490,17 @@ var V2_OPERATIONS = {
|
|
|
9466
9490
|
timeout: {
|
|
9467
9491
|
kind: "integer",
|
|
9468
9492
|
default: 30000,
|
|
9469
|
-
describe: "Per-request timeout in milliseconds.
|
|
9493
|
+
describe: "Per-request timeout in milliseconds. Defaults to 30000 on creation."
|
|
9470
9494
|
},
|
|
9471
9495
|
retries: {
|
|
9472
9496
|
kind: "integer",
|
|
9473
9497
|
default: 3,
|
|
9474
|
-
describe: "Number of retries per request.
|
|
9498
|
+
describe: "Number of retries per request. Defaults to 3 on creation."
|
|
9475
9499
|
},
|
|
9476
9500
|
enabled: {
|
|
9477
9501
|
kind: "boolean",
|
|
9478
9502
|
default: true,
|
|
9479
|
-
describe: "Whether the server tools
|
|
9503
|
+
describe: "Whether workflows can use the server's tools. Defaults to true on creation."
|
|
9480
9504
|
},
|
|
9481
9505
|
oauthClientId: {
|
|
9482
9506
|
kind: "string",
|
|
@@ -10374,7 +10398,7 @@ var V2_OPERATIONS = {
|
|
|
10374
10398
|
input: {
|
|
10375
10399
|
kind: "object",
|
|
10376
10400
|
default: {},
|
|
10377
|
-
describe: "
|
|
10401
|
+
describe: "Tool arguments keyed by published parameter IDs. For `user-only` parameters, a whole-value `{{VAR_NAME}}` reference resolves a workspace environment variable. Other values pass through unchanged."
|
|
10378
10402
|
},
|
|
10379
10403
|
credentialId: {
|
|
10380
10404
|
kind: "string",
|
|
@@ -10409,7 +10433,7 @@ var V2_OPERATIONS = {
|
|
|
10409
10433
|
},
|
|
10410
10434
|
executionTimeoutSeconds: {
|
|
10411
10435
|
kind: "integer",
|
|
10412
|
-
describe: "
|
|
10436
|
+
describe: "Maximum duration of an asynchronous run, in seconds, capped by the plan's execution timeout. Requires `async: true`; otherwise returns `400`."
|
|
10413
10437
|
},
|
|
10414
10438
|
stream: {
|
|
10415
10439
|
kind: "boolean",
|
|
@@ -10418,7 +10442,7 @@ var V2_OPERATIONS = {
|
|
|
10418
10442
|
},
|
|
10419
10443
|
selectedOutputs: {
|
|
10420
10444
|
kind: "array",
|
|
10421
|
-
describe: "
|
|
10445
|
+
describe: "Output references for streaming: `<blockName>.<outputPath>` or `<childWorkflowId>.<blockName>.<outputPath>`, using normalized block names. Child references apply to every invocation. Requires `stream: true` and rejects synchronous or async requests. Use `selectedOutputs` with Get Workflow Run to narrow an existing run."
|
|
10422
10446
|
},
|
|
10423
10447
|
includeThinking: {
|
|
10424
10448
|
kind: "boolean",
|
|
@@ -10442,7 +10466,7 @@ var V2_OPERATIONS = {
|
|
|
10442
10466
|
headers: {
|
|
10443
10467
|
"x-run-id": {
|
|
10444
10468
|
kind: "string",
|
|
10445
|
-
describe:
|
|
10469
|
+
describe: "Run ID for API-key or OAuth callers; ignored for anonymous requests. Reuse it after an uncertain response: a claimed ID returns `409` with `RUN_ID_CONFLICT`, without replaying results. Check Get Workflow Run, but `404` can persist while the ID remains claimed and does not establish whether execution started. Do not automatically restart with a fresh or omitted ID; either can start another run."
|
|
10446
10470
|
},
|
|
10447
10471
|
"x-sim-via": {
|
|
10448
10472
|
kind: "string",
|
|
@@ -10666,7 +10690,7 @@ var V2_OPERATIONS = {
|
|
|
10666
10690
|
},
|
|
10667
10691
|
folderPaths: {
|
|
10668
10692
|
kind: "string",
|
|
10669
|
-
describe: "Comma-separated workflow folder paths
|
|
10693
|
+
describe: "Comma-separated workflow folder paths, including descendants. Up to 100 paths. Unknown folder paths contribute no matches."
|
|
10670
10694
|
},
|
|
10671
10695
|
triggers: {
|
|
10672
10696
|
kind: "string",
|
|
@@ -10688,7 +10712,7 @@ var V2_OPERATIONS = {
|
|
|
10688
10712
|
segmentCount: {
|
|
10689
10713
|
kind: "integer",
|
|
10690
10714
|
default: 72,
|
|
10691
|
-
describe: "Number of
|
|
10715
|
+
describe: "Number of time buckets, up to 500. Exactly this many are returned, each at least one minute wide. Short windows extend past the requested end and include empty trailing buckets."
|
|
10692
10716
|
}
|
|
10693
10717
|
}
|
|
10694
10718
|
},
|
|
@@ -11144,7 +11168,7 @@ var V2_OPERATIONS = {
|
|
|
11144
11168
|
source: {
|
|
11145
11169
|
kind: "enum",
|
|
11146
11170
|
values: ["builtin", "custom"],
|
|
11147
|
-
describe: "Restrict to
|
|
11171
|
+
describe: "Restrict to built-in blocks or this workspace's deployed custom blocks."
|
|
11148
11172
|
},
|
|
11149
11173
|
sortBy: {
|
|
11150
11174
|
kind: "enum",
|
|
@@ -11343,7 +11367,7 @@ var V2_OPERATIONS = {
|
|
|
11343
11367
|
},
|
|
11344
11368
|
parentPath: {
|
|
11345
11369
|
kind: "string",
|
|
11346
|
-
describe: "Restrict results to direct children of this parent path.
|
|
11370
|
+
describe: "Restrict results to direct children of this parent path. Unknown folder paths contribute no matches."
|
|
11347
11371
|
},
|
|
11348
11372
|
search: {
|
|
11349
11373
|
kind: "string",
|
|
@@ -11405,7 +11429,7 @@ var V2_OPERATIONS = {
|
|
|
11405
11429
|
},
|
|
11406
11430
|
folderPath: {
|
|
11407
11431
|
kind: "string",
|
|
11408
|
-
describe: "Restrict
|
|
11432
|
+
describe: "Restrict files to this folder, including subfolders when `recursive` is true. Unknown folder paths contribute no matches."
|
|
11409
11433
|
},
|
|
11410
11434
|
recursive: {
|
|
11411
11435
|
kind: "enum",
|
|
@@ -11423,7 +11447,7 @@ var V2_OPERATIONS = {
|
|
|
11423
11447
|
"n",
|
|
11424
11448
|
"disabled"
|
|
11425
11449
|
],
|
|
11426
|
-
describe: "
|
|
11450
|
+
describe: "Include subfolders in the folder filter. Defaults to true when searching and false otherwise. Ignored without a folder filter."
|
|
11427
11451
|
},
|
|
11428
11452
|
scope: {
|
|
11429
11453
|
kind: "enum",
|
|
@@ -11474,11 +11498,11 @@ var V2_OPERATIONS = {
|
|
|
11474
11498
|
kind: "enum",
|
|
11475
11499
|
values: ["active", "archived"],
|
|
11476
11500
|
default: "active",
|
|
11477
|
-
describe: "
|
|
11501
|
+
describe: "Lifecycle scope: active or archived knowledge bases. Use Restore Knowledge Base to recover archived entries. Folder paths resolve only active folders, so filtering by an archived folder returns no matches."
|
|
11478
11502
|
},
|
|
11479
11503
|
folderPath: {
|
|
11480
11504
|
kind: "string",
|
|
11481
|
-
describe: "Restrict results to knowledge bases in this folder.
|
|
11505
|
+
describe: "Restrict results to knowledge bases in this folder. Unknown folder paths contribute no matches."
|
|
11482
11506
|
},
|
|
11483
11507
|
search: {
|
|
11484
11508
|
kind: "string",
|
|
@@ -11698,7 +11722,7 @@ var V2_OPERATIONS = {
|
|
|
11698
11722
|
},
|
|
11699
11723
|
parentPath: {
|
|
11700
11724
|
kind: "string",
|
|
11701
|
-
describe: "Restrict results to direct children of this parent path.
|
|
11725
|
+
describe: "Restrict results to direct children of this parent path. Unknown folder paths contribute no matches."
|
|
11702
11726
|
},
|
|
11703
11727
|
search: {
|
|
11704
11728
|
kind: "string",
|
|
@@ -11849,7 +11873,7 @@ var V2_OPERATIONS = {
|
|
|
11849
11873
|
},
|
|
11850
11874
|
folderPaths: {
|
|
11851
11875
|
kind: "string",
|
|
11852
|
-
describe: "Comma-separated workflow folder paths
|
|
11876
|
+
describe: "Comma-separated workflow folder paths, including descendants. Up to 100 paths. Unknown folder paths contribute no matches."
|
|
11853
11877
|
}
|
|
11854
11878
|
}
|
|
11855
11879
|
},
|
|
@@ -11908,7 +11932,7 @@ var V2_OPERATIONS = {
|
|
|
11908
11932
|
},
|
|
11909
11933
|
refresh: {
|
|
11910
11934
|
kind: "boolean",
|
|
11911
|
-
describe: "
|
|
11935
|
+
describe: "Refresh tools using your credentials. Otherwise results may reuse another workspace member's recent discovery and omit newly added tools."
|
|
11912
11936
|
}
|
|
11913
11937
|
}
|
|
11914
11938
|
},
|
|
@@ -12086,7 +12110,7 @@ var V2_OPERATIONS = {
|
|
|
12086
12110
|
},
|
|
12087
12111
|
parentPath: {
|
|
12088
12112
|
kind: "string",
|
|
12089
|
-
describe: "Restrict results to direct children of this parent path.
|
|
12113
|
+
describe: "Restrict results to direct children of this parent path. Unknown folder paths contribute no matches."
|
|
12090
12114
|
},
|
|
12091
12115
|
search: {
|
|
12092
12116
|
kind: "string",
|
|
@@ -12150,7 +12174,7 @@ var V2_OPERATIONS = {
|
|
|
12150
12174
|
},
|
|
12151
12175
|
folderPath: {
|
|
12152
12176
|
kind: "string",
|
|
12153
|
-
describe: "Restrict results to tables in this folder.
|
|
12177
|
+
describe: "Restrict results to tables in this folder. Unknown folder paths contribute no matches."
|
|
12154
12178
|
},
|
|
12155
12179
|
search: {
|
|
12156
12180
|
kind: "string",
|
|
@@ -12252,7 +12276,7 @@ var V2_OPERATIONS = {
|
|
|
12252
12276
|
},
|
|
12253
12277
|
parentPath: {
|
|
12254
12278
|
kind: "string",
|
|
12255
|
-
describe: "Restrict results to direct children of this parent path.
|
|
12279
|
+
describe: "Restrict results to direct children of this parent path. Unknown folder paths contribute no matches."
|
|
12256
12280
|
},
|
|
12257
12281
|
search: {
|
|
12258
12282
|
kind: "string",
|
|
@@ -12387,7 +12411,7 @@ var V2_OPERATIONS = {
|
|
|
12387
12411
|
},
|
|
12388
12412
|
folderPath: {
|
|
12389
12413
|
kind: "string",
|
|
12390
|
-
describe: "Restrict results to workflows in this folder path.
|
|
12414
|
+
describe: "Restrict results to workflows in this folder path. Unknown folder paths contribute no matches."
|
|
12391
12415
|
},
|
|
12392
12416
|
deployedOnly: {
|
|
12393
12417
|
kind: "boolean",
|
|
@@ -12694,6 +12718,7 @@ var V2_OPERATIONS = {
|
|
|
12694
12718
|
pathParamDocs: { workflowId: "Unique workflow identifier." },
|
|
12695
12719
|
responseMode: "json",
|
|
12696
12720
|
summary: "Create or Replace Workflow Chat Deployment",
|
|
12721
|
+
workspaceKeyUnsupported: true,
|
|
12697
12722
|
body: {
|
|
12698
12723
|
identifier: {
|
|
12699
12724
|
kind: "string",
|
|
@@ -12746,6 +12771,7 @@ var V2_OPERATIONS = {
|
|
|
12746
12771
|
pathParamDocs: { workflowId: "Unique workflow identifier." },
|
|
12747
12772
|
responseMode: "json",
|
|
12748
12773
|
summary: "Replace Workflow State",
|
|
12774
|
+
workspaceKeyUnsupported: true,
|
|
12749
12775
|
query: {
|
|
12750
12776
|
dryRun: {
|
|
12751
12777
|
kind: "boolean",
|
|
@@ -13182,6 +13208,11 @@ var V2_OPERATIONS = {
|
|
|
13182
13208
|
},
|
|
13183
13209
|
apiToken: { kind: "string", describe: "Write-only provider API token." },
|
|
13184
13210
|
domain: { kind: "string", describe: "Provider account domain." },
|
|
13211
|
+
atlassianProduct: {
|
|
13212
|
+
kind: "enum",
|
|
13213
|
+
values: ["jira", "confluence"],
|
|
13214
|
+
describe: "Atlassian product to verify; defaults to Jira on create and preserves the saved product on reconnect."
|
|
13215
|
+
},
|
|
13185
13216
|
signingSecret: { kind: "string", describe: "Write-only webhook signing secret." },
|
|
13186
13217
|
botToken: { kind: "string", describe: "Write-only bot token." },
|
|
13187
13218
|
clientId: { kind: "string", describe: "OAuth client identifier." },
|
|
@@ -13432,7 +13463,7 @@ var V2_OPERATIONS = {
|
|
|
13432
13463
|
kind: "enum",
|
|
13433
13464
|
values: ["streamable-http"],
|
|
13434
13465
|
default: "streamable-http",
|
|
13435
|
-
describe: "Transport
|
|
13466
|
+
describe: "Transport protocol. Defaults to `streamable-http` on creation."
|
|
13436
13467
|
},
|
|
13437
13468
|
url: {
|
|
13438
13469
|
kind: "string",
|
|
@@ -13450,17 +13481,17 @@ var V2_OPERATIONS = {
|
|
|
13450
13481
|
timeout: {
|
|
13451
13482
|
kind: "integer",
|
|
13452
13483
|
default: 30000,
|
|
13453
|
-
describe: "Per-request timeout in milliseconds.
|
|
13484
|
+
describe: "Per-request timeout in milliseconds. Defaults to 30000 on creation."
|
|
13454
13485
|
},
|
|
13455
13486
|
retries: {
|
|
13456
13487
|
kind: "integer",
|
|
13457
13488
|
default: 3,
|
|
13458
|
-
describe: "Number of retries per request.
|
|
13489
|
+
describe: "Number of retries per request. Defaults to 3 on creation."
|
|
13459
13490
|
},
|
|
13460
13491
|
enabled: {
|
|
13461
13492
|
kind: "boolean",
|
|
13462
13493
|
default: true,
|
|
13463
|
-
describe: "Whether the server tools
|
|
13494
|
+
describe: "Whether workflows can use the server's tools. Defaults to true on creation."
|
|
13464
13495
|
},
|
|
13465
13496
|
oauthClientId: {
|
|
13466
13497
|
kind: "string",
|
|
@@ -16056,7 +16087,30 @@ function buildRequest(operation, positional, flags, workspaceId) {
|
|
|
16056
16087
|
}
|
|
16057
16088
|
|
|
16058
16089
|
// src/runtime/options.ts
|
|
16059
|
-
var
|
|
16090
|
+
var DEFAULT_PAGE_SIZE = 100;
|
|
16091
|
+
var COMPLETE_LIST_OPERATIONS = new Set([
|
|
16092
|
+
"listBlocks",
|
|
16093
|
+
"listChatDeployments",
|
|
16094
|
+
"listCredentials",
|
|
16095
|
+
"listCustomTools",
|
|
16096
|
+
"listFiles",
|
|
16097
|
+
"listKnowledgeBases",
|
|
16098
|
+
"listKnowledgeConnectors",
|
|
16099
|
+
"listMcpServers",
|
|
16100
|
+
"listSandboxes",
|
|
16101
|
+
"listSecrets",
|
|
16102
|
+
"listSkillEditors",
|
|
16103
|
+
"listSkills",
|
|
16104
|
+
"listTables",
|
|
16105
|
+
"listTools",
|
|
16106
|
+
"listWorkflowMcpServers",
|
|
16107
|
+
"listWorkflows",
|
|
16108
|
+
"listWorkspaceMembers",
|
|
16109
|
+
"listWorkspaces"
|
|
16110
|
+
]);
|
|
16111
|
+
function defaultListLimit(operation) {
|
|
16112
|
+
return COMPLETE_LIST_OPERATIONS.has(operation) ? 0 : 100;
|
|
16113
|
+
}
|
|
16060
16114
|
function describeField(flag, descriptor, name, field) {
|
|
16061
16115
|
return flag.describe ?? descriptor.describe ?? `Set ${name.replaceAll("-", " ") || field}`;
|
|
16062
16116
|
}
|
|
@@ -16069,15 +16123,21 @@ function withoutWireVocabulary(documented) {
|
|
|
16069
16123
|
}
|
|
16070
16124
|
var NON_PAGINATED_LIMIT_HINT = " (caps a --filter match only; omit it to act on every match, and note 0 is not accepted)";
|
|
16071
16125
|
function addFieldOption(command, operation, field, descriptor, slot, paginates, capsAFilter) {
|
|
16072
|
-
if (field === PROFILE_INJECTED_FIELD
|
|
16126
|
+
if (field === PROFILE_INJECTED_FIELD)
|
|
16127
|
+
return;
|
|
16128
|
+
if (field === "cursor") {
|
|
16129
|
+
if (paginates && defaultListLimit(operation) > 0) {
|
|
16130
|
+
command.option("--cursor <value>", "Continue from nextCursor returned by a previous result");
|
|
16131
|
+
}
|
|
16073
16132
|
return;
|
|
16133
|
+
}
|
|
16074
16134
|
const flag = flagSpecFor(operation, field);
|
|
16075
16135
|
if (flag.omit)
|
|
16076
16136
|
return;
|
|
16077
16137
|
const name = flagNameFor(operation, field);
|
|
16078
16138
|
const short = flag.short ? `-${flag.short}, ` : "";
|
|
16079
16139
|
if (paginates && field === "limit" && (descriptor.kind === "number" || descriptor.kind === "integer")) {
|
|
16080
|
-
command.option("--limit <n>", "Maximum items to return (0 for everything)", String(
|
|
16140
|
+
command.option("--limit <n>", "Maximum items to return (0 for everything)", String(defaultListLimit(operation)));
|
|
16081
16141
|
return;
|
|
16082
16142
|
}
|
|
16083
16143
|
const documented = `${describeField(flag, descriptor, name, field)}${capsAFilter && field === "limit" && (descriptor.kind === "number" || descriptor.kind === "integer") ? NON_PAGINATED_LIMIT_HINT : ""}`;
|
|
@@ -16437,11 +16497,10 @@ function unwrapResource(data) {
|
|
|
16437
16497
|
const [, value] = entries[0];
|
|
16438
16498
|
return value && typeof value === "object" && !Array.isArray(value) ? value : data;
|
|
16439
16499
|
}
|
|
16440
|
-
function renderPage(format,
|
|
16500
|
+
function renderPage(format, page, spec, envelope) {
|
|
16441
16501
|
writePageNote(spec, envelope);
|
|
16442
16502
|
writeEnvelopeTruncation(envelope);
|
|
16443
|
-
|
|
16444
|
-
printList(format, rows, spec.columns ? columnsFrom(spec.columns) : inferColumns(rows, spec.expand));
|
|
16503
|
+
printList(format, page.data, spec.columns ? columnsFrom(spec.columns) : inferColumns(page.data, spec.expand), page);
|
|
16445
16504
|
}
|
|
16446
16505
|
function writePageNote(spec, envelope) {
|
|
16447
16506
|
if (!spec.pageNote)
|
|
@@ -16486,12 +16545,6 @@ function writeEnvelopeTruncation(envelope) {
|
|
|
16486
16545
|
`));
|
|
16487
16546
|
}
|
|
16488
16547
|
}
|
|
16489
|
-
function writeCursorTruncation(count, truncated) {
|
|
16490
|
-
if (!truncated)
|
|
16491
|
-
return;
|
|
16492
|
-
process.stderr.write(source_default.dim(`showing the first ${count}; more results exist — re-run with --limit 0 for all
|
|
16493
|
-
`));
|
|
16494
|
-
}
|
|
16495
16548
|
function renderResult(operation, format, raw, spec, options = {}, envelope) {
|
|
16496
16549
|
writeEnvelopeTruncation(envelope);
|
|
16497
16550
|
if (spec.document) {
|
|
@@ -16628,8 +16681,8 @@ function bulkFailureMessage(operation, payload, body) {
|
|
|
16628
16681
|
var EXCLUSIVE_CAP_FIELDS = {
|
|
16629
16682
|
deleteTableRows: { cap: "limit", ids: "rowIds" }
|
|
16630
16683
|
};
|
|
16631
|
-
function readPagedLimit(raw) {
|
|
16632
|
-
const text = String(raw ??
|
|
16684
|
+
function readPagedLimit(raw, operation) {
|
|
16685
|
+
const text = String(raw ?? defaultListLimit(operation)).trim();
|
|
16633
16686
|
const value = text === "" ? Number.NaN : Number(text);
|
|
16634
16687
|
if (!Number.isInteger(value) || value < 0) {
|
|
16635
16688
|
throw new SimApiError("--limit must be a whole number of 0 or more (0 for everything)", 0);
|
|
@@ -16704,24 +16757,33 @@ async function executeOperation(operation, commandSpec, operationSpec, invocatio
|
|
|
16704
16757
|
const omitsWorkspace = commandSpec.allWorkspaces && requestFlags.allWorkspaces === true;
|
|
16705
16758
|
const needsWorkspace = (hasWorkspaceField || commandSpec.profileWorkspacePath === true) && !omitsWorkspace;
|
|
16706
16759
|
const paging = cursorSlot(operationSpec);
|
|
16707
|
-
const pagedLimit = paging ? readPagedLimit(requestFlags.limit) : 0;
|
|
16760
|
+
const pagedLimit = paging ? readPagedLimit(requestFlags.limit, operation) : 0;
|
|
16708
16761
|
const request = buildRequest(operation, positional, requestFlags, needsWorkspace ? client.requireWorkspace() : profile.workspaceId);
|
|
16709
16762
|
if (paging) {
|
|
16763
|
+
const initialCursor = request[paging]?.cursor;
|
|
16764
|
+
if (initialCursor !== undefined && (typeof initialCursor !== "string" || initialCursor.trim() === "")) {
|
|
16765
|
+
throw new SimApiError("--cursor must be a non-empty string", 0);
|
|
16766
|
+
}
|
|
16710
16767
|
const limit = pagedLimit === 0 ? Number.POSITIVE_INFINITY : pagedLimit;
|
|
16711
|
-
const pageSize = Math.min(Number.isFinite(limit) ? limit : DEFAULT_LIMIT, DEFAULT_LIMIT);
|
|
16712
|
-
const pageLimit = "limit" in (operationSpec[paging] ?? {}) ? { limit: pageSize } : {};
|
|
16713
16768
|
const rows = [];
|
|
16769
|
+
const seenCursors = new Set(initialCursor ? [initialCursor] : []);
|
|
16714
16770
|
const progress = pageProgress();
|
|
16715
|
-
let cursor = null;
|
|
16771
|
+
let cursor = initialCursor ?? null;
|
|
16716
16772
|
let envelope;
|
|
16717
16773
|
try {
|
|
16718
16774
|
do {
|
|
16775
|
+
const pageSize = Math.min(DEFAULT_PAGE_SIZE, limit - rows.length);
|
|
16776
|
+
const pageLimit = "limit" in (operationSpec[paging] ?? {}) ? { limit: pageSize } : {};
|
|
16719
16777
|
const page = await client.request(request.path, {
|
|
16720
16778
|
method: operationSpec.method,
|
|
16721
16779
|
headers: request.headers,
|
|
16722
16780
|
query: paging === "query" ? { ...request.query, ...pageLimit, cursor } : request.query,
|
|
16723
16781
|
body: paging === "body" ? { ...request.body ?? {}, ...pageLimit, ...cursor ? { cursor } : {} } : request.body
|
|
16724
16782
|
});
|
|
16783
|
+
if (page.data.length > pageSize) {
|
|
16784
|
+
throw new SimApiError(`The API returned ${page.data.length} items for a page limit of ${pageSize}; nextCursor would skip unreturned items.`, 0);
|
|
16785
|
+
}
|
|
16786
|
+
assertCursorAdvances(page.nextCursor, seenCursors);
|
|
16725
16787
|
envelope = foldPageEnvelope(envelope, page);
|
|
16726
16788
|
rows.push(...page.data);
|
|
16727
16789
|
cursor = page.nextCursor;
|
|
@@ -16731,7 +16793,7 @@ async function executeOperation(operation, commandSpec, operationSpec, invocatio
|
|
|
16731
16793
|
} finally {
|
|
16732
16794
|
progress.finish();
|
|
16733
16795
|
}
|
|
16734
|
-
renderPage(profile.output,
|
|
16796
|
+
renderPage(profile.output, { data: rows, nextCursor: cursor }, commandSpec, envelope);
|
|
16735
16797
|
return;
|
|
16736
16798
|
}
|
|
16737
16799
|
const result = await client.request(request.path, {
|
|
@@ -17239,6 +17301,47 @@ function attachCredentialCommands(program) {
|
|
|
17239
17301
|
credentials.command("reconnect").argument("<credentialId>", "Existing OAuth credential to re-authorize").description(describeOperation(V2_OPERATIONS.createCredentialConnection, "Create a short-lived link for reconnecting an OAuth credential")).action((credentialId, _options, command) => createConnectionLink(command, { credentialId }));
|
|
17240
17302
|
}
|
|
17241
17303
|
|
|
17304
|
+
// src/http/ndjson.ts
|
|
17305
|
+
async function* readNdjson(body, protocol) {
|
|
17306
|
+
if (!body) {
|
|
17307
|
+
throw new SimApiError(`${protocol} ended without a response body`, 0);
|
|
17308
|
+
}
|
|
17309
|
+
const reader = body.getReader();
|
|
17310
|
+
const decoder = new TextDecoder;
|
|
17311
|
+
let buffer = "";
|
|
17312
|
+
const parse = (line) => {
|
|
17313
|
+
const trimmed = line.trim();
|
|
17314
|
+
if (!trimmed)
|
|
17315
|
+
return;
|
|
17316
|
+
try {
|
|
17317
|
+
return JSON.parse(trimmed);
|
|
17318
|
+
} catch {
|
|
17319
|
+
throw new SimApiError(`${protocol} returned malformed data`, 0);
|
|
17320
|
+
}
|
|
17321
|
+
};
|
|
17322
|
+
try {
|
|
17323
|
+
while (true) {
|
|
17324
|
+
const { done, value } = await reader.read();
|
|
17325
|
+
buffer += done ? decoder.decode() : decoder.decode(value, { stream: true });
|
|
17326
|
+
const lines = buffer.split(`
|
|
17327
|
+
`);
|
|
17328
|
+
buffer = done ? "" : lines.pop() ?? "";
|
|
17329
|
+
for (const line of lines) {
|
|
17330
|
+
const event = parse(line);
|
|
17331
|
+
if (event !== undefined)
|
|
17332
|
+
yield event;
|
|
17333
|
+
}
|
|
17334
|
+
if (done)
|
|
17335
|
+
return;
|
|
17336
|
+
}
|
|
17337
|
+
} finally {
|
|
17338
|
+
reader.cancel().catch(() => {
|
|
17339
|
+
return;
|
|
17340
|
+
});
|
|
17341
|
+
reader.releaseLock();
|
|
17342
|
+
}
|
|
17343
|
+
}
|
|
17344
|
+
|
|
17242
17345
|
// src/commands/protocol/result.ts
|
|
17243
17346
|
function printProtocolResult(format, result) {
|
|
17244
17347
|
const fields = Object.entries(result).map(([key, value]) => [key, text(value)]);
|
|
@@ -17246,72 +17349,28 @@ function printProtocolResult(format, result) {
|
|
|
17246
17349
|
}
|
|
17247
17350
|
|
|
17248
17351
|
// src/commands/protocol/chat.ts
|
|
17249
|
-
function parseChatStreamLine(line) {
|
|
17250
|
-
const trimmed = line.trim();
|
|
17251
|
-
if (!trimmed)
|
|
17252
|
-
return;
|
|
17253
|
-
try {
|
|
17254
|
-
return JSON.parse(trimmed);
|
|
17255
|
-
} catch {
|
|
17256
|
-
throw new SimApiError("Chat stream returned malformed data", 0);
|
|
17257
|
-
}
|
|
17258
|
-
}
|
|
17259
17352
|
async function readChatStream(response, onChunk) {
|
|
17260
|
-
|
|
17261
|
-
|
|
17262
|
-
|
|
17263
|
-
|
|
17264
|
-
|
|
17265
|
-
|
|
17266
|
-
|
|
17267
|
-
const processLine = (line) => {
|
|
17268
|
-
const event = parseChatStreamLine(line);
|
|
17269
|
-
if (!event || event.type === "heartbeat")
|
|
17270
|
-
return false;
|
|
17353
|
+
for await (const value of readNdjson(response.body, "Chat stream")) {
|
|
17354
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
17355
|
+
throw new SimApiError("Chat stream returned an unknown event", 0);
|
|
17356
|
+
}
|
|
17357
|
+
const event = value;
|
|
17358
|
+
if (event.type === "heartbeat")
|
|
17359
|
+
continue;
|
|
17271
17360
|
if (event.type === "chunk") {
|
|
17272
17361
|
if (event.content)
|
|
17273
17362
|
onChunk(sanitize(event.content));
|
|
17274
|
-
|
|
17363
|
+
continue;
|
|
17275
17364
|
}
|
|
17276
17365
|
if (event.type === "error") {
|
|
17277
17366
|
throw new SimApiError(event.error || "Chat request failed", 0);
|
|
17278
17367
|
}
|
|
17279
17368
|
if (event.type === "final") {
|
|
17280
|
-
|
|
17281
|
-
return true;
|
|
17369
|
+
return event.data;
|
|
17282
17370
|
}
|
|
17283
17371
|
throw new SimApiError("Chat stream returned an unknown event", 0);
|
|
17284
|
-
};
|
|
17285
|
-
try {
|
|
17286
|
-
let ended = false;
|
|
17287
|
-
while (!ended) {
|
|
17288
|
-
const { done, value } = await reader.read();
|
|
17289
|
-
if (done)
|
|
17290
|
-
break;
|
|
17291
|
-
buffer += decoder.decode(value, { stream: true });
|
|
17292
|
-
const lines = buffer.split(`
|
|
17293
|
-
`);
|
|
17294
|
-
buffer = lines.pop() ?? "";
|
|
17295
|
-
for (const line of lines) {
|
|
17296
|
-
if (processLine(line)) {
|
|
17297
|
-
ended = true;
|
|
17298
|
-
break;
|
|
17299
|
-
}
|
|
17300
|
-
}
|
|
17301
|
-
}
|
|
17302
|
-
if (!ended) {
|
|
17303
|
-
buffer += decoder.decode();
|
|
17304
|
-
processLine(buffer);
|
|
17305
|
-
}
|
|
17306
|
-
if (!finalResult) {
|
|
17307
|
-
throw new SimApiError("Chat stream ended without a final result", 0);
|
|
17308
|
-
}
|
|
17309
|
-
return finalResult;
|
|
17310
|
-
} finally {
|
|
17311
|
-
reader.cancel().catch(() => {
|
|
17312
|
-
return;
|
|
17313
|
-
});
|
|
17314
17372
|
}
|
|
17373
|
+
throw new SimApiError("Chat stream ended without a final result", 0);
|
|
17315
17374
|
}
|
|
17316
17375
|
function ignoreBrokenPipe(stream) {
|
|
17317
17376
|
const onError = (error) => {
|
|
@@ -18086,11 +18145,11 @@ async function listResources(client, config, workspaceId, folderPath, search, li
|
|
|
18086
18145
|
const paginated = "cursor" in V2_OPERATIONS[config.resources].query;
|
|
18087
18146
|
if (!paginated) {
|
|
18088
18147
|
const page = await client.request(path, { query });
|
|
18089
|
-
return
|
|
18148
|
+
return page.data.slice(0, limit);
|
|
18090
18149
|
}
|
|
18091
|
-
return
|
|
18150
|
+
return requestAllPages(client, path, {
|
|
18092
18151
|
query,
|
|
18093
|
-
pageSize:
|
|
18152
|
+
pageSize: DEFAULT_PAGE_SIZE,
|
|
18094
18153
|
limit
|
|
18095
18154
|
});
|
|
18096
18155
|
}
|
|
@@ -18120,7 +18179,7 @@ function entriesFor(config, folders, resources) {
|
|
|
18120
18179
|
].sort((left, right) => left.name.localeCompare(right.name) || left.kind.localeCompare(right.kind));
|
|
18121
18180
|
}
|
|
18122
18181
|
function attachResourceDirectoryCommands(group, config) {
|
|
18123
|
-
group.command("ls").argument("[path]", "Folder path to list; defaults to the root folder").allowExcessArguments(false).description(`List ${config.kind} resources and child folders together`).option("--search <text>", "Filter folders and resources by name").addOption(new Option("--limit <n>", "Maximum combined items to return (0 for everything)").default(
|
|
18182
|
+
group.command("ls").argument("[path]", "Folder path to list; defaults to the root folder").allowExcessArguments(false).description(`List ${config.kind} resources and child folders together`).option("--search <text>", "Filter folders and resources by name").addOption(new Option("--limit <n>", "Maximum combined items to return (0 for everything)").default("0")).action(async (path, options, command) => {
|
|
18124
18183
|
const rawLimit = Number(options.limit);
|
|
18125
18184
|
if (!Number.isSafeInteger(rawLimit) || rawLimit < 0) {
|
|
18126
18185
|
throw new SimApiError("--limit must be a whole number of 0 or more (0 for everything)", 0);
|
|
@@ -18133,9 +18192,8 @@ function attachResourceDirectoryCommands(group, config) {
|
|
|
18133
18192
|
listFolders(client, config.folders, workspaceId, folderPath, options.search),
|
|
18134
18193
|
listResources(client, config, workspaceId, folderPath, options.search, limit)
|
|
18135
18194
|
]);
|
|
18136
|
-
const entries = entriesFor(config, folders, resources
|
|
18195
|
+
const entries = entriesFor(config, folders, resources);
|
|
18137
18196
|
const shown = entries.slice(0, limit);
|
|
18138
|
-
writeCursorTruncation(shown.length, resources.truncated || entries.length > limit);
|
|
18139
18197
|
printList(profile.output, shown, COLUMNS2);
|
|
18140
18198
|
});
|
|
18141
18199
|
group.command("mkdir").argument("<path>", "Folder path to create; the leading / is optional").allowExcessArguments(false).description(`Create a ${config.kind} directory at a path`).action(async (path, _options, command) => {
|
|
@@ -18302,6 +18360,7 @@ function attachTableImport(tables) {
|
|
|
18302
18360
|
// src/commands/protocol/workflow-run-follow.ts
|
|
18303
18361
|
var AGENT_STREAM_PROTOCOL_HEADER = "x-sim-stream-protocol";
|
|
18304
18362
|
var AGENT_STREAM_PROTOCOL_V1 = "agent-events-v1";
|
|
18363
|
+
var WORKFLOW_RESULT_STREAM_CONTENT_TYPE = "application/x-ndjson";
|
|
18305
18364
|
var DONE_SENTINEL = "[DONE]";
|
|
18306
18365
|
function resolveWorkflowRunSelection(flags) {
|
|
18307
18366
|
const manual = flags.manual === true;
|
|
@@ -18353,6 +18412,59 @@ function stringField(frame, key) {
|
|
|
18353
18412
|
const value = frame[key];
|
|
18354
18413
|
return typeof value === "string" ? value : null;
|
|
18355
18414
|
}
|
|
18415
|
+
async function readWorkflowResult(response) {
|
|
18416
|
+
const contentType = (response.headers.get("content-type") ?? "").toLowerCase();
|
|
18417
|
+
if (!contentType.includes(WORKFLOW_RESULT_STREAM_CONTENT_TYPE)) {
|
|
18418
|
+
let envelope;
|
|
18419
|
+
try {
|
|
18420
|
+
envelope = await response.json();
|
|
18421
|
+
} catch {
|
|
18422
|
+
throw new SimApiError(`Workflow run returned malformed JSON${contentType ? ` as ${contentType}` : ""}`, response.status);
|
|
18423
|
+
}
|
|
18424
|
+
if (!isRecord(envelope)) {
|
|
18425
|
+
throw new SimApiError("Workflow run returned an invalid result envelope", response.status);
|
|
18426
|
+
}
|
|
18427
|
+
return isRecord(envelope.data) ? envelope.data : envelope;
|
|
18428
|
+
}
|
|
18429
|
+
for await (const value of readNdjson(response.body, "Workflow result stream")) {
|
|
18430
|
+
if (!isRecord(value) || typeof value.type !== "string") {
|
|
18431
|
+
throw new SimApiError("Workflow result stream returned an unknown event", response.status);
|
|
18432
|
+
}
|
|
18433
|
+
if (value.type === "heartbeat")
|
|
18434
|
+
continue;
|
|
18435
|
+
if (value.type === "error") {
|
|
18436
|
+
throw new SimApiError(safeOneLine(typeof value.error === "string" ? value.error : "Workflow run failed"), typeof value.status === "number" ? value.status : 0, typeof value.code === "string" ? value.code : null);
|
|
18437
|
+
}
|
|
18438
|
+
if (value.type === "final" && isRecord(value.data))
|
|
18439
|
+
return value.data;
|
|
18440
|
+
throw new SimApiError("Workflow result stream returned an unknown event", response.status);
|
|
18441
|
+
}
|
|
18442
|
+
throw new SimApiError("Workflow result stream ended without a final result", response.status);
|
|
18443
|
+
}
|
|
18444
|
+
async function runWithResultStream(workflowId, command) {
|
|
18445
|
+
const flags = command.optsWithGlobals();
|
|
18446
|
+
const { client, profile } = clientFrom(command);
|
|
18447
|
+
const operation = V2_OPERATIONS.executeWorkflow;
|
|
18448
|
+
const commandSpec = CLI_CONTRACT.executeWorkflow ?? {};
|
|
18449
|
+
try {
|
|
18450
|
+
const request = buildRequest("executeWorkflow", [workflowId], flags, profile.workspaceId);
|
|
18451
|
+
const response = await client.requestRaw(request.path, {
|
|
18452
|
+
method: operation.method,
|
|
18453
|
+
query: request.query,
|
|
18454
|
+
body: request.body,
|
|
18455
|
+
headers: { ...request.headers, accept: WORKFLOW_RESULT_STREAM_CONTENT_TYPE }
|
|
18456
|
+
});
|
|
18457
|
+
const payload = await readWorkflowResult(response);
|
|
18458
|
+
renderResult("executeWorkflow", profile.output, payload, commandSpec, {
|
|
18459
|
+
expandedTrace: flags.trace === true
|
|
18460
|
+
});
|
|
18461
|
+
const failure = runFailureMessage("executeWorkflow", payload);
|
|
18462
|
+
if (failure)
|
|
18463
|
+
throw new SimApiError(failure, 0);
|
|
18464
|
+
} catch (error) {
|
|
18465
|
+
throw retypeApiError(error, "executeWorkflow", commandSpec, operation);
|
|
18466
|
+
}
|
|
18467
|
+
}
|
|
18356
18468
|
async function* sseData(body) {
|
|
18357
18469
|
const reader = body.getReader();
|
|
18358
18470
|
const decoder = new TextDecoder;
|
|
@@ -18524,6 +18636,10 @@ function followOrDelegate(previous) {
|
|
|
18524
18636
|
if (flags.includeThinking === true || flags.includeToolCalls === true) {
|
|
18525
18637
|
throw new SimApiError("--include-thinking and --include-tool-calls describe a stream; add --follow", 0);
|
|
18526
18638
|
}
|
|
18639
|
+
if (flags.async !== true) {
|
|
18640
|
+
await runWithResultStream(workflowId, command);
|
|
18641
|
+
return;
|
|
18642
|
+
}
|
|
18527
18643
|
if (previous) {
|
|
18528
18644
|
await previous(command.processedArgs);
|
|
18529
18645
|
return;
|