@atlashub/smartstack-cli 4.62.0 → 4.64.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.
package/dist/index.js CHANGED
@@ -127429,6 +127429,67 @@ var import_cli_table34 = __toESM(require_cli_table3());
127429
127429
  var import_child_process8 = require("child_process");
127430
127430
  var import_fs_extra13 = __toESM(require_lib());
127431
127431
  var import_path13 = require("path");
127432
+ function detectPackageManager() {
127433
+ const tryCmd = (cmd) => {
127434
+ try {
127435
+ (0, import_child_process8.execSync)(`${cmd} --version`, { encoding: "utf-8", timeout: 5e3, stdio: "pipe" });
127436
+ return true;
127437
+ } catch {
127438
+ return false;
127439
+ }
127440
+ };
127441
+ if (process.platform === "win32" && tryCmd("winget")) return "winget";
127442
+ if (process.platform === "darwin" && tryCmd("brew")) return "brew";
127443
+ if (process.platform === "linux") {
127444
+ if (tryCmd("apt")) return "apt";
127445
+ if (tryCmd("dnf")) return "dnf";
127446
+ if (tryCmd("pacman")) return "pacman";
127447
+ }
127448
+ return null;
127449
+ }
127450
+ function getInstallCmd(pm, info) {
127451
+ if (!pm) return void 0;
127452
+ return info[pm];
127453
+ }
127454
+ function resolvePodmanCmd() {
127455
+ try {
127456
+ (0, import_child_process8.execSync)("podman --version", { encoding: "utf-8", timeout: 5e3, stdio: "pipe" });
127457
+ return "podman";
127458
+ } catch {
127459
+ }
127460
+ if (process.platform === "win32") {
127461
+ const knownPaths = [
127462
+ "C:\\Program Files\\RedHat\\Podman\\podman.exe",
127463
+ (0, import_path13.join)(process.env.LOCALAPPDATA || "", "RedHat", "Podman", "podman.exe")
127464
+ ];
127465
+ for (const p of knownPaths) {
127466
+ if (require("fs").existsSync(p)) return `"${p}"`;
127467
+ }
127468
+ }
127469
+ return "podman";
127470
+ }
127471
+ function getContainerEngineStatus() {
127472
+ try {
127473
+ const dockerVer = (0, import_child_process8.execSync)("docker --version", { encoding: "utf-8", timeout: 5e3, stdio: "pipe" }).trim();
127474
+ const dockerInfo = (() => {
127475
+ try {
127476
+ (0, import_child_process8.execSync)("docker info", { encoding: "utf-8", timeout: 1e4, stdio: "pipe" });
127477
+ return true;
127478
+ } catch {
127479
+ return false;
127480
+ }
127481
+ })();
127482
+ return { name: "Docker", version: dockerVer.replace("Docker version ", "").split(",")[0], running: dockerInfo };
127483
+ } catch {
127484
+ }
127485
+ try {
127486
+ const podmanCmd = resolvePodmanCmd();
127487
+ const podmanVer = (0, import_child_process8.execSync)(`${podmanCmd} --version`, { encoding: "utf-8", timeout: 5e3, stdio: "pipe" }).trim();
127488
+ return { name: "Podman", version: podmanVer.replace("podman version ", ""), running: true };
127489
+ } catch {
127490
+ }
127491
+ return null;
127492
+ }
127432
127493
  function getNodeVersion() {
127433
127494
  return process.version;
127434
127495
  }
@@ -127468,9 +127529,10 @@ function getNpmVersion() {
127468
127529
  return null;
127469
127530
  }
127470
127531
  }
127471
- var doctorCommand = new Command("doctor").description("Run diagnostics and check SmartStack health").option("--json", "Output as JSON").option("-v, --verbose", "Show detailed information").action(async (options) => {
127532
+ var doctorCommand = new Command("doctor").description("Run diagnostics and check SmartStack health").option("--json", "Output as JSON").option("-v, --verbose", "Show detailed information").option("--fix", "Auto-install missing tools using system package manager").action(async (options) => {
127472
127533
  const diagnostics = [];
127473
127534
  const pkg2 = JSON.parse(await import_fs_extra13.default.readFile((0, import_path13.join)(__dirname, "..", "package.json"), "utf-8"));
127535
+ const pm = options.fix ? detectPackageManager() : null;
127474
127536
  if (!options.json) {
127475
127537
  console.log(source_default.cyan(`
127476
127538
  \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
@@ -127559,7 +127621,14 @@ var doctorCommand = new Command("doctor").description("Run diagnostics and check
127559
127621
  name: "Git",
127560
127622
  status: gitVersion ? "ok" : "error",
127561
127623
  message: gitVersion || "Not installed",
127562
- fix: !gitVersion ? "Install Git: https://git-scm.com/" : void 0
127624
+ fix: !gitVersion ? "Install Git: https://git-scm.com/" : void 0,
127625
+ installCmd: !gitVersion ? getInstallCmd(pm, {
127626
+ winget: "winget install -e --id Git.Git",
127627
+ brew: "brew install git",
127628
+ apt: "sudo apt install -y git",
127629
+ dnf: "sudo dnf install -y git",
127630
+ pacman: "sudo pacman -S --noconfirm git"
127631
+ }) : void 0
127563
127632
  });
127564
127633
  const dotnetVersion = getDotNetVersion();
127565
127634
  diagnostics.push({
@@ -127567,8 +127636,51 @@ var doctorCommand = new Command("doctor").description("Run diagnostics and check
127567
127636
  status: dotnetVersion ? "ok" : "warning",
127568
127637
  message: dotnetVersion || "Not installed",
127569
127638
  details: !dotnetVersion ? "Required for .NET projects" : void 0,
127570
- fix: !dotnetVersion ? "Install .NET SDK: https://dotnet.microsoft.com/" : void 0
127639
+ fix: !dotnetVersion ? "Install .NET SDK: https://dotnet.microsoft.com/" : void 0,
127640
+ installCmd: !dotnetVersion ? getInstallCmd(pm, {
127641
+ winget: "winget install -e --id Microsoft.DotNet.SDK.9",
127642
+ brew: "brew install dotnet",
127643
+ apt: "sudo apt install -y dotnet-sdk-9.0",
127644
+ dnf: "sudo dnf install -y dotnet-sdk-9.0"
127645
+ }) : void 0
127571
127646
  });
127647
+ const containerEngine = getContainerEngineStatus();
127648
+ if (containerEngine && containerEngine.running) {
127649
+ diagnostics.push({
127650
+ name: "Container Engine",
127651
+ status: "ok",
127652
+ message: `${containerEngine.name} ${containerEngine.version}`
127653
+ });
127654
+ } else if (containerEngine && !containerEngine.running) {
127655
+ diagnostics.push({
127656
+ name: "Container Engine",
127657
+ status: "warning",
127658
+ message: `${containerEngine.name} installed but daemon not running`,
127659
+ fix: "Start Docker Desktop, or install Podman (daemonless)",
127660
+ installCmd: getInstallCmd(pm, {
127661
+ winget: "winget install -e --id RedHat.Podman",
127662
+ brew: "brew install podman",
127663
+ apt: "sudo apt install -y podman",
127664
+ dnf: "sudo dnf install -y podman",
127665
+ pacman: "sudo pacman -S --noconfirm podman"
127666
+ })
127667
+ });
127668
+ } else {
127669
+ diagnostics.push({
127670
+ name: "Container Engine",
127671
+ status: "warning",
127672
+ message: "Not installed (Docker or Podman)",
127673
+ details: "Required for ss docker commands",
127674
+ fix: "Install Docker Desktop or Podman",
127675
+ installCmd: getInstallCmd(pm, {
127676
+ winget: "winget install -e --id RedHat.Podman",
127677
+ brew: "brew install podman",
127678
+ apt: "sudo apt install -y podman",
127679
+ dnf: "sudo dnf install -y podman",
127680
+ pacman: "sudo pacman -S --noconfirm podman"
127681
+ })
127682
+ });
127683
+ }
127572
127684
  const claudeInstalled = isClaudeCodeInstalled();
127573
127685
  const claudeVersion = getClaudeCodeVersion();
127574
127686
  diagnostics.push({
@@ -127585,7 +127697,8 @@ var doctorCommand = new Command("doctor").description("Run diagnostics and check
127585
127697
  status: server.installed ? "ok" : "error",
127586
127698
  message: server.installed ? "Available" : "Not installed",
127587
127699
  details: server.description,
127588
- fix: !server.installed ? server.installCommand : void 0
127700
+ fix: !server.installed ? server.installCommand : void 0,
127701
+ installCmd: !server.installed ? server.installCommand : void 0
127589
127702
  });
127590
127703
  }
127591
127704
  } else {
@@ -127701,12 +127814,57 @@ ${source_default.gray(item.details)}`;
127701
127814
  if (errorCount > 0) console.log(` ${source_default.red("\u2717")} ${errorCount} Errors`);
127702
127815
  console.log();
127703
127816
  const itemsWithFixes = diagnostics.filter((d) => d.fix && (d.status === "error" || d.status === "warning"));
127704
- if (itemsWithFixes.length > 0) {
127817
+ if (itemsWithFixes.length > 0 && !options.fix) {
127705
127818
  console.log(source_default.bold("Recommended fixes:"));
127706
127819
  for (const item of itemsWithFixes) {
127707
127820
  console.log(` ${item.name}: ${source_default.cyan(item.fix)}`);
127708
127821
  }
127709
127822
  console.log();
127823
+ const fixableCount = diagnostics.filter((d) => d.installCmd).length;
127824
+ if (fixableCount > 0) {
127825
+ console.log(source_default.gray(` Tip: Run ${source_default.cyan("ss doctor --fix")} to auto-install ${fixableCount} missing tool(s)`));
127826
+ console.log();
127827
+ }
127828
+ }
127829
+ if (options.fix) {
127830
+ const fixable = diagnostics.filter((d) => d.installCmd && (d.status === "error" || d.status === "warning"));
127831
+ if (fixable.length === 0) {
127832
+ console.log(source_default.green("Nothing to fix \u2014 all installable tools are present."));
127833
+ console.log();
127834
+ } else if (!pm) {
127835
+ logger.error("No supported package manager found (winget, brew, apt, dnf, pacman).");
127836
+ console.log(` Please install the missing tools manually.`);
127837
+ console.log();
127838
+ } else {
127839
+ console.log(source_default.bold(`Auto-fix using ${source_default.cyan(pm)}:`));
127840
+ console.log();
127841
+ let fixed = 0;
127842
+ for (const item of fixable) {
127843
+ console.log(` ${source_default.yellow("Installing")} ${item.name}: ${source_default.gray(item.installCmd)}`);
127844
+ try {
127845
+ (0, import_child_process8.execSync)(item.installCmd, { encoding: "utf-8", stdio: "inherit", timeout: 3e5 });
127846
+ console.log(` ${source_default.green("\u2713")} ${item.name} installed`);
127847
+ fixed++;
127848
+ } catch (err) {
127849
+ const stderr = err.stderr || "";
127850
+ const stdout = err.stdout || "";
127851
+ const output = stderr + stdout;
127852
+ const alreadyInstalled = /already installed|déjà.*install|no applicable update|introuvable/i.test(output);
127853
+ if (alreadyInstalled) {
127854
+ console.log(` ${source_default.green("\u2713")} ${item.name} already installed (restart terminal if not detected)`);
127855
+ fixed++;
127856
+ } else {
127857
+ console.log(` ${source_default.red("\u2717")} ${item.name} install failed \u2014 try manually: ${source_default.cyan(item.installCmd)}`);
127858
+ }
127859
+ }
127860
+ console.log();
127861
+ }
127862
+ console.log(source_default.bold(`Fixed: ${fixed}/${fixable.length}`));
127863
+ if (fixed > 0) {
127864
+ console.log(source_default.gray(" Restart your terminal, then run ss doctor to verify."));
127865
+ }
127866
+ console.log();
127867
+ }
127710
127868
  }
127711
127869
  if (errorCount === 0) {
127712
127870
  logger.box([
@@ -129971,29 +130129,63 @@ tmuxCommand.command("status").description("Show WSL development environment stat
129971
130129
  var import_child_process12 = require("child_process");
129972
130130
  var import_path18 = require("path");
129973
130131
  var import_fs_extra16 = __toESM(require_lib());
130132
+ function resolveEngineCmd(name) {
130133
+ try {
130134
+ const result = (0, import_child_process12.spawnSync)(name, ["--version"], {
130135
+ encoding: "utf-8",
130136
+ shell: true,
130137
+ timeout: 5e3,
130138
+ stdio: "pipe"
130139
+ });
130140
+ if (result.status === 0) return name;
130141
+ } catch {
130142
+ }
130143
+ if (process.platform === "win32" && name === "podman") {
130144
+ const knownPaths = [
130145
+ "C:\\Program Files\\RedHat\\Podman\\podman.exe",
130146
+ (0, import_path18.join)(process.env.LOCALAPPDATA || "", "RedHat", "Podman", "podman.exe")
130147
+ ];
130148
+ for (const p of knownPaths) {
130149
+ if (import_fs_extra16.default.existsSync(p)) {
130150
+ try {
130151
+ const result = (0, import_child_process12.spawnSync)(`"${p}"`, ["--version"], {
130152
+ encoding: "utf-8",
130153
+ shell: true,
130154
+ timeout: 5e3,
130155
+ stdio: "pipe"
130156
+ });
130157
+ if (result.status === 0) return `"${p}"`;
130158
+ } catch {
130159
+ }
130160
+ }
130161
+ }
130162
+ }
130163
+ return name;
130164
+ }
129974
130165
  function checkEngine(name) {
130166
+ const cmd = resolveEngineCmd(name);
129975
130167
  try {
129976
- const version2 = (0, import_child_process12.spawnSync)(name, ["--version"], {
130168
+ const version2 = (0, import_child_process12.spawnSync)(cmd, ["--version"], {
129977
130169
  encoding: "utf-8",
129978
130170
  shell: true,
129979
130171
  timeout: 5e3,
129980
130172
  stdio: "pipe"
129981
130173
  });
129982
130174
  if (version2.status !== 0) {
129983
- return { name, installed: false, running: false };
130175
+ return { name, installed: false, running: false, cmd };
129984
130176
  }
129985
130177
  if (name === "podman") {
129986
- return { name, installed: true, running: true };
130178
+ return { name, installed: true, running: true, cmd };
129987
130179
  }
129988
- const info = (0, import_child_process12.spawnSync)(name, ["info"], {
130180
+ const info = (0, import_child_process12.spawnSync)(cmd, ["info"], {
129989
130181
  encoding: "utf-8",
129990
130182
  shell: true,
129991
130183
  timeout: 1e4,
129992
130184
  stdio: "pipe"
129993
130185
  });
129994
- return { name, installed: true, running: info.status === 0 };
130186
+ return { name, installed: true, running: info.status === 0, cmd };
129995
130187
  } catch {
129996
- return { name, installed: false, running: false };
130188
+ return { name, installed: false, running: false, cmd };
129997
130189
  }
129998
130190
  }
129999
130191
  function detectEngine() {
@@ -130044,7 +130236,7 @@ function requireComposeFile() {
130044
130236
  return composePath;
130045
130237
  }
130046
130238
  function runCompose(engine, composePath, args) {
130047
- const result = (0, import_child_process12.spawnSync)(engine.name, ["compose", "-f", composePath, ...args], {
130239
+ const result = (0, import_child_process12.spawnSync)(engine.cmd, ["compose", "-f", composePath, ...args], {
130048
130240
  encoding: "utf-8",
130049
130241
  shell: true,
130050
130242
  stdio: "inherit",