sim 2.1.8-preview.100.1 → 2.1.8-preview.102.1
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 +67 -30
- 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
|
@@ -4763,15 +4763,21 @@ function pageProgress() {
|
|
|
4763
4763
|
}
|
|
4764
4764
|
};
|
|
4765
4765
|
}
|
|
4766
|
-
|
|
4767
|
-
|
|
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);
|
|
4768
4773
|
}
|
|
4769
|
-
async function
|
|
4774
|
+
async function requestAllPages(client, path, options) {
|
|
4770
4775
|
const { query, pageSize, limit: requestedLimit, ...requestOptions } = options;
|
|
4771
4776
|
const limit = requestedLimit ?? Number.POSITIVE_INFINITY;
|
|
4772
4777
|
if (limit <= 0)
|
|
4773
|
-
return
|
|
4778
|
+
return [];
|
|
4774
4779
|
const items = [];
|
|
4780
|
+
const seenCursors = new Set;
|
|
4775
4781
|
const progress = pageProgress();
|
|
4776
4782
|
let cursor = null;
|
|
4777
4783
|
try {
|
|
@@ -4784,6 +4790,7 @@ async function requestPages(client, path, options) {
|
|
|
4784
4790
|
cursor
|
|
4785
4791
|
}
|
|
4786
4792
|
});
|
|
4793
|
+
assertCursorAdvances(page.nextCursor, seenCursors);
|
|
4787
4794
|
items.push(...page.data);
|
|
4788
4795
|
cursor = page.nextCursor;
|
|
4789
4796
|
if (cursor && items.length < limit)
|
|
@@ -4792,7 +4799,7 @@ async function requestPages(client, path, options) {
|
|
|
4792
4799
|
} finally {
|
|
4793
4800
|
progress.finish();
|
|
4794
4801
|
}
|
|
4795
|
-
return
|
|
4802
|
+
return items.slice(0, limit);
|
|
4796
4803
|
}
|
|
4797
4804
|
function resolvePath(template, params = {}) {
|
|
4798
4805
|
return template.replace(/\[([^\]]+)\]/g, (_match, key) => {
|
|
@@ -16075,7 +16082,30 @@ function buildRequest(operation, positional, flags, workspaceId) {
|
|
|
16075
16082
|
}
|
|
16076
16083
|
|
|
16077
16084
|
// src/runtime/options.ts
|
|
16078
|
-
var
|
|
16085
|
+
var DEFAULT_PAGE_SIZE = 100;
|
|
16086
|
+
var COMPLETE_LIST_OPERATIONS = new Set([
|
|
16087
|
+
"listBlocks",
|
|
16088
|
+
"listChatDeployments",
|
|
16089
|
+
"listCredentials",
|
|
16090
|
+
"listCustomTools",
|
|
16091
|
+
"listFiles",
|
|
16092
|
+
"listKnowledgeBases",
|
|
16093
|
+
"listKnowledgeConnectors",
|
|
16094
|
+
"listMcpServers",
|
|
16095
|
+
"listSandboxes",
|
|
16096
|
+
"listSecrets",
|
|
16097
|
+
"listSkillEditors",
|
|
16098
|
+
"listSkills",
|
|
16099
|
+
"listTables",
|
|
16100
|
+
"listTools",
|
|
16101
|
+
"listWorkflowMcpServers",
|
|
16102
|
+
"listWorkflows",
|
|
16103
|
+
"listWorkspaceMembers",
|
|
16104
|
+
"listWorkspaces"
|
|
16105
|
+
]);
|
|
16106
|
+
function defaultListLimit(operation) {
|
|
16107
|
+
return COMPLETE_LIST_OPERATIONS.has(operation) ? 0 : 100;
|
|
16108
|
+
}
|
|
16079
16109
|
function describeField(flag, descriptor, name, field) {
|
|
16080
16110
|
return flag.describe ?? descriptor.describe ?? `Set ${name.replaceAll("-", " ") || field}`;
|
|
16081
16111
|
}
|
|
@@ -16088,15 +16118,21 @@ function withoutWireVocabulary(documented) {
|
|
|
16088
16118
|
}
|
|
16089
16119
|
var NON_PAGINATED_LIMIT_HINT = " (caps a --filter match only; omit it to act on every match, and note 0 is not accepted)";
|
|
16090
16120
|
function addFieldOption(command, operation, field, descriptor, slot, paginates, capsAFilter) {
|
|
16091
|
-
if (field === PROFILE_INJECTED_FIELD
|
|
16121
|
+
if (field === PROFILE_INJECTED_FIELD)
|
|
16092
16122
|
return;
|
|
16123
|
+
if (field === "cursor") {
|
|
16124
|
+
if (paginates && defaultListLimit(operation) > 0) {
|
|
16125
|
+
command.option("--cursor <value>", "Continue from nextCursor returned by a previous result");
|
|
16126
|
+
}
|
|
16127
|
+
return;
|
|
16128
|
+
}
|
|
16093
16129
|
const flag = flagSpecFor(operation, field);
|
|
16094
16130
|
if (flag.omit)
|
|
16095
16131
|
return;
|
|
16096
16132
|
const name = flagNameFor(operation, field);
|
|
16097
16133
|
const short = flag.short ? `-${flag.short}, ` : "";
|
|
16098
16134
|
if (paginates && field === "limit" && (descriptor.kind === "number" || descriptor.kind === "integer")) {
|
|
16099
|
-
command.option("--limit <n>", "Maximum items to return (0 for everything)", String(
|
|
16135
|
+
command.option("--limit <n>", "Maximum items to return (0 for everything)", String(defaultListLimit(operation)));
|
|
16100
16136
|
return;
|
|
16101
16137
|
}
|
|
16102
16138
|
const documented = `${describeField(flag, descriptor, name, field)}${capsAFilter && field === "limit" && (descriptor.kind === "number" || descriptor.kind === "integer") ? NON_PAGINATED_LIMIT_HINT : ""}`;
|
|
@@ -16456,11 +16492,10 @@ function unwrapResource(data) {
|
|
|
16456
16492
|
const [, value] = entries[0];
|
|
16457
16493
|
return value && typeof value === "object" && !Array.isArray(value) ? value : data;
|
|
16458
16494
|
}
|
|
16459
|
-
function renderPage(format,
|
|
16495
|
+
function renderPage(format, page, spec, envelope) {
|
|
16460
16496
|
writePageNote(spec, envelope);
|
|
16461
16497
|
writeEnvelopeTruncation(envelope);
|
|
16462
|
-
|
|
16463
|
-
printList(format, rows, spec.columns ? columnsFrom(spec.columns) : inferColumns(rows, spec.expand));
|
|
16498
|
+
printList(format, page.data, spec.columns ? columnsFrom(spec.columns) : inferColumns(page.data, spec.expand), page);
|
|
16464
16499
|
}
|
|
16465
16500
|
function writePageNote(spec, envelope) {
|
|
16466
16501
|
if (!spec.pageNote)
|
|
@@ -16505,12 +16540,6 @@ function writeEnvelopeTruncation(envelope) {
|
|
|
16505
16540
|
`));
|
|
16506
16541
|
}
|
|
16507
16542
|
}
|
|
16508
|
-
function writeCursorTruncation(count, truncated) {
|
|
16509
|
-
if (!truncated)
|
|
16510
|
-
return;
|
|
16511
|
-
process.stderr.write(source_default.dim(`showing the first ${count}; more results exist — re-run with --limit 0 for all
|
|
16512
|
-
`));
|
|
16513
|
-
}
|
|
16514
16543
|
function renderResult(operation, format, raw, spec, options = {}, envelope) {
|
|
16515
16544
|
writeEnvelopeTruncation(envelope);
|
|
16516
16545
|
if (spec.document) {
|
|
@@ -16647,8 +16676,8 @@ function bulkFailureMessage(operation, payload, body) {
|
|
|
16647
16676
|
var EXCLUSIVE_CAP_FIELDS = {
|
|
16648
16677
|
deleteTableRows: { cap: "limit", ids: "rowIds" }
|
|
16649
16678
|
};
|
|
16650
|
-
function readPagedLimit(raw) {
|
|
16651
|
-
const text = String(raw ??
|
|
16679
|
+
function readPagedLimit(raw, operation) {
|
|
16680
|
+
const text = String(raw ?? defaultListLimit(operation)).trim();
|
|
16652
16681
|
const value = text === "" ? Number.NaN : Number(text);
|
|
16653
16682
|
if (!Number.isInteger(value) || value < 0) {
|
|
16654
16683
|
throw new SimApiError("--limit must be a whole number of 0 or more (0 for everything)", 0);
|
|
@@ -16723,24 +16752,33 @@ async function executeOperation(operation, commandSpec, operationSpec, invocatio
|
|
|
16723
16752
|
const omitsWorkspace = commandSpec.allWorkspaces && requestFlags.allWorkspaces === true;
|
|
16724
16753
|
const needsWorkspace = (hasWorkspaceField || commandSpec.profileWorkspacePath === true) && !omitsWorkspace;
|
|
16725
16754
|
const paging = cursorSlot(operationSpec);
|
|
16726
|
-
const pagedLimit = paging ? readPagedLimit(requestFlags.limit) : 0;
|
|
16755
|
+
const pagedLimit = paging ? readPagedLimit(requestFlags.limit, operation) : 0;
|
|
16727
16756
|
const request = buildRequest(operation, positional, requestFlags, needsWorkspace ? client.requireWorkspace() : profile.workspaceId);
|
|
16728
16757
|
if (paging) {
|
|
16758
|
+
const initialCursor = request[paging]?.cursor;
|
|
16759
|
+
if (initialCursor !== undefined && (typeof initialCursor !== "string" || initialCursor.trim() === "")) {
|
|
16760
|
+
throw new SimApiError("--cursor must be a non-empty string", 0);
|
|
16761
|
+
}
|
|
16729
16762
|
const limit = pagedLimit === 0 ? Number.POSITIVE_INFINITY : pagedLimit;
|
|
16730
|
-
const pageSize = Math.min(Number.isFinite(limit) ? limit : DEFAULT_LIMIT, DEFAULT_LIMIT);
|
|
16731
|
-
const pageLimit = "limit" in (operationSpec[paging] ?? {}) ? { limit: pageSize } : {};
|
|
16732
16763
|
const rows = [];
|
|
16764
|
+
const seenCursors = new Set(initialCursor ? [initialCursor] : []);
|
|
16733
16765
|
const progress = pageProgress();
|
|
16734
|
-
let cursor = null;
|
|
16766
|
+
let cursor = initialCursor ?? null;
|
|
16735
16767
|
let envelope;
|
|
16736
16768
|
try {
|
|
16737
16769
|
do {
|
|
16770
|
+
const pageSize = Math.min(DEFAULT_PAGE_SIZE, limit - rows.length);
|
|
16771
|
+
const pageLimit = "limit" in (operationSpec[paging] ?? {}) ? { limit: pageSize } : {};
|
|
16738
16772
|
const page = await client.request(request.path, {
|
|
16739
16773
|
method: operationSpec.method,
|
|
16740
16774
|
headers: request.headers,
|
|
16741
16775
|
query: paging === "query" ? { ...request.query, ...pageLimit, cursor } : request.query,
|
|
16742
16776
|
body: paging === "body" ? { ...request.body ?? {}, ...pageLimit, ...cursor ? { cursor } : {} } : request.body
|
|
16743
16777
|
});
|
|
16778
|
+
if (page.data.length > pageSize) {
|
|
16779
|
+
throw new SimApiError(`The API returned ${page.data.length} items for a page limit of ${pageSize}; nextCursor would skip unreturned items.`, 0);
|
|
16780
|
+
}
|
|
16781
|
+
assertCursorAdvances(page.nextCursor, seenCursors);
|
|
16744
16782
|
envelope = foldPageEnvelope(envelope, page);
|
|
16745
16783
|
rows.push(...page.data);
|
|
16746
16784
|
cursor = page.nextCursor;
|
|
@@ -16750,7 +16788,7 @@ async function executeOperation(operation, commandSpec, operationSpec, invocatio
|
|
|
16750
16788
|
} finally {
|
|
16751
16789
|
progress.finish();
|
|
16752
16790
|
}
|
|
16753
|
-
renderPage(profile.output,
|
|
16791
|
+
renderPage(profile.output, { data: rows, nextCursor: cursor }, commandSpec, envelope);
|
|
16754
16792
|
return;
|
|
16755
16793
|
}
|
|
16756
16794
|
const result = await client.request(request.path, {
|
|
@@ -18102,11 +18140,11 @@ async function listResources(client, config, workspaceId, folderPath, search, li
|
|
|
18102
18140
|
const paginated = "cursor" in V2_OPERATIONS[config.resources].query;
|
|
18103
18141
|
if (!paginated) {
|
|
18104
18142
|
const page = await client.request(path, { query });
|
|
18105
|
-
return
|
|
18143
|
+
return page.data.slice(0, limit);
|
|
18106
18144
|
}
|
|
18107
|
-
return
|
|
18145
|
+
return requestAllPages(client, path, {
|
|
18108
18146
|
query,
|
|
18109
|
-
pageSize:
|
|
18147
|
+
pageSize: DEFAULT_PAGE_SIZE,
|
|
18110
18148
|
limit
|
|
18111
18149
|
});
|
|
18112
18150
|
}
|
|
@@ -18136,7 +18174,7 @@ function entriesFor(config, folders, resources) {
|
|
|
18136
18174
|
].sort((left, right) => left.name.localeCompare(right.name) || left.kind.localeCompare(right.kind));
|
|
18137
18175
|
}
|
|
18138
18176
|
function attachResourceDirectoryCommands(group, config) {
|
|
18139
|
-
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(
|
|
18177
|
+
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) => {
|
|
18140
18178
|
const rawLimit = Number(options.limit);
|
|
18141
18179
|
if (!Number.isSafeInteger(rawLimit) || rawLimit < 0) {
|
|
18142
18180
|
throw new SimApiError("--limit must be a whole number of 0 or more (0 for everything)", 0);
|
|
@@ -18149,9 +18187,8 @@ function attachResourceDirectoryCommands(group, config) {
|
|
|
18149
18187
|
listFolders(client, config.folders, workspaceId, folderPath, options.search),
|
|
18150
18188
|
listResources(client, config, workspaceId, folderPath, options.search, limit)
|
|
18151
18189
|
]);
|
|
18152
|
-
const entries = entriesFor(config, folders, resources
|
|
18190
|
+
const entries = entriesFor(config, folders, resources);
|
|
18153
18191
|
const shown = entries.slice(0, limit);
|
|
18154
|
-
writeCursorTruncation(shown.length, resources.truncated || entries.length > limit);
|
|
18155
18192
|
printList(profile.output, shown, COLUMNS2);
|
|
18156
18193
|
});
|
|
18157
18194
|
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) => {
|