mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-03-30 13:43:26 +08:00
feat: orchestration harness, selective install, observer improvements
This commit is contained in:
120
scripts/lib/install-state.js
Normal file
120
scripts/lib/install-state.js
Normal file
@@ -0,0 +1,120 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const Ajv = require('ajv');
|
||||
|
||||
const SCHEMA_PATH = path.join(__dirname, '..', '..', 'schemas', 'install-state.schema.json');
|
||||
|
||||
let cachedValidator = null;
|
||||
|
||||
function readJson(filePath, label) {
|
||||
try {
|
||||
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to read ${label}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
function getValidator() {
|
||||
if (cachedValidator) {
|
||||
return cachedValidator;
|
||||
}
|
||||
|
||||
const schema = readJson(SCHEMA_PATH, 'install-state schema');
|
||||
const ajv = new Ajv({ allErrors: true });
|
||||
cachedValidator = ajv.compile(schema);
|
||||
return cachedValidator;
|
||||
}
|
||||
|
||||
function formatValidationErrors(errors = []) {
|
||||
return errors
|
||||
.map(error => `${error.instancePath || '/'} ${error.message}`)
|
||||
.join('; ');
|
||||
}
|
||||
|
||||
function validateInstallState(state) {
|
||||
const validator = getValidator();
|
||||
const valid = validator(state);
|
||||
return {
|
||||
valid,
|
||||
errors: validator.errors || [],
|
||||
};
|
||||
}
|
||||
|
||||
function assertValidInstallState(state, label) {
|
||||
const result = validateInstallState(state);
|
||||
if (!result.valid) {
|
||||
throw new Error(`Invalid install-state${label ? ` (${label})` : ''}: ${formatValidationErrors(result.errors)}`);
|
||||
}
|
||||
}
|
||||
|
||||
function createInstallState(options) {
|
||||
const installedAt = options.installedAt || new Date().toISOString();
|
||||
const state = {
|
||||
schemaVersion: 'ecc.install.v1',
|
||||
installedAt,
|
||||
target: {
|
||||
id: options.adapter.id,
|
||||
target: options.adapter.target || undefined,
|
||||
kind: options.adapter.kind || undefined,
|
||||
root: options.targetRoot,
|
||||
installStatePath: options.installStatePath,
|
||||
},
|
||||
request: {
|
||||
profile: options.request.profile || null,
|
||||
modules: Array.isArray(options.request.modules) ? [...options.request.modules] : [],
|
||||
includeComponents: Array.isArray(options.request.includeComponents)
|
||||
? [...options.request.includeComponents]
|
||||
: [],
|
||||
excludeComponents: Array.isArray(options.request.excludeComponents)
|
||||
? [...options.request.excludeComponents]
|
||||
: [],
|
||||
legacyLanguages: Array.isArray(options.request.legacyLanguages)
|
||||
? [...options.request.legacyLanguages]
|
||||
: [],
|
||||
legacyMode: Boolean(options.request.legacyMode),
|
||||
},
|
||||
resolution: {
|
||||
selectedModules: Array.isArray(options.resolution.selectedModules)
|
||||
? [...options.resolution.selectedModules]
|
||||
: [],
|
||||
skippedModules: Array.isArray(options.resolution.skippedModules)
|
||||
? [...options.resolution.skippedModules]
|
||||
: [],
|
||||
},
|
||||
source: {
|
||||
repoVersion: options.source.repoVersion || null,
|
||||
repoCommit: options.source.repoCommit || null,
|
||||
manifestVersion: options.source.manifestVersion,
|
||||
},
|
||||
operations: Array.isArray(options.operations)
|
||||
? options.operations.map(operation => ({ ...operation }))
|
||||
: [],
|
||||
};
|
||||
|
||||
if (options.lastValidatedAt) {
|
||||
state.lastValidatedAt = options.lastValidatedAt;
|
||||
}
|
||||
|
||||
assertValidInstallState(state, 'create');
|
||||
return state;
|
||||
}
|
||||
|
||||
function readInstallState(filePath) {
|
||||
const state = readJson(filePath, 'install-state');
|
||||
assertValidInstallState(state, filePath);
|
||||
return state;
|
||||
}
|
||||
|
||||
function writeInstallState(filePath, state) {
|
||||
assertValidInstallState(state, filePath);
|
||||
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||||
fs.writeFileSync(filePath, `${JSON.stringify(state, null, 2)}\n`);
|
||||
return state;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createInstallState,
|
||||
readInstallState,
|
||||
validateInstallState,
|
||||
writeInstallState,
|
||||
};
|
||||
Reference in New Issue
Block a user