windmill-cli 1.739.0 → 1.741.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 +449 -72
  2. package/package.json +1 -1
package/esm/main.js CHANGED
@@ -16784,7 +16784,7 @@ var init_OpenAPI = __esm(() => {
16784
16784
  PASSWORD: undefined,
16785
16785
  TOKEN: getEnv3("WM_TOKEN"),
16786
16786
  USERNAME: undefined,
16787
- VERSION: "1.739.0",
16787
+ VERSION: "1.741.0",
16788
16788
  WITH_CREDENTIALS: true,
16789
16789
  interceptors: {
16790
16790
  request: new Interceptors,
@@ -17157,6 +17157,7 @@ __export(exports_services_gen, {
17157
17157
  sendMessageToConversation: () => sendMessageToConversation,
17158
17158
  searchLogsIndex: () => searchLogsIndex,
17159
17159
  searchJobsIndex: () => searchJobsIndex,
17160
+ searchDocs: () => searchDocs,
17160
17161
  s3ResourceInfo: () => s3ResourceInfo,
17161
17162
  runWaitResultScriptByPathGet: () => runWaitResultScriptByPathGet,
17162
17163
  runWaitResultScriptByPath: () => runWaitResultScriptByPath,
@@ -17182,6 +17183,7 @@ __export(exports_services_gen, {
17182
17183
  runFlowByPath: () => runFlowByPath,
17183
17184
  runDynamicSelect: () => runDynamicSelect,
17184
17185
  runCodeWorkflowTask: () => runCodeWorkflowTask,
17186
+ runAuditLogsS3Backfill: () => runAuditLogsS3Backfill,
17185
17187
  runAndStreamScriptByPathGet: () => runAndStreamScriptByPathGet,
17186
17188
  runAndStreamScriptByPath: () => runAndStreamScriptByPath,
17187
17189
  runAndStreamScriptByHashGet: () => runAndStreamScriptByHashGet,
@@ -17213,12 +17215,12 @@ __export(exports_services_gen, {
17213
17215
  refreshToken: () => refreshToken,
17214
17216
  refreshCustomInstanceUserPwd: () => refreshCustomInstanceUserPwd,
17215
17217
  rebuildDependencyMap: () => rebuildDependencyMap,
17218
+ readDocsPage: () => readDocsPage,
17216
17219
  rawScriptByPathTokened: () => rawScriptByPathTokened,
17217
17220
  rawScriptByPath: () => rawScriptByPath,
17218
17221
  rawScriptByHash: () => rawScriptByHash,
17219
17222
  queryResourceTypes: () => queryResourceTypes,
17220
17223
  queryHubScripts: () => queryHubScripts,
17221
- queryDocumentation: () => queryDocumentation,
17222
17224
  pruneVersions: () => pruneVersions,
17223
17225
  previewSchedule: () => previewSchedule,
17224
17226
  polarsConnectionSettingsV2: () => polarsConnectionSettingsV2,
@@ -17530,6 +17532,7 @@ __export(exports_services_gen, {
17530
17532
  getFlowDeploymentStatus: () => getFlowDeploymentStatus,
17531
17533
  getFlowDebugInfo: () => getFlowDebugInfo,
17532
17534
  getFlowByPath: () => getFlowByPath,
17535
+ getFlowAllLogsStructured: () => getFlowAllLogsStructured,
17533
17536
  getFlowAllLogs: () => getFlowAllLogs,
17534
17537
  getEmailTrigger: () => getEmailTrigger,
17535
17538
  getDraftForUser: () => getDraftForUser,
@@ -17564,6 +17567,7 @@ __export(exports_services_gen, {
17564
17567
  getCapture: () => getCapture,
17565
17568
  getAzureTrigger: () => getAzureTrigger,
17566
17569
  getAuditLogsS3Status: () => getAuditLogsS3Status,
17570
+ getAuditLogsS3BackfillStatus: () => getAuditLogsS3BackfillStatus,
17567
17571
  getAuditLog: () => getAuditLog,
17568
17572
  getAssetsGraph: () => getAssetsGraph,
17569
17573
  getArgsFromHistoryOrSavedInput: () => getArgsFromHistoryOrSavedInput,
@@ -17827,14 +17831,21 @@ var backendVersion = () => {
17827
17831
  method: "GET",
17828
17832
  url: "/ee_license"
17829
17833
  });
17830
- }, queryDocumentation = (data3) => {
17834
+ }, searchDocs = (data3) => {
17831
17835
  return request(OpenAPI, {
17832
- method: "POST",
17833
- url: "/inkeep",
17834
- body: data3.requestBody,
17835
- mediaType: "application/json",
17836
- errors: {
17837
- 403: "Enterprise Edition required"
17836
+ method: "GET",
17837
+ url: "/docs/search",
17838
+ query: {
17839
+ query: data3.query
17840
+ }
17841
+ });
17842
+ }, readDocsPage = (data3) => {
17843
+ return request(OpenAPI, {
17844
+ method: "GET",
17845
+ url: "/docs/page",
17846
+ query: {
17847
+ url: data3.url,
17848
+ section: data3.section
17838
17849
  }
17839
17850
  });
17840
17851
  }, getOpenApiYaml = () => {
@@ -18318,6 +18329,18 @@ var backendVersion = () => {
18318
18329
  method: "GET",
18319
18330
  url: "/settings/audit_logs_s3_status"
18320
18331
  });
18332
+ }, runAuditLogsS3Backfill = (data3) => {
18333
+ return request(OpenAPI, {
18334
+ method: "POST",
18335
+ url: "/settings/audit_logs_s3_backfill",
18336
+ body: data3.requestBody,
18337
+ mediaType: "application/json"
18338
+ });
18339
+ }, getAuditLogsS3BackfillStatus = () => {
18340
+ return request(OpenAPI, {
18341
+ method: "GET",
18342
+ url: "/settings/audit_logs_s3_backfill_status"
18343
+ });
18321
18344
  }, sendStats = () => {
18322
18345
  return request(OpenAPI, {
18323
18346
  method: "POST",
@@ -21770,6 +21793,7 @@ var backendVersion = () => {
21770
21793
  query: {
21771
21794
  include_header: data3.includeHeader,
21772
21795
  invisible_to_owner: data3.invisibleToOwner,
21796
+ timeout: data3.timeout,
21773
21797
  job_id: data3.jobId
21774
21798
  },
21775
21799
  body: data3.requestBody,
@@ -22279,6 +22303,15 @@ var backendVersion = () => {
22279
22303
  id: data3.id
22280
22304
  }
22281
22305
  });
22306
+ }, getFlowAllLogsStructured = (data3) => {
22307
+ return request(OpenAPI, {
22308
+ method: "GET",
22309
+ url: "/w/{workspace}/jobs_u/get_flow_all_logs_structured/{id}",
22310
+ path: {
22311
+ workspace: data3.workspace,
22312
+ id: data3.id
22313
+ }
22314
+ });
22282
22315
  }, getCompletedJobLogsTail = (data3) => {
22283
22316
  return request(OpenAPI, {
22284
22317
  method: "GET",
@@ -25509,7 +25542,7 @@ var init_auth = __esm(async () => {
25509
25542
  });
25510
25543
 
25511
25544
  // src/core/constants.ts
25512
- var WM_FORK_PREFIX = "wm-fork", VERSION = "1.739.0";
25545
+ var WM_FORK_PREFIX = "wm-fork", VERSION = "1.741.0";
25513
25546
 
25514
25547
  // src/utils/git.ts
25515
25548
  var exports_git = {};
@@ -77034,6 +77067,30 @@ ${details.join(`
77034
77067
  `)}
77035
77068
  Use --remote to preview deployed workspace scripts instead.`);
77036
77069
  }
77070
+ function collectStepPaths(flowValue) {
77071
+ const paths = [];
77072
+ const walk = (modules) => {
77073
+ for (const m of modules ?? []) {
77074
+ const v = m?.value;
77075
+ if (!v)
77076
+ continue;
77077
+ if ((v.type === "script" || v.type === "flow") && typeof v.path === "string") {
77078
+ paths.push(v.path);
77079
+ }
77080
+ walk(v.modules);
77081
+ walk(v.default);
77082
+ for (const b of v.branches ?? [])
77083
+ walk(b?.modules);
77084
+ walk(v.tools);
77085
+ }
77086
+ };
77087
+ walk(flowValue?.modules);
77088
+ if (flowValue?.failure_module)
77089
+ walk([flowValue.failure_module]);
77090
+ if (flowValue?.preprocessor_module)
77091
+ walk([flowValue.preprocessor_module]);
77092
+ return paths;
77093
+ }
77037
77094
  async function pushFlow(workspace, remotePath, localPath, message, permissionedAsContext) {
77038
77095
  if (alreadySynced3.includes(localPath)) {
77039
77096
  return;
@@ -77063,6 +77120,10 @@ async function pushFlow(workspace, remotePath, localPath, message, permissionedA
77063
77120
  if (missingFiles.length > 0) {
77064
77121
  throw new Error(`Cannot push flow ${remotePath}: missing inline script file(s): ${missingFiles.join(", ")}. ` + `Either restore the file(s) or remove the !inline reference(s) from flow.yaml before pushing.`);
77065
77122
  }
77123
+ const badStepPaths = collectStepPaths(localFlow.value).filter((p) => p !== "" && !/^(u|f|g|hub)\//.test(p));
77124
+ if (badStepPaths.length > 0) {
77125
+ throw new Error(`Cannot push flow ${remotePath}: step(s) reference non-workspace path(s): ${badStepPaths.join(", ")}. ` + `Flow step paths must be workspace paths (u/, f/, g/ or hub/), not absolute or local filesystem paths. ` + `This usually means flow.yaml was generated with paths from a checkout directory.`);
77126
+ }
77066
77127
  const hasOnBehalfOf = localFlow.has_on_behalf_of ?? !!localFlow.on_behalf_of_email;
77067
77128
  delete localFlow.has_on_behalf_of;
77068
77129
  const preserveFields = {};
@@ -79434,25 +79495,27 @@ async getRootJobId(jobId?: string): Promise<string>
79434
79495
  /**
79435
79496
  * @deprecated Use runScriptByPath or runScriptByHash instead
79436
79497
  */
79437
- async runScript(path: string | null = null, hash_: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
79498
+ async runScript(path: string | null = null, hash_: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false, tag: string | null = null): Promise<any>
79438
79499
 
79439
79500
  /**
79440
79501
  * Run a script synchronously by its path and wait for the result
79441
79502
  * @param path - Script path in Windmill
79442
79503
  * @param args - Arguments to pass to the script
79443
79504
  * @param verbose - Enable verbose logging
79505
+ * @param tag - Override the worker tag the job runs on
79444
79506
  * @returns Script execution result
79445
79507
  */
79446
- async runScriptByPath(path: string, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
79508
+ async runScriptByPath(path: string, args: Record<string, any> | null = null, verbose: boolean = false, tag: string | null = null): Promise<any>
79447
79509
 
79448
79510
  /**
79449
79511
  * Run a script synchronously by its hash and wait for the result
79450
79512
  * @param hash_ - Script hash in Windmill
79451
79513
  * @param args - Arguments to pass to the script
79452
79514
  * @param verbose - Enable verbose logging
79515
+ * @param tag - Override the worker tag the job runs on
79453
79516
  * @returns Script execution result
79454
79517
  */
79455
- async runScriptByHash(hash_: string, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
79518
+ async runScriptByHash(hash_: string, args: Record<string, any> | null = null, verbose: boolean = false, tag: string | null = null): Promise<any>
79456
79519
 
79457
79520
  /**
79458
79521
  * Append a text to the result stream
@@ -79471,9 +79534,10 @@ async streamResult(stream: AsyncIterable<string>): Promise<void>
79471
79534
  * @param path - Flow path in Windmill
79472
79535
  * @param args - Arguments to pass to the flow
79473
79536
  * @param verbose - Enable verbose logging
79537
+ * @param tag - Override the worker tag the job runs on
79474
79538
  * @returns Flow execution result
79475
79539
  */
79476
- async runFlow(path: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
79540
+ async runFlow(path: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false, tag: string | null = null): Promise<any>
79477
79541
 
79478
79542
  /**
79479
79543
  * Wait for a job to complete and return its result
@@ -79500,25 +79564,27 @@ async getResultMaybe(jobId: string): Promise<any>
79500
79564
  /**
79501
79565
  * @deprecated Use runScriptByPathAsync or runScriptByHashAsync instead
79502
79566
  */
79503
- async runScriptAsync(path: string | null, hash_: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null): Promise<string>
79567
+ async runScriptAsync(path: string | null, hash_: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null, tag: string | null = null): Promise<string>
79504
79568
 
79505
79569
  /**
79506
79570
  * Run a script asynchronously by its path
79507
79571
  * @param path - Script path in Windmill
79508
79572
  * @param args - Arguments to pass to the script
79509
79573
  * @param scheduledInSeconds - Schedule execution for a future time (in seconds)
79574
+ * @param tag - Override the worker tag the job runs on
79510
79575
  * @returns Job ID of the created job
79511
79576
  */
79512
- async runScriptByPathAsync(path: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null): Promise<string>
79577
+ async runScriptByPathAsync(path: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null, tag: string | null = null): Promise<string>
79513
79578
 
79514
79579
  /**
79515
79580
  * Run a script asynchronously by its hash
79516
79581
  * @param hash_ - Script hash in Windmill
79517
79582
  * @param args - Arguments to pass to the script
79518
79583
  * @param scheduledInSeconds - Schedule execution for a future time (in seconds)
79584
+ * @param tag - Override the worker tag the job runs on
79519
79585
  * @returns Job ID of the created job
79520
79586
  */
79521
- async runScriptByHashAsync(hash_: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null): Promise<string>
79587
+ async runScriptByHashAsync(hash_: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null, tag: string | null = null): Promise<string>
79522
79588
 
79523
79589
  /**
79524
79590
  * Run a flow asynchronously by its path
@@ -79526,9 +79592,10 @@ async runScriptByHashAsync(hash_: string, args: Record<string, any> | null = nul
79526
79592
  * @param args - Arguments to pass to the flow
79527
79593
  * @param scheduledInSeconds - Schedule execution for a future time (in seconds)
79528
79594
  * @param doNotTrackInParent - If false, tracks state in parent job (only use when fully awaiting the job)
79595
+ * @param tag - Override the worker tag the job runs on
79529
79596
  * @returns Job ID of the created job
79530
79597
  */
79531
- async runFlowAsync(path: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null, // can only be set to false if this the job will be fully await and not concurrent with any other job // as otherwise the child flow and its own child will store their state in the parent job which will // lead to incorrectness and failures doNotTrackInParent: boolean = true): Promise<string>
79598
+ async runFlowAsync(path: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null, // can only be set to false if this the job will be fully await and not concurrent with any other job // as otherwise the child flow and its own child will store their state in the parent job which will // lead to incorrectness and failures doNotTrackInParent: boolean = true, tag: string | null = null): Promise<string>
79532
79599
 
79533
79600
  /**
79534
79601
  * Resolve a resource value in case the default value was picked because the input payload was undefined
@@ -80188,25 +80255,27 @@ async getRootJobId(jobId?: string): Promise<string>
80188
80255
  /**
80189
80256
  * @deprecated Use runScriptByPath or runScriptByHash instead
80190
80257
  */
80191
- async runScript(path: string | null = null, hash_: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
80258
+ async runScript(path: string | null = null, hash_: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false, tag: string | null = null): Promise<any>
80192
80259
 
80193
80260
  /**
80194
80261
  * Run a script synchronously by its path and wait for the result
80195
80262
  * @param path - Script path in Windmill
80196
80263
  * @param args - Arguments to pass to the script
80197
80264
  * @param verbose - Enable verbose logging
80265
+ * @param tag - Override the worker tag the job runs on
80198
80266
  * @returns Script execution result
80199
80267
  */
80200
- async runScriptByPath(path: string, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
80268
+ async runScriptByPath(path: string, args: Record<string, any> | null = null, verbose: boolean = false, tag: string | null = null): Promise<any>
80201
80269
 
80202
80270
  /**
80203
80271
  * Run a script synchronously by its hash and wait for the result
80204
80272
  * @param hash_ - Script hash in Windmill
80205
80273
  * @param args - Arguments to pass to the script
80206
80274
  * @param verbose - Enable verbose logging
80275
+ * @param tag - Override the worker tag the job runs on
80207
80276
  * @returns Script execution result
80208
80277
  */
80209
- async runScriptByHash(hash_: string, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
80278
+ async runScriptByHash(hash_: string, args: Record<string, any> | null = null, verbose: boolean = false, tag: string | null = null): Promise<any>
80210
80279
 
80211
80280
  /**
80212
80281
  * Append a text to the result stream
@@ -80225,9 +80294,10 @@ async streamResult(stream: AsyncIterable<string>): Promise<void>
80225
80294
  * @param path - Flow path in Windmill
80226
80295
  * @param args - Arguments to pass to the flow
80227
80296
  * @param verbose - Enable verbose logging
80297
+ * @param tag - Override the worker tag the job runs on
80228
80298
  * @returns Flow execution result
80229
80299
  */
80230
- async runFlow(path: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
80300
+ async runFlow(path: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false, tag: string | null = null): Promise<any>
80231
80301
 
80232
80302
  /**
80233
80303
  * Wait for a job to complete and return its result
@@ -80254,25 +80324,27 @@ async getResultMaybe(jobId: string): Promise<any>
80254
80324
  /**
80255
80325
  * @deprecated Use runScriptByPathAsync or runScriptByHashAsync instead
80256
80326
  */
80257
- async runScriptAsync(path: string | null, hash_: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null): Promise<string>
80327
+ async runScriptAsync(path: string | null, hash_: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null, tag: string | null = null): Promise<string>
80258
80328
 
80259
80329
  /**
80260
80330
  * Run a script asynchronously by its path
80261
80331
  * @param path - Script path in Windmill
80262
80332
  * @param args - Arguments to pass to the script
80263
80333
  * @param scheduledInSeconds - Schedule execution for a future time (in seconds)
80334
+ * @param tag - Override the worker tag the job runs on
80264
80335
  * @returns Job ID of the created job
80265
80336
  */
80266
- async runScriptByPathAsync(path: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null): Promise<string>
80337
+ async runScriptByPathAsync(path: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null, tag: string | null = null): Promise<string>
80267
80338
 
80268
80339
  /**
80269
80340
  * Run a script asynchronously by its hash
80270
80341
  * @param hash_ - Script hash in Windmill
80271
80342
  * @param args - Arguments to pass to the script
80272
80343
  * @param scheduledInSeconds - Schedule execution for a future time (in seconds)
80344
+ * @param tag - Override the worker tag the job runs on
80273
80345
  * @returns Job ID of the created job
80274
80346
  */
80275
- async runScriptByHashAsync(hash_: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null): Promise<string>
80347
+ async runScriptByHashAsync(hash_: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null, tag: string | null = null): Promise<string>
80276
80348
 
80277
80349
  /**
80278
80350
  * Run a flow asynchronously by its path
@@ -80280,9 +80352,10 @@ async runScriptByHashAsync(hash_: string, args: Record<string, any> | null = nul
80280
80352
  * @param args - Arguments to pass to the flow
80281
80353
  * @param scheduledInSeconds - Schedule execution for a future time (in seconds)
80282
80354
  * @param doNotTrackInParent - If false, tracks state in parent job (only use when fully awaiting the job)
80355
+ * @param tag - Override the worker tag the job runs on
80283
80356
  * @returns Job ID of the created job
80284
80357
  */
80285
- async runFlowAsync(path: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null, // can only be set to false if this the job will be fully await and not concurrent with any other job // as otherwise the child flow and its own child will store their state in the parent job which will // lead to incorrectness and failures doNotTrackInParent: boolean = true): Promise<string>
80358
+ async runFlowAsync(path: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null, // can only be set to false if this the job will be fully await and not concurrent with any other job // as otherwise the child flow and its own child will store their state in the parent job which will // lead to incorrectness and failures doNotTrackInParent: boolean = true, tag: string | null = null): Promise<string>
80286
80359
 
80287
80360
  /**
80288
80361
  * Resolve a resource value in case the default value was picked because the input payload was undefined
@@ -81034,25 +81107,27 @@ async getRootJobId(jobId?: string): Promise<string>
81034
81107
  /**
81035
81108
  * @deprecated Use runScriptByPath or runScriptByHash instead
81036
81109
  */
81037
- async runScript(path: string | null = null, hash_: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
81110
+ async runScript(path: string | null = null, hash_: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false, tag: string | null = null): Promise<any>
81038
81111
 
81039
81112
  /**
81040
81113
  * Run a script synchronously by its path and wait for the result
81041
81114
  * @param path - Script path in Windmill
81042
81115
  * @param args - Arguments to pass to the script
81043
81116
  * @param verbose - Enable verbose logging
81117
+ * @param tag - Override the worker tag the job runs on
81044
81118
  * @returns Script execution result
81045
81119
  */
81046
- async runScriptByPath(path: string, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
81120
+ async runScriptByPath(path: string, args: Record<string, any> | null = null, verbose: boolean = false, tag: string | null = null): Promise<any>
81047
81121
 
81048
81122
  /**
81049
81123
  * Run a script synchronously by its hash and wait for the result
81050
81124
  * @param hash_ - Script hash in Windmill
81051
81125
  * @param args - Arguments to pass to the script
81052
81126
  * @param verbose - Enable verbose logging
81127
+ * @param tag - Override the worker tag the job runs on
81053
81128
  * @returns Script execution result
81054
81129
  */
81055
- async runScriptByHash(hash_: string, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
81130
+ async runScriptByHash(hash_: string, args: Record<string, any> | null = null, verbose: boolean = false, tag: string | null = null): Promise<any>
81056
81131
 
81057
81132
  /**
81058
81133
  * Append a text to the result stream
@@ -81071,9 +81146,10 @@ async streamResult(stream: AsyncIterable<string>): Promise<void>
81071
81146
  * @param path - Flow path in Windmill
81072
81147
  * @param args - Arguments to pass to the flow
81073
81148
  * @param verbose - Enable verbose logging
81149
+ * @param tag - Override the worker tag the job runs on
81074
81150
  * @returns Flow execution result
81075
81151
  */
81076
- async runFlow(path: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
81152
+ async runFlow(path: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false, tag: string | null = null): Promise<any>
81077
81153
 
81078
81154
  /**
81079
81155
  * Wait for a job to complete and return its result
@@ -81100,25 +81176,27 @@ async getResultMaybe(jobId: string): Promise<any>
81100
81176
  /**
81101
81177
  * @deprecated Use runScriptByPathAsync or runScriptByHashAsync instead
81102
81178
  */
81103
- async runScriptAsync(path: string | null, hash_: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null): Promise<string>
81179
+ async runScriptAsync(path: string | null, hash_: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null, tag: string | null = null): Promise<string>
81104
81180
 
81105
81181
  /**
81106
81182
  * Run a script asynchronously by its path
81107
81183
  * @param path - Script path in Windmill
81108
81184
  * @param args - Arguments to pass to the script
81109
81185
  * @param scheduledInSeconds - Schedule execution for a future time (in seconds)
81186
+ * @param tag - Override the worker tag the job runs on
81110
81187
  * @returns Job ID of the created job
81111
81188
  */
81112
- async runScriptByPathAsync(path: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null): Promise<string>
81189
+ async runScriptByPathAsync(path: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null, tag: string | null = null): Promise<string>
81113
81190
 
81114
81191
  /**
81115
81192
  * Run a script asynchronously by its hash
81116
81193
  * @param hash_ - Script hash in Windmill
81117
81194
  * @param args - Arguments to pass to the script
81118
81195
  * @param scheduledInSeconds - Schedule execution for a future time (in seconds)
81196
+ * @param tag - Override the worker tag the job runs on
81119
81197
  * @returns Job ID of the created job
81120
81198
  */
81121
- async runScriptByHashAsync(hash_: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null): Promise<string>
81199
+ async runScriptByHashAsync(hash_: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null, tag: string | null = null): Promise<string>
81122
81200
 
81123
81201
  /**
81124
81202
  * Run a flow asynchronously by its path
@@ -81126,9 +81204,10 @@ async runScriptByHashAsync(hash_: string, args: Record<string, any> | null = nul
81126
81204
  * @param args - Arguments to pass to the flow
81127
81205
  * @param scheduledInSeconds - Schedule execution for a future time (in seconds)
81128
81206
  * @param doNotTrackInParent - If false, tracks state in parent job (only use when fully awaiting the job)
81207
+ * @param tag - Override the worker tag the job runs on
81129
81208
  * @returns Job ID of the created job
81130
81209
  */
81131
- async runFlowAsync(path: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null, // can only be set to false if this the job will be fully await and not concurrent with any other job // as otherwise the child flow and its own child will store their state in the parent job which will // lead to incorrectness and failures doNotTrackInParent: boolean = true): Promise<string>
81210
+ async runFlowAsync(path: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null, // can only be set to false if this the job will be fully await and not concurrent with any other job // as otherwise the child flow and its own child will store their state in the parent job which will // lead to incorrectness and failures doNotTrackInParent: boolean = true, tag: string | null = null): Promise<string>
81132
81211
 
81133
81212
  /**
81134
81213
  * Resolve a resource value in case the default value was picked because the input payload was undefined
@@ -82723,27 +82802,27 @@ def create_token(duration = dt.timedelta(days=1)) -> str
82723
82802
  # Create a script job and return its job id.
82724
82803
  #
82725
82804
  # .. deprecated:: Use run_script_by_path_async or run_script_by_hash_async instead.
82726
- def run_script_async(path: str = None, hash_: str = None, args: dict = None, scheduled_in_secs: int = None) -> str
82805
+ def run_script_async(path: str = None, hash_: str = None, args: dict = None, scheduled_in_secs: int = None, tag: str = None) -> str
82727
82806
 
82728
82807
  # Create a script job by path and return its job id.
82729
- def run_script_by_path_async(path: str, args: dict = None, scheduled_in_secs: int = None) -> str
82808
+ def run_script_by_path_async(path: str, args: dict = None, scheduled_in_secs: int = None, tag: str = None) -> str
82730
82809
 
82731
82810
  # Create a script job by hash and return its job id.
82732
- def run_script_by_hash_async(hash_: str, args: dict = None, scheduled_in_secs: int = None) -> str
82811
+ def run_script_by_hash_async(hash_: str, args: dict = None, scheduled_in_secs: int = None, tag: str = None) -> str
82733
82812
 
82734
82813
  # Create a flow job and return its job id.
82735
- def run_flow_async(path: str, args: dict = None, scheduled_in_secs: int = None, do_not_track_in_parent: bool = True) -> str
82814
+ def run_flow_async(path: str, args: dict = None, scheduled_in_secs: int = None, do_not_track_in_parent: bool = True, tag: str = None) -> str
82736
82815
 
82737
82816
  # Run script synchronously and return its result.
82738
82817
  #
82739
82818
  # .. deprecated:: Use run_script_by_path or run_script_by_hash instead.
82740
- def run_script(path: str = None, hash_: str = None, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False) -> Any
82819
+ def run_script(path: str = None, hash_: str = None, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False, tag: str = None) -> Any
82741
82820
 
82742
82821
  # Run script by path synchronously and return its result.
82743
- def run_script_by_path(path: str, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False) -> Any
82822
+ def run_script_by_path(path: str, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False, tag: str = None) -> Any
82744
82823
 
82745
82824
  # Run script by hash synchronously and return its result.
82746
- def run_script_by_hash(hash_: str, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False) -> Any
82825
+ def run_script_by_hash(hash_: str, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False, tag: str = None) -> Any
82747
82826
 
82748
82827
  # Run a script on the current worker without creating a job.
82749
82828
  #
@@ -83161,10 +83240,11 @@ def get_version() -> str
83161
83240
  # assert_result_is_not_none: Raise exception if result is None
83162
83241
  # cleanup: Register cleanup handler to cancel job on exit
83163
83242
  # timeout: Maximum time to wait
83243
+ # tag: Override the worker tag the job runs on
83164
83244
  #
83165
83245
  # Returns:
83166
83246
  # Script result
83167
- def run_script_sync(hash: str, args: Dict[str, Any] = None, verbose: bool = False, assert_result_is_not_none: bool = True, cleanup: bool = True, timeout: dt.timedelta = None) -> Any
83247
+ def run_script_sync(hash: str, args: Dict[str, Any] = None, verbose: bool = False, assert_result_is_not_none: bool = True, cleanup: bool = True, timeout: dt.timedelta = None, tag: str = None) -> Any
83168
83248
 
83169
83249
  # Run a script synchronously by path and return its result.
83170
83250
  #
@@ -83175,10 +83255,11 @@ def run_script_sync(hash: str, args: Dict[str, Any] = None, verbose: bool = Fals
83175
83255
  # assert_result_is_not_none: Raise exception if result is None
83176
83256
  # cleanup: Register cleanup handler to cancel job on exit
83177
83257
  # timeout: Maximum time to wait
83258
+ # tag: Override the worker tag the job runs on
83178
83259
  #
83179
83260
  # Returns:
83180
83261
  # Script result
83181
- def run_script_by_path_sync(path: str, args: Dict[str, Any] = None, verbose: bool = False, assert_result_is_not_none: bool = True, cleanup: bool = True, timeout: dt.timedelta = None) -> Any
83262
+ def run_script_by_path_sync(path: str, args: Dict[str, Any] = None, verbose: bool = False, assert_result_is_not_none: bool = True, cleanup: bool = True, timeout: dt.timedelta = None, tag: str = None) -> Any
83182
83263
 
83183
83264
  # Convenient helpers that takes an S3 resource as input and returns the settings necessary to
83184
83265
  # initiate an S3 connection from DuckDB
@@ -85751,6 +85832,11 @@ inspect asset-driven pipelines (scripts marked \`// pipeline\`, wired by \`// on
85751
85832
  - \`--json\` - Output as JSON (for piping to jq)
85752
85833
  - \`pipeline show <folder:string>\` - render a pipeline folder's DAG (sources, lineage, subscriptions) in the terminal
85753
85834
  - \`--json\` - Output the raw asset graph as JSON
85835
+ - \`pipeline run <folder:string>\` - run a bounded cascade: from a schedule/manual root, fan downstream up to the --to end node(s)
85836
+ - \`--from <script:string>\` - Start script (short name or path). Defaults to the folder's sole schedule/manual root.
85837
+ - \`--to <node:string>\` - End node(s) to stop at — script names/paths or asset URIs (e.g. datatable://main/staged). Repeatable or comma-separated. Omit to run the full downstream.
85838
+ - \`--dry-run\` - Print the topological run plan without executing.
85839
+ - \`--json\` - Output the plan as JSON (for piping to jq).
85754
85840
 
85755
85841
  ### protection-rules
85756
85842
 
@@ -92589,7 +92675,7 @@ await __promiseAll([
92589
92675
  async function docs(opts, query) {
92590
92676
  await requireLogin(opts);
92591
92677
  const workspace = await resolveWorkspace(opts);
92592
- const url = `${workspace.remote}api/inkeep`;
92678
+ const url = `${workspace.remote}api/docs/search?query=${encodeURIComponent(query)}`;
92593
92679
  console.log(colors.bold(`
92594
92680
  Searching Windmill docs...
92595
92681
  `));
@@ -92597,55 +92683,36 @@ Searching Windmill docs...
92597
92683
  let res;
92598
92684
  try {
92599
92685
  res = await fetch(url, {
92600
- method: "POST",
92686
+ method: "GET",
92601
92687
  headers: {
92602
- "Content-Type": "application/json",
92603
92688
  Authorization: `Bearer ${workspace.token}`,
92604
92689
  ...extraHeaders
92605
- },
92606
- body: JSON.stringify({ query })
92690
+ }
92607
92691
  });
92608
92692
  } catch (e) {
92609
92693
  throw new Error(`Network error connecting to ${workspace.remote}: ${e}`);
92610
92694
  }
92611
92695
  await detectAuthGatewayChallenge(res, url);
92612
- if (res.status === 403) {
92613
- info("Windmill documentation search is an Enterprise Edition feature. Please upgrade to use this command.");
92614
- return;
92615
- }
92616
92696
  if (!res.ok) {
92617
92697
  throw new Error(`Documentation search failed: ${res.status} ${res.statusText}
92618
92698
  ${await res.text()}`);
92619
92699
  }
92620
92700
  const data3 = await res.json();
92621
- const raw = data3.choices?.[0]?.message?.content;
92622
- if (!raw) {
92623
- info("No documentation found for this query.");
92701
+ const items = data3.results ?? [];
92702
+ if (opts.json) {
92703
+ console.log(JSON.stringify(items, null, 2));
92624
92704
  return;
92625
92705
  }
92626
- let parsed;
92627
- try {
92628
- parsed = JSON.parse(raw);
92629
- } catch {
92630
- throw new Error("Failed to parse documentation response.");
92631
- }
92632
- const items = parsed.content ?? [];
92633
92706
  if (items.length === 0) {
92634
92707
  info("No documentation found for this query.");
92635
92708
  return;
92636
92709
  }
92637
- if (opts.json) {
92638
- console.log(JSON.stringify(items, null, 2));
92639
- return;
92640
- }
92641
92710
  for (const item of items) {
92642
92711
  console.log(colors.bold(colors.cyan(`\uD83D\uDCC4 ${item.title}`)));
92643
92712
  if (item.url) {
92644
92713
  console.log(` ${colors.underline(item.url)}`);
92645
92714
  }
92646
- const text = item.source?.content?.[0]?.text;
92647
- if (text) {
92648
- const snippet = text.length > 500 ? text.slice(0, 500) + "..." : text;
92715
+ for (const snippet of item.snippets ?? []) {
92649
92716
  console.log(` ${snippet}`);
92650
92717
  }
92651
92718
  console.log();
@@ -94680,6 +94747,191 @@ await __promiseAll([
94680
94747
  init_auth(),
94681
94748
  init_context()
94682
94749
  ]);
94750
+
94751
+ // src/commands/pipeline/boundedCascade.ts
94752
+ var SCRIPT_PREFIX = "script:";
94753
+ var scriptNodeId = (path23) => `${SCRIPT_PREFIX}${path23}`;
94754
+ var isScriptNode = (id) => id.startsWith(SCRIPT_PREFIX);
94755
+ var scriptPathOf = (id) => id.slice(SCRIPT_PREFIX.length);
94756
+ var assetNodeId = (kind, path23) => `${kind}:${path23}`;
94757
+ var EVENT_TRIGGER_KINDS = new Set([
94758
+ "kafka",
94759
+ "mqtt",
94760
+ "nats",
94761
+ "postgres",
94762
+ "sqs",
94763
+ "gcp",
94764
+ "email"
94765
+ ]);
94766
+ function assetUriToNodeId(uri) {
94767
+ const m3 = uri.match(/^([a-z0-9_]+):\/\/(.+)$/i);
94768
+ if (!m3)
94769
+ return;
94770
+ const prefix = m3[1].toLowerCase();
94771
+ const kind = prefix === "s3" ? "s3object" : prefix;
94772
+ return `${kind}:${m3[2]}`;
94773
+ }
94774
+ function addEdge(dag, a2, b2) {
94775
+ if (a2 === b2)
94776
+ return;
94777
+ dag.nodes.add(a2);
94778
+ dag.nodes.add(b2);
94779
+ (dag.down.get(a2) ?? dag.down.set(a2, new Set).get(a2)).add(b2);
94780
+ (dag.up.get(b2) ?? dag.up.set(b2, new Set).get(b2)).add(a2);
94781
+ }
94782
+ function buildLineageDag(g2) {
94783
+ const dag = { down: new Map, up: new Map, nodes: new Set };
94784
+ for (const r2 of g2.runnables ?? []) {
94785
+ if (r2.usage_kind === "script")
94786
+ dag.nodes.add(scriptNodeId(r2.path));
94787
+ }
94788
+ for (const a2 of g2.assets ?? [])
94789
+ dag.nodes.add(assetNodeId(a2.kind, a2.path));
94790
+ for (const e2 of g2.edges ?? []) {
94791
+ if (e2.runnable_kind !== "script")
94792
+ continue;
94793
+ const aid = assetNodeId(e2.asset_kind, e2.asset_path);
94794
+ const access2 = e2.access_type ?? "r";
94795
+ if (access2 === "w" || access2 === "rw") {
94796
+ addEdge(dag, scriptNodeId(e2.runnable_path), aid);
94797
+ } else if (access2 === "r") {
94798
+ addEdge(dag, aid, scriptNodeId(e2.runnable_path));
94799
+ }
94800
+ }
94801
+ for (const t2 of g2.triggers ?? []) {
94802
+ if (t2.trigger_kind !== "asset" || t2.runnable_kind !== "script")
94803
+ continue;
94804
+ const at = t2;
94805
+ addEdge(dag, assetNodeId(at.asset_kind, at.asset_path), scriptNodeId(at.runnable_path));
94806
+ }
94807
+ return dag;
94808
+ }
94809
+ function closure(adj, start) {
94810
+ const seen = new Set;
94811
+ const queue = [start];
94812
+ while (queue.length > 0) {
94813
+ const cur = queue.shift();
94814
+ for (const n2 of adj.get(cur) ?? []) {
94815
+ if (seen.has(n2))
94816
+ continue;
94817
+ seen.add(n2);
94818
+ queue.push(n2);
94819
+ }
94820
+ }
94821
+ seen.delete(start);
94822
+ return seen;
94823
+ }
94824
+ var descendants = (dag, n2) => closure(dag.down, n2);
94825
+ var ancestors = (dag, n2) => closure(dag.up, n2);
94826
+ function boundedSet(dag, start, ends) {
94827
+ const downSet = new Set(descendants(dag, start));
94828
+ downSet.add(start);
94829
+ const reachableEnds = ends.filter((e2) => downSet.has(e2));
94830
+ const droppedEnds = ends.filter((e2) => !downSet.has(e2));
94831
+ if (reachableEnds.length === 0) {
94832
+ return { nodes: new Set([start]), reachableEnds, droppedEnds };
94833
+ }
94834
+ const upClosure = new Set;
94835
+ for (const e2 of reachableEnds) {
94836
+ upClosure.add(e2);
94837
+ for (const a2 of ancestors(dag, e2))
94838
+ upClosure.add(a2);
94839
+ }
94840
+ const nodes = new Set;
94841
+ for (const n2 of downSet)
94842
+ if (upClosure.has(n2))
94843
+ nodes.add(n2);
94844
+ nodes.add(start);
94845
+ return { nodes, reachableEnds, droppedEnds };
94846
+ }
94847
+ function validStarts(g2) {
94848
+ const subscribers = new Set;
94849
+ const scheduleScripts = new Set;
94850
+ const eventScripts = new Set;
94851
+ for (const t2 of g2.triggers ?? []) {
94852
+ if (t2.runnable_kind !== "script")
94853
+ continue;
94854
+ if (t2.trigger_kind === "asset")
94855
+ subscribers.add(t2.runnable_path);
94856
+ else if (t2.trigger_kind === "schedule")
94857
+ scheduleScripts.add(t2.runnable_path);
94858
+ else if (EVENT_TRIGGER_KINDS.has(t2.trigger_kind))
94859
+ eventScripts.add(t2.runnable_path);
94860
+ }
94861
+ const out = new Set;
94862
+ for (const r2 of g2.runnables ?? []) {
94863
+ if (r2.usage_kind !== "script")
94864
+ continue;
94865
+ const p3 = r2.path;
94866
+ if (scheduleScripts.has(p3))
94867
+ out.add(scriptNodeId(p3));
94868
+ else if (!subscribers.has(p3) && !eventScripts.has(p3))
94869
+ out.add(scriptNodeId(p3));
94870
+ }
94871
+ return out;
94872
+ }
94873
+ function scriptsOf(nodes) {
94874
+ const out = [];
94875
+ for (const id of nodes)
94876
+ if (isScriptNode(id))
94877
+ out.push(scriptPathOf(id));
94878
+ return out;
94879
+ }
94880
+ function resolveToken(g2, token) {
94881
+ if (token.includes("://")) {
94882
+ const id = assetUriToNodeId(token);
94883
+ return id && g2.assets.some((a2) => `${a2.kind}:${a2.path}` === id) ? id : undefined;
94884
+ }
94885
+ const scripts = (g2.runnables ?? []).filter((r2) => r2.usage_kind === "script");
94886
+ const exact = scripts.find((r2) => r2.path === token);
94887
+ if (exact)
94888
+ return scriptNodeId(exact.path);
94889
+ const byShort = scripts.filter((r2) => (r2.path.split("/").pop() ?? r2.path) === token);
94890
+ return byShort.length === 1 ? scriptNodeId(byShort[0].path) : undefined;
94891
+ }
94892
+ function topoOrder(g2, scripts) {
94893
+ const dag = buildLineageDag(g2);
94894
+ const down = new Map;
94895
+ const indegree = new Map;
94896
+ for (const s2 of scripts)
94897
+ indegree.set(s2, 0);
94898
+ for (const s2 of scripts) {
94899
+ const sid = scriptNodeId(s2);
94900
+ const oneHop = new Set;
94901
+ for (const asset of dag.down.get(sid) ?? []) {
94902
+ for (const sub of dag.down.get(asset) ?? []) {
94903
+ if (isScriptNode(sub)) {
94904
+ const p3 = scriptPathOf(sub);
94905
+ if (p3 !== s2 && scripts.has(p3))
94906
+ oneHop.add(p3);
94907
+ }
94908
+ }
94909
+ }
94910
+ if (oneHop.size > 0) {
94911
+ down.set(s2, oneHop);
94912
+ for (const p3 of oneHop)
94913
+ indegree.set(p3, (indegree.get(p3) ?? 0) + 1);
94914
+ }
94915
+ }
94916
+ const ready = [...scripts].filter((s2) => (indegree.get(s2) ?? 0) === 0);
94917
+ const remaining = new Map(indegree);
94918
+ const order = [];
94919
+ while (ready.length > 0) {
94920
+ const n2 = ready.shift();
94921
+ order.push(n2);
94922
+ for (const p3 of down.get(n2) ?? []) {
94923
+ const d3 = (remaining.get(p3) ?? 0) - 1;
94924
+ remaining.set(p3, d3);
94925
+ if (d3 === 0)
94926
+ ready.push(p3);
94927
+ }
94928
+ }
94929
+ const orderedSet = new Set(order);
94930
+ const cyclic = [...scripts].filter((s2) => !orderedSet.has(s2));
94931
+ return { order, cyclic };
94932
+ }
94933
+
94934
+ // src/commands/pipeline/pipeline.ts
94683
94935
  async function apiGet(path23) {
94684
94936
  const response = await fetch(`${OpenAPI.BASE}${path23}`, {
94685
94937
  headers: { Authorization: `Bearer ${OpenAPI.TOKEN}` }
@@ -94838,7 +95090,132 @@ async function show2(opts, folder) {
94838
95090
  console.log(lines.join(`
94839
95091
  `));
94840
95092
  }
94841
- var command41 = new Command().description("inspect asset-driven pipelines (scripts marked `// pipeline`, wired by `// on <spec>` annotations)").command("list", "list pipeline folders in the workspace").option("--json", "Output as JSON (for piping to jq)").action(list18).command("show", "render a pipeline folder's DAG (sources, lineage, subscriptions) in the terminal").arguments("<folder:string>").option("--json", "Output the raw asset graph as JSON").action(show2);
95093
+ async function waitJob(workspace, id) {
95094
+ const MAX_RETRIES = 6000;
95095
+ for (let i = 0;i < MAX_RETRIES; i++) {
95096
+ try {
95097
+ const r2 = await getCompletedJobResultMaybe({
95098
+ workspace,
95099
+ id,
95100
+ getStarted: false
95101
+ });
95102
+ if (r2.completed)
95103
+ return r2.success === true;
95104
+ } catch {}
95105
+ await new Promise((res) => setTimeout(res, 100));
95106
+ }
95107
+ throw new Error(`Timed out waiting for job ${id}`);
95108
+ }
95109
+ async function run5(opts, folder) {
95110
+ if (opts.json)
95111
+ setSilent(true);
95112
+ const workspace = await resolveWorkspace(opts);
95113
+ await requireLogin(opts);
95114
+ const f3 = folder.replace(/^f\//, "").replace(/\/$/, "");
95115
+ const graph = await apiGet(`/w/${workspace.workspaceId}/assets/graph?folder=${encodeURIComponent(f3)}&asset_kinds=${ASSET_KINDS}`);
95116
+ const starts = validStarts(graph);
95117
+ let start;
95118
+ if (opts.from) {
95119
+ const resolved = resolveToken(graph, opts.from);
95120
+ if (!resolved) {
95121
+ const matches = graph.runnables.filter((r2) => r2.usage_kind === "script" && (r2.path.split("/").pop() ?? r2.path) === opts.from);
95122
+ if (matches.length > 1) {
95123
+ throw new Error(`--from '${opts.from}' matches multiple scripts (${matches.map((r2) => r2.path).sort().join(", ")}) — pass the full path.`);
95124
+ }
95125
+ throw new Error(`--from '${opts.from}' matched no script in f/${f3}.`);
95126
+ }
95127
+ if (!starts.has(resolved)) {
95128
+ throw new Error(`--from '${opts.from}' is not a valid bounded-run start. Starts must be schedule-triggered or manual roots; row-backed event triggers (kafka/mqtt/nats/postgres/sqs/gcp/email) fan out per-event and can't be bounded.`);
95129
+ }
95130
+ start = resolved;
95131
+ } else if (starts.size === 1) {
95132
+ start = [...starts][0];
95133
+ } else if (starts.size === 0) {
95134
+ throw new Error(`No schedule or manual root in f/${f3} to start a bounded run from.`);
95135
+ } else {
95136
+ throw new Error(`f/${f3} has ${starts.size} possible starts — pass --from <script>. Candidates: ${scriptsOf(starts).sort().join(", ")}`);
95137
+ }
95138
+ const toTokens = (opts.to ?? []).flatMap((t2) => t2.split(",")).map((t2) => t2.trim()).filter(Boolean);
95139
+ const ends = [];
95140
+ const unresolved = [];
95141
+ for (const tok of toTokens) {
95142
+ const id = resolveToken(graph, tok);
95143
+ if (!id)
95144
+ unresolved.push(tok);
95145
+ else
95146
+ ends.push(id);
95147
+ }
95148
+ if (unresolved.length > 0) {
95149
+ const details = unresolved.map((tok) => {
95150
+ const matches = graph.runnables.filter((r2) => r2.usage_kind === "script" && (r2.path.split("/").pop() ?? r2.path) === tok);
95151
+ return matches.length > 1 ? `'${tok}' (ambiguous: ${matches.map((r2) => r2.path).sort().join(", ")} — use the full path)` : `'${tok}' (no match in f/${f3})`;
95152
+ });
95153
+ throw new Error(`--to could not be resolved: ${details.join("; ")}.`);
95154
+ }
95155
+ const idLabel = (id) => id.startsWith("script:") ? scriptPathOf(id) : id;
95156
+ const dag = buildLineageDag(graph);
95157
+ let selectedScripts;
95158
+ let reachableEnds = [];
95159
+ let droppedEnds = [];
95160
+ if (ends.length === 0) {
95161
+ const all = new Set(descendants(dag, start));
95162
+ all.add(start);
95163
+ selectedScripts = new Set(scriptsOf(all));
95164
+ } else {
95165
+ const res = boundedSet(dag, start, ends);
95166
+ reachableEnds = res.reachableEnds;
95167
+ droppedEnds = res.droppedEnds;
95168
+ for (const d3 of droppedEnds) {
95169
+ warn(`end '${idLabel(d3)}' is not downstream of the start — ignored.`);
95170
+ }
95171
+ selectedScripts = new Set(scriptsOf(res.nodes));
95172
+ }
95173
+ const { order, cyclic } = topoOrder(graph, selectedScripts);
95174
+ if (cyclic.length > 0) {
95175
+ warn(`Skipping ${cyclic.length} script(s) on a dependency cycle: ${cyclic.sort().join(", ")}`);
95176
+ }
95177
+ if (opts.json) {
95178
+ console.log(JSON.stringify({
95179
+ start: scriptPathOf(start),
95180
+ ends: ends.map(idLabel),
95181
+ reachableEnds: reachableEnds.map(idLabel),
95182
+ droppedEnds: droppedEnds.map(idLabel),
95183
+ order,
95184
+ cyclic
95185
+ }));
95186
+ }
95187
+ if (order.length === 0) {
95188
+ if (!opts.json)
95189
+ info("Nothing to run.");
95190
+ return;
95191
+ }
95192
+ if (opts.dryRun) {
95193
+ if (!opts.json) {
95194
+ info(colors.bold(`Bounded run plan — ${order.length} script${order.length === 1 ? "" : "s"}`) + colors.dim(` (from ${shortName(scriptPathOf(start))})`));
95195
+ order.forEach((p3, i) => info(` ${i + 1}. ${p3}`));
95196
+ }
95197
+ return;
95198
+ }
95199
+ for (const path23 of order) {
95200
+ if (!opts.json)
95201
+ info(colors.gray(`▶ running ${path23}…`));
95202
+ const id = await runScriptByPath({
95203
+ workspace: workspace.workspaceId,
95204
+ path: path23,
95205
+ requestBody: { _wmill_skip_asset_dispatch: true }
95206
+ });
95207
+ const ok = await waitJob(workspace.workspaceId, id);
95208
+ if (!ok) {
95209
+ throw new Error(`Bounded run failed at ${path23} (job ${id}).`);
95210
+ }
95211
+ if (!opts.json)
95212
+ info(colors.green(` ✓ ${path23}`));
95213
+ }
95214
+ if (!opts.json) {
95215
+ info(colors.green.bold(`Bounded run complete — ${order.length} script(s) succeeded.`));
95216
+ }
95217
+ }
95218
+ var command41 = new Command().description("inspect asset-driven pipelines (scripts marked `// pipeline`, wired by `// on <spec>` annotations)").command("list", "list pipeline folders in the workspace").option("--json", "Output as JSON (for piping to jq)").action(list18).command("show", "render a pipeline folder's DAG (sources, lineage, subscriptions) in the terminal").arguments("<folder:string>").option("--json", "Output the raw asset graph as JSON").action(show2).command("run", "run a bounded cascade: from a schedule/manual root, fan downstream up to the --to end node(s)").arguments("<folder:string>").option("--from <script:string>", "Start script (short name or path). Defaults to the folder's sole schedule/manual root.").option("--to <node:string>", "End node(s) to stop at — script names/paths or asset URIs (e.g. datatable://main/staged). Repeatable or comma-separated. Omit to run the full downstream.", { collect: true }).option("--dry-run", "Print the topological run plan without executing.").option("--json", "Output the plan as JSON (for piping to jq).").action(run5);
94842
95219
  var pipeline_default = command41;
94843
95220
 
94844
95221
  // src/commands/ducklake/ducklake.ts
@@ -94865,11 +95242,11 @@ async function list19(opts) {
94865
95242
  new Table2().header(["Name"]).padding(2).border(true).body(names.map((name) => [name])).render();
94866
95243
  }
94867
95244
  }
94868
- async function run5(opts, sql) {
95245
+ async function run6(opts, sql) {
94869
95246
  const name = opts.name ?? DEFAULT_DUCKLAKE_NAME;
94870
95247
  await runCatalogQuery(opts, "ducklake", name, sql);
94871
95248
  }
94872
- var command42 = new Command().description("ducklake related commands").command("list", "list all ducklakes in the workspace").option("--json", "Output as JSON (for piping to jq)").action(list19).command("run", "run a SQL query on a ducklake").arguments("<sql:string>").option("-n --name <name:string>", "Ducklake name (default: main)").option("-s --silent", "Output only the final result as JSON. Useful for scripting.").action(run5);
95249
+ var command42 = new Command().description("ducklake related commands").command("list", "list all ducklakes in the workspace").option("--json", "Output as JSON (for piping to jq)").action(list19).command("run", "run a SQL query on a ducklake").arguments("<sql:string>").option("-n --name <name:string>", "Ducklake name (default: main)").option("-s --silent", "Output only the final result as JSON. Useful for scripting.").action(run6);
94873
95250
  var ducklake_default = command42;
94874
95251
 
94875
95252
  // src/commands/object-storage/object-storage.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windmill-cli",
3
- "version": "1.739.0",
3
+ "version": "1.741.0",
4
4
  "description": "CLI for Windmill",
5
5
  "license": "Apache 2.0",
6
6
  "type": "module",