mirror of
https://github.com/affaan-m/ECC.git
synced 2026-08-17 21:15:40 +02:00
test(release): verify packed Ito distribution
This commit is contained in:
committed by
Affaan Mustafa
parent
50743cec75
commit
e169ff9397
@@ -135,7 +135,7 @@ function getNpmExecInvocation(publicArgs, environment, platform = process.platfo
|
||||
|
||||
const commandParts = ['npm', ...npmArgs];
|
||||
for (const part of commandParts) {
|
||||
if (!/^[A-Za-z0-9_.=+/-]+$/.test(part)) {
|
||||
if (!/^[A-Za-z0-9_.=+,:/-]+$/.test(part)) {
|
||||
throw new Error(`Unsafe npm exec argument for Windows lifecycle: ${part}`);
|
||||
}
|
||||
}
|
||||
@@ -292,18 +292,70 @@ function runLifecycle(options) {
|
||||
assert.match(setupHelp.stdout, /ECC guided setup/);
|
||||
assert.match(setupHelp.stdout, /ecc setup --mode claude-plugin/);
|
||||
|
||||
const itoInstallArgs = [
|
||||
'install',
|
||||
'--profile', 'core',
|
||||
'--with', 'capability:ito-compute',
|
||||
'--with', 'capability:prediction-markets',
|
||||
'--target', 'cursor',
|
||||
'--json',
|
||||
];
|
||||
parseJsonOutput(
|
||||
runCli(['install', '--profile', 'core', '--target', 'cursor', '--json']),
|
||||
'initial install'
|
||||
runCli(itoInstallArgs),
|
||||
'initial Itô install'
|
||||
);
|
||||
assert.ok(fs.existsSync(statePath), 'initial install must write Cursor install-state');
|
||||
const initialState = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
||||
const initialLedger = getOperationLedger(initialState);
|
||||
assert.ok(
|
||||
initialState.operations.some(operation => operation.moduleId === 'ito-compute'),
|
||||
'installed ledger must include the Itô compute module'
|
||||
);
|
||||
assert.ok(
|
||||
initialState.operations.some(operation => operation.moduleId === 'prediction-market-skills'),
|
||||
'installed ledger must include the Itô baskets module'
|
||||
);
|
||||
for (const relativePath of [
|
||||
'skills/ito-baskets/SKILL.md',
|
||||
'skills/ito-baskets/agents/openai.yaml',
|
||||
'skills/ito-baskets/scripts/ito-baskets.js',
|
||||
'skills/ito-compute/SKILL.md',
|
||||
'skills/ito-compute/agents/openai.yaml',
|
||||
'skills/ito-inference/SKILL.md',
|
||||
'skills/ito-training/SKILL.md',
|
||||
]) {
|
||||
const installedPath = path.join(cursorRoot, relativePath);
|
||||
const installedStat = fs.lstatSync(installedPath);
|
||||
assert.ok(installedStat.isFile(), `packed Itô asset is not a file: ${relativePath}`);
|
||||
assert.ok(!installedStat.isSymbolicLink(), `packed Itô asset is a symlink: ${relativePath}`);
|
||||
assert.ok(installedStat.size > 0, `packed Itô asset is empty: ${relativePath}`);
|
||||
}
|
||||
const hostileBin = path.join(tempRoot, 'hostile-bin');
|
||||
const hostileItoSentinel = path.join(tempRoot, 'hostile-ito-spawned');
|
||||
fs.mkdirSync(hostileBin, { recursive: true });
|
||||
const hostileIto = path.join(hostileBin, process.platform === 'win32' ? 'ito.cmd' : 'ito');
|
||||
if (process.platform === 'win32') {
|
||||
fs.writeFileSync(hostileIto, `@echo hostile>"${hostileItoSentinel}"\r\n`, 'utf8');
|
||||
} else {
|
||||
fs.writeFileSync(hostileIto, `#!${process.execPath}\nrequire('fs').writeFileSync(${JSON.stringify(hostileItoSentinel)}, 'spawned');\n`, 'utf8');
|
||||
fs.chmodSync(hostileIto, 0o755);
|
||||
}
|
||||
const itoStatus = runCli(['ito', 'status'], {
|
||||
expectedStatus: 1,
|
||||
env: {
|
||||
...environment,
|
||||
PATH: `${hostileBin}${path.delimiter}${environment.PATH || environment.Path || ''}`,
|
||||
ITO_API_KEY: 'must-not-reach-hostile-path',
|
||||
},
|
||||
});
|
||||
assert.match(itoStatus.stderr, /canonical ito-compute-cli is unpublished/i);
|
||||
assert.doesNotMatch(itoStatus.stderr, /npx|npm exec|npm link|install -g/i);
|
||||
assert.ok(!fs.existsSync(hostileItoSentinel), 'packed Itô bridge executed a PATH collision');
|
||||
const managedSnapshot = getManagedOperationSnapshot(initialState, cursorRoot);
|
||||
assert.ok(managedSnapshot.length > 0, 'initial install must create managed Cursor files');
|
||||
|
||||
parseJsonOutput(
|
||||
runCli(['install', '--profile', 'core', '--target', 'cursor', '--json']),
|
||||
runCli(itoInstallArgs),
|
||||
'repeat install'
|
||||
);
|
||||
const repeatState = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
||||
@@ -405,7 +457,8 @@ function runLifecycle(options) {
|
||||
lifecycle: [
|
||||
'npm-install',
|
||||
'public-ecc-universal-setup',
|
||||
'cursor-install',
|
||||
'cursor-ito-install',
|
||||
'public-ecc-ito-fail-closed',
|
||||
'cursor-repeat-install',
|
||||
'doctor-clean',
|
||||
'status-installed',
|
||||
|
||||
@@ -125,6 +125,25 @@ test('public CLI invocations use npm exec instead of internal package paths', ()
|
||||
assert.ok(!unixInvocation.args.some(argument => argument.includes('node_modules')));
|
||||
});
|
||||
|
||||
test('Windows public CLI invocation accepts the exact Itô capability selection', () => {
|
||||
const invocation = lifecycle.getNpmExecInvocation(
|
||||
[
|
||||
'ecc', 'install', '--profile', 'core',
|
||||
'--with', 'capability:ito-compute',
|
||||
'--with', 'capability:prediction-markets',
|
||||
'--target', 'cursor', '--json',
|
||||
],
|
||||
{ ComSpec: 'C:\\Windows\\System32\\cmd.exe' },
|
||||
'win32'
|
||||
);
|
||||
|
||||
assert.strictEqual(invocation.command, 'C:\\Windows\\System32\\cmd.exe');
|
||||
assert.strictEqual(
|
||||
invocation.args[3],
|
||||
'npm exec --offline --yes=false -- ecc install --profile core --with capability:ito-compute --with capability:prediction-markets --target cursor --json'
|
||||
);
|
||||
});
|
||||
|
||||
test('lifecycle cleanup retries Windows file locks without masking results', () => {
|
||||
const source = fs.readFileSync(
|
||||
path.join(__dirname, 'packed-artifact-lifecycle.js'),
|
||||
|
||||
@@ -161,6 +161,35 @@ test('packed lifecycle invokes installed public bins, including setup help', ()
|
||||
assert.doesNotMatch(lifecycleRunnerSource, /node_modules.*scripts.*ecc\.js/);
|
||||
});
|
||||
|
||||
test('packed lifecycle installs and verifies the opt-in Ito distribution surface', () => {
|
||||
assert.match(
|
||||
lifecycleRunnerSource,
|
||||
/'--profile', 'core'[\s\S]*'--with', 'capability:ito-compute'[\s\S]*'--with', 'capability:prediction-markets'/
|
||||
);
|
||||
for (const moduleId of ['ito-compute', 'prediction-market-skills']) {
|
||||
assert.match(lifecycleRunnerSource, new RegExp(`moduleId === '${moduleId}'`));
|
||||
}
|
||||
for (const installedPath of [
|
||||
'skills/ito-baskets/SKILL.md',
|
||||
'skills/ito-baskets/agents/openai.yaml',
|
||||
'skills/ito-baskets/scripts/ito-baskets.js',
|
||||
'skills/ito-compute/SKILL.md',
|
||||
'skills/ito-compute/agents/openai.yaml',
|
||||
'skills/ito-inference/SKILL.md',
|
||||
'skills/ito-training/SKILL.md',
|
||||
]) {
|
||||
assert.match(lifecycleRunnerSource, new RegExp(installedPath.replaceAll('.', '\\.')));
|
||||
}
|
||||
assert.match(lifecycleRunnerSource, /\['ito', 'status'\]/);
|
||||
assert.match(lifecycleRunnerSource, /canonical ito-compute-cli is unpublished/i);
|
||||
assert.match(lifecycleRunnerSource, /npx\|npm exec\|npm link\|install -g/i);
|
||||
assert.match(lifecycleRunnerSource, /installedStat\.isFile\(\)/);
|
||||
assert.match(lifecycleRunnerSource, /installedStat\.size > 0/);
|
||||
assert.match(lifecycleRunnerSource, /hostileItoSentinel/);
|
||||
assert.match(lifecycleRunnerSource, /must-not-reach-hostile-path/);
|
||||
assert.match(lifecycleRunnerSource, /packed Itô bridge executed a PATH collision/);
|
||||
});
|
||||
|
||||
console.log(`\nPassed: ${passed}`);
|
||||
console.log(`Failed: ${failed}`);
|
||||
process.exit(failed > 0 ? 1 : 0);
|
||||
|
||||
Reference in New Issue
Block a user