@agentprojectcontext/apx 1.15.2 → 1.15.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentprojectcontext/apx",
3
- "version": "1.15.2",
3
+ "version": "1.15.3",
4
4
  "description": "APX — unified CLI + daemon for the Agent Project Context (APC) standard.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -4,6 +4,29 @@ import { getLatestVersion } from "../../core/update-check.js";
4
4
 
5
5
  const PACKAGE_NAME = "@agentprojectcontext/apx";
6
6
 
7
+ function isNewer(cur, lat) {
8
+ const parse = (v) => v.replace(/^v/, "").split(".").map(Number);
9
+ const [ma, mi, pa] = parse(cur);
10
+ const [mb, mib, pb] = parse(lat);
11
+ if (mb > ma) return true;
12
+ if (mb === ma && mib > mi) return true;
13
+ if (mb === ma && mib === mi && pb > pa) return true;
14
+ return false;
15
+ }
16
+
17
+ function hasPnpmGlobal() {
18
+ const r = spawnSync("pnpm", ["--version"], { encoding: "utf8", stdio: "pipe" });
19
+ if (r.status !== 0) return false;
20
+ // pnpm needs PNPM_HOME configured to manage global packages
21
+ const check = spawnSync("pnpm", ["root", "-g"], { encoding: "utf8", stdio: "pipe" });
22
+ return check.status === 0 && !!check.stdout?.trim();
23
+ }
24
+
25
+ function daemonRunning() {
26
+ const r = spawnSync("apx", ["daemon", "status", "--json"], { encoding: "utf8", stdio: "pipe" });
27
+ try { return JSON.parse(r.stdout)?.running === true; } catch { return false; }
28
+ }
29
+
7
30
  export async function cmdUpdate(args, currentVersion) {
8
31
  const force = args.flags.force || args.flags.yes || args.flags.y;
9
32
 
@@ -15,24 +38,12 @@ export async function cmdUpdate(args, currentVersion) {
15
38
  process.exit(1);
16
39
  }
17
40
 
18
- const current = currentVersion;
19
-
20
- function isNewer(cur, lat) {
21
- const parse = (v) => v.replace(/^v/, "").split(".").map(Number);
22
- const [ma, mi, pa] = parse(cur);
23
- const [mb, mib, pb] = parse(lat);
24
- if (mb > ma) return true;
25
- if (mb === ma && mib > mi) return true;
26
- if (mb === ma && mib === mi && pb > pa) return true;
27
- return false;
28
- }
29
-
30
- if (!isNewer(current, latest)) {
31
- console.log(`✅ Already up to date (${current})`);
41
+ if (!isNewer(currentVersion, latest)) {
42
+ console.log(`✅ Already up to date (${currentVersion})`);
32
43
  return;
33
44
  }
34
45
 
35
- console.log(`\n Current: ${current}`);
46
+ console.log(`\n Current: ${currentVersion}`);
36
47
  console.log(` Latest: ${latest}`);
37
48
 
38
49
  if (!force) {
@@ -43,20 +54,41 @@ export async function cmdUpdate(args, currentVersion) {
43
54
  }
44
55
  }
45
56
 
46
- console.log(`\nRunning: npm install -g ${PACKAGE_NAME}@${latest}\n`);
47
- const result = spawnSync(
48
- "npm",
49
- ["install", "-g", `${PACKAGE_NAME}@${latest}`],
50
- { stdio: "inherit" }
51
- );
57
+ // Stop daemon before replacing the binary so Node doesn't lock files on Windows.
58
+ const wasDaemonRunning = daemonRunning();
59
+ if (wasDaemonRunning) {
60
+ process.stdout.write("\nStopping daemon... ");
61
+ spawnSync("apx", ["daemon", "stop"], { stdio: "inherit" });
62
+ console.log("stopped.");
63
+ }
64
+
65
+ // Prefer pnpm global if configured, fall back to npm.
66
+ const usePnpm = hasPnpmGlobal();
67
+ const pm = usePnpm ? "pnpm" : "npm";
68
+ const installArgs = usePnpm
69
+ ? ["add", "-g", `${PACKAGE_NAME}@${latest}`]
70
+ : ["install", "-g", `${PACKAGE_NAME}@${latest}`];
71
+
72
+ console.log(`\nInstalling ${PACKAGE_NAME}@${latest} via ${pm}...\n`);
73
+ const result = spawnSync(pm, installArgs, { stdio: "inherit" });
52
74
 
53
75
  if (result.status !== 0) {
54
76
  console.error(`\n❌ Update failed (exit ${result.status})`);
77
+ if (wasDaemonRunning) {
78
+ console.log("Restarting daemon with old version...");
79
+ spawnSync("apx", ["daemon", "start"], { stdio: "inherit" });
80
+ }
55
81
  process.exit(result.status || 1);
56
82
  }
57
83
 
58
- console.log(`\n✅ Updated to ${latest}. Restart any running apx daemon:`);
59
- console.log(` apx daemon stop && apx daemon start`);
84
+ // Restart daemon with new version.
85
+ if (wasDaemonRunning) {
86
+ process.stdout.write("\nStarting daemon... ");
87
+ spawnSync("apx", ["daemon", "start"], { stdio: "inherit" });
88
+ console.log("done.");
89
+ }
90
+
91
+ console.log(`\n✅ Updated to ${latest}.`);
60
92
  }
61
93
 
62
94
  function confirm(prompt) {
@@ -176,7 +176,12 @@ export function installIdeSkills(root, targetIds = null) {
176
176
  return results;
177
177
  }
178
178
 
179
- // Install bundled APX/APC skills + runtime docs to global ~/.../skills/ dirs.
179
+ // Install bundled APX/APC skills to global ~/.../skills/ dirs.
180
+ // Only apx and apc-context are installed everywhere — they teach IDE tools
181
+ // (Claude Code, Cursor, Codex) about the APX CLI and APC project standard.
182
+ // Runtime CLI skills (claude-code, codex-cli, etc.) are APX-internal; APX
183
+ // loads them from src/daemon/runtime-skills/ at startup and does NOT push
184
+ // them to other tools' global skill dirs.
180
185
  // Returns an array of result objects with { dir, skill, status }.
181
186
  export function installGlobalSkills() {
182
187
  const results = [];
@@ -186,7 +191,8 @@ export function installGlobalSkills() {
186
191
  const apcRaw = readBundledSkill("apc-context");
187
192
  if (apxRaw) skills.push({ slug: "apx", md: apxRaw });
188
193
  if (apcRaw) skills.push({ slug: "apc-context", md: apcRaw });
189
- skills.push(...readRuntimeSkillFiles());
194
+ // Runtime skills (claude-code, codex-cli, opencode-cli, openrouter, …) are
195
+ // NOT included here — they are APX-only internals, not for IDE consumption.
190
196
 
191
197
  for (const base of GLOBAL_SKILL_DIRS) {
192
198
  for (const { slug, md } of skills) {