@anvil-works/anvil-cli 0.5.9 → 0.5.10

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/dist/cli.js +241 -85
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -42538,6 +42538,13 @@ var __webpack_exports__ = {};
42538
42538
  function getConfig(key) {
42539
42539
  return config_config.get(key);
42540
42540
  }
42541
+ function deleteConfig(key) {
42542
+ if (key in configDefaults) config_config.set(key, configDefaults[key]);
42543
+ else {
42544
+ const store = config_config.store;
42545
+ if (store && "object" == typeof store && key in store) config_config.delete(key);
42546
+ }
42547
+ }
42541
42548
  function resetConfig() {
42542
42549
  for (const [key, value] of Object.entries(configDefaults))config_config.set(key, value);
42543
42550
  const currentStore = config_config.store;
@@ -42670,7 +42677,7 @@ var __webpack_exports__ = {};
42670
42677
  ...config
42671
42678
  };
42672
42679
  }
42673
- function globalConfig_getGlobalOutputConfig() {
42680
+ function getGlobalOutputConfig() {
42674
42681
  return globalOutputConfig;
42675
42682
  }
42676
42683
  const logger_timestamp = ()=>new Date().toISOString();
@@ -42691,10 +42698,20 @@ var __webpack_exports__ = {};
42691
42698
  function writeJson(entry) {
42692
42699
  console.log(JSON.stringify(entry));
42693
42700
  }
42701
+ function logJsonResult(success, options) {
42702
+ if (getGlobalOutputConfig().jsonMode) writeJson({
42703
+ type: "result",
42704
+ success,
42705
+ message: options?.message,
42706
+ data: options?.data,
42707
+ error: options?.error,
42708
+ timestamp: logger_timestamp()
42709
+ });
42710
+ }
42694
42711
  class DefaultLogger {
42695
42712
  paused = false;
42696
42713
  get jsonMode() {
42697
- return globalConfig_getGlobalOutputConfig().jsonMode;
42714
+ return getGlobalOutputConfig().jsonMode;
42698
42715
  }
42699
42716
  log(...args) {
42700
42717
  if (this.paused) return;
@@ -42796,7 +42813,7 @@ var __webpack_exports__ = {};
42796
42813
  this.sessionVerbose = options.verbose ?? false;
42797
42814
  }
42798
42815
  get jsonMode() {
42799
- return globalConfig_getGlobalOutputConfig().jsonMode;
42816
+ return getGlobalOutputConfig().jsonMode;
42800
42817
  }
42801
42818
  isVerbose() {
42802
42819
  return this.sessionVerbose || getConfig("verbose");
@@ -50593,7 +50610,7 @@ var __webpack_exports__ = {};
50593
50610
  const execFile = (0, external_node_util_namespaceObject.promisify)(external_node_child_process_.execFile);
50594
50611
  const open_dirname = external_node_path_.dirname((0, external_node_url_namespaceObject.fileURLToPath)(__rslib_import_meta_url__));
50595
50612
  const localXdgOpenPath = external_node_path_.join(open_dirname, 'xdg-open');
50596
- const { platform, arch } = external_node_process_;
50613
+ const { platform: open_platform, arch } = external_node_process_;
50597
50614
  async function getWindowsDefaultBrowserFromWsl() {
50598
50615
  const powershellPath = await powerShellPath();
50599
50616
  const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
@@ -50686,13 +50703,13 @@ var __webpack_exports__ = {};
50686
50703
  let command;
50687
50704
  const cliArguments = [];
50688
50705
  const childProcessOptions = {};
50689
- if ('darwin' === platform) {
50706
+ if ('darwin' === open_platform) {
50690
50707
  command = 'open';
50691
50708
  if (options.wait) cliArguments.push('--wait-apps');
50692
50709
  if (options.background) cliArguments.push('--background');
50693
50710
  if (options.newInstance) cliArguments.push('--new');
50694
50711
  if (app) cliArguments.push('-a', app);
50695
- } else if ('win32' !== platform && (!is_wsl || isInsideContainer() || app)) {
50712
+ } else if ('win32' !== open_platform && (!is_wsl || isInsideContainer() || app)) {
50696
50713
  if (app) command = app;
50697
50714
  else {
50698
50715
  const isBundled = !open_dirname || '/' === open_dirname;
@@ -50701,7 +50718,7 @@ var __webpack_exports__ = {};
50701
50718
  await external_node_fs_promises_namespaceObject.access(localXdgOpenPath, external_node_fs_promises_namespaceObject.constants.X_OK);
50702
50719
  exeLocalXdgOpen = true;
50703
50720
  } catch {}
50704
- const useSystemXdgOpen = external_node_process_.versions.electron ?? ('android' === platform || isBundled || !exeLocalXdgOpen);
50721
+ const useSystemXdgOpen = external_node_process_.versions.electron ?? ('android' === open_platform || isBundled || !exeLocalXdgOpen);
50705
50722
  command = useSystemXdgOpen ? 'xdg-open' : localXdgOpenPath;
50706
50723
  }
50707
50724
  if (appArguments.length > 0) cliArguments.push(...appArguments);
@@ -50727,7 +50744,7 @@ var __webpack_exports__ = {};
50727
50744
  }
50728
50745
  options.target = external_node_buffer_namespaceObject.Buffer.from(encodedArguments.join(' '), 'utf16le').toString('base64');
50729
50746
  }
50730
- if ('darwin' === platform && appArguments.length > 0) cliArguments.push('--args', ...appArguments);
50747
+ if ('darwin' === open_platform && appArguments.length > 0) cliArguments.push('--args', ...appArguments);
50731
50748
  if (options.target) cliArguments.push(options.target);
50732
50749
  const subprocess = external_node_child_process_.spawn(command, cliArguments, childProcessOptions);
50733
50750
  if (options.wait) return new Promise((resolve, reject)=>{
@@ -50753,9 +50770,9 @@ var __webpack_exports__ = {};
50753
50770
  if (!archBinary) throw new Error(`${arch} is not supported`);
50754
50771
  return archBinary;
50755
50772
  }
50756
- function detectPlatformBinary({ [platform]: platformBinary }, { wsl }) {
50773
+ function detectPlatformBinary({ [open_platform]: platformBinary }, { wsl }) {
50757
50774
  if (wsl && is_wsl) return detectArchBinary(wsl);
50758
- if (!platformBinary) throw new Error(`${platform} is not supported`);
50775
+ if (!platformBinary) throw new Error(`${open_platform} is not supported`);
50759
50776
  return detectArchBinary(platformBinary);
50760
50777
  }
50761
50778
  const open_apps = {};
@@ -50882,6 +50899,11 @@ var __webpack_exports__ = {};
50882
50899
  if ("win32" === process.platform) return tokens.map(quoteForCmdShell).join(" ");
50883
50900
  return tokens.map(quoteForPosixShell).join(" ");
50884
50901
  }
50902
+ function formatFallbackEditorLabel(preferredEditorCommand) {
50903
+ const trimmed = preferredEditorCommand.trim();
50904
+ if (!trimmed) return "your editor";
50905
+ return trimmed;
50906
+ }
50885
50907
  async function openPathInEditorOrDefault(targetPath, preferredEditorCommand, deps = defaultDeps) {
50886
50908
  if (preferredEditorCommand) if (deps.isCommandAvailable(preferredEditorCommand)) try {
50887
50909
  const tokens = parseCommandTokens(preferredEditorCommand);
@@ -50892,9 +50914,9 @@ var __webpack_exports__ = {};
50892
50914
  ]));
50893
50915
  return;
50894
50916
  } catch (error) {
50895
- logger_logger.warn(`Failed to open preferred editor '${preferredEditorCommand}': ${errors_getErrorMessage(error)}. Falling back to the system default app.`);
50917
+ logger_logger.warn(`Failed to open ${formatFallbackEditorLabel(preferredEditorCommand)} automatically: ${errors_getErrorMessage(error)}.`);
50896
50918
  }
50897
- else logger_logger.warn(`Preferred editor command '${preferredEditorCommand}' was not found in PATH. Falling back to the system default app.`);
50919
+ else logger_logger.info(`Open ${formatFallbackEditorLabel(preferredEditorCommand)} to edit your app.`);
50898
50920
  await deps.openSystem(targetPath);
50899
50921
  }
50900
50922
  function decideFallbackUrl(explicitUrl, availableUrls = getAvailableAnvilUrls()) {
@@ -51613,7 +51635,7 @@ var __webpack_exports__ = {};
51613
51635
  if (username) logger_logger.error(`Not logged in to ${anvilUrl} as ${username}`);
51614
51636
  else logger_logger.error(`Not logged in to ${anvilUrl}`);
51615
51637
  logger_logger.verbose(chalk_source.yellow("Please log in first:"));
51616
- console.log(chalk_source.cyan(` anvil login ${anvilUrl.replace(/^https?:\/\//, "")}`));
51638
+ logger_logger.info(chalk_source.cyan(` anvil login ${anvilUrl.replace(/^https?:\/\//, "")}`));
51617
51639
  process.exit(1);
51618
51640
  }
51619
51641
  logger_logger.verbose(chalk_source.green("✓ Authentication tokens found"));
@@ -52803,6 +52825,54 @@ var __webpack_exports__ = {};
52803
52825
  await deps.logout();
52804
52826
  deps.resetConfig();
52805
52827
  }
52828
+ function performConfigDelete(key) {
52829
+ const allConfig = getAllConfig();
52830
+ const existed = Object.prototype.hasOwnProperty.call(allConfig, key);
52831
+ deleteConfig(key);
52832
+ return {
52833
+ existed
52834
+ };
52835
+ }
52836
+ function getConfigListData() {
52837
+ const allConfig = getAllConfig();
52838
+ const resolvedUrl = resolveAnvilUrl();
52839
+ const defaultUrl = isDevMode() ? "http://localhost:3000" : "https://anvil.works";
52840
+ const authTokens = allConfig.authTokens;
52841
+ const urls = authTokens && "object" == typeof authTokens ? Object.keys(authTokens).sort() : [];
52842
+ const accounts = [];
52843
+ for (const url of urls){
52844
+ const urlData = authTokens?.[url];
52845
+ if (!(!urlData || "object" != typeof urlData || Array.isArray(urlData))) for (const username of Object.keys(urlData).sort()){
52846
+ const accountData = urlData[username];
52847
+ const hasConfigTokens = !!(accountData?.authToken || accountData?.refreshToken);
52848
+ const hasAnyTokens = hasTokensForUrl(url, username);
52849
+ accounts.push({
52850
+ url,
52851
+ username,
52852
+ status: hasConfigTokens ? "config" : hasAnyTokens ? "keychain" : "none"
52853
+ });
52854
+ }
52855
+ }
52856
+ const skipKeys = new Set([
52857
+ "anvilUrl",
52858
+ "authTokens"
52859
+ ]);
52860
+ const values = {};
52861
+ for (const [key, value] of Object.entries(allConfig))if (!skipKeys.has(key)) values[key] = value;
52862
+ return {
52863
+ anvilUrl: {
52864
+ value: resolvedUrl,
52865
+ defaultValue: defaultUrl,
52866
+ isDefault: resolvedUrl === defaultUrl
52867
+ },
52868
+ authTokens: {
52869
+ totalUrls: urls.length,
52870
+ totalAccounts: accounts.filter((account)=>"none" !== account.status).length,
52871
+ accounts
52872
+ },
52873
+ values
52874
+ };
52875
+ }
52806
52876
  function registerConfigCommand(program) {
52807
52877
  const configCommand = program.command("config").description("Manage configuration").alias("c");
52808
52878
  configCommand.command("get <key>").description("Get a configuration value").action(async (key)=>{
@@ -52829,49 +52899,35 @@ var __webpack_exports__ = {};
52829
52899
  process.exit(1);
52830
52900
  }
52831
52901
  });
52902
+ configCommand.command("delete <key>").alias("unset").description("Delete a configuration value or reset it to its default").action(async (key)=>{
52903
+ try {
52904
+ const result = performConfigDelete(key);
52905
+ if (result.existed) logger_logger.success(`Deleted ${key}`);
52906
+ else logger_logger.warn(`Key '${key}' was not set; applied default/empty value if applicable.`);
52907
+ } catch (error) {
52908
+ logger_logger.error(error instanceof Error ? error.message : String(error));
52909
+ process.exit(1);
52910
+ }
52911
+ });
52832
52912
  configCommand.command("list").description("List all configuration values").action(async ()=>{
52833
52913
  try {
52834
- const allConfig = getAllConfig();
52914
+ const configData = getConfigListData();
52915
+ if (getGlobalOutputConfig().jsonMode) return void logJsonResult(true, {
52916
+ data: configData
52917
+ });
52835
52918
  console.log(chalk_source.bold("\nConfiguration:"));
52836
52919
  console.log(chalk_source.gray("─".repeat(50)));
52837
- const resolvedUrl = resolveAnvilUrl();
52838
- const defaultUrl = isDevMode() ? "http://localhost:3000" : "https://anvil.works";
52839
- const defaultHint = resolvedUrl === defaultUrl ? "" : chalk_source.gray(` (default: ${defaultUrl})`);
52840
- console.log(chalk_source.cyan("anvilUrl") + ` = ${resolvedUrl}${defaultHint}`);
52841
- const authTokens = allConfig.authTokens;
52842
- if (authTokens && "object" == typeof authTokens) {
52843
- const urls = Object.keys(authTokens).sort();
52844
- if (urls.length > 0) {
52845
- let totalAccounts = 0;
52846
- for (const url of urls){
52847
- const urlData = authTokens[url];
52848
- if (urlData && "object" == typeof urlData && !Array.isArray(urlData)) {
52849
- const usernames = Object.keys(urlData);
52850
- totalAccounts += usernames.filter((username)=>hasTokensForUrl(url, username)).length;
52851
- }
52852
- }
52853
- console.log(chalk_source.cyan("authTokens") + ` = ${chalk_source.gray(`${totalAccounts} logged-in account(s) across ${urls.length} URL(s)`)}`);
52854
- for (const url of urls){
52855
- const urlData = authTokens[url];
52856
- if (urlData && "object" == typeof urlData && !Array.isArray(urlData)) {
52857
- const usernames = Object.keys(urlData).sort();
52858
- if (usernames.length > 0) for (const username of usernames){
52859
- const accountData = urlData[username];
52860
- const hasConfigTokens = !!(accountData?.authToken || accountData?.refreshToken);
52861
- const hasAnyTokens = hasTokensForUrl(url, username);
52862
- const status = hasConfigTokens ? chalk_source.green("✓ logged in (config)") : hasAnyTokens ? chalk_source.green("✓ logged in (keychain)") : chalk_source.gray("(no tokens)");
52863
- console.log(chalk_source.gray(` ${url}: ${username} ${status}`));
52864
- }
52865
- }
52866
- }
52867
- } else console.log(chalk_source.cyan("authTokens") + ` = ${chalk_source.gray("(no accounts)")}`);
52920
+ const defaultHint = configData.anvilUrl.isDefault ? "" : chalk_source.gray(` (default: ${configData.anvilUrl.defaultValue})`);
52921
+ console.log(chalk_source.cyan("anvilUrl") + ` = ${configData.anvilUrl.value}${defaultHint}`);
52922
+ if (configData.authTokens.totalUrls > 0) {
52923
+ console.log(chalk_source.cyan("authTokens") + ` = ${chalk_source.gray(`${configData.authTokens.totalAccounts} logged-in account(s) across ${configData.authTokens.totalUrls} URL(s)`)}`);
52924
+ for (const account of configData.authTokens.accounts){
52925
+ const status = "config" === account.status ? chalk_source.green("✓ logged in (config)") : "keychain" === account.status ? chalk_source.green("✓ logged in (keychain)") : chalk_source.gray("(no tokens)");
52926
+ console.log(chalk_source.gray(` ${account.url}: ${account.username} ${status}`));
52927
+ }
52868
52928
  } else console.log(chalk_source.cyan("authTokens") + ` = ${chalk_source.gray("(none)")}`);
52869
- const skipKeys = new Set([
52870
- "anvilUrl",
52871
- "authTokens"
52872
- ]);
52873
- for (const [k, v] of Object.entries(allConfig))if (!skipKeys.has(k)) if (null === v) console.log(chalk_source.cyan(k) + ` = ${chalk_source.gray("null")}`);
52874
- else console.log(chalk_source.cyan(k) + ` = ${v}`);
52929
+ for (const [key, value] of Object.entries(configData.values))if (null === value) console.log(chalk_source.cyan(key) + ` = ${chalk_source.gray("null")}`);
52930
+ else console.log(chalk_source.cyan(key) + ` = ${value}`);
52875
52931
  console.log(chalk_source.gray("─".repeat(50)));
52876
52932
  console.log();
52877
52933
  } catch (e) {
@@ -52889,11 +52945,23 @@ var __webpack_exports__ = {};
52889
52945
  }
52890
52946
  });
52891
52947
  }
52948
+ function getVersionInfo(version) {
52949
+ return {
52950
+ version,
52951
+ nodeVersion: process.version,
52952
+ platform: process.platform,
52953
+ arch: process.arch
52954
+ };
52955
+ }
52892
52956
  function registerVersionCommand(program, version) {
52893
52957
  program.command("version").description("Show version information").action(()=>{
52894
- console.log(chalk_source.cyan.bold(`\n⚙ anvil ${version}`));
52895
- console.log(chalk_source.gray(` Node.js ${process.version}`));
52896
- console.log(chalk_source.gray(` Platform: ${process.platform} ${process.arch}`));
52958
+ const info = getVersionInfo(version);
52959
+ if (getGlobalOutputConfig().jsonMode) return void logJsonResult(true, {
52960
+ data: info
52961
+ });
52962
+ console.log(chalk_source.cyan.bold(`\n⚙ anvil ${info.version}`));
52963
+ console.log(chalk_source.gray(` Node.js ${info.nodeVersion}`));
52964
+ console.log(chalk_source.gray(` Platform: ${info.platform} ${info.arch}`));
52897
52965
  console.log();
52898
52966
  });
52899
52967
  }
@@ -52903,6 +52971,68 @@ var __webpack_exports__ = {};
52903
52971
  runInteractiveLoginFlow: runInteractiveLoginFlow
52904
52972
  };
52905
52973
  const DEFAULT_ANVIL_SERVER_URL_PROMPT = "Default Anvil server URL";
52974
+ const CUSTOM_EDITOR_CHOICE = "__custom_editor_command__";
52975
+ function formatCustomEditorChoice(currentEditor) {
52976
+ if (!currentEditor) return "Enter custom editor command";
52977
+ return `Custom editor command (${currentEditor})`;
52978
+ }
52979
+ async function promptForPreferredEditor(currentEditor, installedEditors, ui) {
52980
+ if (0 === installedEditors.length) {
52981
+ ui.warn("No supported editor command was found in PATH.");
52982
+ ui.info(chalk_source.gray("If your editor is installed, its shell command may not be available in this terminal."));
52983
+ const action = await ui.select("Preferred editor", [
52984
+ {
52985
+ name: "None",
52986
+ value: ""
52987
+ },
52988
+ {
52989
+ name: formatCustomEditorChoice(currentEditor),
52990
+ value: CUSTOM_EDITOR_CHOICE
52991
+ }
52992
+ ], currentEditor ? CUSTOM_EDITOR_CHOICE : "");
52993
+ if (action !== CUSTOM_EDITOR_CHOICE) return action;
52994
+ const customDefault = currentEditor && !preferredEditors.includes(currentEditor) ? currentEditor : "";
52995
+ const answer = await ui.prompt([
52996
+ {
52997
+ type: "input",
52998
+ name: "preferredEditorCommand",
52999
+ message: "Custom editor command",
53000
+ default: customDefault
53001
+ }
53002
+ ]);
53003
+ return answer.preferredEditorCommand.trim();
53004
+ }
53005
+ if (installedEditors.length < preferredEditors.length) {
53006
+ const unavailableCount = preferredEditors.length - installedEditors.length;
53007
+ ui.verbose(chalk_source.gray(`${unavailableCount} supported editor(s) are not installed and were hidden.`));
53008
+ }
53009
+ const editorChoices = [
53010
+ {
53011
+ name: "None",
53012
+ value: ""
53013
+ },
53014
+ ...installedEditors.map((editor)=>({
53015
+ name: editor,
53016
+ value: editor
53017
+ })),
53018
+ {
53019
+ name: formatCustomEditorChoice(currentEditor),
53020
+ value: CUSTOM_EDITOR_CHOICE
53021
+ }
53022
+ ];
53023
+ const defaultValue = editorChoices.some((choice)=>choice.value === currentEditor) ? currentEditor : currentEditor ? CUSTOM_EDITOR_CHOICE : "";
53024
+ const selectedEditor = await ui.select("Preferred editor", editorChoices, defaultValue);
53025
+ if (selectedEditor !== CUSTOM_EDITOR_CHOICE) return selectedEditor;
53026
+ const answer = await ui.prompt([
53027
+ {
53028
+ type: "input",
53029
+ name: "preferredEditorCommand",
53030
+ message: "Custom editor command",
53031
+ default: currentEditor && !installedEditors.includes(currentEditor) ? currentEditor : ""
53032
+ }
53033
+ ]);
53034
+ return answer.preferredEditorCommand.trim();
53035
+ }
52906
53036
  async function getConfigureVersionStatus(currentVersion, latestVersionGetter = getLatestVersion) {
52907
53037
  const latestVersion = await latestVersionGetter();
52908
53038
  if (!latestVersion) return {
@@ -52961,25 +53091,11 @@ var __webpack_exports__ = {};
52961
53091
  const configuredAnvilUrl = parseConfigSetValue("anvilUrl", urlAnswer.anvilUrl);
52962
53092
  setConfig("anvilUrl", configuredAnvilUrl);
52963
53093
  logger_logger.success(`Set default Anvil server URL (anvilUrl) = ${configuredAnvilUrl}`);
52964
- const currentEditor = String(getConfig("preferredEditor") || "").trim().toLowerCase();
53094
+ const currentEditor = String(getConfig("preferredEditor") || "").trim();
53095
+ const currentEditorNormalized = currentEditor.toLowerCase();
52965
53096
  const installedEditors = getInstalledPreferredEditors();
52966
- if (0 === installedEditors.length) logger_logger.warn("No supported editor command was found in PATH. Leaving preferredEditor unset is recommended.");
52967
- else if (installedEditors.length < preferredEditors.length) {
52968
- const unavailableCount = preferredEditors.length - installedEditors.length;
52969
- logger_logger.verbose(chalk_source.gray(`${unavailableCount} supported editor(s) are not installed and were hidden.`));
52970
- }
52971
- const editorChoices = [
52972
- {
52973
- name: "None",
52974
- value: ""
52975
- },
52976
- ...installedEditors.map((editor)=>({
52977
- name: editor,
52978
- value: editor
52979
- }))
52980
- ];
52981
- if (currentEditor && !editorChoices.some((choice)=>choice.value === currentEditor)) logger_logger.warn(`Configured preferredEditor '${currentEditor}' is not currently available in PATH.`);
52982
- const selectedEditor = await logger_logger.select("Preferred editor", editorChoices, editorChoices.some((choice)=>choice.value === currentEditor) ? currentEditor : "");
53097
+ if (currentEditor && installedEditors.length > 0 && !installedEditors.includes(currentEditorNormalized)) logger_logger.warn(`Configured preferredEditor '${currentEditor}' is not currently available in PATH.`);
53098
+ const selectedEditor = await promptForPreferredEditor(currentEditor, installedEditors, logger_logger);
52983
53099
  setConfig("preferredEditor", selectedEditor);
52984
53100
  if (selectedEditor) logger_logger.success(`Set preferredEditor = ${selectedEditor}`);
52985
53101
  else logger_logger.info("Left preferredEditor unset.");
@@ -53025,11 +53141,23 @@ var __webpack_exports__ = {};
53025
53141
  getLatestVersion().then((latestVersion)=>{
53026
53142
  if (latestVersion && semver_default().valid(VERSION) && semver_default().valid(latestVersion) && semver_default().lt(VERSION, latestVersion)) {
53027
53143
  logger_logger.warn("A new version of anvil is available!");
53028
- console.log(chalk_source.gray(` Current: ${VERSION} → Latest: ${latestVersion}`) + chalk_source.cyan("\n Run 'anvil update' to see update commands."));
53029
- console.log();
53144
+ logger_logger.info(chalk_source.gray(` Current: ${VERSION} → Latest: ${latestVersion}`) + chalk_source.cyan("\n Run 'anvil update' to see update commands."));
53030
53145
  }
53031
53146
  }).catch(()=>{});
53032
53147
  }
53148
+ function getUpdateInstructions(platform) {
53149
+ if ("win32" === platform) return [
53150
+ "try { irm https://anvil.works/install-cli.ps1 | iex } catch { npm install -g @anvil-works/anvil-cli@latest }",
53151
+ "curl -fsSL https://anvil.works/install-cli.cmd -o install.cmd && install.cmd && del install.cmd || npm install -g @anvil-works/anvil-cli@latest",
53152
+ "npm install -g @anvil-works/anvil-cli@latest",
53153
+ "pnpm add -g @anvil-works/anvil-cli@latest"
53154
+ ];
53155
+ return [
53156
+ "curl -fsSL https://anvil.works/install-cli.sh | sh || npm install -g @anvil-works/anvil-cli@latest",
53157
+ "npm install -g @anvil-works/anvil-cli@latest",
53158
+ "pnpm add -g @anvil-works/anvil-cli@latest"
53159
+ ];
53160
+ }
53033
53161
  async function handleUpdateCommand() {
53034
53162
  try {
53035
53163
  logger_logger.progress("update", "Checking for updates...");
@@ -53044,26 +53172,54 @@ var __webpack_exports__ = {};
53044
53172
  process.exit(1);
53045
53173
  }
53046
53174
  if (semver_default().eq(VERSION, latestVersion)) {
53047
- logger_logger.success(`You're already using the latest version: ${VERSION}`);
53048
- console.log();
53175
+ if (getGlobalOutputConfig().jsonMode) logJsonResult(true, {
53176
+ data: {
53177
+ currentVersion: VERSION,
53178
+ latestVersion,
53179
+ status: "up-to-date"
53180
+ }
53181
+ });
53182
+ else {
53183
+ logger_logger.success(`You're already using the latest version: ${VERSION}`);
53184
+ console.log();
53185
+ }
53049
53186
  return;
53050
53187
  }
53051
53188
  if (semver_default().gt(VERSION, latestVersion)) {
53052
- logger_logger.warn(`You're using version ${VERSION}, which is newer than the latest published version ${latestVersion}.`);
53053
- console.log(chalk_source.gray(" This might be a development build."));
53054
- console.log();
53189
+ if (getGlobalOutputConfig().jsonMode) logJsonResult(true, {
53190
+ data: {
53191
+ currentVersion: VERSION,
53192
+ latestVersion,
53193
+ status: "ahead",
53194
+ note: "This might be a development build."
53195
+ }
53196
+ });
53197
+ else {
53198
+ logger_logger.warn(`You're using version ${VERSION}, which is newer than the latest published version ${latestVersion}.`);
53199
+ console.log(chalk_source.gray(" This might be a development build."));
53200
+ console.log();
53201
+ }
53055
53202
  return;
53056
53203
  }
53204
+ const instructions = getUpdateInstructions(process.platform);
53205
+ if (getGlobalOutputConfig().jsonMode) return void logJsonResult(true, {
53206
+ data: {
53207
+ currentVersion: VERSION,
53208
+ latestVersion,
53209
+ status: "update-available",
53210
+ instructions
53211
+ }
53212
+ });
53057
53213
  logger_logger.warn(`↑ Update available: ${VERSION} → ${latestVersion}`);
53058
53214
  console.log();
53059
53215
  console.log(chalk_source.cyan("To update, run one of the following commands:"));
53060
53216
  console.log();
53061
53217
  if ("win32" === process.platform) {
53062
- console.log(chalk_source.gray(" PowerShell: ") + chalk_source.white("try { irm https://anvil.works/install-cli.ps1 | iex } catch { npm install -g @anvil-works/anvil-cli@latest }"));
53063
- console.log(chalk_source.gray(" CMD: ") + chalk_source.white("curl -fsSL https://anvil.works/install-cli.cmd -o install.cmd && install.cmd && del install.cmd || npm install -g @anvil-works/anvil-cli@latest"));
53064
- } else console.log(chalk_source.gray(" macOS/Linux: ") + chalk_source.white("curl -fsSL https://anvil.works/install-cli.sh | sh || npm install -g @anvil-works/anvil-cli@latest"));
53065
- console.log(chalk_source.gray(" npm: ") + chalk_source.white("npm install -g @anvil-works/anvil-cli@latest"));
53066
- console.log(chalk_source.gray(" pnpm: ") + chalk_source.white("pnpm add -g @anvil-works/anvil-cli@latest"));
53218
+ console.log(chalk_source.gray(" PowerShell: ") + chalk_source.white(instructions[0]));
53219
+ console.log(chalk_source.gray(" CMD: ") + chalk_source.white(instructions[1]));
53220
+ } else console.log(chalk_source.gray(" macOS/Linux: ") + chalk_source.white(instructions[0]));
53221
+ console.log(chalk_source.gray(" npm: ") + chalk_source.white(instructions[instructions.length - 2]));
53222
+ console.log(chalk_source.gray(" pnpm: ") + chalk_source.white(instructions[instructions.length - 1]));
53067
53223
  console.log();
53068
53224
  } catch (e) {
53069
53225
  logger_logger.error("Error: " + e.message);
@@ -53071,7 +53227,7 @@ var __webpack_exports__ = {};
53071
53227
  }
53072
53228
  }
53073
53229
  function addGlobalOptionsHelp(command) {
53074
- if ("help" !== command.name()) command.addHelpText("after", "\n" + chalk_source.bold("Global Options:") + "\n -V, --verbose Show detailed output\n");
53230
+ if ("help" !== command.name()) command.addHelpText("after", "\n" + chalk_source.bold("Global Options:") + "\n --json Output in JSON format (NDJSON) for scripting/LLM consumption\n -V, --verbose Show detailed output\n");
53075
53231
  command.commands.forEach((subcommand)=>addGlobalOptionsHelp(subcommand));
53076
53232
  }
53077
53233
  function buildProgram() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anvil-works/anvil-cli",
3
- "version": "0.5.9",
3
+ "version": "0.5.10",
4
4
  "description": "CLI tool for developing Anvil apps locally",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",