@caupulican/pi-adaptative 0.81.43 → 0.85.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/CHANGELOG.md +48 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +14 -8
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +14 -8
- package/dist/bundled-resources/skills/deduplicate-by-evidence/SKILL.md +7 -5
- package/dist/bundled-resources/skills/worker-profile-writer/SKILL.md +63 -0
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-paths.d.ts +1 -1
- package/dist/core/agent-paths.d.ts.map +1 -1
- package/dist/core/agent-paths.js +1 -1
- package/dist/core/agent-paths.js.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.js +4 -2
- package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +3 -0
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +6 -0
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/default-tool-surface.d.ts.map +1 -1
- package/dist/core/default-tool-surface.js +1 -0
- package/dist/core/default-tool-surface.js.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.d.ts +7 -0
- package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.js +28 -0
- package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
- package/dist/core/delegation/worker-profile-resolver.d.ts +2 -0
- package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -1
- package/dist/core/delegation/worker-profile-resolver.js +46 -11
- package/dist/core/delegation/worker-profile-resolver.js.map +1 -1
- package/dist/core/doctor.d.ts +5 -5
- package/dist/core/doctor.d.ts.map +1 -1
- package/dist/core/doctor.js +17 -20
- package/dist/core/doctor.js.map +1 -1
- package/dist/core/model-capability.d.ts.map +1 -1
- package/dist/core/model-capability.js +1 -0
- package/dist/core/model-capability.js.map +1 -1
- package/dist/core/orchestration/lane-tool-manifests.d.ts +1 -1
- package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -1
- package/dist/core/orchestration/lane-tool-manifests.js +6 -1
- package/dist/core/orchestration/lane-tool-manifests.js.map +1 -1
- package/dist/core/orchestration/session-task-profile-store.d.ts +31 -0
- package/dist/core/orchestration/session-task-profile-store.d.ts.map +1 -0
- package/dist/core/orchestration/session-task-profile-store.js +138 -0
- package/dist/core/orchestration/session-task-profile-store.js.map +1 -0
- package/dist/core/orchestration/task-profile-writer.d.ts +58 -0
- package/dist/core/orchestration/task-profile-writer.d.ts.map +1 -0
- package/dist/core/orchestration/task-profile-writer.js +165 -0
- package/dist/core/orchestration/task-profile-writer.js.map +1 -0
- package/dist/core/runtime-builder.d.ts +3 -1
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +14 -0
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/secrets/credential-exposure-guard.d.ts.map +1 -1
- package/dist/core/secrets/credential-exposure-guard.js +32 -0
- package/dist/core/secrets/credential-exposure-guard.js.map +1 -1
- package/dist/core/security/untrusted-boundary.d.ts.map +1 -1
- package/dist/core/security/untrusted-boundary.js +4 -6
- package/dist/core/security/untrusted-boundary.js.map +1 -1
- package/dist/core/session-role.d.ts.map +1 -1
- package/dist/core/session-role.js +1 -0
- package/dist/core/session-role.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +21 -22
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tool-capability-policy.js +1 -1
- package/dist/core/tool-capability-policy.js.map +1 -1
- package/dist/core/tools/bash.d.ts +1 -6
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +2 -26
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/delegate.js +4 -4
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +32 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +137 -69
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +22 -7
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +128 -55
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-intent.d.ts +70 -0
- package/dist/core/tools/file-mutation-intent.d.ts.map +1 -0
- package/dist/core/tools/file-mutation-intent.js +325 -0
- package/dist/core/tools/file-mutation-intent.js.map +1 -0
- package/dist/core/tools/goal.d.ts.map +1 -1
- package/dist/core/tools/goal.js +41 -18
- package/dist/core/tools/goal.js.map +1 -1
- package/dist/core/tools/index.d.ts +3 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +31 -8
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/profile-writer.d.ts +33 -0
- package/dist/core/tools/profile-writer.d.ts.map +1 -0
- package/dist/core/tools/profile-writer.js +67 -0
- package/dist/core/tools/profile-writer.js.map +1 -0
- package/dist/core/tools/task-steps.d.ts.map +1 -1
- package/dist/core/tools/task-steps.js +6 -11
- package/dist/core/tools/task-steps.js.map +1 -1
- package/dist/core/tools/tmux-dispatch.d.ts +2 -0
- package/dist/core/tools/tmux-dispatch.d.ts.map +1 -1
- package/dist/core/tools/tmux-dispatch.js +16 -2
- package/dist/core/tools/tmux-dispatch.js.map +1 -1
- package/dist/core/tools/write.d.ts +24 -7
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +182 -107
- package/dist/core/tools/write.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/jscpd-cli.d.ts +3 -0
- package/dist/jscpd-cli.d.ts.map +1 -0
- package/dist/jscpd-cli.js +22 -0
- package/dist/jscpd-cli.js.map +1 -0
- package/dist/modes/interactive/components/profile-resource-editor.js +2 -2
- package/dist/modes/interactive/components/profile-resource-editor.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +85 -3
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +3 -3
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/utils/bundled-jscpd.d.ts +20 -0
- package/dist/utils/bundled-jscpd.d.ts.map +1 -0
- package/dist/utils/bundled-jscpd.js +154 -0
- package/dist/utils/bundled-jscpd.js.map +1 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +11 -0
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/tools-manager.d.ts +6 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +81 -2
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/development.md +1 -1
- package/docs/index.md +3 -0
- package/docs/managed-data-tools.md +15 -0
- package/docs/quickstart.md +2 -2
- package/docs/tool-boundary-performance-roadmap-2026-08-02.md +166 -0
- package/docs/tool-repair.md +1 -1
- package/docs/windows.md +2 -2
- package/docs/work-directory.md +1 -1
- package/docs/worker-profiles.md +16 -0
- package/examples/extensions/built-in-tool-renderer.ts +12 -5
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/minimal-mode.ts +8 -7
- package/examples/extensions/prompt-customizer.ts +4 -2
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/ssh.ts +113 -24
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +123 -23
- package/package.json +8 -6
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const JSCPD_VERSION = "5.0.14";
|
|
2
|
+
type ModuleRequire = ((id: string) => unknown) & {
|
|
3
|
+
resolve?(id: string): string;
|
|
4
|
+
};
|
|
5
|
+
export interface BundledJscpdSource {
|
|
6
|
+
sourcePath: string;
|
|
7
|
+
sourceVersion: string;
|
|
8
|
+
}
|
|
9
|
+
export interface InstallBundledJscpdBinaryOptions extends BundledJscpdSource {
|
|
10
|
+
managedBinDir: string;
|
|
11
|
+
targetPlatform: string;
|
|
12
|
+
probeVersion?: (path: string) => string | undefined;
|
|
13
|
+
}
|
|
14
|
+
export declare function resolveJscpdPlatformPackage(targetPlatform: string, targetArchitecture: string, libc?: "glibc" | "musl"): string | undefined;
|
|
15
|
+
export declare function resolveBundledJscpdSource(targetPlatform?: string, targetArchitecture?: string, requires?: readonly ModuleRequire[]): BundledJscpdSource | undefined;
|
|
16
|
+
export declare function probeJscpdVersion(path: string): string | undefined;
|
|
17
|
+
export declare function installBundledJscpdBinary(options: InstallBundledJscpdBinaryOptions): string;
|
|
18
|
+
export declare function ensureManagedJscpd(managedBinDir?: string): string;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=bundled-jscpd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundled-jscpd.d.ts","sourceRoot":"","sources":["../../src/utils/bundled-jscpd.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,aAAa,WAAW,CAAC;AAEtC,KAAK,aAAa,GAAG,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG;IAAE,OAAO,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AAElF,MAAM,WAAW,kBAAkB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gCAAiC,SAAQ,kBAAkB;IAC3E,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CACpD;AAMD,wBAAgB,2BAA2B,CAC1C,cAAc,EAAE,MAAM,EACtB,kBAAkB,EAAE,MAAM,EAC1B,IAAI,GAAE,OAAO,GAAG,MAAgB,GAC9B,MAAM,GAAG,SAAS,CAepB;AAgCD,wBAAgB,yBAAyB,CACxC,cAAc,GAAE,MAAmB,EACnC,kBAAkB,GAAE,MAAe,EACnC,QAAQ,GAAE,SAAS,aAAa,EAA0C,GACxE,kBAAkB,GAAG,SAAS,CAWhC;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAalE;AAMD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gCAAgC,GAAG,MAAM,CA2C3F;AAED,wBAAgB,kBAAkB,CAAC,aAAa,GAAE,MAAoB,GAAG,MAAM,CA0B9E"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync } from "node:fs";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { arch, platform } from "node:os";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
import { pathToFileURL } from "node:url";
|
|
7
|
+
import { getBinDir } from "../config.js";
|
|
8
|
+
export const JSCPD_VERSION = "5.0.14";
|
|
9
|
+
const moduleRequire = createRequire(import.meta.url);
|
|
10
|
+
const executableDirRequire = createRequire(pathToFileURL(join(dirname(process.execPath), "package.json")).href);
|
|
11
|
+
let cachedManagedPath;
|
|
12
|
+
export function resolveJscpdPlatformPackage(targetPlatform, targetArchitecture, libc = "glibc") {
|
|
13
|
+
if (targetPlatform === "darwin" && (targetArchitecture === "arm64" || targetArchitecture === "x64")) {
|
|
14
|
+
return `jscpd-darwin-${targetArchitecture}`;
|
|
15
|
+
}
|
|
16
|
+
if (targetPlatform === "linux" && targetArchitecture === "x64") {
|
|
17
|
+
return libc === "musl" ? "jscpd-linux-x64-musl" : "jscpd-linux-x64-gnu";
|
|
18
|
+
}
|
|
19
|
+
if (targetPlatform === "linux" && targetArchitecture === "arm64" && libc === "glibc") {
|
|
20
|
+
return "jscpd-linux-arm64-gnu";
|
|
21
|
+
}
|
|
22
|
+
if (targetPlatform === "win32" && (targetArchitecture === "arm64" || targetArchitecture === "x64")) {
|
|
23
|
+
// Upstream publishes x64 only. Windows on Arm supports x64 application emulation.
|
|
24
|
+
return "jscpd-windows-x64-msvc";
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
function detectRuntimeLibc() {
|
|
29
|
+
if (platform() !== "linux")
|
|
30
|
+
return "glibc";
|
|
31
|
+
const report = process.report?.getReport();
|
|
32
|
+
return report?.header?.glibcVersionRuntime ? "glibc" : "musl";
|
|
33
|
+
}
|
|
34
|
+
function binaryName(targetPlatform) {
|
|
35
|
+
return targetPlatform === "win32" ? "jscpd.exe" : "jscpd";
|
|
36
|
+
}
|
|
37
|
+
function readSourceFromPackage(packageName, requires) {
|
|
38
|
+
for (const requireFrom of requires) {
|
|
39
|
+
try {
|
|
40
|
+
const packageJsonPath = requireFrom.resolve?.(`${packageName}/package.json`);
|
|
41
|
+
if (!packageJsonPath)
|
|
42
|
+
continue;
|
|
43
|
+
const manifest = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
44
|
+
const sourcePath = join(dirname(packageJsonPath), "bin", binaryName(platform()));
|
|
45
|
+
if (typeof manifest.version === "string" && existsSync(sourcePath)) {
|
|
46
|
+
return { sourcePath, sourceVersion: manifest.version };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// Try the next package-resolution root.
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
export function resolveBundledJscpdSource(targetPlatform = platform(), targetArchitecture = arch(), requires = [moduleRequire, executableDirRequire]) {
|
|
56
|
+
const standaloneBinary = join(dirname(process.execPath), "bundled-tools", binaryName(targetPlatform));
|
|
57
|
+
const standaloneVersion = join(dirname(process.execPath), "bundled-tools", "jscpd.version");
|
|
58
|
+
if (targetPlatform === platform() && existsSync(standaloneBinary) && existsSync(standaloneVersion)) {
|
|
59
|
+
return {
|
|
60
|
+
sourcePath: standaloneBinary,
|
|
61
|
+
sourceVersion: readFileSync(standaloneVersion, "utf8").trim(),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const packageName = resolveJscpdPlatformPackage(targetPlatform, targetArchitecture, detectRuntimeLibc());
|
|
65
|
+
return packageName ? readSourceFromPackage(packageName, requires) : undefined;
|
|
66
|
+
}
|
|
67
|
+
export function probeJscpdVersion(path) {
|
|
68
|
+
try {
|
|
69
|
+
const result = spawnSync(path, ["--version"], {
|
|
70
|
+
encoding: "utf8",
|
|
71
|
+
stdio: "pipe",
|
|
72
|
+
timeout: 5_000,
|
|
73
|
+
windowsHide: true,
|
|
74
|
+
});
|
|
75
|
+
if (result.error || result.status !== 0)
|
|
76
|
+
return undefined;
|
|
77
|
+
return `${result.stdout ?? ""}${result.stderr ?? ""}`.trim() || undefined;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function isExactVersion(output) {
|
|
84
|
+
return output?.split(/\s+/).includes(JSCPD_VERSION) === true;
|
|
85
|
+
}
|
|
86
|
+
export function installBundledJscpdBinary(options) {
|
|
87
|
+
if (options.sourceVersion !== JSCPD_VERSION) {
|
|
88
|
+
throw new Error(`Pi requires bundled jscpd ${JSCPD_VERSION}; found ${options.sourceVersion || "unknown"}.`);
|
|
89
|
+
}
|
|
90
|
+
const targetPath = join(options.managedBinDir, binaryName(options.targetPlatform));
|
|
91
|
+
const temporaryPath = join(options.managedBinDir, `.jscpd-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}${options.targetPlatform === "win32" ? ".exe" : ""}`);
|
|
92
|
+
mkdirSync(options.managedBinDir, { recursive: true });
|
|
93
|
+
const probeVersion = options.probeVersion ?? probeJscpdVersion;
|
|
94
|
+
let promoted = false;
|
|
95
|
+
try {
|
|
96
|
+
copyFileSync(options.sourcePath, temporaryPath);
|
|
97
|
+
if (options.targetPlatform !== "win32")
|
|
98
|
+
chmodSync(temporaryPath, 0o755);
|
|
99
|
+
const version = probeVersion(temporaryPath);
|
|
100
|
+
if (!isExactVersion(version)) {
|
|
101
|
+
throw new Error(`Pi requires bundled jscpd ${JSCPD_VERSION}; installed binary reported ${version ?? "no version"}.`);
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
renameSync(temporaryPath, targetPath);
|
|
105
|
+
promoted = true;
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// Concurrent sessions converge on the same exact binary. Windows cannot replace an
|
|
109
|
+
// existing executable with rename, so accept a valid winner without deleting it.
|
|
110
|
+
if (existsSync(targetPath) && isExactVersion(probeVersion(targetPath))) {
|
|
111
|
+
rmSync(temporaryPath, { force: true });
|
|
112
|
+
return targetPath;
|
|
113
|
+
}
|
|
114
|
+
rmSync(targetPath, { force: true });
|
|
115
|
+
renameSync(temporaryPath, targetPath);
|
|
116
|
+
promoted = true;
|
|
117
|
+
}
|
|
118
|
+
return targetPath;
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
rmSync(temporaryPath, { force: true });
|
|
122
|
+
if (promoted && !isExactVersion(probeVersion(targetPath)))
|
|
123
|
+
rmSync(targetPath, { force: true });
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
export function ensureManagedJscpd(managedBinDir = getBinDir()) {
|
|
128
|
+
const targetPath = join(managedBinDir, binaryName(platform()));
|
|
129
|
+
if (cachedManagedPath?.path === targetPath) {
|
|
130
|
+
try {
|
|
131
|
+
if (statSync(cachedManagedPath.path).mtimeMs === cachedManagedPath.mtimeMs)
|
|
132
|
+
return cachedManagedPath.path;
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
cachedManagedPath = undefined;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (existsSync(targetPath) && isExactVersion(probeJscpdVersion(targetPath))) {
|
|
139
|
+
cachedManagedPath = { path: targetPath, mtimeMs: statSync(targetPath).mtimeMs };
|
|
140
|
+
return targetPath;
|
|
141
|
+
}
|
|
142
|
+
const source = resolveBundledJscpdSource();
|
|
143
|
+
if (!source) {
|
|
144
|
+
throw new Error(`Bundled jscpd ${JSCPD_VERSION} is unavailable for ${platform()}/${arch()}. Reinstall Pi for this platform.`);
|
|
145
|
+
}
|
|
146
|
+
const installed = installBundledJscpdBinary({
|
|
147
|
+
...source,
|
|
148
|
+
managedBinDir,
|
|
149
|
+
targetPlatform: platform(),
|
|
150
|
+
});
|
|
151
|
+
cachedManagedPath = { path: installed, mtimeMs: statSync(installed).mtimeMs };
|
|
152
|
+
return installed;
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=bundled-jscpd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundled-jscpd.js","sourceRoot":"","sources":["../../src/utils/bundled-jscpd.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawnSync } from \"node:child_process\";\nimport { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { arch, platform } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { getBinDir } from \"../config.ts\";\n\nexport const JSCPD_VERSION = \"5.0.14\";\n\ntype ModuleRequire = ((id: string) => unknown) & { resolve?(id: string): string };\n\nexport interface BundledJscpdSource {\n\tsourcePath: string;\n\tsourceVersion: string;\n}\n\nexport interface InstallBundledJscpdBinaryOptions extends BundledJscpdSource {\n\tmanagedBinDir: string;\n\ttargetPlatform: string;\n\tprobeVersion?: (path: string) => string | undefined;\n}\n\nconst moduleRequire = createRequire(import.meta.url);\nconst executableDirRequire = createRequire(pathToFileURL(join(dirname(process.execPath), \"package.json\")).href);\nlet cachedManagedPath: { path: string; mtimeMs: number } | undefined;\n\nexport function resolveJscpdPlatformPackage(\n\ttargetPlatform: string,\n\ttargetArchitecture: string,\n\tlibc: \"glibc\" | \"musl\" = \"glibc\",\n): string | undefined {\n\tif (targetPlatform === \"darwin\" && (targetArchitecture === \"arm64\" || targetArchitecture === \"x64\")) {\n\t\treturn `jscpd-darwin-${targetArchitecture}`;\n\t}\n\tif (targetPlatform === \"linux\" && targetArchitecture === \"x64\") {\n\t\treturn libc === \"musl\" ? \"jscpd-linux-x64-musl\" : \"jscpd-linux-x64-gnu\";\n\t}\n\tif (targetPlatform === \"linux\" && targetArchitecture === \"arm64\" && libc === \"glibc\") {\n\t\treturn \"jscpd-linux-arm64-gnu\";\n\t}\n\tif (targetPlatform === \"win32\" && (targetArchitecture === \"arm64\" || targetArchitecture === \"x64\")) {\n\t\t// Upstream publishes x64 only. Windows on Arm supports x64 application emulation.\n\t\treturn \"jscpd-windows-x64-msvc\";\n\t}\n\treturn undefined;\n}\n\nfunction detectRuntimeLibc(): \"glibc\" | \"musl\" {\n\tif (platform() !== \"linux\") return \"glibc\";\n\tconst report = process.report?.getReport() as { header?: { glibcVersionRuntime?: string } } | undefined;\n\treturn report?.header?.glibcVersionRuntime ? \"glibc\" : \"musl\";\n}\n\nfunction binaryName(targetPlatform: string): string {\n\treturn targetPlatform === \"win32\" ? \"jscpd.exe\" : \"jscpd\";\n}\n\nfunction readSourceFromPackage(\n\tpackageName: string,\n\trequires: readonly ModuleRequire[],\n): BundledJscpdSource | undefined {\n\tfor (const requireFrom of requires) {\n\t\ttry {\n\t\t\tconst packageJsonPath = requireFrom.resolve?.(`${packageName}/package.json`);\n\t\t\tif (!packageJsonPath) continue;\n\t\t\tconst manifest = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as { version?: unknown };\n\t\t\tconst sourcePath = join(dirname(packageJsonPath), \"bin\", binaryName(platform()));\n\t\t\tif (typeof manifest.version === \"string\" && existsSync(sourcePath)) {\n\t\t\t\treturn { sourcePath, sourceVersion: manifest.version };\n\t\t\t}\n\t\t} catch {\n\t\t\t// Try the next package-resolution root.\n\t\t}\n\t}\n\treturn undefined;\n}\n\nexport function resolveBundledJscpdSource(\n\ttargetPlatform: string = platform(),\n\ttargetArchitecture: string = arch(),\n\trequires: readonly ModuleRequire[] = [moduleRequire, executableDirRequire],\n): BundledJscpdSource | undefined {\n\tconst standaloneBinary = join(dirname(process.execPath), \"bundled-tools\", binaryName(targetPlatform));\n\tconst standaloneVersion = join(dirname(process.execPath), \"bundled-tools\", \"jscpd.version\");\n\tif (targetPlatform === platform() && existsSync(standaloneBinary) && existsSync(standaloneVersion)) {\n\t\treturn {\n\t\t\tsourcePath: standaloneBinary,\n\t\t\tsourceVersion: readFileSync(standaloneVersion, \"utf8\").trim(),\n\t\t};\n\t}\n\tconst packageName = resolveJscpdPlatformPackage(targetPlatform, targetArchitecture, detectRuntimeLibc());\n\treturn packageName ? readSourceFromPackage(packageName, requires) : undefined;\n}\n\nexport function probeJscpdVersion(path: string): string | undefined {\n\ttry {\n\t\tconst result = spawnSync(path, [\"--version\"], {\n\t\t\tencoding: \"utf8\",\n\t\t\tstdio: \"pipe\",\n\t\t\ttimeout: 5_000,\n\t\t\twindowsHide: true,\n\t\t});\n\t\tif (result.error || result.status !== 0) return undefined;\n\t\treturn `${result.stdout ?? \"\"}${result.stderr ?? \"\"}`.trim() || undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isExactVersion(output: string | undefined): boolean {\n\treturn output?.split(/\\s+/).includes(JSCPD_VERSION) === true;\n}\n\nexport function installBundledJscpdBinary(options: InstallBundledJscpdBinaryOptions): string {\n\tif (options.sourceVersion !== JSCPD_VERSION) {\n\t\tthrow new Error(`Pi requires bundled jscpd ${JSCPD_VERSION}; found ${options.sourceVersion || \"unknown\"}.`);\n\t}\n\tconst targetPath = join(options.managedBinDir, binaryName(options.targetPlatform));\n\tconst temporaryPath = join(\n\t\toptions.managedBinDir,\n\t\t`.jscpd-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}${\n\t\t\toptions.targetPlatform === \"win32\" ? \".exe\" : \"\"\n\t\t}`,\n\t);\n\tmkdirSync(options.managedBinDir, { recursive: true });\n\tconst probeVersion = options.probeVersion ?? probeJscpdVersion;\n\tlet promoted = false;\n\ttry {\n\t\tcopyFileSync(options.sourcePath, temporaryPath);\n\t\tif (options.targetPlatform !== \"win32\") chmodSync(temporaryPath, 0o755);\n\t\tconst version = probeVersion(temporaryPath);\n\t\tif (!isExactVersion(version)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Pi requires bundled jscpd ${JSCPD_VERSION}; installed binary reported ${version ?? \"no version\"}.`,\n\t\t\t);\n\t\t}\n\t\ttry {\n\t\t\trenameSync(temporaryPath, targetPath);\n\t\t\tpromoted = true;\n\t\t} catch {\n\t\t\t// Concurrent sessions converge on the same exact binary. Windows cannot replace an\n\t\t\t// existing executable with rename, so accept a valid winner without deleting it.\n\t\t\tif (existsSync(targetPath) && isExactVersion(probeVersion(targetPath))) {\n\t\t\t\trmSync(temporaryPath, { force: true });\n\t\t\t\treturn targetPath;\n\t\t\t}\n\t\t\trmSync(targetPath, { force: true });\n\t\t\trenameSync(temporaryPath, targetPath);\n\t\t\tpromoted = true;\n\t\t}\n\t\treturn targetPath;\n\t} catch (error) {\n\t\trmSync(temporaryPath, { force: true });\n\t\tif (promoted && !isExactVersion(probeVersion(targetPath))) rmSync(targetPath, { force: true });\n\t\tthrow error;\n\t}\n}\n\nexport function ensureManagedJscpd(managedBinDir: string = getBinDir()): string {\n\tconst targetPath = join(managedBinDir, binaryName(platform()));\n\tif (cachedManagedPath?.path === targetPath) {\n\t\ttry {\n\t\t\tif (statSync(cachedManagedPath.path).mtimeMs === cachedManagedPath.mtimeMs) return cachedManagedPath.path;\n\t\t} catch {\n\t\t\tcachedManagedPath = undefined;\n\t\t}\n\t}\n\tif (existsSync(targetPath) && isExactVersion(probeJscpdVersion(targetPath))) {\n\t\tcachedManagedPath = { path: targetPath, mtimeMs: statSync(targetPath).mtimeMs };\n\t\treturn targetPath;\n\t}\n\tconst source = resolveBundledJscpdSource();\n\tif (!source) {\n\t\tthrow new Error(\n\t\t\t`Bundled jscpd ${JSCPD_VERSION} is unavailable for ${platform()}/${arch()}. Reinstall Pi for this platform.`,\n\t\t);\n\t}\n\tconst installed = installBundledJscpdBinary({\n\t\t...source,\n\t\tmanagedBinDir,\n\t\ttargetPlatform: platform(),\n\t});\n\tcachedManagedPath = { path: installed, mtimeMs: statSync(installed).mtimeMs };\n\treturn installed;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,YAAY,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;CACf;AAED,eAAO,MAAM,sBAAsB,8EAA8E,CAAC;AAIlH,wBAAgB,wBAAwB,CAAC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,qBAAqB,CAE5G;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/D;AAqFD,sHAAsH;AACtH,wBAAgB,cAAc,CAC7B,eAAe,CAAC,EAAE,MAAM,EACxB,SAAS,GAAE,qBAAkD,GAC3D,WAAW,CAeb;AAED,wBAAgB,WAAW,IAAI,MAAM,CAAC,UAAU,CAoB/C;AAQD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEvD;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEzD;AAED,wBAAgB,2BAA2B,IAAI,IAAI,CAKlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAyBjD"}
|
package/dist/utils/shell.js
CHANGED
|
@@ -2,6 +2,7 @@ import { existsSync } from "node:fs";
|
|
|
2
2
|
import { delimiter } from "node:path";
|
|
3
3
|
import { spawnSync } from "child_process";
|
|
4
4
|
import { getBinDir } from "../config.js";
|
|
5
|
+
import { ensureManagedJscpd } from "./bundled-jscpd.js";
|
|
5
6
|
import { normalizePath } from "./paths.js";
|
|
6
7
|
export const POWERSHELL_UTF8_PREFIX = "try { [Console]::OutputEncoding=[System.Text.Encoding]::UTF8 } catch {}\n";
|
|
7
8
|
const POWERSHELL_ARGS = ["-NoLogo", "-NoProfile", "-NonInteractive", "-Command"];
|
|
@@ -92,6 +93,7 @@ function getBashConfig() {
|
|
|
92
93
|
// boot on Windows) and is a process-lifetime invariant, so successful resolutions are cached.
|
|
93
94
|
// Failures are not cached: the user can install a shell and retry without restarting.
|
|
94
95
|
const resolvedPlatformShellConfigs = new Map();
|
|
96
|
+
let managedJscpdProvisionAttempted = false;
|
|
95
97
|
/** Resolve the requested shell. Runtime callers omit shellName to select PowerShell on Windows and Bash elsewhere. */
|
|
96
98
|
export function getShellConfig(customShellPath, shellName = getPlatformShellToolName()) {
|
|
97
99
|
if (customShellPath) {
|
|
@@ -111,6 +113,15 @@ export function getShellConfig(customShellPath, shellName = getPlatformShellTool
|
|
|
111
113
|
return { shell: resolved.shell, args: [...resolved.args] };
|
|
112
114
|
}
|
|
113
115
|
export function getShellEnv() {
|
|
116
|
+
if (!managedJscpdProvisionAttempted) {
|
|
117
|
+
managedJscpdProvisionAttempted = true;
|
|
118
|
+
try {
|
|
119
|
+
ensureManagedJscpd();
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// The jscpd wrapper and doctor surface the exact packaging failure. Shell startup stays usable.
|
|
123
|
+
}
|
|
124
|
+
}
|
|
114
125
|
const binDir = getBinDir();
|
|
115
126
|
const pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === "path") ?? "PATH";
|
|
116
127
|
const currentPath = process.env[pathKey] ?? "";
|
package/dist/utils/shell.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { delimiter } from \"node:path\";\nimport { spawnSync } from \"child_process\";\nimport { getBinDir } from \"../config.ts\";\nimport { normalizePath } from \"./paths.ts\";\n\nexport type PlatformShellToolName = \"bash\" | \"powershell\";\n\nexport interface ShellConfig {\n\tshell: string;\n\targs: string[];\n}\n\nexport const POWERSHELL_UTF8_PREFIX = \"try { [Console]::OutputEncoding=[System.Text.Encoding]::UTF8 } catch {}\\n\";\n\nconst POWERSHELL_ARGS = [\"-NoLogo\", \"-NoProfile\", \"-NonInteractive\", \"-Command\"];\n\nexport function getPlatformShellToolName(platform: NodeJS.Platform = process.platform): PlatformShellToolName {\n\treturn platform === \"win32\" ? \"powershell\" : \"bash\";\n}\n\nexport function prefixPowerShellCommand(command: string): string {\n\treturn command.trimStart().startsWith(POWERSHELL_UTF8_PREFIX) ? command : `${POWERSHELL_UTF8_PREFIX}${command}`;\n}\n\nfunction findExecutableOnPath(executable: string): string | null {\n\tconst locator = process.platform === \"win32\" ? \"where\" : \"which\";\n\ttry {\n\t\tconst result = spawnSync(locator, [executable], {\n\t\t\tencoding: \"utf-8\",\n\t\t\ttimeout: 5_000,\n\t\t\twindowsHide: true,\n\t\t});\n\t\tif (result.status === 0 && result.stdout) {\n\t\t\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\t\t\tif (firstMatch && (process.platform !== \"win32\" || existsSync(firstMatch))) return firstMatch;\n\t\t}\n\t} catch {\n\t\t// Resolution falls through to known paths or the platform fallback.\n\t}\n\treturn null;\n}\n\nfunction isPowerShellExecutableAvailable(executable: string): boolean {\n\ttry {\n\t\treturn (\n\t\t\tspawnSync(executable, [...POWERSHELL_ARGS, \"Write-Output ok\"], {\n\t\t\t\tencoding: \"utf-8\",\n\t\t\t\ttimeout: 5_000,\n\t\t\t\twindowsHide: true,\n\t\t\t}).status === 0\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction getPowerShellConfig(): ShellConfig {\n\tconst pwshOnPath = findExecutableOnPath(process.platform === \"win32\" ? \"pwsh.exe\" : \"pwsh\");\n\tif (pwshOnPath && isPowerShellExecutableAvailable(pwshOnPath)) {\n\t\treturn { shell: pwshOnPath, args: [...POWERSHELL_ARGS] };\n\t}\n\n\tconst knownPaths: string[] = [];\n\tconst programFiles = process.env.ProgramFiles;\n\tif (programFiles) knownPaths.push(`${programFiles}\\\\PowerShell\\\\7\\\\pwsh.exe`);\n\tconst systemRoot = process.env.SystemRoot;\n\tif (systemRoot) knownPaths.push(`${systemRoot}\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe`);\n\tfor (const path of knownPaths) {\n\t\tif (existsSync(path) && isPowerShellExecutableAvailable(path)) {\n\t\t\treturn { shell: path, args: [...POWERSHELL_ARGS] };\n\t\t}\n\t}\n\n\tconst windowsPowerShellOnPath = findExecutableOnPath(\"powershell.exe\");\n\tif (windowsPowerShellOnPath && isPowerShellExecutableAvailable(windowsPowerShellOnPath)) {\n\t\treturn { shell: windowsPowerShellOnPath, args: [...POWERSHELL_ARGS] };\n\t}\n\tthrow new Error(\n\t\t\"No PowerShell executable found. Install PowerShell 7 (pwsh), restore Windows PowerShell, or set shellPath in settings.json.\",\n\t);\n}\n\nfunction getBashConfig(): ShellConfig {\n\tif (process.platform === \"win32\") {\n\t\tconst knownPaths: string[] = [];\n\t\tconst programFiles = process.env.ProgramFiles;\n\t\tif (programFiles) knownPaths.push(`${programFiles}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tconst programFilesX86 = process.env[\"ProgramFiles(x86)\"];\n\t\tif (programFilesX86) knownPaths.push(`${programFilesX86}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tfor (const path of knownPaths) {\n\t\t\tif (existsSync(path)) return { shell: path, args: [\"-c\"] };\n\t\t}\n\t\tconst bashOnPath = findExecutableOnPath(\"bash.exe\");\n\t\tif (bashOnPath) return { shell: bashOnPath, args: [\"-c\"] };\n\t\tthrow new Error(\"No Bash executable found. Install Git Bash or set shellPath in settings.json.\");\n\t}\n\tif (existsSync(\"/bin/bash\")) return { shell: \"/bin/bash\", args: [\"-c\"] };\n\tconst bashOnPath = findExecutableOnPath(\"bash\");\n\treturn bashOnPath ? { shell: bashOnPath, args: [\"-c\"] } : { shell: \"sh\", args: [\"-c\"] };\n}\n\n// Platform shell resolution spawns probe processes (`where`/`which`, plus a full PowerShell\n// boot on Windows) and is a process-lifetime invariant, so successful resolutions are cached.\n// Failures are not cached: the user can install a shell and retry without restarting.\nconst resolvedPlatformShellConfigs = new Map<PlatformShellToolName, ShellConfig>();\n\n/** Resolve the requested shell. Runtime callers omit shellName to select PowerShell on Windows and Bash elsewhere. */\nexport function getShellConfig(\n\tcustomShellPath?: string,\n\tshellName: PlatformShellToolName = getPlatformShellToolName(),\n): ShellConfig {\n\tif (customShellPath) {\n\t\tconst resolvedShellPath = normalizePath(customShellPath);\n\t\tif (!existsSync(resolvedShellPath)) throw new Error(`Custom shell path not found: ${resolvedShellPath}`);\n\t\treturn {\n\t\t\tshell: resolvedShellPath,\n\t\t\targs: shellName === \"powershell\" ? [...POWERSHELL_ARGS] : [\"-c\"],\n\t\t};\n\t}\n\tlet resolved = resolvedPlatformShellConfigs.get(shellName);\n\tif (!resolved) {\n\t\tresolved = shellName === \"powershell\" ? getPowerShellConfig() : getBashConfig();\n\t\tresolvedPlatformShellConfigs.set(shellName, resolved);\n\t}\n\treturn { shell: resolved.shell, args: [...resolved.args] };\n}\n\nexport function getShellEnv(): NodeJS.ProcessEnv {\n\tconst binDir = getBinDir();\n\tconst pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === \"path\") ?? \"PATH\";\n\tconst currentPath = process.env[pathKey] ?? \"\";\n\tconst pathEntries = currentPath.split(delimiter).filter(Boolean);\n\tconst hasBinDir = pathEntries.includes(binDir);\n\tconst updatedPath = hasBinDir ? currentPath : [binDir, currentPath].filter(Boolean).join(delimiter);\n\n\treturn {\n\t\t...process.env,\n\t\t[pathKey]: updatedPath,\n\t};\n}\n\n/**\n * Detached child processes must be tracked so they can be killed on parent\n * shutdown signals (SIGHUP/SIGTERM).\n */\nconst trackedDetachedChildPids = new Set<number>();\n\nexport function trackDetachedChildPid(pid: number): void {\n\ttrackedDetachedChildPids.add(pid);\n}\n\nexport function untrackDetachedChildPid(pid: number): void {\n\ttrackedDetachedChildPids.delete(pid);\n}\n\nexport function killTrackedDetachedChildren(): void {\n\tfor (const pid of trackedDetachedChildPids) {\n\t\tkillProcessTree(pid);\n\t}\n\ttrackedDetachedChildPids.clear();\n}\n\n/**\n * Kill a process and all its children (cross-platform).\n *\n * Windows uses `spawnSync` (not `spawn`) deliberately: callers rely on this function returning\n * only once the tree is actually gone (e.g. before removing a directory that was the killed\n * process's cwd — a directory Windows keeps locked until every handle into it, including a\n * live process's cwd handle, is released). A fire-and-forget async `taskkill` would return before\n * termination completed, leaving a race where the directory is still locked.\n */\nexport function killProcessTree(pid: number): void {\n\tif (process.platform === \"win32\") {\n\t\t// Use taskkill on Windows to kill process tree; spawnSync blocks until taskkill itself\n\t\t// (and therefore the termination it requested) has finished.\n\t\ttry {\n\t\t\tspawnSync(\"taskkill\", [\"/F\", \"/T\", \"/PID\", String(pid)], {\n\t\t\t\tstdio: \"ignore\",\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Ignore errors if taskkill fails\n\t\t}\n\t} else {\n\t\t// Use SIGKILL on Unix/Linux/Mac\n\t\ttry {\n\t\t\tprocess.kill(-pid, \"SIGKILL\");\n\t\t} catch {\n\t\t\t// Fallback to killing just the child if process group kill fails\n\t\t\ttry {\n\t\t\t\tprocess.kill(pid, \"SIGKILL\");\n\t\t\t} catch {\n\t\t\t\t// Process already dead\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { delimiter } from \"node:path\";\nimport { spawnSync } from \"child_process\";\nimport { getBinDir } from \"../config.ts\";\nimport { ensureManagedJscpd } from \"./bundled-jscpd.ts\";\nimport { normalizePath } from \"./paths.ts\";\n\nexport type PlatformShellToolName = \"bash\" | \"powershell\";\n\nexport interface ShellConfig {\n\tshell: string;\n\targs: string[];\n}\n\nexport const POWERSHELL_UTF8_PREFIX = \"try { [Console]::OutputEncoding=[System.Text.Encoding]::UTF8 } catch {}\\n\";\n\nconst POWERSHELL_ARGS = [\"-NoLogo\", \"-NoProfile\", \"-NonInteractive\", \"-Command\"];\n\nexport function getPlatformShellToolName(platform: NodeJS.Platform = process.platform): PlatformShellToolName {\n\treturn platform === \"win32\" ? \"powershell\" : \"bash\";\n}\n\nexport function prefixPowerShellCommand(command: string): string {\n\treturn command.trimStart().startsWith(POWERSHELL_UTF8_PREFIX) ? command : `${POWERSHELL_UTF8_PREFIX}${command}`;\n}\n\nfunction findExecutableOnPath(executable: string): string | null {\n\tconst locator = process.platform === \"win32\" ? \"where\" : \"which\";\n\ttry {\n\t\tconst result = spawnSync(locator, [executable], {\n\t\t\tencoding: \"utf-8\",\n\t\t\ttimeout: 5_000,\n\t\t\twindowsHide: true,\n\t\t});\n\t\tif (result.status === 0 && result.stdout) {\n\t\t\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\t\t\tif (firstMatch && (process.platform !== \"win32\" || existsSync(firstMatch))) return firstMatch;\n\t\t}\n\t} catch {\n\t\t// Resolution falls through to known paths or the platform fallback.\n\t}\n\treturn null;\n}\n\nfunction isPowerShellExecutableAvailable(executable: string): boolean {\n\ttry {\n\t\treturn (\n\t\t\tspawnSync(executable, [...POWERSHELL_ARGS, \"Write-Output ok\"], {\n\t\t\t\tencoding: \"utf-8\",\n\t\t\t\ttimeout: 5_000,\n\t\t\t\twindowsHide: true,\n\t\t\t}).status === 0\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction getPowerShellConfig(): ShellConfig {\n\tconst pwshOnPath = findExecutableOnPath(process.platform === \"win32\" ? \"pwsh.exe\" : \"pwsh\");\n\tif (pwshOnPath && isPowerShellExecutableAvailable(pwshOnPath)) {\n\t\treturn { shell: pwshOnPath, args: [...POWERSHELL_ARGS] };\n\t}\n\n\tconst knownPaths: string[] = [];\n\tconst programFiles = process.env.ProgramFiles;\n\tif (programFiles) knownPaths.push(`${programFiles}\\\\PowerShell\\\\7\\\\pwsh.exe`);\n\tconst systemRoot = process.env.SystemRoot;\n\tif (systemRoot) knownPaths.push(`${systemRoot}\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe`);\n\tfor (const path of knownPaths) {\n\t\tif (existsSync(path) && isPowerShellExecutableAvailable(path)) {\n\t\t\treturn { shell: path, args: [...POWERSHELL_ARGS] };\n\t\t}\n\t}\n\n\tconst windowsPowerShellOnPath = findExecutableOnPath(\"powershell.exe\");\n\tif (windowsPowerShellOnPath && isPowerShellExecutableAvailable(windowsPowerShellOnPath)) {\n\t\treturn { shell: windowsPowerShellOnPath, args: [...POWERSHELL_ARGS] };\n\t}\n\tthrow new Error(\n\t\t\"No PowerShell executable found. Install PowerShell 7 (pwsh), restore Windows PowerShell, or set shellPath in settings.json.\",\n\t);\n}\n\nfunction getBashConfig(): ShellConfig {\n\tif (process.platform === \"win32\") {\n\t\tconst knownPaths: string[] = [];\n\t\tconst programFiles = process.env.ProgramFiles;\n\t\tif (programFiles) knownPaths.push(`${programFiles}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tconst programFilesX86 = process.env[\"ProgramFiles(x86)\"];\n\t\tif (programFilesX86) knownPaths.push(`${programFilesX86}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tfor (const path of knownPaths) {\n\t\t\tif (existsSync(path)) return { shell: path, args: [\"-c\"] };\n\t\t}\n\t\tconst bashOnPath = findExecutableOnPath(\"bash.exe\");\n\t\tif (bashOnPath) return { shell: bashOnPath, args: [\"-c\"] };\n\t\tthrow new Error(\"No Bash executable found. Install Git Bash or set shellPath in settings.json.\");\n\t}\n\tif (existsSync(\"/bin/bash\")) return { shell: \"/bin/bash\", args: [\"-c\"] };\n\tconst bashOnPath = findExecutableOnPath(\"bash\");\n\treturn bashOnPath ? { shell: bashOnPath, args: [\"-c\"] } : { shell: \"sh\", args: [\"-c\"] };\n}\n\n// Platform shell resolution spawns probe processes (`where`/`which`, plus a full PowerShell\n// boot on Windows) and is a process-lifetime invariant, so successful resolutions are cached.\n// Failures are not cached: the user can install a shell and retry without restarting.\nconst resolvedPlatformShellConfigs = new Map<PlatformShellToolName, ShellConfig>();\nlet managedJscpdProvisionAttempted = false;\n\n/** Resolve the requested shell. Runtime callers omit shellName to select PowerShell on Windows and Bash elsewhere. */\nexport function getShellConfig(\n\tcustomShellPath?: string,\n\tshellName: PlatformShellToolName = getPlatformShellToolName(),\n): ShellConfig {\n\tif (customShellPath) {\n\t\tconst resolvedShellPath = normalizePath(customShellPath);\n\t\tif (!existsSync(resolvedShellPath)) throw new Error(`Custom shell path not found: ${resolvedShellPath}`);\n\t\treturn {\n\t\t\tshell: resolvedShellPath,\n\t\t\targs: shellName === \"powershell\" ? [...POWERSHELL_ARGS] : [\"-c\"],\n\t\t};\n\t}\n\tlet resolved = resolvedPlatformShellConfigs.get(shellName);\n\tif (!resolved) {\n\t\tresolved = shellName === \"powershell\" ? getPowerShellConfig() : getBashConfig();\n\t\tresolvedPlatformShellConfigs.set(shellName, resolved);\n\t}\n\treturn { shell: resolved.shell, args: [...resolved.args] };\n}\n\nexport function getShellEnv(): NodeJS.ProcessEnv {\n\tif (!managedJscpdProvisionAttempted) {\n\t\tmanagedJscpdProvisionAttempted = true;\n\t\ttry {\n\t\t\tensureManagedJscpd();\n\t\t} catch {\n\t\t\t// The jscpd wrapper and doctor surface the exact packaging failure. Shell startup stays usable.\n\t\t}\n\t}\n\tconst binDir = getBinDir();\n\tconst pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === \"path\") ?? \"PATH\";\n\tconst currentPath = process.env[pathKey] ?? \"\";\n\tconst pathEntries = currentPath.split(delimiter).filter(Boolean);\n\tconst hasBinDir = pathEntries.includes(binDir);\n\tconst updatedPath = hasBinDir ? currentPath : [binDir, currentPath].filter(Boolean).join(delimiter);\n\n\treturn {\n\t\t...process.env,\n\t\t[pathKey]: updatedPath,\n\t};\n}\n\n/**\n * Detached child processes must be tracked so they can be killed on parent\n * shutdown signals (SIGHUP/SIGTERM).\n */\nconst trackedDetachedChildPids = new Set<number>();\n\nexport function trackDetachedChildPid(pid: number): void {\n\ttrackedDetachedChildPids.add(pid);\n}\n\nexport function untrackDetachedChildPid(pid: number): void {\n\ttrackedDetachedChildPids.delete(pid);\n}\n\nexport function killTrackedDetachedChildren(): void {\n\tfor (const pid of trackedDetachedChildPids) {\n\t\tkillProcessTree(pid);\n\t}\n\ttrackedDetachedChildPids.clear();\n}\n\n/**\n * Kill a process and all its children (cross-platform).\n *\n * Windows uses `spawnSync` (not `spawn`) deliberately: callers rely on this function returning\n * only once the tree is actually gone (e.g. before removing a directory that was the killed\n * process's cwd — a directory Windows keeps locked until every handle into it, including a\n * live process's cwd handle, is released). A fire-and-forget async `taskkill` would return before\n * termination completed, leaving a race where the directory is still locked.\n */\nexport function killProcessTree(pid: number): void {\n\tif (process.platform === \"win32\") {\n\t\t// Use taskkill on Windows to kill process tree; spawnSync blocks until taskkill itself\n\t\t// (and therefore the termination it requested) has finished.\n\t\ttry {\n\t\t\tspawnSync(\"taskkill\", [\"/F\", \"/T\", \"/PID\", String(pid)], {\n\t\t\t\tstdio: \"ignore\",\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Ignore errors if taskkill fails\n\t\t}\n\t} else {\n\t\t// Use SIGKILL on Unix/Linux/Mac\n\t\ttry {\n\t\t\tprocess.kill(-pid, \"SIGKILL\");\n\t\t} catch {\n\t\t\t// Fallback to killing just the child if process group kill fails\n\t\t\ttry {\n\t\t\t\tprocess.kill(pid, \"SIGKILL\");\n\t\t\t} catch {\n\t\t\t\t// Process already dead\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export declare const RG_VERSION = "15.2.0";
|
|
2
|
+
export declare const JQ_VERSION = "1.8.2";
|
|
1
3
|
export declare const UV_VERSION = "0.11.28";
|
|
2
4
|
type ModuleRequire = ((id: string) => unknown) & {
|
|
3
5
|
resolve?: (id: string) => string;
|
|
@@ -9,10 +11,11 @@ interface ToolConfig {
|
|
|
9
11
|
systemBinaryNames?: string[];
|
|
10
12
|
tagPrefix: string;
|
|
11
13
|
getAssetName: (version: string, plat: string, architecture: string) => string | null;
|
|
14
|
+
downloadKind?: "archive" | "binary";
|
|
12
15
|
pinnedVersion?: string;
|
|
13
16
|
sha256ByAsset?: Readonly<Record<string, string>>;
|
|
14
17
|
}
|
|
15
|
-
declare const TOOLS: Record<"fd" | "rg" | "uv", ToolConfig>;
|
|
18
|
+
declare const TOOLS: Record<"fd" | "jq" | "jscpd" | "rg" | "uv", ToolConfig>;
|
|
16
19
|
export type ManagedToolName = keyof typeof TOOLS;
|
|
17
20
|
export interface PinnedToolAsset {
|
|
18
21
|
version: string;
|
|
@@ -44,6 +47,8 @@ export declare function detectPython(commands?: readonly string[]): SystemToolSt
|
|
|
44
47
|
*/
|
|
45
48
|
export declare function probeVersion(command: string, versionArgs?: readonly string[]): string | undefined;
|
|
46
49
|
export declare function verifyFileSha256(filePath: string, expectedSha256: string): Promise<boolean>;
|
|
50
|
+
/** Move a verified upstream standalone executable into Pi's managed bin directory. */
|
|
51
|
+
export declare function installStandaloneBinaryAsset(downloadedPath: string, binaryPath: string, targetPlatform?: string): void;
|
|
47
52
|
export declare function runExclusiveToolDownload(tool: ManagedToolName, installer: () => Promise<string | undefined>): Promise<string | undefined>;
|
|
48
53
|
/**
|
|
49
54
|
* @param requires Override the resolution candidates, for tests (mirrors
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools-manager.d.ts","sourceRoot":"","sources":["../../src/utils/tools-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tools-manager.d.ts","sourceRoot":"","sources":["../../src/utils/tools-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ import { pipeline } from "stream/promises";
|
|
|
10
10
|
import { pathToFileURL } from "url";
|
|
11
11
|
import { APP_NAME, getAgentDir, getBinDir } from "../config.js";
|
|
12
12
|
import { cacheDir as agentCacheDir, cacheFile } from "../core/agent-paths.js";
|
|
13
|
+
import { ensureManagedJscpd, JSCPD_VERSION } from "./bundled-jscpd.js";
|
|
13
14
|
import { spawnProcess, waitForChildProcessWithTermination } from "./child-process.js";
|
|
14
15
|
import { getProcessWorkRun } from "./work-directory.js";
|
|
15
16
|
const TOOLS_DIR = getBinDir();
|
|
@@ -18,6 +19,8 @@ const DOWNLOAD_TIMEOUT_MS = 120_000;
|
|
|
18
19
|
const COMMAND_PROBE_TIMEOUT_MS = 5_000;
|
|
19
20
|
const ARCHIVE_EXTRACTION_TIMEOUT_MS = 5 * 60_000;
|
|
20
21
|
const FFF_NODE_VERSION = "0.9.6";
|
|
22
|
+
export const RG_VERSION = "15.2.0";
|
|
23
|
+
export const JQ_VERSION = "1.8.2";
|
|
21
24
|
export const UV_VERSION = "0.11.28";
|
|
22
25
|
const FFF_MANAGED_DIR = join(TOOLS_DIR, "fff-node");
|
|
23
26
|
const FFF_MANAGED_PACKAGE_JSON = join(FFF_MANAGED_DIR, "package.json");
|
|
@@ -57,6 +60,7 @@ const TOOLS = {
|
|
|
57
60
|
repo: "BurntSushi/ripgrep",
|
|
58
61
|
binaryName: "rg",
|
|
59
62
|
tagPrefix: "",
|
|
63
|
+
pinnedVersion: RG_VERSION,
|
|
60
64
|
getAssetName: (version, plat, architecture) => {
|
|
61
65
|
if (plat === "darwin") {
|
|
62
66
|
const archStr = architecture === "arm64" ? "aarch64" : "x86_64";
|
|
@@ -74,6 +78,52 @@ const TOOLS = {
|
|
|
74
78
|
}
|
|
75
79
|
return null;
|
|
76
80
|
},
|
|
81
|
+
sha256ByAsset: {
|
|
82
|
+
"ripgrep-15.2.0-aarch64-apple-darwin.tar.gz": "3750b2e93f37e0c692657da574d7019a101c0084da05a790c83fd335bad973e4",
|
|
83
|
+
"ripgrep-15.2.0-aarch64-pc-windows-msvc.zip": "e4abca10c3a64ebea742667dd7009449d49403db5460dd6873e389fa2945360f",
|
|
84
|
+
"ripgrep-15.2.0-aarch64-unknown-linux-gnu.tar.gz": "a740b91c82eaf9914cfedd353572f2791cbe0162c84101ee0951058f4dcbc90d",
|
|
85
|
+
"ripgrep-15.2.0-x86_64-apple-darwin.tar.gz": "af7825fcc69a2afc7a7aea55fc9af90e26421d8f20fe59df32e233c0b8a231c1",
|
|
86
|
+
"ripgrep-15.2.0-x86_64-pc-windows-msvc.zip": "71b2fef860abe467217a538ff31de02f5258807c0129f771846f87bd029aafc5",
|
|
87
|
+
"ripgrep-15.2.0-x86_64-unknown-linux-musl.tar.gz": "33e15bcf1624b25cdd2a55813a47a2f95dbe126268203e76aa6a585d1e7b149c",
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
jq: {
|
|
91
|
+
name: "jq",
|
|
92
|
+
repo: "jqlang/jq",
|
|
93
|
+
binaryName: "jq",
|
|
94
|
+
systemBinaryNames: ["jq"],
|
|
95
|
+
tagPrefix: "jq-",
|
|
96
|
+
downloadKind: "binary",
|
|
97
|
+
pinnedVersion: JQ_VERSION,
|
|
98
|
+
getAssetName: (_version, plat, architecture) => {
|
|
99
|
+
if (architecture !== "arm64" && architecture !== "x64")
|
|
100
|
+
return null;
|
|
101
|
+
const archStr = architecture === "arm64" ? "arm64" : "amd64";
|
|
102
|
+
if (plat === "darwin")
|
|
103
|
+
return `jq-macos-${archStr}`;
|
|
104
|
+
if (plat === "linux")
|
|
105
|
+
return `jq-linux-${archStr}`;
|
|
106
|
+
if (plat === "win32")
|
|
107
|
+
return `jq-windows-${archStr}.exe`;
|
|
108
|
+
return null;
|
|
109
|
+
},
|
|
110
|
+
sha256ByAsset: {
|
|
111
|
+
"jq-linux-amd64": "b1c22172dd303f3be49e935aa56aa48a8b7a46e0bc838b4997d3bb451495870f",
|
|
112
|
+
"jq-linux-arm64": "8b85c817833814ddca00a144c33705546355afccf0cf39b188f3cdb48b852309",
|
|
113
|
+
"jq-macos-amd64": "e94b266e3c26690550006abe63152b782280f4e14374accdf04cbde844f00bc0",
|
|
114
|
+
"jq-macos-arm64": "2d75340ba57a4b4b4c8708a21c2dc8e958a48aaa8bba13b27f77f6e4c0eca07e",
|
|
115
|
+
"jq-windows-amd64.exe": "a6fc67fedaf9128a3309a1e2ebb8b986aeccf70122ee46d2cb4849e423f0c627",
|
|
116
|
+
"jq-windows-arm64.exe": "083b5377392bc57cf27052b6d20a2d927770683bca844632901ff38b4b7b0ac7",
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
jscpd: {
|
|
120
|
+
name: "jscpd",
|
|
121
|
+
repo: "",
|
|
122
|
+
binaryName: "jscpd",
|
|
123
|
+
systemBinaryNames: [],
|
|
124
|
+
tagPrefix: "",
|
|
125
|
+
pinnedVersion: JSCPD_VERSION,
|
|
126
|
+
getAssetName: () => null,
|
|
77
127
|
},
|
|
78
128
|
uv: {
|
|
79
129
|
name: "uv",
|
|
@@ -429,6 +479,13 @@ function extractZipArchive(archivePath, extractDir, assetName) {
|
|
|
429
479
|
}
|
|
430
480
|
throw new Error(`Failed to extract ${assetName}: ${failures.join("; ")}`);
|
|
431
481
|
}
|
|
482
|
+
/** Move a verified upstream standalone executable into Pi's managed bin directory. */
|
|
483
|
+
export function installStandaloneBinaryAsset(downloadedPath, binaryPath, targetPlatform = platform()) {
|
|
484
|
+
mkdirSync(dirname(binaryPath), { recursive: true });
|
|
485
|
+
renameSync(downloadedPath, binaryPath);
|
|
486
|
+
if (targetPlatform !== "win32")
|
|
487
|
+
chmodSync(binaryPath, 0o755);
|
|
488
|
+
}
|
|
432
489
|
// Download and install a tool
|
|
433
490
|
const toolDownloadPromises = new Map();
|
|
434
491
|
export function runExclusiveToolDownload(tool, installer) {
|
|
@@ -449,7 +506,7 @@ async function downloadTool(tool) {
|
|
|
449
506
|
throw new Error(`Unknown tool: ${tool}`);
|
|
450
507
|
const plat = platform();
|
|
451
508
|
const architecture = arch();
|
|
452
|
-
// Pinned tools are reproducible
|
|
509
|
+
// Pinned tools are reproducible and verified before installation.
|
|
453
510
|
let version = config.pinnedVersion ?? (await getLatestVersion(config.repo));
|
|
454
511
|
if (tool === "fd" && plat === "darwin" && architecture === "x64") {
|
|
455
512
|
version = "10.3.0";
|
|
@@ -475,7 +532,16 @@ async function downloadTool(tool) {
|
|
|
475
532
|
if (expectedSha256 && !(await verifyFileSha256(archivePath, expectedSha256))) {
|
|
476
533
|
throw new Error(`SHA-256 verification failed for ${assetName}`);
|
|
477
534
|
}
|
|
478
|
-
|
|
535
|
+
if (config.downloadKind === "binary") {
|
|
536
|
+
try {
|
|
537
|
+
installStandaloneBinaryAsset(archivePath, binaryPath, plat);
|
|
538
|
+
}
|
|
539
|
+
finally {
|
|
540
|
+
rmSync(archivePath, { force: true });
|
|
541
|
+
}
|
|
542
|
+
return binaryPath;
|
|
543
|
+
}
|
|
544
|
+
// Extract into a unique temp directory. Tool downloads can run concurrently
|
|
479
545
|
// during startup, so sharing a fixed directory causes races.
|
|
480
546
|
const extractDir = join(downloadWorkDir, `extract-${config.binaryName}-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`);
|
|
481
547
|
mkdirSync(extractDir, { recursive: true });
|
|
@@ -519,6 +585,8 @@ async function downloadTool(tool) {
|
|
|
519
585
|
// Termux package names for tools
|
|
520
586
|
const TERMUX_PACKAGES = {
|
|
521
587
|
fd: "fd",
|
|
588
|
+
jscpd: "jscpd",
|
|
589
|
+
jq: "jq",
|
|
522
590
|
rg: "ripgrep",
|
|
523
591
|
uv: "uv",
|
|
524
592
|
};
|
|
@@ -786,6 +854,17 @@ async function installTermuxManagedTool(tool, silent) {
|
|
|
786
854
|
// Ensure a tool is available, downloading if necessary
|
|
787
855
|
// Returns the path to the tool, or undefined if unavailable
|
|
788
856
|
export async function ensureTool(tool, silent = false) {
|
|
857
|
+
if (tool === "jscpd") {
|
|
858
|
+
try {
|
|
859
|
+
return ensureManagedJscpd();
|
|
860
|
+
}
|
|
861
|
+
catch (error) {
|
|
862
|
+
if (!silent) {
|
|
863
|
+
console.log(chalk.yellow(`Failed to provision jscpd: ${error instanceof Error ? error.message : error}`));
|
|
864
|
+
}
|
|
865
|
+
return undefined;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
789
868
|
const existingPath = getToolPath(tool);
|
|
790
869
|
if (existingPath) {
|
|
791
870
|
return existingPath;
|