@withone/cli 1.47.0 → 1.47.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/{chunk-Q3OY2F6W.js → chunk-HS5AHQ4V.js} +9 -0
- package/dist/{chunk-5NLP47QP.js → chunk-IFTHWFLL.js} +13 -5
- package/dist/{chunk-4RZSK5LD.js → chunk-PLMFRFTT.js} +1 -1
- package/dist/{chunk-CESNNUKJ.js → chunk-QV3Y5N5G.js} +1 -1
- package/dist/{flow-runner-UWIM4Z2Y.js → flow-runner-7YOPMXWO.js} +1 -1
- package/dist/index.js +40 -16
- package/dist/{migrate-DHZ3SI65.js → migrate-UDEANXEZ.js} +2 -2
- package/dist/{sql-5XR53LV5.js → sql-W3ZUOUNR.js} +2 -2
- package/package.json +1 -1
- package/skills/one/references/flows.md +4 -0
package/README.md
CHANGED
|
@@ -488,6 +488,9 @@ Press Ctrl+C during execution to pause - the run can be resumed later with `one
|
|
|
488
488
|
| `--skip-validation` | Skip input validation against action schemas |
|
|
489
489
|
| `--allow-bash` | Allow bash step execution (disabled by default for security) |
|
|
490
490
|
| `-v, --verbose` | Show full request/response for each step |
|
|
491
|
+
| `--output-file <path>` | Stream the full result to a file instead of stdout — for large results that would otherwise be truncated or exceed the JSON string-size limit. stdout (and `--agent` output) then carries an `outputFile` pointer instead of inline `steps`. |
|
|
492
|
+
|
|
493
|
+
Step-level `if`/`unless` conditions (and `while`/`condition` steps) are null-safe: a condition that references a skipped or not-yet-run step's output (e.g. `$.steps.maybeSkipped.output.x`) evaluates to `false` rather than crashing the run.
|
|
491
494
|
|
|
492
495
|
### `one flow list`
|
|
493
496
|
|
|
@@ -15,6 +15,14 @@ function setAgentMode(value) {
|
|
|
15
15
|
function isAgentMode() {
|
|
16
16
|
return _agentMode || process.env.ONE_AGENT === "1";
|
|
17
17
|
}
|
|
18
|
+
function silenceWarningsInAgentMode() {
|
|
19
|
+
const agent = process.argv.includes("--agent") || process.env.ONE_AGENT === "1";
|
|
20
|
+
if (!agent) return;
|
|
21
|
+
process.env.NODE_NO_WARNINGS = "1";
|
|
22
|
+
process.removeAllListeners("warning");
|
|
23
|
+
process.emitWarning = (() => {
|
|
24
|
+
});
|
|
25
|
+
}
|
|
18
26
|
function createSpinner() {
|
|
19
27
|
if (isAgentMode()) {
|
|
20
28
|
return { start() {
|
|
@@ -141,6 +149,7 @@ function semanticSearchUpgradeLine(opts = {}) {
|
|
|
141
149
|
export {
|
|
142
150
|
setAgentMode,
|
|
143
151
|
isAgentMode,
|
|
152
|
+
silenceWarningsInAgentMode,
|
|
144
153
|
createSpinner,
|
|
145
154
|
intro2 as intro,
|
|
146
155
|
outro2 as outro,
|
|
@@ -902,6 +902,14 @@ function evaluateExpression(expr, context) {
|
|
|
902
902
|
const fn = new Function("$", `return (${expr})`);
|
|
903
903
|
return fn(context);
|
|
904
904
|
}
|
|
905
|
+
function evaluateCondition(expr, context) {
|
|
906
|
+
try {
|
|
907
|
+
return Boolean(evaluateExpression(expr, context));
|
|
908
|
+
} catch (err) {
|
|
909
|
+
if (err instanceof TypeError) return false;
|
|
910
|
+
throw err;
|
|
911
|
+
}
|
|
912
|
+
}
|
|
905
913
|
var ALLOWED_MODULES = {
|
|
906
914
|
buffer: () => import("buffer"),
|
|
907
915
|
crypto: () => import("crypto"),
|
|
@@ -1106,7 +1114,7 @@ async function executeCodeModule(stepId, modulePath, context, options) {
|
|
|
1106
1114
|
}
|
|
1107
1115
|
async function executeConditionStep(step, context, api, permissions, allowedActionIds, options, flowStack) {
|
|
1108
1116
|
const condition = step.condition;
|
|
1109
|
-
const result =
|
|
1117
|
+
const result = evaluateCondition(condition.expression, context);
|
|
1110
1118
|
const branch = result ? condition.then : condition.else || [];
|
|
1111
1119
|
const branchResults = await executeSteps(branch, context, api, permissions, allowedActionIds, options, void 0, flowStack);
|
|
1112
1120
|
return {
|
|
@@ -1246,7 +1254,7 @@ async function executeWhileStep(step, context, api, permissions, allowedActionId
|
|
|
1246
1254
|
};
|
|
1247
1255
|
for (let iteration = 0; iteration < maxIterations; iteration++) {
|
|
1248
1256
|
if (iteration > 0) {
|
|
1249
|
-
const conditionResult =
|
|
1257
|
+
const conditionResult = evaluateCondition(config.condition, context);
|
|
1250
1258
|
if (!conditionResult) break;
|
|
1251
1259
|
}
|
|
1252
1260
|
await executeSteps(config.steps, context, api, permissions, allowedActionIds, options, void 0, flowStack);
|
|
@@ -1271,7 +1279,7 @@ async function executeSubflowStep(step, context, api, permissions, allowedAction
|
|
|
1271
1279
|
if (flowStack.includes(resolvedKey)) {
|
|
1272
1280
|
throw new Error(`Circular flow detected: ${[...flowStack, resolvedKey].join(" \u2192 ")}`);
|
|
1273
1281
|
}
|
|
1274
|
-
const { loadFlowWithMeta: loadFlowWithMeta2 } = await import("./flow-runner-
|
|
1282
|
+
const { loadFlowWithMeta: loadFlowWithMeta2 } = await import("./flow-runner-7YOPMXWO.js");
|
|
1275
1283
|
const { flow: subFlow, rootDir: subRootDir } = loadFlowWithMeta2(resolvedKey);
|
|
1276
1284
|
const subContext = await executeFlow(
|
|
1277
1285
|
subFlow,
|
|
@@ -1468,7 +1476,7 @@ function checkRequires(step, context) {
|
|
|
1468
1476
|
}
|
|
1469
1477
|
async function executeSingleStep(step, context, api, permissions, allowedActionIds, options, flowStack = []) {
|
|
1470
1478
|
if (step.if) {
|
|
1471
|
-
const condResult =
|
|
1479
|
+
const condResult = evaluateCondition(step.if, context);
|
|
1472
1480
|
if (!condResult) {
|
|
1473
1481
|
const result = { status: "skipped" };
|
|
1474
1482
|
context.steps[step.id] = result;
|
|
@@ -1476,7 +1484,7 @@ async function executeSingleStep(step, context, api, permissions, allowedActionI
|
|
|
1476
1484
|
}
|
|
1477
1485
|
}
|
|
1478
1486
|
if (step.unless) {
|
|
1479
|
-
const condResult =
|
|
1487
|
+
const condResult = evaluateCondition(step.unless, context);
|
|
1480
1488
|
if (condResult) {
|
|
1481
1489
|
const result = { status: "skipped" };
|
|
1482
1490
|
context.steps[step.id] = result;
|
package/dist/index.js
CHANGED
|
@@ -30,10 +30,10 @@ import {
|
|
|
30
30
|
searchCachePath,
|
|
31
31
|
validateActionInput,
|
|
32
32
|
writeCache
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-IFTHWFLL.js";
|
|
34
34
|
import {
|
|
35
35
|
memSqlCommand
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-QV3Y5N5G.js";
|
|
37
37
|
import {
|
|
38
38
|
countRecords,
|
|
39
39
|
deleteDatabase,
|
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
upsertRecords,
|
|
59
59
|
writeDraftProfile,
|
|
60
60
|
writeProfile
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-PLMFRFTT.js";
|
|
62
62
|
import {
|
|
63
63
|
getByDotPath
|
|
64
64
|
} from "./chunk-44CV5IMX.js";
|
|
@@ -80,8 +80,9 @@ import {
|
|
|
80
80
|
requireMemoryInit,
|
|
81
81
|
semanticSearchUpgradeHint,
|
|
82
82
|
semanticSearchUpgradeLine,
|
|
83
|
-
setAgentMode
|
|
84
|
-
|
|
83
|
+
setAgentMode,
|
|
84
|
+
silenceWarningsInAgentMode
|
|
85
|
+
} from "./chunk-HS5AHQ4V.js";
|
|
85
86
|
import {
|
|
86
87
|
SCHEMA_VERSION,
|
|
87
88
|
addRecord,
|
|
@@ -3653,6 +3654,26 @@ function validateCodeModules(flow2, rootDir) {
|
|
|
3653
3654
|
// src/commands/flow.ts
|
|
3654
3655
|
import fs5 from "fs";
|
|
3655
3656
|
import path5 from "path";
|
|
3657
|
+
async function writeFlowResultFile(filePath, meta, steps) {
|
|
3658
|
+
const abs = path5.resolve(filePath);
|
|
3659
|
+
const ws = fs5.createWriteStream(abs);
|
|
3660
|
+
const done = new Promise((resolve, reject) => {
|
|
3661
|
+
ws.on("finish", () => resolve());
|
|
3662
|
+
ws.on("error", reject);
|
|
3663
|
+
});
|
|
3664
|
+
ws.write(
|
|
3665
|
+
`{"event":"workflow:result","runId":${JSON.stringify(meta.runId)},"logFile":${JSON.stringify(meta.logFile)},"status":${JSON.stringify(meta.status)},"steps":{`
|
|
3666
|
+
);
|
|
3667
|
+
let first = true;
|
|
3668
|
+
for (const [id, result] of Object.entries(steps)) {
|
|
3669
|
+
ws.write(`${first ? "" : ","}${JSON.stringify(id)}:${JSON.stringify(result)}`);
|
|
3670
|
+
first = false;
|
|
3671
|
+
}
|
|
3672
|
+
ws.write("}}");
|
|
3673
|
+
ws.end();
|
|
3674
|
+
await done;
|
|
3675
|
+
return abs;
|
|
3676
|
+
}
|
|
3656
3677
|
function getConfig2() {
|
|
3657
3678
|
const apiKey = getApiKey();
|
|
3658
3679
|
if (!apiKey) {
|
|
@@ -3853,16 +3874,16 @@ ${pc7.yellow("Pausing after current step completes...")} (run ID: ${runId})`);
|
|
|
3853
3874
|
if (!options.verbose && !isAgentMode()) {
|
|
3854
3875
|
execSpinner.stop("Workflow completed");
|
|
3855
3876
|
}
|
|
3877
|
+
const resultFile = options.outputFile ? await writeFlowResultFile(options.outputFile, { runId, logFile: logPath, status: "success" }, context.steps) : void 0;
|
|
3856
3878
|
if (isAgentMode()) {
|
|
3857
|
-
json(
|
|
3858
|
-
event: "workflow:result",
|
|
3859
|
-
|
|
3860
|
-
logFile: logPath,
|
|
3861
|
-
status: "success",
|
|
3862
|
-
steps: context.steps
|
|
3863
|
-
});
|
|
3879
|
+
json(
|
|
3880
|
+
resultFile ? { event: "workflow:result", runId, logFile: logPath, status: "success", outputFile: resultFile } : { event: "workflow:result", runId, logFile: logPath, status: "success", steps: context.steps }
|
|
3881
|
+
);
|
|
3864
3882
|
return;
|
|
3865
3883
|
}
|
|
3884
|
+
if (resultFile) {
|
|
3885
|
+
note(`Full result written to ${resultFile}`, "Output");
|
|
3886
|
+
}
|
|
3866
3887
|
const stepEntries = Object.entries(context.steps);
|
|
3867
3888
|
const succeeded = stepEntries.filter(([, r]) => r.status === "success").length;
|
|
3868
3889
|
const failed = stepEntries.filter(([, r]) => r.status === "failed").length;
|
|
@@ -7799,7 +7820,7 @@ ${result.total} results`);
|
|
|
7799
7820
|
}
|
|
7800
7821
|
}
|
|
7801
7822
|
async function syncSqlCommand(platformModel, sql) {
|
|
7802
|
-
const { syncSqlCommand: runSyncSql } = await import("./sql-
|
|
7823
|
+
const { syncSqlCommand: runSyncSql } = await import("./sql-W3ZUOUNR.js");
|
|
7803
7824
|
await runSyncSql(platformModel, sql);
|
|
7804
7825
|
}
|
|
7805
7826
|
async function syncDeleteCommand(platformModel, options) {
|
|
@@ -7893,7 +7914,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
|
|
|
7893
7914
|
` detected legacy .one/sync/data/${platform}.db (${dbSize}) \u2014 auto-migrating into memory before sync.
|
|
7894
7915
|
`
|
|
7895
7916
|
);
|
|
7896
|
-
const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-
|
|
7917
|
+
const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-UDEANXEZ.js");
|
|
7897
7918
|
await memMigrateCommand3({ platform, yes: true });
|
|
7898
7919
|
return;
|
|
7899
7920
|
}
|
|
@@ -7902,7 +7923,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
|
|
|
7902
7923
|
initialValue: true
|
|
7903
7924
|
});
|
|
7904
7925
|
if (p7.isCancel(shouldMigrate) || !shouldMigrate) return;
|
|
7905
|
-
const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-
|
|
7926
|
+
const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-UDEANXEZ.js");
|
|
7906
7927
|
await memMigrateCommand2({ platform, yes: true });
|
|
7907
7928
|
}
|
|
7908
7929
|
async function syncSuggestSearchableCommand(platformModel, options = {}) {
|
|
@@ -9391,6 +9412,8 @@ one --agent flow list # List all workflows
|
|
|
9391
9412
|
- AI analysis via bash steps: \`claude --print\` with \`parseJson: true\`
|
|
9392
9413
|
- Use \`--allow-bash\` to enable bash steps, \`--mock\` for dry-run with realistic mock responses (uses example data from action schemas)
|
|
9393
9414
|
- Use \`--skip-validation\` to bypass input validation on action steps
|
|
9415
|
+
- Use \`--output-file <path>\` to stream the full result to a file instead of stdout \u2014 for large results that would otherwise be truncated or hit the JSON string-size limit; stdout (and \`--agent\` output) then carries an \`outputFile\` pointer instead of inline \`steps\`
|
|
9416
|
+
- Step-level \`if\`/\`unless\` (and \`while\`/\`condition\` steps) are null-safe: a condition referencing a skipped or not-yet-run step's output (e.g. \`$.steps.maybeSkipped.output.x\`) evaluates to \`false\` instead of crashing the flow
|
|
9394
9417
|
|
|
9395
9418
|
### 3. Relay \u2014 Webhook event forwarding between platforms
|
|
9396
9419
|
Receive webhooks from platforms (Stripe, GitHub, Airtable, Attio, Google Calendar) and forward event data to any connected platform using passthrough actions with Handlebars templates. No middleware, no code.
|
|
@@ -10968,6 +10991,7 @@ function maybeShowTelemetryNotice() {
|
|
|
10968
10991
|
}
|
|
10969
10992
|
|
|
10970
10993
|
// src/cli.ts
|
|
10994
|
+
silenceWarningsInAgentMode();
|
|
10971
10995
|
var require4 = createRequire3(import.meta.url);
|
|
10972
10996
|
var { version } = require4("../package.json");
|
|
10973
10997
|
var program = new Command();
|
|
@@ -11283,7 +11307,7 @@ var flow = program.command("flow").alias("f").description("Create, execute, and
|
|
|
11283
11307
|
flow.command("create [key]").description("Create a new workflow from JSON definition").option("--definition <json>", "Workflow definition as JSON string").option("-o, --output <path>", "Custom output path (default .one/flows/<key>/flow.json)").action(async (key, options) => {
|
|
11284
11308
|
await flowCreateCommand(key, options);
|
|
11285
11309
|
});
|
|
11286
|
-
flow.command("execute <keyOrPath>").alias("x").description("Execute a workflow by key or file path").option("-i, --input <name=value>", "Input parameter (repeatable)", collect, []).option("--dry-run", "Validate and show execution plan without running").option("--mock", "With --dry-run: execute transforms/code with realistic mock API responses").option("--skip-validation", "Skip input validation against action schemas").option("--allow-bash", "Allow bash step execution (disabled by default for security)").option("-v, --verbose", "Show full request/response for each step").action(async (keyOrPath, options) => {
|
|
11310
|
+
flow.command("execute <keyOrPath>").alias("x").description("Execute a workflow by key or file path").option("-i, --input <name=value>", "Input parameter (repeatable)", collect, []).option("--dry-run", "Validate and show execution plan without running").option("--mock", "With --dry-run: execute transforms/code with realistic mock API responses").option("--skip-validation", "Skip input validation against action schemas").option("--allow-bash", "Allow bash step execution (disabled by default for security)").option("-v, --verbose", "Show full request/response for each step").option("--output-file <path>", "Write the full result to a file (streamed) instead of stdout \u2014 avoids truncation/string-limit errors for large results; stdout/agent output then carries an outputFile pointer").action(async (keyOrPath, options) => {
|
|
11287
11311
|
await flowExecuteCommand(keyOrPath, options);
|
|
11288
11312
|
});
|
|
11289
11313
|
flow.command("list").alias("ls").description("List all workflows in .one/flows/").action(async () => {
|
|
@@ -3,9 +3,9 @@ import {
|
|
|
3
3
|
dotPathToJsonbExpr,
|
|
4
4
|
memMigrateCommand,
|
|
5
5
|
reviveStringifiedJson
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PLMFRFTT.js";
|
|
7
7
|
import "./chunk-44CV5IMX.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-HS5AHQ4V.js";
|
|
9
9
|
import "./chunk-OADHUAEU.js";
|
|
10
10
|
import "./chunk-TXTRXV74.js";
|
|
11
11
|
import "./chunk-K6MWE2ZH.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
memSqlCommand,
|
|
3
3
|
syncSqlCommand
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-QV3Y5N5G.js";
|
|
5
|
+
import "./chunk-HS5AHQ4V.js";
|
|
6
6
|
import "./chunk-OADHUAEU.js";
|
|
7
7
|
import "./chunk-TXTRXV74.js";
|
|
8
8
|
import "./chunk-K6MWE2ZH.js";
|
package/package.json
CHANGED
|
@@ -271,6 +271,10 @@ Selectors in data fields (`data`, `queryParams`, `pathVars`, `connectionKey`) ar
|
|
|
271
271
|
|
|
272
272
|
The `if`, `unless`, `condition.expression`, `while.condition`, `transform.expression`, and `code.source` fields **do** support full JavaScript expressions (e.g., `$.input.email && $.input.email.length > 0`).
|
|
273
273
|
|
|
274
|
+
**Condition null-safety:** `if`/`unless`, `while.condition`, and `condition.expression` are null-safe. A condition that walks into a skipped or not-yet-run step's output — e.g. `$.steps.maybeSkipped.output.value` — evaluates to `false` instead of throwing `Cannot read properties of undefined`. (This applies to *conditions* only; `transform.expression` and `code.source` still throw on undefined access, since their output feeds downstream steps and should fail loudly.)
|
|
275
|
+
|
|
276
|
+
**Large results:** pass `--output-file <path>` to `flow execute` to stream the full result to a file instead of stdout. Use it when a flow aggregates large outputs that would otherwise be truncated on stdout or exceed the JSON string-size limit. stdout (and `--agent` output) then carries `{"event":"workflow:result", ..., "outputFile":"<path>"}` instead of inline `steps` — read the file for the full result.
|
|
277
|
+
|
|
274
278
|
## Step Types
|
|
275
279
|
|
|
276
280
|
### `action` — Execute a One API action
|