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.
Files changed (2) hide show
  1. package/esm/main.js +465 -50
  2. 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.689.0",
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
- after_id: data3.afterId
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 (currentBranch) {
61236
- const branchSpecificJSON = toWorkspaceSpecificPath(contentBasePathJSON, currentBranch);
61237
- const branchSpecificYAML = toWorkspaceSpecificPath(contentBasePathYAML, currentBranch);
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
- await createScript({
61497
- workspace: workspaceId,
61498
- requestBody: body
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
- if (!hasExplicitCredentials && !branchDeprecationWarned) {
65183
- warn("⚠️ --branch/--env is deprecated. Use --workspace instead.");
65184
- branchDeprecationWarned = true;
65185
- }
65186
- wsNameForConfig = resolveWsNameFromBranch(opts, opts.branch);
65187
- } else if (opts.workspace && !hasExplicitCredentials) {
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
- if (!hasExplicitCredentials && !branchDeprecationWarned) {
65440
- warn("⚠️ --branch/--env is deprecated. Use --workspace instead.");
65441
- branchDeprecationWarned = true;
65442
- }
65443
- wsNameForConfig = resolveWsNameFromBranch(opts, opts.branch);
65444
- } else if (opts.workspace && !hasExplicitCredentials) {
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 && typeof settings.error_handler === "object") {
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 && typeof settings.success_handler === "object") {
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
- pathToAnalyze = fromWorkspaceSpecificPath(filePath, currentBranch);
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.689.0";
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");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windmill-cli",
3
- "version": "1.689.0",
3
+ "version": "1.691.0",
4
4
  "description": "CLI for Windmill",
5
5
  "license": "Apache 2.0",
6
6
  "type": "module",