pi-background-tasks 2.5.0 → 2.6.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/BACKGROUND-TASKS-INSTRUCTIONS.md +1 -1
- package/README.md +70 -25
- package/TESTING.md +42 -2
- package/TEST_PLAN.md +7 -4
- package/dist/extensions/anthropic-attribution-child.js +4 -0
- package/dist/extensions/anthropic-attribution-child.js.map +1 -0
- package/dist/extensions/anthropic-attribution.js +107 -0
- package/dist/extensions/anthropic-attribution.js.map +1 -0
- package/dist/extensions/background-tasks.js +2 -0
- package/dist/extensions/background-tasks.js.map +1 -0
- package/dist/extensions/delegate-child.js +2 -0
- package/dist/extensions/delegate-child.js.map +1 -0
- package/dist/extensions/fusion-child.js +2 -0
- package/dist/extensions/fusion-child.js.map +1 -0
- package/dist/package.json +5 -0
- package/dist/src/core/anthropic-attribution-path.js +24 -0
- package/dist/src/core/anthropic-attribution-path.js.map +1 -0
- package/dist/src/core/anthropic-attribution.js +2247 -0
- package/dist/src/core/anthropic-attribution.js.map +1 -0
- package/dist/src/core/attested-pi-contract.js +5 -0
- package/dist/src/core/attested-pi-contract.js.map +1 -0
- package/dist/src/core/attested-pi-run.js +749 -0
- package/dist/src/core/attested-pi-run.js.map +1 -0
- package/dist/src/core/canonical-json.js +19 -0
- package/dist/src/core/canonical-json.js.map +1 -0
- package/dist/src/core/common.js +787 -0
- package/dist/src/core/common.js.map +1 -0
- package/dist/src/core/config.js +78 -0
- package/dist/src/core/config.js.map +1 -0
- package/dist/src/core/context/parent-snapshot.js +75 -0
- package/dist/src/core/context/parent-snapshot.js.map +1 -0
- package/dist/src/core/context/token-budget.js +631 -0
- package/dist/src/core/context/token-budget.js.map +1 -0
- package/dist/src/core/context/visible-conversation-v2.js +390 -0
- package/dist/src/core/context/visible-conversation-v2.js.map +1 -0
- package/dist/src/core/delegate/artifacts.js +357 -0
- package/dist/src/core/delegate/artifacts.js.map +1 -0
- package/dist/src/core/delegate/budget.js +266 -0
- package/dist/src/core/delegate/budget.js.map +1 -0
- package/dist/src/core/delegate/facade-contract.js +7 -0
- package/dist/src/core/delegate/facade-contract.js.map +1 -0
- package/dist/src/core/delegate/hook-contract-evidence.json +18 -0
- package/dist/src/core/delegate/hook-contract.js +124 -0
- package/dist/src/core/delegate/hook-contract.js.map +1 -0
- package/dist/src/core/delegate/launch.js +366 -0
- package/dist/src/core/delegate/launch.js.map +1 -0
- package/dist/src/core/delegate/result-package.js +293 -0
- package/dist/src/core/delegate/result-package.js.map +1 -0
- package/dist/src/core/delegate/runner.js +398 -0
- package/dist/src/core/delegate/runner.js.map +1 -0
- package/dist/src/core/delegate/seed.js +334 -0
- package/dist/src/core/delegate/seed.js.map +1 -0
- package/dist/src/core/delegate/types.js +103 -0
- package/dist/src/core/delegate/types.js.map +1 -0
- package/dist/src/core/durable-fs.js +372 -0
- package/dist/src/core/durable-fs.js.map +1 -0
- package/dist/src/core/extension-api.js +382 -0
- package/dist/src/core/extension-api.js.map +1 -0
- package/dist/src/core/fusion/artifacts.js +654 -0
- package/dist/src/core/fusion/artifacts.js.map +1 -0
- package/dist/src/core/fusion/budget.js +949 -0
- package/dist/src/core/fusion/budget.js.map +1 -0
- package/dist/src/core/fusion/child-protocol.js +176 -0
- package/dist/src/core/fusion/child-protocol.js.map +1 -0
- package/dist/src/core/fusion/claude-cache.js +156 -0
- package/dist/src/core/fusion/claude-cache.js.map +1 -0
- package/dist/src/core/fusion/clean-context.js +64 -0
- package/dist/src/core/fusion/clean-context.js.map +1 -0
- package/dist/src/core/fusion/config.js +349 -0
- package/dist/src/core/fusion/config.js.map +1 -0
- package/dist/src/core/fusion/context.js +184 -0
- package/dist/src/core/fusion/context.js.map +1 -0
- package/dist/src/core/fusion/evaluation.js +696 -0
- package/dist/src/core/fusion/evaluation.js.map +1 -0
- package/dist/src/core/fusion/facade-contract.js +3 -0
- package/dist/src/core/fusion/facade-contract.js.map +1 -0
- package/dist/src/core/fusion/orchestrator.js +867 -0
- package/dist/src/core/fusion/orchestrator.js.map +1 -0
- package/dist/src/core/fusion/output-contract.js +27 -0
- package/dist/src/core/fusion/output-contract.js.map +1 -0
- package/dist/src/core/fusion/pi-child.js +1741 -0
- package/dist/src/core/fusion/pi-child.js.map +1 -0
- package/dist/src/core/fusion/prompts.js +260 -0
- package/dist/src/core/fusion/prompts.js.map +1 -0
- package/dist/src/core/fusion/result-package.js +857 -0
- package/dist/src/core/fusion/result-package.js.map +1 -0
- package/dist/src/core/fusion/source-policy.js +259 -0
- package/dist/src/core/fusion/source-policy.js.map +1 -0
- package/dist/src/core/fusion/types.js +207 -0
- package/dist/src/core/fusion/types.js.map +1 -0
- package/dist/src/core/fusion/web-fetch.js +777 -0
- package/dist/src/core/fusion/web-fetch.js.map +1 -0
- package/dist/src/core/fusion/workflows.js +126 -0
- package/dist/src/core/fusion/workflows.js.map +1 -0
- package/dist/src/core/lazy-module.js +181 -0
- package/dist/src/core/lazy-module.js.map +1 -0
- package/dist/src/core/pi-launch.js +431 -0
- package/dist/src/core/pi-launch.js.map +1 -0
- package/dist/src/core/registry.js +3331 -0
- package/dist/src/core/registry.js.map +1 -0
- package/dist/src/core/reload-shell-owner.js +1396 -0
- package/dist/src/core/reload-shell-owner.js.map +1 -0
- package/dist/src/core/shell-policy.js +80 -0
- package/dist/src/core/shell-policy.js.map +1 -0
- package/dist/src/core/task-durable.js +51 -0
- package/dist/src/core/task-durable.js.map +1 -0
- package/dist/src/core/update-check.js +92 -0
- package/dist/src/core/update-check.js.map +1 -0
- package/dist/src/core/windows-taskkill.js +185 -0
- package/dist/src/core/windows-taskkill.js.map +1 -0
- package/dist/src/delegate-child-extension.js +776 -0
- package/dist/src/delegate-child-extension.js.map +1 -0
- package/dist/src/delegate-extension.js +746 -0
- package/dist/src/delegate-extension.js.map +1 -0
- package/dist/src/extension.js +953 -0
- package/dist/src/extension.js.map +1 -0
- package/dist/src/fusion-child-extension.js +760 -0
- package/dist/src/fusion-child-extension.js.map +1 -0
- package/dist/src/fusion-extension.js +1030 -0
- package/dist/src/fusion-extension.js.map +1 -0
- package/dist/src/ui/background-tasks-manager.js +689 -0
- package/dist/src/ui/background-tasks-manager.js.map +1 -0
- package/dist/src/ui/fusion-model-selector.js +277 -0
- package/dist/src/ui/fusion-model-selector.js.map +1 -0
- package/docs/INDEX.md +35 -33
- package/docs/api/eventbus-v1.md +21 -5
- package/docs/choose-a-workflow.md +2 -0
- package/docs/commands/bg-clear.md +3 -3
- package/docs/commands/bg-update.md +3 -3
- package/docs/commands/bg.md +18 -6
- package/docs/commands/claude-cache.md +4 -4
- package/docs/commands/fusion-models.md +49 -4
- package/docs/commands/fusion.md +3 -3
- package/docs/commands/jobs.md +3 -3
- package/docs/commands/kill.md +3 -3
- package/docs/commands/logs.md +3 -3
- package/docs/commands/task-manager.md +5 -5
- package/docs/concepts/completion-delivery.md +6 -2
- package/docs/getting-started.md +7 -1
- package/docs/manifest.json +228 -42
- package/docs/operations/configuration.md +58 -5
- package/docs/operations/releasing.md +4 -2
- package/docs/operations/testing.md +22 -0
- package/docs/operations/troubleshooting.md +6 -2
- package/docs/read-before-edit.md +44 -31
- package/docs/reference/runtime-contracts.md +87 -51
- package/docs/reference/shortcuts-and-dock.md +28 -14
- package/docs/subsystems/anthropic-attribution.md +23 -11
- package/docs/subsystems/attested-pi-runs.md +12 -7
- package/docs/subsystems/background-task-runtime.md +53 -11
- package/docs/subsystems/child-launch-durability-and-safety.md +28 -9
- package/docs/subsystems/delegation.md +16 -3
- package/docs/subsystems/docs-freshness-gate.md +14 -7
- package/docs/subsystems/fusion.md +36 -11
- package/docs/subsystems/host-ui-and-telemetry.md +22 -9
- package/docs/tools/bg_delegate.md +3 -1
- package/docs/tools/bg_kill.md +3 -1
- package/docs/tools/bg_logs.md +3 -1
- package/docs/tools/bg_result.md +5 -3
- package/docs/tools/bg_run.md +31 -5
- package/docs/tools/bg_run_pi_attested.md +3 -1
- package/docs/tools/bg_status.md +3 -1
- package/docs/tools/fusion_investigate.md +3 -1
- package/docs/tools/fusion_reason.md +3 -1
- package/docs/tools/fusion_research.md +3 -1
- package/docs/tools/fusion_validate.md +3 -1
- package/extensions/anthropic-attribution-child.ts +3 -0
- package/extensions/anthropic-attribution.ts +166 -1
- package/package.json +12 -10
- package/src/core/anthropic-attribution-path.ts +5 -4
- package/src/core/anthropic-attribution.ts +293 -113
- package/src/core/attested-pi-contract.ts +4 -0
- package/src/core/attested-pi-run.ts +468 -81
- package/src/core/canonical-json.ts +21 -0
- package/src/core/common.ts +450 -40
- package/src/core/config.ts +121 -0
- package/src/core/context/visible-conversation-v2.ts +3 -6
- package/src/core/delegate/artifacts.ts +13 -9
- package/src/core/delegate/budget.ts +13 -6
- package/src/core/delegate/facade-contract.ts +6 -0
- package/src/core/delegate/result-package.ts +32 -14
- package/src/core/delegate/runner.ts +129 -58
- package/src/core/delegate/seed.ts +5 -7
- package/src/core/durable-fs.ts +178 -30
- package/src/core/extension-api.ts +36 -8
- package/src/core/fusion/artifacts.ts +17 -16
- package/src/core/fusion/clean-context.ts +8 -5
- package/src/core/fusion/config.ts +2 -1
- package/src/core/fusion/context.ts +2 -6
- package/src/core/fusion/facade-contract.ts +2 -0
- package/src/core/fusion/orchestrator.ts +3 -3
- package/src/core/fusion/prompts.ts +1 -1
- package/src/core/fusion/result-package.ts +259 -72
- package/src/core/fusion/source-policy.ts +43 -17
- package/src/core/lazy-module.ts +215 -0
- package/src/core/pi-launch.ts +390 -65
- package/src/core/registry.ts +2010 -381
- package/src/core/reload-shell-owner.ts +1662 -0
- package/src/core/shell-policy.ts +134 -0
- package/src/core/task-durable.ts +67 -0
- package/src/delegate-extension.ts +404 -144
- package/src/extension.ts +387 -114
- package/src/fusion-extension.ts +202 -96
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
import { accessSync, constants, readFileSync, realpathSync, statSync } from 'node:fs';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { basename, delimiter, dirname, extname, isAbsolute, join, relative, resolve, sep, win32 as win32Path, } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
export class PiLaunchResolutionError extends Error {
|
|
6
|
+
code = 'pi_executable_resolution_failed';
|
|
7
|
+
constructor(message) {
|
|
8
|
+
super(`pi_executable_resolution_failed: ${message}`);
|
|
9
|
+
this.name = 'PiLaunchResolutionError';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export class PiCommandLineLimitError extends Error {
|
|
13
|
+
code = 'pi_command_line_too_long';
|
|
14
|
+
stage;
|
|
15
|
+
measuredLength;
|
|
16
|
+
limit;
|
|
17
|
+
constructor(stage, measuredLength, limit) {
|
|
18
|
+
super(`pi_command_line_too_long: ${stage} measured UTF-16 command line length ${String(measuredLength)} exceeds limit ${String(limit)}`);
|
|
19
|
+
this.name = 'PiCommandLineLimitError';
|
|
20
|
+
this.stage = stage;
|
|
21
|
+
this.measuredLength = measuredLength;
|
|
22
|
+
this.limit = limit;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const PI_PACKAGE_NAME = '@earendil-works/pi-coding-agent';
|
|
26
|
+
const PI_PACKAGE_MANIFEST = `${PI_PACKAGE_NAME}/package.json`;
|
|
27
|
+
const WINDOWS_COMMAND_LINE_LIMIT = 32767;
|
|
28
|
+
const JAVASCRIPT_EXTENSIONS = new Set(['.js', '.cjs', '.mjs']);
|
|
29
|
+
const WINDOWS_NATIVE_EXTENSIONS = new Set(['.exe', '.com']);
|
|
30
|
+
class HostIsNotPiError extends Error {
|
|
31
|
+
constructor(message) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = 'HostIsNotPiError';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
class LaunchPathOperationError extends Error {
|
|
37
|
+
operation;
|
|
38
|
+
path;
|
|
39
|
+
pathCause;
|
|
40
|
+
constructor(operation, path, cause) {
|
|
41
|
+
super(`${operation} failed for ${path}: ${errorMessage(cause)}`, { cause });
|
|
42
|
+
this.name = 'LaunchPathOperationError';
|
|
43
|
+
this.operation = operation;
|
|
44
|
+
this.path = path;
|
|
45
|
+
this.pathCause = cause;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const nodeLaunchIo = {
|
|
49
|
+
readFile: (path) => readFileSync(path),
|
|
50
|
+
realpath: (path) => realpathSync(path),
|
|
51
|
+
stat: (path) => statSync(path),
|
|
52
|
+
access: (path, mode) => accessSync(path, mode),
|
|
53
|
+
};
|
|
54
|
+
function launchIo(deps) {
|
|
55
|
+
return {
|
|
56
|
+
readFile: deps.readFile ?? nodeLaunchIo.readFile,
|
|
57
|
+
realpath: deps.realpath ?? nodeLaunchIo.realpath,
|
|
58
|
+
stat: deps.stat ?? nodeLaunchIo.stat,
|
|
59
|
+
access: deps.access ?? nodeLaunchIo.access,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function failResolution(message) {
|
|
63
|
+
throw new PiLaunchResolutionError(message);
|
|
64
|
+
}
|
|
65
|
+
function errorMessage(error) {
|
|
66
|
+
return error instanceof Error ? error.message : String(error);
|
|
67
|
+
}
|
|
68
|
+
function pathOperation(label, path, action) {
|
|
69
|
+
try {
|
|
70
|
+
return action();
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
throw new LaunchPathOperationError(label, path, error);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function isMissingPathError(error) {
|
|
77
|
+
if (typeof error !== 'object' || error === null)
|
|
78
|
+
return false;
|
|
79
|
+
const code = Reflect.get(error, 'code');
|
|
80
|
+
return code === 'ENOENT' || code === 'ENOTDIR';
|
|
81
|
+
}
|
|
82
|
+
function isJsonRecord(value) {
|
|
83
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
84
|
+
}
|
|
85
|
+
function parseManifest(raw, manifestPath) {
|
|
86
|
+
let parsed;
|
|
87
|
+
try {
|
|
88
|
+
parsed = JSON.parse(Buffer.isBuffer(raw) ? raw.toString('utf8') : raw);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
throw new Error(`manifest JSON is invalid at ${manifestPath}: ${errorMessage(error)}`);
|
|
92
|
+
}
|
|
93
|
+
if (!isJsonRecord(parsed))
|
|
94
|
+
throw new Error(`manifest is not an object at ${manifestPath}`);
|
|
95
|
+
return parsed;
|
|
96
|
+
}
|
|
97
|
+
function packageName(manifest, manifestPath) {
|
|
98
|
+
const name = manifest['name'];
|
|
99
|
+
if (name === undefined)
|
|
100
|
+
return undefined;
|
|
101
|
+
if (typeof name !== 'string' || name.trim().length === 0) {
|
|
102
|
+
throw new Error(`manifest name is malformed at ${manifestPath}`);
|
|
103
|
+
}
|
|
104
|
+
return name;
|
|
105
|
+
}
|
|
106
|
+
function requirePiPackageName(manifest, manifestPath) {
|
|
107
|
+
const name = packageName(manifest, manifestPath);
|
|
108
|
+
if (name !== PI_PACKAGE_NAME) {
|
|
109
|
+
throw new Error(`manifest package name must be ${PI_PACKAGE_NAME} at ${manifestPath}; received ${name === undefined ? '<missing>' : name}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function readPiBin(manifest, manifestPath) {
|
|
113
|
+
const bin = manifest['bin'];
|
|
114
|
+
if (typeof bin === 'string' && bin.trim().length > 0)
|
|
115
|
+
return bin;
|
|
116
|
+
if (isJsonRecord(bin)) {
|
|
117
|
+
const pi = bin['pi'];
|
|
118
|
+
if (typeof pi === 'string' && pi.trim().length > 0)
|
|
119
|
+
return pi;
|
|
120
|
+
}
|
|
121
|
+
throw new Error(`manifest bin.pi is missing or malformed at ${manifestPath}`);
|
|
122
|
+
}
|
|
123
|
+
function pathInside(parent, child) {
|
|
124
|
+
const rel = relative(parent, child);
|
|
125
|
+
return rel === '' || (!isAbsolute(rel) && rel !== '..' && !rel.startsWith(`..${sep}`));
|
|
126
|
+
}
|
|
127
|
+
function findNearestNamedManifest(sourcePath, io) {
|
|
128
|
+
const sourceReal = pathOperation('source realpath', sourcePath, () => io.realpath(sourcePath));
|
|
129
|
+
let dir = dirname(sourceReal);
|
|
130
|
+
for (;;) {
|
|
131
|
+
const candidate = join(dir, 'package.json');
|
|
132
|
+
let candidateStat;
|
|
133
|
+
try {
|
|
134
|
+
candidateStat = io.stat(candidate);
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
if (!isMissingPathError(error)) {
|
|
138
|
+
throw new Error(`manifest stat failed for ${candidate}: ${errorMessage(error)}`);
|
|
139
|
+
}
|
|
140
|
+
const parent = dirname(dir);
|
|
141
|
+
if (parent === dir) {
|
|
142
|
+
throw new HostIsNotPiError(`no named package manifest above ${sourceReal}`);
|
|
143
|
+
}
|
|
144
|
+
dir = parent;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (!candidateStat.isFile()) {
|
|
148
|
+
throw new Error(`package boundary manifest is not a regular file at ${candidate}`);
|
|
149
|
+
}
|
|
150
|
+
const manifest = parseManifest(pathOperation('manifest read', candidate, () => io.readFile(candidate)), candidate);
|
|
151
|
+
const name = packageName(manifest, candidate);
|
|
152
|
+
if (name !== undefined)
|
|
153
|
+
return { manifestPath: candidate, sourceReal, name };
|
|
154
|
+
const parent = dirname(dir);
|
|
155
|
+
if (parent === dir) {
|
|
156
|
+
throw new HostIsNotPiError(`no named package manifest above ${sourceReal}`);
|
|
157
|
+
}
|
|
158
|
+
dir = parent;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function findPiManifestFromHostScript(hostScript, io) {
|
|
162
|
+
if (!hostScript)
|
|
163
|
+
throw new HostIsNotPiError('host script path is unavailable');
|
|
164
|
+
let found;
|
|
165
|
+
try {
|
|
166
|
+
found = findNearestNamedManifest(hostScript, io);
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
if (error instanceof HostIsNotPiError)
|
|
170
|
+
throw error;
|
|
171
|
+
if (error instanceof LaunchPathOperationError &&
|
|
172
|
+
error.operation === 'source realpath' &&
|
|
173
|
+
isMissingPathError(error.pathCause)) {
|
|
174
|
+
throw new HostIsNotPiError(error.message);
|
|
175
|
+
}
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
178
|
+
if (found.name !== PI_PACKAGE_NAME) {
|
|
179
|
+
throw new HostIsNotPiError(`nearest named manifest above host script belongs to ${found.name}: ${found.manifestPath}`);
|
|
180
|
+
}
|
|
181
|
+
return found;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Resolve only a genuine running Pi package. This helper performs package-boundary
|
|
185
|
+
* discovery; resolvePiLaunch() additionally validates bin.pi and host/bin identity.
|
|
186
|
+
*/
|
|
187
|
+
export function resolvePiManifestFromHostScript(hostScript, deps = {}) {
|
|
188
|
+
return findPiManifestFromHostScript(hostScript, launchIo(deps)).manifestPath;
|
|
189
|
+
}
|
|
190
|
+
function normalizeResolvedModulePath(pathOrUrl) {
|
|
191
|
+
return pathOrUrl.startsWith('file:') ? fileURLToPath(pathOrUrl) : pathOrUrl;
|
|
192
|
+
}
|
|
193
|
+
function defaultResolveModule(specifier) {
|
|
194
|
+
if (specifier === PI_PACKAGE_MANIFEST) {
|
|
195
|
+
return createRequire(import.meta.url).resolve(specifier);
|
|
196
|
+
}
|
|
197
|
+
return normalizeResolvedModulePath(import.meta.resolve(specifier));
|
|
198
|
+
}
|
|
199
|
+
function resolvePiManifestFromModules(deps, io) {
|
|
200
|
+
if (deps.resolvePackageJson) {
|
|
201
|
+
return normalizeResolvedModulePath(deps.resolvePackageJson(PI_PACKAGE_MANIFEST));
|
|
202
|
+
}
|
|
203
|
+
const resolveModule = deps.resolveModule ?? defaultResolveModule;
|
|
204
|
+
let manifestError;
|
|
205
|
+
try {
|
|
206
|
+
return normalizeResolvedModulePath(resolveModule(PI_PACKAGE_MANIFEST));
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
manifestError = error;
|
|
210
|
+
}
|
|
211
|
+
let packageEntry;
|
|
212
|
+
try {
|
|
213
|
+
packageEntry = normalizeResolvedModulePath(resolveModule(PI_PACKAGE_NAME));
|
|
214
|
+
}
|
|
215
|
+
catch (entryError) {
|
|
216
|
+
throw new Error(`package manifest resolve failed for ${PI_PACKAGE_MANIFEST}: ${errorMessage(manifestError)}; package entry resolve failed: ${errorMessage(entryError)}`);
|
|
217
|
+
}
|
|
218
|
+
let found;
|
|
219
|
+
try {
|
|
220
|
+
found = findNearestNamedManifest(packageEntry, io);
|
|
221
|
+
}
|
|
222
|
+
catch (searchError) {
|
|
223
|
+
throw new Error(`package manifest resolve failed for ${PI_PACKAGE_MANIFEST}: ${errorMessage(manifestError)}; package entry manifest search failed: ${errorMessage(searchError)}`);
|
|
224
|
+
}
|
|
225
|
+
if (found.name !== PI_PACKAGE_NAME) {
|
|
226
|
+
throw new Error(`package entry nearest named manifest belongs to ${found.name}: ${found.manifestPath}`);
|
|
227
|
+
}
|
|
228
|
+
return found.manifestPath;
|
|
229
|
+
}
|
|
230
|
+
function executableBasename(execPath, platform) {
|
|
231
|
+
return platform === 'win32' ? win32Path.basename(execPath) : basename(execPath);
|
|
232
|
+
}
|
|
233
|
+
function isGenericJavaScriptRuntime(execPath, platform) {
|
|
234
|
+
return /^(?:node|nodejs|bun)(?:\.exe)?$/i.test(executableBasename(execPath, platform));
|
|
235
|
+
}
|
|
236
|
+
function resolveCompiledHostLaunch(deps, io, platform) {
|
|
237
|
+
const execPath = deps.execPath ?? process.execPath;
|
|
238
|
+
const executableName = executableBasename(execPath, platform);
|
|
239
|
+
const isNamedPiExecutable = platform === 'win32' ? /^pi\.(?:exe|com)$/i.test(executableName) : executableName === 'pi';
|
|
240
|
+
// A Bun virtual script path describes packaging mechanics shared by every
|
|
241
|
+
// compiled SDK application; it is not Pi CLI authority. Retain the direct
|
|
242
|
+
// route only for the established Pi executable name.
|
|
243
|
+
if (isGenericJavaScriptRuntime(execPath, platform) || !isNamedPiExecutable)
|
|
244
|
+
return undefined;
|
|
245
|
+
const executableReal = pathOperation('compiled host realpath', execPath, () => io.realpath(execPath));
|
|
246
|
+
const executableStat = pathOperation('compiled host stat', executableReal, () => io.stat(executableReal));
|
|
247
|
+
if (!executableStat.isFile())
|
|
248
|
+
throw new Error('compiled Pi host is not a regular file');
|
|
249
|
+
if (platform === 'win32') {
|
|
250
|
+
if (!WINDOWS_NATIVE_EXTENSIONS.has(extname(executableReal).toLowerCase())) {
|
|
251
|
+
throw new Error('compiled Windows Pi host must be an .exe or .com file');
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
pathOperation('compiled host execute access', executableReal, () => io.access(executableReal, constants.X_OK));
|
|
256
|
+
}
|
|
257
|
+
return { executable: executableReal, argvPrefix: [], kind: 'compiled-host' };
|
|
258
|
+
}
|
|
259
|
+
function resolvePackageLaunch(manifestPath, deps, io, platform, expectedHostReal) {
|
|
260
|
+
const manifestReal = pathOperation('manifest realpath', manifestPath, () => io.realpath(manifestPath));
|
|
261
|
+
if (basename(manifestReal).toLowerCase() !== 'package.json') {
|
|
262
|
+
throw new Error(`resolved Pi manifest is not package.json: ${manifestReal}`);
|
|
263
|
+
}
|
|
264
|
+
const manifestStat = pathOperation('manifest stat', manifestReal, () => io.stat(manifestReal));
|
|
265
|
+
if (!manifestStat.isFile())
|
|
266
|
+
throw new Error(`Pi package manifest is not a regular file: ${manifestReal}`);
|
|
267
|
+
const manifest = parseManifest(pathOperation('manifest read', manifestReal, () => io.readFile(manifestReal)), manifestReal);
|
|
268
|
+
requirePiPackageName(manifest, manifestReal);
|
|
269
|
+
const packageRootReal = pathOperation('package root realpath', dirname(manifestReal), () => io.realpath(dirname(manifestReal)));
|
|
270
|
+
if (!pathInside(packageRootReal, manifestReal)) {
|
|
271
|
+
throw new Error('Pi package manifest resolves outside the package root');
|
|
272
|
+
}
|
|
273
|
+
const bin = readPiBin(manifest, manifestReal);
|
|
274
|
+
if (isAbsolute(bin) ||
|
|
275
|
+
(platform === 'win32' && (win32Path.isAbsolute(bin) || /^[a-z]:/i.test(bin))))
|
|
276
|
+
throw new Error('Pi package bin target must not be absolute; it must be relative to the package root');
|
|
277
|
+
const targetCandidate = resolve(packageRootReal, bin);
|
|
278
|
+
if (!pathInside(packageRootReal, targetCandidate)) {
|
|
279
|
+
throw new Error('Pi package bin target path escapes the package root');
|
|
280
|
+
}
|
|
281
|
+
const targetReal = pathOperation('bin target realpath', targetCandidate, () => io.realpath(targetCandidate));
|
|
282
|
+
if (!pathInside(packageRootReal, targetReal)) {
|
|
283
|
+
throw new Error('Pi package bin target resolves outside the package root');
|
|
284
|
+
}
|
|
285
|
+
const targetStat = pathOperation('bin target stat', targetReal, () => io.stat(targetReal));
|
|
286
|
+
if (!targetStat.isFile())
|
|
287
|
+
throw new Error('Pi package bin target is not a regular file');
|
|
288
|
+
if (expectedHostReal !== undefined && targetReal !== expectedHostReal) {
|
|
289
|
+
throw new Error(`running host script does not match manifest bin.pi: host ${expectedHostReal}; bin ${targetReal}`);
|
|
290
|
+
}
|
|
291
|
+
const extension = extname(targetReal).toLowerCase();
|
|
292
|
+
if (JAVASCRIPT_EXTENSIONS.has(extension)) {
|
|
293
|
+
const execPath = deps.execPath ?? process.execPath;
|
|
294
|
+
if (!isGenericJavaScriptRuntime(execPath, platform)) {
|
|
295
|
+
throw new Error(`Pi package JavaScript bin cannot launch through a non-generic JavaScript runtime: ${execPath}`);
|
|
296
|
+
}
|
|
297
|
+
return { executable: execPath, argvPrefix: [targetReal], kind: 'package-node-cli' };
|
|
298
|
+
}
|
|
299
|
+
if (platform === 'win32' && WINDOWS_NATIVE_EXTENSIONS.has(extension)) {
|
|
300
|
+
// Keep the historical package launch kind for compatibility; argvPrefix
|
|
301
|
+
// distinguishes this direct native form from the JavaScript package form.
|
|
302
|
+
return { executable: targetReal, argvPrefix: [], kind: 'package-node-cli' };
|
|
303
|
+
}
|
|
304
|
+
throw new Error(`Pi package bin target extension is unsupported: ${extension || '<none>'}`);
|
|
305
|
+
}
|
|
306
|
+
function resolveExecutableOnPosixPath(deps, io) {
|
|
307
|
+
const rawPath = deps.path ?? process.env['PATH'] ?? '';
|
|
308
|
+
const diagnostics = [];
|
|
309
|
+
if (rawPath.length === 0)
|
|
310
|
+
diagnostics.push('PATH is empty');
|
|
311
|
+
for (const entry of rawPath.split(delimiter)) {
|
|
312
|
+
const directory = entry.length === 0 ? process.cwd() : entry;
|
|
313
|
+
const candidate = resolve(directory, 'pi');
|
|
314
|
+
let candidateReal;
|
|
315
|
+
try {
|
|
316
|
+
candidateReal = io.realpath(candidate);
|
|
317
|
+
}
|
|
318
|
+
catch (error) {
|
|
319
|
+
diagnostics.push(`${candidate}: ${errorMessage(error)}`);
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
try {
|
|
323
|
+
if (!io.stat(candidateReal).isFile()) {
|
|
324
|
+
diagnostics.push(`${candidateReal} is not a regular file`);
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
io.access(candidateReal, constants.X_OK);
|
|
328
|
+
}
|
|
329
|
+
catch (error) {
|
|
330
|
+
diagnostics.push(`${candidateReal} is not executable: ${errorMessage(error)}`);
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
return {
|
|
334
|
+
// Bind the launch plan to the exact canonical executable admitted above.
|
|
335
|
+
// A later cwd or environment/PATH change must not trigger a second lookup.
|
|
336
|
+
launch: { executable: candidateReal, argvPrefix: [], kind: 'path' },
|
|
337
|
+
diagnostics,
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
return { diagnostics };
|
|
341
|
+
}
|
|
342
|
+
export function resolvePiLaunch(deps = {}) {
|
|
343
|
+
const platform = deps.platform ?? process.platform;
|
|
344
|
+
const io = launchIo(deps);
|
|
345
|
+
try {
|
|
346
|
+
const compiled = resolveCompiledHostLaunch(deps, io, platform);
|
|
347
|
+
if (compiled)
|
|
348
|
+
return compiled;
|
|
349
|
+
}
|
|
350
|
+
catch (error) {
|
|
351
|
+
failResolution(errorMessage(error));
|
|
352
|
+
}
|
|
353
|
+
const hostScript = deps.hostScript ?? process.argv[1];
|
|
354
|
+
let pathDiagnostic;
|
|
355
|
+
if (platform !== 'win32') {
|
|
356
|
+
const pathResult = resolveExecutableOnPosixPath(deps, io);
|
|
357
|
+
if (pathResult.launch)
|
|
358
|
+
return pathResult.launch;
|
|
359
|
+
pathDiagnostic = `no executable pi on PATH (${pathResult.diagnostics.join('; ') || 'no candidates'})`;
|
|
360
|
+
}
|
|
361
|
+
let hostDiagnostic = 'host script was not inspected';
|
|
362
|
+
try {
|
|
363
|
+
const host = findPiManifestFromHostScript(hostScript, io);
|
|
364
|
+
// A manifest that identifies the running host as Pi is authoritative. Never
|
|
365
|
+
// hide its invalid bin/identity behind another module installation.
|
|
366
|
+
return resolvePackageLaunch(host.manifestPath, deps, io, platform, host.sourceReal);
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
// Only genuine absence or a positively foreign package identity permits the
|
|
370
|
+
// exact installed-module route. I/O and integrity failures remain fatal.
|
|
371
|
+
if (!(error instanceof HostIsNotPiError))
|
|
372
|
+
failResolution(errorMessage(error));
|
|
373
|
+
hostDiagnostic = errorMessage(error);
|
|
374
|
+
}
|
|
375
|
+
let manifestPath;
|
|
376
|
+
try {
|
|
377
|
+
manifestPath = resolvePiManifestFromModules(deps, io);
|
|
378
|
+
}
|
|
379
|
+
catch (error) {
|
|
380
|
+
const prefix = pathDiagnostic === undefined ? '' : `${pathDiagnostic}; `;
|
|
381
|
+
failResolution(`${prefix}${errorMessage(error)}; running host lookup: ${hostDiagnostic}`);
|
|
382
|
+
}
|
|
383
|
+
try {
|
|
384
|
+
return resolvePackageLaunch(manifestPath, deps, io, platform);
|
|
385
|
+
}
|
|
386
|
+
catch (error) {
|
|
387
|
+
failResolution(errorMessage(error));
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
export function piLaunchArgv(launch, piArgs) {
|
|
391
|
+
return [...launch.argvPrefix, ...piArgs];
|
|
392
|
+
}
|
|
393
|
+
function renderWindowsArgument(value) {
|
|
394
|
+
if (value.length > 0 && !/[ \t"]/.test(value))
|
|
395
|
+
return value;
|
|
396
|
+
let rendered = '"';
|
|
397
|
+
let backslashes = 0;
|
|
398
|
+
for (const char of value) {
|
|
399
|
+
if (char === '\\') {
|
|
400
|
+
backslashes += 1;
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
if (char === '"') {
|
|
404
|
+
rendered += '\\'.repeat(backslashes * 2 + 1);
|
|
405
|
+
rendered += '"';
|
|
406
|
+
backslashes = 0;
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
if (backslashes > 0) {
|
|
410
|
+
rendered += '\\'.repeat(backslashes);
|
|
411
|
+
backslashes = 0;
|
|
412
|
+
}
|
|
413
|
+
rendered += char;
|
|
414
|
+
}
|
|
415
|
+
if (backslashes > 0)
|
|
416
|
+
rendered += '\\'.repeat(backslashes * 2);
|
|
417
|
+
rendered += '"';
|
|
418
|
+
return rendered;
|
|
419
|
+
}
|
|
420
|
+
function renderWindowsCommandLine(parts) {
|
|
421
|
+
return parts.map(renderWindowsArgument).join(' ');
|
|
422
|
+
}
|
|
423
|
+
export function assertWindowsCommandLineWithinLimit(launch, piArgs, platform, stage) {
|
|
424
|
+
if (platform !== 'win32')
|
|
425
|
+
return;
|
|
426
|
+
const measuredLength = renderWindowsCommandLine([launch.executable, ...launch.argvPrefix, ...piArgs]).length + 1;
|
|
427
|
+
if (measuredLength > WINDOWS_COMMAND_LINE_LIMIT) {
|
|
428
|
+
throw new PiCommandLineLimitError(stage, measuredLength, WINDOWS_COMMAND_LINE_LIMIT);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
//# sourceMappingURL=pi-launch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi-launch.js","sourceRoot":"","sources":["../../../src/core/pi-launch.ts"],"names":[],"mappings":"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","sourcesContent":["import { accessSync, constants, readFileSync, realpathSync, statSync } from 'node:fs';\nimport type { Stats } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport {\n basename,\n delimiter,\n dirname,\n extname,\n isAbsolute,\n join,\n relative,\n resolve,\n sep,\n win32 as win32Path,\n} from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport interface PiLaunchSpec {\n readonly executable: string;\n readonly argvPrefix: readonly string[];\n readonly kind: 'path' | 'package-node-cli' | 'compiled-host';\n}\n\nexport interface PiLaunchDependencies {\n readonly platform?: NodeJS.Platform;\n readonly execPath?: string;\n readonly hostScript?: string;\n readonly path?: string;\n readonly resolvePackageJson?: (specifier: string) => string;\n readonly resolveModule?: (specifier: string) => string;\n readonly readFile?: (path: string) => string | Buffer;\n readonly realpath?: (path: string) => string;\n readonly stat?: (path: string) => Pick<Stats, 'isFile'>;\n readonly access?: (path: string, mode?: number) => void;\n}\n\nexport class PiLaunchResolutionError extends Error {\n readonly code = 'pi_executable_resolution_failed';\n\n constructor(message: string) {\n super(`pi_executable_resolution_failed: ${message}`);\n this.name = 'PiLaunchResolutionError';\n }\n}\n\nexport class PiCommandLineLimitError extends Error {\n readonly code = 'pi_command_line_too_long';\n readonly stage: string;\n readonly measuredLength: number;\n readonly limit: number;\n\n constructor(stage: string, measuredLength: number, limit: number) {\n super(\n `pi_command_line_too_long: ${stage} measured UTF-16 command line length ${String(measuredLength)} exceeds limit ${String(limit)}`,\n );\n this.name = 'PiCommandLineLimitError';\n this.stage = stage;\n this.measuredLength = measuredLength;\n this.limit = limit;\n }\n}\n\nconst PI_PACKAGE_NAME = '@earendil-works/pi-coding-agent';\nconst PI_PACKAGE_MANIFEST = `${PI_PACKAGE_NAME}/package.json`;\nconst WINDOWS_COMMAND_LINE_LIMIT = 32767;\nconst JAVASCRIPT_EXTENSIONS = new Set(['.js', '.cjs', '.mjs']);\nconst WINDOWS_NATIVE_EXTENSIONS = new Set(['.exe', '.com']);\n\ninterface JsonRecord {\n readonly [key: string]: unknown;\n}\n\ninterface LaunchIo {\n readonly readFile: (path: string) => string | Buffer;\n readonly realpath: (path: string) => string;\n readonly stat: (path: string) => Pick<Stats, 'isFile'>;\n readonly access: (path: string, mode?: number) => void;\n}\n\ninterface NamedManifest {\n readonly manifestPath: string;\n readonly sourceReal: string;\n readonly name: string;\n}\n\nclass HostIsNotPiError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'HostIsNotPiError';\n }\n}\n\nclass LaunchPathOperationError extends Error {\n readonly operation: string;\n readonly path: string;\n readonly pathCause: unknown;\n\n constructor(operation: string, path: string, cause: unknown) {\n super(`${operation} failed for ${path}: ${errorMessage(cause)}`, { cause });\n this.name = 'LaunchPathOperationError';\n this.operation = operation;\n this.path = path;\n this.pathCause = cause;\n }\n}\n\nconst nodeLaunchIo: LaunchIo = {\n readFile: (path) => readFileSync(path),\n realpath: (path) => realpathSync(path),\n stat: (path) => statSync(path),\n access: (path, mode) => accessSync(path, mode),\n};\n\nfunction launchIo(deps: PiLaunchDependencies): LaunchIo {\n return {\n readFile: deps.readFile ?? nodeLaunchIo.readFile,\n realpath: deps.realpath ?? nodeLaunchIo.realpath,\n stat: deps.stat ?? nodeLaunchIo.stat,\n access: deps.access ?? nodeLaunchIo.access,\n };\n}\n\nfunction failResolution(message: string): never {\n throw new PiLaunchResolutionError(message);\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction pathOperation<T>(label: string, path: string, action: () => T): T {\n try {\n return action();\n } catch (error) {\n throw new LaunchPathOperationError(label, path, error);\n }\n}\n\nfunction isMissingPathError(error: unknown): boolean {\n if (typeof error !== 'object' || error === null) return false;\n const code = Reflect.get(error, 'code');\n return code === 'ENOENT' || code === 'ENOTDIR';\n}\n\nfunction isJsonRecord(value: unknown): value is JsonRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseManifest(raw: string | Buffer, manifestPath: string): JsonRecord {\n let parsed: unknown;\n try {\n parsed = JSON.parse(Buffer.isBuffer(raw) ? raw.toString('utf8') : raw);\n } catch (error) {\n throw new Error(`manifest JSON is invalid at ${manifestPath}: ${errorMessage(error)}`);\n }\n if (!isJsonRecord(parsed)) throw new Error(`manifest is not an object at ${manifestPath}`);\n return parsed;\n}\n\nfunction packageName(manifest: JsonRecord, manifestPath: string): string | undefined {\n const name = manifest['name'];\n if (name === undefined) return undefined;\n if (typeof name !== 'string' || name.trim().length === 0) {\n throw new Error(`manifest name is malformed at ${manifestPath}`);\n }\n return name;\n}\n\nfunction requirePiPackageName(manifest: JsonRecord, manifestPath: string): void {\n const name = packageName(manifest, manifestPath);\n if (name !== PI_PACKAGE_NAME) {\n throw new Error(\n `manifest package name must be ${PI_PACKAGE_NAME} at ${manifestPath}; received ${name === undefined ? '<missing>' : name}`,\n );\n }\n}\n\nfunction readPiBin(manifest: JsonRecord, manifestPath: string): string {\n const bin = manifest['bin'];\n if (typeof bin === 'string' && bin.trim().length > 0) return bin;\n if (isJsonRecord(bin)) {\n const pi = bin['pi'];\n if (typeof pi === 'string' && pi.trim().length > 0) return pi;\n }\n throw new Error(`manifest bin.pi is missing or malformed at ${manifestPath}`);\n}\n\nfunction pathInside(parent: string, child: string): boolean {\n const rel = relative(parent, child);\n return rel === '' || (!isAbsolute(rel) && rel !== '..' && !rel.startsWith(`..${sep}`));\n}\n\nfunction findNearestNamedManifest(sourcePath: string, io: LaunchIo): NamedManifest {\n const sourceReal = pathOperation('source realpath', sourcePath, () => io.realpath(sourcePath));\n let dir = dirname(sourceReal);\n for (;;) {\n const candidate = join(dir, 'package.json');\n let candidateStat: Pick<Stats, 'isFile'>;\n try {\n candidateStat = io.stat(candidate);\n } catch (error) {\n if (!isMissingPathError(error)) {\n throw new Error(`manifest stat failed for ${candidate}: ${errorMessage(error)}`);\n }\n const parent = dirname(dir);\n if (parent === dir) {\n throw new HostIsNotPiError(`no named package manifest above ${sourceReal}`);\n }\n dir = parent;\n continue;\n }\n if (!candidateStat.isFile()) {\n throw new Error(`package boundary manifest is not a regular file at ${candidate}`);\n }\n const manifest = parseManifest(\n pathOperation('manifest read', candidate, () => io.readFile(candidate)),\n candidate,\n );\n const name = packageName(manifest, candidate);\n if (name !== undefined) return { manifestPath: candidate, sourceReal, name };\n\n const parent = dirname(dir);\n if (parent === dir) {\n throw new HostIsNotPiError(`no named package manifest above ${sourceReal}`);\n }\n dir = parent;\n }\n}\n\nfunction findPiManifestFromHostScript(hostScript: string | undefined, io: LaunchIo): NamedManifest {\n if (!hostScript) throw new HostIsNotPiError('host script path is unavailable');\n let found: NamedManifest;\n try {\n found = findNearestNamedManifest(hostScript, io);\n } catch (error) {\n if (error instanceof HostIsNotPiError) throw error;\n if (\n error instanceof LaunchPathOperationError &&\n error.operation === 'source realpath' &&\n isMissingPathError(error.pathCause)\n ) {\n throw new HostIsNotPiError(error.message);\n }\n throw error;\n }\n if (found.name !== PI_PACKAGE_NAME) {\n throw new HostIsNotPiError(\n `nearest named manifest above host script belongs to ${found.name}: ${found.manifestPath}`,\n );\n }\n return found;\n}\n\n/**\n * Resolve only a genuine running Pi package. This helper performs package-boundary\n * discovery; resolvePiLaunch() additionally validates bin.pi and host/bin identity.\n */\nexport function resolvePiManifestFromHostScript(\n hostScript: string | undefined,\n deps: Pick<PiLaunchDependencies, 'readFile' | 'realpath' | 'stat' | 'access'> = {},\n): string {\n return findPiManifestFromHostScript(hostScript, launchIo(deps)).manifestPath;\n}\n\nfunction normalizeResolvedModulePath(pathOrUrl: string): string {\n return pathOrUrl.startsWith('file:') ? fileURLToPath(pathOrUrl) : pathOrUrl;\n}\n\nfunction defaultResolveModule(specifier: string): string {\n if (specifier === PI_PACKAGE_MANIFEST) {\n return createRequire(import.meta.url).resolve(specifier);\n }\n return normalizeResolvedModulePath(import.meta.resolve(specifier));\n}\n\nfunction resolvePiManifestFromModules(deps: PiLaunchDependencies, io: LaunchIo): string {\n if (deps.resolvePackageJson) {\n return normalizeResolvedModulePath(deps.resolvePackageJson(PI_PACKAGE_MANIFEST));\n }\n\n const resolveModule = deps.resolveModule ?? defaultResolveModule;\n let manifestError: unknown;\n try {\n return normalizeResolvedModulePath(resolveModule(PI_PACKAGE_MANIFEST));\n } catch (error) {\n manifestError = error;\n }\n\n let packageEntry: string;\n try {\n packageEntry = normalizeResolvedModulePath(resolveModule(PI_PACKAGE_NAME));\n } catch (entryError) {\n throw new Error(\n `package manifest resolve failed for ${PI_PACKAGE_MANIFEST}: ${errorMessage(manifestError)}; package entry resolve failed: ${errorMessage(entryError)}`,\n );\n }\n\n let found: NamedManifest;\n try {\n found = findNearestNamedManifest(packageEntry, io);\n } catch (searchError) {\n throw new Error(\n `package manifest resolve failed for ${PI_PACKAGE_MANIFEST}: ${errorMessage(manifestError)}; package entry manifest search failed: ${errorMessage(searchError)}`,\n );\n }\n if (found.name !== PI_PACKAGE_NAME) {\n throw new Error(\n `package entry nearest named manifest belongs to ${found.name}: ${found.manifestPath}`,\n );\n }\n return found.manifestPath;\n}\n\nfunction executableBasename(execPath: string, platform: NodeJS.Platform): string {\n return platform === 'win32' ? win32Path.basename(execPath) : basename(execPath);\n}\n\nfunction isGenericJavaScriptRuntime(execPath: string, platform: NodeJS.Platform): boolean {\n return /^(?:node|nodejs|bun)(?:\\.exe)?$/i.test(executableBasename(execPath, platform));\n}\n\nfunction resolveCompiledHostLaunch(\n deps: PiLaunchDependencies,\n io: LaunchIo,\n platform: NodeJS.Platform,\n): PiLaunchSpec | undefined {\n const execPath = deps.execPath ?? process.execPath;\n const executableName = executableBasename(execPath, platform);\n const isNamedPiExecutable =\n platform === 'win32' ? /^pi\\.(?:exe|com)$/i.test(executableName) : executableName === 'pi';\n // A Bun virtual script path describes packaging mechanics shared by every\n // compiled SDK application; it is not Pi CLI authority. Retain the direct\n // route only for the established Pi executable name.\n if (isGenericJavaScriptRuntime(execPath, platform) || !isNamedPiExecutable) return undefined;\n\n const executableReal = pathOperation('compiled host realpath', execPath, () => io.realpath(execPath));\n const executableStat = pathOperation('compiled host stat', executableReal, () =>\n io.stat(executableReal),\n );\n if (!executableStat.isFile()) throw new Error('compiled Pi host is not a regular file');\n if (platform === 'win32') {\n if (!WINDOWS_NATIVE_EXTENSIONS.has(extname(executableReal).toLowerCase())) {\n throw new Error('compiled Windows Pi host must be an .exe or .com file');\n }\n } else {\n pathOperation('compiled host execute access', executableReal, () =>\n io.access(executableReal, constants.X_OK),\n );\n }\n return { executable: executableReal, argvPrefix: [], kind: 'compiled-host' };\n}\n\nfunction resolvePackageLaunch(\n manifestPath: string,\n deps: PiLaunchDependencies,\n io: LaunchIo,\n platform: NodeJS.Platform,\n expectedHostReal?: string,\n): PiLaunchSpec {\n const manifestReal = pathOperation('manifest realpath', manifestPath, () => io.realpath(manifestPath));\n if (basename(manifestReal).toLowerCase() !== 'package.json') {\n throw new Error(`resolved Pi manifest is not package.json: ${manifestReal}`);\n }\n const manifestStat = pathOperation('manifest stat', manifestReal, () => io.stat(manifestReal));\n if (!manifestStat.isFile()) throw new Error(`Pi package manifest is not a regular file: ${manifestReal}`);\n\n const manifest = parseManifest(\n pathOperation('manifest read', manifestReal, () => io.readFile(manifestReal)),\n manifestReal,\n );\n requirePiPackageName(manifest, manifestReal);\n const packageRootReal = pathOperation('package root realpath', dirname(manifestReal), () =>\n io.realpath(dirname(manifestReal)),\n );\n if (!pathInside(packageRootReal, manifestReal)) {\n throw new Error('Pi package manifest resolves outside the package root');\n }\n\n const bin = readPiBin(manifest, manifestReal);\n if (\n isAbsolute(bin) ||\n (platform === 'win32' && (win32Path.isAbsolute(bin) || /^[a-z]:/i.test(bin)))\n )\n throw new Error('Pi package bin target must not be absolute; it must be relative to the package root');\n const targetCandidate = resolve(packageRootReal, bin);\n if (!pathInside(packageRootReal, targetCandidate)) {\n throw new Error('Pi package bin target path escapes the package root');\n }\n const targetReal = pathOperation('bin target realpath', targetCandidate, () =>\n io.realpath(targetCandidate),\n );\n if (!pathInside(packageRootReal, targetReal)) {\n throw new Error('Pi package bin target resolves outside the package root');\n }\n const targetStat = pathOperation('bin target stat', targetReal, () => io.stat(targetReal));\n if (!targetStat.isFile()) throw new Error('Pi package bin target is not a regular file');\n if (expectedHostReal !== undefined && targetReal !== expectedHostReal) {\n throw new Error(\n `running host script does not match manifest bin.pi: host ${expectedHostReal}; bin ${targetReal}`,\n );\n }\n\n const extension = extname(targetReal).toLowerCase();\n if (JAVASCRIPT_EXTENSIONS.has(extension)) {\n const execPath = deps.execPath ?? process.execPath;\n if (!isGenericJavaScriptRuntime(execPath, platform)) {\n throw new Error(\n `Pi package JavaScript bin cannot launch through a non-generic JavaScript runtime: ${execPath}`,\n );\n }\n return { executable: execPath, argvPrefix: [targetReal], kind: 'package-node-cli' };\n }\n if (platform === 'win32' && WINDOWS_NATIVE_EXTENSIONS.has(extension)) {\n // Keep the historical package launch kind for compatibility; argvPrefix\n // distinguishes this direct native form from the JavaScript package form.\n return { executable: targetReal, argvPrefix: [], kind: 'package-node-cli' };\n }\n throw new Error(`Pi package bin target extension is unsupported: ${extension || '<none>'}`);\n}\n\nfunction resolveExecutableOnPosixPath(\n deps: PiLaunchDependencies,\n io: LaunchIo,\n): { readonly launch?: PiLaunchSpec; readonly diagnostics: readonly string[] } {\n const rawPath = deps.path ?? process.env['PATH'] ?? '';\n const diagnostics: string[] = [];\n if (rawPath.length === 0) diagnostics.push('PATH is empty');\n for (const entry of rawPath.split(delimiter)) {\n const directory = entry.length === 0 ? process.cwd() : entry;\n const candidate = resolve(directory, 'pi');\n let candidateReal: string;\n try {\n candidateReal = io.realpath(candidate);\n } catch (error) {\n diagnostics.push(`${candidate}: ${errorMessage(error)}`);\n continue;\n }\n try {\n if (!io.stat(candidateReal).isFile()) {\n diagnostics.push(`${candidateReal} is not a regular file`);\n continue;\n }\n io.access(candidateReal, constants.X_OK);\n } catch (error) {\n diagnostics.push(`${candidateReal} is not executable: ${errorMessage(error)}`);\n continue;\n }\n return {\n // Bind the launch plan to the exact canonical executable admitted above.\n // A later cwd or environment/PATH change must not trigger a second lookup.\n launch: { executable: candidateReal, argvPrefix: [], kind: 'path' },\n diagnostics,\n };\n }\n return { diagnostics };\n}\n\nexport function resolvePiLaunch(deps: PiLaunchDependencies = {}): PiLaunchSpec {\n const platform = deps.platform ?? process.platform;\n const io = launchIo(deps);\n\n try {\n const compiled = resolveCompiledHostLaunch(deps, io, platform);\n if (compiled) return compiled;\n } catch (error) {\n failResolution(errorMessage(error));\n }\n\n const hostScript = deps.hostScript ?? process.argv[1];\n let pathDiagnostic: string | undefined;\n if (platform !== 'win32') {\n const pathResult = resolveExecutableOnPosixPath(deps, io);\n if (pathResult.launch) return pathResult.launch;\n pathDiagnostic = `no executable pi on PATH (${pathResult.diagnostics.join('; ') || 'no candidates'})`;\n }\n\n let hostDiagnostic = 'host script was not inspected';\n try {\n const host = findPiManifestFromHostScript(hostScript, io);\n // A manifest that identifies the running host as Pi is authoritative. Never\n // hide its invalid bin/identity behind another module installation.\n return resolvePackageLaunch(host.manifestPath, deps, io, platform, host.sourceReal);\n } catch (error) {\n // Only genuine absence or a positively foreign package identity permits the\n // exact installed-module route. I/O and integrity failures remain fatal.\n if (!(error instanceof HostIsNotPiError)) failResolution(errorMessage(error));\n hostDiagnostic = errorMessage(error);\n }\n\n let manifestPath: string;\n try {\n manifestPath = resolvePiManifestFromModules(deps, io);\n } catch (error) {\n const prefix = pathDiagnostic === undefined ? '' : `${pathDiagnostic}; `;\n failResolution(`${prefix}${errorMessage(error)}; running host lookup: ${hostDiagnostic}`);\n }\n try {\n return resolvePackageLaunch(manifestPath, deps, io, platform);\n } catch (error) {\n failResolution(errorMessage(error));\n }\n}\n\nexport function piLaunchArgv(launch: PiLaunchSpec, piArgs: readonly string[]): string[] {\n return [...launch.argvPrefix, ...piArgs];\n}\n\nfunction renderWindowsArgument(value: string): string {\n if (value.length > 0 && !/[ \\t\"]/.test(value)) return value;\n let rendered = '\"';\n let backslashes = 0;\n for (const char of value) {\n if (char === '\\\\') {\n backslashes += 1;\n continue;\n }\n if (char === '\"') {\n rendered += '\\\\'.repeat(backslashes * 2 + 1);\n rendered += '\"';\n backslashes = 0;\n continue;\n }\n if (backslashes > 0) {\n rendered += '\\\\'.repeat(backslashes);\n backslashes = 0;\n }\n rendered += char;\n }\n if (backslashes > 0) rendered += '\\\\'.repeat(backslashes * 2);\n rendered += '\"';\n return rendered;\n}\n\nfunction renderWindowsCommandLine(parts: readonly string[]): string {\n return parts.map(renderWindowsArgument).join(' ');\n}\n\nexport function assertWindowsCommandLineWithinLimit(\n launch: PiLaunchSpec,\n piArgs: readonly string[],\n platform: NodeJS.Platform,\n stage: string,\n): void {\n if (platform !== 'win32') return;\n const measuredLength =\n renderWindowsCommandLine([launch.executable, ...launch.argvPrefix, ...piArgs]).length + 1;\n if (measuredLength > WINDOWS_COMMAND_LINE_LIMIT) {\n throw new PiCommandLineLimitError(stage, measuredLength, WINDOWS_COMMAND_LINE_LIMIT);\n }\n}\n"]}
|