sim 2.1.5 → 2.1.6-dev.85.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 +325 -117
- package/package.json +7 -1
package/dist/index.js
CHANGED
|
@@ -2314,6 +2314,30 @@ 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
|
+
|
|
2317
2341
|
// src/config/ini.ts
|
|
2318
2342
|
class ProfileConfigError extends Error {
|
|
2319
2343
|
constructor(message) {
|
|
@@ -2629,6 +2653,9 @@ function refuseBlankOverrides(overrides) {
|
|
|
2629
2653
|
}
|
|
2630
2654
|
}
|
|
2631
2655
|
function resolveProfile(overrides = {}) {
|
|
2656
|
+
const embedded = embeddedProfile();
|
|
2657
|
+
if (embedded)
|
|
2658
|
+
return embedded;
|
|
2632
2659
|
refuseBlankOverrides(overrides);
|
|
2633
2660
|
const named = overrides.profile || process.env.SIM_PROFILE;
|
|
2634
2661
|
const name = named || DEFAULT_PROFILE;
|
|
@@ -2681,14 +2708,22 @@ function resolveProfile(overrides = {}) {
|
|
|
2681
2708
|
// src/version.ts
|
|
2682
2709
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
2683
2710
|
function readPackageVersion() {
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
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})`;
|
|
2689
2726
|
}
|
|
2690
|
-
var CLI_VERSION = readPackageVersion();
|
|
2691
|
-
var USER_AGENT = `sim-cli/${CLI_VERSION} node/${process.versions.node} (${process.platform}; ${process.arch})`;
|
|
2692
2727
|
|
|
2693
2728
|
// src/http/environment.ts
|
|
2694
2729
|
var reported = new Set;
|
|
@@ -2971,7 +3006,7 @@ class SimClient {
|
|
|
2971
3006
|
headers: {
|
|
2972
3007
|
...apiKey ? { "x-api-key": apiKey } : {},
|
|
2973
3008
|
accept: "application/json",
|
|
2974
|
-
"user-agent":
|
|
3009
|
+
"user-agent": userAgent(),
|
|
2975
3010
|
...hasBody ? { "content-type": "application/json" } : {},
|
|
2976
3011
|
...options.headers
|
|
2977
3012
|
},
|
|
@@ -6470,7 +6505,7 @@ async function pollForKey(endpoint, auth, signal) {
|
|
|
6470
6505
|
headers: {
|
|
6471
6506
|
"content-type": "application/json",
|
|
6472
6507
|
accept: "application/json",
|
|
6473
|
-
"user-agent":
|
|
6508
|
+
"user-agent": userAgent()
|
|
6474
6509
|
},
|
|
6475
6510
|
body: JSON.stringify({ request: auth.request, verifier: auth.pollSecret }),
|
|
6476
6511
|
signal,
|
|
@@ -6631,8 +6666,8 @@ var V2_OPERATIONS = {
|
|
|
6631
6666
|
},
|
|
6632
6667
|
outputColumns: {
|
|
6633
6668
|
kind: "array",
|
|
6634
|
-
|
|
6635
|
-
describe: "Columns
|
|
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."
|
|
6636
6671
|
},
|
|
6637
6672
|
autoRun: {
|
|
6638
6673
|
kind: "boolean",
|
|
@@ -6936,7 +6971,7 @@ var V2_OPERATIONS = {
|
|
|
6936
6971
|
rowId: { kind: "string", describe: "Row whose runs should be canceled for row scope." },
|
|
6937
6972
|
filter: {
|
|
6938
6973
|
kind: "unknown",
|
|
6939
|
-
describe: '
|
|
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.'
|
|
6940
6975
|
},
|
|
6941
6976
|
excludeRowIds: { kind: "array", describe: "Rows excluded from an all-scope cancellation." }
|
|
6942
6977
|
}
|
|
@@ -6967,6 +7002,11 @@ var V2_OPERATIONS = {
|
|
|
6967
7002
|
conversationId: {
|
|
6968
7003
|
kind: "string",
|
|
6969
7004
|
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)."
|
|
6970
7010
|
}
|
|
6971
7011
|
}
|
|
6972
7012
|
},
|
|
@@ -7495,7 +7535,7 @@ var V2_OPERATIONS = {
|
|
|
7495
7535
|
description: { kind: "string", describe: "Optional credential description." },
|
|
7496
7536
|
id: {
|
|
7497
7537
|
kind: "string",
|
|
7498
|
-
describe: "
|
|
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."
|
|
7499
7539
|
},
|
|
7500
7540
|
credentials: {
|
|
7501
7541
|
kind: "string",
|
|
@@ -7571,7 +7611,7 @@ var V2_OPERATIONS = {
|
|
|
7571
7611
|
rowIds: { kind: "array", describe: "Explicit row subset to run." },
|
|
7572
7612
|
filter: {
|
|
7573
7613
|
kind: "unknown",
|
|
7574
|
-
describe: '
|
|
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.'
|
|
7575
7615
|
},
|
|
7576
7616
|
excludeRowIds: { kind: "array", describe: "Rows excluded from a select-all run scope." },
|
|
7577
7617
|
limit: { kind: "object", describe: "Optional cap on eligible rows to run." }
|
|
@@ -8093,7 +8133,7 @@ var V2_OPERATIONS = {
|
|
|
8093
8133
|
workspaceId: { kind: "string", required: true, describe: "Unique workspace identifier." },
|
|
8094
8134
|
filter: {
|
|
8095
8135
|
kind: "unknown",
|
|
8096
|
-
describe: '
|
|
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.'
|
|
8097
8137
|
},
|
|
8098
8138
|
limit: { kind: "integer", describe: "Maximum matching rows to delete." },
|
|
8099
8139
|
rowIds: { kind: "array", describe: "Explicit row identifiers to delete." }
|
|
@@ -8263,37 +8303,6 @@ var V2_OPERATIONS = {
|
|
|
8263
8303
|
}
|
|
8264
8304
|
}
|
|
8265
8305
|
},
|
|
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
|
-
},
|
|
8297
8306
|
executeWorkflow: {
|
|
8298
8307
|
method: "POST",
|
|
8299
8308
|
path: "/api/v2/workflows/[workflowId]/execute",
|
|
@@ -8326,7 +8335,7 @@ var V2_OPERATIONS = {
|
|
|
8326
8335
|
},
|
|
8327
8336
|
selectedOutputs: {
|
|
8328
8337
|
kind: "array",
|
|
8329
|
-
describe: "Block output references to include in
|
|
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."
|
|
8330
8339
|
},
|
|
8331
8340
|
includeThinking: {
|
|
8332
8341
|
kind: "boolean",
|
|
@@ -8364,7 +8373,13 @@ var V2_OPERATIONS = {
|
|
|
8364
8373
|
pathParams: ["workflowId"],
|
|
8365
8374
|
pathParamDocs: { workflowId: "Unique workflow identifier." },
|
|
8366
8375
|
responseMode: "json",
|
|
8367
|
-
summary: "Export Workflow"
|
|
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
|
+
}
|
|
8368
8383
|
},
|
|
8369
8384
|
getAuditLog: {
|
|
8370
8385
|
method: "GET",
|
|
@@ -8585,6 +8600,10 @@ var V2_OPERATIONS = {
|
|
|
8585
8600
|
values: ["info", "error"],
|
|
8586
8601
|
describe: "Severity level to include."
|
|
8587
8602
|
},
|
|
8603
|
+
includeHandledErrors: {
|
|
8604
|
+
kind: "boolean",
|
|
8605
|
+
describe: "Whether runs with a handled block error are counted as `handledErrorRuns`, and whether `level=error` also selects them. Off by default: counting them scans each run’s stored trace."
|
|
8606
|
+
},
|
|
8588
8607
|
startDate: {
|
|
8589
8608
|
kind: "string",
|
|
8590
8609
|
describe: "Only include runs started at or after this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant."
|
|
@@ -8596,7 +8615,26 @@ var V2_OPERATIONS = {
|
|
|
8596
8615
|
segmentCount: {
|
|
8597
8616
|
kind: "integer",
|
|
8598
8617
|
default: 72,
|
|
8599
|
-
describe: "Number of equal time buckets to divide the window into, from 1 to 500.
|
|
8618
|
+
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."
|
|
8619
|
+
},
|
|
8620
|
+
includeEmpty: {
|
|
8621
|
+
kind: "enum",
|
|
8622
|
+
values: [
|
|
8623
|
+
"true",
|
|
8624
|
+
"1",
|
|
8625
|
+
"yes",
|
|
8626
|
+
"on",
|
|
8627
|
+
"y",
|
|
8628
|
+
"enabled",
|
|
8629
|
+
"false",
|
|
8630
|
+
"0",
|
|
8631
|
+
"no",
|
|
8632
|
+
"off",
|
|
8633
|
+
"n",
|
|
8634
|
+
"disabled"
|
|
8635
|
+
],
|
|
8636
|
+
default: false,
|
|
8637
|
+
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."
|
|
8600
8638
|
}
|
|
8601
8639
|
}
|
|
8602
8640
|
},
|
|
@@ -8654,7 +8692,7 @@ var V2_OPERATIONS = {
|
|
|
8654
8692
|
groupId: "Workflow or enrichment group to run."
|
|
8655
8693
|
},
|
|
8656
8694
|
responseMode: "json",
|
|
8657
|
-
summary: "Get
|
|
8695
|
+
summary: "Get Row Group Run",
|
|
8658
8696
|
query: {
|
|
8659
8697
|
workspaceId: { kind: "string", required: true, describe: "Workspace that owns the table." }
|
|
8660
8698
|
}
|
|
@@ -8978,8 +9016,7 @@ var V2_OPERATIONS = {
|
|
|
8978
9016
|
"knowledge-base",
|
|
8979
9017
|
"voice-input",
|
|
8980
9018
|
"enrichment",
|
|
8981
|
-
"voice-output"
|
|
8982
|
-
"api-tool"
|
|
9019
|
+
"voice-output"
|
|
8983
9020
|
],
|
|
8984
9021
|
describe: "Restrict results to one usage source."
|
|
8985
9022
|
},
|
|
@@ -9043,6 +9080,10 @@ var V2_OPERATIONS = {
|
|
|
9043
9080
|
values: ["builtin", "custom"],
|
|
9044
9081
|
describe: "Restrict to shipped blocks or to this workspace’s deployed custom blocks."
|
|
9045
9082
|
},
|
|
9083
|
+
includeSunset: {
|
|
9084
|
+
kind: "boolean",
|
|
9085
|
+
describe: "Include `legacy` and `deprecated` blocks. Off by default: a sunset block keeps executing where it is already placed, but it is not offered for new authoring. Each returned entry carries `sunset.replacedBy`, the block to build with instead."
|
|
9086
|
+
},
|
|
9046
9087
|
sortBy: {
|
|
9047
9088
|
kind: "enum",
|
|
9048
9089
|
values: ["id", "name", "category"],
|
|
@@ -9118,6 +9159,21 @@ var V2_OPERATIONS = {
|
|
|
9118
9159
|
search: {
|
|
9119
9160
|
kind: "string",
|
|
9120
9161
|
describe: "Case-insensitive substring match against the connector name."
|
|
9162
|
+
},
|
|
9163
|
+
detail: {
|
|
9164
|
+
kind: "enum",
|
|
9165
|
+
values: ["summary", "full"],
|
|
9166
|
+
default: "summary",
|
|
9167
|
+
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."
|
|
9168
|
+
},
|
|
9169
|
+
limit: {
|
|
9170
|
+
kind: "integer",
|
|
9171
|
+
default: 25,
|
|
9172
|
+
describe: "Maximum connector types to return per page. Must be a whole number from 1 to 100. Defaults to 25."
|
|
9173
|
+
},
|
|
9174
|
+
cursor: {
|
|
9175
|
+
kind: "string",
|
|
9176
|
+
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."
|
|
9121
9177
|
}
|
|
9122
9178
|
}
|
|
9123
9179
|
},
|
|
@@ -9697,6 +9753,10 @@ var V2_OPERATIONS = {
|
|
|
9697
9753
|
kind: "string",
|
|
9698
9754
|
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."
|
|
9699
9755
|
},
|
|
9756
|
+
includeHandledErrors: {
|
|
9757
|
+
kind: "boolean",
|
|
9758
|
+
describe: "Whether `level=error` also selects runs that finished at `info` after a block error was recovered by an error path. Off by default: such a run succeeded, so it is an error only to a caller auditing error handling. Every row reports `hasHandledErrors` whether or not this is set. Job runs carry no block trace, so the flag never widens that branch."
|
|
9759
|
+
},
|
|
9700
9760
|
status: {
|
|
9701
9761
|
kind: "string",
|
|
9702
9762
|
describe: "Comma-separated execution statuses to include, from `pending` | `running` | `paused` | `redacting` | `completed` | `failed` | `cancelled`. An empty entry is rejected. ANDed with `level`, which reports severity rather than lifecycle."
|
|
@@ -9907,7 +9967,7 @@ var V2_OPERATIONS = {
|
|
|
9907
9967
|
pathParams: ["tableId"],
|
|
9908
9968
|
pathParamDocs: { tableId: "Unique table identifier." },
|
|
9909
9969
|
responseMode: "json",
|
|
9910
|
-
summary: "List
|
|
9970
|
+
summary: "List Run Dispatches",
|
|
9911
9971
|
query: {
|
|
9912
9972
|
workspaceId: { kind: "string", required: true, describe: "Workspace that owns the table." }
|
|
9913
9973
|
}
|
|
@@ -10319,8 +10379,8 @@ var V2_OPERATIONS = {
|
|
|
10319
10379
|
},
|
|
10320
10380
|
limit: {
|
|
10321
10381
|
kind: "integer",
|
|
10322
|
-
default:
|
|
10323
|
-
describe: "Maximum workspaces to return per page. Must be a whole number from 1 to 100. Defaults to
|
|
10382
|
+
default: 25,
|
|
10383
|
+
describe: "Maximum workspaces to return per page. Must be a whole number from 1 to 100. Defaults to 25."
|
|
10324
10384
|
},
|
|
10325
10385
|
cursor: {
|
|
10326
10386
|
kind: "string",
|
|
@@ -10455,7 +10515,7 @@ var V2_OPERATIONS = {
|
|
|
10455
10515
|
destinationPath: {
|
|
10456
10516
|
kind: "string",
|
|
10457
10517
|
required: true,
|
|
10458
|
-
describe: "
|
|
10518
|
+
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)."
|
|
10459
10519
|
}
|
|
10460
10520
|
}
|
|
10461
10521
|
},
|
|
@@ -10471,7 +10531,7 @@ var V2_OPERATIONS = {
|
|
|
10471
10531
|
destinationPath: {
|
|
10472
10532
|
kind: "string",
|
|
10473
10533
|
required: true,
|
|
10474
|
-
describe: "
|
|
10534
|
+
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)."
|
|
10475
10535
|
}
|
|
10476
10536
|
}
|
|
10477
10537
|
},
|
|
@@ -10487,7 +10547,7 @@ var V2_OPERATIONS = {
|
|
|
10487
10547
|
destinationPath: {
|
|
10488
10548
|
kind: "string",
|
|
10489
10549
|
required: true,
|
|
10490
|
-
describe: "
|
|
10550
|
+
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)."
|
|
10491
10551
|
}
|
|
10492
10552
|
}
|
|
10493
10553
|
},
|
|
@@ -10503,7 +10563,7 @@ var V2_OPERATIONS = {
|
|
|
10503
10563
|
destinationPath: {
|
|
10504
10564
|
kind: "string",
|
|
10505
10565
|
required: true,
|
|
10506
|
-
describe: "
|
|
10566
|
+
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)."
|
|
10507
10567
|
}
|
|
10508
10568
|
}
|
|
10509
10569
|
},
|
|
@@ -10833,7 +10893,7 @@ var V2_OPERATIONS = {
|
|
|
10833
10893
|
q: { kind: "string", required: true, describe: "Case-insensitive cell substring to find." },
|
|
10834
10894
|
predicate: {
|
|
10835
10895
|
kind: "unknown",
|
|
10836
|
-
describe: '
|
|
10896
|
+
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.'
|
|
10837
10897
|
},
|
|
10838
10898
|
sort: { kind: "array", describe: "Ordered table-row sort specification." }
|
|
10839
10899
|
}
|
|
@@ -11275,7 +11335,7 @@ var V2_OPERATIONS = {
|
|
|
11275
11335
|
filter: {
|
|
11276
11336
|
kind: "unknown",
|
|
11277
11337
|
required: true,
|
|
11278
|
-
describe: '
|
|
11338
|
+
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.'
|
|
11279
11339
|
},
|
|
11280
11340
|
data: {
|
|
11281
11341
|
kind: "object",
|
|
@@ -11859,7 +11919,7 @@ function whoamiCommand() {
|
|
|
11859
11919
|
});
|
|
11860
11920
|
const exitCode = WHOAMI_EXIT_CODES[verification.status];
|
|
11861
11921
|
if (exitCode !== 0)
|
|
11862
|
-
|
|
11922
|
+
setSoftExitCode(exitCode);
|
|
11863
11923
|
});
|
|
11864
11924
|
}
|
|
11865
11925
|
var PROFILE_COLUMNS = [
|
|
@@ -12228,7 +12288,7 @@ var CLI_CONTRACT = {
|
|
|
12228
12288
|
},
|
|
12229
12289
|
deleteTableView: { confirm: "This deletes the saved view and its filters." },
|
|
12230
12290
|
deleteWorkflowGroup: {
|
|
12231
|
-
confirm: "This deletes the group
|
|
12291
|
+
confirm: "This deletes the group AND its output columns with all of their row data; the workflow it pointed at is untouched.",
|
|
12232
12292
|
fields: [
|
|
12233
12293
|
{ header: "id" },
|
|
12234
12294
|
{ header: "deleted", format: "bool" },
|
|
@@ -12348,7 +12408,7 @@ var CLI_CONTRACT = {
|
|
|
12348
12408
|
},
|
|
12349
12409
|
applyWorkflowOperations: {
|
|
12350
12410
|
command: "workflows operations apply",
|
|
12351
|
-
confirm: "This edits the draft graph
|
|
12411
|
+
confirm: "This edits the draft graph: the batch adds, edits, or deletes blocks and their edges as written.",
|
|
12352
12412
|
flags: {
|
|
12353
12413
|
operations: { json: true, describe: WORKFLOW_OPERATIONS_HELP },
|
|
12354
12414
|
setBlockEnabled: { json: true, describe: WORKFLOW_SET_BLOCK_ENABLED_HELP }
|
|
@@ -13057,24 +13117,6 @@ var CLI_CONTRACT = {
|
|
|
13057
13117
|
describe: "Print a workflow as a portable JSON document",
|
|
13058
13118
|
document: true
|
|
13059
13119
|
},
|
|
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
|
-
},
|
|
13078
13120
|
executeWorkflow: {
|
|
13079
13121
|
command: "workflows run",
|
|
13080
13122
|
describe: "Run a deployed workflow or execute saved state manually",
|
|
@@ -13088,7 +13130,7 @@ var CLI_CONTRACT = {
|
|
|
13088
13130
|
selectedOutputs: {
|
|
13089
13131
|
name: "select-output",
|
|
13090
13132
|
list: true,
|
|
13091
|
-
describe: "Return
|
|
13133
|
+
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"
|
|
13092
13134
|
},
|
|
13093
13135
|
stream: { omit: true },
|
|
13094
13136
|
includeThinking: { omit: true },
|
|
@@ -13112,7 +13154,7 @@ var CLI_CONTRACT = {
|
|
|
13112
13154
|
selectedOutputs: {
|
|
13113
13155
|
name: "select-output",
|
|
13114
13156
|
list: true,
|
|
13115
|
-
describe: "Include
|
|
13157
|
+
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"
|
|
13116
13158
|
}
|
|
13117
13159
|
},
|
|
13118
13160
|
fields: [
|
|
@@ -13306,6 +13348,13 @@ function readArgumentSource(raw, flagName) {
|
|
|
13306
13348
|
return { text: raw.slice(1), from: "" };
|
|
13307
13349
|
if (!raw.startsWith("@"))
|
|
13308
13350
|
return { text: raw, from: "" };
|
|
13351
|
+
const embedded = embedStore.getStore();
|
|
13352
|
+
if (embedded) {
|
|
13353
|
+
const preloaded = embedded.fileArguments?.[raw.slice(1)];
|
|
13354
|
+
if (preloaded !== undefined)
|
|
13355
|
+
return { text: preloaded, from: " (read from your machine)" };
|
|
13356
|
+
throw new SimApiError(`--${flagName}: no file "${raw.slice(1)}" on this machine — write it first (run_code), or pass the value inline`, 0);
|
|
13357
|
+
}
|
|
13309
13358
|
const path = raw.slice(1);
|
|
13310
13359
|
if (path === "-") {
|
|
13311
13360
|
if (process.stdin.isTTY) {
|
|
@@ -13961,7 +14010,7 @@ function renderResult(operation, format, raw, spec, options = {}, envelope) {
|
|
|
13961
14010
|
printDocument(format, raw);
|
|
13962
14011
|
return;
|
|
13963
14012
|
}
|
|
13964
|
-
const data = unwrapResource(raw);
|
|
14013
|
+
const data = format === "json" || format === "yaml" ? raw : unwrapResource(raw);
|
|
13965
14014
|
if (spec.itemsPath) {
|
|
13966
14015
|
const items = at(data, spec.itemsPath);
|
|
13967
14016
|
if (!Array.isArray(items)) {
|
|
@@ -13989,25 +14038,20 @@ function renderResult(operation, format, raw, spec, options = {}, envelope) {
|
|
|
13989
14038
|
}
|
|
13990
14039
|
|
|
13991
14040
|
// src/runtime/execute.ts
|
|
13992
|
-
var RUN_OUTCOME_OPERATIONS =
|
|
13993
|
-
|
|
13994
|
-
|
|
13995
|
-
|
|
13996
|
-
},
|
|
13997
|
-
executeTool: {
|
|
13998
|
-
failed: "The tool call failed."
|
|
13999
|
-
}
|
|
14041
|
+
var RUN_OUTCOME_OPERATIONS = new Set(["executeWorkflow"]);
|
|
14042
|
+
var FAILED_RUN_STATUS_MESSAGES = {
|
|
14043
|
+
failed: "The workflow run failed.",
|
|
14044
|
+
cancelled: "The workflow run was cancelled."
|
|
14000
14045
|
};
|
|
14001
14046
|
function runFailureMessage(operation, payload) {
|
|
14002
|
-
|
|
14003
|
-
if (!failureMessages)
|
|
14047
|
+
if (!RUN_OUTCOME_OPERATIONS.has(operation))
|
|
14004
14048
|
return null;
|
|
14005
14049
|
if (!payload || typeof payload !== "object" || Array.isArray(payload))
|
|
14006
14050
|
return null;
|
|
14007
14051
|
const { status, error } = payload;
|
|
14008
14052
|
if (typeof status !== "string")
|
|
14009
14053
|
return null;
|
|
14010
|
-
const fallback =
|
|
14054
|
+
const fallback = FAILED_RUN_STATUS_MESSAGES[status];
|
|
14011
14055
|
if (!fallback)
|
|
14012
14056
|
return null;
|
|
14013
14057
|
const reported2 = error?.message;
|
|
@@ -14080,6 +14124,22 @@ function countOf(value) {
|
|
|
14080
14124
|
function lengthOf(value) {
|
|
14081
14125
|
return Array.isArray(value) ? value.length : 0;
|
|
14082
14126
|
}
|
|
14127
|
+
var RESULT_NOTES = {
|
|
14128
|
+
replaceWorkflowChatDeployment: (payload, body) => {
|
|
14129
|
+
const authType = payload.authType ?? body?.authType ?? "public";
|
|
14130
|
+
return authType === "public" ? "note: auth type is public — anyone with the link can chat; pass --auth-type password|email to restrict it." : null;
|
|
14131
|
+
}
|
|
14132
|
+
};
|
|
14133
|
+
function writeResultNote(operation, payload, body) {
|
|
14134
|
+
const note = RESULT_NOTES[operation];
|
|
14135
|
+
if (!note)
|
|
14136
|
+
return;
|
|
14137
|
+
const record = payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
|
|
14138
|
+
const message = note(record, body);
|
|
14139
|
+
if (message)
|
|
14140
|
+
process.stderr.write(source_default.dim(`${message}
|
|
14141
|
+
`));
|
|
14142
|
+
}
|
|
14083
14143
|
function bulkFailureMessage(operation, payload, body) {
|
|
14084
14144
|
const check = BULK_OUTCOME_CHECKS[operation];
|
|
14085
14145
|
if (!check)
|
|
@@ -14205,6 +14265,7 @@ async function executeOperation(operation, commandSpec, operationSpec, invocatio
|
|
|
14205
14265
|
});
|
|
14206
14266
|
const payload = result?.data ?? result;
|
|
14207
14267
|
renderResult(operation, profile.output, payload, commandSpec, { expandedTrace: requestFlags.trace === true }, result);
|
|
14268
|
+
writeResultNote(operation, payload, request.body);
|
|
14208
14269
|
const failure = runFailureMessage(operation, payload) ?? bulkFailureMessage(operation, payload, request.body);
|
|
14209
14270
|
if (failure)
|
|
14210
14271
|
throw new SimApiError(failure, 0);
|
|
@@ -14975,6 +15036,18 @@ async function saveStagedFile(body, target, force) {
|
|
|
14975
15036
|
}
|
|
14976
15037
|
}
|
|
14977
15038
|
async function saveToFile(body, target, force) {
|
|
15039
|
+
const embedded = embedStore.getStore();
|
|
15040
|
+
if (embedded) {
|
|
15041
|
+
if (!embedded.writeFile) {
|
|
15042
|
+
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);
|
|
15043
|
+
}
|
|
15044
|
+
const bytes2 = new Uint8Array(await new Response(body).arrayBuffer());
|
|
15045
|
+
const written = await embedded.writeFile(target, bytes2);
|
|
15046
|
+
if (!written) {
|
|
15047
|
+
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);
|
|
15048
|
+
}
|
|
15049
|
+
return;
|
|
15050
|
+
}
|
|
14978
15051
|
return saveStagedFile(body, target, force);
|
|
14979
15052
|
}
|
|
14980
15053
|
async function streamToStdout(body, output = process.stdout) {
|
|
@@ -15046,6 +15119,16 @@ function attachFileGet(files) {
|
|
|
15046
15119
|
import { constants } from "node:fs";
|
|
15047
15120
|
import { access, stat } from "node:fs/promises";
|
|
15048
15121
|
import { basename } from "node:path";
|
|
15122
|
+
function embeddedFileKey(path) {
|
|
15123
|
+
return path.startsWith("@") ? path.slice(1) : path;
|
|
15124
|
+
}
|
|
15125
|
+
function embeddedFileContent(embedded, path) {
|
|
15126
|
+
const key = embeddedFileKey(path);
|
|
15127
|
+
const content = embedded.fileArguments?.[key];
|
|
15128
|
+
if (content !== undefined)
|
|
15129
|
+
return content;
|
|
15130
|
+
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);
|
|
15131
|
+
}
|
|
15049
15132
|
var CONTENT_TYPES = {
|
|
15050
15133
|
css: "text/css",
|
|
15051
15134
|
csv: "text/csv",
|
|
@@ -15079,6 +15162,14 @@ function contentTypeFor(name) {
|
|
|
15079
15162
|
return CONTENT_TYPES[extension] ?? "application/octet-stream";
|
|
15080
15163
|
}
|
|
15081
15164
|
async function localFile(path, override) {
|
|
15165
|
+
const embedded = embedStore.getStore();
|
|
15166
|
+
if (embedded) {
|
|
15167
|
+
const content = embeddedFileContent(embedded, path);
|
|
15168
|
+
const size2 = Buffer.byteLength(content);
|
|
15169
|
+
if (size2 === 0)
|
|
15170
|
+
throw new SimApiError(`${path} is empty`, 0);
|
|
15171
|
+
return { name: override ?? basename(embeddedFileKey(path)), size: size2 };
|
|
15172
|
+
}
|
|
15082
15173
|
let size;
|
|
15083
15174
|
try {
|
|
15084
15175
|
const stats = await stat(path);
|
|
@@ -15141,7 +15232,8 @@ async function uploadParts(client, workspaceId, session, transfer, blob) {
|
|
|
15141
15232
|
}
|
|
15142
15233
|
async function finishUploadSession(client, workspaceId, session, path) {
|
|
15143
15234
|
try {
|
|
15144
|
-
const
|
|
15235
|
+
const embedded = embedStore.getStore();
|
|
15236
|
+
const blob = embedded ? new Blob([embeddedFileContent(embedded, path)]) : await openAsBlob(path);
|
|
15145
15237
|
if (session.transfer.method === "put") {
|
|
15146
15238
|
await uploadPut(session.transfer, blob);
|
|
15147
15239
|
} else {
|
|
@@ -15247,9 +15339,11 @@ function attachKnowledgeDocumentUpload(documents) {
|
|
|
15247
15339
|
printProtocolResult(profile.output, {
|
|
15248
15340
|
id: completed.document.id,
|
|
15249
15341
|
knowledgeBaseId: completed.document.knowledgeBaseId,
|
|
15250
|
-
|
|
15251
|
-
|
|
15252
|
-
|
|
15342
|
+
filename: completed.document.filename,
|
|
15343
|
+
fileSize: completed.document.fileSize,
|
|
15344
|
+
mimeType: completed.document.mimeType,
|
|
15345
|
+
processingStatus: completed.document.processingStatus,
|
|
15346
|
+
chunkCount: completed.document.chunkCount
|
|
15253
15347
|
});
|
|
15254
15348
|
});
|
|
15255
15349
|
}
|
|
@@ -15766,14 +15860,11 @@ var AGENT_STREAM_PROTOCOL_HEADER = "x-sim-stream-protocol";
|
|
|
15766
15860
|
var AGENT_STREAM_PROTOCOL_V1 = "agent-events-v1";
|
|
15767
15861
|
var DONE_SENTINEL = "[DONE]";
|
|
15768
15862
|
function resolveWorkflowRunSelection(flags) {
|
|
15769
|
-
const manual = flags.manual === true;
|
|
15770
15863
|
const trigger = typeof flags.trigger === "string" ? flags.trigger : undefined;
|
|
15771
15864
|
const useMockPayload = flags.mockPayload === true;
|
|
15865
|
+
const manual = flags.manual === true || trigger !== undefined || useMockPayload;
|
|
15772
15866
|
const fromBlock = typeof flags.fromBlock === "string" ? flags.fromBlock : undefined;
|
|
15773
15867
|
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
|
-
}
|
|
15777
15868
|
if (fromBlock && (trigger || useMockPayload)) {
|
|
15778
15869
|
throw new SimApiError("--from-block cannot be combined with --trigger or --mock-payload", 0);
|
|
15779
15870
|
}
|
|
@@ -15980,8 +16071,8 @@ function followOrDelegate(previous) {
|
|
|
15980
16071
|
command.setOptionValue("run", selection);
|
|
15981
16072
|
const flags = command.optsWithGlobals();
|
|
15982
16073
|
if (flags.follow !== true) {
|
|
15983
|
-
if (Array.isArray(flags.selectOutput) && flags.selectOutput.length > 0) {
|
|
15984
|
-
throw new SimApiError(
|
|
16074
|
+
if (Array.isArray(flags.selectOutput) && flags.selectOutput.length > 0 && flags.async === true) {
|
|
16075
|
+
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);
|
|
15985
16076
|
}
|
|
15986
16077
|
if (flags.includeThinking === true || flags.includeToolCalls === true) {
|
|
15987
16078
|
throw new SimApiError("--include-thinking and --include-tool-calls describe a stream; add --follow", 0);
|
|
@@ -16003,7 +16094,119 @@ function attachWorkflowRunFollow(workflows) {
|
|
|
16003
16094
|
}
|
|
16004
16095
|
const held = run._actionHandler;
|
|
16005
16096
|
const previous = typeof held === "function" ? held : null;
|
|
16006
|
-
run.option("--manual", "Run the current saved workflow state instead of the active deployment").option("--trigger <blockId>", "Enter
|
|
16097
|
+
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));
|
|
16098
|
+
}
|
|
16099
|
+
|
|
16100
|
+
// src/commands/protocol/workflow-run-get.ts
|
|
16101
|
+
var BLOCK_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
16102
|
+
var SELECT_OUTPUT_FLAG = "select-output";
|
|
16103
|
+
function normalizeBlockName(name) {
|
|
16104
|
+
return name.toLowerCase().replace(/\s+/g, "").replace(/\./g, "");
|
|
16105
|
+
}
|
|
16106
|
+
function isRecord2(value) {
|
|
16107
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16108
|
+
}
|
|
16109
|
+
async function loadWorkflowBlocks(client, workflowId) {
|
|
16110
|
+
const operation = V2_OPERATIONS.getWorkflowState;
|
|
16111
|
+
const raw = await client.request(resolvePath(operation.path, { workflowId }), {
|
|
16112
|
+
method: operation.method
|
|
16113
|
+
});
|
|
16114
|
+
const state = isRecord2(raw) && isRecord2(raw.data) ? raw.data : raw;
|
|
16115
|
+
const blocks = isRecord2(state) && isRecord2(state.blocks) ? Object.entries(state.blocks) : [];
|
|
16116
|
+
return blocks.map(([key, block]) => ({
|
|
16117
|
+
id: isRecord2(block) && typeof block.id === "string" ? block.id : key,
|
|
16118
|
+
name: isRecord2(block) && typeof block.name === "string" ? block.name : ""
|
|
16119
|
+
}));
|
|
16120
|
+
}
|
|
16121
|
+
function splitSelector(selector) {
|
|
16122
|
+
const dot = selector.indexOf(".");
|
|
16123
|
+
return dot === -1 ? { head: selector, path: "" } : { head: selector.slice(0, dot), path: selector.slice(dot) };
|
|
16124
|
+
}
|
|
16125
|
+
function isIdHeaded(selector) {
|
|
16126
|
+
return BLOCK_ID.test(splitSelector(selector).head);
|
|
16127
|
+
}
|
|
16128
|
+
function resolveSelection(typed, blocks, workflowId) {
|
|
16129
|
+
const resolved = [];
|
|
16130
|
+
const typedBy = new Map;
|
|
16131
|
+
const unresolved = [];
|
|
16132
|
+
for (const selector of typed) {
|
|
16133
|
+
const { head, path } = splitSelector(selector);
|
|
16134
|
+
let blockId = head;
|
|
16135
|
+
if (!BLOCK_ID.test(head)) {
|
|
16136
|
+
const wanted = normalizeBlockName(head);
|
|
16137
|
+
const matches = blocks.filter((block) => block.id === head || normalizeBlockName(block.name) === wanted);
|
|
16138
|
+
if (matches.length === 0) {
|
|
16139
|
+
unresolved.push(selector);
|
|
16140
|
+
continue;
|
|
16141
|
+
}
|
|
16142
|
+
if (matches.length > 1) {
|
|
16143
|
+
throw new SimApiError(`--${SELECT_OUTPUT_FLAG} ${selector} names ${matches.length} blocks (${matches.map((block) => block.id).join(", ")}); pass the block id instead`, 0);
|
|
16144
|
+
}
|
|
16145
|
+
blockId = matches[0].id;
|
|
16146
|
+
}
|
|
16147
|
+
const rewritten = `${blockId}${path}`;
|
|
16148
|
+
resolved.push(rewritten);
|
|
16149
|
+
if (!typedBy.has(rewritten))
|
|
16150
|
+
typedBy.set(rewritten, selector);
|
|
16151
|
+
}
|
|
16152
|
+
if (unresolved.length > 0) {
|
|
16153
|
+
const names = blocks.map((block) => block.name).filter((name) => name !== "");
|
|
16154
|
+
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);
|
|
16155
|
+
}
|
|
16156
|
+
return { resolved, typedBy };
|
|
16157
|
+
}
|
|
16158
|
+
function keyByTyped(payload, typedBy) {
|
|
16159
|
+
if (!isRecord2(payload) || !isRecord2(payload.blockOutputs))
|
|
16160
|
+
return payload;
|
|
16161
|
+
const blockOutputs = {};
|
|
16162
|
+
for (const [key, value] of Object.entries(payload.blockOutputs)) {
|
|
16163
|
+
blockOutputs[typedBy.get(key) ?? key] = value;
|
|
16164
|
+
}
|
|
16165
|
+
return { ...payload, blockOutputs };
|
|
16166
|
+
}
|
|
16167
|
+
async function readRunByName(runId, typed, command) {
|
|
16168
|
+
const flags = command.optsWithGlobals();
|
|
16169
|
+
const { client, profile } = clientFrom(command);
|
|
16170
|
+
const operation = V2_OPERATIONS.getWorkflowRun;
|
|
16171
|
+
const spec = CLI_CONTRACT.getWorkflowRun ?? {};
|
|
16172
|
+
buildRequest("getWorkflowRun", [runId], flags, profile.workspaceId);
|
|
16173
|
+
const workflowId = String(flags.workflow);
|
|
16174
|
+
const selection = resolveSelection(typed, await loadWorkflowBlocks(client, workflowId), workflowId);
|
|
16175
|
+
const request = buildRequest("getWorkflowRun", [runId], { ...flags, selectOutput: selection.resolved }, profile.workspaceId);
|
|
16176
|
+
let result;
|
|
16177
|
+
try {
|
|
16178
|
+
result = await client.request(request.path, {
|
|
16179
|
+
method: operation.method,
|
|
16180
|
+
headers: request.headers,
|
|
16181
|
+
query: request.query,
|
|
16182
|
+
body: request.body
|
|
16183
|
+
});
|
|
16184
|
+
} catch (error) {
|
|
16185
|
+
throw retypeApiError(error, "getWorkflowRun", spec, operation);
|
|
16186
|
+
}
|
|
16187
|
+
renderResult("getWorkflowRun", profile.output, keyByTyped(result?.data ?? result, selection.typedBy), spec, {}, result);
|
|
16188
|
+
}
|
|
16189
|
+
function attachWorkflowRunGet(runs) {
|
|
16190
|
+
const get = runs.commands.find((command) => command.name() === "get");
|
|
16191
|
+
const held = get?._actionHandler;
|
|
16192
|
+
if (!get || typeof held !== "function") {
|
|
16193
|
+
throw new Error("workflows runs get must be registered before block names can be attached to it");
|
|
16194
|
+
}
|
|
16195
|
+
const previous = held;
|
|
16196
|
+
get.action(async (runId, _options, command) => {
|
|
16197
|
+
const raw = command.optsWithGlobals().selectOutput;
|
|
16198
|
+
if (raw === undefined) {
|
|
16199
|
+
await previous(command.processedArgs);
|
|
16200
|
+
return;
|
|
16201
|
+
}
|
|
16202
|
+
const typed = readListValues(raw, SELECT_OUTPUT_FLAG);
|
|
16203
|
+
command.setOptionValue("selectOutput", typed);
|
|
16204
|
+
if (typed.every(isIdHeaded)) {
|
|
16205
|
+
await previous(command.processedArgs);
|
|
16206
|
+
return;
|
|
16207
|
+
}
|
|
16208
|
+
await readRunByName(runId, typed, command);
|
|
16209
|
+
});
|
|
16007
16210
|
}
|
|
16008
16211
|
|
|
16009
16212
|
// src/commands/protocol/workflow-run-wait.ts
|
|
@@ -16020,18 +16223,21 @@ var MAX_POLL_DELAY_MS = 15000;
|
|
|
16020
16223
|
var POLL_BACKOFF_FACTOR = 2;
|
|
16021
16224
|
var DEFAULT_WAIT_TIMEOUT_SECONDS = 3600;
|
|
16022
16225
|
var WAIT_TIMEOUT_FLAG = "--wait-timeout <seconds>";
|
|
16023
|
-
function
|
|
16226
|
+
function isRecord3(value) {
|
|
16024
16227
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16025
16228
|
}
|
|
16026
16229
|
function optionalString(value) {
|
|
16027
16230
|
return typeof value === "string" && value !== "" ? value : null;
|
|
16028
16231
|
}
|
|
16232
|
+
function runData(raw) {
|
|
16233
|
+
return isRecord3(raw) && isRecord3(raw.data) ? raw.data : raw;
|
|
16234
|
+
}
|
|
16029
16235
|
function readRun(raw) {
|
|
16030
|
-
const run =
|
|
16031
|
-
if (!
|
|
16236
|
+
const run = isRecord3(raw) && isRecord3(raw.data) ? raw.data : raw;
|
|
16237
|
+
if (!isRecord3(run) || typeof run.status !== "string") {
|
|
16032
16238
|
throw new SimApiError("Run status response carried no status.", 0);
|
|
16033
16239
|
}
|
|
16034
|
-
const paused =
|
|
16240
|
+
const paused = isRecord3(run.paused) ? run.paused : null;
|
|
16035
16241
|
return {
|
|
16036
16242
|
status: run.status,
|
|
16037
16243
|
pauseKind: paused ? optionalString(paused.pauseKind) : null,
|
|
@@ -16100,19 +16306,19 @@ function attachWorkflowRunWait(runs) {
|
|
|
16100
16306
|
const outcome = classify(snapshot);
|
|
16101
16307
|
if (outcome) {
|
|
16102
16308
|
progress.finish();
|
|
16103
|
-
renderResult("getWorkflowRun", profile.output, raw, runSpec());
|
|
16309
|
+
renderResult("getWorkflowRun", profile.output, runData(raw), runSpec());
|
|
16104
16310
|
const message = explain(outcome, runId, options.workflow, snapshot);
|
|
16105
16311
|
if (message)
|
|
16106
16312
|
console.error(source_default.red(message));
|
|
16107
|
-
|
|
16313
|
+
setSoftExitCode(WAIT_EXIT_CODES[outcome]);
|
|
16108
16314
|
return;
|
|
16109
16315
|
}
|
|
16110
16316
|
const remainingMs = deadline - Date.now();
|
|
16111
16317
|
if (remainingMs <= 0) {
|
|
16112
16318
|
progress.finish();
|
|
16113
|
-
renderResult("getWorkflowRun", profile.output, raw, runSpec());
|
|
16319
|
+
renderResult("getWorkflowRun", profile.output, runData(raw), runSpec());
|
|
16114
16320
|
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.`));
|
|
16115
|
-
|
|
16321
|
+
setSoftExitCode(WAIT_EXIT_CODES.timeout);
|
|
16116
16322
|
return;
|
|
16117
16323
|
}
|
|
16118
16324
|
progress.advance(snapshot.status, Date.now() - startedAt);
|
|
@@ -16168,7 +16374,9 @@ function attachProtocolCommands(program2) {
|
|
|
16168
16374
|
createFolder: "createWorkflowFolder"
|
|
16169
16375
|
});
|
|
16170
16376
|
attachWorkflowRunFollow(workflows);
|
|
16171
|
-
|
|
16377
|
+
const runs = group(workflows, "runs");
|
|
16378
|
+
attachWorkflowRunGet(runs);
|
|
16379
|
+
attachWorkflowRunWait(runs);
|
|
16172
16380
|
attachLogsFollow(group(program2, "logs"));
|
|
16173
16381
|
attachChat(program2);
|
|
16174
16382
|
}
|
|
@@ -16396,7 +16604,7 @@ function addVersionOption(program2) {
|
|
|
16396
16604
|
}
|
|
16397
16605
|
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.");
|
|
16398
16606
|
});
|
|
16399
|
-
program2.version(
|
|
16607
|
+
program2.version(cliVersion(), "-V, --version [none]", "output the version number (takes no value)");
|
|
16400
16608
|
}
|
|
16401
16609
|
function buildProgram(options = {}) {
|
|
16402
16610
|
const program2 = new Command;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sim",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.6-dev.85.1",
|
|
4
4
|
"description": "Sim CLI - talk to the Sim API from your terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -57,5 +57,11 @@
|
|
|
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
|
+
}
|
|
60
66
|
}
|
|
61
67
|
}
|