fix(kiroide): adopt workspace v1 hooks
This commit is contained in:
1 parent
3cfd0a5187
commit
5889b09a09
11 files changed
+1535
-74
No files matched your search
+52
-73
@@ -1,94 +1,73 @@
|
||||
import fsp from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import os from 'node:os';
|
||||
import type { AgentPlugin, InstallConfig, PluginStatus } from './base.js';
|
||||
import {
|
||||
AGENT_KEY,
|
||||
buildKiroIdeHook,
|
||||
kiroIdeRuntimeContracts,
|
||||
renderKiroIdeDocument,
|
||||
requireAvailableKiroIdeHooks,
|
||||
withoutManagedKiroIdeHooks,
|
||||
} from './kiroide-contract.js';
|
||||
import {
|
||||
commitKiroIdeInstallation,
|
||||
commitKiroIdeUninstall,
|
||||
preflightKiroIdeInstallation,
|
||||
prepareKiroIdeInstallation,
|
||||
prepareKiroIdeUninstall,
|
||||
} from './kiroide-installation.js';
|
||||
import { readKiroIdeSources, runtimeFilesExist } from './kiroide-io.js';
|
||||
import { SUPPORTED_AGENTS } from './registry.js';
|
||||
|
||||
const AGENT_KEY = 'kiroide';
|
||||
const entry = SUPPORTED_AGENTS.get(AGENT_KEY)!;
|
||||
|
||||
function resolveConfigDir(): string {
|
||||
// .kiro/hooks is project-relative, but for global install use home dir
|
||||
return path.join(os.homedir(), entry.configDir);
|
||||
}
|
||||
|
||||
function resolveConfigPath(): string {
|
||||
return path.join(resolveConfigDir(), entry.configFile);
|
||||
}
|
||||
|
||||
export const kiroidePlugin: AgentPlugin = {
|
||||
async install(config: InstallConfig): Promise<void> {
|
||||
const configDir = resolveConfigDir();
|
||||
await fsp.mkdir(configDir, { recursive: true });
|
||||
managesRuntime: true,
|
||||
|
||||
const configPath = resolveConfigPath();
|
||||
|
||||
const hookConfig = {
|
||||
name: 'Elydora Audit',
|
||||
description: 'Sends tool-use events to the Elydora tamper-evident audit platform',
|
||||
version: '1.0.0',
|
||||
hooks: {
|
||||
pre_tool_use: {
|
||||
command: `node "${config.guardScriptPath}"`,
|
||||
timeout_ms: 5000,
|
||||
},
|
||||
post_tool_use: {
|
||||
command: `node "${config.hookScriptPath}"`,
|
||||
timeout_ms: 5000,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
await fsp.writeFile(configPath, JSON.stringify(hookConfig, null, 2) + '\n', 'utf-8');
|
||||
async preflightInstall(config: InstallConfig): Promise<void> {
|
||||
const sources = await readKiroIdeSources();
|
||||
requireAvailableKiroIdeHooks(sources.document.hooks);
|
||||
await preflightKiroIdeInstallation(config, sources.paths);
|
||||
},
|
||||
|
||||
async uninstall(_agentId?: string): Promise<void> {
|
||||
const configPath = resolveConfigPath();
|
||||
try {
|
||||
await fsp.unlink(configPath);
|
||||
} catch {
|
||||
// Already removed
|
||||
}
|
||||
async install(config: InstallConfig): Promise<void> {
|
||||
const sources = await readKiroIdeSources();
|
||||
requireAvailableKiroIdeHooks(sources.document.hooks);
|
||||
const paths = await preflightKiroIdeInstallation(config, sources.paths);
|
||||
const hooks = withoutManagedKiroIdeHooks(sources.document.hooks);
|
||||
const rendered = renderKiroIdeDocument(sources.document, [
|
||||
...hooks,
|
||||
buildKiroIdeHook('elydora-guard', paths.guardPath),
|
||||
buildKiroIdeHook('elydora-audit', paths.auditPath),
|
||||
]);
|
||||
const prepared = await prepareKiroIdeInstallation(config, sources, rendered);
|
||||
await commitKiroIdeInstallation(prepared);
|
||||
console.log(` Kiro IDE workspace hooks: ${sources.paths.configPath}`);
|
||||
console.log(' Kiro IDE verification: confirm Elydora hooks in the Agent Hooks panel.');
|
||||
},
|
||||
|
||||
async uninstall(agentId?: string): Promise<void> {
|
||||
const sources = await readKiroIdeSources();
|
||||
const rendered = renderKiroIdeDocument(
|
||||
sources.document,
|
||||
withoutManagedKiroIdeHooks(sources.document.hooks, agentId),
|
||||
);
|
||||
const prepared = await prepareKiroIdeUninstall(sources, rendered, agentId);
|
||||
await commitKiroIdeUninstall(prepared);
|
||||
},
|
||||
|
||||
async status(): Promise<PluginStatus> {
|
||||
const configPath = resolveConfigPath();
|
||||
|
||||
let hookConfigured = false;
|
||||
let hookScriptPath = '';
|
||||
try {
|
||||
const raw = await fsp.readFile(configPath, 'utf-8');
|
||||
const config = JSON.parse(raw);
|
||||
hookConfigured = !!(config.hooks && config.hooks.pre_tool_use && config.hooks.post_tool_use);
|
||||
|
||||
// Extract hook script path from post_tool_use command
|
||||
if (hookConfigured && config.hooks.post_tool_use) {
|
||||
const cmd = config.hooks.post_tool_use.command as string;
|
||||
if (cmd && cmd.includes('elydora')) {
|
||||
hookScriptPath = cmd.replace(/^node\s+"?/, '').replace(/"?\s*$/, '');
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Config not readable
|
||||
}
|
||||
|
||||
let hookScriptExists = false;
|
||||
if (hookScriptPath) {
|
||||
try {
|
||||
await fsp.access(hookScriptPath);
|
||||
hookScriptExists = true;
|
||||
} catch {
|
||||
// File doesn't exist
|
||||
}
|
||||
}
|
||||
|
||||
const sources = await readKiroIdeSources();
|
||||
requireAvailableKiroIdeHooks(sources.document.hooks);
|
||||
const contracts = kiroIdeRuntimeContracts(sources.document.hooks);
|
||||
const hookConfigured = contracts.length > 0;
|
||||
const hookScriptExists = hookConfigured
|
||||
&& (await Promise.all(contracts.map(runtimeFilesExist))).every(Boolean);
|
||||
return {
|
||||
installed: hookConfigured && hookScriptExists,
|
||||
agentName: AGENT_KEY,
|
||||
displayName: entry.name,
|
||||
hookConfigured,
|
||||
hookScriptExists,
|
||||
configPath,
|
||||
configPath: sources.paths.configPath,
|
||||
};
|
||||
},
|
||||
};
|
||||
Reference in new issue
Block a user