windmill-cli 1.689.0 → 1.691.0
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/esm/main.js +465 -50
- package/package.json +1 -1
package/esm/main.js
CHANGED
|
@@ -16701,7 +16701,7 @@ var init_OpenAPI = __esm(() => {
|
|
|
16701
16701
|
PASSWORD: undefined,
|
|
16702
16702
|
TOKEN: getEnv3("WM_TOKEN"),
|
|
16703
16703
|
USERNAME: undefined,
|
|
16704
|
-
VERSION: "1.
|
|
16704
|
+
VERSION: "1.691.0",
|
|
16705
16705
|
WITH_CREDENTIALS: true,
|
|
16706
16706
|
interceptors: {
|
|
16707
16707
|
request: new Interceptors,
|
|
@@ -17008,6 +17008,7 @@ __export(exports_services_gen, {
|
|
|
17008
17008
|
updateFlow: () => updateFlow,
|
|
17009
17009
|
updateEmailTrigger: () => updateEmailTrigger,
|
|
17010
17010
|
updateConfig: () => updateConfig,
|
|
17011
|
+
updateAzureTrigger: () => updateAzureTrigger,
|
|
17011
17012
|
updateAppRaw: () => updateAppRaw,
|
|
17012
17013
|
updateAppHistory: () => updateAppHistory,
|
|
17013
17014
|
updateApp: () => updateApp,
|
|
@@ -17029,6 +17030,7 @@ __export(exports_services_gen, {
|
|
|
17029
17030
|
testGcpConnection: () => testGcpConnection,
|
|
17030
17031
|
testCriticalChannels: () => testCriticalChannels,
|
|
17031
17032
|
testAzureKvBackend: () => testAzureKvBackend,
|
|
17033
|
+
testAzureConnection: () => testAzureConnection,
|
|
17032
17034
|
testAwsSmBackend: () => testAwsSmBackend,
|
|
17033
17035
|
syncNativeTriggers: () => syncNativeTriggers,
|
|
17034
17036
|
submitOnboardingData: () => submitOnboardingData,
|
|
@@ -17061,6 +17063,7 @@ __export(exports_services_gen, {
|
|
|
17061
17063
|
setEmailTriggerMode: () => setEmailTriggerMode,
|
|
17062
17064
|
setDefaultErrorOrRecoveryHandler: () => setDefaultErrorOrRecoveryHandler,
|
|
17063
17065
|
setCaptureConfig: () => setCaptureConfig,
|
|
17066
|
+
setAzureTriggerMode: () => setAzureTriggerMode,
|
|
17064
17067
|
sendStats: () => sendStats,
|
|
17065
17068
|
sendMessageToConversation: () => sendMessageToConversation,
|
|
17066
17069
|
searchLogsIndex: () => searchLogsIndex,
|
|
@@ -17254,6 +17257,11 @@ __export(exports_services_gen, {
|
|
|
17254
17257
|
listCompletedJobs: () => listCompletedJobs,
|
|
17255
17258
|
listCaptures: () => listCaptures,
|
|
17256
17259
|
listBlacklistedAgentTokens: () => listBlacklistedAgentTokens,
|
|
17260
|
+
listAzureTriggers: () => listAzureTriggers,
|
|
17261
|
+
listAzureNamespaces: () => listAzureNamespaces,
|
|
17262
|
+
listAzureNamespaceTopics: () => listAzureNamespaceTopics,
|
|
17263
|
+
listAzureNamespaceSubscriptions: () => listAzureNamespaceSubscriptions,
|
|
17264
|
+
listAzureBasicTopics: () => listAzureBasicTopics,
|
|
17257
17265
|
listAvailableTeamsIds: () => listAvailableTeamsIds,
|
|
17258
17266
|
listAvailableTeamsChannels: () => listAvailableTeamsChannels,
|
|
17259
17267
|
listAvailableScopes: () => listAvailableScopes,
|
|
@@ -17446,6 +17454,7 @@ __export(exports_services_gen, {
|
|
|
17446
17454
|
getCiTestResults: () => getCiTestResults,
|
|
17447
17455
|
getCaptureConfigs: () => getCaptureConfigs,
|
|
17448
17456
|
getCapture: () => getCapture,
|
|
17457
|
+
getAzureTrigger: () => getAzureTrigger,
|
|
17449
17458
|
getAuditLog: () => getAuditLog,
|
|
17450
17459
|
getArgsFromHistoryOrSavedInput: () => getArgsFromHistoryOrSavedInput,
|
|
17451
17460
|
getApprovalInfo: () => getApprovalInfo,
|
|
@@ -17493,6 +17502,7 @@ __export(exports_services_gen, {
|
|
|
17493
17502
|
existsEmailTrigger: () => existsEmailTrigger,
|
|
17494
17503
|
existsEmailLocalPart: () => existsEmailLocalPart,
|
|
17495
17504
|
existsEmail: () => existsEmail,
|
|
17505
|
+
existsAzureTrigger: () => existsAzureTrigger,
|
|
17496
17506
|
existsApp: () => existsApp,
|
|
17497
17507
|
executeComponent: () => executeComponent,
|
|
17498
17508
|
encryptValue: () => encryptValue,
|
|
@@ -17570,6 +17580,8 @@ __export(exports_services_gen, {
|
|
|
17570
17580
|
deleteConcurrencyGroup: () => deleteConcurrencyGroup,
|
|
17571
17581
|
deleteCompletedJob: () => deleteCompletedJob,
|
|
17572
17582
|
deleteCapture: () => deleteCapture,
|
|
17583
|
+
deleteAzureTrigger: () => deleteAzureTrigger,
|
|
17584
|
+
deleteAzureSubscription: () => deleteAzureSubscription,
|
|
17573
17585
|
deleteApp: () => deleteApp,
|
|
17574
17586
|
declineInvite: () => declineInvite,
|
|
17575
17587
|
datasetStorageTestConnection: () => datasetStorageTestConnection,
|
|
@@ -17615,6 +17627,7 @@ __export(exports_services_gen, {
|
|
|
17615
17627
|
createDeploymentRequestComment: () => createDeploymentRequestComment,
|
|
17616
17628
|
createDeploymentRequest: () => createDeploymentRequest,
|
|
17617
17629
|
createCustomerPortalSession: () => createCustomerPortalSession,
|
|
17630
|
+
createAzureTrigger: () => createAzureTrigger,
|
|
17618
17631
|
createAppRaw: () => createAppRaw,
|
|
17619
17632
|
createApp: () => createApp,
|
|
17620
17633
|
createAgentToken: () => createAgentToken,
|
|
@@ -17624,8 +17637,10 @@ __export(exports_services_gen, {
|
|
|
17624
17637
|
countCompletedJobs: () => countCompletedJobs,
|
|
17625
17638
|
convertUserToGroup: () => convertUserToGroup,
|
|
17626
17639
|
connectTeams: () => connectTeams,
|
|
17640
|
+
connectSlackInstance: () => connectSlackInstance,
|
|
17627
17641
|
connectSlackCallbackInstance: () => connectSlackCallbackInstance,
|
|
17628
17642
|
connectSlackCallback: () => connectSlackCallback,
|
|
17643
|
+
connectSlack: () => connectSlack,
|
|
17629
17644
|
connectClientCredentials: () => connectClientCredentials,
|
|
17630
17645
|
connectCallback: () => connectCallback,
|
|
17631
17646
|
computeObjectStorageUsage: () => computeObjectStorageUsage,
|
|
@@ -18820,6 +18835,16 @@ var backendVersion = () => {
|
|
|
18820
18835
|
body: data3.requestBody,
|
|
18821
18836
|
mediaType: "application/json"
|
|
18822
18837
|
});
|
|
18838
|
+
}, connectSlack = (data3) => {
|
|
18839
|
+
return request(OpenAPI, {
|
|
18840
|
+
method: "POST",
|
|
18841
|
+
url: "/w/{workspace}/workspaces/connect_slack",
|
|
18842
|
+
path: {
|
|
18843
|
+
workspace: data3.workspace
|
|
18844
|
+
},
|
|
18845
|
+
body: data3.requestBody,
|
|
18846
|
+
mediaType: "application/json"
|
|
18847
|
+
});
|
|
18823
18848
|
}, runSlackMessageTestJob = (data3) => {
|
|
18824
18849
|
return request(OpenAPI, {
|
|
18825
18850
|
method: "POST",
|
|
@@ -19581,6 +19606,13 @@ var backendVersion = () => {
|
|
|
19581
19606
|
body: data3.requestBody,
|
|
19582
19607
|
mediaType: "application/json"
|
|
19583
19608
|
});
|
|
19609
|
+
}, connectSlackInstance = (data3) => {
|
|
19610
|
+
return request(OpenAPI, {
|
|
19611
|
+
method: "POST",
|
|
19612
|
+
url: "/oauth/connect_slack_instance",
|
|
19613
|
+
body: data3.requestBody,
|
|
19614
|
+
mediaType: "application/json"
|
|
19615
|
+
});
|
|
19584
19616
|
}, connectCallback = (data3) => {
|
|
19585
19617
|
return request(OpenAPI, {
|
|
19586
19618
|
method: "POST",
|
|
@@ -20970,7 +21002,7 @@ var backendVersion = () => {
|
|
|
20970
21002
|
query: {
|
|
20971
21003
|
page: data3.page,
|
|
20972
21004
|
per_page: data3.perPage,
|
|
20973
|
-
|
|
21005
|
+
after_seq: data3.afterSeq
|
|
20974
21006
|
}
|
|
20975
21007
|
});
|
|
20976
21008
|
}, listPathAutocompletePaths = (data3) => {
|
|
@@ -21849,7 +21881,8 @@ var backendVersion = () => {
|
|
|
21849
21881
|
},
|
|
21850
21882
|
query: {
|
|
21851
21883
|
no_logs: data3.noLogs,
|
|
21852
|
-
no_code: data3.noCode
|
|
21884
|
+
no_code: data3.noCode,
|
|
21885
|
+
approval_token: data3.approvalToken
|
|
21853
21886
|
}
|
|
21854
21887
|
});
|
|
21855
21888
|
}, getRootJobId = (data3) => {
|
|
@@ -23265,6 +23298,141 @@ var backendVersion = () => {
|
|
|
23265
23298
|
body: data3.requestBody,
|
|
23266
23299
|
mediaType: "application/json"
|
|
23267
23300
|
});
|
|
23301
|
+
}, createAzureTrigger = (data3) => {
|
|
23302
|
+
return request(OpenAPI, {
|
|
23303
|
+
method: "POST",
|
|
23304
|
+
url: "/w/{workspace}/azure_triggers/create",
|
|
23305
|
+
path: {
|
|
23306
|
+
workspace: data3.workspace
|
|
23307
|
+
},
|
|
23308
|
+
body: data3.requestBody,
|
|
23309
|
+
mediaType: "application/json"
|
|
23310
|
+
});
|
|
23311
|
+
}, updateAzureTrigger = (data3) => {
|
|
23312
|
+
return request(OpenAPI, {
|
|
23313
|
+
method: "POST",
|
|
23314
|
+
url: "/w/{workspace}/azure_triggers/update/{path}",
|
|
23315
|
+
path: {
|
|
23316
|
+
workspace: data3.workspace,
|
|
23317
|
+
path: data3.path
|
|
23318
|
+
},
|
|
23319
|
+
body: data3.requestBody,
|
|
23320
|
+
mediaType: "application/json"
|
|
23321
|
+
});
|
|
23322
|
+
}, deleteAzureTrigger = (data3) => {
|
|
23323
|
+
return request(OpenAPI, {
|
|
23324
|
+
method: "DELETE",
|
|
23325
|
+
url: "/w/{workspace}/azure_triggers/delete/{path}",
|
|
23326
|
+
path: {
|
|
23327
|
+
workspace: data3.workspace,
|
|
23328
|
+
path: data3.path
|
|
23329
|
+
}
|
|
23330
|
+
});
|
|
23331
|
+
}, getAzureTrigger = (data3) => {
|
|
23332
|
+
return request(OpenAPI, {
|
|
23333
|
+
method: "GET",
|
|
23334
|
+
url: "/w/{workspace}/azure_triggers/get/{path}",
|
|
23335
|
+
path: {
|
|
23336
|
+
workspace: data3.workspace,
|
|
23337
|
+
path: data3.path
|
|
23338
|
+
}
|
|
23339
|
+
});
|
|
23340
|
+
}, listAzureTriggers = (data3) => {
|
|
23341
|
+
return request(OpenAPI, {
|
|
23342
|
+
method: "GET",
|
|
23343
|
+
url: "/w/{workspace}/azure_triggers/list",
|
|
23344
|
+
path: {
|
|
23345
|
+
workspace: data3.workspace
|
|
23346
|
+
},
|
|
23347
|
+
query: {
|
|
23348
|
+
page: data3.page,
|
|
23349
|
+
per_page: data3.perPage,
|
|
23350
|
+
path: data3.path,
|
|
23351
|
+
is_flow: data3.isFlow,
|
|
23352
|
+
path_start: data3.pathStart
|
|
23353
|
+
}
|
|
23354
|
+
});
|
|
23355
|
+
}, existsAzureTrigger = (data3) => {
|
|
23356
|
+
return request(OpenAPI, {
|
|
23357
|
+
method: "GET",
|
|
23358
|
+
url: "/w/{workspace}/azure_triggers/exists/{path}",
|
|
23359
|
+
path: {
|
|
23360
|
+
workspace: data3.workspace,
|
|
23361
|
+
path: data3.path
|
|
23362
|
+
}
|
|
23363
|
+
});
|
|
23364
|
+
}, setAzureTriggerMode = (data3) => {
|
|
23365
|
+
return request(OpenAPI, {
|
|
23366
|
+
method: "POST",
|
|
23367
|
+
url: "/w/{workspace}/azure_triggers/setmode/{path}",
|
|
23368
|
+
path: {
|
|
23369
|
+
workspace: data3.workspace,
|
|
23370
|
+
path: data3.path
|
|
23371
|
+
},
|
|
23372
|
+
body: data3.requestBody,
|
|
23373
|
+
mediaType: "application/json"
|
|
23374
|
+
});
|
|
23375
|
+
}, testAzureConnection = (data3) => {
|
|
23376
|
+
return request(OpenAPI, {
|
|
23377
|
+
method: "POST",
|
|
23378
|
+
url: "/w/{workspace}/azure_triggers/test",
|
|
23379
|
+
path: {
|
|
23380
|
+
workspace: data3.workspace
|
|
23381
|
+
},
|
|
23382
|
+
body: data3.requestBody,
|
|
23383
|
+
mediaType: "application/json"
|
|
23384
|
+
});
|
|
23385
|
+
}, listAzureNamespaceTopics = (data3) => {
|
|
23386
|
+
return request(OpenAPI, {
|
|
23387
|
+
method: "POST",
|
|
23388
|
+
url: "/w/{workspace}/azure_triggers/namespaces/topics/list/{path}",
|
|
23389
|
+
path: {
|
|
23390
|
+
workspace: data3.workspace,
|
|
23391
|
+
path: data3.path
|
|
23392
|
+
},
|
|
23393
|
+
body: data3.requestBody,
|
|
23394
|
+
mediaType: "application/json"
|
|
23395
|
+
});
|
|
23396
|
+
}, listAzureNamespaceSubscriptions = (data3) => {
|
|
23397
|
+
return request(OpenAPI, {
|
|
23398
|
+
method: "POST",
|
|
23399
|
+
url: "/w/{workspace}/azure_triggers/namespaces/subscriptions/list/{path}",
|
|
23400
|
+
path: {
|
|
23401
|
+
workspace: data3.workspace,
|
|
23402
|
+
path: data3.path
|
|
23403
|
+
},
|
|
23404
|
+
body: data3.requestBody,
|
|
23405
|
+
mediaType: "application/json"
|
|
23406
|
+
});
|
|
23407
|
+
}, deleteAzureSubscription = (data3) => {
|
|
23408
|
+
return request(OpenAPI, {
|
|
23409
|
+
method: "DELETE",
|
|
23410
|
+
url: "/w/{workspace}/azure_triggers/subscriptions/delete/{path}",
|
|
23411
|
+
path: {
|
|
23412
|
+
workspace: data3.workspace,
|
|
23413
|
+
path: data3.path
|
|
23414
|
+
},
|
|
23415
|
+
body: data3.requestBody,
|
|
23416
|
+
mediaType: "application/json"
|
|
23417
|
+
});
|
|
23418
|
+
}, listAzureNamespaces = (data3) => {
|
|
23419
|
+
return request(OpenAPI, {
|
|
23420
|
+
method: "POST",
|
|
23421
|
+
url: "/w/{workspace}/azure_triggers/namespaces/list/{path}",
|
|
23422
|
+
path: {
|
|
23423
|
+
workspace: data3.workspace,
|
|
23424
|
+
path: data3.path
|
|
23425
|
+
}
|
|
23426
|
+
});
|
|
23427
|
+
}, listAzureBasicTopics = (data3) => {
|
|
23428
|
+
return request(OpenAPI, {
|
|
23429
|
+
method: "POST",
|
|
23430
|
+
url: "/w/{workspace}/azure_triggers/basic/topics/list/{path}",
|
|
23431
|
+
path: {
|
|
23432
|
+
workspace: data3.workspace,
|
|
23433
|
+
path: data3.path
|
|
23434
|
+
}
|
|
23435
|
+
});
|
|
23268
23436
|
}, getPostgresVersion = (data3) => {
|
|
23269
23437
|
return request(OpenAPI, {
|
|
23270
23438
|
method: "GET",
|
|
@@ -25985,6 +26153,36 @@ var init_merge = __esm(async () => {
|
|
|
25985
26153
|
};
|
|
25986
26154
|
});
|
|
25987
26155
|
|
|
26156
|
+
// src/commands/workspace/slack.ts
|
|
26157
|
+
async function connectSlack2(opts) {
|
|
26158
|
+
await requireLogin(opts);
|
|
26159
|
+
const workspace = await resolveWorkspace(opts);
|
|
26160
|
+
await connectSlack({
|
|
26161
|
+
workspace: workspace.workspaceId,
|
|
26162
|
+
requestBody: {
|
|
26163
|
+
bot_token: opts.botToken,
|
|
26164
|
+
team_id: opts.teamId,
|
|
26165
|
+
team_name: opts.teamName
|
|
26166
|
+
}
|
|
26167
|
+
});
|
|
26168
|
+
info(colors.bold.underline.green(`Slack connected to workspace ${workspace.workspaceId} (team ${opts.teamName} / ${opts.teamId})`));
|
|
26169
|
+
}
|
|
26170
|
+
async function disconnectSlack2(opts) {
|
|
26171
|
+
await requireLogin(opts);
|
|
26172
|
+
const workspace = await resolveWorkspace(opts);
|
|
26173
|
+
await disconnectSlack({ workspace: workspace.workspaceId });
|
|
26174
|
+
info(colors.bold.underline.green(`Slack disconnected from workspace ${workspace.workspaceId} (slack_team_id / slack_name cleared). ` + `To also remove the bot token variable/resource/folder/group, delete the corresponding files from the local sync folder and run 'wmill sync push'. ` + `To remove the workspace-level OAuth override (if any), set slack_oauth_client_id/_secret to '' in settings.yaml and push.`));
|
|
26175
|
+
}
|
|
26176
|
+
var init_slack = __esm(async () => {
|
|
26177
|
+
init_colors2();
|
|
26178
|
+
init_log();
|
|
26179
|
+
init_services_gen();
|
|
26180
|
+
await __promiseAll([
|
|
26181
|
+
init_auth(),
|
|
26182
|
+
init_context()
|
|
26183
|
+
]);
|
|
26184
|
+
});
|
|
26185
|
+
|
|
25988
26186
|
// src/utils/resource_folders.ts
|
|
25989
26187
|
import { sep as SEP2 } from "node:path";
|
|
25990
26188
|
import * as fs6 from "node:fs";
|
|
@@ -27326,11 +27524,12 @@ var init_workspace = __esm(async () => {
|
|
|
27326
27524
|
init_input(),
|
|
27327
27525
|
init_auth(),
|
|
27328
27526
|
init_fork(),
|
|
27329
|
-
init_merge()
|
|
27527
|
+
init_merge(),
|
|
27528
|
+
init_slack()
|
|
27330
27529
|
]);
|
|
27331
27530
|
command2 = new Command().alias("profile").description("workspace related commands").action(list3).command("switch").complete("workspace", async () => (await allWorkspaces()).map((x) => x.name)).description("Switch to another workspace").arguments("<workspace_name:string:workspace>").action(switchC).command("add").description("Add a workspace").arguments("[workspace_name:string] [workspace_id:string] [remote:string]").option("-c --create", "Create the workspace if it does not exist").option("--create-workspace-name <workspace_name:string>", "Specify the workspace name. Ignored if --create is not specified or the workspace already exists. Will default to the workspace id.").option("--create-username <username:string>", "Specify your own username in the newly created workspace. Ignored if --create is not specified, the workspace already exists or automatic username creation is enabled on the instance.", {
|
|
27332
27531
|
default: "admin"
|
|
27333
|
-
}).action(add).command("remove").description("Remove a workspace").arguments("<workspace_name:string>").action(remove).command("whoami").description("Show the currently active user").action(whoami2).command("list").description("List local workspace profiles").action(list3).command("list-remote").description("List workspaces on the remote server that you have access to").action(listRemote).command("list-forks").description("List forked workspaces on the remote server").action(listForks).command("bind").description("Create or update a workspace entry in wmill.yaml from the active profile").option("--workspace <name:string>", "Workspace name (default: current branch or workspaceId)").option("--branch <branch:string>", "Git branch to associate (default: workspace name)").action((opts) => bind(opts, true)).command("unbind").description("Remove baseUrl and workspaceId from a workspace entry").option("--workspace <name:string>", "Workspace to unbind").action((opts) => bind(opts, false)).command("fork").description("Create a forked workspace").arguments("[workspace_name:string] [workspace_id:string]").option("--create-workspace-name <workspace_name:string>", "Specify the workspace name. Ignored if --create is not specified or the workspace already exists. Will default to the workspace id.").option("--color <color:string>", "Workspace color (hex code, e.g. #ff0000)").option("--datatable-behavior <behavior:string>", "How to handle datatables: skip, schema_only, or schema_and_data (default: interactive prompt)").option("-y --yes", "Skip interactive prompts (defaults datatable behavior to 'skip')").action(createWorkspaceFork2).command("delete-fork").description("Delete a forked workspace and git branch").arguments("<fork_name:string>").option("-y --yes", "Skip confirmation prompt").action(deleteWorkspaceFork).command("merge").description("Compare and deploy changes between a fork and its parent workspace").option("--direction <direction:string>", "Deploy direction: to-parent or to-fork").option("--all", "Deploy all changed items including conflicts").option("--skip-conflicts", "Skip items modified in both workspaces").option("--include <items:string>", "Comma-separated kind:path items to include (e.g. script:f/test/main,flow:f/my/flow)").option("--exclude <items:string>", "Comma-separated kind:path items to exclude").option("--preserve-on-behalf-of", "Preserve original on_behalf_of/permissioned_as values").option("-y --yes", "Non-interactive mode (deploy without prompts)").action(mergeWorkspaces);
|
|
27532
|
+
}).action(add).command("remove").description("Remove a workspace").arguments("<workspace_name:string>").action(remove).command("whoami").description("Show the currently active user").action(whoami2).command("list").description("List local workspace profiles").action(list3).command("list-remote").description("List workspaces on the remote server that you have access to").action(listRemote).command("list-forks").description("List forked workspaces on the remote server").action(listForks).command("bind").description("Create or update a workspace entry in wmill.yaml from the active profile").option("--workspace <name:string>", "Workspace name (default: current branch or workspaceId)").option("--branch <branch:string>", "Git branch to associate (default: workspace name)").action((opts) => bind(opts, true)).command("unbind").description("Remove baseUrl and workspaceId from a workspace entry").option("--workspace <name:string>", "Workspace to unbind").action((opts) => bind(opts, false)).command("fork").description("Create a forked workspace").arguments("[workspace_name:string] [workspace_id:string]").option("--create-workspace-name <workspace_name:string>", "Specify the workspace name. Ignored if --create is not specified or the workspace already exists. Will default to the workspace id.").option("--color <color:string>", "Workspace color (hex code, e.g. #ff0000)").option("--datatable-behavior <behavior:string>", "How to handle datatables: skip, schema_only, or schema_and_data (default: interactive prompt)").option("-y --yes", "Skip interactive prompts (defaults datatable behavior to 'skip')").action(createWorkspaceFork2).command("delete-fork").description("Delete a forked workspace and git branch").arguments("<fork_name:string>").option("-y --yes", "Skip confirmation prompt").action(deleteWorkspaceFork).command("merge").description("Compare and deploy changes between a fork and its parent workspace").option("--direction <direction:string>", "Deploy direction: to-parent or to-fork").option("--all", "Deploy all changed items including conflicts").option("--skip-conflicts", "Skip items modified in both workspaces").option("--include <items:string>", "Comma-separated kind:path items to include (e.g. script:f/test/main,flow:f/my/flow)").option("--exclude <items:string>", "Comma-separated kind:path items to exclude").option("--preserve-on-behalf-of", "Preserve original on_behalf_of/permissioned_as values").option("-y --yes", "Non-interactive mode (deploy without prompts)").action(mergeWorkspaces).command("connect-slack").description("Non-interactively connect Slack to the active workspace using a pre-minted bot token (xoxb-...). Produces the same artifacts as the UI OAuth flow: workspace_settings fields, g/slack group, f/slack_bot folder, and the encrypted bot token variable + resource at f/slack_bot/bot_token.").option("--bot-token <bot_token:string>", "Slack bot token (xoxb-...)", { required: true }).option("--team-id <team_id:string>", "Slack team id", { required: true }).option("--team-name <team_name:string>", "Slack team name", { required: true }).action(connectSlack2).command("disconnect-slack").description("Clear slack_team_id / slack_name on the active workspace (marks the workspace as disconnected). Does NOT remove the bot token variable/resource/folder/group — delete those from the local sync folder and run 'wmill sync push' to tear them down. Does NOT remove the workspace-level OAuth override — set slack_oauth_client_id/_secret to '' in settings.yaml and push.").action(disconnectSlack2);
|
|
27334
27533
|
workspace_default = command2;
|
|
27335
27534
|
});
|
|
27336
27535
|
|
|
@@ -60846,6 +61045,11 @@ var require_dist3 = __commonJS((exports) => {
|
|
|
60846
61045
|
});
|
|
60847
61046
|
|
|
60848
61047
|
// src/core/specific_items.ts
|
|
61048
|
+
async function resolveWsNameForGitBranch(branchName) {
|
|
61049
|
+
const config = await readConfigFile({ warnIfMissing: false });
|
|
61050
|
+
const match2 = findWorkspaceByGitBranch(config.workspaces, branchName);
|
|
61051
|
+
return match2 ? match2[0] : branchName;
|
|
61052
|
+
}
|
|
60849
61053
|
function getWorkspaceSpecificTypes() {
|
|
60850
61054
|
return {
|
|
60851
61055
|
variable: ".variable.yaml",
|
|
@@ -61231,10 +61435,11 @@ async function findResourceFile(path8) {
|
|
|
61231
61435
|
let contentBasePathJSON = splitPath[0] + "." + splitPath[1] + ".json";
|
|
61232
61436
|
let contentBasePathYAML = splitPath[0] + "." + splitPath[1] + ".yaml";
|
|
61233
61437
|
const currentBranch = getCurrentGitBranch();
|
|
61438
|
+
const wsName = currentBranch ? await resolveWsNameForGitBranch(currentBranch) : null;
|
|
61234
61439
|
const candidates = [contentBasePathJSON, contentBasePathYAML];
|
|
61235
|
-
if (
|
|
61236
|
-
const branchSpecificJSON = toWorkspaceSpecificPath(contentBasePathJSON,
|
|
61237
|
-
const branchSpecificYAML = toWorkspaceSpecificPath(contentBasePathYAML,
|
|
61440
|
+
if (wsName) {
|
|
61441
|
+
const branchSpecificJSON = toWorkspaceSpecificPath(contentBasePathJSON, wsName);
|
|
61442
|
+
const branchSpecificYAML = toWorkspaceSpecificPath(contentBasePathYAML, wsName);
|
|
61238
61443
|
candidates.unshift(branchSpecificJSON, branchSpecificYAML);
|
|
61239
61444
|
}
|
|
61240
61445
|
const validCandidates = (await Promise.all(candidates.map((x) => {
|
|
@@ -61491,12 +61696,21 @@ async function readModulesFromDisk(moduleFolderPath, defaultTs, folderLayout = f
|
|
|
61491
61696
|
}
|
|
61492
61697
|
async function createScript2(bundleContent, workspaceId, body, workspace) {
|
|
61493
61698
|
const start = performance.now();
|
|
61699
|
+
const skipIfNoop = "skip_if_noop=true";
|
|
61494
61700
|
if (!bundleContent) {
|
|
61495
61701
|
try {
|
|
61496
|
-
|
|
61497
|
-
|
|
61498
|
-
|
|
61702
|
+
const url = workspace.remote + "api/w/" + workspaceId + "/scripts/create?" + skipIfNoop;
|
|
61703
|
+
const req = await fetch(url, {
|
|
61704
|
+
method: "POST",
|
|
61705
|
+
headers: {
|
|
61706
|
+
Authorization: `Bearer ${workspace.token}`,
|
|
61707
|
+
"Content-Type": "application/json"
|
|
61708
|
+
},
|
|
61709
|
+
body: JSON.stringify(body)
|
|
61499
61710
|
});
|
|
61711
|
+
if (req.status != 201) {
|
|
61712
|
+
throw Error(`${req.status} - ${req.statusText} - ${await req.text()}`);
|
|
61713
|
+
}
|
|
61500
61714
|
} catch (e) {
|
|
61501
61715
|
throw Error(`Script creation for ${body.path} with parent ${body.parent_hash} was not successful: ${e.body ?? e.message} `);
|
|
61502
61716
|
}
|
|
@@ -61504,7 +61718,7 @@ async function createScript2(bundleContent, workspaceId, body, workspace) {
|
|
|
61504
61718
|
const form = new FormData;
|
|
61505
61719
|
form.append("script", JSON.stringify(body));
|
|
61506
61720
|
form.append("file", typeof bundleContent == "string" ? bundleContent : bundleContent);
|
|
61507
|
-
const url = workspace.remote + "api/w/" + workspace.workspaceId + "/scripts/create_snapshot";
|
|
61721
|
+
const url = workspace.remote + "api/w/" + workspace.workspaceId + "/scripts/create_snapshot?" + skipIfNoop;
|
|
61508
61722
|
const req = await fetch(url, {
|
|
61509
61723
|
method: "POST",
|
|
61510
61724
|
headers: { Authorization: `Bearer ${workspace.token} ` },
|
|
@@ -63744,6 +63958,7 @@ var init_flow_metadata = __esm(async () => {
|
|
|
63744
63958
|
var exports_sync = {};
|
|
63745
63959
|
__export(exports_sync, {
|
|
63746
63960
|
yamlOptions: () => yamlOptions,
|
|
63961
|
+
resolveWsNameForConfigFromFlags: () => resolveWsNameForConfigFromFlags,
|
|
63747
63962
|
readDirRecursiveWithIgnore: () => readDirRecursiveWithIgnore2,
|
|
63748
63963
|
push: () => push4,
|
|
63749
63964
|
pull: () => pull,
|
|
@@ -63765,6 +63980,18 @@ function resolveWsNameFromBranch(opts, branchName) {
|
|
|
63765
63980
|
const match2 = findWorkspaceByGitBranch(opts.workspaces, branchName);
|
|
63766
63981
|
return match2 ? match2[0] : branchName;
|
|
63767
63982
|
}
|
|
63983
|
+
function resolveWsNameForConfigFromFlags(opts) {
|
|
63984
|
+
if (opts.branch) {
|
|
63985
|
+
return resolveWsNameFromBranch(opts, opts.branch);
|
|
63986
|
+
}
|
|
63987
|
+
if (opts.workspace) {
|
|
63988
|
+
const validKeys = getWorkspaceNames(opts.workspaces);
|
|
63989
|
+
if (validKeys.includes(opts.workspace)) {
|
|
63990
|
+
return opts.workspace;
|
|
63991
|
+
}
|
|
63992
|
+
}
|
|
63993
|
+
return;
|
|
63994
|
+
}
|
|
63768
63995
|
function warnWorkspaceOverride(opts, wsNameForConfig) {
|
|
63769
63996
|
if (!wsNameForConfig || !opts.workspaces)
|
|
63770
63997
|
return;
|
|
@@ -64738,7 +64965,7 @@ async function elementsToMap(els, ignore, json, skips, specificItems, branchOver
|
|
|
64738
64965
|
const ext2 = json ? ".json" : ".yaml";
|
|
64739
64966
|
if (!skips.includeSchedules && path11.endsWith(".schedule" + ext2))
|
|
64740
64967
|
continue;
|
|
64741
|
-
if (!skips.includeTriggers && (path11.endsWith(".http_trigger" + ext2) || path11.endsWith(".websocket_trigger" + ext2) || path11.endsWith(".kafka_trigger" + ext2) || path11.endsWith(".nats_trigger" + ext2) || path11.endsWith(".postgres_trigger" + ext2) || path11.endsWith(".mqtt_trigger" + ext2) || path11.endsWith(".sqs_trigger" + ext2) || path11.endsWith(".gcp_trigger" + ext2) || path11.endsWith(".email_trigger" + ext2) || path11.endsWith("_native_trigger" + ext2))) {
|
|
64968
|
+
if (!skips.includeTriggers && (path11.endsWith(".http_trigger" + ext2) || path11.endsWith(".websocket_trigger" + ext2) || path11.endsWith(".kafka_trigger" + ext2) || path11.endsWith(".nats_trigger" + ext2) || path11.endsWith(".postgres_trigger" + ext2) || path11.endsWith(".mqtt_trigger" + ext2) || path11.endsWith(".sqs_trigger" + ext2) || path11.endsWith(".gcp_trigger" + ext2) || path11.endsWith(".azure_trigger" + ext2) || path11.endsWith(".email_trigger" + ext2) || path11.endsWith("_native_trigger" + ext2))) {
|
|
64742
64969
|
continue;
|
|
64743
64970
|
}
|
|
64744
64971
|
if (!skips.includeUsers && path11.endsWith(".user" + ext2))
|
|
@@ -64857,6 +65084,12 @@ async function compareDynFSElement(els1, els2, ignore, json, skips, ignoreMetada
|
|
|
64857
65084
|
if (o["is_template"] != null) {
|
|
64858
65085
|
delete o["is_template"];
|
|
64859
65086
|
}
|
|
65087
|
+
if (o["no_main_func"] != null) {
|
|
65088
|
+
delete o["no_main_func"];
|
|
65089
|
+
}
|
|
65090
|
+
if (o["auto_kind"] != null) {
|
|
65091
|
+
delete o["auto_kind"];
|
|
65092
|
+
}
|
|
64860
65093
|
}
|
|
64861
65094
|
return o;
|
|
64862
65095
|
} else {
|
|
@@ -65025,7 +65258,7 @@ function getOrderFromPath(p) {
|
|
|
65025
65258
|
return 12;
|
|
65026
65259
|
} else if (typ == "schedule") {
|
|
65027
65260
|
return 13;
|
|
65028
|
-
} else if (typ == "http_trigger" || typ == "websocket_trigger" || typ == "kafka_trigger" || typ == "nats_trigger" || typ == "postgres_trigger" || typ == "mqtt_trigger" || typ == "sqs_trigger" || typ == "gcp_trigger" || typ == "email_trigger" || typ == "native_trigger") {
|
|
65261
|
+
} else if (typ == "http_trigger" || typ == "websocket_trigger" || typ == "kafka_trigger" || typ == "nats_trigger" || typ == "postgres_trigger" || typ == "mqtt_trigger" || typ == "sqs_trigger" || typ == "gcp_trigger" || typ == "azure_trigger" || typ == "email_trigger" || typ == "native_trigger") {
|
|
65029
65262
|
return 14;
|
|
65030
65263
|
} else {
|
|
65031
65264
|
return 15;
|
|
@@ -65178,18 +65411,16 @@ async function pull(opts) {
|
|
|
65178
65411
|
}
|
|
65179
65412
|
const hasExplicitCredentials = !!opts.baseUrl;
|
|
65180
65413
|
let wsNameForConfig;
|
|
65181
|
-
if (opts.branch) {
|
|
65182
|
-
|
|
65183
|
-
|
|
65184
|
-
|
|
65185
|
-
|
|
65186
|
-
|
|
65187
|
-
|
|
65188
|
-
wsNameForConfig = opts.workspace;
|
|
65189
|
-
warnWorkspaceOverride(opts, wsNameForConfig);
|
|
65414
|
+
if (opts.branch && !hasExplicitCredentials && !branchDeprecationWarned) {
|
|
65415
|
+
warn("⚠️ --branch/--env is deprecated. Use --workspace instead.");
|
|
65416
|
+
branchDeprecationWarned = true;
|
|
65417
|
+
}
|
|
65418
|
+
wsNameForConfig = resolveWsNameForConfigFromFlags(opts);
|
|
65419
|
+
if (!opts.branch && opts.workspace && !hasExplicitCredentials) {
|
|
65420
|
+
warnWorkspaceOverride(opts, opts.workspace);
|
|
65190
65421
|
}
|
|
65191
65422
|
try {
|
|
65192
|
-
await validateBranchConfiguration(opts, wsNameForConfig);
|
|
65423
|
+
await validateBranchConfiguration(opts, wsNameForConfig ?? opts.workspace);
|
|
65193
65424
|
} catch (error2) {
|
|
65194
65425
|
if (error2 instanceof Error && error2.message.includes("overrides")) {
|
|
65195
65426
|
error(error2.message);
|
|
@@ -65435,18 +65666,16 @@ async function push4(opts) {
|
|
|
65435
65666
|
}
|
|
65436
65667
|
const hasExplicitCredentials = !!opts.baseUrl;
|
|
65437
65668
|
let wsNameForConfig;
|
|
65438
|
-
if (opts.branch) {
|
|
65439
|
-
|
|
65440
|
-
|
|
65441
|
-
|
|
65442
|
-
|
|
65443
|
-
|
|
65444
|
-
|
|
65445
|
-
wsNameForConfig = opts.workspace;
|
|
65446
|
-
warnWorkspaceOverride(opts, wsNameForConfig);
|
|
65669
|
+
if (opts.branch && !hasExplicitCredentials && !branchDeprecationWarned) {
|
|
65670
|
+
warn("⚠️ --branch/--env is deprecated. Use --workspace instead.");
|
|
65671
|
+
branchDeprecationWarned = true;
|
|
65672
|
+
}
|
|
65673
|
+
wsNameForConfig = resolveWsNameForConfigFromFlags(opts);
|
|
65674
|
+
if (!opts.branch && opts.workspace && !hasExplicitCredentials) {
|
|
65675
|
+
warnWorkspaceOverride(opts, opts.workspace);
|
|
65447
65676
|
}
|
|
65448
65677
|
try {
|
|
65449
|
-
await validateBranchConfiguration(opts, wsNameForConfig);
|
|
65678
|
+
await validateBranchConfiguration(opts, wsNameForConfig ?? opts.workspace);
|
|
65450
65679
|
} catch (error2) {
|
|
65451
65680
|
if (error2 instanceof Error && error2.message.includes("overrides")) {
|
|
65452
65681
|
error(error2.message);
|
|
@@ -65704,7 +65933,7 @@ ${folderList}
|
|
|
65704
65933
|
}
|
|
65705
65934
|
}
|
|
65706
65935
|
const rules = folderRulesCache.get(folderName2);
|
|
65707
|
-
const remotePath = change.path.replace(/\.(script|schedule|http_trigger|websocket_trigger|kafka_trigger|nats_trigger|postgres_trigger|mqtt_trigger|sqs_trigger|gcp_trigger|email_trigger)\.(yaml|json)$/, "").replace(/(\.flow|__flow)\/flow\.(yaml|json)$/, "").replace(/\.(app|raw_app)(\/app\.(yaml|json))?$/, "");
|
|
65936
|
+
const remotePath = change.path.replace(/\.(script|schedule|http_trigger|websocket_trigger|kafka_trigger|nats_trigger|postgres_trigger|mqtt_trigger|sqs_trigger|gcp_trigger|azure_trigger|email_trigger)\.(yaml|json)$/, "").replace(/(\.flow|__flow)\/flow\.(yaml|json)$/, "").replace(/\.(app|raw_app)(\/app\.(yaml|json))?$/, "");
|
|
65708
65937
|
const relative6 = remotePath.slice(`f/${folderName2}/`.length);
|
|
65709
65938
|
if (!relative6)
|
|
65710
65939
|
continue;
|
|
@@ -66090,6 +66319,12 @@ ${folderList}
|
|
|
66090
66319
|
path: removeSuffix(target, ".gcp_trigger.json")
|
|
66091
66320
|
});
|
|
66092
66321
|
break;
|
|
66322
|
+
case "azure_trigger":
|
|
66323
|
+
await deleteAzureTrigger({
|
|
66324
|
+
workspace: workspaceId,
|
|
66325
|
+
path: removeSuffix(target, ".azure_trigger.json")
|
|
66326
|
+
});
|
|
66327
|
+
break;
|
|
66093
66328
|
case "email_trigger":
|
|
66094
66329
|
await deleteEmailTrigger({
|
|
66095
66330
|
workspace: workspaceId,
|
|
@@ -66705,6 +66940,7 @@ async function updateScriptSchema(scriptContent, language, metadataContent, path
|
|
|
66705
66940
|
delete metadataContent.has_preprocessor;
|
|
66706
66941
|
}
|
|
66707
66942
|
delete metadataContent.auto_kind;
|
|
66943
|
+
delete metadataContent.no_main_func;
|
|
66708
66944
|
}
|
|
66709
66945
|
function extractWorkspaceDepsAnnotation(scriptContent, language) {
|
|
66710
66946
|
const config = LANG_ANNOTATION_CONFIG[language];
|
|
@@ -70992,6 +71228,45 @@ var init_schedule = __esm(async () => {
|
|
|
70992
71228
|
schedule_default = command15;
|
|
70993
71229
|
});
|
|
70994
71230
|
|
|
71231
|
+
// src/commands/instance/slack.ts
|
|
71232
|
+
async function resolveInstance(instanceName) {
|
|
71233
|
+
if (instanceName) {
|
|
71234
|
+
const match3 = (await allInstances()).find((i) => i.name === instanceName);
|
|
71235
|
+
if (!match3) {
|
|
71236
|
+
throw new Error(`No local instance profile named ${instanceName}`);
|
|
71237
|
+
}
|
|
71238
|
+
return match3;
|
|
71239
|
+
}
|
|
71240
|
+
const activeName = await getActiveInstance({});
|
|
71241
|
+
if (!activeName) {
|
|
71242
|
+
throw new Error("No active instance. Run 'wmill instance add' or pass --instance.");
|
|
71243
|
+
}
|
|
71244
|
+
const match2 = (await allInstances()).find((i) => i.name === activeName);
|
|
71245
|
+
if (!match2) {
|
|
71246
|
+
throw new Error(`Active instance ${activeName} not found in config`);
|
|
71247
|
+
}
|
|
71248
|
+
return match2;
|
|
71249
|
+
}
|
|
71250
|
+
async function connectSlackInstance2(opts) {
|
|
71251
|
+
const instance = await resolveInstance(opts.instance);
|
|
71252
|
+
setClient(instance.token, instance.remote.substring(0, instance.remote.length - 1));
|
|
71253
|
+
await connectSlackInstance({
|
|
71254
|
+
requestBody: {
|
|
71255
|
+
bot_token: opts.botToken,
|
|
71256
|
+
team_id: opts.teamId,
|
|
71257
|
+
team_name: opts.teamName
|
|
71258
|
+
}
|
|
71259
|
+
});
|
|
71260
|
+
info(colors.bold.underline.green(`Slack connected at instance ${instance.name} (team ${opts.teamName} / ${opts.teamId})`));
|
|
71261
|
+
}
|
|
71262
|
+
var init_slack2 = __esm(async () => {
|
|
71263
|
+
init_colors2();
|
|
71264
|
+
init_log();
|
|
71265
|
+
init_client();
|
|
71266
|
+
init_services_gen();
|
|
71267
|
+
await init_instance();
|
|
71268
|
+
});
|
|
71269
|
+
|
|
70995
71270
|
// src/utils/local_encryption.ts
|
|
70996
71271
|
import crypto3 from "node:crypto";
|
|
70997
71272
|
function encode2(input) {
|
|
@@ -71072,6 +71347,10 @@ function migrateToGroupedFormat(settings) {
|
|
|
71072
71347
|
result.slack_name = settings.slack_name;
|
|
71073
71348
|
if (settings.slack_command_script !== undefined)
|
|
71074
71349
|
result.slack_command_script = settings.slack_command_script;
|
|
71350
|
+
if (settings.slack_oauth_client_id !== undefined)
|
|
71351
|
+
result.slack_oauth_client_id = settings.slack_oauth_client_id;
|
|
71352
|
+
if (settings.slack_oauth_client_secret !== undefined)
|
|
71353
|
+
result.slack_oauth_client_secret = settings.slack_oauth_client_secret;
|
|
71075
71354
|
if (settings.auto_invite && typeof settings.auto_invite === "object") {
|
|
71076
71355
|
result.auto_invite = settings.auto_invite;
|
|
71077
71356
|
} else if (settings.auto_invite_enabled !== undefined) {
|
|
@@ -71081,7 +71360,9 @@ function migrateToGroupedFormat(settings) {
|
|
|
71081
71360
|
mode: settings.auto_invite_mode ?? "invite"
|
|
71082
71361
|
};
|
|
71083
71362
|
}
|
|
71084
|
-
if (settings.error_handler
|
|
71363
|
+
if (settings.error_handler === null) {
|
|
71364
|
+
result.error_handler = null;
|
|
71365
|
+
} else if (settings.error_handler && typeof settings.error_handler === "object") {
|
|
71085
71366
|
result.error_handler = settings.error_handler;
|
|
71086
71367
|
} else if (typeof settings.error_handler === "string") {
|
|
71087
71368
|
result.error_handler = {
|
|
@@ -71090,7 +71371,9 @@ function migrateToGroupedFormat(settings) {
|
|
|
71090
71371
|
muted_on_cancel: settings.error_handler_muted_on_cancel ?? false
|
|
71091
71372
|
};
|
|
71092
71373
|
}
|
|
71093
|
-
if (settings.success_handler
|
|
71374
|
+
if (settings.success_handler === null) {
|
|
71375
|
+
result.success_handler = null;
|
|
71376
|
+
} else if (settings.success_handler && typeof settings.success_handler === "object") {
|
|
71094
71377
|
result.success_handler = settings.success_handler;
|
|
71095
71378
|
} else if (typeof settings.success_handler === "string") {
|
|
71096
71379
|
result.success_handler = {
|
|
@@ -71137,7 +71420,9 @@ async function pushWorkspaceSettings(workspace, _path, settings, localSettings)
|
|
|
71137
71420
|
datatable: remoteSettings.datatable,
|
|
71138
71421
|
slack_team_id: remoteSettings.slack_team_id,
|
|
71139
71422
|
slack_name: remoteSettings.slack_name,
|
|
71140
|
-
slack_command_script: remoteSettings.slack_command_script
|
|
71423
|
+
slack_command_script: remoteSettings.slack_command_script,
|
|
71424
|
+
slack_oauth_client_id: remoteSettings.slack_oauth_client_id,
|
|
71425
|
+
slack_oauth_client_secret: remoteSettings.slack_oauth_client_secret
|
|
71141
71426
|
};
|
|
71142
71427
|
} catch (err) {
|
|
71143
71428
|
throw new Error(`Failed to get workspace settings: ${err}`);
|
|
@@ -71309,6 +71594,20 @@ async function pushWorkspaceSettings(workspace, _path, settings, localSettings)
|
|
|
71309
71594
|
}
|
|
71310
71595
|
});
|
|
71311
71596
|
}
|
|
71597
|
+
if (localSettings.slack_oauth_client_id != settings.slack_oauth_client_id || localSettings.slack_oauth_client_secret != settings.slack_oauth_client_secret) {
|
|
71598
|
+
debug(`Updating slack oauth config...`);
|
|
71599
|
+
if (localSettings.slack_oauth_client_id && localSettings.slack_oauth_client_secret) {
|
|
71600
|
+
await setWorkspaceSlackOauthConfig({
|
|
71601
|
+
workspace,
|
|
71602
|
+
requestBody: {
|
|
71603
|
+
slack_oauth_client_id: localSettings.slack_oauth_client_id,
|
|
71604
|
+
slack_oauth_client_secret: localSettings.slack_oauth_client_secret
|
|
71605
|
+
}
|
|
71606
|
+
});
|
|
71607
|
+
} else {
|
|
71608
|
+
await deleteWorkspaceSlackOauthConfig({ workspace });
|
|
71609
|
+
}
|
|
71610
|
+
}
|
|
71312
71611
|
}
|
|
71313
71612
|
async function pushWorkspaceKey(workspace, _path, key, localKey) {
|
|
71314
71613
|
try {
|
|
@@ -72038,6 +72337,7 @@ var init_instance = __esm(async () => {
|
|
|
72038
72337
|
init_sync(),
|
|
72039
72338
|
init_types(),
|
|
72040
72339
|
init_user(),
|
|
72340
|
+
init_slack2(),
|
|
72041
72341
|
init_workspace(),
|
|
72042
72342
|
init_settings(),
|
|
72043
72343
|
init_utils(),
|
|
@@ -72069,7 +72369,7 @@ var init_instance = __esm(async () => {
|
|
|
72069
72369
|
});
|
|
72070
72370
|
await removeInstance(choice);
|
|
72071
72371
|
info(colors.green.underline(`Removed instance ${choice}`));
|
|
72072
|
-
}).command("switch").complete("instance", async () => (await allInstances()).map((x) => x.name)).arguments("<instance:string:instance>").description("Switch the current instance").action(switchI).command("pull").description("Pull instance settings, users, configs, instance groups and overwrite local").option("--yes", "Pull without needing confirmation").option("--dry-run", "Perform a dry run without making changes").option("--skip-users", "Skip pulling users").option("--skip-settings", "Skip pulling settings").option("--skip-configs", "Skip pulling configs (worker groups)").option("--skip-groups", "Skip pulling instance groups").option("--include-workspaces", "Also pull workspaces").option("--folder-per-instance", "Create a folder per instance").option("--instance <instance:string>", "Name of the instance to pull from, override the active instance").option("--prefix <prefix:string>", "Prefix of the local workspaces to pull, used to create the folders when using --include-workspaces").option("--prefix-settings", "Store instance yamls inside prefixed folders when using --prefix and --folder-per-instance").action(instancePull).command("push").description("Push instance settings, users, configs, group and overwrite remote").option("--yes", "Push without needing confirmation").option("--dry-run", "Perform a dry run without making changes").option("--skip-users", "Skip pushing users").option("--skip-settings", "Skip pushing settings").option("--skip-configs", "Skip pushing configs (worker groups)").option("--skip-groups", "Skip pushing instance groups").option("--include-workspaces", "Also push workspaces").option("--folder-per-instance", "Create a folder per instance").option("--instance <instance:string>", "Name of the instance to push to, override the active instance").option("--prefix <prefix:string>", "Prefix of the local workspaces folders to push").option("--prefix-settings", "Store instance yamls inside prefixed folders when using --prefix and --folder-per-instance").action(instancePush).command("whoami").description("Display information about the currently logged-in user").action(whoami3).command("get-config").description("Dump the current instance config (global settings + worker configs) as YAML").option("-o, --output-file <file:string>", "Write YAML to a file instead of stdout").option("--show-secrets", "Include sensitive fields (license key, JWT secret) without prompting").option("--instance <instance:string>", "Name of the instance, override the active instance").action(getConfig2);
|
|
72372
|
+
}).command("switch").complete("instance", async () => (await allInstances()).map((x) => x.name)).arguments("<instance:string:instance>").description("Switch the current instance").action(switchI).command("pull").description("Pull instance settings, users, configs, instance groups and overwrite local").option("--yes", "Pull without needing confirmation").option("--dry-run", "Perform a dry run without making changes").option("--skip-users", "Skip pulling users").option("--skip-settings", "Skip pulling settings").option("--skip-configs", "Skip pulling configs (worker groups)").option("--skip-groups", "Skip pulling instance groups").option("--include-workspaces", "Also pull workspaces").option("--folder-per-instance", "Create a folder per instance").option("--instance <instance:string>", "Name of the instance to pull from, override the active instance").option("--prefix <prefix:string>", "Prefix of the local workspaces to pull, used to create the folders when using --include-workspaces").option("--prefix-settings", "Store instance yamls inside prefixed folders when using --prefix and --folder-per-instance").action(instancePull).command("push").description("Push instance settings, users, configs, group and overwrite remote").option("--yes", "Push without needing confirmation").option("--dry-run", "Perform a dry run without making changes").option("--skip-users", "Skip pushing users").option("--skip-settings", "Skip pushing settings").option("--skip-configs", "Skip pushing configs (worker groups)").option("--skip-groups", "Skip pushing instance groups").option("--include-workspaces", "Also push workspaces").option("--folder-per-instance", "Create a folder per instance").option("--instance <instance:string>", "Name of the instance to push to, override the active instance").option("--prefix <prefix:string>", "Prefix of the local workspaces folders to push").option("--prefix-settings", "Store instance yamls inside prefixed folders when using --prefix and --folder-per-instance").action(instancePush).command("whoami").description("Display information about the currently logged-in user").action(whoami3).command("get-config").description("Dump the current instance config (global settings + worker configs) as YAML").option("-o, --output-file <file:string>", "Write YAML to a file instead of stdout").option("--show-secrets", "Include sensitive fields (license key, JWT secret) without prompting").option("--instance <instance:string>", "Name of the instance, override the active instance").action(getConfig2).command("connect-slack").description("Non-interactively connect Slack at the instance level using a pre-minted bot token (xoxb-...). Produces the same artifacts as the UI OAuth flow: global_settings 'slack' row + encrypted f/slack_bot/global_bot_token variable and resource in the admins workspace.").option("--bot-token <bot_token:string>", "Slack bot token (xoxb-...)", { required: true }).option("--team-id <team_id:string>", "Slack team id", { required: true }).option("--team-name <team_name:string>", "Slack team name", { required: true }).option("--instance <instance:string>", "Instance profile to connect against (defaults to the active instance)").action((opts) => connectSlackInstance2(opts));
|
|
72073
72373
|
instance_default = command16;
|
|
72074
72374
|
});
|
|
72075
72375
|
|
|
@@ -72525,6 +72825,7 @@ async function getTrigger(triggerType, workspace, path19) {
|
|
|
72525
72825
|
mqtt: getMqttTrigger,
|
|
72526
72826
|
sqs: getSqsTrigger,
|
|
72527
72827
|
gcp: getGcpTrigger,
|
|
72828
|
+
azure: getAzureTrigger,
|
|
72528
72829
|
email: getEmailTrigger
|
|
72529
72830
|
};
|
|
72530
72831
|
const triggerFunction = triggerFunctions[triggerType];
|
|
@@ -72541,6 +72842,7 @@ async function updateTrigger(triggerType, workspace, path19, trigger) {
|
|
|
72541
72842
|
mqtt: updateMqttTrigger,
|
|
72542
72843
|
sqs: updateSqsTrigger,
|
|
72543
72844
|
gcp: updateGcpTrigger,
|
|
72845
|
+
azure: updateAzureTrigger,
|
|
72544
72846
|
email: updateEmailTrigger
|
|
72545
72847
|
};
|
|
72546
72848
|
const triggerFunction = triggerFunctions[triggerType];
|
|
@@ -72556,6 +72858,7 @@ async function createTrigger(triggerType, workspace, path19, trigger) {
|
|
|
72556
72858
|
mqtt: createMqttTrigger,
|
|
72557
72859
|
sqs: createSqsTrigger,
|
|
72558
72860
|
gcp: createGcpTrigger,
|
|
72861
|
+
azure: createAzureTrigger,
|
|
72559
72862
|
email: createEmailTrigger
|
|
72560
72863
|
};
|
|
72561
72864
|
const triggerFunction = triggerFunctions[triggerType];
|
|
@@ -72799,6 +73102,7 @@ async function list11(opts) {
|
|
|
72799
73102
|
mqttTriggers,
|
|
72800
73103
|
sqsTriggers,
|
|
72801
73104
|
gcpTriggers,
|
|
73105
|
+
azureTriggers,
|
|
72802
73106
|
emailTriggers
|
|
72803
73107
|
] = await Promise.all([
|
|
72804
73108
|
listOrEmpty(() => listHttpTriggers({ workspace: ws })),
|
|
@@ -72809,6 +73113,7 @@ async function list11(opts) {
|
|
|
72809
73113
|
listOrEmpty(() => listMqttTriggers({ workspace: ws })),
|
|
72810
73114
|
listOrEmpty(() => listSqsTriggers({ workspace: ws })),
|
|
72811
73115
|
listOrEmpty(() => listGcpTriggers({ workspace: ws })),
|
|
73116
|
+
listOrEmpty(() => listAzureTriggers({ workspace: ws })),
|
|
72812
73117
|
listOrEmpty(() => listEmailTriggers({ workspace: ws }))
|
|
72813
73118
|
]);
|
|
72814
73119
|
const triggers = [
|
|
@@ -72820,6 +73125,7 @@ async function list11(opts) {
|
|
|
72820
73125
|
...mqttTriggers.map((x) => ({ path: x.path, kind: "mqtt" })),
|
|
72821
73126
|
...sqsTriggers.map((x) => ({ path: x.path, kind: "sqs" })),
|
|
72822
73127
|
...gcpTriggers.map((x) => ({ path: x.path, kind: "gcp" })),
|
|
73128
|
+
...azureTriggers.map((x) => ({ path: x.path, kind: "azure" })),
|
|
72823
73129
|
...emailTriggers.map((x) => ({ path: x.path, kind: "email" }))
|
|
72824
73130
|
];
|
|
72825
73131
|
if (opts.json) {
|
|
@@ -72835,12 +73141,13 @@ function checkIfValidTrigger(kind) {
|
|
|
72835
73141
|
return false;
|
|
72836
73142
|
}
|
|
72837
73143
|
}
|
|
72838
|
-
function extractTriggerKindFromPath(filePath) {
|
|
73144
|
+
async function extractTriggerKindFromPath(filePath) {
|
|
72839
73145
|
let pathToAnalyze = filePath;
|
|
72840
73146
|
if (isWorkspaceSpecificFile(filePath)) {
|
|
72841
73147
|
const currentBranch = getCurrentGitBranch();
|
|
72842
73148
|
if (currentBranch) {
|
|
72843
|
-
|
|
73149
|
+
const wsName = await resolveWsNameForGitBranch(currentBranch);
|
|
73150
|
+
pathToAnalyze = fromWorkspaceSpecificPath(filePath, wsName);
|
|
72844
73151
|
}
|
|
72845
73152
|
}
|
|
72846
73153
|
const triggerMatch = pathToAnalyze.match(/\.(\w+)_trigger\.yaml$/);
|
|
@@ -72857,7 +73164,7 @@ async function push10(opts, filePath, remotePath) {
|
|
|
72857
73164
|
throw new Error("file path must refer to a file.");
|
|
72858
73165
|
}
|
|
72859
73166
|
console.log(colors.bold.yellow("Pushing trigger..."));
|
|
72860
|
-
const triggerKind = extractTriggerKindFromPath(filePath);
|
|
73167
|
+
const triggerKind = await extractTriggerKindFromPath(filePath);
|
|
72861
73168
|
if (!checkIfValidTrigger(triggerKind)) {
|
|
72862
73169
|
throw new Error("Invalid trigger kind: " + triggerKind);
|
|
72863
73170
|
}
|
|
@@ -72953,6 +73260,15 @@ var init_trigger = __esm(async () => {
|
|
|
72953
73260
|
subscription_mode: "create_update",
|
|
72954
73261
|
enabled: false
|
|
72955
73262
|
},
|
|
73263
|
+
azure: {
|
|
73264
|
+
script_path: "",
|
|
73265
|
+
is_flow: false,
|
|
73266
|
+
azure_resource_path: "",
|
|
73267
|
+
azure_mode: "namespace_pull",
|
|
73268
|
+
scope_resource_id: "",
|
|
73269
|
+
subscription_name: "",
|
|
73270
|
+
enabled: false
|
|
73271
|
+
},
|
|
72956
73272
|
email: {
|
|
72957
73273
|
script_path: "",
|
|
72958
73274
|
is_flow: false,
|
|
@@ -72961,7 +73277,7 @@ var init_trigger = __esm(async () => {
|
|
|
72961
73277
|
}
|
|
72962
73278
|
};
|
|
72963
73279
|
TRIGGER_SKIP_FIELDS = new Set(["workspace_id", "extra_perms", "edited_by", "edited_at"]);
|
|
72964
|
-
command19 = new Command().description("trigger related commands").option("--json", "Output as JSON (for piping to jq)").action(list11).command("list", "list all triggers").option("--json", "Output as JSON (for piping to jq)").action(list11).command("get", "get a trigger's details").arguments("<path:string>").option("--json", "Output as JSON (for piping to jq)").option("--kind <kind:string>", "Trigger kind (http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, email). Recommended for faster lookup").action(get8).command("new", "create a new trigger locally").arguments("<path:string>").option("--kind <kind:string>", "Trigger kind (required: http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, email)").action(newTrigger).command("push", "push a local trigger spec. This overrides any remote versions.").arguments("<file_path:string> <remote_path:string>").action(push10).command("set-permissioned-as", "Set the email (run-as user) for a trigger (requires admin or wm_deployers group)").arguments("<path:string> <email:string>").option("--kind <kind:string>", "Trigger kind (required: http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, email)").action(async (opts, triggerPath, email) => {
|
|
73280
|
+
command19 = new Command().description("trigger related commands").option("--json", "Output as JSON (for piping to jq)").action(list11).command("list", "list all triggers").option("--json", "Output as JSON (for piping to jq)").action(list11).command("get", "get a trigger's details").arguments("<path:string>").option("--json", "Output as JSON (for piping to jq)").option("--kind <kind:string>", "Trigger kind (http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, azure, email). Recommended for faster lookup").action(get8).command("new", "create a new trigger locally").arguments("<path:string>").option("--kind <kind:string>", "Trigger kind (required: http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, azure, email)").action(newTrigger).command("push", "push a local trigger spec. This overrides any remote versions.").arguments("<file_path:string> <remote_path:string>").action(push10).command("set-permissioned-as", "Set the email (run-as user) for a trigger (requires admin or wm_deployers group)").arguments("<path:string> <email:string>").option("--kind <kind:string>", "Trigger kind (required: http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, azure, email)").action(async (opts, triggerPath, email) => {
|
|
72965
73281
|
const workspace = await resolveWorkspace(opts);
|
|
72966
73282
|
await requireLogin(opts);
|
|
72967
73283
|
if (!opts.kind) {
|
|
@@ -73088,6 +73404,8 @@ async function pushObj(workspace, p, befObj, newObj, plainSecrets, alreadySynced
|
|
|
73088
73404
|
await pushTrigger("sqs", workspace, p, befObj, newObj, permissionedAsContext);
|
|
73089
73405
|
} else if (typeEnding === "gcp_trigger") {
|
|
73090
73406
|
await pushTrigger("gcp", workspace, p, befObj, newObj, permissionedAsContext);
|
|
73407
|
+
} else if (typeEnding === "azure_trigger") {
|
|
73408
|
+
await pushTrigger("azure", workspace, p, befObj, newObj, permissionedAsContext);
|
|
73091
73409
|
} else if (typeEnding === "email_trigger") {
|
|
73092
73410
|
await pushTrigger("email", workspace, p, befObj, newObj, permissionedAsContext);
|
|
73093
73411
|
} else if (typeEnding === "native_trigger") {
|
|
@@ -73154,7 +73472,7 @@ function getTypeStrFromPath(p) {
|
|
|
73154
73472
|
if (typeEnding?.endsWith("_native_trigger")) {
|
|
73155
73473
|
return "native_trigger";
|
|
73156
73474
|
}
|
|
73157
|
-
if (typeEnding === "script" || typeEnding === "variable" || typeEnding === "resource" || typeEnding === "resource-type" || typeEnding === "app" || typeEnding === "schedule" || typeEnding === "http_trigger" || typeEnding === "websocket_trigger" || typeEnding === "kafka_trigger" || typeEnding === "nats_trigger" || typeEnding === "postgres_trigger" || typeEnding === "mqtt_trigger" || typeEnding === "sqs_trigger" || typeEnding === "gcp_trigger" || typeEnding === "email_trigger" || typeEnding === "user" || typeEnding === "group" || typeEnding === "settings" || typeEnding === "encryption_key") {
|
|
73475
|
+
if (typeEnding === "script" || typeEnding === "variable" || typeEnding === "resource" || typeEnding === "resource-type" || typeEnding === "app" || typeEnding === "schedule" || typeEnding === "http_trigger" || typeEnding === "websocket_trigger" || typeEnding === "kafka_trigger" || typeEnding === "nats_trigger" || typeEnding === "postgres_trigger" || typeEnding === "mqtt_trigger" || typeEnding === "sqs_trigger" || typeEnding === "gcp_trigger" || typeEnding === "azure_trigger" || typeEnding === "email_trigger" || typeEnding === "user" || typeEnding === "group" || typeEnding === "settings" || typeEnding === "encryption_key") {
|
|
73158
73476
|
return typeEnding;
|
|
73159
73477
|
} else {
|
|
73160
73478
|
throw new Error("Could not infer type of path " + JSON.stringify(parsed));
|
|
@@ -73230,6 +73548,7 @@ var init_types = __esm(async () => {
|
|
|
73230
73548
|
"mqtt",
|
|
73231
73549
|
"sqs",
|
|
73232
73550
|
"gcp",
|
|
73551
|
+
"azure",
|
|
73233
73552
|
"email"
|
|
73234
73553
|
];
|
|
73235
73554
|
});
|
|
@@ -81663,7 +81982,7 @@ Reference a specific resource using \`$res:\` prefix:
|
|
|
81663
81982
|
|
|
81664
81983
|
## OpenFlow Schema
|
|
81665
81984
|
|
|
81666
|
-
{"OpenFlow":{"type":"object","description":"Top-level flow definition containing metadata, configuration, and the flow structure","properties":{"summary":{"type":"string","description":"Short description of what this flow does"},"description":{"type":"string","description":"Detailed documentation for this flow"},"value":{"$ref":"#/components/schemas/FlowValue"},"schema":{"type":"object","description":"JSON Schema for flow inputs. Use this to define input parameters, their types, defaults, and validation. For resource inputs, set type to 'object' and format to 'resource-<type>' (e.g., 'resource-stripe')"},"on_behalf_of_email":{"type":"string","description":"The flow will be run with the permissions of the user with this email."}},"required":["summary","value"]},"FlowValue":{"type":"object","description":"The flow structure containing modules and optional preprocessor/failure handlers","properties":{"modules":{"type":"array","description":"Array of steps that execute in sequence. Each step can be a script, subflow, loop, or branch","items":{"$ref":"#/components/schemas/FlowModule"}},"failure_module":{"description":"Special module that executes when the flow fails. Receives error object with message, name, stack, and step_id. Must have id 'failure'. Only supports script/rawscript types","$ref":"#/components/schemas/FlowModule"},"preprocessor_module":{"description":"Special module that runs before the first step on external triggers. Must have id 'preprocessor'. Only supports script/rawscript types. Cannot reference other step results","$ref":"#/components/schemas/FlowModule"},"same_worker":{"type":"boolean","description":"If true, all steps run on the same worker for better performance"},"concurrent_limit":{"type":"number","description":"Maximum number of concurrent executions of this flow"},"concurrency_key":{"type":"string","description":"Expression to group concurrent executions (e.g., by user ID)"},"concurrency_time_window_s":{"type":"number","description":"Time window in seconds for concurrent_limit"},"debounce_delay_s":{"type":"integer","description":"Delay in seconds to debounce flow executions"},"debounce_key":{"type":"string","description":"Expression to group debounced executions"},"debounce_args_to_accumulate":{"type":"array","description":"Arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"integer","description":"Maximum total time in seconds that a job can be debounced"},"max_total_debounces_amount":{"type":"integer","description":"Maximum number of times a job can be debounced"},"skip_expr":{"type":"string","description":"JavaScript expression to conditionally skip the entire flow"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for flow results"},"cache_ignore_s3_path":{"type":"boolean"},"delete_after_secs":{"type":"integer","description":"If set, delete the flow job's args, result and logs after this many seconds following job completion"},"flow_env":{"type":"object","description":"Environment variables available to all steps. Values can be strings, JSON values, or special references: '$var:path' (workspace variable) or '$res:path' (resource).","additionalProperties":{}},"priority":{"type":"number","description":"Execution priority (higher numbers run first)"},"early_return":{"type":"string","description":"JavaScript expression to return early from the flow"},"chat_input_enabled":{"type":"boolean","description":"Whether this flow accepts chat-style input"},"notes":{"type":"array","description":"Sticky notes attached to the flow","items":{"$ref":"#/components/schemas/FlowNote"}},"groups":{"type":"array","description":"Semantic groups of modules for organizational purposes","items":{"$ref":"#/components/schemas/FlowGroup"}}},"required":["modules"]},"Retry":{"type":"object","description":"Retry configuration for failed module executions","properties":{"constant":{"type":"object","description":"Retry with constant delay between attempts","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"seconds":{"type":"integer","description":"Seconds to wait between retries"}}},"exponential":{"type":"object","description":"Retry with exponential backoff (delay doubles each time)","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"multiplier":{"type":"integer","description":"Multiplier for exponential backoff"},"seconds":{"type":"integer","minimum":1,"description":"Initial delay in seconds"},"random_factor":{"type":"integer","minimum":0,"maximum":100,"description":"Random jitter percentage (0-100) to avoid thundering herd"}}},"retry_if":{"$ref":"#/components/schemas/RetryIf"}}},"FlowNote":{"type":"object","description":"A sticky note attached to a flow for documentation and annotation","properties":{"id":{"type":"string","description":"Unique identifier for the note"},"text":{"type":"string","description":"Content of the note"},"position":{"type":"object","description":"Position of the note in the flow editor","properties":{"x":{"type":"number","description":"X coordinate"},"y":{"type":"number","description":"Y coordinate"}},"required":["x","y"]},"size":{"type":"object","description":"Size of the note in the flow editor","properties":{"width":{"type":"number","description":"Width in pixels"},"height":{"type":"number","description":"Height in pixels"}},"required":["width","height"]},"color":{"type":"string","description":"Color of the note (e.g., \\"yellow\\", \\"#ffff00\\")"},"type":{"type":"string","enum":["free","group"],"description":"Type of note - 'free' for standalone notes, 'group' for notes that group other nodes"},"locked":{"type":"boolean","default":false,"description":"Whether the note is locked and cannot be edited or moved"},"contained_node_ids":{"type":"array","items":{"type":"string"},"description":"For group notes, the IDs of nodes contained within this group"}},"required":["id","text","color","type"]},"FlowGroup":{"type":"object","description":"A semantic group of flow modules for organizational purposes. Does not affect execution \\u2014 modules remain in their original position in the flow. Groups provide naming and collapsibility in the editor. Members are computed dynamically from all nodes on paths between start_id and end_id.","properties":{"summary":{"type":"string","description":"Display name for this group"},"note":{"type":"string","description":"Markdown note shown below the group header"},"autocollapse":{"type":"boolean","default":false,"description":"If true, this group is collapsed by default in the flow editor. UI hint only."},"start_id":{"type":"string","description":"ID of the first flow module in this group (topological entry point)"},"end_id":{"type":"string","description":"ID of the last flow module in this group (topological exit point)"},"color":{"type":"string","description":"Color for the group in the flow editor"}},"required":["start_id","end_id"]},"RetryIf":{"type":"object","description":"Conditional retry based on error or result","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to retry. Has access to 'result' and 'error' variables"}},"required":["expr"]},"StopAfterIf":{"type":"object","description":"Early termination condition for a module","properties":{"skip_if_stopped":{"type":"boolean","description":"If true, following steps are skipped when this condition triggers"},"expr":{"type":"string","description":"JavaScript expression evaluated after the module runs. Can use 'result' (step's result) or 'flow_input'. Return true to stop"},"error_message":{"type":"string","nullable":true,"description":"Custom error message when stopping with an error. Mutually exclusive with skip_if_stopped. If set to a non-empty string, the flow stops with this error. If empty string, a default error message is used. If null or omitted, no error is raised."}},"required":["expr"]},"FlowModule":{"type":"object","description":"A single step in a flow. Can be a script, subflow, loop, or branch","properties":{"id":{"type":"string","description":"Unique identifier for this step. Used to reference results via 'results.step_id'. Must be a valid identifier (alphanumeric, underscore, hyphen)"},"value":{"$ref":"#/components/schemas/FlowModuleValue"},"stop_after_if":{"description":"Early termination condition evaluated after this step completes","$ref":"#/components/schemas/StopAfterIf"},"stop_after_all_iters_if":{"description":"For loops only - early termination condition evaluated after all iterations complete","$ref":"#/components/schemas/StopAfterIf"},"skip_if":{"type":"object","description":"Conditionally skip this step based on previous results or flow inputs","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to skip. Can use 'flow_input' or 'results.<step_id>'"}},"required":["expr"]},"sleep":{"description":"Delay before executing this step (in seconds or as expression)","$ref":"#/components/schemas/InputTransform"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for this step's results"},"cache_ignore_s3_path":{"type":"boolean"},"timeout":{"description":"Maximum execution time in seconds (static value or expression)","$ref":"#/components/schemas/InputTransform"},"delete_after_secs":{"type":"integer","description":"If set, delete the step's args, result and logs after this many seconds following job completion"},"summary":{"type":"string","description":"Short description of what this step does"},"mock":{"type":"object","description":"Mock configuration for testing without executing the actual step","properties":{"enabled":{"type":"boolean","description":"If true, return mock value instead of executing"},"return_value":{"description":"Value to return when mocked"}}},"suspend":{"type":"object","description":"Configuration for approval/resume steps that wait for user input","properties":{"required_events":{"type":"integer","description":"Number of approvals required before continuing"},"timeout":{"type":"integer","description":"Timeout in seconds before auto-continuing or canceling"},"resume_form":{"type":"object","description":"Form schema for collecting input when resuming","properties":{"schema":{"type":"object","description":"JSON Schema for the resume form"}}},"user_auth_required":{"type":"boolean","description":"If true, only authenticated users can approve"},"user_groups_required":{"description":"Expression or list of groups that can approve","$ref":"#/components/schemas/InputTransform"},"self_approval_disabled":{"type":"boolean","description":"If true, the user who started the flow cannot approve"},"hide_cancel":{"type":"boolean","description":"If true, hide the cancel button on the approval form"},"continue_on_disapprove_timeout":{"type":"boolean","description":"If true, continue flow on timeout instead of canceling"}}},"priority":{"type":"number","description":"Execution priority for this step (higher numbers run first)"},"continue_on_error":{"type":"boolean","description":"If true, flow continues even if this step fails"},"retry":{"description":"Retry configuration if this step fails","$ref":"#/components/schemas/Retry"},"debouncing":{"description":"Debounce configuration for this step (EE only)","type":"object","properties":{"debounce_delay_s":{"type":"integer","description":"Delay in seconds to debounce this step's executions across flow runs"},"debounce_key":{"type":"string","description":"Expression to group debounced executions. Supports $workspace and $args[name]. Default: $workspace/flow/<flow_path>-<step_id>"},"debounce_args_to_accumulate":{"type":"array","description":"Array-type arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"integer","description":"Maximum total time in seconds before forced execution"},"max_total_debounces_amount":{"type":"integer","description":"Maximum number of debounces before forced execution"}}}},"required":["value","id"]},"InputTransform":{"description":"Maps input parameters for a step. Can be a static value or a JavaScript expression that references previous results or flow inputs","oneOf":[{"$ref":"#/components/schemas/StaticTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"StaticTransform":{"type":"object","description":"Static value passed directly to the step. Use for hardcoded values or resource references like '$res:path/to/resource'","properties":{"value":{"description":"The static value. For resources, use format '$res:path/to/resource'"},"type":{"type":"string","enum":["static"]}},"required":["type"]},"JavascriptTransform":{"type":"object","description":"JavaScript expression evaluated at runtime. Can reference previous step results via 'results.step_id' or flow inputs via 'flow_input.property'. Inside loops, use 'flow_input.iter.value' for the current iteration value","properties":{"expr":{"type":"string","description":"JavaScript expression returning the value. Available variables - results (object with all previous step results), flow_input (flow inputs), flow_input.iter (in loops)"},"type":{"type":"string","enum":["javascript"]}},"required":["expr","type"]},"AiTransform":{"type":"object","description":"Value resolved by the AI runtime for this input. The AI engine decides how to satisfy the parameter.","properties":{"type":{"type":"string","enum":["ai"]}},"required":["type"]},"AIProviderKind":{"type":"string","description":"Supported AI provider types","enum":["openai","azure_openai","anthropic","mistral","deepseek","googleai","groq","openrouter","togetherai","customai","aws_bedrock"]},"ProviderConfig":{"type":"object","description":"Complete AI provider configuration with resource reference and model selection","properties":{"kind":{"$ref":"#/components/schemas/AIProviderKind"},"resource":{"type":"string","description":"Resource reference in format '$res:{resource_path}' pointing to provider credentials"},"model":{"type":"string","description":"Model identifier (e.g., 'gpt-4', 'claude-3-opus-20240229', 'gemini-pro')"}},"required":["kind","resource","model"]},"StaticProviderTransform":{"type":"object","description":"Static provider configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/ProviderConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"ProviderTransform":{"description":"Provider configuration - can be static (ProviderConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticProviderTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticProviderTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"MemoryOff":{"type":"object","description":"No conversation memory/context","properties":{"kind":{"type":"string","enum":["off"]}},"required":["kind"]},"MemoryAuto":{"type":"object","description":"Automatic context management","properties":{"kind":{"type":"string","enum":["auto"]},"context_length":{"type":"integer","description":"Maximum number of messages to retain in context"},"memory_id":{"type":"string","description":"Identifier for persistent memory across agent invocations"}},"required":["kind"]},"MemoryMessage":{"type":"object","description":"A single message in conversation history","properties":{"role":{"type":"string","enum":["user","assistant","system"]},"content":{"type":"string"}},"required":["role","content"]},"MemoryManual":{"type":"object","description":"Explicit message history","properties":{"kind":{"type":"string","enum":["manual"]},"messages":{"type":"array","items":{"$ref":"#/components/schemas/MemoryMessage"}}},"required":["kind","messages"]},"MemoryConfig":{"description":"Conversation memory configuration","oneOf":[{"$ref":"#/components/schemas/MemoryOff"},{"$ref":"#/components/schemas/MemoryAuto"},{"$ref":"#/components/schemas/MemoryManual"}],"discriminator":{"propertyName":"kind","mapping":{"off":"#/components/schemas/MemoryOff","auto":"#/components/schemas/MemoryAuto","manual":"#/components/schemas/MemoryManual"}}},"StaticMemoryTransform":{"type":"object","description":"Static memory configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/MemoryConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"MemoryTransform":{"description":"Memory configuration - can be static (MemoryConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticMemoryTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticMemoryTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"FlowModuleValue":{"description":"The actual implementation of a flow step. Can be a script (inline or referenced), subflow, loop, branch, or special module type","oneOf":[{"$ref":"#/components/schemas/RawScript"},{"$ref":"#/components/schemas/PathScript"},{"$ref":"#/components/schemas/PathFlow"},{"$ref":"#/components/schemas/ForloopFlow"},{"$ref":"#/components/schemas/WhileloopFlow"},{"$ref":"#/components/schemas/BranchOne"},{"$ref":"#/components/schemas/BranchAll"},{"$ref":"#/components/schemas/Identity"},{"$ref":"#/components/schemas/AiAgent"}],"discriminator":{"propertyName":"type","mapping":{"rawscript":"#/components/schemas/RawScript","script":"#/components/schemas/PathScript","flow":"#/components/schemas/PathFlow","forloopflow":"#/components/schemas/ForloopFlow","whileloopflow":"#/components/schemas/WhileloopFlow","branchone":"#/components/schemas/BranchOne","branchall":"#/components/schemas/BranchAll","identity":"#/components/schemas/Identity","aiagent":"#/components/schemas/AiAgent"}}},"RawScript":{"type":"object","description":"Inline script with code defined directly in the flow. Use 'bun' as default language if unspecified. The script receives arguments from input_transforms","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"content":{"type":"string","description":"The script source code. Should export a 'main' function"},"language":{"type":"string","description":"Programming language for this script","enum":["deno","bun","python3","go","bash","powershell","postgresql","mysql","bigquery","snowflake","mssql","oracledb","graphql","nativets","php","rust","ansible","csharp","nu","java","ruby","rlang","duckdb"]},"path":{"type":"string","description":"Optional path for saving this script"},"lock":{"type":"string","description":"Lock file content for dependencies"},"type":{"type":"string","enum":["rawscript"]},"tag":{"type":"string","description":"Worker group tag for execution routing"},"concurrent_limit":{"type":"number","description":"Maximum concurrent executions of this script"},"concurrency_time_window_s":{"type":"number","description":"Time window for concurrent_limit"},"custom_concurrency_key":{"type":"string","description":"Custom key for grouping concurrent executions"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"},"assets":{"type":"array","description":"External resources this script accesses (S3 objects, resources, etc.)","items":{"type":"object","required":["path","kind"],"properties":{"path":{"type":"string","description":"Path to the asset"},"kind":{"type":"string","description":"Type of asset","enum":["s3object","resource","ducklake","datatable","volume"]},"access_type":{"type":"string","nullable":true,"description":"Access level for this asset","enum":["r","w","rw"]},"alt_access_type":{"type":"string","nullable":true,"description":"Alternative access level","enum":["r","w","rw"]}}}}},"required":["type","content","language","input_transforms"]},"PathScript":{"type":"object","description":"Reference to an existing script by path. Use this when calling a previously saved script instead of writing inline code","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the script in the workspace (e.g., 'f/scripts/send_email')"},"hash":{"type":"string","description":"Optional specific version hash of the script to use"},"type":{"type":"string","enum":["script"]},"tag_override":{"type":"string","description":"Override the script's default worker group tag"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"}},"required":["type","path","input_transforms"]},"PathFlow":{"type":"object","description":"Reference to an existing flow by path. Use this to call another flow as a subflow","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the subflow's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the flow in the workspace (e.g., 'f/flows/process_user')"},"type":{"type":"string","enum":["flow"]}},"required":["type","path","input_transforms"]},"ForloopFlow":{"type":"object","description":"Executes nested modules in a loop over an iterator. Inside the loop, use 'flow_input.iter.value' to access the current iteration value, and 'flow_input.iter.index' for the index. Supports parallel execution for better performance on I/O-bound operations","properties":{"modules":{"type":"array","description":"Steps to execute for each iteration. These can reference the iteration value via 'flow_input.iter.value'","items":{"$ref":"#/components/schemas/FlowModule"}},"iterator":{"description":"JavaScript expression that returns an array to iterate over. Can reference 'results.step_id' or 'flow_input'","$ref":"#/components/schemas/InputTransform"},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["forloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (faster for I/O-bound operations). Use with parallelism to control concurrency"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true. Limits resource usage. Can be static number or expression","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","iterator","skip_failures","type"]},"WhileloopFlow":{"type":"object","description":"Executes nested modules repeatedly while a condition is true. The loop checks the condition after each iteration. Use stop_after_if on modules to control loop termination","properties":{"modules":{"type":"array","description":"Steps to execute in each iteration. Use stop_after_if to control when the loop ends","items":{"$ref":"#/components/schemas/FlowModule"}},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["whileloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (use with caution in while loops)"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","skip_failures","type"]},"BranchOne":{"type":"object","description":"Conditional branching where only the first matching branch executes. Branches are evaluated in order, and the first one with a true expression runs. If no branches match, the default branch executes","properties":{"branches":{"type":"array","description":"Array of branches to evaluate in order. The first branch with expr evaluating to true executes","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch condition"},"expr":{"type":"string","description":"JavaScript expression that returns boolean. Can use 'results.step_id' or 'flow_input'. First true expr wins"},"modules":{"type":"array","description":"Steps to execute if this branch's expr is true","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules","expr"]}},"default":{"type":"array","description":"Steps to execute if no branch expressions match","items":{"$ref":"#/components/schemas/FlowModule"}},"type":{"type":"string","enum":["branchone"]}},"required":["branches","default","type"]},"BranchAll":{"type":"object","description":"Parallel branching where all branches execute simultaneously. Unlike BranchOne, all branches run regardless of conditions. Useful for executing independent tasks concurrently","properties":{"branches":{"type":"array","description":"Array of branches that all execute (either in parallel or sequentially)","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch's purpose"},"skip_failure":{"type":"boolean","description":"If true, failure in this branch doesn't fail the entire flow"},"modules":{"type":"array","description":"Steps to execute in this branch","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules"]}},"type":{"type":"string","enum":["branchall"]},"parallel":{"type":"boolean","description":"If true, all branches execute concurrently. If false, they execute sequentially"}},"required":["branches","type"]},"AgentTool":{"type":"object","description":"A tool available to an AI agent. Can be a flow module or an external MCP (Model Context Protocol) tool","properties":{"id":{"type":"string","description":"Unique identifier for this tool. Cannot contain spaces - use underscores instead (e.g., 'get_user_data' not 'get user data')"},"summary":{"type":"string","description":"Short description of what this tool does (shown to the AI)"},"value":{"$ref":"#/components/schemas/ToolValue"}},"required":["id","value"]},"ToolValue":{"description":"The implementation of a tool. Can be a flow module (script/flow) or an MCP tool reference","oneOf":[{"$ref":"#/components/schemas/FlowModuleTool"},{"$ref":"#/components/schemas/McpToolValue"},{"$ref":"#/components/schemas/WebsearchToolValue"}],"discriminator":{"propertyName":"tool_type","mapping":{"flowmodule":"#/components/schemas/FlowModuleTool","mcp":"#/components/schemas/McpToolValue","websearch":"#/components/schemas/WebsearchToolValue"}}},"FlowModuleTool":{"description":"A tool implemented as a flow module (script, flow, etc.). The AI can call this like any other flow module","allOf":[{"type":"object","properties":{"tool_type":{"type":"string","enum":["flowmodule"]}},"required":["tool_type"]},{"$ref":"#/components/schemas/FlowModuleValue"}]},"WebsearchToolValue":{"type":"object","description":"A tool implemented as a websearch tool. The AI can call this like any other websearch tool","properties":{"tool_type":{"type":"string","enum":["websearch"]}},"required":["tool_type"]},"McpToolValue":{"type":"object","description":"Reference to an external MCP (Model Context Protocol) tool. The AI can call tools from MCP servers","properties":{"tool_type":{"type":"string","enum":["mcp"]},"resource_path":{"type":"string","description":"Path to the MCP resource/server configuration"},"include_tools":{"type":"array","description":"Whitelist of specific tools to include from this MCP server","items":{"type":"string"}},"exclude_tools":{"type":"array","description":"Blacklist of tools to exclude from this MCP server","items":{"type":"string"}}},"required":["tool_type","resource_path"]},"AiAgent":{"type":"object","description":"AI agent step that can use tools to accomplish tasks. The agent receives inputs and can call any of its configured tools to complete the task","properties":{"input_transforms":{"type":"object","description":"Input parameters for the AI agent mapped to their values","properties":{"provider":{"$ref":"#/components/schemas/ProviderTransform"},"output_type":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Output format type.\\nValid values: 'text' (default) - plain text response, 'image' - image generation\\n"},"user_message":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"The user's prompt/message to the AI agent. Supports variable interpolation with flow.input syntax."},"system_prompt":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"System instructions that guide the AI's behavior, persona, and response style. Optional."},"streaming":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Boolean. If true, stream the AI response incrementally.\\nStreaming events include: token_delta, tool_call, tool_call_arguments, tool_execution, tool_result\\n"},"memory":{"$ref":"#/components/schemas/MemoryTransform"},"output_schema":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"JSON Schema object defining structured output format. Used when you need the AI to return data in a specific shape.\\nSupports standard JSON Schema properties: type, properties, required, items, enum, pattern, minLength, maxLength, minimum, maximum, etc.\\nExample: { type: 'object', properties: { name: { type: 'string' }, age: { type: 'integer' } }, required: ['name'] }\\n"},"user_attachments":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Array of file references (images or PDFs) for the AI agent.\\nFormat: Array<{ bucket: string, key: string }> - S3 object references\\nExample: [{ bucket: 'my-bucket', key: 'documents/report.pdf' }]\\n"},"max_completion_tokens":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Integer. Maximum number of tokens the AI will generate in its response.\\nRange: 1 to 4,294,967,295. Typical values: 256-4096 for most use cases.\\n"},"temperature":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Float. Controls randomness/creativity of responses.\\nRange: 0.0 to 2.0 (provider-dependent)\\n- 0.0 = deterministic, focused responses\\n- 0.7 = balanced (common default)\\n- 1.0+ = more creative/random\\n"}},"required":["provider","user_message","output_type"]},"tools":{"type":"array","description":"Array of tools the agent can use. The agent decides which tools to call based on the task","items":{"$ref":"#/components/schemas/AgentTool"}},"type":{"type":"string","enum":["aiagent"]},"parallel":{"type":"boolean","description":"If true, the agent can execute multiple tool calls in parallel"}},"required":["tools","type","input_transforms"]},"Identity":{"type":"object","description":"Pass-through module that returns its input unchanged. Useful for flow structure or as a placeholder","properties":{"type":{"type":"string","enum":["identity"]},"flow":{"type":"boolean","description":"If true, marks this as a flow identity (special handling)"}},"required":["type"]},"FlowStatus":{"type":"object","properties":{"step":{"type":"integer"},"modules":{"type":"array","items":{"$ref":"#/components/schemas/FlowStatusModule"}},"user_states":{"additionalProperties":true},"preprocessor_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"}]},"failure_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"},{"type":"object","properties":{"parent_module":{"type":"string"}}}]},"retry":{"type":"object","properties":{"fail_count":{"type":"integer"},"failed_jobs":{"type":"array","items":{"type":"string","format":"uuid"}}}}},"required":["step","modules","failure_module"]},"FlowStatusModule":{"type":"object","properties":{"type":{"type":"string","enum":["WaitingForPriorSteps","WaitingForEvents","WaitingForExecutor","InProgress","Success","Failure"]},"id":{"type":"string"},"job":{"type":"string","format":"uuid"},"count":{"type":"integer"},"progress":{"type":"integer"},"iterator":{"type":"object","properties":{"index":{"type":"integer"},"itered":{"type":"array","items":{}},"itered_len":{"type":"integer"},"args":{}}},"flow_jobs":{"type":"array","items":{"type":"string"}},"flow_jobs_success":{"type":"array","items":{"type":"boolean"}},"flow_jobs_duration":{"type":"object","properties":{"started_at":{"type":"array","items":{"type":"string"}},"duration_ms":{"type":"array","items":{"type":"integer"}}}},"branch_chosen":{"type":"object","properties":{"type":{"type":"string","enum":["branch","default"]},"branch":{"type":"integer"}},"required":["type"]},"branchall":{"type":"object","properties":{"branch":{"type":"integer"},"len":{"type":"integer"}},"required":["branch","len"]},"approvers":{"type":"array","items":{"type":"object","properties":{"resume_id":{"type":"integer"},"approver":{"type":"string"}},"required":["resume_id","approver"]}},"failed_retries":{"type":"array","items":{"type":"string","format":"uuid"}},"skipped":{"type":"boolean"},"agent_actions":{"type":"array","items":{"type":"object","oneOf":[{"type":"object","properties":{"job_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"type":{"type":"string","enum":["tool_call"]},"module_id":{"type":"string"}},"required":["job_id","function_name","type","module_id"]},{"type":"object","properties":{"call_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"resource_path":{"type":"string"},"type":{"type":"string","enum":["mcp_tool_call"]},"arguments":{"type":"object"}},"required":["call_id","function_name","resource_path","type"]},{"type":"object","properties":{"type":{"type":"string","enum":["web_search"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["message"]}},"required":["content","type"]}]}},"agent_actions_success":{"type":"array","items":{"type":"boolean"}}},"required":["type"]}}`,
|
|
81985
|
+
{"OpenFlow":{"type":"object","description":"Top-level flow definition containing metadata, configuration, and the flow structure","properties":{"summary":{"type":"string","description":"Short description of what this flow does"},"description":{"type":"string","description":"Detailed documentation for this flow"},"value":{"$ref":"#/components/schemas/FlowValue"},"schema":{"type":"object","description":"JSON Schema for flow inputs. Use this to define input parameters, their types, defaults, and validation. For resource inputs, set type to 'object' and format to 'resource-<type>' (e.g., 'resource-stripe')"},"on_behalf_of_email":{"type":"string","description":"The flow will be run with the permissions of the user with this email."}},"required":["summary","value"]},"FlowValue":{"type":"object","description":"The flow structure containing modules and optional preprocessor/failure handlers","properties":{"modules":{"type":"array","description":"Array of steps that execute in sequence. Each step can be a script, subflow, loop, or branch","items":{"$ref":"#/components/schemas/FlowModule"}},"failure_module":{"description":"Special module that executes when the flow fails. Receives error object with message, name, stack, and step_id. Must have id 'failure'. Only supports script/rawscript types","$ref":"#/components/schemas/FlowModule"},"preprocessor_module":{"description":"Special module that runs before the first step on external triggers. Must have id 'preprocessor'. Only supports script/rawscript types. Cannot reference other step results","$ref":"#/components/schemas/FlowModule"},"same_worker":{"type":"boolean","description":"If true, all steps run on the same worker for better performance"},"concurrent_limit":{"type":"number","description":"Maximum number of concurrent executions of this flow"},"concurrency_key":{"type":"string","description":"Expression to group concurrent executions (e.g., by user ID)"},"concurrency_time_window_s":{"type":"number","description":"Time window in seconds for concurrent_limit"},"debounce_delay_s":{"type":"integer","description":"Delay in seconds to debounce flow executions"},"debounce_key":{"type":"string","description":"Expression to group debounced executions"},"debounce_args_to_accumulate":{"type":"array","description":"Arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"integer","description":"Maximum total time in seconds that a job can be debounced"},"max_total_debounces_amount":{"type":"integer","description":"Maximum number of times a job can be debounced"},"skip_expr":{"type":"string","description":"JavaScript expression to conditionally skip the entire flow"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for flow results"},"cache_ignore_s3_path":{"type":"boolean"},"delete_after_secs":{"type":"integer","description":"If set, delete the flow job's args, result and logs after this many seconds following job completion"},"flow_env":{"type":"object","description":"Environment variables available to all steps. Values can be strings, JSON values, or special references: '$var:path' (workspace variable) or '$res:path' (resource).","additionalProperties":{}},"priority":{"type":"number","description":"Execution priority (higher numbers run first)"},"early_return":{"type":"string","description":"JavaScript expression to return early from the flow"},"chat_input_enabled":{"type":"boolean","description":"Whether this flow accepts chat-style input"},"notes":{"type":"array","description":"Sticky notes attached to the flow","items":{"$ref":"#/components/schemas/FlowNote"}},"groups":{"type":"array","description":"Semantic groups of modules for organizational purposes","items":{"$ref":"#/components/schemas/FlowGroup"}}},"required":["modules"]},"Retry":{"type":"object","description":"Retry configuration for failed module executions","properties":{"constant":{"type":"object","description":"Retry with constant delay between attempts","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"seconds":{"type":"integer","description":"Seconds to wait between retries"}}},"exponential":{"type":"object","description":"Retry with exponential backoff (delay doubles each time)","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"multiplier":{"type":"integer","description":"Multiplier for exponential backoff"},"seconds":{"type":"integer","minimum":1,"description":"Initial delay in seconds"},"random_factor":{"type":"integer","minimum":0,"maximum":100,"description":"Random jitter percentage (0-100) to avoid thundering herd"}}},"retry_if":{"$ref":"#/components/schemas/RetryIf"}}},"FlowNote":{"type":"object","description":"A sticky note attached to a flow for documentation and annotation","properties":{"id":{"type":"string","description":"Unique identifier for the note"},"text":{"type":"string","description":"Content of the note"},"position":{"type":"object","description":"Position of the note in the flow editor","properties":{"x":{"type":"number","description":"X coordinate"},"y":{"type":"number","description":"Y coordinate"}},"required":["x","y"]},"size":{"type":"object","description":"Size of the note in the flow editor","properties":{"width":{"type":"number","description":"Width in pixels"},"height":{"type":"number","description":"Height in pixels"}},"required":["width","height"]},"color":{"type":"string","description":"Color of the note (e.g., \\"yellow\\", \\"#ffff00\\")"},"type":{"type":"string","enum":["free","group"],"description":"Type of note - 'free' for standalone notes, 'group' for notes that group other nodes"},"locked":{"type":"boolean","default":false,"description":"Whether the note is locked and cannot be edited or moved"},"contained_node_ids":{"type":"array","items":{"type":"string"},"description":"For group notes, the IDs of nodes contained within this group"}},"required":["id","text","color","type"]},"FlowGroup":{"type":"object","description":"A semantic group of flow modules for organizational purposes. Does not affect execution \\u2014 modules remain in their original position in the flow. Groups provide naming and collapsibility in the editor. Members are computed dynamically from all nodes on paths between start_id and end_id.","properties":{"summary":{"type":"string","description":"Display name for this group"},"note":{"type":"string","description":"Markdown note shown below the group header"},"autocollapse":{"type":"boolean","default":false,"description":"If true, this group is collapsed by default in the flow editor. UI hint only."},"start_id":{"type":"string","description":"ID of the first flow module in this group (topological entry point)"},"end_id":{"type":"string","description":"ID of the last flow module in this group (topological exit point)"},"color":{"type":"string","description":"Color for the group in the flow editor"}},"required":["start_id","end_id"]},"RetryIf":{"type":"object","description":"Conditional retry based on error or result","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to retry. Has access to 'result' and 'error' variables"}},"required":["expr"]},"StopAfterIf":{"type":"object","description":"Early termination condition for a module","properties":{"skip_if_stopped":{"type":"boolean","description":"If true, following steps are skipped when this condition triggers"},"expr":{"type":"string","description":"JavaScript expression evaluated after the module runs. Can use 'result' (step's result) or 'flow_input'. Return true to stop"},"error_message":{"type":"string","nullable":true,"description":"Custom error message when stopping with an error. Mutually exclusive with skip_if_stopped. If set to a non-empty string, the flow stops with this error. If empty string, a default error message is used. If null or omitted, no error is raised."}},"required":["expr"]},"FlowModule":{"type":"object","description":"A single step in a flow. Can be a script, subflow, loop, or branch","properties":{"id":{"type":"string","description":"Unique identifier for this step. Used to reference results via 'results.step_id'. Must be a valid identifier (alphanumeric, underscore, hyphen)"},"value":{"$ref":"#/components/schemas/FlowModuleValue"},"stop_after_if":{"description":"Early termination condition evaluated after this step completes","$ref":"#/components/schemas/StopAfterIf"},"stop_after_all_iters_if":{"description":"For loops only - early termination condition evaluated after all iterations complete","$ref":"#/components/schemas/StopAfterIf"},"skip_if":{"type":"object","description":"Conditionally skip this step based on previous results or flow inputs","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to skip. Can use 'flow_input' or 'results.<step_id>'"}},"required":["expr"]},"sleep":{"description":"Delay before executing this step (in seconds or as expression)","$ref":"#/components/schemas/InputTransform"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for this step's results"},"cache_ignore_s3_path":{"type":"boolean"},"timeout":{"description":"Maximum execution time in seconds (static value or expression)","$ref":"#/components/schemas/InputTransform"},"delete_after_secs":{"type":"integer","description":"If set, delete the step's args, result and logs after this many seconds following job completion"},"summary":{"type":"string","description":"Short description of what this step does"},"mock":{"type":"object","description":"Mock configuration for testing without executing the actual step","properties":{"enabled":{"type":"boolean","description":"If true, return mock value instead of executing"},"return_value":{"description":"Value to return when mocked"}}},"suspend":{"type":"object","description":"Configuration for approval/resume steps that wait for user input","properties":{"required_events":{"type":"integer","description":"Number of approvals required before continuing"},"timeout":{"type":"integer","description":"Timeout in seconds before auto-continuing or canceling"},"resume_form":{"type":"object","description":"Form schema for collecting input when resuming","properties":{"schema":{"type":"object","description":"JSON Schema for the resume form"}}},"user_auth_required":{"type":"boolean","description":"If true, only authenticated users can approve"},"user_groups_required":{"description":"Expression or list of groups that can approve","$ref":"#/components/schemas/InputTransform"},"self_approval_disabled":{"type":"boolean","description":"If true, the user who started the flow cannot approve"},"hide_cancel":{"type":"boolean","description":"If true, hide the cancel button on the approval form"},"continue_on_disapprove_timeout":{"type":"boolean","description":"If true, continue flow on timeout instead of canceling"}}},"priority":{"type":"number","description":"Execution priority for this step (higher numbers run first)"},"continue_on_error":{"type":"boolean","description":"If true, flow continues even if this step fails"},"retry":{"description":"Retry configuration if this step fails","$ref":"#/components/schemas/Retry"},"debouncing":{"description":"Debounce configuration for this step (EE only)","type":"object","properties":{"debounce_delay_s":{"type":"integer","description":"Delay in seconds to debounce this step's executions across flow runs"},"debounce_key":{"type":"string","description":"Expression to group debounced executions. Supports $workspace and $args[name]. Default: $workspace/flow/<flow_path>-<step_id>"},"debounce_args_to_accumulate":{"type":"array","description":"Array-type arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"integer","description":"Maximum total time in seconds before forced execution"},"max_total_debounces_amount":{"type":"integer","description":"Maximum number of debounces before forced execution"}}}},"required":["value","id"]},"InputTransform":{"description":"Maps input parameters for a step. Can be a static value or a JavaScript expression that references previous results or flow inputs","oneOf":[{"$ref":"#/components/schemas/StaticTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"StaticTransform":{"type":"object","description":"Static value passed directly to the step. Use for hardcoded values or resource references like '$res:path/to/resource'","properties":{"value":{"description":"The static value. For resources, use format '$res:path/to/resource'"},"type":{"type":"string","enum":["static"]}},"required":["type"]},"JavascriptTransform":{"type":"object","description":"JavaScript expression evaluated at runtime. Can reference previous step results via 'results.step_id' or flow inputs via 'flow_input.property'. Inside loops, use 'flow_input.iter.value' for the current iteration value","properties":{"expr":{"type":"string","description":"JavaScript expression returning the value. Available variables - results (object with all previous step results), flow_input (flow inputs), flow_input.iter (in loops)"},"type":{"type":"string","enum":["javascript"]}},"required":["expr","type"]},"AiTransform":{"type":"object","description":"Value resolved by the AI runtime for this input. The AI engine decides how to satisfy the parameter.","properties":{"type":{"type":"string","enum":["ai"]}},"required":["type"]},"AIProviderKind":{"type":"string","description":"Supported AI provider types","enum":["openai","azure_openai","anthropic","mistral","deepseek","googleai","groq","openrouter","togetherai","customai","aws_bedrock"]},"ProviderConfig":{"type":"object","description":"Complete AI provider configuration with resource reference and model selection","properties":{"kind":{"$ref":"#/components/schemas/AIProviderKind"},"resource":{"type":"string","description":"Resource reference in format '$res:{resource_path}' pointing to provider credentials"},"model":{"type":"string","description":"Model identifier (e.g., 'gpt-4', 'claude-3-opus-20240229', 'gemini-pro')"}},"required":["kind","resource","model"]},"StaticProviderTransform":{"type":"object","description":"Static provider configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/ProviderConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"ProviderTransform":{"description":"Provider configuration - can be static (ProviderConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticProviderTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticProviderTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"MemoryOff":{"type":"object","description":"No conversation memory/context","properties":{"kind":{"type":"string","enum":["off"]}},"required":["kind"]},"MemoryAuto":{"type":"object","description":"Automatic context management","properties":{"kind":{"type":"string","enum":["auto"]},"context_length":{"type":"integer","description":"Maximum number of messages to retain in context"},"memory_id":{"type":"string","description":"Identifier for persistent memory across agent invocations"}},"required":["kind"]},"MemoryMessage":{"type":"object","description":"A single message in conversation history","properties":{"role":{"type":"string","enum":["user","assistant","system"]},"content":{"type":"string"}},"required":["role","content"]},"MemoryManual":{"type":"object","description":"Explicit message history","properties":{"kind":{"type":"string","enum":["manual"]},"messages":{"type":"array","items":{"$ref":"#/components/schemas/MemoryMessage"}}},"required":["kind","messages"]},"MemoryConfig":{"description":"Conversation memory configuration","oneOf":[{"$ref":"#/components/schemas/MemoryOff"},{"$ref":"#/components/schemas/MemoryAuto"},{"$ref":"#/components/schemas/MemoryManual"}],"discriminator":{"propertyName":"kind","mapping":{"off":"#/components/schemas/MemoryOff","auto":"#/components/schemas/MemoryAuto","manual":"#/components/schemas/MemoryManual"}}},"StaticMemoryTransform":{"type":"object","description":"Static memory configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/MemoryConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"MemoryTransform":{"description":"Memory configuration - can be static (MemoryConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticMemoryTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticMemoryTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"FlowModuleValue":{"description":"The actual implementation of a flow step. Can be a script (inline or referenced), subflow, loop, branch, or special module type","oneOf":[{"$ref":"#/components/schemas/RawScript"},{"$ref":"#/components/schemas/PathScript"},{"$ref":"#/components/schemas/PathFlow"},{"$ref":"#/components/schemas/ForloopFlow"},{"$ref":"#/components/schemas/WhileloopFlow"},{"$ref":"#/components/schemas/BranchOne"},{"$ref":"#/components/schemas/BranchAll"},{"$ref":"#/components/schemas/Identity"},{"$ref":"#/components/schemas/AiAgent"}],"discriminator":{"propertyName":"type","mapping":{"rawscript":"#/components/schemas/RawScript","script":"#/components/schemas/PathScript","flow":"#/components/schemas/PathFlow","forloopflow":"#/components/schemas/ForloopFlow","whileloopflow":"#/components/schemas/WhileloopFlow","branchone":"#/components/schemas/BranchOne","branchall":"#/components/schemas/BranchAll","identity":"#/components/schemas/Identity","aiagent":"#/components/schemas/AiAgent"}}},"RawScript":{"type":"object","description":"Inline script with code defined directly in the flow. Use 'bun' as default language if unspecified. The script receives arguments from input_transforms","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"content":{"type":"string","description":"The script source code. Should export a 'main' function"},"language":{"type":"string","description":"Programming language for this script","enum":["deno","bun","python3","go","bash","powershell","postgresql","mysql","bigquery","snowflake","mssql","oracledb","graphql","nativets","php","rust","ansible","csharp","nu","java","ruby","rlang","duckdb"]},"path":{"type":"string","description":"Optional path for saving this script"},"lock":{"type":"string","description":"Lock file content for dependencies"},"type":{"type":"string","enum":["rawscript"]},"tag":{"type":"string","description":"Worker group tag for execution routing"},"concurrent_limit":{"type":"number","description":"Maximum concurrent executions of this script"},"concurrency_time_window_s":{"type":"number","description":"Time window for concurrent_limit"},"custom_concurrency_key":{"type":"string","description":"Custom key for grouping concurrent executions"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"},"assets":{"type":"array","description":"External resources this script accesses (S3 objects, resources, etc.)","items":{"type":"object","required":["path","kind"],"properties":{"path":{"type":"string","description":"Path to the asset"},"kind":{"type":"string","description":"Type of asset","enum":["s3object","resource","ducklake","datatable","volume"]},"access_type":{"type":"string","nullable":true,"description":"Access level for this asset","enum":["r","w","rw"]},"alt_access_type":{"type":"string","nullable":true,"description":"Alternative access level","enum":["r","w","rw"]}}}}},"required":["type","content","language","input_transforms"]},"PathScript":{"type":"object","description":"Reference to an existing script by path. Use this when calling a previously saved script instead of writing inline code","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the script in the workspace (e.g., 'f/scripts/send_email')"},"hash":{"type":"string","description":"Optional specific version hash of the script to use"},"type":{"type":"string","enum":["script"]},"tag_override":{"type":"string","description":"Override the script's default worker group tag"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"}},"required":["type","path","input_transforms"]},"PathFlow":{"type":"object","description":"Reference to an existing flow by path. Use this to call another flow as a subflow","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the subflow's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the flow in the workspace (e.g., 'f/flows/process_user')"},"type":{"type":"string","enum":["flow"]}},"required":["type","path","input_transforms"]},"ForloopFlow":{"type":"object","description":"Executes nested modules in a loop over an iterator. Inside the loop, use 'flow_input.iter.value' to access the current iteration value, and 'flow_input.iter.index' for the index. Supports parallel execution for better performance on I/O-bound operations","properties":{"modules":{"type":"array","description":"Steps to execute for each iteration. These can reference the iteration value via 'flow_input.iter.value'","items":{"$ref":"#/components/schemas/FlowModule"}},"iterator":{"description":"JavaScript expression that returns an array to iterate over. Can reference 'results.step_id' or 'flow_input'","$ref":"#/components/schemas/InputTransform"},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["forloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (faster for I/O-bound operations). Use with parallelism to control concurrency"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true. Limits resource usage. Can be static number or expression","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","iterator","skip_failures","type"]},"WhileloopFlow":{"type":"object","description":"Executes nested modules repeatedly while a condition is true. The loop checks the condition after each iteration. Use stop_after_if on modules to control loop termination","properties":{"modules":{"type":"array","description":"Steps to execute in each iteration. Use stop_after_if to control when the loop ends","items":{"$ref":"#/components/schemas/FlowModule"}},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["whileloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (use with caution in while loops)"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","skip_failures","type"]},"BranchOne":{"type":"object","description":"Conditional branching where only the first matching branch executes. Branches are evaluated in order, and the first one with a true expression runs. If no branches match, the default branch executes","properties":{"branches":{"type":"array","description":"Array of branches to evaluate in order. The first branch with expr evaluating to true executes","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch condition"},"expr":{"type":"string","description":"JavaScript expression that returns boolean. Can use 'results.step_id' or 'flow_input'. First true expr wins"},"modules":{"type":"array","description":"Steps to execute if this branch's expr is true","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules","expr"]}},"default":{"type":"array","description":"Steps to execute if no branch expressions match","items":{"$ref":"#/components/schemas/FlowModule"}},"type":{"type":"string","enum":["branchone"]}},"required":["branches","default","type"]},"BranchAll":{"type":"object","description":"Parallel branching where all branches execute simultaneously. Unlike BranchOne, all branches run regardless of conditions. Useful for executing independent tasks concurrently","properties":{"branches":{"type":"array","description":"Array of branches that all execute (either in parallel or sequentially)","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch's purpose"},"skip_failure":{"type":"boolean","description":"If true, failure in this branch doesn't fail the entire flow"},"modules":{"type":"array","description":"Steps to execute in this branch","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules"]}},"type":{"type":"string","enum":["branchall"]},"parallel":{"type":"boolean","description":"If true, all branches execute concurrently. If false, they execute sequentially"}},"required":["branches","type"]},"AgentTool":{"type":"object","description":"A tool available to an AI agent. Can be a flow module or an external MCP (Model Context Protocol) tool","properties":{"id":{"type":"string","description":"Unique identifier for this tool. Cannot contain spaces - use underscores instead (e.g., 'get_user_data' not 'get user data')"},"summary":{"type":"string","description":"Short description of what this tool does (shown to the AI)"},"value":{"$ref":"#/components/schemas/ToolValue"}},"required":["id","value"]},"ToolValue":{"description":"The implementation of a tool. Can be a flow module (script/flow) or an MCP tool reference","oneOf":[{"$ref":"#/components/schemas/FlowModuleTool"},{"$ref":"#/components/schemas/McpToolValue"},{"$ref":"#/components/schemas/WebsearchToolValue"}],"discriminator":{"propertyName":"tool_type","mapping":{"flowmodule":"#/components/schemas/FlowModuleTool","mcp":"#/components/schemas/McpToolValue","websearch":"#/components/schemas/WebsearchToolValue"}}},"FlowModuleTool":{"description":"A tool implemented as a flow module (script, flow, etc.). The AI can call this like any other flow module","allOf":[{"type":"object","properties":{"tool_type":{"type":"string","enum":["flowmodule"]}},"required":["tool_type"]},{"$ref":"#/components/schemas/FlowModuleValue"}]},"WebsearchToolValue":{"type":"object","description":"A tool implemented as a websearch tool. The AI can call this like any other websearch tool","properties":{"tool_type":{"type":"string","enum":["websearch"]}},"required":["tool_type"]},"McpToolValue":{"type":"object","description":"Reference to an external MCP (Model Context Protocol) tool. The AI can call tools from MCP servers","properties":{"tool_type":{"type":"string","enum":["mcp"]},"resource_path":{"type":"string","description":"Path to the MCP resource/server configuration"},"include_tools":{"type":"array","description":"Whitelist of specific tools to include from this MCP server","items":{"type":"string"}},"exclude_tools":{"type":"array","description":"Blacklist of tools to exclude from this MCP server","items":{"type":"string"}}},"required":["tool_type","resource_path"]},"AiAgent":{"type":"object","description":"AI agent step that can use tools to accomplish tasks. The agent receives inputs and can call any of its configured tools to complete the task","properties":{"input_transforms":{"type":"object","description":"Input parameters for the AI agent mapped to their values","properties":{"provider":{"$ref":"#/components/schemas/ProviderTransform"},"output_type":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Output format type.\\nValid values: 'text' (default) - plain text response, 'image' - image generation\\n"},"user_message":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"The user's prompt/message to the AI agent. Supports variable interpolation with flow.input syntax."},"system_prompt":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"System instructions that guide the AI's behavior, persona, and response style. Optional."},"streaming":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Boolean. If true, stream the AI response incrementally.\\nStreaming events include: token_delta, tool_call, tool_call_arguments, tool_execution, tool_result\\n"},"memory":{"$ref":"#/components/schemas/MemoryTransform"},"output_schema":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"JSON Schema object defining structured output format. Used when you need the AI to return data in a specific shape.\\nSupports standard JSON Schema properties: type, properties, required, items, enum, pattern, minLength, maxLength, minimum, maximum, etc.\\nExample: { type: 'object', properties: { name: { type: 'string' }, age: { type: 'integer' } }, required: ['name'] }\\n"},"user_attachments":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Array of file references (images or PDFs) for the AI agent.\\nFormat: Array<{ bucket: string, key: string }> - S3 object references\\nExample: [{ bucket: 'my-bucket', key: 'documents/report.pdf' }]\\n"},"max_completion_tokens":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Integer. Maximum number of tokens the AI will generate in its response.\\nRange: 1 to 4,294,967,295. Typical values: 256-4096 for most use cases.\\n"},"temperature":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Float. Controls randomness/creativity of responses.\\nRange: 0.0 to 2.0 (provider-dependent)\\n- 0.0 = deterministic, focused responses\\n- 0.7 = balanced (common default)\\n- 1.0+ = more creative/random\\n"}},"required":["provider","user_message","output_type"]},"tools":{"type":"array","description":"Array of tools the agent can use. The agent decides which tools to call based on the task","items":{"$ref":"#/components/schemas/AgentTool"}},"type":{"type":"string","enum":["aiagent"]},"omit_output_from_conversation":{"type":"boolean","default":false,"description":"If true, this AI agent step does not persist its assistant or tool messages to the flow conversation when chat mode is enabled."},"parallel":{"type":"boolean","description":"If true, the agent can execute multiple tool calls in parallel"}},"required":["tools","type","input_transforms"]},"Identity":{"type":"object","description":"Pass-through module that returns its input unchanged. Useful for flow structure or as a placeholder","properties":{"type":{"type":"string","enum":["identity"]},"flow":{"type":"boolean","description":"If true, marks this as a flow identity (special handling)"}},"required":["type"]},"FlowStatus":{"type":"object","properties":{"step":{"type":"integer"},"modules":{"type":"array","items":{"$ref":"#/components/schemas/FlowStatusModule"}},"user_states":{"additionalProperties":true},"preprocessor_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"}]},"failure_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"},{"type":"object","properties":{"parent_module":{"type":"string"}}}]},"retry":{"type":"object","properties":{"fail_count":{"type":"integer"},"failed_jobs":{"type":"array","items":{"type":"string","format":"uuid"}}}}},"required":["step","modules","failure_module"]},"FlowStatusModule":{"type":"object","properties":{"type":{"type":"string","enum":["WaitingForPriorSteps","WaitingForEvents","WaitingForExecutor","InProgress","Success","Failure"]},"id":{"type":"string"},"job":{"type":"string","format":"uuid"},"count":{"type":"integer"},"progress":{"type":"integer"},"iterator":{"type":"object","properties":{"index":{"type":"integer"},"itered":{"type":"array","items":{}},"itered_len":{"type":"integer"},"args":{}}},"flow_jobs":{"type":"array","items":{"type":"string"}},"flow_jobs_success":{"type":"array","items":{"type":"boolean"}},"flow_jobs_duration":{"type":"object","properties":{"started_at":{"type":"array","items":{"type":"string"}},"duration_ms":{"type":"array","items":{"type":"integer"}}}},"branch_chosen":{"type":"object","properties":{"type":{"type":"string","enum":["branch","default"]},"branch":{"type":"integer"}},"required":["type"]},"branchall":{"type":"object","properties":{"branch":{"type":"integer"},"len":{"type":"integer"}},"required":["branch","len"]},"approvers":{"type":"array","items":{"type":"object","properties":{"resume_id":{"type":"integer"},"approver":{"type":"string"}},"required":["resume_id","approver"]}},"failed_retries":{"type":"array","items":{"type":"string","format":"uuid"}},"skipped":{"type":"boolean"},"agent_actions":{"type":"array","items":{"type":"object","oneOf":[{"type":"object","properties":{"job_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"type":{"type":"string","enum":["tool_call"]},"module_id":{"type":"string"}},"required":["job_id","function_name","type","module_id"]},{"type":"object","properties":{"call_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"resource_path":{"type":"string"},"type":{"type":"string","enum":["mcp_tool_call"]},"arguments":{"type":"object"}},"required":["call_id","function_name","resource_path","type"]},{"type":"object","properties":{"type":{"type":"string","enum":["web_search"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["message"]}},"required":["content","type"]}]}},"agent_actions_success":{"type":"array","items":{"type":"boolean"}}},"required":["type"]}}`,
|
|
81667
81986
|
"raw-app": `---
|
|
81668
81987
|
name: raw-app
|
|
81669
81988
|
description: MUST use when creating raw apps.
|
|
@@ -82523,6 +82842,11 @@ sync local with a remote instance or the opposite (push or pull)
|
|
|
82523
82842
|
- \`-o, --output-file <file:string>\` - Write YAML to a file instead of stdout
|
|
82524
82843
|
- \`--show-secrets\` - Include sensitive fields (license key, JWT secret) without prompting
|
|
82525
82844
|
- \`--instance <instance:string>\` - Name of the instance, override the active instance
|
|
82845
|
+
- \`instance connect-slack\`
|
|
82846
|
+
- \`--bot-token <bot_token:string>\` - Slack bot token (xoxb-...)
|
|
82847
|
+
- \`--team-id <team_id:string>\` - Slack team id
|
|
82848
|
+
- \`--team-name <team_name:string>\` - Slack team name
|
|
82849
|
+
- \`--instance <instance:string>\` - Instance profile to connect against (defaults to the active instance)
|
|
82526
82850
|
|
|
82527
82851
|
### job
|
|
82528
82852
|
|
|
@@ -82764,12 +83088,12 @@ trigger related commands
|
|
|
82764
83088
|
- \`--json\` - Output as JSON (for piping to jq)
|
|
82765
83089
|
- \`trigger get <path:string>\` - get a trigger's details
|
|
82766
83090
|
- \`--json\` - Output as JSON (for piping to jq)
|
|
82767
|
-
- \`--kind <kind:string>\` - Trigger kind (http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, email). Recommended for faster lookup
|
|
83091
|
+
- \`--kind <kind:string>\` - Trigger kind (http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, azure, email). Recommended for faster lookup
|
|
82768
83092
|
- \`trigger new <path:string>\` - create a new trigger locally
|
|
82769
|
-
- \`--kind <kind:string>\` - Trigger kind (required: http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, email)
|
|
83093
|
+
- \`--kind <kind:string>\` - Trigger kind (required: http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, azure, email)
|
|
82770
83094
|
- \`trigger push <file_path:string> <remote_path:string>\` - push a local trigger spec. This overrides any remote versions.
|
|
82771
83095
|
- \`trigger set-permissioned-as <path:string> <email:string>\` - Set the email (run-as user) for a trigger (requires admin or wm_deployers group)
|
|
82772
|
-
- \`--kind <kind:string>\` - Trigger kind (required: http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, email)
|
|
83096
|
+
- \`--kind <kind:string>\` - Trigger kind (required: http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, azure, email)
|
|
82773
83097
|
|
|
82774
83098
|
### user
|
|
82775
83099
|
|
|
@@ -82871,10 +83195,100 @@ workspace related commands
|
|
|
82871
83195
|
- \`--exclude <items:string>\` - Comma-separated kind:path items to exclude
|
|
82872
83196
|
- \`--preserve-on-behalf-of\` - Preserve original on_behalf_of/permissioned_as values
|
|
82873
83197
|
- \`-y --yes\` - Non-interactive mode (deploy without prompts)
|
|
83198
|
+
- \`workspace connect-slack\` - Non-interactively connect Slack to the active workspace using a pre-minted bot token (xoxb-...). Produces the same artifacts as the UI OAuth flow: workspace_settings fields, g/slack group, f/slack_bot folder, and the encrypted bot token variable + resource at f/slack_bot/bot_token.
|
|
83199
|
+
- \`--bot-token <bot_token:string>\` - Slack bot token (xoxb-...)
|
|
83200
|
+
- \`--team-id <team_id:string>\` - Slack team id
|
|
83201
|
+
- \`--team-name <team_name:string>\` - Slack team name
|
|
83202
|
+
- \`workspace disconnect-slack\`
|
|
82874
83203
|
|
|
82875
83204
|
`
|
|
82876
83205
|
};
|
|
82877
83206
|
var SCHEMAS = {
|
|
83207
|
+
azure_trigger: `type: object
|
|
83208
|
+
properties:
|
|
83209
|
+
script_path:
|
|
83210
|
+
type: string
|
|
83211
|
+
description: Path to the script or flow to execute when triggered
|
|
83212
|
+
permissioned_as:
|
|
83213
|
+
type: string
|
|
83214
|
+
description: The user or group this trigger runs as (permissioned_as)
|
|
83215
|
+
is_flow:
|
|
83216
|
+
type: boolean
|
|
83217
|
+
description: True if script_path points to a flow, false if it points to a script
|
|
83218
|
+
labels:
|
|
83219
|
+
type: array
|
|
83220
|
+
items:
|
|
83221
|
+
type: string
|
|
83222
|
+
azure_resource_path:
|
|
83223
|
+
type: string
|
|
83224
|
+
azure_mode:
|
|
83225
|
+
type: string
|
|
83226
|
+
enum:
|
|
83227
|
+
- basic_push
|
|
83228
|
+
- namespace_push
|
|
83229
|
+
- namespace_pull
|
|
83230
|
+
description: Azure Event Grid trigger mode.
|
|
83231
|
+
scope_resource_id:
|
|
83232
|
+
type: string
|
|
83233
|
+
description: ARM resource ID of the topic (basic) or namespace (namespace modes).
|
|
83234
|
+
topic_name:
|
|
83235
|
+
type: string
|
|
83236
|
+
description: Topic name within the namespace (namespace modes only).
|
|
83237
|
+
subscription_name:
|
|
83238
|
+
type: string
|
|
83239
|
+
event_type_filters:
|
|
83240
|
+
type: array
|
|
83241
|
+
items:
|
|
83242
|
+
type: string
|
|
83243
|
+
error_handler_path:
|
|
83244
|
+
type: string
|
|
83245
|
+
error_handler_args:
|
|
83246
|
+
type: object
|
|
83247
|
+
description: The arguments to pass to the script or flow
|
|
83248
|
+
retry:
|
|
83249
|
+
type: object
|
|
83250
|
+
properties:
|
|
83251
|
+
constant:
|
|
83252
|
+
type: object
|
|
83253
|
+
description: Retry with constant delay between attempts
|
|
83254
|
+
properties:
|
|
83255
|
+
attempts:
|
|
83256
|
+
type: integer
|
|
83257
|
+
description: Number of retry attempts
|
|
83258
|
+
seconds:
|
|
83259
|
+
type: integer
|
|
83260
|
+
description: Seconds to wait between retries
|
|
83261
|
+
exponential:
|
|
83262
|
+
type: object
|
|
83263
|
+
description: Retry with exponential backoff (delay doubles each time)
|
|
83264
|
+
properties:
|
|
83265
|
+
attempts:
|
|
83266
|
+
type: integer
|
|
83267
|
+
description: Number of retry attempts
|
|
83268
|
+
multiplier:
|
|
83269
|
+
type: integer
|
|
83270
|
+
description: Multiplier for exponential backoff
|
|
83271
|
+
seconds:
|
|
83272
|
+
type: integer
|
|
83273
|
+
minimum: 1
|
|
83274
|
+
description: Initial delay in seconds
|
|
83275
|
+
random_factor:
|
|
83276
|
+
type: integer
|
|
83277
|
+
minimum: 0
|
|
83278
|
+
maximum: 100
|
|
83279
|
+
description: Random jitter percentage (0-100) to avoid thundering herd
|
|
83280
|
+
retry_if:
|
|
83281
|
+
$ref: '#/components/schemas/RetryIf'
|
|
83282
|
+
description: Retry configuration for failed module executions
|
|
83283
|
+
required:
|
|
83284
|
+
- script_path
|
|
83285
|
+
- permissioned_as
|
|
83286
|
+
- is_flow
|
|
83287
|
+
- azure_resource_path
|
|
83288
|
+
- azure_mode
|
|
83289
|
+
- scope_resource_id
|
|
83290
|
+
- subscription_name
|
|
83291
|
+
`,
|
|
82878
83292
|
gcp_trigger: `type: object
|
|
82879
83293
|
properties:
|
|
82880
83294
|
script_path:
|
|
@@ -83800,7 +84214,8 @@ var SCHEMA_MAPPINGS = {
|
|
|
83800
84214
|
{ name: "PostgresTrigger", schemaKey: "postgres_trigger", filePattern: "*.postgres_trigger.yaml" },
|
|
83801
84215
|
{ name: "MqttTrigger", schemaKey: "mqtt_trigger", filePattern: "*.mqtt_trigger.yaml" },
|
|
83802
84216
|
{ name: "SqsTrigger", schemaKey: "sqs_trigger", filePattern: "*.sqs_trigger.yaml" },
|
|
83803
|
-
{ name: "GcpTrigger", schemaKey: "gcp_trigger", filePattern: "*.gcp_trigger.yaml" }
|
|
84217
|
+
{ name: "GcpTrigger", schemaKey: "gcp_trigger", filePattern: "*.gcp_trigger.yaml" },
|
|
84218
|
+
{ name: "AzureTrigger", schemaKey: "azure_trigger", filePattern: "*.azure_trigger.yaml" }
|
|
83804
84219
|
],
|
|
83805
84220
|
schedules: [
|
|
83806
84221
|
{ name: "Schedule", schemaKey: "schedule", filePattern: "*.schedule.yaml" }
|
|
@@ -85726,7 +86141,7 @@ var config_default = command35;
|
|
|
85726
86141
|
|
|
85727
86142
|
// src/main.ts
|
|
85728
86143
|
await init_context();
|
|
85729
|
-
var VERSION = "1.
|
|
86144
|
+
var VERSION = "1.691.0";
|
|
85730
86145
|
async function checkVersionSafe(cmd) {
|
|
85731
86146
|
const mainCommand = cmd.getMainCommand();
|
|
85732
86147
|
const upgradeCommand = mainCommand.getCommand("upgrade");
|