mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-03-31 14:13:27 +08:00
feat: orchestration harness, selective install, observer improvements
This commit is contained in:
82
scripts/lib/install/config.js
Normal file
82
scripts/lib/install/config.js
Normal file
@@ -0,0 +1,82 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const Ajv = require('ajv');
|
||||
|
||||
const DEFAULT_INSTALL_CONFIG = 'ecc-install.json';
|
||||
const CONFIG_SCHEMA_PATH = path.join(__dirname, '..', '..', '..', 'schemas', 'ecc-install-config.schema.json');
|
||||
|
||||
let cachedValidator = null;
|
||||
|
||||
function readJson(filePath, label) {
|
||||
try {
|
||||
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
||||
} catch (error) {
|
||||
throw new Error(`Invalid JSON in ${label}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
function getValidator() {
|
||||
if (cachedValidator) {
|
||||
return cachedValidator;
|
||||
}
|
||||
|
||||
const schema = readJson(CONFIG_SCHEMA_PATH, 'ecc-install-config.schema.json');
|
||||
const ajv = new Ajv({ allErrors: true });
|
||||
cachedValidator = ajv.compile(schema);
|
||||
return cachedValidator;
|
||||
}
|
||||
|
||||
function dedupeStrings(values) {
|
||||
return [...new Set((Array.isArray(values) ? values : []).map(value => String(value).trim()).filter(Boolean))];
|
||||
}
|
||||
|
||||
function formatValidationErrors(errors = []) {
|
||||
return errors.map(error => `${error.instancePath || '/'} ${error.message}`).join('; ');
|
||||
}
|
||||
|
||||
function resolveInstallConfigPath(configPath, options = {}) {
|
||||
if (!configPath) {
|
||||
throw new Error('An install config path is required');
|
||||
}
|
||||
|
||||
const cwd = options.cwd || process.cwd();
|
||||
return path.isAbsolute(configPath)
|
||||
? configPath
|
||||
: path.resolve(cwd, configPath);
|
||||
}
|
||||
|
||||
function loadInstallConfig(configPath, options = {}) {
|
||||
const resolvedPath = resolveInstallConfigPath(configPath, options);
|
||||
|
||||
if (!fs.existsSync(resolvedPath)) {
|
||||
throw new Error(`Install config not found: ${resolvedPath}`);
|
||||
}
|
||||
|
||||
const raw = readJson(resolvedPath, path.basename(resolvedPath));
|
||||
const validator = getValidator();
|
||||
|
||||
if (!validator(raw)) {
|
||||
throw new Error(
|
||||
`Invalid install config ${resolvedPath}: ${formatValidationErrors(validator.errors)}`
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
path: resolvedPath,
|
||||
version: raw.version,
|
||||
target: raw.target || null,
|
||||
profileId: raw.profile || null,
|
||||
moduleIds: dedupeStrings(raw.modules),
|
||||
includeComponentIds: dedupeStrings(raw.include),
|
||||
excludeComponentIds: dedupeStrings(raw.exclude),
|
||||
options: raw.options && typeof raw.options === 'object' ? { ...raw.options } : {},
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
DEFAULT_INSTALL_CONFIG,
|
||||
loadInstallConfig,
|
||||
resolveInstallConfigPath,
|
||||
};
|
||||
Reference in New Issue
Block a user