windmill-cli 1.738.0 → 1.740.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 +362 -39
  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.738.0",
16787
+ VERSION: "1.740.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,
@@ -17213,12 +17214,12 @@ __export(exports_services_gen, {
17213
17214
  refreshToken: () => refreshToken,
17214
17215
  refreshCustomInstanceUserPwd: () => refreshCustomInstanceUserPwd,
17215
17216
  rebuildDependencyMap: () => rebuildDependencyMap,
17217
+ readDocsPage: () => readDocsPage,
17216
17218
  rawScriptByPathTokened: () => rawScriptByPathTokened,
17217
17219
  rawScriptByPath: () => rawScriptByPath,
17218
17220
  rawScriptByHash: () => rawScriptByHash,
17219
17221
  queryResourceTypes: () => queryResourceTypes,
17220
17222
  queryHubScripts: () => queryHubScripts,
17221
- queryDocumentation: () => queryDocumentation,
17222
17223
  pruneVersions: () => pruneVersions,
17223
17224
  previewSchedule: () => previewSchedule,
17224
17225
  polarsConnectionSettingsV2: () => polarsConnectionSettingsV2,
@@ -17428,6 +17429,7 @@ __export(exports_services_gen, {
17428
17429
  getSharedUiVersion: () => getSharedUiVersion,
17429
17430
  getSharedUi: () => getSharedUi,
17430
17431
  getSettings: () => getSettings,
17432
+ getSessionWorkspaceStatus: () => getSessionWorkspaceStatus,
17431
17433
  getSecondaryStorageNames: () => getSecondaryStorageNames,
17432
17434
  getScriptLatestVersion: () => getScriptLatestVersion,
17433
17435
  getScriptHistoryByPath: () => getScriptHistoryByPath,
@@ -17529,6 +17531,7 @@ __export(exports_services_gen, {
17529
17531
  getFlowDeploymentStatus: () => getFlowDeploymentStatus,
17530
17532
  getFlowDebugInfo: () => getFlowDebugInfo,
17531
17533
  getFlowByPath: () => getFlowByPath,
17534
+ getFlowAllLogsStructured: () => getFlowAllLogsStructured,
17532
17535
  getFlowAllLogs: () => getFlowAllLogs,
17533
17536
  getEmailTrigger: () => getEmailTrigger,
17534
17537
  getDraftForUser: () => getDraftForUser,
@@ -17826,14 +17829,21 @@ var backendVersion = () => {
17826
17829
  method: "GET",
17827
17830
  url: "/ee_license"
17828
17831
  });
17829
- }, queryDocumentation = (data3) => {
17832
+ }, searchDocs = (data3) => {
17830
17833
  return request(OpenAPI, {
17831
- method: "POST",
17832
- url: "/inkeep",
17833
- body: data3.requestBody,
17834
- mediaType: "application/json",
17835
- errors: {
17836
- 403: "Enterprise Edition required"
17834
+ method: "GET",
17835
+ url: "/docs/search",
17836
+ query: {
17837
+ query: data3.query
17838
+ }
17839
+ });
17840
+ }, readDocsPage = (data3) => {
17841
+ return request(OpenAPI, {
17842
+ method: "GET",
17843
+ url: "/docs/page",
17844
+ query: {
17845
+ url: data3.url,
17846
+ section: data3.section
17837
17847
  }
17838
17848
  });
17839
17849
  }, getOpenApiYaml = () => {
@@ -18120,6 +18130,13 @@ var backendVersion = () => {
18120
18130
  method: "GET",
18121
18131
  url: "/workspaces/users"
18122
18132
  });
18133
+ }, getSessionWorkspaceStatus = (data3) => {
18134
+ return request(OpenAPI, {
18135
+ method: "POST",
18136
+ url: "/workspaces/session_workspace_status",
18137
+ body: data3.requestBody,
18138
+ mediaType: "application/json"
18139
+ });
18123
18140
  }, getWorkspaceAsSuperAdmin = (data3) => {
18124
18141
  return request(OpenAPI, {
18125
18142
  method: "GET",
@@ -21762,6 +21779,7 @@ var backendVersion = () => {
21762
21779
  query: {
21763
21780
  include_header: data3.includeHeader,
21764
21781
  invisible_to_owner: data3.invisibleToOwner,
21782
+ timeout: data3.timeout,
21765
21783
  job_id: data3.jobId
21766
21784
  },
21767
21785
  body: data3.requestBody,
@@ -22271,6 +22289,15 @@ var backendVersion = () => {
22271
22289
  id: data3.id
22272
22290
  }
22273
22291
  });
22292
+ }, getFlowAllLogsStructured = (data3) => {
22293
+ return request(OpenAPI, {
22294
+ method: "GET",
22295
+ url: "/w/{workspace}/jobs_u/get_flow_all_logs_structured/{id}",
22296
+ path: {
22297
+ workspace: data3.workspace,
22298
+ id: data3.id
22299
+ }
22300
+ });
22274
22301
  }, getCompletedJobLogsTail = (data3) => {
22275
22302
  return request(OpenAPI, {
22276
22303
  method: "GET",
@@ -25501,7 +25528,7 @@ var init_auth = __esm(async () => {
25501
25528
  });
25502
25529
 
25503
25530
  // src/core/constants.ts
25504
- var WM_FORK_PREFIX = "wm-fork", VERSION = "1.738.0";
25531
+ var WM_FORK_PREFIX = "wm-fork", VERSION = "1.740.0";
25505
25532
 
25506
25533
  // src/utils/git.ts
25507
25534
  var exports_git = {};
@@ -85743,6 +85770,11 @@ inspect asset-driven pipelines (scripts marked \`// pipeline\`, wired by \`// on
85743
85770
  - \`--json\` - Output as JSON (for piping to jq)
85744
85771
  - \`pipeline show <folder:string>\` - render a pipeline folder's DAG (sources, lineage, subscriptions) in the terminal
85745
85772
  - \`--json\` - Output the raw asset graph as JSON
85773
+ - \`pipeline run <folder:string>\` - run a bounded cascade: from a schedule/manual root, fan downstream up to the --to end node(s)
85774
+ - \`--from <script:string>\` - Start script (short name or path). Defaults to the folder's sole schedule/manual root.
85775
+ - \`--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.
85776
+ - \`--dry-run\` - Print the topological run plan without executing.
85777
+ - \`--json\` - Output the plan as JSON (for piping to jq).
85746
85778
 
85747
85779
  ### protection-rules
85748
85780
 
@@ -92581,7 +92613,7 @@ await __promiseAll([
92581
92613
  async function docs(opts, query) {
92582
92614
  await requireLogin(opts);
92583
92615
  const workspace = await resolveWorkspace(opts);
92584
- const url = `${workspace.remote}api/inkeep`;
92616
+ const url = `${workspace.remote}api/docs/search?query=${encodeURIComponent(query)}`;
92585
92617
  console.log(colors.bold(`
92586
92618
  Searching Windmill docs...
92587
92619
  `));
@@ -92589,55 +92621,36 @@ Searching Windmill docs...
92589
92621
  let res;
92590
92622
  try {
92591
92623
  res = await fetch(url, {
92592
- method: "POST",
92624
+ method: "GET",
92593
92625
  headers: {
92594
- "Content-Type": "application/json",
92595
92626
  Authorization: `Bearer ${workspace.token}`,
92596
92627
  ...extraHeaders
92597
- },
92598
- body: JSON.stringify({ query })
92628
+ }
92599
92629
  });
92600
92630
  } catch (e) {
92601
92631
  throw new Error(`Network error connecting to ${workspace.remote}: ${e}`);
92602
92632
  }
92603
92633
  await detectAuthGatewayChallenge(res, url);
92604
- if (res.status === 403) {
92605
- info("Windmill documentation search is an Enterprise Edition feature. Please upgrade to use this command.");
92606
- return;
92607
- }
92608
92634
  if (!res.ok) {
92609
92635
  throw new Error(`Documentation search failed: ${res.status} ${res.statusText}
92610
92636
  ${await res.text()}`);
92611
92637
  }
92612
92638
  const data3 = await res.json();
92613
- const raw = data3.choices?.[0]?.message?.content;
92614
- if (!raw) {
92615
- info("No documentation found for this query.");
92639
+ const items = data3.results ?? [];
92640
+ if (opts.json) {
92641
+ console.log(JSON.stringify(items, null, 2));
92616
92642
  return;
92617
92643
  }
92618
- let parsed;
92619
- try {
92620
- parsed = JSON.parse(raw);
92621
- } catch {
92622
- throw new Error("Failed to parse documentation response.");
92623
- }
92624
- const items = parsed.content ?? [];
92625
92644
  if (items.length === 0) {
92626
92645
  info("No documentation found for this query.");
92627
92646
  return;
92628
92647
  }
92629
- if (opts.json) {
92630
- console.log(JSON.stringify(items, null, 2));
92631
- return;
92632
- }
92633
92648
  for (const item of items) {
92634
92649
  console.log(colors.bold(colors.cyan(`\uD83D\uDCC4 ${item.title}`)));
92635
92650
  if (item.url) {
92636
92651
  console.log(` ${colors.underline(item.url)}`);
92637
92652
  }
92638
- const text = item.source?.content?.[0]?.text;
92639
- if (text) {
92640
- const snippet = text.length > 500 ? text.slice(0, 500) + "..." : text;
92653
+ for (const snippet of item.snippets ?? []) {
92641
92654
  console.log(` ${snippet}`);
92642
92655
  }
92643
92656
  console.log();
@@ -94672,6 +94685,191 @@ await __promiseAll([
94672
94685
  init_auth(),
94673
94686
  init_context()
94674
94687
  ]);
94688
+
94689
+ // src/commands/pipeline/boundedCascade.ts
94690
+ var SCRIPT_PREFIX = "script:";
94691
+ var scriptNodeId = (path23) => `${SCRIPT_PREFIX}${path23}`;
94692
+ var isScriptNode = (id) => id.startsWith(SCRIPT_PREFIX);
94693
+ var scriptPathOf = (id) => id.slice(SCRIPT_PREFIX.length);
94694
+ var assetNodeId = (kind, path23) => `${kind}:${path23}`;
94695
+ var EVENT_TRIGGER_KINDS = new Set([
94696
+ "kafka",
94697
+ "mqtt",
94698
+ "nats",
94699
+ "postgres",
94700
+ "sqs",
94701
+ "gcp",
94702
+ "email"
94703
+ ]);
94704
+ function assetUriToNodeId(uri) {
94705
+ const m3 = uri.match(/^([a-z0-9_]+):\/\/(.+)$/i);
94706
+ if (!m3)
94707
+ return;
94708
+ const prefix = m3[1].toLowerCase();
94709
+ const kind = prefix === "s3" ? "s3object" : prefix;
94710
+ return `${kind}:${m3[2]}`;
94711
+ }
94712
+ function addEdge(dag, a2, b2) {
94713
+ if (a2 === b2)
94714
+ return;
94715
+ dag.nodes.add(a2);
94716
+ dag.nodes.add(b2);
94717
+ (dag.down.get(a2) ?? dag.down.set(a2, new Set).get(a2)).add(b2);
94718
+ (dag.up.get(b2) ?? dag.up.set(b2, new Set).get(b2)).add(a2);
94719
+ }
94720
+ function buildLineageDag(g2) {
94721
+ const dag = { down: new Map, up: new Map, nodes: new Set };
94722
+ for (const r2 of g2.runnables ?? []) {
94723
+ if (r2.usage_kind === "script")
94724
+ dag.nodes.add(scriptNodeId(r2.path));
94725
+ }
94726
+ for (const a2 of g2.assets ?? [])
94727
+ dag.nodes.add(assetNodeId(a2.kind, a2.path));
94728
+ for (const e2 of g2.edges ?? []) {
94729
+ if (e2.runnable_kind !== "script")
94730
+ continue;
94731
+ const aid = assetNodeId(e2.asset_kind, e2.asset_path);
94732
+ const access2 = e2.access_type ?? "r";
94733
+ if (access2 === "w" || access2 === "rw") {
94734
+ addEdge(dag, scriptNodeId(e2.runnable_path), aid);
94735
+ } else if (access2 === "r") {
94736
+ addEdge(dag, aid, scriptNodeId(e2.runnable_path));
94737
+ }
94738
+ }
94739
+ for (const t2 of g2.triggers ?? []) {
94740
+ if (t2.trigger_kind !== "asset" || t2.runnable_kind !== "script")
94741
+ continue;
94742
+ const at = t2;
94743
+ addEdge(dag, assetNodeId(at.asset_kind, at.asset_path), scriptNodeId(at.runnable_path));
94744
+ }
94745
+ return dag;
94746
+ }
94747
+ function closure(adj, start) {
94748
+ const seen = new Set;
94749
+ const queue = [start];
94750
+ while (queue.length > 0) {
94751
+ const cur = queue.shift();
94752
+ for (const n2 of adj.get(cur) ?? []) {
94753
+ if (seen.has(n2))
94754
+ continue;
94755
+ seen.add(n2);
94756
+ queue.push(n2);
94757
+ }
94758
+ }
94759
+ seen.delete(start);
94760
+ return seen;
94761
+ }
94762
+ var descendants = (dag, n2) => closure(dag.down, n2);
94763
+ var ancestors = (dag, n2) => closure(dag.up, n2);
94764
+ function boundedSet(dag, start, ends) {
94765
+ const downSet = new Set(descendants(dag, start));
94766
+ downSet.add(start);
94767
+ const reachableEnds = ends.filter((e2) => downSet.has(e2));
94768
+ const droppedEnds = ends.filter((e2) => !downSet.has(e2));
94769
+ if (reachableEnds.length === 0) {
94770
+ return { nodes: new Set([start]), reachableEnds, droppedEnds };
94771
+ }
94772
+ const upClosure = new Set;
94773
+ for (const e2 of reachableEnds) {
94774
+ upClosure.add(e2);
94775
+ for (const a2 of ancestors(dag, e2))
94776
+ upClosure.add(a2);
94777
+ }
94778
+ const nodes = new Set;
94779
+ for (const n2 of downSet)
94780
+ if (upClosure.has(n2))
94781
+ nodes.add(n2);
94782
+ nodes.add(start);
94783
+ return { nodes, reachableEnds, droppedEnds };
94784
+ }
94785
+ function validStarts(g2) {
94786
+ const subscribers = new Set;
94787
+ const scheduleScripts = new Set;
94788
+ const eventScripts = new Set;
94789
+ for (const t2 of g2.triggers ?? []) {
94790
+ if (t2.runnable_kind !== "script")
94791
+ continue;
94792
+ if (t2.trigger_kind === "asset")
94793
+ subscribers.add(t2.runnable_path);
94794
+ else if (t2.trigger_kind === "schedule")
94795
+ scheduleScripts.add(t2.runnable_path);
94796
+ else if (EVENT_TRIGGER_KINDS.has(t2.trigger_kind))
94797
+ eventScripts.add(t2.runnable_path);
94798
+ }
94799
+ const out = new Set;
94800
+ for (const r2 of g2.runnables ?? []) {
94801
+ if (r2.usage_kind !== "script")
94802
+ continue;
94803
+ const p3 = r2.path;
94804
+ if (scheduleScripts.has(p3))
94805
+ out.add(scriptNodeId(p3));
94806
+ else if (!subscribers.has(p3) && !eventScripts.has(p3))
94807
+ out.add(scriptNodeId(p3));
94808
+ }
94809
+ return out;
94810
+ }
94811
+ function scriptsOf(nodes) {
94812
+ const out = [];
94813
+ for (const id of nodes)
94814
+ if (isScriptNode(id))
94815
+ out.push(scriptPathOf(id));
94816
+ return out;
94817
+ }
94818
+ function resolveToken(g2, token) {
94819
+ if (token.includes("://")) {
94820
+ const id = assetUriToNodeId(token);
94821
+ return id && g2.assets.some((a2) => `${a2.kind}:${a2.path}` === id) ? id : undefined;
94822
+ }
94823
+ const scripts = (g2.runnables ?? []).filter((r2) => r2.usage_kind === "script");
94824
+ const exact = scripts.find((r2) => r2.path === token);
94825
+ if (exact)
94826
+ return scriptNodeId(exact.path);
94827
+ const byShort = scripts.filter((r2) => (r2.path.split("/").pop() ?? r2.path) === token);
94828
+ return byShort.length === 1 ? scriptNodeId(byShort[0].path) : undefined;
94829
+ }
94830
+ function topoOrder(g2, scripts) {
94831
+ const dag = buildLineageDag(g2);
94832
+ const down = new Map;
94833
+ const indegree = new Map;
94834
+ for (const s2 of scripts)
94835
+ indegree.set(s2, 0);
94836
+ for (const s2 of scripts) {
94837
+ const sid = scriptNodeId(s2);
94838
+ const oneHop = new Set;
94839
+ for (const asset of dag.down.get(sid) ?? []) {
94840
+ for (const sub of dag.down.get(asset) ?? []) {
94841
+ if (isScriptNode(sub)) {
94842
+ const p3 = scriptPathOf(sub);
94843
+ if (p3 !== s2 && scripts.has(p3))
94844
+ oneHop.add(p3);
94845
+ }
94846
+ }
94847
+ }
94848
+ if (oneHop.size > 0) {
94849
+ down.set(s2, oneHop);
94850
+ for (const p3 of oneHop)
94851
+ indegree.set(p3, (indegree.get(p3) ?? 0) + 1);
94852
+ }
94853
+ }
94854
+ const ready = [...scripts].filter((s2) => (indegree.get(s2) ?? 0) === 0);
94855
+ const remaining = new Map(indegree);
94856
+ const order = [];
94857
+ while (ready.length > 0) {
94858
+ const n2 = ready.shift();
94859
+ order.push(n2);
94860
+ for (const p3 of down.get(n2) ?? []) {
94861
+ const d3 = (remaining.get(p3) ?? 0) - 1;
94862
+ remaining.set(p3, d3);
94863
+ if (d3 === 0)
94864
+ ready.push(p3);
94865
+ }
94866
+ }
94867
+ const orderedSet = new Set(order);
94868
+ const cyclic = [...scripts].filter((s2) => !orderedSet.has(s2));
94869
+ return { order, cyclic };
94870
+ }
94871
+
94872
+ // src/commands/pipeline/pipeline.ts
94675
94873
  async function apiGet(path23) {
94676
94874
  const response = await fetch(`${OpenAPI.BASE}${path23}`, {
94677
94875
  headers: { Authorization: `Bearer ${OpenAPI.TOKEN}` }
@@ -94830,7 +95028,132 @@ async function show2(opts, folder) {
94830
95028
  console.log(lines.join(`
94831
95029
  `));
94832
95030
  }
94833
- 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);
95031
+ async function waitJob(workspace, id) {
95032
+ const MAX_RETRIES = 6000;
95033
+ for (let i = 0;i < MAX_RETRIES; i++) {
95034
+ try {
95035
+ const r2 = await getCompletedJobResultMaybe({
95036
+ workspace,
95037
+ id,
95038
+ getStarted: false
95039
+ });
95040
+ if (r2.completed)
95041
+ return r2.success === true;
95042
+ } catch {}
95043
+ await new Promise((res) => setTimeout(res, 100));
95044
+ }
95045
+ throw new Error(`Timed out waiting for job ${id}`);
95046
+ }
95047
+ async function run5(opts, folder) {
95048
+ if (opts.json)
95049
+ setSilent(true);
95050
+ const workspace = await resolveWorkspace(opts);
95051
+ await requireLogin(opts);
95052
+ const f3 = folder.replace(/^f\//, "").replace(/\/$/, "");
95053
+ const graph = await apiGet(`/w/${workspace.workspaceId}/assets/graph?folder=${encodeURIComponent(f3)}&asset_kinds=${ASSET_KINDS}`);
95054
+ const starts = validStarts(graph);
95055
+ let start;
95056
+ if (opts.from) {
95057
+ const resolved = resolveToken(graph, opts.from);
95058
+ if (!resolved) {
95059
+ const matches = graph.runnables.filter((r2) => r2.usage_kind === "script" && (r2.path.split("/").pop() ?? r2.path) === opts.from);
95060
+ if (matches.length > 1) {
95061
+ throw new Error(`--from '${opts.from}' matches multiple scripts (${matches.map((r2) => r2.path).sort().join(", ")}) — pass the full path.`);
95062
+ }
95063
+ throw new Error(`--from '${opts.from}' matched no script in f/${f3}.`);
95064
+ }
95065
+ if (!starts.has(resolved)) {
95066
+ 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.`);
95067
+ }
95068
+ start = resolved;
95069
+ } else if (starts.size === 1) {
95070
+ start = [...starts][0];
95071
+ } else if (starts.size === 0) {
95072
+ throw new Error(`No schedule or manual root in f/${f3} to start a bounded run from.`);
95073
+ } else {
95074
+ throw new Error(`f/${f3} has ${starts.size} possible starts — pass --from <script>. Candidates: ${scriptsOf(starts).sort().join(", ")}`);
95075
+ }
95076
+ const toTokens = (opts.to ?? []).flatMap((t2) => t2.split(",")).map((t2) => t2.trim()).filter(Boolean);
95077
+ const ends = [];
95078
+ const unresolved = [];
95079
+ for (const tok of toTokens) {
95080
+ const id = resolveToken(graph, tok);
95081
+ if (!id)
95082
+ unresolved.push(tok);
95083
+ else
95084
+ ends.push(id);
95085
+ }
95086
+ if (unresolved.length > 0) {
95087
+ const details = unresolved.map((tok) => {
95088
+ const matches = graph.runnables.filter((r2) => r2.usage_kind === "script" && (r2.path.split("/").pop() ?? r2.path) === tok);
95089
+ return matches.length > 1 ? `'${tok}' (ambiguous: ${matches.map((r2) => r2.path).sort().join(", ")} — use the full path)` : `'${tok}' (no match in f/${f3})`;
95090
+ });
95091
+ throw new Error(`--to could not be resolved: ${details.join("; ")}.`);
95092
+ }
95093
+ const idLabel = (id) => id.startsWith("script:") ? scriptPathOf(id) : id;
95094
+ const dag = buildLineageDag(graph);
95095
+ let selectedScripts;
95096
+ let reachableEnds = [];
95097
+ let droppedEnds = [];
95098
+ if (ends.length === 0) {
95099
+ const all = new Set(descendants(dag, start));
95100
+ all.add(start);
95101
+ selectedScripts = new Set(scriptsOf(all));
95102
+ } else {
95103
+ const res = boundedSet(dag, start, ends);
95104
+ reachableEnds = res.reachableEnds;
95105
+ droppedEnds = res.droppedEnds;
95106
+ for (const d3 of droppedEnds) {
95107
+ warn(`end '${idLabel(d3)}' is not downstream of the start — ignored.`);
95108
+ }
95109
+ selectedScripts = new Set(scriptsOf(res.nodes));
95110
+ }
95111
+ const { order, cyclic } = topoOrder(graph, selectedScripts);
95112
+ if (cyclic.length > 0) {
95113
+ warn(`Skipping ${cyclic.length} script(s) on a dependency cycle: ${cyclic.sort().join(", ")}`);
95114
+ }
95115
+ if (opts.json) {
95116
+ console.log(JSON.stringify({
95117
+ start: scriptPathOf(start),
95118
+ ends: ends.map(idLabel),
95119
+ reachableEnds: reachableEnds.map(idLabel),
95120
+ droppedEnds: droppedEnds.map(idLabel),
95121
+ order,
95122
+ cyclic
95123
+ }));
95124
+ }
95125
+ if (order.length === 0) {
95126
+ if (!opts.json)
95127
+ info("Nothing to run.");
95128
+ return;
95129
+ }
95130
+ if (opts.dryRun) {
95131
+ if (!opts.json) {
95132
+ info(colors.bold(`Bounded run plan — ${order.length} script${order.length === 1 ? "" : "s"}`) + colors.dim(` (from ${shortName(scriptPathOf(start))})`));
95133
+ order.forEach((p3, i) => info(` ${i + 1}. ${p3}`));
95134
+ }
95135
+ return;
95136
+ }
95137
+ for (const path23 of order) {
95138
+ if (!opts.json)
95139
+ info(colors.gray(`▶ running ${path23}…`));
95140
+ const id = await runScriptByPath({
95141
+ workspace: workspace.workspaceId,
95142
+ path: path23,
95143
+ requestBody: { _wmill_skip_asset_dispatch: true }
95144
+ });
95145
+ const ok = await waitJob(workspace.workspaceId, id);
95146
+ if (!ok) {
95147
+ throw new Error(`Bounded run failed at ${path23} (job ${id}).`);
95148
+ }
95149
+ if (!opts.json)
95150
+ info(colors.green(` ✓ ${path23}`));
95151
+ }
95152
+ if (!opts.json) {
95153
+ info(colors.green.bold(`Bounded run complete — ${order.length} script(s) succeeded.`));
95154
+ }
95155
+ }
95156
+ 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);
94834
95157
  var pipeline_default = command41;
94835
95158
 
94836
95159
  // src/commands/ducklake/ducklake.ts
@@ -94857,11 +95180,11 @@ async function list19(opts) {
94857
95180
  new Table2().header(["Name"]).padding(2).border(true).body(names.map((name) => [name])).render();
94858
95181
  }
94859
95182
  }
94860
- async function run5(opts, sql) {
95183
+ async function run6(opts, sql) {
94861
95184
  const name = opts.name ?? DEFAULT_DUCKLAKE_NAME;
94862
95185
  await runCatalogQuery(opts, "ducklake", name, sql);
94863
95186
  }
94864
- 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);
95187
+ 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);
94865
95188
  var ducklake_default = command42;
94866
95189
 
94867
95190
  // 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.738.0",
3
+ "version": "1.740.0",
4
4
  "description": "CLI for Windmill",
5
5
  "license": "Apache 2.0",
6
6
  "type": "module",