sim 2.1.3-preview.50.1 → 2.1.3-preview.52.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.
Files changed (2) hide show
  1. package/dist/index.js +133 -35
  2. 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) => ` ${issue.path.length > 0 ? issue.path.join(".") : "request"}: ${issue.message}`)
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) => {
@@ -9198,7 +9208,7 @@ var V2_OPERATIONS = {
9198
9208
  },
9199
9209
  parentPath: {
9200
9210
  kind: "string",
9201
- describe: "Restrict results to direct children of this parent path."
9211
+ describe: "Restrict results to direct children of this parent path. A path that names no folder narrows the result to nothing, so the response is an empty page rather than an error."
9202
9212
  },
9203
9213
  search: {
9204
9214
  kind: "string",
@@ -9531,7 +9541,7 @@ var V2_OPERATIONS = {
9531
9541
  },
9532
9542
  parentPath: {
9533
9543
  kind: "string",
9534
- describe: "Restrict results to direct children of this parent path."
9544
+ describe: "Restrict results to direct children of this parent path. A path that names no folder narrows the result to nothing, so the response is an empty page rather than an error."
9535
9545
  },
9536
9546
  search: {
9537
9547
  kind: "string",
@@ -9884,7 +9894,7 @@ var V2_OPERATIONS = {
9884
9894
  },
9885
9895
  parentPath: {
9886
9896
  kind: "string",
9887
- describe: "Restrict results to direct children of this parent path."
9897
+ describe: "Restrict results to direct children of this parent path. A path that names no folder narrows the result to nothing, so the response is an empty page rather than an error."
9888
9898
  },
9889
9899
  search: {
9890
9900
  kind: "string",
@@ -10050,7 +10060,7 @@ var V2_OPERATIONS = {
10050
10060
  },
10051
10061
  parentPath: {
10052
10062
  kind: "string",
10053
- describe: "Restrict results to direct children of this parent path."
10063
+ describe: "Restrict results to direct children of this parent path. A path that names no folder narrows the result to nothing, so the response is an empty page rather than an error."
10054
10064
  },
10055
10065
  search: {
10056
10066
  kind: "string",
@@ -11902,14 +11912,22 @@ function requireValue(value, flag, key) {
11902
11912
  throw new SimApiError(`${flag} requires a value. To remove it, run: sim configure --unset ${key}`, 0);
11903
11913
  }
11904
11914
  }
11915
+ function quoteProfileArgument(name) {
11916
+ const redacted = redact(name);
11917
+ if (PROFILE_NAME_PATTERN.test(redacted))
11918
+ return redacted;
11919
+ return `'${redacted.replaceAll("'", "'\\''")}'`;
11920
+ }
11905
11921
  function configureCommand() {
11906
11922
  return new Command("configure").description("Set a profile's endpoint, default workspace, or output format").option("--set-endpoint <url>", "Sim deployment to talk to").option("--set-workspace <id>", "Default workspace for workspace-scoped commands").option("--set-output <format>", `Default output format (${OUTPUT_FORMATS.join(" | ")})`).option("--unset <key...>", "Remove settings (endpoint, workspace, output)").action((options, command) => {
11907
11923
  const globals = globalsOf(command);
11924
+ const selectedProfile = globals.profile || process.env.SIM_PROFILE;
11925
+ const profileArg = selectedProfile ? ` --profile ${quoteProfileArgument(selectedProfile)}` : "";
11908
11926
  for (const { option, flag, setFlag } of GLOBAL_FLAG_TWINS) {
11909
11927
  const value = globals[option];
11910
11928
  if (value === undefined)
11911
11929
  continue;
11912
- throw new SimApiError(`${flag} applies to a single command and is not stored. To save it, run: sim configure ${setFlag} ${value}`, 0);
11930
+ throw new SimApiError(`${flag} applies to a single command and is not stored. To save it, run: sim configure${profileArg} ${setFlag} ${redact(value)}`, 0);
11913
11931
  }
11914
11932
  const profile = profileFrom(command, { allowUnknownProfile: true });
11915
11933
  const authProfile = resolveAuthenticationProfileName(profile.name);
@@ -11970,7 +11988,7 @@ var TABLE_SORT_HELP = 'Ordered sort keys: [{"field":"createdAt","direction":"des
11970
11988
  var KNOWLEDGE_TAG_DEFINITIONS_HELP = 'Tag definitions: [{"tagSlot":"tag1","displayName":"category","fieldType":"text"}]';
11971
11989
  var CUSTOM_TOOL_SCHEMA_HELP = 'OpenAI function schema: {"type":"function","function":{"name":"...","parameters":{"type":"object","properties":{}}}}';
11972
11990
  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 insert_into_subflow and extract_from_subflow, whose params carry {"subflowId":"<loop-id>"}';
11991
+ 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
11992
  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
11993
  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
11994
  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 +12064,7 @@ var CLI_CONTRACT = {
12046
12064
  listBillingLogs: {
12047
12065
  command: "billing logs",
12048
12066
  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)",
12067
+ 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
12068
  flags: {
12051
12069
  source: { describe: "Filter by usage source; sim-chat combines Copilot and workspace chat" },
12052
12070
  period: { describe: "Billing period" },
@@ -12239,7 +12257,7 @@ var CLI_CONTRACT = {
12239
12257
  },
12240
12258
  getLogStats: {
12241
12259
  command: "logs stats",
12242
- describe: "Summarize run counts, failures, and cost over a window",
12260
+ describe: "Summarize run counts, failures and latency over a window",
12243
12261
  flags: LOG_LIST_FILTER_FLAGS,
12244
12262
  fields: [
12245
12263
  { header: "runs", path: "totalRuns" },
@@ -12316,6 +12334,9 @@ var CLI_CONTRACT = {
12316
12334
  rollbackWorkflow: {
12317
12335
  confirm: "This changes which deployed version runs in production for every API and chat consumer."
12318
12336
  },
12337
+ activateWorkflowVersion: {
12338
+ confirm: "This changes which deployed version runs in production for every API and chat consumer."
12339
+ },
12319
12340
  moveWorkflows: {
12320
12341
  command: "workflows move",
12321
12342
  flags: {
@@ -12567,7 +12588,7 @@ var CLI_CONTRACT = {
12567
12588
  listCustomTools: {
12568
12589
  columns: [
12569
12590
  { header: "id" },
12570
- { header: "name", path: "title" },
12591
+ { header: "title", path: "title" },
12571
12592
  { header: "description", path: "schema.function.description" },
12572
12593
  { header: "updated", path: "updatedAt", format: "timestamp" }
12573
12594
  ]
@@ -12799,6 +12820,7 @@ var CLI_CONTRACT = {
12799
12820
  ]
12800
12821
  },
12801
12822
  listFileFolders: {
12823
+ describe: "List folders",
12802
12824
  aliases: ["ls"],
12803
12825
  flags: {
12804
12826
  parentPath: { ...FOLDER_PATH_INPUT, name: "parent", describe: "Direct parent folder path" }
@@ -12806,6 +12828,7 @@ var CLI_CONTRACT = {
12806
12828
  columns: FOLDER_LIST_COLUMNS
12807
12829
  },
12808
12830
  listKnowledgeFolders: {
12831
+ describe: "List knowledge folders",
12809
12832
  aliases: ["ls"],
12810
12833
  flags: {
12811
12834
  parentPath: { ...FOLDER_PATH_INPUT, name: "parent", describe: "Direct parent folder path" }
@@ -12813,6 +12836,7 @@ var CLI_CONTRACT = {
12813
12836
  columns: FOLDER_LIST_COLUMNS
12814
12837
  },
12815
12838
  listTableFolders: {
12839
+ describe: "List table folders",
12816
12840
  aliases: ["ls"],
12817
12841
  flags: {
12818
12842
  parentPath: { ...FOLDER_PATH_INPUT, name: "parent", describe: "Direct parent folder path" }
@@ -12820,6 +12844,7 @@ var CLI_CONTRACT = {
12820
12844
  columns: FOLDER_LIST_COLUMNS
12821
12845
  },
12822
12846
  listWorkflowFolders: {
12847
+ describe: "List workflow folders",
12823
12848
  aliases: ["ls"],
12824
12849
  flags: {
12825
12850
  parentPath: { ...FOLDER_PATH_INPUT, name: "parent", describe: "Direct parent folder path" }
@@ -13298,6 +13323,7 @@ function encodeFolderPath(value) {
13298
13323
  }
13299
13324
  }).join("/");
13300
13325
  }
13326
+ var FRACTIONAL_DIGITS = /\.\d*[1-9]/;
13301
13327
  function pathHint(raw) {
13302
13328
  if (raw.startsWith("@") || /^\s*[[{"\-\d]|^\s*(true|false|null)/.test(raw))
13303
13329
  return "";
@@ -13326,6 +13352,12 @@ function coerce(raw, field, flag, flagName) {
13326
13352
  const value = Number(raw);
13327
13353
  if (Number.isNaN(value))
13328
13354
  throw new SimApiError(`--${flagName} must be a number`, 0);
13355
+ if (field.kind === "integer" && (!Number.isInteger(value) || FRACTIONAL_DIGITS.test(String(raw)))) {
13356
+ throw new SimApiError(`--${flagName} must be a whole number`, 0);
13357
+ }
13358
+ if (field.kind === "integer" && !Number.isSafeInteger(value)) {
13359
+ throw new SimApiError(`--${flagName} is outside the whole-number range the API accepts (±${Number.MAX_SAFE_INTEGER})`, 0);
13360
+ }
13329
13361
  return value;
13330
13362
  }
13331
13363
  if (field.kind === "boolean" || flag.boolean)
@@ -13385,6 +13417,9 @@ function buildRequest(operation, positional, flags, workspaceId) {
13385
13417
  throw new SimApiError(`--${flagName} cannot be empty`, 0);
13386
13418
  }
13387
13419
  const value = coerce(raw ?? undefined, descriptor, flag, flagName);
13420
+ if (field === "limit" && !paginatedLimit && NUMERIC_KINDS.has(descriptor.kind) && typeof value === "number" && value < 1) {
13421
+ throw new SimApiError(`--${flagName} must be 1 or more`, 0);
13422
+ }
13388
13423
  if (value === undefined) {
13389
13424
  if (descriptor.required) {
13390
13425
  throw new SimApiError(field === PROFILE_INJECTED_FIELD ? NO_WORKSPACE_FALLBACK : `--${flagName} is required`, 0);
@@ -13533,7 +13568,7 @@ function addOperationOptions(command, operation, commandSpec, operationSpec) {
13533
13568
  }
13534
13569
  if (commandSpec.confirm) {
13535
13570
  const exemptedByDryRun = operationSpec.query?.dryRun !== undefined || operationSpec.body?.dryRun !== undefined;
13536
- command.option("-y, --yes", exemptedByDryRun ? "Confirm this destructive operation (required unless --dry-run)" : "Confirm this destructive operation (required)");
13571
+ command.option("-y, --yes", exemptedByDryRun ? "Confirm this operation (required unless --dry-run)" : "Confirm this operation (required)");
13537
13572
  }
13538
13573
  }
13539
13574
 
@@ -13959,6 +13994,14 @@ var BULK_OUTCOME_CHECKS = {
13959
13994
  const reported2 = payload.errors?.[0];
13960
13995
  return typeof reported2 === "string" && reported2 ? safeOneLine(reported2) : `Updated nothing: none of the ${requested} requested ${requested === 1 ? "chunk" : "chunks"} matched.`;
13961
13996
  },
13997
+ deleteTableRows: (payload) => {
13998
+ if (countOf(payload.deletedCount) > 0)
13999
+ return null;
14000
+ const requested = countOf(payload.requestedCount);
14001
+ if (requested === 0)
14002
+ return null;
14003
+ return `Deleted nothing: none of the ${requested} requested ${requested === 1 ? "row was" : "rows were"} deleted.`;
14004
+ },
13962
14005
  moveTables: (payload) => {
13963
14006
  if (lengthOf(payload.moved) > 0)
13964
14007
  return null;
@@ -13993,6 +14036,14 @@ function bulkFailureMessage(operation, payload, body) {
13993
14036
  var EXCLUSIVE_CAP_FIELDS = {
13994
14037
  deleteTableRows: { cap: "limit", ids: "rowIds" }
13995
14038
  };
14039
+ function readPagedLimit(raw) {
14040
+ const text2 = String(raw ?? DEFAULT_LIMIT).trim();
14041
+ const value = text2 === "" ? Number.NaN : Number(text2);
14042
+ if (!Number.isInteger(value) || value < 0) {
14043
+ throw new SimApiError("--limit must be a whole number of 0 or more (0 for everything)", 0);
14044
+ }
14045
+ return value;
14046
+ }
13996
14047
  function assertCapIsUsable(operation, flags) {
13997
14048
  const exclusive = EXCLUSIVE_CAP_FIELDS[operation];
13998
14049
  if (!exclusive)
@@ -14003,6 +14054,19 @@ function assertCapIsUsable(operation, flags) {
14003
14054
  return;
14004
14055
  throw new SimApiError(`--${cap} caps a --filter match and does nothing to an explicit --${ids} list; pass one, not both`, 0);
14005
14056
  }
14057
+ var REQUIRED_SELECTORS = {
14058
+ deleteTableRows: { fields: ["filter", "rowIds"], noun: "rows to delete" }
14059
+ };
14060
+ function assertSelectorIsUsable(operation, flags) {
14061
+ const selector = REQUIRED_SELECTORS[operation];
14062
+ if (!selector)
14063
+ return;
14064
+ const [first, second] = selector.fields.map((field) => flagNameFor(operation, field));
14065
+ const given = [first, second].filter((name) => flags[camel(name)] !== undefined);
14066
+ if (given.length === 1)
14067
+ return;
14068
+ 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);
14069
+ }
14006
14070
  function foldRenamedFlags(operation, commandSpec, flags) {
14007
14071
  for (const [field, flag] of Object.entries(commandSpec.flags ?? {})) {
14008
14072
  if (!flag.renamedFrom?.length)
@@ -14036,6 +14100,7 @@ async function executeOperation(operation, commandSpec, operationSpec, invocatio
14036
14100
  }
14037
14101
  foldRenamedFlags(operation, commandSpec, requestFlags);
14038
14102
  assertCapIsUsable(operation, requestFlags);
14103
+ assertSelectorIsUsable(operation, requestFlags);
14039
14104
  if (commandSpec.confirm && !requestFlags.yes && requestFlags.dryRun !== true) {
14040
14105
  throw new SimApiError(`${commandSpec.confirm} Re-run with --yes to confirm.`, 0);
14041
14106
  }
@@ -14046,15 +14111,11 @@ async function executeOperation(operation, commandSpec, operationSpec, invocatio
14046
14111
  const hasWorkspaceField = Boolean(operationSpec.query && PROFILE_INJECTED_FIELD in operationSpec.query || operationSpec.body && PROFILE_INJECTED_FIELD in operationSpec.body);
14047
14112
  const omitsWorkspace = commandSpec.allWorkspaces && requestFlags.allWorkspaces === true;
14048
14113
  const needsWorkspace = (hasWorkspaceField || commandSpec.profileWorkspacePath === true) && !omitsWorkspace;
14049
- const request = buildRequest(operation, positional, requestFlags, needsWorkspace ? client.requireWorkspace() : profile.workspaceId);
14050
14114
  const paging = cursorSlot(operationSpec);
14115
+ const pagedLimit = paging ? readPagedLimit(requestFlags.limit) : 0;
14116
+ const request = buildRequest(operation, positional, requestFlags, needsWorkspace ? client.requireWorkspace() : profile.workspaceId);
14051
14117
  if (paging) {
14052
- const limitText = String(requestFlags.limit ?? DEFAULT_LIMIT).trim();
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;
14118
+ const limit = pagedLimit === 0 ? Number.POSITIVE_INFINITY : pagedLimit;
14058
14119
  const pageSize = Math.min(Number.isFinite(limit) ? limit : DEFAULT_LIMIT, DEFAULT_LIMIT);
14059
14120
  const pageLimit = "limit" in (operationSpec[paging] ?? {}) ? { limit: pageSize } : {};
14060
14121
  const rows = [];
@@ -14139,6 +14200,14 @@ function retypeMessage(message, spellings) {
14139
14200
  continue;
14140
14201
  retyped = retyped.replaceAll(new RegExp(`\\b${field}\\b`, "g"), spelling);
14141
14202
  }
14203
+ if (retyped === message)
14204
+ return message;
14205
+ for (const field of spellings.keys()) {
14206
+ if (WIRE_IDENTIFIER.test(field))
14207
+ continue;
14208
+ if (new RegExp(`\\b${field}\\b`).test(message))
14209
+ return message;
14210
+ }
14142
14211
  return retyped;
14143
14212
  }
14144
14213
  function retypeDetails(details, spellings) {
@@ -14204,18 +14273,30 @@ function commandPath(command) {
14204
14273
  }
14205
14274
  return names.join(" ");
14206
14275
  }
14207
- function addMissingArgumentExample(command) {
14276
+ var UNKNOWN_OPTION_TOKEN = /^error: unknown option '(.+?)'/;
14277
+ function looksLikeAnId(token2) {
14278
+ return token2.length > 2 && !token2.startsWith("--") && /^-[A-Za-z0-9_-]*[A-Z0-9][A-Za-z0-9_-]*$/.test(token2);
14279
+ }
14280
+ function addArgumentExamples(command) {
14208
14281
  const outputError = command.configureOutput().outputError;
14209
14282
  if (!outputError)
14210
14283
  throw new Error("Commander output formatter is not configured");
14211
14284
  command.configureOutput({
14212
14285
  outputError: (message, write) => {
14213
14286
  outputError(message, write);
14214
- if (!message.startsWith("error: missing required argument "))
14287
+ if (message.startsWith("error: missing required argument ")) {
14288
+ const syntax = argumentSyntax(command);
14289
+ const example = syntax ? `${commandPath(command)} ${syntax}` : commandPath(command);
14290
+ write(`Example: ${example}
14291
+ `);
14292
+ return;
14293
+ }
14294
+ if (command.registeredArguments.length === 0)
14295
+ return;
14296
+ const token2 = UNKNOWN_OPTION_TOKEN.exec(message)?.[1];
14297
+ if (!token2 || !looksLikeAnId(token2))
14215
14298
  return;
14216
- const syntax = argumentSyntax(command);
14217
- const example = syntax ? `${commandPath(command)} ${syntax}` : commandPath(command);
14218
- write(`Example: ${example}
14299
+ write(`Example: ${commandPath(command)} -- ${token2}
14219
14300
  `);
14220
14301
  }
14221
14302
  });
@@ -14342,7 +14423,7 @@ function configureOperation(command, operation, spec) {
14342
14423
  return command;
14343
14424
  }
14344
14425
  function buildLeaf(operation, spec, leafName) {
14345
- return addMissingArgumentExample(configureOperation(new Command(leafName), operation, spec));
14426
+ return addArgumentExamples(configureOperation(new Command(leafName), operation, spec));
14346
14427
  }
14347
14428
  function addRenamedCommand(groups, operation, spec, from, to) {
14348
14429
  const segments = from.split(" ");
@@ -14662,6 +14743,12 @@ Examples:
14662
14743
  $ sim chat -c 3f2a… "Which of those run on a schedule?"
14663
14744
  $ sim --output json chat "Summarize yesterday's failed runs" | jq -r '.content'
14664
14745
  `).action(async (message, options, command) => {
14746
+ if (message.trim() === "") {
14747
+ throw new SimApiError("<message> cannot be empty", 0);
14748
+ }
14749
+ if (options.conversation !== undefined && options.conversation.trim() === "") {
14750
+ throw new SimApiError("-c/--conversation cannot be empty — pass the conversation id printed on stderr after each turn", 0);
14751
+ }
14665
14752
  const { client, profile } = clientFrom(command);
14666
14753
  const workspaceId = client.requireWorkspace();
14667
14754
  const response = await client.requestRaw(V2_OPERATIONS.chat.path, {
@@ -15070,8 +15157,15 @@ function uploadMetadata(options) {
15070
15157
  }
15071
15158
  return metadata;
15072
15159
  }
15160
+ var UPLOAD_RECIPES = [
15161
+ "default",
15162
+ "plain",
15163
+ "markdown",
15164
+ "code"
15165
+ ];
15166
+ var LANGUAGE_TAG_HELP = "Document language tag: hyphen-separated letter and digit subtags, for example en or en-US";
15073
15167
  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").option("--recipe <name>", "Document processing recipe").option("--lang <code>", "Document language code").action(async (knowledgeBaseId, path, options, command) => {
15168
+ 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
15169
  const { client, profile } = clientFrom(command);
15076
15170
  const workspaceId = client.requireWorkspace();
15077
15171
  const { name, size } = await localFile(path, options.name);
@@ -15290,7 +15384,7 @@ function isTransient(error) {
15290
15384
  function nonNegativeInteger(raw, flag) {
15291
15385
  const value = Number(raw);
15292
15386
  if (!Number.isSafeInteger(value) || value < 0) {
15293
- throw new SimApiError(`${flag} must be a non-negative integer`, 0);
15387
+ throw new SimApiError(`${flag} must be a whole number of 0 or more`, 0);
15294
15388
  }
15295
15389
  return value;
15296
15390
  }
@@ -15317,7 +15411,7 @@ follow.
15317
15411
 
15318
15412
  Examples:
15319
15413
  $ sim logs follow --level error
15320
- $ sim logs follow --workflow wf_123 -n 0
15414
+ $ sim logs follow --workflow 00000000-0000-4000-8000-000000000000 -n 0
15321
15415
  $ sim --output json logs follow | jq -r '.runId'
15322
15416
  `).action(async (options, command) => {
15323
15417
  const lines = nonNegativeInteger(options.lines, "--lines");
@@ -15399,9 +15493,9 @@ async function listResources(client, config, workspaceId, folderPath, search, li
15399
15493
  const paginated = "cursor" in V2_OPERATIONS[config.resources].query;
15400
15494
  if (!paginated) {
15401
15495
  const page = await client.request(path, { query });
15402
- return page.data.slice(0, limit);
15496
+ return { items: page.data.slice(0, limit), truncated: page.data.length > limit };
15403
15497
  }
15404
- return requestAllPages(client, path, {
15498
+ return requestPages(client, path, {
15405
15499
  query,
15406
15500
  pageSize: DEFAULT_LIMIT,
15407
15501
  limit
@@ -15436,7 +15530,7 @@ function attachResourceDirectoryCommands(group, config) {
15436
15530
  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
15531
  const rawLimit = Number(options.limit);
15438
15532
  if (!Number.isSafeInteger(rawLimit) || rawLimit < 0) {
15439
- throw new SimApiError("--limit must be a non-negative integer", 0);
15533
+ throw new SimApiError("--limit must be a whole number of 0 or more (0 for everything)", 0);
15440
15534
  }
15441
15535
  const limit = rawLimit === 0 ? Number.POSITIVE_INFINITY : rawLimit;
15442
15536
  const folderPath = encodeFolderPath(path ?? "/");
@@ -15446,8 +15540,10 @@ function attachResourceDirectoryCommands(group, config) {
15446
15540
  listFolders(client, config.folders, workspaceId, folderPath, options.search),
15447
15541
  listResources(client, config, workspaceId, folderPath, options.search, limit)
15448
15542
  ]);
15449
- const entries = entriesFor(config, folders, resources);
15450
- printList(profile.output, entries.slice(0, limit), COLUMNS2);
15543
+ const entries = entriesFor(config, folders, resources.items);
15544
+ const shown = entries.slice(0, limit);
15545
+ writeCursorTruncation(shown.length, resources.truncated || entries.length > limit);
15546
+ printList(profile.output, shown, COLUMNS2);
15451
15547
  });
15452
15548
  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
15549
  const { client, profile } = clientFrom(command);
@@ -16194,7 +16290,9 @@ Profiles work like the AWS CLI: settings live in ~/.sim/config, keys in
16194
16290
  with -P, --profile, or SIM_PROFILE.
16195
16291
 
16196
16292
  Workflow, knowledge-base and workspace IDs are bare UUIDs. Table IDs carry a
16197
- tbl_ prefix and file IDs a wf_ one, so wf_ never names a workflow.
16293
+ tbl_ prefix and file IDs a wf_ one, so wf_ never names a workflow. An audit-log
16294
+ or custom-tool ID can open with a dash, which reads as a flag; put -- in front
16295
+ of it, as in sim audit-logs get -- -HlDcD1z76nK6R4crsUp0.
16198
16296
 
16199
16297
  Examples:
16200
16298
  $ sim login Authorize the default profile
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sim",
3
- "version": "2.1.3-preview.50.1",
3
+ "version": "2.1.3-preview.52.1",
4
4
  "description": "Sim CLI - talk to the Sim API from your terminal",
5
5
  "type": "module",
6
6
  "bin": {