@pi-unipi/background-tasks 2.6.1
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/README.md +87 -0
- package/extensions/anthropic-attribution.ts +1 -0
- package/extensions/delegate-child.ts +1 -0
- package/extensions/fusion-child.ts +1 -0
- package/package.json +40 -0
- package/src/__tests__/anthropic-attribution.test.ts +195 -0
- package/src/__tests__/config.test.ts +137 -0
- package/src/__tests__/core.test.ts +493 -0
- package/src/__tests__/delegate-artifacts.test.ts +528 -0
- package/src/__tests__/delegate-budget.test.ts +456 -0
- package/src/__tests__/delegate-launch.test.ts +676 -0
- package/src/__tests__/delegate-result-package.test.ts +350 -0
- package/src/__tests__/delegate-seed.test.ts +392 -0
- package/src/__tests__/durable-fs.test.ts +559 -0
- package/src/__tests__/extension-api.test.ts +579 -0
- package/src/__tests__/fusion-artifacts.test.ts +1039 -0
- package/src/__tests__/fusion-budget.test.ts +1356 -0
- package/src/__tests__/fusion-claude-cache.test.ts +320 -0
- package/src/__tests__/fusion-config.test.ts +335 -0
- package/src/__tests__/fusion-context-prompts.test.ts +670 -0
- package/src/__tests__/fusion-evaluation.test.ts +315 -0
- package/src/__tests__/fusion-extraction-equivalence.test.ts +58 -0
- package/src/__tests__/fusion-golden-bytes.test.ts +35 -0
- package/src/__tests__/fusion-high-cardinality.test.ts +192 -0
- package/src/__tests__/fusion-model-selector.test.ts +205 -0
- package/src/__tests__/fusion-orchestrator.test.ts +1194 -0
- package/src/__tests__/fusion-rpc.test.ts +369 -0
- package/src/__tests__/fusion-sdk.test.ts +1226 -0
- package/src/__tests__/fusion-v5-core.test.ts +219 -0
- package/src/__tests__/fusion-validate-orchestrator.test.ts +240 -0
- package/src/__tests__/fusion-web-fetch.test.ts +485 -0
- package/src/__tests__/fusion-workflows.test.ts +59 -0
- package/src/__tests__/helpers/delegate-deterministic-seed.ts +109 -0
- package/src/__tests__/helpers/delegate-seed-subprocess.ts +10 -0
- package/src/__tests__/helpers/fusion-canonical-subprocess.ts +21 -0
- package/src/__tests__/helpers/fusion-canonical.ts +140 -0
- package/src/__tests__/helpers/fusion-fake-pi.ts +279 -0
- package/src/__tests__/helpers/fusion-golden-corpus.ts +500 -0
- package/src/__tests__/helpers/fusion-high-cardinality.ts +140 -0
- package/src/__tests__/helpers/normalize.ts +22 -0
- package/src/__tests__/helpers/pi-hook-contract-evidence.json +18 -0
- package/src/__tests__/pi-launch.test.ts +202 -0
- package/src/__tests__/registry.test.ts +1580 -0
- package/src/__tests__/scripted-provider/delegate-ambient-provider.test.ts +130 -0
- package/src/__tests__/scripted-provider/delegate-child-guard.test.ts +631 -0
- package/src/__tests__/scripted-provider/delegate-guard-provider.ts +403 -0
- package/src/__tests__/scripted-provider/follow-up.test.ts +448 -0
- package/src/__tests__/scripted-provider/fusion-output-recovery.test.ts +132 -0
- package/src/__tests__/scripted-provider/fusion-reason.test.ts +310 -0
- package/src/__tests__/scripted-provider/fusion-runtime-guard.test.ts +163 -0
- package/src/__tests__/scripted-provider/hook-contract-provider.ts +179 -0
- package/src/__tests__/scripted-provider/hook-probe-a.ts +3 -0
- package/src/__tests__/scripted-provider/hook-probe-b.ts +3 -0
- package/src/__tests__/scripted-provider/hook-probe-extension.ts +126 -0
- package/src/__tests__/scripted-provider/output-recovery-provider.ts +153 -0
- package/src/__tests__/scripted-provider/pi-hook-contract-evidence.json +18 -0
- package/src/__tests__/scripted-provider/pi-hook-contract.test.ts +477 -0
- package/src/__tests__/scripted-provider/runtime-guard-probe.ts +28 -0
- package/src/__tests__/scripted-provider/runtime-guard-provider.ts +49 -0
- package/src/__tests__/scripted-provider/scripted-provider-extension.ts +408 -0
- package/src/__tests__/task-manager.test.ts +479 -0
- package/src/__tests__/windows-taskkill.test.ts +161 -0
- package/src/anthropic-attribution-path.ts +21 -0
- package/src/anthropic-attribution.ts +1983 -0
- package/src/attested-pi-run.ts +612 -0
- package/src/child-process.ts +55 -0
- package/src/common.ts +8 -0
- package/src/config.ts +292 -0
- package/src/context-parent-snapshot.ts +142 -0
- package/src/context-token-budget.ts +903 -0
- package/src/context-visible-conversation-v2.ts +551 -0
- package/src/delegate/artifacts.ts +487 -0
- package/src/delegate/budget.ts +415 -0
- package/src/delegate/hook-contract-evidence.json +18 -0
- package/src/delegate/hook-contract.ts +154 -0
- package/src/delegate/launch.ts +497 -0
- package/src/delegate/result-package.ts +459 -0
- package/src/delegate/runner.ts +449 -0
- package/src/delegate/seed.ts +423 -0
- package/src/delegate/types.ts +323 -0
- package/src/delegate-child-extension.ts +978 -0
- package/src/delegate-extension.ts +806 -0
- package/src/durable-fs.ts +386 -0
- package/src/extension-api.ts +548 -0
- package/src/fixtures/delegate-context-incident.json +17 -0
- package/src/fixtures/fusion-golden-bytes.json +310 -0
- package/src/fixtures/fusion-validate-golden-bytes.json +282 -0
- package/src/fusion/artifacts.ts +967 -0
- package/src/fusion/budget.ts +1162 -0
- package/src/fusion/child-protocol.ts +305 -0
- package/src/fusion/claude-cache.ts +207 -0
- package/src/fusion/clean-context.ts +91 -0
- package/src/fusion/config.ts +449 -0
- package/src/fusion/context.ts +265 -0
- package/src/fusion/evaluation.ts +800 -0
- package/src/fusion/orchestrator.ts +1288 -0
- package/src/fusion/output-contract.ts +34 -0
- package/src/fusion/pi-child.ts +2373 -0
- package/src/fusion/prompts.ts +345 -0
- package/src/fusion/result-package.ts +959 -0
- package/src/fusion/source-policy.ts +257 -0
- package/src/fusion/types.ts +1139 -0
- package/src/fusion/web-fetch.ts +1060 -0
- package/src/fusion/workflows.ts +184 -0
- package/src/fusion-child-extension.ts +1052 -0
- package/src/fusion-extension.ts +1293 -0
- package/src/index.ts +295 -0
- package/src/pi-launch.ts +225 -0
- package/src/registry.ts +2424 -0
- package/src/settings-overlay.ts +208 -0
- package/src/task-manager.ts +774 -0
- package/src/tools.ts +530 -0
- package/src/turndown.d.ts +15 -0
- package/src/types.ts +963 -0
- package/src/ui/fusion-model-selector.ts +322 -0
- package/src/windows-taskkill.ts +250 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { readFileSync, realpathSync, statSync } from 'node:fs';
|
|
4
|
+
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
5
|
+
import { dirname, join } from 'node:path';
|
|
6
|
+
import { tmpdir } from 'node:os';
|
|
7
|
+
import {
|
|
8
|
+
assertWindowsCommandLineWithinLimit,
|
|
9
|
+
piLaunchArgv,
|
|
10
|
+
resolvePiLaunch,
|
|
11
|
+
type PiLaunchDependencies,
|
|
12
|
+
type PiLaunchSpec,
|
|
13
|
+
} from '../pi-launch.js';
|
|
14
|
+
|
|
15
|
+
interface PackageFixture {
|
|
16
|
+
readonly root: string;
|
|
17
|
+
readonly packageRoot: string;
|
|
18
|
+
readonly manifestPath: string;
|
|
19
|
+
readonly deps: PiLaunchDependencies;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function writeNestedFile(path: string, content = ''): Promise<void> {
|
|
23
|
+
await mkdir(dirname(path), { recursive: true });
|
|
24
|
+
await writeFile(path, content, 'utf8');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function depsFor(manifestPath: string): PiLaunchDependencies {
|
|
28
|
+
return {
|
|
29
|
+
platform: 'win32',
|
|
30
|
+
execPath: process.execPath,
|
|
31
|
+
resolvePackageJson: () => manifestPath,
|
|
32
|
+
readFile: (path) => readFileSync(path),
|
|
33
|
+
realpath: (path) => realpathSync(path),
|
|
34
|
+
stat: (path) => statSync(path),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function createPackageFixture(
|
|
39
|
+
manifest: unknown,
|
|
40
|
+
files: readonly string[],
|
|
41
|
+
): Promise<PackageFixture> {
|
|
42
|
+
const root = await mkdtemp(join(tmpdir(), 'pi-bg-launch-'));
|
|
43
|
+
const packageRoot = join(root, 'node_modules', '@earendil-works', 'pi-coding-agent');
|
|
44
|
+
const manifestPath = join(packageRoot, 'package.json');
|
|
45
|
+
await mkdir(packageRoot, { recursive: true });
|
|
46
|
+
await writeFile(manifestPath, `${JSON.stringify(manifest)}\n`, 'utf8');
|
|
47
|
+
for (const file of files) await writeNestedFile(join(packageRoot, file));
|
|
48
|
+
return { root, packageRoot, manifestPath, deps: depsFor(manifestPath) };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function removeFixture(root: string): Promise<void> {
|
|
52
|
+
await rm(root, { recursive: true, force: true });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
void describe('Pi launch resolution', () => {
|
|
56
|
+
void it('returns the bare path form on POSIX without package lookup', () => {
|
|
57
|
+
let resolved = false;
|
|
58
|
+
const spec = resolvePiLaunch({
|
|
59
|
+
platform: 'darwin',
|
|
60
|
+
resolvePackageJson: () => {
|
|
61
|
+
resolved = true;
|
|
62
|
+
throw new Error('should not run');
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
assert.deepEqual(spec, { executable: 'pi', argvPrefix: [], kind: 'path' });
|
|
66
|
+
assert.equal(resolved, false);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
void it('resolves a Windows string bin JavaScript CLI through Node', async () => {
|
|
70
|
+
const fixture = await createPackageFixture({ bin: 'dist/cli.js' }, ['dist/cli.js']);
|
|
71
|
+
try {
|
|
72
|
+
const spec = resolvePiLaunch(fixture.deps);
|
|
73
|
+
assert.equal(spec.executable, process.execPath);
|
|
74
|
+
assert.equal(spec.kind, 'package-node-cli');
|
|
75
|
+
assert.equal(spec.argvPrefix.length, 1);
|
|
76
|
+
const cli = spec.argvPrefix[0];
|
|
77
|
+
assert.ok(cli);
|
|
78
|
+
assert.equal(cli, realpathSync(join(fixture.packageRoot, 'dist', 'cli.js')));
|
|
79
|
+
assert.deepEqual(piLaunchArgv(spec, ['--mode', 'json']), [cli, '--mode', 'json']);
|
|
80
|
+
} finally {
|
|
81
|
+
await removeFixture(fixture.root);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
void it('resolves a Windows object bin JavaScript CLI through Node', async () => {
|
|
86
|
+
const fixture = await createPackageFixture({ bin: { pi: 'dist/cli.cjs' } }, ['dist/cli.cjs']);
|
|
87
|
+
try {
|
|
88
|
+
const spec = resolvePiLaunch(fixture.deps);
|
|
89
|
+
assert.equal(spec.executable, process.execPath);
|
|
90
|
+
assert.equal(spec.argvPrefix.length, 1);
|
|
91
|
+
assert.equal(spec.argvPrefix[0], realpathSync(join(fixture.packageRoot, 'dist', 'cli.cjs')));
|
|
92
|
+
} finally {
|
|
93
|
+
await removeFixture(fixture.root);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
void it('permits direct Windows native executable package bins', async () => {
|
|
98
|
+
for (const extension of ['.exe', '.com']) {
|
|
99
|
+
const file = `dist/pi${extension}`;
|
|
100
|
+
const fixture = await createPackageFixture({ bin: { pi: file } }, [file]);
|
|
101
|
+
try {
|
|
102
|
+
const spec = resolvePiLaunch(fixture.deps);
|
|
103
|
+
assert.equal(spec.executable, realpathSync(join(fixture.packageRoot, file)));
|
|
104
|
+
assert.deepEqual(spec.argvPrefix, []);
|
|
105
|
+
} finally {
|
|
106
|
+
await removeFixture(fixture.root);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
void it('rejects command shims, scripts, extensionless targets, and unknown extensions', async () => {
|
|
112
|
+
for (const extension of ['.cmd', '.bat', '.ps1', '', '.txt']) {
|
|
113
|
+
const file = `dist/pi${extension}`;
|
|
114
|
+
const fixture = await createPackageFixture({ bin: { pi: file } }, [file]);
|
|
115
|
+
try {
|
|
116
|
+
assert.throws(
|
|
117
|
+
() => resolvePiLaunch(fixture.deps),
|
|
118
|
+
/pi_executable_resolution_failed: Pi package bin target extension is unsupported/,
|
|
119
|
+
);
|
|
120
|
+
} finally {
|
|
121
|
+
await removeFixture(fixture.root);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
void it('rejects package bin targets that escape the package root', async () => {
|
|
127
|
+
const fixture = await createPackageFixture({ bin: '../outside/cli.js' }, []);
|
|
128
|
+
try {
|
|
129
|
+
await writeNestedFile(join(fixture.packageRoot, '..', 'outside', 'cli.js'));
|
|
130
|
+
assert.throws(
|
|
131
|
+
() => resolvePiLaunch(fixture.deps),
|
|
132
|
+
/pi_executable_resolution_failed: Pi package bin target resolves outside the package root/,
|
|
133
|
+
);
|
|
134
|
+
} finally {
|
|
135
|
+
await removeFixture(fixture.root);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
void it('rejects malformed manifests, missing manifests, missing bins, and non-file targets', async () => {
|
|
140
|
+
const malformed = await createPackageFixture({ bin: 'dist/cli.js' }, ['dist/cli.js']);
|
|
141
|
+
try {
|
|
142
|
+
await writeFile(malformed.manifestPath, '{', 'utf8');
|
|
143
|
+
assert.throws(() => resolvePiLaunch(malformed.deps), /pi_executable_resolution_failed/);
|
|
144
|
+
} finally {
|
|
145
|
+
await removeFixture(malformed.root);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const missingRoot = await mkdtemp(join(tmpdir(), 'pi-bg-launch-missing-'));
|
|
149
|
+
try {
|
|
150
|
+
const missingManifest = join(missingRoot, 'package.json');
|
|
151
|
+
assert.throws(() => resolvePiLaunch(depsFor(missingManifest)), /pi_executable_resolution_failed/);
|
|
152
|
+
} finally {
|
|
153
|
+
await rm(missingRoot, { recursive: true, force: true });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const missingBin = await createPackageFixture({}, []);
|
|
157
|
+
try {
|
|
158
|
+
assert.throws(() => resolvePiLaunch(missingBin.deps), /pi_executable_resolution_failed/);
|
|
159
|
+
} finally {
|
|
160
|
+
await removeFixture(missingBin.root);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const directoryTarget = await createPackageFixture({ bin: 'dist/cli.js' }, []);
|
|
164
|
+
try {
|
|
165
|
+
await mkdir(join(directoryTarget.packageRoot, 'dist', 'cli.js'), { recursive: true });
|
|
166
|
+
assert.throws(() => resolvePiLaunch(directoryTarget.deps), /regular file/);
|
|
167
|
+
} finally {
|
|
168
|
+
await removeFixture(directoryTarget.root);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
void it('rejects oversized Windows command lines without leaking argument text', () => {
|
|
173
|
+
const launch: PiLaunchSpec = {
|
|
174
|
+
executable: 'C:\\Node\\node.exe',
|
|
175
|
+
argvPrefix: ['C:\\pkg\\cli.js'],
|
|
176
|
+
kind: 'package-node-cli',
|
|
177
|
+
};
|
|
178
|
+
assert.doesNotThrow(() =>
|
|
179
|
+
assertWindowsCommandLineWithinLimit(launch, ['--model', 'gpt-5.5'], 'win32', 'unit-stage'),
|
|
180
|
+
);
|
|
181
|
+
const secret = 'SECRET_TOKEN_VALUE';
|
|
182
|
+
assert.throws(
|
|
183
|
+
() =>
|
|
184
|
+
assertWindowsCommandLineWithinLimit(
|
|
185
|
+
launch,
|
|
186
|
+
[secret.repeat(3000)],
|
|
187
|
+
'win32',
|
|
188
|
+
'oversized-stage',
|
|
189
|
+
),
|
|
190
|
+
(error: unknown) => {
|
|
191
|
+
assert.ok(error instanceof Error);
|
|
192
|
+
assert.match(error.message, /oversized-stage/);
|
|
193
|
+
assert.match(error.message, /32767/);
|
|
194
|
+
assert.doesNotMatch(error.message, /SECRET_TOKEN_VALUE/);
|
|
195
|
+
return true;
|
|
196
|
+
},
|
|
197
|
+
);
|
|
198
|
+
assert.doesNotThrow(() =>
|
|
199
|
+
assertWindowsCommandLineWithinLimit(launch, [secret.repeat(3000)], 'linux', 'posix-stage'),
|
|
200
|
+
);
|
|
201
|
+
});
|
|
202
|
+
});
|