sim 2.1.5-dev.81.1 → 2.1.5

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 +113 -307
  2. package/package.json +1 -7
package/dist/index.js CHANGED
@@ -2314,30 +2314,6 @@ function credentialsPath() {
2314
2314
  import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2315
2315
  import { dirname } from "node:path";
2316
2316
 
2317
- // src/embed-context.ts
2318
- import { AsyncLocalStorage } from "node:async_hooks";
2319
- function setSoftExitCode(code) {
2320
- const ctx = embedStore.getStore();
2321
- if (ctx)
2322
- ctx.softExitCode = code;
2323
- else
2324
- process.exitCode = code;
2325
- }
2326
- var embedStore = new AsyncLocalStorage;
2327
- function embeddedProfile() {
2328
- const ctx = embedStore.getStore();
2329
- if (!ctx)
2330
- return null;
2331
- return {
2332
- name: "embedded",
2333
- endpoint: ctx.identity.endpoint,
2334
- apiKey: ctx.identity.apiKey,
2335
- workspaceId: ctx.identity.workspaceId ?? null,
2336
- output: "json",
2337
- sources: { endpoint: "flag", apiKey: "flag", workspaceId: "flag", output: "flag" }
2338
- };
2339
- }
2340
-
2341
2317
  // src/config/ini.ts
2342
2318
  class ProfileConfigError extends Error {
2343
2319
  constructor(message) {
@@ -2653,9 +2629,6 @@ function refuseBlankOverrides(overrides) {
2653
2629
  }
2654
2630
  }
2655
2631
  function resolveProfile(overrides = {}) {
2656
- const embedded = embeddedProfile();
2657
- if (embedded)
2658
- return embedded;
2659
2632
  refuseBlankOverrides(overrides);
2660
2633
  const named = overrides.profile || process.env.SIM_PROFILE;
2661
2634
  const name = named || DEFAULT_PROFILE;
@@ -2708,22 +2681,14 @@ function resolveProfile(overrides = {}) {
2708
2681
  // src/version.ts
2709
2682
  import { readFileSync as readFileSync2 } from "node:fs";
2710
2683
  function readPackageVersion() {
2711
- try {
2712
- const metadata = JSON.parse(readFileSync2(new URL("../package.json", import.meta.url), "utf8"));
2713
- if (typeof metadata === "object" && metadata !== null && "version" in metadata && typeof metadata.version === "string") {
2714
- return metadata.version;
2715
- }
2716
- } catch {}
2717
- return "0.0.0-embedded";
2718
- }
2719
- var cachedVersion = null;
2720
- function cliVersion() {
2721
- cachedVersion ??= readPackageVersion();
2722
- return cachedVersion;
2723
- }
2724
- function userAgent() {
2725
- return `sim-cli/${cliVersion()} node/${process.versions.node} (${process.platform}; ${process.arch})`;
2684
+ const metadata = JSON.parse(readFileSync2(new URL("../package.json", import.meta.url), "utf8"));
2685
+ if (typeof metadata !== "object" || metadata === null || !("version" in metadata) || typeof metadata.version !== "string") {
2686
+ throw new Error("CLI package metadata is missing a valid version");
2687
+ }
2688
+ return metadata.version;
2726
2689
  }
2690
+ var CLI_VERSION = readPackageVersion();
2691
+ var USER_AGENT = `sim-cli/${CLI_VERSION} node/${process.versions.node} (${process.platform}; ${process.arch})`;
2727
2692
 
2728
2693
  // src/http/environment.ts
2729
2694
  var reported = new Set;
@@ -3006,7 +2971,7 @@ class SimClient {
3006
2971
  headers: {
3007
2972
  ...apiKey ? { "x-api-key": apiKey } : {},
3008
2973
  accept: "application/json",
3009
- "user-agent": userAgent(),
2974
+ "user-agent": USER_AGENT,
3010
2975
  ...hasBody ? { "content-type": "application/json" } : {},
3011
2976
  ...options.headers
3012
2977
  },
@@ -6505,7 +6470,7 @@ async function pollForKey(endpoint, auth, signal) {
6505
6470
  headers: {
6506
6471
  "content-type": "application/json",
6507
6472
  accept: "application/json",
6508
- "user-agent": userAgent()
6473
+ "user-agent": USER_AGENT
6509
6474
  },
6510
6475
  body: JSON.stringify({ request: auth.request, verifier: auth.pollSecret }),
6511
6476
  signal,
@@ -6666,8 +6631,8 @@ var V2_OPERATIONS = {
6666
6631
  },
6667
6632
  outputColumns: {
6668
6633
  kind: "array",
6669
- default: [],
6670
- describe: "Columns to create for producer outputs. An entry naming a column the table already has attaches that column to the group instead of creating it (its `type` must match), and an output whose column already exists may omit its entry entirely — so `[]` attaches existing columns only."
6634
+ required: true,
6635
+ describe: "Columns created for producer outputs."
6671
6636
  },
6672
6637
  autoRun: {
6673
6638
  kind: "boolean",
@@ -6971,7 +6936,7 @@ var V2_OPERATIONS = {
6971
6936
  rowId: { kind: "string", describe: "Row whose runs should be canceled for row scope." },
6972
6937
  filter: {
6973
6938
  kind: "unknown",
6974
- describe: 'A single `{ field, op, value }` condition or a recursive `all`/`any` group; either form is normalized to a grouped predicate after validation. At most 100 members per group, 10 levels of nesting, and 500 nodes in total. The negating operators include nulls: `ne`, `nin`, `ncontains`, `nlike`, and `nilike` match rows whose column is null or absent, so "not X" is not the complement of "X" over a nullable column. That holds for every column type, multi-select included. To exclude nulls, `all`-combine the negation with `isNotEmpty` (multi-select) or `isNotNull`. Comparison: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`. Membership: `in`, `nin` (array operand). Emptiness: `isEmpty`, `isNotEmpty`, `isNull`, `isNotNull` (no operand). Substring, always case-insensitive, operand matched literally: `contains`, `ncontains`, `startsWith`, `endsWith`. Pattern: `like`/`nlike` (case-sensitive), `ilike`/`nilike` (case-insensitive). **`*` is the only wildcard** and stands for any run of characters; `%`, `_`, and backslash match themselves. Use `like: "Hi*"`, not `like: "Hi%"`. A `select` column compares by option id and restricts its operators: single-select accepts `eq`, `ne`, `in`, `nin`; multi-select accepts `contains`, `ncontains`. Option names are accepted as operands and resolved to ids.'
6939
+ describe: 'Recursive predicate tree. Each group node is exactly one non-empty `all` or `any` array whose members are further groups or `{ field, op, value }` conditions; the root must be a group, not a bare condition. At most 100 members per group, 10 levels of nesting, and 500 nodes in total. The negating operators include nulls: `ne`, `nin`, `ncontains`, `nlike`, and `nilike` match rows whose column is null or absent, so "not X" is not the complement of "X" over a nullable column. That holds for every column type, multi-select included. To exclude nulls, `all`-combine the negation with `isNotEmpty` (multi-select) or `isNotNull`. Comparison: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`. Membership: `in`, `nin` (array operand). Emptiness: `isEmpty`, `isNotEmpty`, `isNull`, `isNotNull` (no operand). Substring, always case-insensitive, operand matched literally: `contains`, `ncontains`, `startsWith`, `endsWith`. Pattern: `like`/`nlike` (case-sensitive), `ilike`/`nilike` (case-insensitive). **`*` is the only wildcard** and stands for any run of characters; `%`, `_`, and backslash match themselves. Use `like: "Hi*"`, not `like: "Hi%"`. A `select` column compares by option id and restricts its operators: single-select accepts `eq`, `ne`, `in`, `nin`; multi-select accepts `contains`, `ncontains`. Option names are accepted as operands and resolved to ids.'
6975
6940
  },
6976
6941
  excludeRowIds: { kind: "array", describe: "Rows excluded from an all-scope cancellation." }
6977
6942
  }
@@ -7002,11 +6967,6 @@ var V2_OPERATIONS = {
7002
6967
  conversationId: {
7003
6968
  kind: "string",
7004
6969
  describe: "Conversation to continue; a new one starts when omitted."
7005
- },
7006
- effort: {
7007
- kind: "enum",
7008
- values: ["low", "medium", "high", "xhigh", "max"],
7009
- describe: "Model effort for this turn; defaults to the deployment default (high)."
7010
6970
  }
7011
6971
  }
7012
6972
  },
@@ -7535,7 +7495,7 @@ var V2_OPERATIONS = {
7535
7495
  description: { kind: "string", describe: "Optional credential description." },
7536
7496
  id: {
7537
7497
  kind: "string",
7538
- describe: "Optional client-generated credential ID. The server mints one when it is omitted, so no provider requires it. A `slack-custom-bot` credential may supply one so its Slack Request URL, which embeds the ID, can be configured before the credential exists; every other provider ignores it."
7498
+ describe: "Required only when provider discovery requests a client-generated ID."
7539
7499
  },
7540
7500
  credentials: {
7541
7501
  kind: "string",
@@ -7611,7 +7571,7 @@ var V2_OPERATIONS = {
7611
7571
  rowIds: { kind: "array", describe: "Explicit row subset to run." },
7612
7572
  filter: {
7613
7573
  kind: "unknown",
7614
- describe: 'A single `{ field, op, value }` condition or a recursive `all`/`any` group; either form is normalized to a grouped predicate after validation. At most 100 members per group, 10 levels of nesting, and 500 nodes in total. The negating operators include nulls: `ne`, `nin`, `ncontains`, `nlike`, and `nilike` match rows whose column is null or absent, so "not X" is not the complement of "X" over a nullable column. That holds for every column type, multi-select included. To exclude nulls, `all`-combine the negation with `isNotEmpty` (multi-select) or `isNotNull`. Comparison: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`. Membership: `in`, `nin` (array operand). Emptiness: `isEmpty`, `isNotEmpty`, `isNull`, `isNotNull` (no operand). Substring, always case-insensitive, operand matched literally: `contains`, `ncontains`, `startsWith`, `endsWith`. Pattern: `like`/`nlike` (case-sensitive), `ilike`/`nilike` (case-insensitive). **`*` is the only wildcard** and stands for any run of characters; `%`, `_`, and backslash match themselves. Use `like: "Hi*"`, not `like: "Hi%"`. A `select` column compares by option id and restricts its operators: single-select accepts `eq`, `ne`, `in`, `nin`; multi-select accepts `contains`, `ncontains`. Option names are accepted as operands and resolved to ids.'
7574
+ describe: 'Recursive predicate tree. Each group node is exactly one non-empty `all` or `any` array whose members are further groups or `{ field, op, value }` conditions; the root must be a group, not a bare condition. At most 100 members per group, 10 levels of nesting, and 500 nodes in total. The negating operators include nulls: `ne`, `nin`, `ncontains`, `nlike`, and `nilike` match rows whose column is null or absent, so "not X" is not the complement of "X" over a nullable column. That holds for every column type, multi-select included. To exclude nulls, `all`-combine the negation with `isNotEmpty` (multi-select) or `isNotNull`. Comparison: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`. Membership: `in`, `nin` (array operand). Emptiness: `isEmpty`, `isNotEmpty`, `isNull`, `isNotNull` (no operand). Substring, always case-insensitive, operand matched literally: `contains`, `ncontains`, `startsWith`, `endsWith`. Pattern: `like`/`nlike` (case-sensitive), `ilike`/`nilike` (case-insensitive). **`*` is the only wildcard** and stands for any run of characters; `%`, `_`, and backslash match themselves. Use `like: "Hi*"`, not `like: "Hi%"`. A `select` column compares by option id and restricts its operators: single-select accepts `eq`, `ne`, `in`, `nin`; multi-select accepts `contains`, `ncontains`. Option names are accepted as operands and resolved to ids.'
7615
7575
  },
7616
7576
  excludeRowIds: { kind: "array", describe: "Rows excluded from a select-all run scope." },
7617
7577
  limit: { kind: "object", describe: "Optional cap on eligible rows to run." }
@@ -8133,7 +8093,7 @@ var V2_OPERATIONS = {
8133
8093
  workspaceId: { kind: "string", required: true, describe: "Unique workspace identifier." },
8134
8094
  filter: {
8135
8095
  kind: "unknown",
8136
- describe: 'A single `{ field, op, value }` condition or a recursive `all`/`any` group; either form is normalized to a grouped predicate after validation. At most 100 members per group, 10 levels of nesting, and 500 nodes in total. The negating operators include nulls: `ne`, `nin`, `ncontains`, `nlike`, and `nilike` match rows whose column is null or absent, so "not X" is not the complement of "X" over a nullable column. That holds for every column type, multi-select included. To exclude nulls, `all`-combine the negation with `isNotEmpty` (multi-select) or `isNotNull`. Comparison: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`. Membership: `in`, `nin` (array operand). Emptiness: `isEmpty`, `isNotEmpty`, `isNull`, `isNotNull` (no operand). Substring, always case-insensitive, operand matched literally: `contains`, `ncontains`, `startsWith`, `endsWith`. Pattern: `like`/`nlike` (case-sensitive), `ilike`/`nilike` (case-insensitive). **`*` is the only wildcard** and stands for any run of characters; `%`, `_`, and backslash match themselves. Use `like: "Hi*"`, not `like: "Hi%"`. A `select` column compares by option id and restricts its operators: single-select accepts `eq`, `ne`, `in`, `nin`; multi-select accepts `contains`, `ncontains`. Option names are accepted as operands and resolved to ids.'
8096
+ describe: 'Recursive predicate tree. Each group node is exactly one non-empty `all` or `any` array whose members are further groups or `{ field, op, value }` conditions; the root must be a group, not a bare condition. At most 100 members per group, 10 levels of nesting, and 500 nodes in total. The negating operators include nulls: `ne`, `nin`, `ncontains`, `nlike`, and `nilike` match rows whose column is null or absent, so "not X" is not the complement of "X" over a nullable column. That holds for every column type, multi-select included. To exclude nulls, `all`-combine the negation with `isNotEmpty` (multi-select) or `isNotNull`. Comparison: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`. Membership: `in`, `nin` (array operand). Emptiness: `isEmpty`, `isNotEmpty`, `isNull`, `isNotNull` (no operand). Substring, always case-insensitive, operand matched literally: `contains`, `ncontains`, `startsWith`, `endsWith`. Pattern: `like`/`nlike` (case-sensitive), `ilike`/`nilike` (case-insensitive). **`*` is the only wildcard** and stands for any run of characters; `%`, `_`, and backslash match themselves. Use `like: "Hi*"`, not `like: "Hi%"`. A `select` column compares by option id and restricts its operators: single-select accepts `eq`, `ne`, `in`, `nin`; multi-select accepts `contains`, `ncontains`. Option names are accepted as operands and resolved to ids.'
8137
8097
  },
8138
8098
  limit: { kind: "integer", describe: "Maximum matching rows to delete." },
8139
8099
  rowIds: { kind: "array", describe: "Explicit row identifiers to delete." }
@@ -8303,6 +8263,37 @@ var V2_OPERATIONS = {
8303
8263
  }
8304
8264
  }
8305
8265
  },
8266
+ executeTool: {
8267
+ method: "POST",
8268
+ path: "/api/v2/tools/[toolId]/execute",
8269
+ pathParams: ["toolId"],
8270
+ pathParamDocs: {
8271
+ toolId: "Tool identifier. An unversioned name resolves to the newest version, and the response echoes the resolved id."
8272
+ },
8273
+ responseMode: "json",
8274
+ summary: "Run Tool",
8275
+ personalKeyOnly: true,
8276
+ body: {
8277
+ workspaceId: {
8278
+ kind: "string",
8279
+ required: true,
8280
+ describe: "Workspace whose integration allowlist, credentials, and environment variables govern this call."
8281
+ },
8282
+ input: {
8283
+ kind: "object",
8284
+ default: {},
8285
+ describe: "Arguments for the tool, keyed by the parameter ids the tool catalog publishes for it. A parameter whose visibility is `user-only` also accepts an environment-variable reference written as the whole value, `{{VAR_NAME}}`, resolved server-side against the workspace environment; any other value is sent verbatim."
8286
+ },
8287
+ credentialId: {
8288
+ kind: "string",
8289
+ describe: "Credential to authenticate with. Required when the tool declares an OAuth requirement; the workspace credentials list names the candidates."
8290
+ },
8291
+ timeoutSeconds: {
8292
+ kind: "integer",
8293
+ describe: "How long to wait for the tool before abandoning the call."
8294
+ }
8295
+ }
8296
+ },
8306
8297
  executeWorkflow: {
8307
8298
  method: "POST",
8308
8299
  path: "/api/v2/workflows/[workflowId]/execute",
@@ -8335,7 +8326,7 @@ var V2_OPERATIONS = {
8335
8326
  },
8336
8327
  selectedOutputs: {
8337
8328
  kind: "array",
8338
- describe: "Block output references to include in the response. Use `<blockName>.<outputPath>` for the executed workflow or `<childWorkflowId>.<blockName>.<outputPath>` for a child workflow; block names are normalized workflow reference names, and selecting a child workflow applies to every invocation of it. On a sync request the named outputs come back in `blockOutputs`, keyed by these selector strings exactly as sent; on a stream they shape the streamed envelope. A selector whose block name or id matches no block in the workflow is rejected with `400` naming the available blocks, before the run starts. A selector whose block did not run or whose path is absent is omitted. Rejected when `async` is true — a queued run has produced nothing to select; narrow the finished run via the run resource instead."
8329
+ describe: "Block output references to include in a streamed response. Use `<blockName>.<outputPath>` for the executed workflow or `<childWorkflowId>.<blockName>.<outputPath>` for a child workflow; block names are normalized workflow reference names. Selecting a child workflow applies to every invocation of it. Requires `stream: true` — it shapes the streamed envelope only, so it is rejected on a sync request and when `async` is true. To narrow a finished run, pass `selectedOutputs` to the run resource instead."
8339
8330
  },
8340
8331
  includeThinking: {
8341
8332
  kind: "boolean",
@@ -8373,13 +8364,7 @@ var V2_OPERATIONS = {
8373
8364
  pathParams: ["workflowId"],
8374
8365
  pathParamDocs: { workflowId: "Unique workflow identifier." },
8375
8366
  responseMode: "json",
8376
- summary: "Export Workflow",
8377
- query: {
8378
- includeWorkspaceBindings: {
8379
- kind: "boolean",
8380
- describe: "Whether to keep workspace-scoped bindings — table, knowledge base, document, folder, channel, and other resource selectors — in the exported state. Defaults to false, the sharing-safe export in which those ids are cleared because they resolve nowhere else. Send true for a same-workspace round trip so the re-imported workflow can run without re-selecting them. Credentials, passwords, and table sub-block values are cleared either way."
8381
- }
8382
- }
8367
+ summary: "Export Workflow"
8383
8368
  },
8384
8369
  getAuditLog: {
8385
8370
  method: "GET",
@@ -8611,26 +8596,7 @@ var V2_OPERATIONS = {
8611
8596
  segmentCount: {
8612
8597
  kind: "integer",
8613
8598
  default: 72,
8614
- describe: "Number of equal time buckets to divide the window into, from 1 to 500. It is the ceiling on how many buckets a series carries: with `includeEmpty=true` exactly this many are returned, otherwise only the buckets holding at least one run. Buckets are never narrower than one minute, so on a short window the series extends past the end of the window rather than being compressed, and the trailing buckets are empty."
8615
- },
8616
- includeEmpty: {
8617
- kind: "enum",
8618
- values: [
8619
- "true",
8620
- "1",
8621
- "yes",
8622
- "on",
8623
- "y",
8624
- "enabled",
8625
- "false",
8626
- "0",
8627
- "no",
8628
- "off",
8629
- "n",
8630
- "disabled"
8631
- ],
8632
- default: false,
8633
- describe: "Whether buckets with no runs are included in every series. Off by default, so each series carries only the buckets that hold at least one run; set it to publish exactly `segmentCount` buckets per series, empty ones included. The listed spellings are the whole accepted vocabulary and are case-sensitive; any other value is rejected."
8599
+ describe: "Number of equal time buckets to divide the window into, from 1 to 500. Exactly this many buckets are always returned. Buckets are never narrower than one minute, so on a short window the series extends past the end of the window rather than being compressed, and the trailing buckets are empty."
8634
8600
  }
8635
8601
  }
8636
8602
  },
@@ -9012,7 +8978,8 @@ var V2_OPERATIONS = {
9012
8978
  "knowledge-base",
9013
8979
  "voice-input",
9014
8980
  "enrichment",
9015
- "voice-output"
8981
+ "voice-output",
8982
+ "api-tool"
9016
8983
  ],
9017
8984
  describe: "Restrict results to one usage source."
9018
8985
  },
@@ -9151,21 +9118,6 @@ var V2_OPERATIONS = {
9151
9118
  search: {
9152
9119
  kind: "string",
9153
9120
  describe: "Case-insensitive substring match against the connector name."
9154
- },
9155
- detail: {
9156
- kind: "enum",
9157
- values: ["summary", "full"],
9158
- default: "summary",
9159
- describe: "Projection of each item. `summary` (the default) carries the identifier, name, description, and auth mode; `full` adds the version, the complete auth settings, the `sourceConfig` field schema, incremental-sync support, and tag definitions."
9160
- },
9161
- limit: {
9162
- kind: "integer",
9163
- default: 25,
9164
- describe: "Maximum connector types to return per page. Must be a whole number from 1 to 100. Defaults to 25."
9165
- },
9166
- cursor: {
9167
- kind: "string",
9168
- describe: "Opaque cursor from the previous page. Send it back with the same sort and filters; only `limit` may change. Change anything else and pagination must restart without a cursor."
9169
9121
  }
9170
9122
  }
9171
9123
  },
@@ -9955,7 +9907,7 @@ var V2_OPERATIONS = {
9955
9907
  pathParams: ["tableId"],
9956
9908
  pathParamDocs: { tableId: "Unique table identifier." },
9957
9909
  responseMode: "json",
9958
- summary: "List Run Dispatches",
9910
+ summary: "List Active Run Dispatches",
9959
9911
  query: {
9960
9912
  workspaceId: { kind: "string", required: true, describe: "Workspace that owns the table." }
9961
9913
  }
@@ -10367,8 +10319,8 @@ var V2_OPERATIONS = {
10367
10319
  },
10368
10320
  limit: {
10369
10321
  kind: "integer",
10370
- default: 25,
10371
- describe: "Maximum workspaces to return per page. Must be a whole number from 1 to 100. Defaults to 25."
10322
+ default: 50,
10323
+ describe: "Maximum workspaces to return per page. Must be a whole number from 1 to 100. Defaults to 50."
10372
10324
  },
10373
10325
  cursor: {
10374
10326
  kind: "string",
@@ -10503,7 +10455,7 @@ var V2_OPERATIONS = {
10503
10455
  destinationPath: {
10504
10456
  kind: "string",
10505
10457
  required: true,
10506
- describe: "Where the folder lands, with `mv` semantics. A path naming an existing folder receives the source as a child under its current name; `/` moves it to the workspace root under its current name; any other path becomes the folder’s new full path (a rename, a relocation, or both)."
10458
+ describe: "New full path for the folder and its descendants."
10507
10459
  }
10508
10460
  }
10509
10461
  },
@@ -10519,7 +10471,7 @@ var V2_OPERATIONS = {
10519
10471
  destinationPath: {
10520
10472
  kind: "string",
10521
10473
  required: true,
10522
- describe: "Where the folder lands, with `mv` semantics. A path naming an existing folder receives the source as a child under its current name; `/` moves it to the workspace root under its current name; any other path becomes the folder’s new full path (a rename, a relocation, or both)."
10474
+ describe: "New full path for the folder and its descendants."
10523
10475
  }
10524
10476
  }
10525
10477
  },
@@ -10535,7 +10487,7 @@ var V2_OPERATIONS = {
10535
10487
  destinationPath: {
10536
10488
  kind: "string",
10537
10489
  required: true,
10538
- describe: "Where the folder lands, with `mv` semantics. A path naming an existing folder receives the source as a child under its current name; `/` moves it to the workspace root under its current name; any other path becomes the folder’s new full path (a rename, a relocation, or both)."
10490
+ describe: "New full path for the folder and its descendants."
10539
10491
  }
10540
10492
  }
10541
10493
  },
@@ -10551,7 +10503,7 @@ var V2_OPERATIONS = {
10551
10503
  destinationPath: {
10552
10504
  kind: "string",
10553
10505
  required: true,
10554
- describe: "Where the folder lands, with `mv` semantics. A path naming an existing folder receives the source as a child under its current name; `/` moves it to the workspace root under its current name; any other path becomes the folder’s new full path (a rename, a relocation, or both)."
10506
+ describe: "New full path for the folder and its descendants."
10555
10507
  }
10556
10508
  }
10557
10509
  },
@@ -10881,7 +10833,7 @@ var V2_OPERATIONS = {
10881
10833
  q: { kind: "string", required: true, describe: "Case-insensitive cell substring to find." },
10882
10834
  predicate: {
10883
10835
  kind: "unknown",
10884
- describe: 'A single `{ field, op, value }` condition or a recursive `all`/`any` group; either form is normalized to a grouped predicate after validation. At most 100 members per group, 10 levels of nesting, and 500 nodes in total. The negating operators include nulls: `ne`, `nin`, `ncontains`, `nlike`, and `nilike` match rows whose column is null or absent, so "not X" is not the complement of "X" over a nullable column. That holds for every column type, multi-select included. To exclude nulls, `all`-combine the negation with `isNotEmpty` (multi-select) or `isNotNull`. Comparison: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`. Membership: `in`, `nin` (array operand). Emptiness: `isEmpty`, `isNotEmpty`, `isNull`, `isNotNull` (no operand). Substring, always case-insensitive, operand matched literally: `contains`, `ncontains`, `startsWith`, `endsWith`. Pattern: `like`/`nlike` (case-sensitive), `ilike`/`nilike` (case-insensitive). **`*` is the only wildcard** and stands for any run of characters; `%`, `_`, and backslash match themselves. Use `like: "Hi*"`, not `like: "Hi%"`. A `select` column compares by option id and restricts its operators: single-select accepts `eq`, `ne`, `in`, `nin`; multi-select accepts `contains`, `ncontains`. Option names are accepted as operands and resolved to ids.'
10836
+ describe: 'Recursive predicate tree. Each group node is exactly one non-empty `all` or `any` array whose members are further groups or `{ field, op, value }` conditions; the root must be a group, not a bare condition. At most 100 members per group, 10 levels of nesting, and 500 nodes in total. The negating operators include nulls: `ne`, `nin`, `ncontains`, `nlike`, and `nilike` match rows whose column is null or absent, so "not X" is not the complement of "X" over a nullable column. That holds for every column type, multi-select included. To exclude nulls, `all`-combine the negation with `isNotEmpty` (multi-select) or `isNotNull`. Comparison: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`. Membership: `in`, `nin` (array operand). Emptiness: `isEmpty`, `isNotEmpty`, `isNull`, `isNotNull` (no operand). Substring, always case-insensitive, operand matched literally: `contains`, `ncontains`, `startsWith`, `endsWith`. Pattern: `like`/`nlike` (case-sensitive), `ilike`/`nilike` (case-insensitive). **`*` is the only wildcard** and stands for any run of characters; `%`, `_`, and backslash match themselves. Use `like: "Hi*"`, not `like: "Hi%"`. A `select` column compares by option id and restricts its operators: single-select accepts `eq`, `ne`, `in`, `nin`; multi-select accepts `contains`, `ncontains`. Option names are accepted as operands and resolved to ids.'
10885
10837
  },
10886
10838
  sort: { kind: "array", describe: "Ordered table-row sort specification." }
10887
10839
  }
@@ -11323,7 +11275,7 @@ var V2_OPERATIONS = {
11323
11275
  filter: {
11324
11276
  kind: "unknown",
11325
11277
  required: true,
11326
- describe: 'A single `{ field, op, value }` condition or a recursive `all`/`any` group; either form is normalized to a grouped predicate after validation. At most 100 members per group, 10 levels of nesting, and 500 nodes in total. The negating operators include nulls: `ne`, `nin`, `ncontains`, `nlike`, and `nilike` match rows whose column is null or absent, so "not X" is not the complement of "X" over a nullable column. That holds for every column type, multi-select included. To exclude nulls, `all`-combine the negation with `isNotEmpty` (multi-select) or `isNotNull`. Comparison: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`. Membership: `in`, `nin` (array operand). Emptiness: `isEmpty`, `isNotEmpty`, `isNull`, `isNotNull` (no operand). Substring, always case-insensitive, operand matched literally: `contains`, `ncontains`, `startsWith`, `endsWith`. Pattern: `like`/`nlike` (case-sensitive), `ilike`/`nilike` (case-insensitive). **`*` is the only wildcard** and stands for any run of characters; `%`, `_`, and backslash match themselves. Use `like: "Hi*"`, not `like: "Hi%"`. A `select` column compares by option id and restricts its operators: single-select accepts `eq`, `ne`, `in`, `nin`; multi-select accepts `contains`, `ncontains`. Option names are accepted as operands and resolved to ids.'
11278
+ describe: 'Recursive predicate tree. Each group node is exactly one non-empty `all` or `any` array whose members are further groups or `{ field, op, value }` conditions; the root must be a group, not a bare condition. At most 100 members per group, 10 levels of nesting, and 500 nodes in total. The negating operators include nulls: `ne`, `nin`, `ncontains`, `nlike`, and `nilike` match rows whose column is null or absent, so "not X" is not the complement of "X" over a nullable column. That holds for every column type, multi-select included. To exclude nulls, `all`-combine the negation with `isNotEmpty` (multi-select) or `isNotNull`. Comparison: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`. Membership: `in`, `nin` (array operand). Emptiness: `isEmpty`, `isNotEmpty`, `isNull`, `isNotNull` (no operand). Substring, always case-insensitive, operand matched literally: `contains`, `ncontains`, `startsWith`, `endsWith`. Pattern: `like`/`nlike` (case-sensitive), `ilike`/`nilike` (case-insensitive). **`*` is the only wildcard** and stands for any run of characters; `%`, `_`, and backslash match themselves. Use `like: "Hi*"`, not `like: "Hi%"`. A `select` column compares by option id and restricts its operators: single-select accepts `eq`, `ne`, `in`, `nin`; multi-select accepts `contains`, `ncontains`. Option names are accepted as operands and resolved to ids.'
11327
11279
  },
11328
11280
  data: {
11329
11281
  kind: "object",
@@ -11907,7 +11859,7 @@ function whoamiCommand() {
11907
11859
  });
11908
11860
  const exitCode = WHOAMI_EXIT_CODES[verification.status];
11909
11861
  if (exitCode !== 0)
11910
- setSoftExitCode(exitCode);
11862
+ process.exitCode = exitCode;
11911
11863
  });
11912
11864
  }
11913
11865
  var PROFILE_COLUMNS = [
@@ -12276,7 +12228,7 @@ var CLI_CONTRACT = {
12276
12228
  },
12277
12229
  deleteTableView: { confirm: "This deletes the saved view and its filters." },
12278
12230
  deleteWorkflowGroup: {
12279
- confirm: "This deletes the group AND its output columns with all of their row data; the workflow it pointed at is untouched.",
12231
+ confirm: "This deletes the group, every column it fed, and the values in them.",
12280
12232
  fields: [
12281
12233
  { header: "id" },
12282
12234
  { header: "deleted", format: "bool" },
@@ -12396,7 +12348,7 @@ var CLI_CONTRACT = {
12396
12348
  },
12397
12349
  applyWorkflowOperations: {
12398
12350
  command: "workflows operations apply",
12399
- confirm: "This edits the draft graph: the batch adds, edits, or deletes blocks and their edges as written.",
12351
+ confirm: "This edits the draft graph, and a delete operation removes blocks and their edges.",
12400
12352
  flags: {
12401
12353
  operations: { json: true, describe: WORKFLOW_OPERATIONS_HELP },
12402
12354
  setBlockEnabled: { json: true, describe: WORKFLOW_SET_BLOCK_ENABLED_HELP }
@@ -13105,6 +13057,24 @@ var CLI_CONTRACT = {
13105
13057
  describe: "Print a workflow as a portable JSON document",
13106
13058
  document: true
13107
13059
  },
13060
+ executeTool: {
13061
+ command: "tools execute",
13062
+ describe: "Run one built-in tool and print what it produced",
13063
+ flags: {
13064
+ input: {
13065
+ json: true,
13066
+ describe: "Tool arguments as JSON, keyed by the parameter ids `sim tools get <toolId>` lists"
13067
+ },
13068
+ credentialId: { describe: "Credential to authenticate with, required for OAuth tools" },
13069
+ timeoutSeconds: { name: "timeout", describe: "Seconds to wait before abandoning the call" }
13070
+ },
13071
+ fields: [
13072
+ { path: "toolId", header: "Tool" },
13073
+ { path: "status", header: "Status" },
13074
+ { path: "output", header: "Output" },
13075
+ { path: "error.message", header: "Error" }
13076
+ ]
13077
+ },
13108
13078
  executeWorkflow: {
13109
13079
  command: "workflows run",
13110
13080
  describe: "Run a deployed workflow or execute saved state manually",
@@ -13118,7 +13088,7 @@ var CLI_CONTRACT = {
13118
13088
  selectedOutputs: {
13119
13089
  name: "select-output",
13120
13090
  list: true,
13121
- describe: "Return blockName.path values (e.g. agent_1.content), or childWorkflowId.blockName.path for a child workflow (applies to every invocation) — in blockOutputs on a sync run, or from the streamed result with --follow; missing paths are omitted. Not available with --async"
13091
+ describe: "Return streamed outputs as blockName.path or childWorkflowId.blockName.path; selecting a child workflow applies to every invocation, requires --follow"
13122
13092
  },
13123
13093
  stream: { omit: true },
13124
13094
  includeThinking: { omit: true },
@@ -13142,7 +13112,7 @@ var CLI_CONTRACT = {
13142
13112
  selectedOutputs: {
13143
13113
  name: "select-output",
13144
13114
  list: true,
13145
- describe: "Include blockName.path or blockId.path values (e.g. agent_1.content) in JSON or YAML output; names resolve against the workflow’s current blocks, and missing paths are omitted"
13115
+ describe: "Include blockId or blockId.path values in JSON or YAML output; block names are not resolved on a finished run"
13146
13116
  }
13147
13117
  },
13148
13118
  fields: [
@@ -13336,13 +13306,6 @@ function readArgumentSource(raw, flagName) {
13336
13306
  return { text: raw.slice(1), from: "" };
13337
13307
  if (!raw.startsWith("@"))
13338
13308
  return { text: raw, from: "" };
13339
- const embedded = embedStore.getStore();
13340
- if (embedded) {
13341
- const preloaded = embedded.fileArguments?.[raw.slice(1)];
13342
- if (preloaded !== undefined)
13343
- return { text: preloaded, from: " (read from your machine)" };
13344
- throw new SimApiError(`--${flagName}: no file "${raw.slice(1)}" on this machine — write it first (run_code), or pass the value inline`, 0);
13345
- }
13346
13309
  const path = raw.slice(1);
13347
13310
  if (path === "-") {
13348
13311
  if (process.stdin.isTTY) {
@@ -13998,7 +13961,7 @@ function renderResult(operation, format, raw, spec, options = {}, envelope) {
13998
13961
  printDocument(format, raw);
13999
13962
  return;
14000
13963
  }
14001
- const data = format === "json" || format === "yaml" ? raw : unwrapResource(raw);
13964
+ const data = unwrapResource(raw);
14002
13965
  if (spec.itemsPath) {
14003
13966
  const items = at(data, spec.itemsPath);
14004
13967
  if (!Array.isArray(items)) {
@@ -14026,20 +13989,25 @@ function renderResult(operation, format, raw, spec, options = {}, envelope) {
14026
13989
  }
14027
13990
 
14028
13991
  // src/runtime/execute.ts
14029
- var RUN_OUTCOME_OPERATIONS = new Set(["executeWorkflow"]);
14030
- var FAILED_RUN_STATUS_MESSAGES = {
14031
- failed: "The workflow run failed.",
14032
- cancelled: "The workflow run was cancelled."
13992
+ var RUN_OUTCOME_OPERATIONS = {
13993
+ executeWorkflow: {
13994
+ failed: "The workflow run failed.",
13995
+ cancelled: "The workflow run was cancelled."
13996
+ },
13997
+ executeTool: {
13998
+ failed: "The tool call failed."
13999
+ }
14033
14000
  };
14034
14001
  function runFailureMessage(operation, payload) {
14035
- if (!RUN_OUTCOME_OPERATIONS.has(operation))
14002
+ const failureMessages = RUN_OUTCOME_OPERATIONS[operation];
14003
+ if (!failureMessages)
14036
14004
  return null;
14037
14005
  if (!payload || typeof payload !== "object" || Array.isArray(payload))
14038
14006
  return null;
14039
14007
  const { status, error } = payload;
14040
14008
  if (typeof status !== "string")
14041
14009
  return null;
14042
- const fallback = FAILED_RUN_STATUS_MESSAGES[status];
14010
+ const fallback = failureMessages[status];
14043
14011
  if (!fallback)
14044
14012
  return null;
14045
14013
  const reported2 = error?.message;
@@ -14112,22 +14080,6 @@ function countOf(value) {
14112
14080
  function lengthOf(value) {
14113
14081
  return Array.isArray(value) ? value.length : 0;
14114
14082
  }
14115
- var RESULT_NOTES = {
14116
- replaceWorkflowChatDeployment: (payload, body) => {
14117
- const authType = payload.authType ?? body?.authType ?? "public";
14118
- return authType === "public" ? "note: auth type is public — anyone with the link can chat; pass --auth-type password|email to restrict it." : null;
14119
- }
14120
- };
14121
- function writeResultNote(operation, payload, body) {
14122
- const note = RESULT_NOTES[operation];
14123
- if (!note)
14124
- return;
14125
- const record = payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
14126
- const message = note(record, body);
14127
- if (message)
14128
- process.stderr.write(source_default.dim(`${message}
14129
- `));
14130
- }
14131
14083
  function bulkFailureMessage(operation, payload, body) {
14132
14084
  const check = BULK_OUTCOME_CHECKS[operation];
14133
14085
  if (!check)
@@ -14253,7 +14205,6 @@ async function executeOperation(operation, commandSpec, operationSpec, invocatio
14253
14205
  });
14254
14206
  const payload = result?.data ?? result;
14255
14207
  renderResult(operation, profile.output, payload, commandSpec, { expandedTrace: requestFlags.trace === true }, result);
14256
- writeResultNote(operation, payload, request.body);
14257
14208
  const failure = runFailureMessage(operation, payload) ?? bulkFailureMessage(operation, payload, request.body);
14258
14209
  if (failure)
14259
14210
  throw new SimApiError(failure, 0);
@@ -15024,18 +14975,6 @@ async function saveStagedFile(body, target, force) {
15024
14975
  }
15025
14976
  }
15026
14977
  async function saveToFile(body, target, force) {
15027
- const embedded = embedStore.getStore();
15028
- if (embedded) {
15029
- if (!embedded.writeFile) {
15030
- throw new SimApiError(`--output-file cannot save ${target} here: this surface has no machine to write to. Read the file instead, or pipe a text command with | to-sandbox <name>.`, 0);
15031
- }
15032
- const bytes2 = new Uint8Array(await new Response(body).arrayBuffer());
15033
- const written = await embedded.writeFile(target, bytes2);
15034
- if (!written) {
15035
- throw new SimApiError(`Could not write ${target} on your machine — the workbench is not running yet; run any run_code call first, then retry.`, 0);
15036
- }
15037
- return;
15038
- }
15039
14978
  return saveStagedFile(body, target, force);
15040
14979
  }
15041
14980
  async function streamToStdout(body, output = process.stdout) {
@@ -15107,16 +15046,6 @@ function attachFileGet(files) {
15107
15046
  import { constants } from "node:fs";
15108
15047
  import { access, stat } from "node:fs/promises";
15109
15048
  import { basename } from "node:path";
15110
- function embeddedFileKey(path) {
15111
- return path.startsWith("@") ? path.slice(1) : path;
15112
- }
15113
- function embeddedFileContent(embedded, path) {
15114
- const key = embeddedFileKey(path);
15115
- const content = embedded.fileArguments?.[key];
15116
- if (content !== undefined)
15117
- return content;
15118
- throw new SimApiError(`Files on your machine are passed as @path: use @${key}. (If it does not exist yet, write it with run_code or | to-sandbox first.)`, 0);
15119
- }
15120
15049
  var CONTENT_TYPES = {
15121
15050
  css: "text/css",
15122
15051
  csv: "text/csv",
@@ -15150,14 +15079,6 @@ function contentTypeFor(name) {
15150
15079
  return CONTENT_TYPES[extension] ?? "application/octet-stream";
15151
15080
  }
15152
15081
  async function localFile(path, override) {
15153
- const embedded = embedStore.getStore();
15154
- if (embedded) {
15155
- const content = embeddedFileContent(embedded, path);
15156
- const size2 = Buffer.byteLength(content);
15157
- if (size2 === 0)
15158
- throw new SimApiError(`${path} is empty`, 0);
15159
- return { name: override ?? basename(embeddedFileKey(path)), size: size2 };
15160
- }
15161
15082
  let size;
15162
15083
  try {
15163
15084
  const stats = await stat(path);
@@ -15220,8 +15141,7 @@ async function uploadParts(client, workspaceId, session, transfer, blob) {
15220
15141
  }
15221
15142
  async function finishUploadSession(client, workspaceId, session, path) {
15222
15143
  try {
15223
- const embedded = embedStore.getStore();
15224
- const blob = embedded ? new Blob([embeddedFileContent(embedded, path)]) : await openAsBlob(path);
15144
+ const blob = await openAsBlob(path);
15225
15145
  if (session.transfer.method === "put") {
15226
15146
  await uploadPut(session.transfer, blob);
15227
15147
  } else {
@@ -15846,11 +15766,14 @@ var AGENT_STREAM_PROTOCOL_HEADER = "x-sim-stream-protocol";
15846
15766
  var AGENT_STREAM_PROTOCOL_V1 = "agent-events-v1";
15847
15767
  var DONE_SENTINEL = "[DONE]";
15848
15768
  function resolveWorkflowRunSelection(flags) {
15769
+ const manual = flags.manual === true;
15849
15770
  const trigger = typeof flags.trigger === "string" ? flags.trigger : undefined;
15850
15771
  const useMockPayload = flags.mockPayload === true;
15851
- const manual = flags.manual === true || trigger !== undefined || useMockPayload;
15852
15772
  const fromBlock = typeof flags.fromBlock === "string" ? flags.fromBlock : undefined;
15853
15773
  const sourceRun = typeof flags.sourceRun === "string" ? flags.sourceRun : undefined;
15774
+ if ((trigger || useMockPayload) && !manual) {
15775
+ throw new SimApiError("--trigger and --mock-payload require --manual", 0);
15776
+ }
15854
15777
  if (fromBlock && (trigger || useMockPayload)) {
15855
15778
  throw new SimApiError("--from-block cannot be combined with --trigger or --mock-payload", 0);
15856
15779
  }
@@ -16057,8 +15980,8 @@ function followOrDelegate(previous) {
16057
15980
  command.setOptionValue("run", selection);
16058
15981
  const flags = command.optsWithGlobals();
16059
15982
  if (flags.follow !== true) {
16060
- if (Array.isArray(flags.selectOutput) && flags.selectOutput.length > 0 && flags.async === true) {
16061
- throw new SimApiError("--select-output names outputs of a completed run, and --async returns as soon as the run is queued. Drop one of them, or read the finished run with: sim workflows runs get <runId> --workflow <workflowId> --select-output <blockId>[.path] — that resource matches block ids, not the block names --select-output takes here.", 0);
15983
+ if (Array.isArray(flags.selectOutput) && flags.selectOutput.length > 0) {
15984
+ throw new SimApiError(flags.async === true ? "--select-output shapes a streamed result, and --async returns as soon as the run is queued, so there is no stream to shape. Drop one of them, or read the finished run with: sim workflows runs get <runId> --workflow <workflowId> --select-output <blockId>[.path] — that resource matches block ids, not the block names --select-output takes here." : "--select-output shapes a streamed result; add --follow. To narrow a run that has already finished: sim workflows runs get <runId> --workflow <workflowId> --select-output <blockId>[.path] — that resource matches block ids, not the block names --select-output takes here.", 0);
16062
15985
  }
16063
15986
  if (flags.includeThinking === true || flags.includeToolCalls === true) {
16064
15987
  throw new SimApiError("--include-thinking and --include-tool-calls describe a stream; add --follow", 0);
@@ -16080,119 +16003,7 @@ function attachWorkflowRunFollow(workflows) {
16080
16003
  }
16081
16004
  const held = run._actionHandler;
16082
16005
  const previous = typeof held === "function" ? held : null;
16083
- run.option("--manual", "Run the current saved workflow state instead of the active deployment").option("--trigger <blockId>", "Enter the run through this runnable trigger; runs the current saved workflow state (implies --manual)").option("--mock-payload", "Use the selected trigger's server-derived mock payload; runs the current saved workflow state (implies --manual)").option("--from-block <blockId>", "Run manually from this saved workflow block").option("--source-run <runId>", "Prior run whose persisted state supplies upstream outputs (requires --from-block)").option("--follow", "Stream the run as it happens; progress on stderr, result on stdout. The stream reports only success and output, so the result omits the run id and timings a non-streaming run returns").option("--include-thinking", "Show model reasoning while following (requires --follow)").option("--include-tool-calls", "Show tool calls while following (requires --follow)").action(followOrDelegate(previous));
16084
- }
16085
-
16086
- // src/commands/protocol/workflow-run-get.ts
16087
- var BLOCK_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16088
- var SELECT_OUTPUT_FLAG = "select-output";
16089
- function normalizeBlockName(name) {
16090
- return name.toLowerCase().replace(/\s+/g, "").replace(/\./g, "");
16091
- }
16092
- function isRecord2(value) {
16093
- return typeof value === "object" && value !== null && !Array.isArray(value);
16094
- }
16095
- async function loadWorkflowBlocks(client, workflowId) {
16096
- const operation = V2_OPERATIONS.getWorkflowState;
16097
- const raw = await client.request(resolvePath(operation.path, { workflowId }), {
16098
- method: operation.method
16099
- });
16100
- const state = isRecord2(raw) && isRecord2(raw.data) ? raw.data : raw;
16101
- const blocks = isRecord2(state) && isRecord2(state.blocks) ? Object.entries(state.blocks) : [];
16102
- return blocks.map(([key, block]) => ({
16103
- id: isRecord2(block) && typeof block.id === "string" ? block.id : key,
16104
- name: isRecord2(block) && typeof block.name === "string" ? block.name : ""
16105
- }));
16106
- }
16107
- function splitSelector(selector) {
16108
- const dot = selector.indexOf(".");
16109
- return dot === -1 ? { head: selector, path: "" } : { head: selector.slice(0, dot), path: selector.slice(dot) };
16110
- }
16111
- function isIdHeaded(selector) {
16112
- return BLOCK_ID.test(splitSelector(selector).head);
16113
- }
16114
- function resolveSelection(typed, blocks, workflowId) {
16115
- const resolved = [];
16116
- const typedBy = new Map;
16117
- const unresolved = [];
16118
- for (const selector of typed) {
16119
- const { head, path } = splitSelector(selector);
16120
- let blockId = head;
16121
- if (!BLOCK_ID.test(head)) {
16122
- const wanted = normalizeBlockName(head);
16123
- const matches = blocks.filter((block) => block.id === head || normalizeBlockName(block.name) === wanted);
16124
- if (matches.length === 0) {
16125
- unresolved.push(selector);
16126
- continue;
16127
- }
16128
- if (matches.length > 1) {
16129
- throw new SimApiError(`--${SELECT_OUTPUT_FLAG} ${selector} names ${matches.length} blocks (${matches.map((block) => block.id).join(", ")}); pass the block id instead`, 0);
16130
- }
16131
- blockId = matches[0].id;
16132
- }
16133
- const rewritten = `${blockId}${path}`;
16134
- resolved.push(rewritten);
16135
- if (!typedBy.has(rewritten))
16136
- typedBy.set(rewritten, selector);
16137
- }
16138
- if (unresolved.length > 0) {
16139
- const names = blocks.map((block) => block.name).filter((name) => name !== "");
16140
- throw new SimApiError(`--${SELECT_OUTPUT_FLAG} did not resolve to any block on this run: ${unresolved.join(", ")}. Pass a block id or its name — "blockId", "blockId.path", "blockName" or "blockName.path"; names match ignoring case, spaces and dots. Blocks on workflow ${workflowId}: ${names.length > 0 ? names.join(", ") : "none"}.`, 0);
16141
- }
16142
- return { resolved, typedBy };
16143
- }
16144
- function keyByTyped(payload, typedBy) {
16145
- if (!isRecord2(payload) || !isRecord2(payload.blockOutputs))
16146
- return payload;
16147
- const blockOutputs = {};
16148
- for (const [key, value] of Object.entries(payload.blockOutputs)) {
16149
- blockOutputs[typedBy.get(key) ?? key] = value;
16150
- }
16151
- return { ...payload, blockOutputs };
16152
- }
16153
- async function readRunByName(runId, typed, command) {
16154
- const flags = command.optsWithGlobals();
16155
- const { client, profile } = clientFrom(command);
16156
- const operation = V2_OPERATIONS.getWorkflowRun;
16157
- const spec = CLI_CONTRACT.getWorkflowRun ?? {};
16158
- buildRequest("getWorkflowRun", [runId], flags, profile.workspaceId);
16159
- const workflowId = String(flags.workflow);
16160
- const selection = resolveSelection(typed, await loadWorkflowBlocks(client, workflowId), workflowId);
16161
- const request = buildRequest("getWorkflowRun", [runId], { ...flags, selectOutput: selection.resolved }, profile.workspaceId);
16162
- let result;
16163
- try {
16164
- result = await client.request(request.path, {
16165
- method: operation.method,
16166
- headers: request.headers,
16167
- query: request.query,
16168
- body: request.body
16169
- });
16170
- } catch (error) {
16171
- throw retypeApiError(error, "getWorkflowRun", spec, operation);
16172
- }
16173
- renderResult("getWorkflowRun", profile.output, keyByTyped(result?.data ?? result, selection.typedBy), spec, {}, result);
16174
- }
16175
- function attachWorkflowRunGet(runs) {
16176
- const get = runs.commands.find((command) => command.name() === "get");
16177
- const held = get?._actionHandler;
16178
- if (!get || typeof held !== "function") {
16179
- throw new Error("workflows runs get must be registered before block names can be attached to it");
16180
- }
16181
- const previous = held;
16182
- get.action(async (runId, _options, command) => {
16183
- const raw = command.optsWithGlobals().selectOutput;
16184
- if (raw === undefined) {
16185
- await previous(command.processedArgs);
16186
- return;
16187
- }
16188
- const typed = readListValues(raw, SELECT_OUTPUT_FLAG);
16189
- command.setOptionValue("selectOutput", typed);
16190
- if (typed.every(isIdHeaded)) {
16191
- await previous(command.processedArgs);
16192
- return;
16193
- }
16194
- await readRunByName(runId, typed, command);
16195
- });
16006
+ run.option("--manual", "Run the current saved workflow state instead of the active deployment").option("--trigger <blockId>", "Enter a manual run through this runnable trigger (requires --manual)").option("--mock-payload", "Use the selected trigger's server-derived mock payload (requires --manual)").option("--from-block <blockId>", "Run manually from this saved workflow block").option("--source-run <runId>", "Prior run whose persisted state supplies upstream outputs (requires --from-block)").option("--follow", "Stream the run as it happens; progress on stderr, result on stdout. The stream reports only success and output, so the result omits the run id and timings a non-streaming run returns").option("--include-thinking", "Show model reasoning while following (requires --follow)").option("--include-tool-calls", "Show tool calls while following (requires --follow)").action(followOrDelegate(previous));
16196
16007
  }
16197
16008
 
16198
16009
  // src/commands/protocol/workflow-run-wait.ts
@@ -16209,21 +16020,18 @@ var MAX_POLL_DELAY_MS = 15000;
16209
16020
  var POLL_BACKOFF_FACTOR = 2;
16210
16021
  var DEFAULT_WAIT_TIMEOUT_SECONDS = 3600;
16211
16022
  var WAIT_TIMEOUT_FLAG = "--wait-timeout <seconds>";
16212
- function isRecord3(value) {
16023
+ function isRecord2(value) {
16213
16024
  return typeof value === "object" && value !== null && !Array.isArray(value);
16214
16025
  }
16215
16026
  function optionalString(value) {
16216
16027
  return typeof value === "string" && value !== "" ? value : null;
16217
16028
  }
16218
- function runData(raw) {
16219
- return isRecord3(raw) && isRecord3(raw.data) ? raw.data : raw;
16220
- }
16221
16029
  function readRun(raw) {
16222
- const run = isRecord3(raw) && isRecord3(raw.data) ? raw.data : raw;
16223
- if (!isRecord3(run) || typeof run.status !== "string") {
16030
+ const run = isRecord2(raw) && isRecord2(raw.data) ? raw.data : raw;
16031
+ if (!isRecord2(run) || typeof run.status !== "string") {
16224
16032
  throw new SimApiError("Run status response carried no status.", 0);
16225
16033
  }
16226
- const paused = isRecord3(run.paused) ? run.paused : null;
16034
+ const paused = isRecord2(run.paused) ? run.paused : null;
16227
16035
  return {
16228
16036
  status: run.status,
16229
16037
  pauseKind: paused ? optionalString(paused.pauseKind) : null,
@@ -16292,19 +16100,19 @@ function attachWorkflowRunWait(runs) {
16292
16100
  const outcome = classify(snapshot);
16293
16101
  if (outcome) {
16294
16102
  progress.finish();
16295
- renderResult("getWorkflowRun", profile.output, runData(raw), runSpec());
16103
+ renderResult("getWorkflowRun", profile.output, raw, runSpec());
16296
16104
  const message = explain(outcome, runId, options.workflow, snapshot);
16297
16105
  if (message)
16298
16106
  console.error(source_default.red(message));
16299
- setSoftExitCode(WAIT_EXIT_CODES[outcome]);
16107
+ process.exitCode = WAIT_EXIT_CODES[outcome];
16300
16108
  return;
16301
16109
  }
16302
16110
  const remainingMs = deadline - Date.now();
16303
16111
  if (remainingMs <= 0) {
16304
16112
  progress.finish();
16305
- renderResult("getWorkflowRun", profile.output, runData(raw), runSpec());
16113
+ renderResult("getWorkflowRun", profile.output, raw, runSpec());
16306
16114
  console.error(source_default.red(`Timed out after ${timeoutSeconds}s waiting for run ${runId} (status: ${snapshot.status}${snapshot.resumeAt ? `, resuming at ${snapshot.resumeAt}` : ""}). Raise ${WAIT_TIMEOUT_FLAG}, or set it to 0 to wait indefinitely.`));
16307
- setSoftExitCode(WAIT_EXIT_CODES.timeout);
16115
+ process.exitCode = WAIT_EXIT_CODES.timeout;
16308
16116
  return;
16309
16117
  }
16310
16118
  progress.advance(snapshot.status, Date.now() - startedAt);
@@ -16360,9 +16168,7 @@ function attachProtocolCommands(program2) {
16360
16168
  createFolder: "createWorkflowFolder"
16361
16169
  });
16362
16170
  attachWorkflowRunFollow(workflows);
16363
- const runs = group(workflows, "runs");
16364
- attachWorkflowRunGet(runs);
16365
- attachWorkflowRunWait(runs);
16171
+ attachWorkflowRunWait(group(workflows, "runs"));
16366
16172
  attachLogsFollow(group(program2, "logs"));
16367
16173
  attachChat(program2);
16368
16174
  }
@@ -16590,7 +16396,7 @@ function addVersionOption(program2) {
16590
16396
  }
16591
16397
  program2.error("error: --version reports the Sim CLI version and takes no value. A command that acts on a deployment version reads it from --to-version.");
16592
16398
  });
16593
- program2.version(cliVersion(), "-V, --version [none]", "output the version number (takes no value)");
16399
+ program2.version(CLI_VERSION, "-V, --version [none]", "output the version number (takes no value)");
16594
16400
  }
16595
16401
  function buildProgram(options = {}) {
16596
16402
  const program2 = new Command;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sim",
3
- "version": "2.1.5-dev.81.1",
3
+ "version": "2.1.5",
4
4
  "description": "Sim CLI - talk to the Sim API from your terminal",
5
5
  "type": "module",
6
6
  "bin": {
@@ -57,11 +57,5 @@
57
57
  "@types/node": "24.2.1",
58
58
  "typescript": "^7.0.2",
59
59
  "vitest": "^4.1.0"
60
- },
61
- "exports": {
62
- "./embed": {
63
- "types": "./src/embed.ts",
64
- "default": "./src/embed.ts"
65
- }
66
60
  }
67
61
  }