taskplane 0.25.3 → 0.25.4
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.
|
@@ -359,11 +359,14 @@ export default function (pi: ExtensionAPI) {
|
|
|
359
359
|
/**
|
|
360
360
|
* Resolve the Pi CLI entrypoint path (same logic as agent-host.ts).
|
|
361
361
|
*/
|
|
362
|
+
let _npmRootCache: string | null = null;
|
|
362
363
|
function getNpmGlobalRoot(): string {
|
|
364
|
+
if (_npmRootCache !== null) return _npmRootCache;
|
|
363
365
|
try {
|
|
364
366
|
const result = spawnSync("npm", ["root", "-g"], { encoding: "utf-8", timeout: 5000, shell: true });
|
|
365
|
-
|
|
366
|
-
} catch {
|
|
367
|
+
_npmRootCache = result.stdout?.trim() || "";
|
|
368
|
+
} catch { _npmRootCache = ""; }
|
|
369
|
+
return _npmRootCache;
|
|
367
370
|
}
|
|
368
371
|
|
|
369
372
|
function resolvePiCli(): string {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* @since TP-104
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
import { spawn, type ChildProcess } from "child_process";
|
|
23
|
+
import { spawn, spawnSync, type ChildProcess } from "child_process";
|
|
24
24
|
import {
|
|
25
25
|
readFileSync, writeFileSync, appendFileSync, mkdirSync,
|
|
26
26
|
existsSync, readdirSync, renameSync,
|
|
@@ -55,46 +55,54 @@ import { appendMailboxAuditEvent } from "./mailbox.ts";
|
|
|
55
55
|
* with `shell: false`. This function resolves the underlying JS file.
|
|
56
56
|
*
|
|
57
57
|
* Resolution order:
|
|
58
|
-
* 1.
|
|
59
|
-
* 2.
|
|
60
|
-
* 3. /
|
|
58
|
+
* 1. npm root -g (dynamic — covers nvm, Homebrew, volta, custom prefix)
|
|
59
|
+
* 2. APPDATA/npm/node_modules/... (Windows)
|
|
60
|
+
* 3. HOME/.npm-global/lib/node_modules/...
|
|
61
|
+
* 4. /usr/local/lib/node_modules/...
|
|
62
|
+
* 5. /opt/homebrew/lib/node_modules/... (macOS Homebrew)
|
|
61
63
|
*
|
|
62
64
|
* @returns Absolute path to the Pi CLI JS entrypoint
|
|
63
65
|
* @throws Error if Pi CLI cannot be found
|
|
64
66
|
*
|
|
65
67
|
* @since TP-104
|
|
66
68
|
*/
|
|
69
|
+
let _npmGlobalRootCache: string | null = null;
|
|
70
|
+
function getNpmGlobalRoot(): string {
|
|
71
|
+
if (_npmGlobalRootCache !== null) return _npmGlobalRootCache;
|
|
72
|
+
try {
|
|
73
|
+
const result = spawnSync("npm", ["root", "-g"], { encoding: "utf-8", timeout: 5000, shell: true });
|
|
74
|
+
_npmGlobalRootCache = result.stdout?.trim() || "";
|
|
75
|
+
} catch {
|
|
76
|
+
_npmGlobalRootCache = "";
|
|
77
|
+
}
|
|
78
|
+
return _npmGlobalRootCache;
|
|
79
|
+
}
|
|
80
|
+
|
|
67
81
|
export function resolvePiCliPath(): string {
|
|
68
|
-
const relPath = join("
|
|
82
|
+
const relPath = join("@mariozechner", "pi-coding-agent", "dist", "cli.js");
|
|
69
83
|
const candidates: string[] = [];
|
|
70
84
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
85
|
+
// Dynamic first: covers nvm, Homebrew, volta, custom npm prefix
|
|
86
|
+
const npmRoot = getNpmGlobalRoot();
|
|
87
|
+
if (npmRoot) candidates.push(join(npmRoot, relPath));
|
|
88
|
+
|
|
89
|
+
// Well-known static fallbacks
|
|
74
90
|
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
91
|
+
if (process.env.APPDATA) candidates.push(join(process.env.APPDATA, "npm", "node_modules", relPath));
|
|
75
92
|
if (home) {
|
|
76
|
-
candidates.push(join(home, "AppData", "Roaming", "npm", relPath));
|
|
77
|
-
candidates.push(join(home, ".npm-global", "lib", relPath));
|
|
93
|
+
candidates.push(join(home, "AppData", "Roaming", "npm", "node_modules", relPath));
|
|
94
|
+
candidates.push(join(home, ".npm-global", "lib", "node_modules", relPath));
|
|
78
95
|
}
|
|
79
|
-
candidates.push(join("/usr", "local", "lib", relPath));
|
|
80
|
-
candidates.push(join("/opt", "homebrew", "lib", relPath));
|
|
81
|
-
|
|
82
|
-
// Dynamic: npm root -g
|
|
83
|
-
try {
|
|
84
|
-
const { spawnSync } = require("child_process");
|
|
85
|
-
const result = spawnSync("npm", ["root", "-g"], { encoding: "utf-8", timeout: 5000, shell: true });
|
|
86
|
-
if (result.stdout?.trim()) {
|
|
87
|
-
candidates.push(join(result.stdout.trim(), "@mariozechner", "pi-coding-agent", "dist", "cli.js"));
|
|
88
|
-
}
|
|
89
|
-
} catch { /* ignore */ }
|
|
96
|
+
candidates.push(join("/usr", "local", "lib", "node_modules", relPath));
|
|
97
|
+
candidates.push(join("/opt", "homebrew", "lib", "node_modules", relPath));
|
|
90
98
|
|
|
91
99
|
for (const candidate of candidates) {
|
|
92
100
|
if (existsSync(candidate)) return candidate;
|
|
93
101
|
}
|
|
94
102
|
|
|
95
103
|
throw new Error(
|
|
96
|
-
"Cannot find Pi CLI entrypoint (cli.js). Ensure pi is installed globally. " +
|
|
97
|
-
`
|
|
104
|
+
"Cannot find Pi CLI entrypoint (cli.js). Ensure pi is installed globally via 'pi install'. " +
|
|
105
|
+
`npm root -g: ${npmRoot || "(not found)"}`,
|
|
98
106
|
);
|
|
99
107
|
}
|
|
100
108
|
|