sim 2.1.3-preview.50.1 → 2.1.3-preview.51.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/dist/index.js +89 -24
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2866,6 +2866,10 @@ function traceRequest(method, url, status, startedAt) {
|
|
|
2866
2866
|
process.stderr.write(`${source_default.dim(`[sim] ${method} ${url} → ${status} ${Math.round(performance.now() - startedAt)}ms`)}
|
|
2867
2867
|
`);
|
|
2868
2868
|
}
|
|
2869
|
+
function withoutLeadingLabel(message, label) {
|
|
2870
|
+
const prefix = `${label}: `;
|
|
2871
|
+
return message.startsWith(prefix) ? message.slice(prefix.length) : message;
|
|
2872
|
+
}
|
|
2869
2873
|
function formatApiErrorDetails(details) {
|
|
2870
2874
|
const issues = [];
|
|
2871
2875
|
const seen = new Set;
|
|
@@ -2903,7 +2907,10 @@ function formatApiErrorDetails(details) {
|
|
|
2903
2907
|
const visible = kept.slice(0, 8);
|
|
2904
2908
|
const lines = [
|
|
2905
2909
|
" details:",
|
|
2906
|
-
...visible.map((issue) =>
|
|
2910
|
+
...visible.map((issue) => {
|
|
2911
|
+
const label = issue.path.length > 0 ? issue.path.join(".") : "request";
|
|
2912
|
+
return ` ${label}: ${withoutLeadingLabel(issue.message, label)}`;
|
|
2913
|
+
})
|
|
2907
2914
|
];
|
|
2908
2915
|
if (kept.length > visible.length)
|
|
2909
2916
|
lines.push(` … ${kept.length - visible.length} more issues`);
|
|
@@ -3041,10 +3048,13 @@ function pageProgress() {
|
|
|
3041
3048
|
};
|
|
3042
3049
|
}
|
|
3043
3050
|
async function requestAllPages(client, path, options) {
|
|
3051
|
+
return (await requestPages(client, path, options)).items;
|
|
3052
|
+
}
|
|
3053
|
+
async function requestPages(client, path, options) {
|
|
3044
3054
|
const { query, pageSize, limit: requestedLimit, ...requestOptions } = options;
|
|
3045
3055
|
const limit = requestedLimit ?? Number.POSITIVE_INFINITY;
|
|
3046
3056
|
if (limit <= 0)
|
|
3047
|
-
return [];
|
|
3057
|
+
return { items: [], truncated: false };
|
|
3048
3058
|
const items = [];
|
|
3049
3059
|
const progress = pageProgress();
|
|
3050
3060
|
let cursor = null;
|
|
@@ -3066,7 +3076,7 @@ async function requestAllPages(client, path, options) {
|
|
|
3066
3076
|
} finally {
|
|
3067
3077
|
progress.finish();
|
|
3068
3078
|
}
|
|
3069
|
-
return items.slice(0, limit);
|
|
3079
|
+
return { items: items.slice(0, limit), truncated: cursor !== null || items.length > limit };
|
|
3070
3080
|
}
|
|
3071
3081
|
function resolvePath(template, params = {}) {
|
|
3072
3082
|
return template.replace(/\[([^\]]+)\]/g, (_match, key) => {
|
|
@@ -11909,7 +11919,7 @@ function configureCommand() {
|
|
|
11909
11919
|
const value = globals[option];
|
|
11910
11920
|
if (value === undefined)
|
|
11911
11921
|
continue;
|
|
11912
|
-
throw new SimApiError(`${flag} applies to a single command and is not stored. To save it, run: sim configure ${setFlag} ${value}`, 0);
|
|
11922
|
+
throw new SimApiError(`${flag} applies to a single command and is not stored. To save it, run: sim configure ${setFlag} ${redact(value)}`, 0);
|
|
11913
11923
|
}
|
|
11914
11924
|
const profile = profileFrom(command, { allowUnknownProfile: true });
|
|
11915
11925
|
const authProfile = resolveAuthenticationProfileName(profile.name);
|
|
@@ -11970,7 +11980,7 @@ var TABLE_SORT_HELP = 'Ordered sort keys: [{"field":"createdAt","direction":"des
|
|
|
11970
11980
|
var KNOWLEDGE_TAG_DEFINITIONS_HELP = 'Tag definitions: [{"tagSlot":"tag1","displayName":"category","fieldType":"text"}]';
|
|
11971
11981
|
var CUSTOM_TOOL_SCHEMA_HELP = 'OpenAI function schema: {"type":"function","function":{"name":"...","parameters":{"type":"object","properties":{}}}}';
|
|
11972
11982
|
var DISPATCH_ROW_LIMIT_HELP = "Stop after this many eligible rows have run (1-1,000,000). Omit for an unbounded run";
|
|
11973
|
-
var WORKFLOW_OPERATIONS_HELP = 'Edits to apply, in a single batch, keyed by operation_type: [{"operation_type":"add","block_id":"my-fn","params":{"type":"function","name":"My Fn","inputs":{"code":"return {ok:true}"}}},{"operation_type":"edit","block_id":"<uuid>","params":{"name":"Renamed","connections":{"success":"my-fn"}}},{"operation_type":"delete","block_id":"<uuid>"}]. Also
|
|
11983
|
+
var WORKFLOW_OPERATIONS_HELP = 'Edits to apply, in a single batch, keyed by operation_type: [{"operation_type":"add","block_id":"my-fn","params":{"type":"function","name":"My Fn","inputs":{"code":"return {ok:true}"}}},{"operation_type":"edit","block_id":"<uuid>","params":{"name":"Renamed","connections":{"success":"my-fn"}}},{"operation_type":"delete","block_id":"<uuid>"}]. Also extract_from_subflow, whose params carry {"subflowId":"<loop-id>"}, and insert_into_subflow, which creates a block and so takes an add’s params plus that subflowId';
|
|
11974
11984
|
var WORKFLOW_SET_BLOCK_ENABLED_HELP = 'Blocks to enable or disable, applied after --operations: [{"block_id":"<uuid>","enabled":false}]. Disabling a loop or parallel cascades to its unlocked descendants; enabling a block whose container is disabled is declined';
|
|
11975
11985
|
var WORKFLOW_VARIABLE_OPERATIONS_HELP = 'Variable changes to apply in order, keyed by operation: [{"operation":"add","name":"my_var","type":"string","value":"hello"},{"operation":"edit","name":"my_var","value":"updated"},{"operation":"delete","name":"my_var"}]';
|
|
11976
11986
|
var MCP_PARAMETER_DESCRIPTIONS_HELP = 'Per-field description overrides applied to the schema generated from the deployed workflow inputs, as [{"name":"email","description":"Customer email address"}]. A name matching no input field is ignored';
|
|
@@ -12046,7 +12056,7 @@ var CLI_CONTRACT = {
|
|
|
12046
12056
|
listBillingLogs: {
|
|
12047
12057
|
command: "billing logs",
|
|
12048
12058
|
allWorkspaces: true,
|
|
12049
|
-
describe: "List credit usage events (a personal API key reports only your own events; a workspace API key reports every member's)",
|
|
12059
|
+
describe: "List credit usage events (a personal API key reports only your own events; a workspace API key reports every member's in aggregate, unattributed)",
|
|
12050
12060
|
flags: {
|
|
12051
12061
|
source: { describe: "Filter by usage source; sim-chat combines Copilot and workspace chat" },
|
|
12052
12062
|
period: { describe: "Billing period" },
|
|
@@ -12239,7 +12249,7 @@ var CLI_CONTRACT = {
|
|
|
12239
12249
|
},
|
|
12240
12250
|
getLogStats: {
|
|
12241
12251
|
command: "logs stats",
|
|
12242
|
-
describe: "Summarize run counts, failures
|
|
12252
|
+
describe: "Summarize run counts, failures and latency over a window",
|
|
12243
12253
|
flags: LOG_LIST_FILTER_FLAGS,
|
|
12244
12254
|
fields: [
|
|
12245
12255
|
{ header: "runs", path: "totalRuns" },
|
|
@@ -12567,7 +12577,7 @@ var CLI_CONTRACT = {
|
|
|
12567
12577
|
listCustomTools: {
|
|
12568
12578
|
columns: [
|
|
12569
12579
|
{ header: "id" },
|
|
12570
|
-
{ header: "
|
|
12580
|
+
{ header: "title", path: "title" },
|
|
12571
12581
|
{ header: "description", path: "schema.function.description" },
|
|
12572
12582
|
{ header: "updated", path: "updatedAt", format: "timestamp" }
|
|
12573
12583
|
]
|
|
@@ -12799,6 +12809,7 @@ var CLI_CONTRACT = {
|
|
|
12799
12809
|
]
|
|
12800
12810
|
},
|
|
12801
12811
|
listFileFolders: {
|
|
12812
|
+
describe: "List folders",
|
|
12802
12813
|
aliases: ["ls"],
|
|
12803
12814
|
flags: {
|
|
12804
12815
|
parentPath: { ...FOLDER_PATH_INPUT, name: "parent", describe: "Direct parent folder path" }
|
|
@@ -12806,6 +12817,7 @@ var CLI_CONTRACT = {
|
|
|
12806
12817
|
columns: FOLDER_LIST_COLUMNS
|
|
12807
12818
|
},
|
|
12808
12819
|
listKnowledgeFolders: {
|
|
12820
|
+
describe: "List knowledge folders",
|
|
12809
12821
|
aliases: ["ls"],
|
|
12810
12822
|
flags: {
|
|
12811
12823
|
parentPath: { ...FOLDER_PATH_INPUT, name: "parent", describe: "Direct parent folder path" }
|
|
@@ -12813,6 +12825,7 @@ var CLI_CONTRACT = {
|
|
|
12813
12825
|
columns: FOLDER_LIST_COLUMNS
|
|
12814
12826
|
},
|
|
12815
12827
|
listTableFolders: {
|
|
12828
|
+
describe: "List table folders",
|
|
12816
12829
|
aliases: ["ls"],
|
|
12817
12830
|
flags: {
|
|
12818
12831
|
parentPath: { ...FOLDER_PATH_INPUT, name: "parent", describe: "Direct parent folder path" }
|
|
@@ -12820,6 +12833,7 @@ var CLI_CONTRACT = {
|
|
|
12820
12833
|
columns: FOLDER_LIST_COLUMNS
|
|
12821
12834
|
},
|
|
12822
12835
|
listWorkflowFolders: {
|
|
12836
|
+
describe: "List workflow folders",
|
|
12823
12837
|
aliases: ["ls"],
|
|
12824
12838
|
flags: {
|
|
12825
12839
|
parentPath: { ...FOLDER_PATH_INPUT, name: "parent", describe: "Direct parent folder path" }
|
|
@@ -13298,6 +13312,7 @@ function encodeFolderPath(value) {
|
|
|
13298
13312
|
}
|
|
13299
13313
|
}).join("/");
|
|
13300
13314
|
}
|
|
13315
|
+
var FRACTIONAL_DIGITS = /\.\d*[1-9]/;
|
|
13301
13316
|
function pathHint(raw) {
|
|
13302
13317
|
if (raw.startsWith("@") || /^\s*[[{"\-\d]|^\s*(true|false|null)/.test(raw))
|
|
13303
13318
|
return "";
|
|
@@ -13326,6 +13341,12 @@ function coerce(raw, field, flag, flagName) {
|
|
|
13326
13341
|
const value = Number(raw);
|
|
13327
13342
|
if (Number.isNaN(value))
|
|
13328
13343
|
throw new SimApiError(`--${flagName} must be a number`, 0);
|
|
13344
|
+
if (field.kind === "integer" && (!Number.isInteger(value) || FRACTIONAL_DIGITS.test(String(raw)))) {
|
|
13345
|
+
throw new SimApiError(`--${flagName} must be a whole number`, 0);
|
|
13346
|
+
}
|
|
13347
|
+
if (field.kind === "integer" && !Number.isSafeInteger(value)) {
|
|
13348
|
+
throw new SimApiError(`--${flagName} is outside the whole-number range the API accepts (±${Number.MAX_SAFE_INTEGER})`, 0);
|
|
13349
|
+
}
|
|
13329
13350
|
return value;
|
|
13330
13351
|
}
|
|
13331
13352
|
if (field.kind === "boolean" || flag.boolean)
|
|
@@ -13385,6 +13406,9 @@ function buildRequest(operation, positional, flags, workspaceId) {
|
|
|
13385
13406
|
throw new SimApiError(`--${flagName} cannot be empty`, 0);
|
|
13386
13407
|
}
|
|
13387
13408
|
const value = coerce(raw ?? undefined, descriptor, flag, flagName);
|
|
13409
|
+
if (field === "limit" && !paginatedLimit && NUMERIC_KINDS.has(descriptor.kind) && typeof value === "number" && value < 1) {
|
|
13410
|
+
throw new SimApiError(`--${flagName} must be 1 or more`, 0);
|
|
13411
|
+
}
|
|
13388
13412
|
if (value === undefined) {
|
|
13389
13413
|
if (descriptor.required) {
|
|
13390
13414
|
throw new SimApiError(field === PROFILE_INJECTED_FIELD ? NO_WORKSPACE_FALLBACK : `--${flagName} is required`, 0);
|
|
@@ -13533,7 +13557,7 @@ function addOperationOptions(command, operation, commandSpec, operationSpec) {
|
|
|
13533
13557
|
}
|
|
13534
13558
|
if (commandSpec.confirm) {
|
|
13535
13559
|
const exemptedByDryRun = operationSpec.query?.dryRun !== undefined || operationSpec.body?.dryRun !== undefined;
|
|
13536
|
-
command.option("-y, --yes", exemptedByDryRun ? "Confirm this
|
|
13560
|
+
command.option("-y, --yes", exemptedByDryRun ? "Confirm this operation (required unless --dry-run)" : "Confirm this operation (required)");
|
|
13537
13561
|
}
|
|
13538
13562
|
}
|
|
13539
13563
|
|
|
@@ -13993,6 +14017,14 @@ function bulkFailureMessage(operation, payload, body) {
|
|
|
13993
14017
|
var EXCLUSIVE_CAP_FIELDS = {
|
|
13994
14018
|
deleteTableRows: { cap: "limit", ids: "rowIds" }
|
|
13995
14019
|
};
|
|
14020
|
+
function readPagedLimit(raw) {
|
|
14021
|
+
const text2 = String(raw ?? DEFAULT_LIMIT).trim();
|
|
14022
|
+
const value = text2 === "" ? Number.NaN : Number(text2);
|
|
14023
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
14024
|
+
throw new SimApiError("--limit must be a whole number of 0 or more (0 for everything)", 0);
|
|
14025
|
+
}
|
|
14026
|
+
return value;
|
|
14027
|
+
}
|
|
13996
14028
|
function assertCapIsUsable(operation, flags) {
|
|
13997
14029
|
const exclusive = EXCLUSIVE_CAP_FIELDS[operation];
|
|
13998
14030
|
if (!exclusive)
|
|
@@ -14003,6 +14035,19 @@ function assertCapIsUsable(operation, flags) {
|
|
|
14003
14035
|
return;
|
|
14004
14036
|
throw new SimApiError(`--${cap} caps a --filter match and does nothing to an explicit --${ids} list; pass one, not both`, 0);
|
|
14005
14037
|
}
|
|
14038
|
+
var REQUIRED_SELECTORS = {
|
|
14039
|
+
deleteTableRows: { fields: ["filter", "rowIds"], noun: "rows to delete" }
|
|
14040
|
+
};
|
|
14041
|
+
function assertSelectorIsUsable(operation, flags) {
|
|
14042
|
+
const selector = REQUIRED_SELECTORS[operation];
|
|
14043
|
+
if (!selector)
|
|
14044
|
+
return;
|
|
14045
|
+
const [first, second] = selector.fields.map((field) => flagNameFor(operation, field));
|
|
14046
|
+
const given = [first, second].filter((name) => flags[camel(name)] !== undefined);
|
|
14047
|
+
if (given.length === 1)
|
|
14048
|
+
return;
|
|
14049
|
+
throw new SimApiError(given.length === 0 ? `--${first} or --${second} is required to choose the ${selector.noun}` : `--${first} and --${second} choose the ${selector.noun} two different ways; pass one, not both`, 0);
|
|
14050
|
+
}
|
|
14006
14051
|
function foldRenamedFlags(operation, commandSpec, flags) {
|
|
14007
14052
|
for (const [field, flag] of Object.entries(commandSpec.flags ?? {})) {
|
|
14008
14053
|
if (!flag.renamedFrom?.length)
|
|
@@ -14036,6 +14081,7 @@ async function executeOperation(operation, commandSpec, operationSpec, invocatio
|
|
|
14036
14081
|
}
|
|
14037
14082
|
foldRenamedFlags(operation, commandSpec, requestFlags);
|
|
14038
14083
|
assertCapIsUsable(operation, requestFlags);
|
|
14084
|
+
assertSelectorIsUsable(operation, requestFlags);
|
|
14039
14085
|
if (commandSpec.confirm && !requestFlags.yes && requestFlags.dryRun !== true) {
|
|
14040
14086
|
throw new SimApiError(`${commandSpec.confirm} Re-run with --yes to confirm.`, 0);
|
|
14041
14087
|
}
|
|
@@ -14046,15 +14092,11 @@ async function executeOperation(operation, commandSpec, operationSpec, invocatio
|
|
|
14046
14092
|
const hasWorkspaceField = Boolean(operationSpec.query && PROFILE_INJECTED_FIELD in operationSpec.query || operationSpec.body && PROFILE_INJECTED_FIELD in operationSpec.body);
|
|
14047
14093
|
const omitsWorkspace = commandSpec.allWorkspaces && requestFlags.allWorkspaces === true;
|
|
14048
14094
|
const needsWorkspace = (hasWorkspaceField || commandSpec.profileWorkspacePath === true) && !omitsWorkspace;
|
|
14049
|
-
const request = buildRequest(operation, positional, requestFlags, needsWorkspace ? client.requireWorkspace() : profile.workspaceId);
|
|
14050
14095
|
const paging = cursorSlot(operationSpec);
|
|
14096
|
+
const pagedLimit = paging ? readPagedLimit(requestFlags.limit) : 0;
|
|
14097
|
+
const request = buildRequest(operation, positional, requestFlags, needsWorkspace ? client.requireWorkspace() : profile.workspaceId);
|
|
14051
14098
|
if (paging) {
|
|
14052
|
-
const
|
|
14053
|
-
const rawLimit = limitText === "" ? Number.NaN : Number(limitText);
|
|
14054
|
-
if (!Number.isInteger(rawLimit) || rawLimit < 0) {
|
|
14055
|
-
throw new SimApiError("--limit must be a whole number of 0 or more (0 for everything)", 0);
|
|
14056
|
-
}
|
|
14057
|
-
const limit = rawLimit === 0 ? Number.POSITIVE_INFINITY : rawLimit;
|
|
14099
|
+
const limit = pagedLimit === 0 ? Number.POSITIVE_INFINITY : pagedLimit;
|
|
14058
14100
|
const pageSize = Math.min(Number.isFinite(limit) ? limit : DEFAULT_LIMIT, DEFAULT_LIMIT);
|
|
14059
14101
|
const pageLimit = "limit" in (operationSpec[paging] ?? {}) ? { limit: pageSize } : {};
|
|
14060
14102
|
const rows = [];
|
|
@@ -14139,6 +14181,14 @@ function retypeMessage(message, spellings) {
|
|
|
14139
14181
|
continue;
|
|
14140
14182
|
retyped = retyped.replaceAll(new RegExp(`\\b${field}\\b`, "g"), spelling);
|
|
14141
14183
|
}
|
|
14184
|
+
if (retyped === message)
|
|
14185
|
+
return message;
|
|
14186
|
+
for (const field of spellings.keys()) {
|
|
14187
|
+
if (WIRE_IDENTIFIER.test(field))
|
|
14188
|
+
continue;
|
|
14189
|
+
if (new RegExp(`\\b${field}\\b`).test(message))
|
|
14190
|
+
return message;
|
|
14191
|
+
}
|
|
14142
14192
|
return retyped;
|
|
14143
14193
|
}
|
|
14144
14194
|
function retypeDetails(details, spellings) {
|
|
@@ -14662,6 +14712,12 @@ Examples:
|
|
|
14662
14712
|
$ sim chat -c 3f2a… "Which of those run on a schedule?"
|
|
14663
14713
|
$ sim --output json chat "Summarize yesterday's failed runs" | jq -r '.content'
|
|
14664
14714
|
`).action(async (message, options, command) => {
|
|
14715
|
+
if (message.trim() === "") {
|
|
14716
|
+
throw new SimApiError("<message> cannot be empty", 0);
|
|
14717
|
+
}
|
|
14718
|
+
if (options.conversation !== undefined && options.conversation.trim() === "") {
|
|
14719
|
+
throw new SimApiError("-c/--conversation cannot be empty — pass the conversation id printed on stderr after each turn", 0);
|
|
14720
|
+
}
|
|
14665
14721
|
const { client, profile } = clientFrom(command);
|
|
14666
14722
|
const workspaceId = client.requireWorkspace();
|
|
14667
14723
|
const response = await client.requestRaw(V2_OPERATIONS.chat.path, {
|
|
@@ -15070,8 +15126,15 @@ function uploadMetadata(options) {
|
|
|
15070
15126
|
}
|
|
15071
15127
|
return metadata;
|
|
15072
15128
|
}
|
|
15129
|
+
var UPLOAD_RECIPES = [
|
|
15130
|
+
"default",
|
|
15131
|
+
"plain",
|
|
15132
|
+
"markdown",
|
|
15133
|
+
"code"
|
|
15134
|
+
];
|
|
15135
|
+
var LANGUAGE_TAG_HELP = "Document language tag: hyphen-separated letter and digit subtags, for example en or en-US";
|
|
15073
15136
|
function attachKnowledgeDocumentUpload(documents) {
|
|
15074
|
-
documents.command("upload").argument("<knowledgeBaseId>", "Knowledge base to upload into").argument("<path>", "Local file to upload").allowExcessArguments(false).description("Upload a document to a knowledge base").option("--name <name>", "Store it under a different name").option("--tag <value...>", "Document tags, in tag1 through tag7 order").
|
|
15137
|
+
documents.command("upload").argument("<knowledgeBaseId>", "Knowledge base to upload into").argument("<path>", "Local file to upload").allowExcessArguments(false).description("Upload a document to a knowledge base").option("--name <name>", "Store it under a different name").option("--tag <value...>", "Document tags, in tag1 through tag7 order").addOption(new Option("--recipe <name>", "Document processing recipe").choices(UPLOAD_RECIPES)).option("--lang <code>", LANGUAGE_TAG_HELP).action(async (knowledgeBaseId, path, options, command) => {
|
|
15075
15138
|
const { client, profile } = clientFrom(command);
|
|
15076
15139
|
const workspaceId = client.requireWorkspace();
|
|
15077
15140
|
const { name, size } = await localFile(path, options.name);
|
|
@@ -15290,7 +15353,7 @@ function isTransient(error) {
|
|
|
15290
15353
|
function nonNegativeInteger(raw, flag) {
|
|
15291
15354
|
const value = Number(raw);
|
|
15292
15355
|
if (!Number.isSafeInteger(value) || value < 0) {
|
|
15293
|
-
throw new SimApiError(`${flag} must be a
|
|
15356
|
+
throw new SimApiError(`${flag} must be a whole number of 0 or more`, 0);
|
|
15294
15357
|
}
|
|
15295
15358
|
return value;
|
|
15296
15359
|
}
|
|
@@ -15317,7 +15380,7 @@ follow.
|
|
|
15317
15380
|
|
|
15318
15381
|
Examples:
|
|
15319
15382
|
$ sim logs follow --level error
|
|
15320
|
-
$ sim logs follow --workflow
|
|
15383
|
+
$ sim logs follow --workflow 00000000-0000-4000-8000-000000000000 -n 0
|
|
15321
15384
|
$ sim --output json logs follow | jq -r '.runId'
|
|
15322
15385
|
`).action(async (options, command) => {
|
|
15323
15386
|
const lines = nonNegativeInteger(options.lines, "--lines");
|
|
@@ -15399,9 +15462,9 @@ async function listResources(client, config, workspaceId, folderPath, search, li
|
|
|
15399
15462
|
const paginated = "cursor" in V2_OPERATIONS[config.resources].query;
|
|
15400
15463
|
if (!paginated) {
|
|
15401
15464
|
const page = await client.request(path, { query });
|
|
15402
|
-
return page.data.slice(0, limit);
|
|
15465
|
+
return { items: page.data.slice(0, limit), truncated: page.data.length > limit };
|
|
15403
15466
|
}
|
|
15404
|
-
return
|
|
15467
|
+
return requestPages(client, path, {
|
|
15405
15468
|
query,
|
|
15406
15469
|
pageSize: DEFAULT_LIMIT,
|
|
15407
15470
|
limit
|
|
@@ -15436,7 +15499,7 @@ function attachResourceDirectoryCommands(group, config) {
|
|
|
15436
15499
|
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(String(DEFAULT_LIMIT))).action(async (path, options, command) => {
|
|
15437
15500
|
const rawLimit = Number(options.limit);
|
|
15438
15501
|
if (!Number.isSafeInteger(rawLimit) || rawLimit < 0) {
|
|
15439
|
-
throw new SimApiError("--limit must be a
|
|
15502
|
+
throw new SimApiError("--limit must be a whole number of 0 or more (0 for everything)", 0);
|
|
15440
15503
|
}
|
|
15441
15504
|
const limit = rawLimit === 0 ? Number.POSITIVE_INFINITY : rawLimit;
|
|
15442
15505
|
const folderPath = encodeFolderPath(path ?? "/");
|
|
@@ -15446,8 +15509,10 @@ function attachResourceDirectoryCommands(group, config) {
|
|
|
15446
15509
|
listFolders(client, config.folders, workspaceId, folderPath, options.search),
|
|
15447
15510
|
listResources(client, config, workspaceId, folderPath, options.search, limit)
|
|
15448
15511
|
]);
|
|
15449
|
-
const entries = entriesFor(config, folders, resources);
|
|
15450
|
-
|
|
15512
|
+
const entries = entriesFor(config, folders, resources.items);
|
|
15513
|
+
const shown = entries.slice(0, limit);
|
|
15514
|
+
writeCursorTruncation(shown.length, resources.truncated || entries.length > limit);
|
|
15515
|
+
printList(profile.output, shown, COLUMNS2);
|
|
15451
15516
|
});
|
|
15452
15517
|
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) => {
|
|
15453
15518
|
const { client, profile } = clientFrom(command);
|