windmill-cli 1.659.1 → 1.660.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/esm/main.js +371 -20
  2. package/package.json +1 -1
package/esm/main.js CHANGED
@@ -11785,7 +11785,7 @@ var init_OpenAPI = __esm(() => {
11785
11785
  PASSWORD: undefined,
11786
11786
  TOKEN: getEnv2("WM_TOKEN"),
11787
11787
  USERNAME: undefined,
11788
- VERSION: "1.659.1",
11788
+ VERSION: "1.660.1",
11789
11789
  WITH_CREDENTIALS: true,
11790
11790
  interceptors: {
11791
11791
  request: new Interceptors,
@@ -12203,6 +12203,7 @@ __export(exports_services_gen, {
12203
12203
  queryResourceTypes: () => queryResourceTypes,
12204
12204
  queryHubScripts: () => queryHubScripts,
12205
12205
  queryDocumentation: () => queryDocumentation,
12206
+ pruneVersions: () => pruneVersions,
12206
12207
  previewSchedule: () => previewSchedule,
12207
12208
  polarsConnectionSettingsV2: () => polarsConnectionSettingsV2,
12208
12209
  polarsConnectionSettings: () => polarsConnectionSettings,
@@ -12488,6 +12489,7 @@ __export(exports_services_gen, {
12488
12489
  getCompletedJobLogsTail: () => getCompletedJobLogsTail,
12489
12490
  getCompletedJob: () => getCompletedJob,
12490
12491
  getCompletedCount: () => getCompletedCount,
12492
+ getCloudQuotas: () => getCloudQuotas,
12491
12493
  getCaptureConfigs: () => getCaptureConfigs,
12492
12494
  getCapture: () => getCapture,
12493
12495
  getAuditLog: () => getAuditLog,
@@ -14253,6 +14255,24 @@ var backendVersion = () => {
14253
14255
  body: data2.requestBody,
14254
14256
  mediaType: "application/json"
14255
14257
  });
14258
+ }, getCloudQuotas = (data2) => {
14259
+ return request(OpenAPI, {
14260
+ method: "GET",
14261
+ url: "/w/{workspace}/workspaces/cloud_quotas",
14262
+ path: {
14263
+ workspace: data2.workspace
14264
+ }
14265
+ });
14266
+ }, pruneVersions = (data2) => {
14267
+ return request(OpenAPI, {
14268
+ method: "POST",
14269
+ url: "/w/{workspace}/workspaces/prune_versions",
14270
+ path: {
14271
+ workspace: data2.workspace
14272
+ },
14273
+ body: data2.requestBody,
14274
+ mediaType: "application/json"
14275
+ });
14256
14276
  }, setPublicAppRateLimit = (data2) => {
14257
14277
  return request(OpenAPI, {
14258
14278
  method: "POST",
@@ -60643,6 +60663,114 @@ async function replaceInlineScripts(modules, fileReader, logger = {
60643
60663
  }
60644
60664
  }));
60645
60665
  }
60666
+ async function replacePathScriptsWithLocal(modules, scriptReader, logger = {
60667
+ info: () => {},
60668
+ error: () => {}
60669
+ }) {
60670
+ await Promise.all(modules.map(async (module) => {
60671
+ if (!module.value) {
60672
+ return;
60673
+ }
60674
+ if (module.value.type === "script") {
60675
+ const scriptPath = module.value.path;
60676
+ const localScript = await scriptReader(scriptPath);
60677
+ if (localScript) {
60678
+ const pathScript = module.value;
60679
+ module.value = {
60680
+ type: "rawscript",
60681
+ content: localScript.content,
60682
+ language: localScript.language,
60683
+ lock: localScript.lock,
60684
+ path: scriptPath,
60685
+ input_transforms: pathScript.input_transforms,
60686
+ tag: pathScript.tag_override ?? localScript.tag
60687
+ };
60688
+ }
60689
+ } else if (module.value.type === "forloopflow" || module.value.type === "whileloopflow") {
60690
+ await replacePathScriptsWithLocal(module.value.modules, scriptReader, logger);
60691
+ } else if (module.value.type === "branchall") {
60692
+ await Promise.all(module.value.branches.map(async (branch) => {
60693
+ await replacePathScriptsWithLocal(branch.modules, scriptReader, logger);
60694
+ }));
60695
+ } else if (module.value.type === "branchone") {
60696
+ await Promise.all(module.value.branches.map(async (branch) => {
60697
+ await replacePathScriptsWithLocal(branch.modules, scriptReader, logger);
60698
+ }));
60699
+ await replacePathScriptsWithLocal(module.value.default, scriptReader, logger);
60700
+ } else if (module.value.type === "aiagent") {
60701
+ await Promise.all((module.value.tools ?? []).map(async (tool) => {
60702
+ const toolValue = tool.value;
60703
+ if (!toolValue || toolValue.tool_type !== "flowmodule" || toolValue.type !== "script") {
60704
+ return;
60705
+ }
60706
+ const localScript = await scriptReader(toolValue.path);
60707
+ if (localScript) {
60708
+ tool.value = {
60709
+ tool_type: "flowmodule",
60710
+ type: "rawscript",
60711
+ content: localScript.content,
60712
+ language: localScript.language,
60713
+ lock: localScript.lock,
60714
+ path: toolValue.path,
60715
+ input_transforms: toolValue.input_transforms,
60716
+ tag: toolValue.tag_override ?? localScript.tag
60717
+ };
60718
+ }
60719
+ }));
60720
+ }
60721
+ }));
60722
+ }
60723
+ function collectPathScriptPathsFromModules(modules, paths) {
60724
+ for (const module of modules) {
60725
+ if (!module.value) {
60726
+ continue;
60727
+ }
60728
+ if (module.value.type === "script") {
60729
+ paths.add(module.value.path);
60730
+ } else if (module.value.type === "forloopflow" || module.value.type === "whileloopflow") {
60731
+ collectPathScriptPathsFromModules(module.value.modules, paths);
60732
+ } else if (module.value.type === "branchall") {
60733
+ for (const branch of module.value.branches) {
60734
+ collectPathScriptPathsFromModules(branch.modules, paths);
60735
+ }
60736
+ } else if (module.value.type === "branchone") {
60737
+ for (const branch of module.value.branches) {
60738
+ collectPathScriptPathsFromModules(branch.modules, paths);
60739
+ }
60740
+ collectPathScriptPathsFromModules(module.value.default, paths);
60741
+ } else if (module.value.type === "aiagent") {
60742
+ for (const tool of module.value.tools ?? []) {
60743
+ const toolValue = tool.value;
60744
+ if (toolValue && toolValue.tool_type === "flowmodule" && toolValue.type === "script") {
60745
+ paths.add(toolValue.path);
60746
+ }
60747
+ }
60748
+ }
60749
+ }
60750
+ }
60751
+ async function replaceAllPathScriptsWithLocal(flowValue, scriptReader, logger = {
60752
+ info: () => {},
60753
+ error: () => {}
60754
+ }) {
60755
+ await replacePathScriptsWithLocal(flowValue.modules, scriptReader, logger);
60756
+ if (flowValue.failure_module) {
60757
+ await replacePathScriptsWithLocal([flowValue.failure_module], scriptReader, logger);
60758
+ }
60759
+ if (flowValue.preprocessor_module) {
60760
+ await replacePathScriptsWithLocal([flowValue.preprocessor_module], scriptReader, logger);
60761
+ }
60762
+ }
60763
+ function collectPathScriptPaths(flowValue) {
60764
+ const paths = new Set;
60765
+ collectPathScriptPathsFromModules(flowValue.modules, paths);
60766
+ if (flowValue.failure_module) {
60767
+ collectPathScriptPathsFromModules([flowValue.failure_module], paths);
60768
+ }
60769
+ if (flowValue.preprocessor_module) {
60770
+ collectPathScriptPathsFromModules([flowValue.preprocessor_module], paths);
60771
+ }
60772
+ return [...paths];
60773
+ }
60646
60774
 
60647
60775
  // src/commands/flow/flow_metadata.ts
60648
60776
  import * as path7 from "node:path";
@@ -63230,6 +63358,7 @@ __export(exports_metadata, {
63230
63358
  updateMetadataGlobalLock: () => updateMetadataGlobalLock,
63231
63359
  replaceLock: () => replaceLock,
63232
63360
  readLockfile: () => readLockfile,
63361
+ parseMetadataFileIfExists: () => parseMetadataFileIfExists,
63233
63362
  parseMetadataFile: () => parseMetadataFile,
63234
63363
  normalizeLockPath: () => normalizeLockPath,
63235
63364
  inferSchema: () => inferSchema,
@@ -63804,6 +63933,33 @@ function replaceLock(o) {
63804
63933
  }
63805
63934
  }
63806
63935
  }
63936
+ async function parseMetadataFileIfExists(scriptPath) {
63937
+ let metadataFilePath = scriptPath + ".script.json";
63938
+ try {
63939
+ await stat7(metadataFilePath);
63940
+ const payload = JSON.parse(await readFile9(metadataFilePath, "utf-8"));
63941
+ replaceLock(payload);
63942
+ return {
63943
+ path: metadataFilePath,
63944
+ payload,
63945
+ isJson: true
63946
+ };
63947
+ } catch {
63948
+ try {
63949
+ metadataFilePath = scriptPath + ".script.yaml";
63950
+ await stat7(metadataFilePath);
63951
+ const payload = await yamlParseFile(metadataFilePath);
63952
+ replaceLock(payload);
63953
+ return {
63954
+ path: metadataFilePath,
63955
+ payload,
63956
+ isJson: false
63957
+ };
63958
+ } catch {
63959
+ return;
63960
+ }
63961
+ }
63962
+ }
63807
63963
  async function parseMetadataFile(scriptPath, generateMetadataIfMissing) {
63808
63964
  let metadataFilePath = scriptPath + ".script.json";
63809
63965
  try {
@@ -69789,10 +69945,167 @@ function defaultFlowDefinition() {
69789
69945
  };
69790
69946
  }
69791
69947
 
69948
+ // src/utils/local_path_scripts.ts
69949
+ import { execFileSync as execFileSync2 } from "node:child_process";
69950
+ import { readFile as readFile14, stat as stat15 } from "node:fs/promises";
69951
+ async function readOptionalLock(scriptPath) {
69952
+ try {
69953
+ return await readFile14(scriptPath + ".script.lock", "utf-8");
69954
+ } catch {
69955
+ return;
69956
+ }
69957
+ }
69958
+ function normalizeOptionalLock(lock) {
69959
+ return typeof lock === "string" && lock.trim() === "" ? undefined : lock;
69960
+ }
69961
+ async function bundleSingleFileCodebaseScript(filePath, codebase) {
69962
+ if (codebase.customBundler) {
69963
+ return execFileSync2("sh", ["-lc", `${codebase.customBundler} "$1"`, "sh", filePath], {
69964
+ maxBuffer: 1024 * 1024 * 50
69965
+ }).toString();
69966
+ }
69967
+ const esbuild = await import("esbuild");
69968
+ const out = await esbuild.build({
69969
+ entryPoints: [filePath],
69970
+ format: "esm",
69971
+ bundle: true,
69972
+ write: false,
69973
+ external: codebase.external,
69974
+ inject: codebase.inject,
69975
+ define: codebase.define,
69976
+ loader: codebase.loader ?? { ".node": "file" },
69977
+ outdir: "/",
69978
+ platform: "node",
69979
+ packages: "bundle",
69980
+ target: "esnext",
69981
+ banner: codebase.banner
69982
+ });
69983
+ if (out.outputFiles.length === 0) {
69984
+ throw new Error(`No output files found for ${filePath}`);
69985
+ }
69986
+ if (out.outputFiles.length > 1) {
69987
+ throw new UnsupportedLocalPathScriptPreviewError(`Local PathScript ${filePath} requires a multi-file bundle, which flow preview/dev cannot inline yet`);
69988
+ }
69989
+ if (Array.isArray(codebase.assets) && codebase.assets.length > 0) {
69990
+ throw new UnsupportedLocalPathScriptPreviewError(`Local PathScript ${filePath} requires codebase assets, which flow preview/dev cannot inline yet`);
69991
+ }
69992
+ return out.outputFiles[0].text;
69993
+ }
69994
+ function createPreviewLocalScriptReader(opts) {
69995
+ return async (scriptPath) => {
69996
+ const localScript = await resolvePreviewLocalScriptState(scriptPath, opts);
69997
+ if (!localScript) {
69998
+ return;
69999
+ }
70000
+ const content = localScript.codebase ? await bundleSingleFileCodebaseScript(localScript.filePath, localScript.codebase) : localScript.content;
70001
+ return {
70002
+ content,
70003
+ language: localScript.language,
70004
+ lock: localScript.lock,
70005
+ tag: localScript.tag
70006
+ };
70007
+ };
70008
+ }
70009
+ async function resolvePreviewLocalScriptState(scriptPath, opts) {
70010
+ for (const ext2 of opts.exts) {
70011
+ const filePath = scriptPath + ext2;
70012
+ let fileStat;
70013
+ try {
70014
+ fileStat = await stat15(filePath);
70015
+ } catch {
70016
+ continue;
70017
+ }
70018
+ if (!fileStat.isFile())
70019
+ continue;
70020
+ const language = inferContentTypeFromFilePath(filePath, opts.defaultTs);
70021
+ const metadata = await parseMetadataFileIfExists(scriptPath);
70022
+ const rawLock = metadata?.payload?.lock ?? await readOptionalLock(scriptPath);
70023
+ const codebase = language === "bun" ? findCodebase(filePath, opts.codebases) : undefined;
70024
+ return {
70025
+ filePath,
70026
+ content: await readFile14(filePath, "utf-8"),
70027
+ language,
70028
+ lock: normalizeOptionalLock(rawLock),
70029
+ tag: metadata?.payload?.tag,
70030
+ codebase,
70031
+ codebaseDigest: codebase ? await codebase.getDigest(Array.isArray(codebase.assets) && codebase.assets.length > 0) : undefined
70032
+ };
70033
+ }
70034
+ return;
70035
+ }
70036
+ var UnsupportedLocalPathScriptPreviewError;
70037
+ var init_local_path_scripts = __esm(async () => {
70038
+ init_script_common();
70039
+ await __promiseAll([
70040
+ init_metadata(),
70041
+ init_sync()
70042
+ ]);
70043
+ UnsupportedLocalPathScriptPreviewError = class UnsupportedLocalPathScriptPreviewError extends Error {
70044
+ constructor(message) {
70045
+ super(message);
70046
+ this.name = "UnsupportedLocalPathScriptPreviewError";
70047
+ }
70048
+ };
70049
+ });
70050
+
69792
70051
  // src/commands/flow/flow.ts
69793
70052
  import { sep as SEP19 } from "node:path";
69794
- import { readFile as readFile14 } from "node:fs/promises";
70053
+ import { readFile as readFile15 } from "node:fs/promises";
69795
70054
  import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "node:fs";
70055
+ function normalizeOptionalString(value) {
70056
+ return typeof value === "string" && value.trim() === "" ? undefined : value ?? undefined;
70057
+ }
70058
+ function normalizeComparableContent(value) {
70059
+ return value?.replaceAll(`\r
70060
+ `, `
70061
+ `).replace(/\n$/, "");
70062
+ }
70063
+ async function findDivergedLocalPathScripts(workspaceId, scriptPaths, opts) {
70064
+ const changed = [];
70065
+ const missing = [];
70066
+ for (const scriptPath of scriptPaths) {
70067
+ const localScript = await resolvePreviewLocalScriptState(scriptPath, opts);
70068
+ if (!localScript) {
70069
+ continue;
70070
+ }
70071
+ let remoteScript;
70072
+ try {
70073
+ remoteScript = await getScriptByPath({
70074
+ workspace: workspaceId,
70075
+ path: scriptPath
70076
+ });
70077
+ } catch {
70078
+ missing.push(scriptPath);
70079
+ continue;
70080
+ }
70081
+ const remoteLock = normalizeOptionalString(remoteScript.lock);
70082
+ const diverged = normalizeComparableContent(localScript.content) !== normalizeComparableContent(remoteScript.content) || localScript.language !== remoteScript.language || localScript.lock !== undefined && normalizeComparableContent(localScript.lock) !== normalizeComparableContent(remoteLock) || localScript.tag !== normalizeOptionalString(remoteScript.tag) || localScript.codebaseDigest !== normalizeOptionalString(remoteScript.codebase);
70083
+ if (diverged) {
70084
+ changed.push(scriptPath);
70085
+ }
70086
+ }
70087
+ return { changed, missing };
70088
+ }
70089
+ function warnAboutLocalPathScriptDivergence(divergence) {
70090
+ if (divergence.changed.length === 0 && divergence.missing.length === 0) {
70091
+ return;
70092
+ }
70093
+ const details = [];
70094
+ if (divergence.changed.length > 0) {
70095
+ details.push(`These workspace scripts differ from the deployed version:
70096
+ ${divergence.changed.map((path19) => `- ${path19}`).join(`
70097
+ `)}`);
70098
+ }
70099
+ if (divergence.missing.length > 0) {
70100
+ details.push(`These scripts do not exist in the workspace yet:
70101
+ ${divergence.missing.map((path19) => `- ${path19}`).join(`
70102
+ `)}`);
70103
+ }
70104
+ warn(`Using local PathScript files for flow preview.
70105
+ ${details.join(`
70106
+ `)}
70107
+ Use --remote to preview deployed workspace scripts instead.`);
70108
+ }
69796
70109
  async function pushFlow(workspace, remotePath, localPath, message) {
69797
70110
  if (alreadySynced3.includes(localPath)) {
69798
70111
  return;
@@ -69810,7 +70123,7 @@ async function pushFlow(workspace, remotePath, localPath, message) {
69810
70123
  localPath += SEP19;
69811
70124
  }
69812
70125
  const localFlow = await yamlParseFile(localPath + "flow.yaml");
69813
- const fileReader = async (path19) => await readFile14(localPath + path19, "utf-8");
70126
+ const fileReader = async (path19) => await readFile15(localPath + path19, "utf-8");
69814
70127
  await replaceInlineScripts(localFlow.value.modules, fileReader, exports_log, localPath, SEP19);
69815
70128
  if (localFlow.value.failure_module) {
69816
70129
  await replaceInlineScripts([localFlow.value.failure_module], fileReader, exports_log, localPath, SEP19);
@@ -69946,8 +70259,13 @@ async function run3(opts, path19) {
69946
70259
  info(JSON.stringify(jobInfo.result ?? {}, null, 2));
69947
70260
  }
69948
70261
  async function preview2(opts, flowPath) {
70262
+ const useLocalPathScripts = !opts.remote;
70263
+ if (useLocalPathScripts) {
70264
+ opts = await mergeConfigWithConfigFile(opts);
70265
+ }
69949
70266
  const workspace = await resolveWorkspace(opts);
69950
70267
  await requireLogin(opts);
70268
+ const codebases = useLocalPathScripts ? listSyncCodebases(opts) : [];
69951
70269
  if (!flowPath.endsWith(".flow") && !flowPath.endsWith(".flow" + SEP19)) {
69952
70270
  if (flowPath.endsWith("flow.yaml") || flowPath.endsWith("flow.json")) {
69953
70271
  flowPath = flowPath.substring(0, flowPath.lastIndexOf(SEP19));
@@ -69959,7 +70277,7 @@ async function preview2(opts, flowPath) {
69959
70277
  flowPath += SEP19;
69960
70278
  }
69961
70279
  const localFlow = await yamlParseFile(flowPath + "flow.yaml");
69962
- const fileReader = async (path19) => await readFile14(flowPath + path19, "utf-8");
70280
+ const fileReader = async (path19) => await readFile15(flowPath + path19, "utf-8");
69963
70281
  await replaceInlineScripts(localFlow.value.modules, fileReader, exports_log, flowPath, SEP19);
69964
70282
  if (localFlow.value.failure_module) {
69965
70283
  await replaceInlineScripts([localFlow.value.failure_module], fileReader, exports_log, flowPath, SEP19);
@@ -69967,6 +70285,25 @@ async function preview2(opts, flowPath) {
69967
70285
  if (localFlow.value.preprocessor_module) {
69968
70286
  await replaceInlineScripts([localFlow.value.preprocessor_module], fileReader, exports_log, flowPath, SEP19);
69969
70287
  }
70288
+ if (useLocalPathScripts) {
70289
+ const scriptPaths = collectPathScriptPaths(localFlow.value);
70290
+ if (scriptPaths.length > 0) {
70291
+ const divergence = await findDivergedLocalPathScripts(workspace.workspaceId, scriptPaths, {
70292
+ exts,
70293
+ defaultTs: opts.defaultTs,
70294
+ codebases
70295
+ });
70296
+ if (!opts.silent) {
70297
+ warnAboutLocalPathScriptDivergence(divergence);
70298
+ }
70299
+ }
70300
+ const localScriptReader = createPreviewLocalScriptReader({
70301
+ exts,
70302
+ defaultTs: opts.defaultTs,
70303
+ codebases
70304
+ });
70305
+ await replaceAllPathScriptsWithLocal(localFlow.value, localScriptReader, exports_log);
70306
+ }
69970
70307
  const input = opts.data ? await resolve6(opts.data) : {};
69971
70308
  if (!opts.silent) {
69972
70309
  info(colors.yellow(`Running flow preview for ${flowPath}...`));
@@ -70064,11 +70401,14 @@ var init_flow = __esm(async () => {
70064
70401
  init_script(),
70065
70402
  init_conf(),
70066
70403
  init_sync(),
70067
- init_flow_metadata()
70404
+ init_flow_metadata(),
70405
+ init_script(),
70406
+ init_codebase(),
70407
+ init_local_path_scripts()
70068
70408
  ]);
70069
70409
  import_yaml36 = __toESM(require_dist(), 1);
70070
70410
  alreadySynced3 = [];
70071
- command21 = new Command().description("flow related commands").option("--show-archived", "Enable archived flows in output").option("--json", "Output as JSON (for piping to jq)").action(list11).command("list", "list all flows").option("--show-archived", "Enable archived flows in output").option("--json", "Output as JSON (for piping to jq)").action(list11).command("get", "get a flow's details").arguments("<path:string>").option("--json", "Output as JSON (for piping to jq)").action(get9).command("push", "push a local flow spec. This overrides any remote versions.").arguments("<file_path:string> <remote_path:string>").action(push11).command("run", "run a flow by path.").arguments("<path:string>").option("-d --data <data:string>", "Inputs specified as a JSON string or a file using @<filename> or stdin using @-.").option("-s --silent", "Do not ouput anything other then the final output. Useful for scripting.").action(run3).command("preview", "preview a local flow without deploying it. Runs the flow definition from local files.").arguments("<flow_path:string>").option("-d --data <data:string>", "Inputs specified as a JSON string or a file using @<filename> or stdin using @-.").option("-s --silent", "Do not output anything other then the final output. Useful for scripting.").action(preview2).command("generate-locks", "re-generate the lock files of all inline scripts of all updated flows").arguments("[flow:file]").option("--yes", "Skip confirmation prompt").option("-i --includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string)").option("-e --excludes <patterns:file[]>", "Comma separated patterns to specify which file to NOT take into account.").action(generateLocks).command("new", "create a new empty flow").arguments("<flow_path:string>").option("--summary <summary:string>", "flow summary").option("--description <description:string>", "flow description").action(bootstrap2).command("bootstrap", "create a new empty flow (alias for new)").arguments("<flow_path:string>").option("--summary <summary:string>", "flow summary").option("--description <description:string>", "flow description").action(bootstrap2);
70411
+ command21 = new Command().description("flow related commands").option("--show-archived", "Enable archived flows in output").option("--json", "Output as JSON (for piping to jq)").action(list11).command("list", "list all flows").option("--show-archived", "Enable archived flows in output").option("--json", "Output as JSON (for piping to jq)").action(list11).command("get", "get a flow's details").arguments("<path:string>").option("--json", "Output as JSON (for piping to jq)").action(get9).command("push", "push a local flow spec. This overrides any remote versions.").arguments("<file_path:string> <remote_path:string>").action(push11).command("run", "run a flow by path.").arguments("<path:string>").option("-d --data <data:string>", "Inputs specified as a JSON string or a file using @<filename> or stdin using @-.").option("-s --silent", "Do not ouput anything other then the final output. Useful for scripting.").action(run3).command("preview", "preview a local flow without deploying it. Runs the flow definition from local files and uses local PathScripts by default.").arguments("<flow_path:string>").option("-d --data <data:string>", "Inputs specified as a JSON string or a file using @<filename> or stdin using @-.").option("-s --silent", "Do not output anything other then the final output. Useful for scripting.").option("--remote", "Use deployed workspace scripts for PathScript steps instead of local files.").action(preview2).command("generate-locks", "re-generate the lock files of all inline scripts of all updated flows").arguments("[flow:file]").option("--yes", "Skip confirmation prompt").option("-i --includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string)").option("-e --excludes <patterns:file[]>", "Comma separated patterns to specify which file to NOT take into account.").action(generateLocks).command("new", "create a new empty flow").arguments("<flow_path:string>").option("--summary <summary:string>", "flow summary").option("--description <description:string>", "flow description").action(bootstrap2).command("bootstrap", "create a new empty flow (alias for new)").arguments("<flow_path:string>").option("--summary <summary:string>", "flow summary").option("--description <description:string>", "flow description").action(bootstrap2);
70072
70412
  flow_default = command21;
70073
70413
  });
70074
70414
 
@@ -72324,23 +72664,25 @@ await __promiseAll([
72324
72664
  init_context(),
72325
72665
  init_conf(),
72326
72666
  init_script(),
72327
- init_metadata()
72667
+ init_metadata(),
72668
+ init_codebase(),
72669
+ init_local_path_scripts()
72328
72670
  ]);
72329
72671
  import { sep as SEP20 } from "node:path";
72330
72672
  import * as http3 from "node:http";
72331
- import { readFile as readFile15, realpath } from "node:fs/promises";
72673
+ import { readFile as readFile16, realpath } from "node:fs/promises";
72332
72674
  import { watch as watch2 } from "node:fs";
72333
72675
  var PORT = 3001;
72334
72676
  async function dev2(opts) {
72677
+ opts = await mergeConfigWithConfigFile(opts);
72335
72678
  const workspace = await resolveWorkspace(opts);
72336
72679
  await requireLogin(opts);
72337
72680
  info("Started dev mode");
72338
- const conf = await readConfigFile();
72339
72681
  let currentLastEdit = undefined;
72340
72682
  const fsWatcher = watch2(".", { recursive: true });
72341
72683
  const base = await realpath(".");
72342
- opts = await mergeConfigWithConfigFile(opts);
72343
72684
  const ignore = await ignoreF(opts);
72685
+ const codebases = await listSyncCodebases(opts);
72344
72686
  const changesTimeouts = {};
72345
72687
  function watchChanges() {
72346
72688
  return new Promise((_resolve, _reject) => {
@@ -72354,7 +72696,9 @@ async function dev2(opts) {
72354
72696
  }
72355
72697
  changesTimeouts[key] = setTimeout(async () => {
72356
72698
  delete changesTimeouts[key];
72357
- await loadPaths([filePath]);
72699
+ await loadPaths([filePath]).catch((error2) => {
72700
+ error(`Failed to reload ${filePath}: ${error2 instanceof Error ? error2.message : error2}`);
72701
+ });
72358
72702
  }, 100);
72359
72703
  });
72360
72704
  fsWatcher.on("error", (err) => {
@@ -72377,7 +72721,13 @@ async function dev2(opts) {
72377
72721
  if (typ == "flow") {
72378
72722
  const localPath = extractFolderPath(cpath, "flow");
72379
72723
  const localFlow = await yamlParseFile(localPath + "flow.yaml");
72380
- await replaceInlineScripts(localFlow.value.modules, async (path19) => await readFile15(localPath + path19, "utf-8"), exports_log, localPath, SEP20, undefined);
72724
+ await replaceInlineScripts(localFlow.value.modules, async (path19) => await readFile16(localPath + path19, "utf-8"), exports_log, localPath, SEP20, undefined);
72725
+ const localScriptReader = createPreviewLocalScriptReader({
72726
+ exts,
72727
+ defaultTs: opts.defaultTs,
72728
+ codebases
72729
+ });
72730
+ await replaceAllPathScriptsWithLocal(localFlow.value, localScriptReader, exports_log);
72381
72731
  currentLastEdit = {
72382
72732
  type: "flow",
72383
72733
  flow: localFlow,
@@ -72386,10 +72736,10 @@ async function dev2(opts) {
72386
72736
  info("Updated " + localPath);
72387
72737
  broadcastChanges(currentLastEdit);
72388
72738
  } else if (typ == "script") {
72389
- const content = await readFile15(cpath, "utf-8");
72739
+ const content = await readFile16(cpath, "utf-8");
72390
72740
  const splitted = cpath.split(".");
72391
72741
  const wmPath = splitted[0];
72392
- const lang = inferContentTypeFromFilePath(cpath, conf.defaultTs);
72742
+ const lang = inferContentTypeFromFilePath(cpath, opts.defaultTs);
72393
72743
  const typed = (await parseMetadataFile(removeExtensionToPath(cpath), undefined))?.payload;
72394
72744
  currentLastEdit = {
72395
72745
  type: "script",
@@ -72701,7 +73051,7 @@ await __promiseAll([
72701
73051
  init_resource_type()
72702
73052
  ]);
72703
73053
  var import_yaml40 = __toESM(require_dist(), 1);
72704
- import { stat as stat15, writeFile as writeFile19, rm as rm4, mkdir as mkdir8 } from "node:fs/promises";
73054
+ import { stat as stat16, writeFile as writeFile19, rm as rm4, mkdir as mkdir8 } from "node:fs/promises";
72705
73055
 
72706
73056
  // src/guidance/skills.ts
72707
73057
  var SKILLS = [
@@ -77735,9 +78085,10 @@ flow related commands
77735
78085
  - \`flow run <path:string>\` - run a flow by path.
77736
78086
  - \`-d --data <data:string>\` - Inputs specified as a JSON string or a file using @<filename> or stdin using @-.
77737
78087
  - \`-s --silent\` - Do not ouput anything other then the final output. Useful for scripting.
77738
- - \`flow preview <flow_path:string>\` - preview a local flow without deploying it. Runs the flow definition from local files.
78088
+ - \`flow preview <flow_path:string>\` - preview a local flow without deploying it. Runs the flow definition from local files and uses local PathScripts by default.
77739
78089
  - \`-d --data <data:string>\` - Inputs specified as a JSON string or a file using @<filename> or stdin using @-.
77740
78090
  - \`-s --silent\` - Do not output anything other then the final output. Useful for scripting.
78091
+ - \`--remote\` - Use deployed workspace scripts for PathScript steps instead of local files.
77741
78092
  - \`flow generate-locks [flow:file]\` - re-generate the lock files of all inline scripts of all updated flows
77742
78093
  - \`--yes\` - Skip confirmation prompt
77743
78094
  - \`-i --includes <patterns:file[]>\` - Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string)
@@ -79057,7 +79408,7 @@ ${schemaYaml.trim()}
79057
79408
  \`\`\``;
79058
79409
  }
79059
79410
  async function initAction(opts) {
79060
- if (await stat15("wmill.yaml").catch(() => null)) {
79411
+ if (await stat16("wmill.yaml").catch(() => null)) {
79061
79412
  error(colors.red("wmill.yaml already exists"));
79062
79413
  } else {
79063
79414
  const { DEFAULT_SYNC_OPTIONS: DEFAULT_SYNC_OPTIONS2 } = await init_conf().then(() => exports_conf);
@@ -79193,11 +79544,11 @@ Current Git branch: ${colors.bold(currentBranch)}`));
79193
79544
  const skills_base_dir = ".claude/skills";
79194
79545
  const skillsReference = SKILLS.map((s) => `- \`${skills_base_dir}/${s.name}/SKILL.md\` - ${s.description}`).join(`
79195
79546
  `);
79196
- if (!await stat15("AGENTS.md").catch(() => null)) {
79547
+ if (!await stat16("AGENTS.md").catch(() => null)) {
79197
79548
  await writeFile19("AGENTS.md", generateAgentsMdContent(skillsReference), "utf-8");
79198
79549
  info(colors.green("Created AGENTS.md"));
79199
79550
  }
79200
- if (!await stat15("CLAUDE.md").catch(() => null)) {
79551
+ if (!await stat16("CLAUDE.md").catch(() => null)) {
79201
79552
  await writeFile19("CLAUDE.md", `Instructions are in @AGENTS.md
79202
79553
  `, "utf-8");
79203
79554
  info(colors.green("Created CLAUDE.md"));
@@ -79663,7 +80014,7 @@ var docs_default = command30;
79663
80014
 
79664
80015
  // src/main.ts
79665
80016
  await init_context();
79666
- var VERSION = "1.659.1";
80017
+ var VERSION = "1.660.1";
79667
80018
  var command31 = new Command().name("wmill").action(() => info(`Welcome to Windmill CLI ${VERSION}. Use -h for help.`)).description("Windmill CLI").globalOption("--workspace <workspace:string>", "Specify the target workspace. This overrides the default workspace.").globalOption("--debug --verbose", "Show debug/verbose logs").globalOption("--show-diffs", "Show diff informations when syncing (may show sensitive informations)").globalOption("--token <token:string>", "Specify an API token. This will override any stored token.").globalOption("--base-url <baseUrl:string>", "Specify the base URL of the API. If used, --token and --workspace are required and no local remote/workspace already set will be used.").globalOption("--config-dir <configDir:string>", "Specify a custom config directory. Overrides WMILL_CONFIG_DIR environment variable and default ~/.config location.").env("HEADERS <headers:string>", `Specify headers to use for all requests. e.g: "HEADERS='h1: v1, h2: v2'"`).version(VERSION).versionOption(false).command("init", init_default).command("app", app_default).command("flow", flow_default).command("script", script_default).command("workspace", workspace_default).command("resource", resource_default).command("resource-type", resource_type_default).command("user", user_default).command("variable", variable_default).command("hub", hub_default).command("folder", folder_default).command("schedule", schedule_default).command("trigger", trigger_default).command("dev", dev_default2).command("sync", sync_default).command("lint", lint_default).command("gitsync-settings", gitsync_settings_default).command("instance", instance_default).command("worker-groups", worker_groups_default).command("workers", workers_default).command("queues", queues_default).command("dependencies", dependencies_default).command("jobs", jobs_default).command("generate-metadata", generate_metadata_default).command("docs", docs_default).command("version --version", "Show version information").action(async (opts) => {
79668
80019
  console.log("CLI version: " + VERSION);
79669
80020
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windmill-cli",
3
- "version": "1.659.1",
3
+ "version": "1.660.1",
4
4
  "description": "CLI for Windmill",
5
5
  "license": "Apache 2.0",
6
6
  "type": "module",