aiupdate 0.1.6 → 0.2.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 (3) hide show
  1. package/README.md +7 -0
  2. package/dist/cli.js +34 -7
  3. package/package.json +2 -1
package/README.md CHANGED
@@ -39,6 +39,13 @@ Each tool runs concurrently. After updating, aiupdate shows the version change (
39
39
 
40
40
  Tools not installed on your machine are silently skipped.
41
41
 
42
+ Tools installed with [mise](https://mise.jdx.dev/) are detected automatically and
43
+ updated with `mise upgrade <package> --yes` instead of their built-in updater.
44
+ This supports direct mise installations, npm backends, and mise shims. Upgrades
45
+ respect the version range in your mise configuration; pinned versions stay pinned.
46
+ Packages installed globally with npm under a mise-managed Node.js installation
47
+ continue to use their built-in updater.
48
+
42
49
  ## Contributing
43
50
 
44
51
  To add a new tool, use the `/add-agent` skill in Claude Code — it walks through verification, adds the entry to `AI_TOOLS`, builds, and commits.
package/dist/cli.js CHANGED
@@ -29,9 +29,9 @@ async function defaultChecker(command) {
29
29
  return false;
30
30
  }
31
31
  }
32
- async function getVersion(command) {
32
+ async function getVersion(command, args = ["--version"]) {
33
33
  try {
34
- const { stdout, stderr } = await execa(command, ["--version"]);
34
+ const { stdout, stderr } = await execa(command, args);
35
35
  const match = `${stdout}
36
36
  ${stderr}`.match(/\d+\.\d+\.\d+/);
37
37
  return match ? match[0] : null;
@@ -39,6 +39,31 @@ ${stderr}`.match(/\d+\.\d+\.\d+/);
39
39
  return null;
40
40
  }
41
41
  }
42
+ async function resolveUpdate(tool) {
43
+ if (!tool.versioned) return tool;
44
+ try {
45
+ const [binary, managedBinary, owner] = await Promise.all([
46
+ execa("which", [tool.command]),
47
+ execa("mise", ["which", tool.command]),
48
+ execa("mise", ["which", tool.command, "--plugin"])
49
+ ]);
50
+ const packageName = owner.stdout.trim();
51
+ if (!packageName || ["node", "bun", "deno"].includes(packageName.replace(/^.*:/, ""))) return tool;
52
+ const actualPath = realpathSync(binary.stdout.trim());
53
+ if (actualPath !== realpathSync(managedBinary.stdout.trim())) {
54
+ const mise = await execa("which", ["mise"]);
55
+ if (actualPath !== realpathSync(mise.stdout.trim())) return tool;
56
+ }
57
+ return {
58
+ command: "mise",
59
+ args: ["upgrade", packageName, "--yes"],
60
+ // Upgrade can remove the old installation still present in our PATH.
61
+ versionArgs: ["exec", packageName, "--", tool.command, "--version"]
62
+ };
63
+ } catch {
64
+ return tool;
65
+ }
66
+ }
42
67
  function formatTitle(name, before, after) {
43
68
  if (!before) return name;
44
69
  return after && after !== before ? `${name} ${before} \u2192 ${after}` : `${name} up to date (${after ?? before})`;
@@ -52,7 +77,7 @@ function selectTools(targetArgs) {
52
77
  }
53
78
  async function run(targetArgs, executor = async (cmd, args) => {
54
79
  await execa(cmd, args);
55
- }, checker = defaultChecker, versioner = getVersion, logger = (message) => console.error(message)) {
80
+ }, checker = defaultChecker, versioner = getVersion, logger = (message) => console.error(message), updateResolver = resolveUpdate) {
56
81
  const { selectedAITools, includeSkills } = selectTools(targetArgs);
57
82
  const toolsToCheck = includeSkills ? [...selectedAITools, SKILLS_TASK] : selectedAITools;
58
83
  const checks = await Promise.all(
@@ -64,17 +89,19 @@ async function run(targetArgs, executor = async (cmd, args) => {
64
89
  allTools.map((tool) => ({
65
90
  title: tool.name,
66
91
  task: async (_, task) => {
67
- const before = tool.versioned ? await versioner(tool.command) : null;
92
+ const update = await updateResolver(tool);
93
+ const versionCommand = update.versionArgs ? update.command : tool.command;
94
+ const before = tool.versioned ? await versioner(versionCommand, update.versionArgs) : null;
68
95
  try {
69
- await executor(tool.command, tool.args);
96
+ await executor(update.command, update.args);
70
97
  } catch (err) {
71
98
  const e = err;
72
- const message = e.stderr || e.shortMessage || String(e);
99
+ const message = String(e.stderr || e.shortMessage || e);
73
100
  failures.push({ name: tool.name, message });
74
101
  throw new Error(message);
75
102
  }
76
103
  if (before) {
77
- const after = await versioner(tool.command);
104
+ const after = await versioner(versionCommand, update.versionArgs);
78
105
  task.title = formatTitle(tool.name, before, after);
79
106
  }
80
107
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiupdate",
3
- "version": "0.1.6",
3
+ "version": "0.2.0",
4
4
  "description": "Update all your AI agent CLIs and skills concurrently",
5
5
  "type": "module",
6
6
  "bin": {
@@ -20,6 +20,7 @@
20
20
  "listr2": "^10.0.0"
21
21
  },
22
22
  "devDependencies": {
23
+ "@types/node": "^24.19.2",
23
24
  "tsup": "^8.0.0",
24
25
  "tsx": "^4.0.0",
25
26
  "typescript": "^5.0.0",