feat: orchestration harness, selective install, observer improvements

This commit is contained in:
Affaan Mustafa
2026-03-14 12:55:25 -07:00
parent 424f3b3729
commit 4e028bd2d2
76 changed files with 11050 additions and 340 deletions

View File

@@ -0,0 +1,23 @@
'use strict';
const fs = require('fs');
const { writeInstallState } = require('../install-state');
function applyInstallPlan(plan) {
for (const operation of plan.operations) {
fs.mkdirSync(require('path').dirname(operation.destinationPath), { recursive: true });
fs.copyFileSync(operation.sourcePath, operation.destinationPath);
}
writeInstallState(plan.installStatePath, plan.statePreview);
return {
...plan,
applied: true,
};
}
module.exports = {
applyInstallPlan,
};

View 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,
};

View File

@@ -0,0 +1,113 @@
'use strict';
const LEGACY_INSTALL_TARGETS = ['claude', 'cursor', 'antigravity'];
function dedupeStrings(values) {
return [...new Set((Array.isArray(values) ? values : []).map(value => String(value).trim()).filter(Boolean))];
}
function parseInstallArgs(argv) {
const args = argv.slice(2);
const parsed = {
target: null,
dryRun: false,
json: false,
help: false,
configPath: null,
profileId: null,
moduleIds: [],
includeComponentIds: [],
excludeComponentIds: [],
languages: [],
};
for (let index = 0; index < args.length; index += 1) {
const arg = args[index];
if (arg === '--target') {
parsed.target = args[index + 1] || null;
index += 1;
} else if (arg === '--config') {
parsed.configPath = args[index + 1] || null;
index += 1;
} else if (arg === '--profile') {
parsed.profileId = args[index + 1] || null;
index += 1;
} else if (arg === '--modules') {
const raw = args[index + 1] || '';
parsed.moduleIds = raw.split(',').map(value => value.trim()).filter(Boolean);
index += 1;
} else if (arg === '--with') {
const componentId = args[index + 1] || '';
if (componentId.trim()) {
parsed.includeComponentIds.push(componentId.trim());
}
index += 1;
} else if (arg === '--without') {
const componentId = args[index + 1] || '';
if (componentId.trim()) {
parsed.excludeComponentIds.push(componentId.trim());
}
index += 1;
} else if (arg === '--dry-run') {
parsed.dryRun = true;
} else if (arg === '--json') {
parsed.json = true;
} else if (arg === '--help' || arg === '-h') {
parsed.help = true;
} else if (arg.startsWith('--')) {
throw new Error(`Unknown argument: ${arg}`);
} else {
parsed.languages.push(arg);
}
}
return parsed;
}
function normalizeInstallRequest(options = {}) {
const config = options.config && typeof options.config === 'object'
? options.config
: null;
const profileId = options.profileId || config?.profileId || null;
const moduleIds = dedupeStrings([...(config?.moduleIds || []), ...(options.moduleIds || [])]);
const includeComponentIds = dedupeStrings([
...(config?.includeComponentIds || []),
...(options.includeComponentIds || []),
]);
const excludeComponentIds = dedupeStrings([
...(config?.excludeComponentIds || []),
...(options.excludeComponentIds || []),
]);
const languages = Array.isArray(options.languages) ? [...options.languages] : [];
const target = options.target || config?.target || 'claude';
const hasManifestBaseSelection = Boolean(profileId) || moduleIds.length > 0 || includeComponentIds.length > 0;
const usingManifestMode = hasManifestBaseSelection || excludeComponentIds.length > 0;
if (usingManifestMode && languages.length > 0) {
throw new Error(
'Legacy language arguments cannot be combined with --profile, --modules, --with, --without, or manifest config selections'
);
}
if (!options.help && !hasManifestBaseSelection && languages.length === 0) {
throw new Error('No install profile, module IDs, included components, or legacy languages were provided');
}
return {
mode: usingManifestMode ? 'manifest' : 'legacy',
target,
profileId,
moduleIds,
includeComponentIds,
excludeComponentIds,
languages,
configPath: config?.path || options.configPath || null,
};
}
module.exports = {
LEGACY_INSTALL_TARGETS,
normalizeInstallRequest,
parseInstallArgs,
};

View File

@@ -0,0 +1,42 @@
'use strict';
const {
createLegacyInstallPlan,
createManifestInstallPlan,
} = require('../install-executor');
function createInstallPlanFromRequest(request, options = {}) {
if (!request || typeof request !== 'object') {
throw new Error('A normalized install request is required');
}
if (request.mode === 'manifest') {
return createManifestInstallPlan({
target: request.target,
profileId: request.profileId,
moduleIds: request.moduleIds,
includeComponentIds: request.includeComponentIds,
excludeComponentIds: request.excludeComponentIds,
projectRoot: options.projectRoot,
homeDir: options.homeDir,
sourceRoot: options.sourceRoot,
});
}
if (request.mode === 'legacy') {
return createLegacyInstallPlan({
target: request.target,
languages: request.languages,
projectRoot: options.projectRoot,
homeDir: options.homeDir,
claudeRulesDir: options.claudeRulesDir,
sourceRoot: options.sourceRoot,
});
}
throw new Error(`Unsupported install request mode: ${request.mode}`);
}
module.exports = {
createInstallPlanFromRequest,
};