fix(cline): mirror transactional Node adapter

This commit is contained in:
ZacharyZhang-NY committed 2026-07-20 10:46:25 -04:00
1 parent 3ca5d701de
commit 4ad139c60a
13 files changed
+1122 -626

No files matched your search

+43 -44
View File
@@ -1,61 +1,60 @@
import type { AgentPlugin, InstallConfig, PluginStatus } from './base.js';
import { AGENT_KEY, resolveHookFiles, runtimeContract } from './cline-contract.js';
import {
AGENT_KEY,
buildMetadata,
buildWrapper,
resolveHookFiles,
runtimeContract,
} from './cline-contract.js';
import {
readHookFile,
removeOwnedHooks,
requireAvailableHookFile,
requireRuntime,
runtimeFilesExist,
writeHookPair,
} from './cline-io.js';
commitClineInstallation,
commitClineUninstall,
preflightClineInstallation,
prepareClineInstallation,
prepareClineUninstall,
} from './cline-installation.js';
import { readHookFile, requireAvailableHookFile, runtimeFilesExist } from './cline-io.js';
import { SUPPORTED_AGENTS } from './registry.js';
const entry = SUPPORTED_AGENTS.get(AGENT_KEY)!;
export const clinePlugin: AgentPlugin = {
async install(config: InstallConfig): Promise<void> {
if (!config.agentId) throw new Error('agentId is required');
const paths = resolveHookFiles();
const guardState = await readHookFile(paths.guardPath);
const auditState = await readHookFile(paths.auditPath);
requireAvailableHookFile(guardState);
requireAvailableHookFile(auditState);
await requireRuntime(config.guardScriptPath, 'Elydora guard runtime');
await requireRuntime(config.hookScriptPath, 'Elydora audit runtime');
async function readHookPair() {
const paths = resolveHookFiles();
const [guardFile, auditFile] = await Promise.all([
readHookFile(paths.guardPath),
readHookFile(paths.auditPath),
]);
return { paths, guardFile, auditFile };
}
const guardMetadata = buildMetadata('guard', config.agentId, config.guardScriptPath);
const auditMetadata = buildMetadata('audit', config.agentId, config.hookScriptPath);
const guardSource = buildWrapper(guardMetadata);
const auditSource = buildWrapper(auditMetadata);
runtimeContract(
{ exists: true, filePath: paths.guardPath, source: guardSource, metadata: guardMetadata },
{ exists: true, filePath: paths.auditPath, source: auditSource, metadata: auditMetadata },
);
await writeHookPair(
{ state: guardState, source: guardSource },
{ state: auditState, source: auditSource },
);
function requireAvailablePair(
guardFile: Awaited<ReturnType<typeof readHookFile>>,
auditFile: Awaited<ReturnType<typeof readHookFile>>,
): void {
requireAvailableHookFile(guardFile);
requireAvailableHookFile(auditFile);
}
export const clinePlugin: AgentPlugin = {
managesRuntime: true,
async preflightInstall(config: InstallConfig): Promise<void> {
const { guardFile, auditFile } = await readHookPair();
requireAvailablePair(guardFile, auditFile);
await preflightClineInstallation(config, [guardFile, auditFile]);
},
async install(config: InstallConfig): Promise<void> {
const { guardFile, auditFile } = await readHookPair();
requireAvailablePair(guardFile, auditFile);
const prepared = await prepareClineInstallation(config, guardFile, auditFile);
await commitClineInstallation(prepared);
console.log(' Cline: user-level PreToolUse and PostToolUse hooks installed.');
},
async uninstall(agentId?: string): Promise<void> {
const paths = resolveHookFiles();
const guardState = await readHookFile(paths.guardPath);
const auditState = await readHookFile(paths.auditPath);
await removeOwnedHooks([guardState, auditState], agentId);
const { guardFile, auditFile } = await readHookPair();
const prepared = await prepareClineUninstall([guardFile, auditFile], agentId);
await commitClineUninstall(prepared);
},
async status(): Promise<PluginStatus> {
const paths = resolveHookFiles();
const guardState = await readHookFile(paths.guardPath);
const auditState = await readHookFile(paths.auditPath);
const contract = runtimeContract(guardState, auditState);
const { paths, guardFile, auditFile } = await readHookPair();
const contract = runtimeContract(guardFile, auditFile);
const hookConfigured = contract !== undefined;
const hookScriptExists = contract ? await runtimeFilesExist(contract) : false;
return {