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,9 @@
const { createInstallTargetAdapter } = require('./helpers');
module.exports = createInstallTargetAdapter({
id: 'antigravity-project',
target: 'antigravity',
kind: 'project',
rootSegments: ['.agent'],
installStatePathSegments: ['ecc-install-state.json'],
});

View File

@@ -0,0 +1,10 @@
const { createInstallTargetAdapter } = require('./helpers');
module.exports = createInstallTargetAdapter({
id: 'claude-home',
target: 'claude',
kind: 'home',
rootSegments: ['.claude'],
installStatePathSegments: ['ecc', 'install-state.json'],
nativeRootRelativePath: '.claude-plugin',
});

View File

@@ -0,0 +1,10 @@
const { createInstallTargetAdapter } = require('./helpers');
module.exports = createInstallTargetAdapter({
id: 'codex-home',
target: 'codex',
kind: 'home',
rootSegments: ['.codex'],
installStatePathSegments: ['ecc-install-state.json'],
nativeRootRelativePath: '.codex',
});

View File

@@ -0,0 +1,10 @@
const { createInstallTargetAdapter } = require('./helpers');
module.exports = createInstallTargetAdapter({
id: 'cursor-project',
target: 'cursor',
kind: 'project',
rootSegments: ['.cursor'],
installStatePathSegments: ['ecc-install-state.json'],
nativeRootRelativePath: '.cursor',
});

View File

@@ -0,0 +1,89 @@
const os = require('os');
const path = require('path');
function normalizeRelativePath(relativePath) {
return String(relativePath || '')
.replace(/\\/g, '/')
.replace(/^\.\/+/, '')
.replace(/\/+$/, '');
}
function resolveBaseRoot(scope, input = {}) {
if (scope === 'home') {
return input.homeDir || os.homedir();
}
if (scope === 'project') {
const projectRoot = input.projectRoot || input.repoRoot;
if (!projectRoot) {
throw new Error('projectRoot or repoRoot is required for project install targets');
}
return projectRoot;
}
throw new Error(`Unsupported install target scope: ${scope}`);
}
function createInstallTargetAdapter(config) {
const adapter = {
id: config.id,
target: config.target,
kind: config.kind,
nativeRootRelativePath: config.nativeRootRelativePath || null,
supports(target) {
return target === config.target || target === config.id;
},
resolveRoot(input = {}) {
const baseRoot = resolveBaseRoot(config.kind, input);
return path.join(baseRoot, ...config.rootSegments);
},
getInstallStatePath(input = {}) {
const root = adapter.resolveRoot(input);
return path.join(root, ...config.installStatePathSegments);
},
resolveDestinationPath(sourceRelativePath, input = {}) {
const normalizedSourcePath = normalizeRelativePath(sourceRelativePath);
const targetRoot = adapter.resolveRoot(input);
if (
config.nativeRootRelativePath
&& normalizedSourcePath === normalizeRelativePath(config.nativeRootRelativePath)
) {
return targetRoot;
}
return path.join(targetRoot, normalizedSourcePath);
},
determineStrategy(sourceRelativePath) {
const normalizedSourcePath = normalizeRelativePath(sourceRelativePath);
if (
config.nativeRootRelativePath
&& normalizedSourcePath === normalizeRelativePath(config.nativeRootRelativePath)
) {
return 'sync-root-children';
}
return 'preserve-relative-path';
},
createScaffoldOperation(moduleId, sourceRelativePath, input = {}) {
const normalizedSourcePath = normalizeRelativePath(sourceRelativePath);
return {
kind: 'copy-path',
moduleId,
sourceRelativePath: normalizedSourcePath,
destinationPath: adapter.resolveDestinationPath(normalizedSourcePath, input),
strategy: adapter.determineStrategy(normalizedSourcePath),
ownership: 'managed',
scaffoldOnly: true,
};
},
};
return Object.freeze(adapter);
}
module.exports = {
createInstallTargetAdapter,
normalizeRelativePath,
};

View File

@@ -0,0 +1,10 @@
const { createInstallTargetAdapter } = require('./helpers');
module.exports = createInstallTargetAdapter({
id: 'opencode-home',
target: 'opencode',
kind: 'home',
rootSegments: ['.opencode'],
installStatePathSegments: ['ecc-install-state.json'],
nativeRootRelativePath: '.opencode',
});

View File

@@ -0,0 +1,64 @@
const antigravityProject = require('./antigravity-project');
const claudeHome = require('./claude-home');
const codexHome = require('./codex-home');
const cursorProject = require('./cursor-project');
const opencodeHome = require('./opencode-home');
const ADAPTERS = Object.freeze([
claudeHome,
cursorProject,
antigravityProject,
codexHome,
opencodeHome,
]);
function listInstallTargetAdapters() {
return ADAPTERS.slice();
}
function getInstallTargetAdapter(targetOrAdapterId) {
const adapter = ADAPTERS.find(candidate => candidate.supports(targetOrAdapterId));
if (!adapter) {
throw new Error(`Unknown install target adapter: ${targetOrAdapterId}`);
}
return adapter;
}
function planInstallTargetScaffold(options = {}) {
const adapter = getInstallTargetAdapter(options.target);
const modules = Array.isArray(options.modules) ? options.modules : [];
const planningInput = {
repoRoot: options.repoRoot,
projectRoot: options.projectRoot || options.repoRoot,
homeDir: options.homeDir,
};
const targetRoot = adapter.resolveRoot(planningInput);
const installStatePath = adapter.getInstallStatePath(planningInput);
const operations = modules.flatMap(module => {
const paths = Array.isArray(module.paths) ? module.paths : [];
return paths.map(sourceRelativePath => adapter.createScaffoldOperation(
module.id,
sourceRelativePath,
planningInput
));
});
return {
adapter: {
id: adapter.id,
target: adapter.target,
kind: adapter.kind,
},
targetRoot,
installStatePath,
operations,
};
}
module.exports = {
getInstallTargetAdapter,
listInstallTargetAdapters,
planInstallTargetScaffold,
};