mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 09:08:38 +00:00
refactor(cli): dedupe hook enable/disable logic
This commit is contained in:
@@ -66,6 +66,50 @@ function buildHooksReport(config: OpenClawConfig): HookStatusReport {
|
|||||||
return buildWorkspaceHookStatus(workspaceDir, { config, entries });
|
return buildWorkspaceHookStatus(workspaceDir, { config, entries });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveHookForToggle(
|
||||||
|
report: HookStatusReport,
|
||||||
|
hookName: string,
|
||||||
|
opts?: { requireEligible?: boolean },
|
||||||
|
): HookStatusEntry {
|
||||||
|
const hook = report.hooks.find((h) => h.name === hookName);
|
||||||
|
if (!hook) {
|
||||||
|
throw new Error(`Hook "${hookName}" not found`);
|
||||||
|
}
|
||||||
|
if (hook.managedByPlugin) {
|
||||||
|
throw new Error(
|
||||||
|
`Hook "${hookName}" is managed by plugin "${hook.pluginId ?? "unknown"}" and cannot be enabled/disabled.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (opts?.requireEligible && !hook.eligible) {
|
||||||
|
throw new Error(`Hook "${hookName}" is not eligible (missing requirements)`);
|
||||||
|
}
|
||||||
|
return hook;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildConfigWithHookEnabled(params: {
|
||||||
|
config: OpenClawConfig;
|
||||||
|
hookName: string;
|
||||||
|
enabled: boolean;
|
||||||
|
ensureHooksEnabled?: boolean;
|
||||||
|
}): OpenClawConfig {
|
||||||
|
const entries = { ...params.config.hooks?.internal?.entries };
|
||||||
|
entries[params.hookName] = { ...entries[params.hookName], enabled: params.enabled };
|
||||||
|
|
||||||
|
const internal = {
|
||||||
|
...params.config.hooks?.internal,
|
||||||
|
...(params.ensureHooksEnabled ? { enabled: true } : {}),
|
||||||
|
entries,
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
...params.config,
|
||||||
|
hooks: {
|
||||||
|
...params.config.hooks,
|
||||||
|
internal,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function formatHookStatus(hook: HookStatusEntry): string {
|
function formatHookStatus(hook: HookStatusEntry): string {
|
||||||
if (hook.eligible) {
|
if (hook.eligible) {
|
||||||
return theme.success("✓ ready");
|
return theme.success("✓ ready");
|
||||||
@@ -384,38 +428,13 @@ export function formatHooksCheck(report: HookStatusReport, opts: HooksCheckOptio
|
|||||||
|
|
||||||
export async function enableHook(hookName: string): Promise<void> {
|
export async function enableHook(hookName: string): Promise<void> {
|
||||||
const config = loadConfig();
|
const config = loadConfig();
|
||||||
const report = buildHooksReport(config);
|
const hook = resolveHookForToggle(buildHooksReport(config), hookName, { requireEligible: true });
|
||||||
const hook = report.hooks.find((h) => h.name === hookName);
|
const nextConfig = buildConfigWithHookEnabled({
|
||||||
|
config,
|
||||||
if (!hook) {
|
hookName,
|
||||||
throw new Error(`Hook "${hookName}" not found`);
|
enabled: true,
|
||||||
}
|
ensureHooksEnabled: true,
|
||||||
|
});
|
||||||
if (hook.managedByPlugin) {
|
|
||||||
throw new Error(
|
|
||||||
`Hook "${hookName}" is managed by plugin "${hook.pluginId ?? "unknown"}" and cannot be enabled/disabled.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hook.eligible) {
|
|
||||||
throw new Error(`Hook "${hookName}" is not eligible (missing requirements)`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update config
|
|
||||||
const entries = { ...config.hooks?.internal?.entries };
|
|
||||||
entries[hookName] = { ...entries[hookName], enabled: true };
|
|
||||||
|
|
||||||
const nextConfig = {
|
|
||||||
...config,
|
|
||||||
hooks: {
|
|
||||||
...config.hooks,
|
|
||||||
internal: {
|
|
||||||
...config.hooks?.internal,
|
|
||||||
enabled: true,
|
|
||||||
entries,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
await writeConfigFile(nextConfig);
|
await writeConfigFile(nextConfig);
|
||||||
defaultRuntime.log(
|
defaultRuntime.log(
|
||||||
@@ -425,33 +444,8 @@ export async function enableHook(hookName: string): Promise<void> {
|
|||||||
|
|
||||||
export async function disableHook(hookName: string): Promise<void> {
|
export async function disableHook(hookName: string): Promise<void> {
|
||||||
const config = loadConfig();
|
const config = loadConfig();
|
||||||
const report = buildHooksReport(config);
|
const hook = resolveHookForToggle(buildHooksReport(config), hookName);
|
||||||
const hook = report.hooks.find((h) => h.name === hookName);
|
const nextConfig = buildConfigWithHookEnabled({ config, hookName, enabled: false });
|
||||||
|
|
||||||
if (!hook) {
|
|
||||||
throw new Error(`Hook "${hookName}" not found`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hook.managedByPlugin) {
|
|
||||||
throw new Error(
|
|
||||||
`Hook "${hookName}" is managed by plugin "${hook.pluginId ?? "unknown"}" and cannot be enabled/disabled.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update config
|
|
||||||
const entries = { ...config.hooks?.internal?.entries };
|
|
||||||
entries[hookName] = { ...entries[hookName], enabled: false };
|
|
||||||
|
|
||||||
const nextConfig = {
|
|
||||||
...config,
|
|
||||||
hooks: {
|
|
||||||
...config.hooks,
|
|
||||||
internal: {
|
|
||||||
...config.hooks?.internal,
|
|
||||||
entries,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
await writeConfigFile(nextConfig);
|
await writeConfigFile(nextConfig);
|
||||||
defaultRuntime.log(
|
defaultRuntime.log(
|
||||||
|
|||||||
Reference in New Issue
Block a user