@rubytech/taskmaster 1.0.54 → 1.0.55

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.54",
2
+ "version": "1.0.55",
3
3
  "commit": "2a1c2ac37038aee2573fee7b793fe2bd24823740",
4
- "builtAt": "2026-02-17T18:13:05.512Z"
4
+ "builtAt": "2026-02-17T18:23:51.217Z"
5
5
  }
@@ -76,10 +76,11 @@ export async function detectGlobalInstallManagerByPresence(runCommand, timeoutMs
76
76
  return "bun";
77
77
  return null;
78
78
  }
79
- export function globalInstallArgs(manager, spec) {
79
+ export function globalInstallArgs(manager, spec, needsSudo = false) {
80
+ const prefix = needsSudo ? ["sudo"] : [];
80
81
  if (manager === "pnpm")
81
- return ["pnpm", "add", "-g", spec];
82
+ return [...prefix, "pnpm", "add", "-g", spec];
82
83
  if (manager === "bun")
83
- return ["bun", "add", "-g", spec];
84
- return ["npm", "i", "-g", spec];
84
+ return [...prefix, "bun", "add", "-g", spec];
85
+ return [...prefix, "npm", "i", "-g", spec];
85
86
  }
@@ -4,7 +4,7 @@ import path from "node:path";
4
4
  import { runCommandWithTimeout } from "../process/exec.js";
5
5
  import { compareSemverStrings } from "./update-check.js";
6
6
  import { DEV_BRANCH, isBetaTag, isStableTag } from "./update-channels.js";
7
- import { detectGlobalInstallManagerForRoot, globalInstallArgs } from "./update-global.js";
7
+ import { detectGlobalInstallManagerForRoot, globalInstallArgs, resolveGlobalRoot, } from "./update-global.js";
8
8
  import { trimLogTail } from "./restart-sentinel.js";
9
9
  const DEFAULT_TIMEOUT_MS = 20 * 60_000;
10
10
  const MAX_LOG_CHARS = 8000;
@@ -439,11 +439,24 @@ export async function runGatewayUpdate(opts = {}) {
439
439
  const beforeVersion = await readPackageVersion(pkgRoot);
440
440
  const globalManager = await detectGlobalInstallManagerForRoot(runCommand, pkgRoot, timeoutMs);
441
441
  if (globalManager) {
442
+ // Check if the global prefix is writable — if not, use sudo (common on Linux/Pi)
443
+ let needsSudo = false;
444
+ if (os.platform() !== "win32") {
445
+ const globalRoot = await resolveGlobalRoot(globalManager, runCommand, timeoutMs);
446
+ if (globalRoot) {
447
+ try {
448
+ await fs.access(globalRoot, fs.constants.W_OK);
449
+ }
450
+ catch {
451
+ needsSudo = true;
452
+ }
453
+ }
454
+ }
442
455
  const spec = `@rubytech/taskmaster@${normalizeTag(opts.tag)}`;
443
456
  const updateStep = await runStep({
444
457
  runCommand,
445
458
  name: "global update",
446
- argv: globalInstallArgs(globalManager, spec),
459
+ argv: globalInstallArgs(globalManager, spec, needsSudo),
447
460
  cwd: pkgRoot,
448
461
  timeoutMs,
449
462
  env: { PATH: augmentedPath },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/taskmaster",
3
- "version": "1.0.54",
3
+ "version": "1.0.55",
4
4
  "description": "AI-powered business assistant for small businesses",
5
5
  "publishConfig": {
6
6
  "access": "public"