mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-01 22:53:27 +08:00
fix: harden install planning and sync tracked catalogs
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const { planInstallTargetScaffold } = require('./install-targets/registry');
|
||||
const { getInstallTargetAdapter, planInstallTargetScaffold } = require('./install-targets/registry');
|
||||
|
||||
const DEFAULT_REPO_ROOT = path.join(__dirname, '../..');
|
||||
const SUPPORTED_INSTALL_TARGETS = ['claude', 'cursor', 'antigravity', 'codex', 'gemini', 'opencode', 'codebuddy'];
|
||||
@@ -76,6 +76,48 @@ function dedupeStrings(values) {
|
||||
return [...new Set((Array.isArray(values) ? values : []).map(value => String(value).trim()).filter(Boolean))];
|
||||
}
|
||||
|
||||
function readOptionalStringOption(options, key) {
|
||||
if (
|
||||
!Object.prototype.hasOwnProperty.call(options, key)
|
||||
|| options[key] === null
|
||||
|| options[key] === undefined
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof options[key] !== 'string' || options[key].trim() === '') {
|
||||
throw new Error(`${key} must be a non-empty string when provided`);
|
||||
}
|
||||
|
||||
return options[key];
|
||||
}
|
||||
|
||||
function readModuleTargetsOrThrow(module) {
|
||||
const moduleId = module && module.id ? module.id : '<unknown>';
|
||||
const targets = module && module.targets;
|
||||
|
||||
if (!Array.isArray(targets)) {
|
||||
throw new Error(`Install module ${moduleId} has invalid targets; expected an array of supported target ids`);
|
||||
}
|
||||
|
||||
const normalizedTargets = targets.map(target => (
|
||||
typeof target === 'string' ? target.trim() : ''
|
||||
));
|
||||
|
||||
if (normalizedTargets.some(target => target.length === 0)) {
|
||||
throw new Error(`Install module ${moduleId} has invalid targets; expected an array of supported target ids`);
|
||||
}
|
||||
|
||||
const unsupportedTargets = normalizedTargets.filter(target => !SUPPORTED_INSTALL_TARGETS.includes(target));
|
||||
if (unsupportedTargets.length > 0) {
|
||||
throw new Error(
|
||||
`Install module ${moduleId} has unsupported targets: ${unsupportedTargets.join(', ')}`
|
||||
);
|
||||
}
|
||||
|
||||
return normalizedTargets;
|
||||
}
|
||||
|
||||
function assertKnownModuleIds(moduleIds, manifests) {
|
||||
const unknownModuleIds = dedupeStrings(moduleIds)
|
||||
.filter(moduleId => !manifests.modulesById.has(moduleId));
|
||||
@@ -125,6 +167,11 @@ function loadInstallManifests(options = {}) {
|
||||
? profilesData.profiles
|
||||
: {};
|
||||
const components = Array.isArray(componentsData.components) ? componentsData.components : [];
|
||||
|
||||
for (const module of modules) {
|
||||
readModuleTargetsOrThrow(module);
|
||||
}
|
||||
|
||||
const modulesById = new Map(modules.map(module => [module.id, module]));
|
||||
const componentsById = new Map(components.map(component => [component.id, component]));
|
||||
|
||||
@@ -361,6 +408,16 @@ function resolveInstallPlan(options = {}) {
|
||||
`Unknown install target: ${target}. Expected one of ${SUPPORTED_INSTALL_TARGETS.join(', ')}`
|
||||
);
|
||||
}
|
||||
const validatedProjectRoot = readOptionalStringOption(options, 'projectRoot');
|
||||
const validatedHomeDir = readOptionalStringOption(options, 'homeDir');
|
||||
const targetPlanningInput = target
|
||||
? {
|
||||
repoRoot: manifests.repoRoot,
|
||||
projectRoot: validatedProjectRoot || manifests.repoRoot,
|
||||
homeDir: validatedHomeDir || os.homedir(),
|
||||
}
|
||||
: null;
|
||||
const targetAdapter = target ? getInstallTargetAdapter(target) : null;
|
||||
|
||||
const effectiveRequestedIds = dedupeStrings(
|
||||
requestedModuleIds.filter(moduleId => !excludedModuleOwners.has(moduleId))
|
||||
@@ -396,7 +453,13 @@ function resolveInstallPlan(options = {}) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (target && !module.targets.includes(target)) {
|
||||
const supportsTarget = !target
|
||||
|| (
|
||||
readModuleTargetsOrThrow(module).includes(target)
|
||||
&& (!targetAdapter || targetAdapter.supportsModule(module, targetPlanningInput))
|
||||
);
|
||||
|
||||
if (!supportsTarget) {
|
||||
if (dependencyOf) {
|
||||
skippedTargetIds.add(rootRequesterId || dependencyOf);
|
||||
return false;
|
||||
@@ -444,9 +507,9 @@ function resolveInstallPlan(options = {}) {
|
||||
const scaffoldPlan = target
|
||||
? planInstallTargetScaffold({
|
||||
target,
|
||||
repoRoot: manifests.repoRoot,
|
||||
projectRoot: options.projectRoot || manifests.repoRoot,
|
||||
homeDir: options.homeDir || os.homedir(),
|
||||
repoRoot: targetPlanningInput.repoRoot,
|
||||
projectRoot: targetPlanningInput.projectRoot,
|
||||
homeDir: targetPlanningInput.homeDir,
|
||||
modules: selectedModules,
|
||||
})
|
||||
: null;
|
||||
|
||||
@@ -4,14 +4,28 @@ const {
|
||||
createFlatRuleOperations,
|
||||
createInstallTargetAdapter,
|
||||
createManagedScaffoldOperation,
|
||||
normalizeRelativePath,
|
||||
} = require('./helpers');
|
||||
|
||||
const SUPPORTED_SOURCE_PREFIXES = ['rules', 'commands', 'agents', 'skills', '.agents', 'AGENTS.md'];
|
||||
|
||||
function supportsAntigravitySourcePath(sourceRelativePath) {
|
||||
const normalizedPath = normalizeRelativePath(sourceRelativePath);
|
||||
return SUPPORTED_SOURCE_PREFIXES.some(prefix => (
|
||||
normalizedPath === prefix || normalizedPath.startsWith(`${prefix}/`)
|
||||
));
|
||||
}
|
||||
|
||||
module.exports = createInstallTargetAdapter({
|
||||
id: 'antigravity-project',
|
||||
target: 'antigravity',
|
||||
kind: 'project',
|
||||
rootSegments: ['.agent'],
|
||||
installStatePathSegments: ['ecc-install-state.json'],
|
||||
supportsModule(module) {
|
||||
const paths = Array.isArray(module && module.paths) ? module.paths : [];
|
||||
return paths.length > 0;
|
||||
},
|
||||
planOperations(input, adapter) {
|
||||
const modules = Array.isArray(input.modules)
|
||||
? input.modules
|
||||
@@ -30,7 +44,9 @@ module.exports = createInstallTargetAdapter({
|
||||
|
||||
return modules.flatMap(module => {
|
||||
const paths = Array.isArray(module.paths) ? module.paths : [];
|
||||
return paths.flatMap(sourceRelativePath => {
|
||||
return paths
|
||||
.filter(supportsAntigravitySourcePath)
|
||||
.flatMap(sourceRelativePath => {
|
||||
if (sourceRelativePath === 'rules') {
|
||||
return createFlatRuleOperations({
|
||||
moduleId: module.id,
|
||||
@@ -62,8 +78,8 @@ module.exports = createInstallTargetAdapter({
|
||||
];
|
||||
}
|
||||
|
||||
return [adapter.createScaffoldOperation(module.id, sourceRelativePath, planningInput)];
|
||||
});
|
||||
return [adapter.createScaffoldOperation(module.id, sourceRelativePath, planningInput)];
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -276,6 +276,13 @@ function createInstallTargetAdapter(config) {
|
||||
input
|
||||
));
|
||||
},
|
||||
supportsModule(module, input = {}) {
|
||||
if (typeof config.supportsModule === 'function') {
|
||||
return config.supportsModule(module, input, adapter);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
validate(input = {}) {
|
||||
if (typeof config.validate === 'function') {
|
||||
return config.validate(input, adapter);
|
||||
|
||||
Reference in New Issue
Block a user