test(release): add ECC 2.2 readiness regressions

This commit is contained in:
haelyra
2026-08-24 20:08:41 -04:00
parent d8409a4b08
commit 6e66dfbae8
6 changed files with 139 additions and 6 deletions
@@ -161,6 +161,15 @@ test('packed lifecycle invokes installed public bins, including setup help', ()
assert.doesNotMatch(lifecycleRunnerSource, /node_modules.*scripts.*ecc\.js/);
});
test('packed lifecycle validates canonical Antigravity and OpenCode installs', () => {
assert.match(lifecycleRunnerSource, /'--target', 'antigravity'/);
assert.match(lifecycleRunnerSource, /path\.join\(projectDir, '\.agents'\)/);
assert.match(lifecycleRunnerSource, /'--target', 'opencode'/);
assert.match(lifecycleRunnerSource, /path\.join\(homeDir, '\.config', 'opencode'\)/);
assert.match(lifecycleRunnerSource, /doctor.*antigravity/s);
assert.match(lifecycleRunnerSource, /doctor.*opencode/s);
});
test('packed lifecycle installs and verifies the opt-in Ito distribution surface', () => {
assert.match(
lifecycleRunnerSource,
@@ -0,0 +1,84 @@
'use strict';
const assert = require('assert');
const fs = require('fs');
const os = require('os');
const path = require('path');
const { applyInstallPlan } = require('../../scripts/lib/install/apply');
const { readInstallState } = require('../../scripts/lib/install-state');
const { uninstallInstalledStates } = require('../../scripts/lib/install-lifecycle');
function makePlan(root, moduleId, fileName) {
const targetRoot = path.join(root, '.cursor');
const installStatePath = path.join(targetRoot, 'ecc-install-state.json');
const sourcePath = path.join(root, 'source', moduleId, fileName);
const destinationPath = path.join(targetRoot, 'skills', moduleId, fileName);
fs.mkdirSync(path.dirname(sourcePath), { recursive: true });
fs.writeFileSync(sourcePath, `${moduleId}\n`);
const operation = {
kind: 'copy-file',
moduleId,
sourcePath,
sourceRelativePath: path.join('skills', moduleId, fileName),
destinationPath,
strategy: 'preserve-relative-path',
ownership: 'managed',
scaffoldOnly: false,
};
return {
mode: 'manifest',
target: 'cursor',
adapter: { id: 'cursor-project', target: 'cursor', kind: 'project' },
targetRoot,
installRoot: targetRoot,
installStatePath,
operations: [operation],
statePreview: {
schemaVersion: 'ecc.install.v1',
installedAt: new Date().toISOString(),
target: {
id: 'cursor-project',
target: 'cursor',
kind: 'project',
root: targetRoot,
installStatePath,
},
request: {
profile: null,
modules: [moduleId],
includeComponents: [],
excludeComponents: [],
legacyLanguages: [],
legacyMode: false,
},
resolution: { selectedModules: [moduleId], skippedModules: [] },
source: { manifestVersion: 1 },
operations: [operation],
},
warnings: [],
};
}
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'ecc-selective-reinstall-'));
try {
const first = makePlan(root, 'first-module', 'FIRST.md');
const second = makePlan(root, 'second-module', 'SECOND.md');
applyInstallPlan(first);
applyInstallPlan(second);
const state = readInstallState(first.installStatePath);
assert.deepStrictEqual(
new Set(state.operations.map(operation => operation.moduleId)),
new Set(['first-module', 'second-module']),
'a later selective install must preserve earlier managed ownership'
);
const result = uninstallInstalledStates({ projectRoot: root, targets: ['cursor'] });
assert.strictEqual(result.summary.errorCount, 0);
assert.ok(!fs.existsSync(first.operations[0].destinationPath));
assert.ok(!fs.existsSync(second.operations[0].destinationPath));
console.log(' ✓ selective reinstall preserves cumulative ownership and uninstall removes it');
} finally {
fs.rmSync(root, { recursive: true, force: true });
}
+5 -2
View File
@@ -1073,8 +1073,11 @@ function runTests() {
assert.strictEqual(adapter.id, 'opencode-home');
assert.strictEqual(adapter.target, 'opencode');
assert.strictEqual(adapter.kind, 'home');
assert.strictEqual(root, path.join(homeDir, '.opencode'));
assert.strictEqual(statePath, path.join(homeDir, '.opencode', 'ecc-install-state.json'));
assert.strictEqual(root, path.join(homeDir, '.config', 'opencode'));
assert.strictEqual(
statePath,
path.join(homeDir, '.config', 'opencode', 'ecc-install-state.json')
);
})) passed++; else failed++;
if (test('opencode adapter validate reports an error when compiled plugin is missing', () => {
+21
View File
@@ -175,6 +175,27 @@ function writeManagedState(plan, overrides = {}) {
}
});
await test('rejects managed preflight plans without an install-state path', () => {
const root = tempDir('ecc-guided-missing-state-');
try {
const source = path.join(root, 'source.md');
writeFile(source, 'ecc\n');
const plan = managedPlan(root, [{
kind: 'copy-file',
sourcePath: source,
destinationPath: path.join(root, 'AGENTS.md'),
}]);
delete plan.installStatePath;
assert.throws(
() => preflightManagedPlan(plan),
/install-state path is required/i
);
} finally {
fs.rmSync(root, { recursive: true, force: true });
}
});
await test('rejects valid install-state from a different managed target identity', () => {
const root = tempDir('ecc-guided-forged-target-');
try {
+5 -1
View File
@@ -201,6 +201,7 @@ function main() {
"schemas/install-state.schema.json",
"schemas/memory.schema.json",
"skills/backend-patterns/SKILL.md",
"skills/skill-comply/SKILL.md",
"skills/unified-memory/SKILL.md",
]) {
assert.ok(
@@ -214,7 +215,6 @@ function main() {
"examples/CLAUDE.md",
"plugins/README.md",
"scripts/ci/catalog.js",
"skills/skill-comply/SKILL.md",
]) {
assert.ok(
!packagedPaths.has(excludedPath),
@@ -231,6 +231,10 @@ function main() {
!/\.py[cod]$/.test(packagedPath),
`npm pack should not include Python bytecode file ${packagedPath}`
)
assert.ok(
!packagedPath.includes(".pytest_cache/"),
`npm pack should not include pytest cache path ${packagedPath}`
)
}
}],
]
+15 -3
View File
@@ -51,6 +51,18 @@ for (const workflow of [
test(`${workflow} checks whether the tagged npm version already exists`, () => {
assert.match(content, /Check npm publish state/);
assert.match(content, /npm view "\$\{PACKAGE_NAME\}@\$\{PACKAGE_VERSION\}" version/);
assert.match(content, /E404/);
assert.match(content, /npm registry lookup failed/i);
});
test(`${workflow} requires the release commit to equal origin main`, () => {
assert.match(content, /git fetch origin main --no-tags/);
assert.match(content, /git rev-parse origin\/main/);
assert.match(content, /release commit.*origin\/main/i);
});
test(`${workflow} uses the reviewed 2.2 release notes`, () => {
assert.match(content, /docs\/releases\/2\.2\.0\/RELEASE_NOTES\.md/);
});
test(`${workflow} publishes new tag versions to npm`, () => {
@@ -59,15 +71,15 @@ for (const workflow of [
assert.match(content, /NODE_AUTH_TOKEN:\s*\$\{\{\s*secrets\.NPM_TOKEN\s*\}\}/);
});
test(`${workflow} creates the GitHub Release before publishing to npm`, () => {
test(`${workflow} publishes to npm before creating the GitHub Release`, () => {
const releaseIndex = content.indexOf('name: Create GitHub Release');
const publishIndex = content.indexOf('name: Publish npm package');
assert.ok(releaseIndex >= 0, `${workflow} should create a GitHub Release`);
assert.ok(publishIndex >= 0, `${workflow} should publish the npm package`);
assert.ok(
releaseIndex < publishIndex,
`${workflow} should not publish to npm until GitHub Release creation has succeeded`
publishIndex < releaseIndex,
`${workflow} should publish the verified package before creating the GitHub Release`
);
});
}