windmill-cli 1.737.0 → 1.738.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 +84 -43
  2. package/package.json +1 -1
package/esm/main.js CHANGED
@@ -4242,9 +4242,11 @@ var init_bun_runtime = __esm(() => {
4242
4242
  // src/core/log.ts
4243
4243
  var exports_log = {};
4244
4244
  __export(exports_log, {
4245
+ warnStderr: () => warnStderr,
4245
4246
  warn: () => warn,
4246
4247
  setup: () => setup,
4247
4248
  setSilent: () => setSilent,
4249
+ infoStderr: () => infoStderr,
4248
4250
  info: () => info,
4249
4251
  error: () => error,
4250
4252
  debug: () => debug
@@ -4264,11 +4266,21 @@ function info(msg) {
4264
4266
  return;
4265
4267
  console.log(`\x1B[34m${String(msg)}\x1B[39m`);
4266
4268
  }
4269
+ function infoStderr(msg) {
4270
+ if (silentMode)
4271
+ return;
4272
+ console.error(`\x1B[34m${String(msg)}\x1B[39m`);
4273
+ }
4267
4274
  function warn(msg) {
4268
4275
  if (silentMode)
4269
4276
  return;
4270
4277
  console.log(`\x1B[33m${String(msg)}\x1B[39m`);
4271
4278
  }
4279
+ function warnStderr(msg) {
4280
+ if (silentMode)
4281
+ return;
4282
+ console.error(`\x1B[33m${String(msg)}\x1B[39m`);
4283
+ }
4272
4284
  function error(msg) {
4273
4285
  console.error(`\x1B[31m${String(msg)}\x1B[39m`);
4274
4286
  }
@@ -16388,7 +16400,7 @@ import * as http from "node:http";
16388
16400
  async function loginInteractive(remote) {
16389
16401
  let token;
16390
16402
  if (!process.stdin.isTTY) {
16391
- info("Not a TTY, can't login interactively.");
16403
+ infoStderr("Not a TTY, can't login interactively.");
16392
16404
  return;
16393
16405
  }
16394
16406
  if (await Select.prompt({
@@ -16420,7 +16432,7 @@ async function browserLogin(baseUrl) {
16420
16432
  const env = process.env["TOKEN_PORT"] != null ? parseInt(process.env["TOKEN_PORT"]) : undefined;
16421
16433
  const port = await getPorts({ port: env });
16422
16434
  if (port == undefined) {
16423
- info(colors.red.underline("failed to aquire port"));
16435
+ infoStderr(colors.red.underline("failed to aquire port"));
16424
16436
  return;
16425
16437
  }
16426
16438
  return new Promise((resolve4) => {
@@ -16435,12 +16447,12 @@ async function browserLogin(baseUrl) {
16435
16447
  resolve4(token ?? undefined);
16436
16448
  });
16437
16449
  const url = `${baseUrl}user/cli?port=${port}`;
16438
- info(`Login by going to ${url}`);
16450
+ infoStderr(`Login by going to ${url}`);
16439
16451
  try {
16440
16452
  open_default(url).catch((error2) => {
16441
16453
  console.error(`Failed to open browser, please navigate to ${url}, error: ${error2}`);
16442
16454
  });
16443
- info("Opened browser for you");
16455
+ infoStderr("Opened browser for you");
16444
16456
  } catch (error2) {
16445
16457
  console.error(`Failed to open browser, please navigate to ${url}, error: ${error2}`);
16446
16458
  }
@@ -16772,7 +16784,7 @@ var init_OpenAPI = __esm(() => {
16772
16784
  PASSWORD: undefined,
16773
16785
  TOKEN: getEnv3("WM_TOKEN"),
16774
16786
  USERNAME: undefined,
16775
- VERSION: "1.737.0",
16787
+ VERSION: "1.738.0",
16776
16788
  WITH_CREDENTIALS: true,
16777
16789
  interceptors: {
16778
16790
  request: new Interceptors,
@@ -25454,20 +25466,20 @@ async function requireLogin(opts) {
25454
25466
  bodyStr = bodyStr.replace(/\s*[@(]\w+\.rs:\d+[:\d]*\)?/g, "");
25455
25467
  bodyStr = bodyStr.replace(/^(Permission denied|Not authorized): /, "");
25456
25468
  if (status === 403) {
25457
- info(colors.red(`Permission denied: the token is valid but lacks the required scope.${bodyStr ? `
25469
+ infoStderr(colors.red(`Permission denied: the token is valid but lacks the required scope.${bodyStr ? `
25458
25470
  ${bodyStr}` : ""}`));
25459
25471
  } else if (status === 401) {
25460
- info(colors.red(`Could not authenticate with the provided credentials. Please check your --token and --base-url and try again.${bodyStr ? `
25472
+ infoStderr(colors.red(`Could not authenticate with the provided credentials. Please check your --token and --base-url and try again.${bodyStr ? `
25461
25473
  ${bodyStr}` : ""}`));
25462
25474
  } else {
25463
- info(colors.red(`Request failed (${status ?? "unknown"}): ${bodyStr}`));
25475
+ infoStderr(colors.red(`Request failed (${status ?? "unknown"}): ${bodyStr}`));
25464
25476
  }
25465
25477
  return process.exit(1);
25466
25478
  }
25467
- info(colors.red("Could not authenticate with the provided credentials. Please check your --token and --base-url and try again."));
25479
+ infoStderr(colors.red("Could not authenticate with the provided credentials. Please check your --token and --base-url and try again."));
25468
25480
  return process.exit(1);
25469
25481
  }
25470
- info("! Could not reach API given existing credentials. Attempting to reauth...");
25482
+ infoStderr("! Could not reach API given existing credentials. Attempting to reauth...");
25471
25483
  const newToken = await loginInteractive(workspace.remote);
25472
25484
  if (!newToken) {
25473
25485
  throw new Error("Unauthorized: Could not authenticate with the provided credentials");
@@ -25489,7 +25501,7 @@ var init_auth = __esm(async () => {
25489
25501
  });
25490
25502
 
25491
25503
  // src/core/constants.ts
25492
- var WM_FORK_PREFIX = "wm-fork", VERSION = "1.737.0";
25504
+ var WM_FORK_PREFIX = "wm-fork", VERSION = "1.738.0";
25493
25505
 
25494
25506
  // src/utils/git.ts
25495
25507
  var exports_git = {};
@@ -28594,17 +28606,17 @@ async function selectFromMultipleProfiles(profiles, baseUrl2, workspaceId, conte
28594
28606
  if (lastUsedProfileName) {
28595
28607
  const lastUsedProfile = profiles.find((p) => p.name === lastUsedProfileName);
28596
28608
  if (lastUsedProfile) {
28597
- info(colors.green(`Using last used profile '${lastUsedProfile.name}' for ${context}`));
28609
+ infoStderr(colors.green(`Using last used profile '${lastUsedProfile.name}' for ${context}`));
28598
28610
  return lastUsedProfile;
28599
28611
  }
28600
28612
  }
28601
28613
  if (!!!process.stdin.isTTY || !!!process.stdout.isTTY) {
28602
28614
  const selectedProfile2 = profiles[0];
28603
- info(colors.yellow(`Multiple profiles found for ${context}. Using first available profile: '${selectedProfile2.name}'`));
28615
+ infoStderr(colors.yellow(`Multiple profiles found for ${context}. Using first available profile: '${selectedProfile2.name}'`));
28604
28616
  await setLastUsedProfile("", baseUrl2, workspaceId, selectedProfile2.name, configDir);
28605
28617
  return selectedProfile2;
28606
28618
  }
28607
- info(colors.yellow(`
28619
+ infoStderr(colors.yellow(`
28608
28620
  Multiple workspace profiles found for ${context}:`));
28609
28621
  const selectedName = await Select.prompt({
28610
28622
  message: "Select profile",
@@ -28619,16 +28631,16 @@ Multiple workspace profiles found for ${context}:`));
28619
28631
  }
28620
28632
  async function createWorkspaceProfileInteractively(normalizedBaseUrl, workspaceId, currentBranch, opts, context) {
28621
28633
  if (!context.isForked) {
28622
- info(colors.yellow(`
28634
+ infoStderr(colors.yellow(`
28623
28635
  No workspace profile found for branch '${context.rawBranch}'
28624
28636
  ` + `(${normalizedBaseUrl}, ${workspaceId})`));
28625
28637
  } else {
28626
- info(colors.yellow(`
28638
+ infoStderr(colors.yellow(`
28627
28639
  No workspace profile was found for this forked workspace
28628
28640
  ` + `(${normalizedBaseUrl}, ${workspaceId})`));
28629
28641
  }
28630
28642
  if (!!!process.stdin.isTTY || !!!process.stdout.isTTY) {
28631
- info("Not a TTY, cannot create profile interactively. Use 'wmill workspace add' first.");
28643
+ infoStderr("Not a TTY, cannot create profile interactively. Use 'wmill workspace add' first.");
28632
28644
  return;
28633
28645
  }
28634
28646
  const shouldCreate = await Confirm.prompt({
@@ -28655,8 +28667,8 @@ No workspace profile was found for this forked workspace
28655
28667
  };
28656
28668
  await addWorkspace(newWorkspace, opts);
28657
28669
  await setLastUsedProfile(currentBranch, normalizedBaseUrl, workspaceId, profileName, opts.configDir);
28658
- info(colors.green(`✓ Created profile '${profileName}' for ${workspaceId} on ${normalizedBaseUrl}`));
28659
- info(colors.green(`✓ Profile '${profileName}' is now active`));
28670
+ infoStderr(colors.green(`✓ Created profile '${profileName}' for ${workspaceId} on ${normalizedBaseUrl}`));
28671
+ infoStderr(colors.green(`✓ Profile '${profileName}' is now active`));
28660
28672
  return newWorkspace;
28661
28673
  }
28662
28674
  async function tryResolveWorkspace(opts) {
@@ -28681,11 +28693,11 @@ async function tryResolveWorkspace(opts) {
28681
28693
  const matching = allProfs.filter((w) => w.remote === normalizedBaseUrl && w.workspaceId === workspaceId);
28682
28694
  if (matching.length >= 1) {
28683
28695
  const selected = matching.length === 1 ? matching[0] : await selectFromMultipleProfiles(matching, normalizedBaseUrl, workspaceId, `workspace '${opts.workspace}'`, opts.configDir);
28684
- info(colors.green(`Using workspace profile '${selected.name}' for workspace '${opts.workspace}' (${workspaceId} on ${normalizedBaseUrl})`));
28696
+ infoStderr(colors.green(`Using workspace profile '${selected.name}' for workspace '${opts.workspace}' (${workspaceId} on ${normalizedBaseUrl})`));
28685
28697
  opts.__secret_workspace = selected;
28686
28698
  return { isError: false, value: selected };
28687
28699
  }
28688
- info(`No profile found for workspace '${opts.workspace}' (${workspaceId} on ${normalizedBaseUrl})`);
28700
+ infoStderr(`No profile found for workspace '${opts.workspace}' (${workspaceId} on ${normalizedBaseUrl})`);
28689
28701
  const ws = await createWorkspaceProfileInteractively(normalizedBaseUrl, workspaceId, opts.workspace, opts, { rawBranch: opts.workspace, isForked: false });
28690
28702
  if (ws) {
28691
28703
  opts.__secret_workspace = ws;
@@ -28718,7 +28730,7 @@ async function tryResolveBranchWorkspace(opts, workspaceNameOverride) {
28718
28730
  wsEntry = config.workspaces?.[workspaceNameOverride];
28719
28731
  if (wsEntry) {
28720
28732
  wsName = workspaceNameOverride;
28721
- info(`Using workspace override: ${workspaceNameOverride}`);
28733
+ infoStderr(`Using workspace override: ${workspaceNameOverride}`);
28722
28734
  }
28723
28735
  } else {
28724
28736
  if (!isGitRepository()) {
@@ -28732,7 +28744,7 @@ async function tryResolveBranchWorkspace(opts, workspaceNameOverride) {
28732
28744
  workspaceIdIfForked = getWorkspaceIdForWorkspaceForkFromBranchName(rawBranch);
28733
28745
  const branchToLookup = originalBranchIfForked ?? rawBranch;
28734
28746
  if (originalBranchIfForked) {
28735
- info(`Using original branch \`${originalBranchIfForked}\` for finding workspace from workspaces section in wmill.yaml`);
28747
+ infoStderr(`Using original branch \`${originalBranchIfForked}\` for finding workspace from workspaces section in wmill.yaml`);
28736
28748
  }
28737
28749
  const match = findWorkspaceByGitBranch(config.workspaces, branchToLookup);
28738
28750
  if (match) {
@@ -28744,7 +28756,7 @@ async function tryResolveBranchWorkspace(opts, workspaceNameOverride) {
28744
28756
  }
28745
28757
  if (!wsEntry.baseUrl) {
28746
28758
  if (workspaceNameOverride) {
28747
- warn(`⚠️ Workspace '${wsName}' has no baseUrl configured. Cannot resolve a profile.
28759
+ warnStderr(`⚠️ Workspace '${wsName}' has no baseUrl configured. Cannot resolve a profile.
28748
28760
  ` + ` Add baseUrl to workspace '${wsName}' in wmill.yaml, or use --base-url flag.`);
28749
28761
  }
28750
28762
  return;
@@ -28762,7 +28774,7 @@ async function tryResolveBranchWorkspace(opts, workspaceNameOverride) {
28762
28774
  } else {
28763
28775
  reason = `matched current git branch '${rawBranch}'`;
28764
28776
  }
28765
- info(`Using workspace '${wsName}' (${reason}) → ${workspaceId} on ${baseUrl2}`);
28777
+ infoStderr(`Using workspace '${wsName}' (${reason}) → ${workspaceId} on ${baseUrl2}`);
28766
28778
  let normalizedBaseUrl;
28767
28779
  try {
28768
28780
  normalizedBaseUrl = new URL(baseUrl2).toString();
@@ -28778,24 +28790,24 @@ async function tryResolveBranchWorkspace(opts, workspaceNameOverride) {
28778
28790
  let selectedProfile;
28779
28791
  if (matchingProfiles.length === 1) {
28780
28792
  selectedProfile = matchingProfiles[0];
28781
- info(colors.green(`Using workspace profile '${selectedProfile.name}' for workspace '${wsName}' with workspace id \`${workspaceId}\``));
28793
+ infoStderr(colors.green(`Using workspace profile '${selectedProfile.name}' for workspace '${wsName}' with workspace id \`${workspaceId}\``));
28782
28794
  } else {
28783
28795
  const lastUsedName = await getLastUsedProfile(wsName, normalizedBaseUrl, workspaceId, opts.configDir);
28784
28796
  if (lastUsedName) {
28785
28797
  const lastUsedProfile = matchingProfiles.find((p) => p.name === lastUsedName);
28786
28798
  if (lastUsedProfile) {
28787
- info(colors.green(`Using workspace profile '${lastUsedProfile.name}' for workspace '${wsName}' (last used)`));
28799
+ infoStderr(colors.green(`Using workspace profile '${lastUsedProfile.name}' for workspace '${wsName}' (last used)`));
28788
28800
  return lastUsedProfile;
28789
28801
  }
28790
28802
  }
28791
28803
  selectedProfile = await selectFromMultipleProfiles(matchingProfiles, normalizedBaseUrl, workspaceId, `workspace '${wsName}'`, opts.configDir);
28792
28804
  await setLastUsedProfile(wsName, normalizedBaseUrl, workspaceId, selectedProfile.name, opts.configDir);
28793
- info(colors.green(`Using workspace profile '${selectedProfile.name}' for workspace '${wsName}'`));
28805
+ infoStderr(colors.green(`Using workspace profile '${selectedProfile.name}' for workspace '${wsName}'`));
28794
28806
  }
28795
28807
  if (workspaceIdIfForked) {
28796
28808
  selectedProfile.name = `${selectedProfile.name}/${workspaceIdIfForked}`;
28797
28809
  selectedProfile.workspaceId = workspaceIdIfForked;
28798
- info(`Using fork workspace \`${workspaceIdIfForked}\` (parent: \`${workspaceId}\`) from branch \`${rawBranch}\``);
28810
+ infoStderr(`Using fork workspace \`${workspaceIdIfForked}\` (parent: \`${workspaceId}\`) from branch \`${rawBranch}\``);
28799
28811
  }
28800
28812
  return selectedProfile;
28801
28813
  }
@@ -28809,7 +28821,7 @@ async function resolveWorkspace(opts, workspaceNameOverride) {
28809
28821
  try {
28810
28822
  normalizedBaseUrl = new URL(opts.baseUrl).toString();
28811
28823
  } catch (error2) {
28812
- info(colors.red(`Invalid base URL: ${opts.baseUrl}`));
28824
+ infoStderr(colors.red(`Invalid base URL: ${opts.baseUrl}`));
28813
28825
  return process.exit(-1);
28814
28826
  }
28815
28827
  if (opts.workspace) {
@@ -28824,7 +28836,7 @@ async function resolveWorkspace(opts, workspaceNameOverride) {
28824
28836
  }
28825
28837
  if (existingWorkspace) {
28826
28838
  if (existingWorkspace.remote !== normalizedBaseUrl) {
28827
- info(colors.red(`Base URL mismatch: --base-url is ${normalizedBaseUrl} but workspace profile "${opts.workspace}" uses ${existingWorkspace.remote}`));
28839
+ infoStderr(colors.red(`Base URL mismatch: --base-url is ${normalizedBaseUrl} but workspace profile "${opts.workspace}" uses ${existingWorkspace.remote}`));
28828
28840
  return process.exit(-1);
28829
28841
  }
28830
28842
  return {
@@ -28840,7 +28852,7 @@ async function resolveWorkspace(opts, workspaceNameOverride) {
28840
28852
  token: opts.token
28841
28853
  };
28842
28854
  } else {
28843
- info(colors.red("If you specify a base URL with --base-url, you must also specify a workspace (--workspace) and token (--token)."));
28855
+ infoStderr(colors.red("If you specify a base URL with --base-url, you must also specify a workspace (--workspace) and token (--token)."));
28844
28856
  return process.exit(-1);
28845
28857
  }
28846
28858
  }
@@ -28851,7 +28863,7 @@ async function resolveWorkspace(opts, workspaceNameOverride) {
28851
28863
  if (workspaceNameOverride || opts.workspace || !branch || !branch.startsWith(WM_FORK_PREFIX)) {
28852
28864
  return workspace;
28853
28865
  } else {
28854
- info(`Found an active workspace \`${workspace.name}\` but the branch name indicates this is a forked workspace. Ignoring active workspace and trying to resolve the correct workspace from the branch name \`${branch}\`. Use --workspace to override.`);
28866
+ infoStderr(`Found an active workspace \`${workspace.name}\` but the branch name indicates this is a forked workspace. Ignoring active workspace and trying to resolve the correct workspace from the branch name \`${branch}\`. Use --workspace to override.`);
28855
28867
  }
28856
28868
  } else if (opts.workspace) {
28857
28869
  const profiles = await allWorkspaces(opts.configDir);
@@ -28861,9 +28873,9 @@ async function resolveWorkspace(opts, workspaceNameOverride) {
28861
28873
  if (suggestions.length > 0) {
28862
28874
  msg += ` Did you mean: ${suggestions.map((s) => `"${s.name}"`).join(", ")}?`;
28863
28875
  }
28864
- info(colors.red.bold(msg));
28876
+ infoStderr(colors.red.bold(msg));
28865
28877
  if (profiles.length > 0) {
28866
- info(`
28878
+ infoStderr(`
28867
28879
  Available workspaces:`);
28868
28880
  new Table2().header(["name", "remote", "workspace id"]).padding(2).border(true).body(profiles.map((w) => [w.name, w.remote, w.workspaceId])).render();
28869
28881
  }
@@ -28894,10 +28906,10 @@ Available workspaces:`);
28894
28906
  `);
28895
28907
  if (wsNames.length === 1) {
28896
28908
  pickedWsName = wsNames[0];
28897
- info(`Auto-selected workspace '${pickedWsName}' (only workspace in config).
28909
+ infoStderr(`Auto-selected workspace '${pickedWsName}' (only workspace in config).
28898
28910
  Use --workspace to override or 'wmill workspace bind' to add more workspaces.`);
28899
28911
  } else if (process.stdin.isTTY) {
28900
- info(`Multiple workspaces configured but none matched the current context.
28912
+ infoStderr(`Multiple workspaces configured but none matched the current context.
28901
28913
  Configured workspaces:
28902
28914
  ${wsListStr}
28903
28915
  Use --workspace to skip this prompt.`);
@@ -28935,7 +28947,7 @@ Use --workspace to select one.`));
28935
28947
  try {
28936
28948
  normalizedBaseUrl = new URL(envBaseUrl).toString();
28937
28949
  } catch {
28938
- info(colors.red(`Invalid BASE_INTERNAL_URL: ${envBaseUrl}`));
28950
+ infoStderr(colors.red(`Invalid BASE_INTERNAL_URL: ${envBaseUrl}`));
28939
28951
  return process.exit(-1);
28940
28952
  }
28941
28953
  debug(`Using workspace from environment variables: ${envWorkspace} on ${normalizedBaseUrl}`);
@@ -28948,7 +28960,7 @@ Use --workspace to select one.`));
28948
28960
  opts.__secret_workspace = ws;
28949
28961
  return ws;
28950
28962
  }
28951
- info(colors.red.bold("No workspace given and no default set. Run 'wmill workspace add' to configure one."));
28963
+ infoStderr(colors.red.bold("No workspace given and no default set. Run 'wmill workspace add' to configure one."));
28952
28964
  return process.exit(-1);
28953
28965
  }
28954
28966
  async function fetchVersion(baseUrl2) {
@@ -28988,7 +29000,7 @@ async function tryResolveVersion(opts) {
28988
29000
  }
28989
29001
  function validatePath(path4) {
28990
29002
  if (!(path4.startsWith("g") || path4.startsWith("u") || path4.startsWith("f"))) {
28991
- info(colors.red("Given remote path looks invalid. Remote paths are typically of the form <u|g|f>/<username|group|folder>/..."));
29003
+ infoStderr(colors.red("Given remote path looks invalid. Remote paths are typically of the form <u|g|f>/<username|group|folder>/..."));
28992
29004
  return false;
28993
29005
  }
28994
29006
  return true;
@@ -74091,7 +74103,18 @@ async function get6(opts, path19) {
74091
74103
  console.log(colors.bold("Account:") + " " + (v.account ?? "-"));
74092
74104
  }
74093
74105
  }
74094
- async function pushVariable(workspace, remotePath, variable, localVariable, plainSecrets, wsSpecific) {
74106
+ function looksLikeWorkspaceCiphertext(value) {
74107
+ if (value.startsWith("$vault:") || value.startsWith("$aws_sm:") || value.startsWith("$azure_kv:")) {
74108
+ return true;
74109
+ }
74110
+ if (value.length === 0 || value.length % 4 !== 0)
74111
+ return false;
74112
+ if (!/^[A-Za-z0-9+/]+={0,2}$/.test(value))
74113
+ return false;
74114
+ const decodedLen = Buffer.from(value, "base64").length;
74115
+ return decodedLen > 0 && decodedLen % 16 === 0;
74116
+ }
74117
+ async function pushVariable(workspace, remotePath, variable, localVariable, plainSecrets, wsSpecific, allowSecretDowngrade = false) {
74095
74118
  remotePath = removeType(remotePath, "variable");
74096
74119
  debug(`Processing local variable ${remotePath}`);
74097
74120
  try {
@@ -74111,13 +74134,21 @@ async function pushVariable(workspace, remotePath, variable, localVariable, plai
74111
74134
  return;
74112
74135
  }
74113
74136
  debug(`Variable ${remotePath} is not up-to-date, updating`);
74137
+ let nextIsSecret = undefined;
74138
+ if (localVariable.is_secret !== variable.is_secret) {
74139
+ if (localVariable.is_secret) {
74140
+ nextIsSecret = true;
74141
+ } else if (allowSecretDowngrade) {
74142
+ nextIsSecret = false;
74143
+ }
74144
+ }
74114
74145
  await updateVariable({
74115
74146
  workspace,
74116
74147
  path: remotePath.replaceAll(SEP16, "/"),
74117
74148
  alreadyEncrypted: !plainSecrets,
74118
74149
  requestBody: {
74119
74150
  ...localVariable,
74120
- is_secret: localVariable.is_secret && !variable.is_secret ? true : undefined,
74151
+ is_secret: nextIsSecret,
74121
74152
  ...wsSpecific !== undefined ? { ws_specific: wsSpecific } : {}
74122
74153
  }
74123
74154
  });
@@ -74145,7 +74176,17 @@ async function push7(opts, filePath, remotePath) {
74145
74176
  throw new Error("file path must refer to a file.");
74146
74177
  }
74147
74178
  info(colors.bold.yellow("Pushing variable..."));
74148
- await pushVariable(workspace.workspaceId, remotePath, undefined, parseFromFile(filePath), opts.plainSecrets ?? false);
74179
+ const local = parseFromFile(filePath);
74180
+ let plainSecrets = opts.plainSecrets ?? false;
74181
+ if (opts.plainSecrets === undefined && local.is_secret) {
74182
+ if (!looksLikeWorkspaceCiphertext(local.value)) {
74183
+ info(colors.yellow("Secret value is not in encrypted form; pushing as plaintext to be encrypted server-side (pass --plain-secrets to silence)."));
74184
+ plainSecrets = true;
74185
+ } else {
74186
+ warn("Secret value looks already-encrypted; pushing it as-is. If it is a plaintext secret, re-run with --plain-secrets so it gets encrypted.");
74187
+ }
74188
+ }
74189
+ await pushVariable(workspace.workspaceId, remotePath, undefined, local, plainSecrets, undefined, true);
74149
74190
  info(colors.bold.underline.green(`Variable ${remotePath} pushed`));
74150
74191
  }
74151
74192
  async function add2(opts, value, remotePath) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windmill-cli",
3
- "version": "1.737.0",
3
+ "version": "1.738.0",
4
4
  "description": "CLI for Windmill",
5
5
  "license": "Apache 2.0",
6
6
  "type": "module",