fix(release): make ECC 2.2 ready to publish

This commit is contained in:
haelyra
2026-08-24 20:15:12 -04:00
parent 528dbea019
commit 2c5a91a1d6
15 changed files with 259 additions and 93 deletions
+1 -3
View File
@@ -18,9 +18,7 @@ const PROFILES_SCHEMA_PATH = path.join(REPO_ROOT, 'schemas/install-profiles.sche
const COMPONENTS_SCHEMA_PATH = path.join(REPO_ROOT, 'schemas/install-components.schema.json');
const CURATED_SKILLS_DIR = path.join(REPO_ROOT, 'skills');
// Empty by default; add only curated skills that are intentionally unshipped.
const INTENTIONALLY_UNSHIPPED_SKILL_IDS = new Set([
'skill-comply', // meta/measurement dev-skill; ships committed .pyc artifacts and a nested .gitignore, revisit after packaging cleanup
]);
const INTENTIONALLY_UNSHIPPED_SKILL_IDS = new Set([]);
const COMPONENT_FAMILY_PREFIXES = {
baseline: 'baseline:',
language: 'lang:',
+2 -2
View File
@@ -135,8 +135,8 @@ const HARNESS_CAPABILITIES = deepFreeze([
installMode: 'managed-home',
guidedReady: false,
availability: 'advanced',
destination: '~/.opencode',
scopes: [scope('home', 'opencode', '~/.opencode')],
destination: '~/.config/opencode',
scopes: [scope('home', 'opencode', '~/.config/opencode')],
hooks: hooks(
'adapter-opt-in',
false,
+6 -1
View File
@@ -80,7 +80,12 @@ function validateLegacyTarget(target) {
throw new Error(`Unknown install target: ${target}. Expected one of ${SUPPORTED_INSTALL_TARGETS.join(', ')}`);
}
const IGNORED_DIRECTORY_NAMES = new Set(['node_modules', '.git', '__pycache__']);
const IGNORED_DIRECTORY_NAMES = new Set([
'node_modules',
'.git',
'__pycache__',
'.pytest_cache',
]);
const IGNORED_FILE_EXTENSIONS = new Set(['.pyc', '.pyo', '.pyd']);
function listFilesRecursive(dirPath) {
+59 -12
View File
@@ -64,11 +64,55 @@ function pathsMatch(left, right) {
return canonicalPath(left) === canonicalPath(right);
}
function sameFileIdentity(left, right) {
return left.dev === right.dev
&& left.ino === right.ino
&& left.size === right.size
&& left.mtimeMs === right.mtimeMs
&& left.ctimeMs === right.ctimeMs;
}
function readRegularFileSnapshot(filePath) {
let pathStat;
try {
pathStat = fs.lstatSync(filePath);
} catch (error) {
if (error && (error.code === 'ENOENT' || error.code === 'ENOTDIR')) return null;
throw error;
}
if (!pathStat.isFile() || pathStat.isSymbolicLink()) {
throw new Error(`Refusing to read a symbolic link or non-file at ${filePath}.`);
}
const flags = fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW || 0);
const descriptor = fs.openSync(filePath, flags);
try {
const before = fs.fstatSync(descriptor);
if (!before.isFile() || !sameFileIdentity(pathStat, before)) {
throw new Error(`Refusing to read a file that changed during open: ${filePath}.`);
}
const content = fs.readFileSync(descriptor);
const after = fs.fstatSync(descriptor);
const finalPathStat = fs.lstatSync(filePath);
if (
finalPathStat.isSymbolicLink()
|| !sameFileIdentity(before, after)
|| !sameFileIdentity(after, finalPathStat)
) {
throw new Error(`Refusing to read a file that changed during validation: ${filePath}.`);
}
return { content, stat: after };
} finally {
fs.closeSync(descriptor);
}
}
function fingerprintFile(filePath) {
if (!fs.existsSync(filePath)) return { exists: false, sha256: null };
const snapshot = readRegularFileSnapshot(filePath);
if (!snapshot) return { exists: false, sha256: null };
return {
exists: true,
sha256: crypto.createHash('sha256').update(fs.readFileSync(filePath)).digest('hex'),
sha256: crypto.createHash('sha256').update(snapshot.content).digest('hex'),
};
}
@@ -131,11 +175,11 @@ function readOwnedDestinations(plan, dependencies) {
} catch (error) {
throw new Error(`Refusing to trust managed install-state path: ${error.message}`);
}
if (!fs.existsSync(plan.installStatePath)) {
const initialFingerprint = fingerprintFile(plan.installStatePath);
if (!initialFingerprint.exists) {
return { destinations: new Set(), stateFingerprint: { exists: false, sha256: null } };
}
const readState = dependencies.readInstallState || require('./install-state').readInstallState;
const initialFingerprint = fingerprintFile(plan.installStatePath);
const state = readState(plan.installStatePath);
const validatedFingerprint = fingerprintFile(plan.installStatePath);
if (
@@ -185,11 +229,12 @@ function readOwnedDestinations(plan, dependencies) {
return { destinations, stateFingerprint: validatedFingerprint };
}
function assertMergeDestination(destinationPath) {
if (!fs.existsSync(destinationPath)) return null;
function assertMergeDestination(destinationPath, existingSnapshot = null) {
const snapshot = existingSnapshot || readRegularFileSnapshot(destinationPath);
if (!snapshot) return null;
let current;
try {
current = JSON.parse(fs.readFileSync(destinationPath, 'utf8'));
current = JSON.parse(snapshot.content.toString('utf8'));
} catch (error) {
throw new Error(`Cannot merge ECC configuration into invalid JSON at ${destinationPath}: ${error.message}`);
}
@@ -218,10 +263,11 @@ function findJsonConflicts(current, patch, prefix = '') {
function classifyManagedOperation(operation, ownedDestinations) {
const destinationPath = operation.destinationPath;
if (!fs.existsSync(destinationPath)) return 'create';
const destination = readRegularFileSnapshot(destinationPath);
if (!destination) return 'create';
const canonicalDestination = canonicalPath(destinationPath);
if (operation.kind === 'merge-json') {
const current = assertMergeDestination(destinationPath);
const current = assertMergeDestination(destinationPath, destination);
if (ownedDestinations.has(canonicalDestination)) return 'managed-json-update';
const conflicts = findJsonConflicts(current, operation.mergePayload);
if (conflicts.length > 0) {
@@ -235,9 +281,7 @@ function classifyManagedOperation(operation, ownedDestinations) {
if (
operation.kind === 'copy-file'
&& typeof operation.sourcePath === 'string'
&& fs.existsSync(operation.sourcePath)
&& fs.statSync(destinationPath).isFile()
&& fs.readFileSync(operation.sourcePath).equals(fs.readFileSync(destinationPath))
&& readRegularFileSnapshot(operation.sourcePath)?.content.equals(destination.content)
) {
return 'identical';
}
@@ -295,6 +339,9 @@ function preflightManagedPlan(plan, dependencies = {}) {
if (!plan || !Array.isArray(plan.operations)) {
throw new Error('A managed install plan with operations is required.');
}
if (typeof plan.installStatePath !== 'string' || plan.installStatePath.length === 0) {
throw new Error('A managed install-state path is required before preflight.');
}
const ownership = readOwnedDestinations(plan, dependencies);
const operations = plan.operations.map(operation => {
assertSafeInstallOperation(plan, operation);