diff --git a/src/config/schema.ts b/src/config/schema.ts index 0eff0bd..2f882cd 100644 --- a/src/config/schema.ts +++ b/src/config/schema.ts @@ -44,6 +44,7 @@ export const HookNameSchema = z.enum([ "session-notification", "comment-checker", "grep-output-truncator", + "tool-output-truncator", "directory-agents-injector", "directory-readme-injector", "empty-task-response-detector", @@ -52,7 +53,7 @@ export const HookNameSchema = z.enum([ "rules-injector", "background-notification", "auto-update-checker", - "ultrawork-mode", + "keyword-detector", "agent-usage-reminder", ]) diff --git a/src/hooks/index.ts b/src/hooks/index.ts index ea1f607..251fe2d 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -4,6 +4,7 @@ export { createSessionNotification } from "./session-notification"; export { createSessionRecoveryHook, type SessionRecoveryHook } from "./session-recovery"; export { createCommentCheckerHooks } from "./comment-checker"; export { createGrepOutputTruncatorHook } from "./grep-output-truncator"; +export { createToolOutputTruncatorHook } from "./tool-output-truncator"; export { createDirectoryAgentsInjectorHook } from "./directory-agents-injector"; export { createDirectoryReadmeInjectorHook } from "./directory-readme-injector"; export { createEmptyTaskResponseDetectorHook } from "./empty-task-response-detector"; @@ -13,5 +14,6 @@ export { createClaudeCodeHooksHook } from "./claude-code-hooks"; export { createRulesInjectorHook } from "./rules-injector"; export { createBackgroundNotificationHook } from "./background-notification" export { createAutoUpdateCheckerHook } from "./auto-update-checker"; -export { createUltraworkModeHook } from "./ultrawork-mode"; + export { createAgentUsageReminderHook } from "./agent-usage-reminder"; +export { createKeywordDetectorHook } from "./keyword-detector"; diff --git a/src/hooks/tool-output-truncator.ts b/src/hooks/tool-output-truncator.ts new file mode 100644 index 0000000..0182d5b --- /dev/null +++ b/src/hooks/tool-output-truncator.ts @@ -0,0 +1,38 @@ +import type { PluginInput } from "@opencode-ai/plugin" +import { createDynamicTruncator } from "../shared/dynamic-truncator" + +const TRUNCATABLE_TOOLS = [ + "Grep", + "safe_grep", + "Glob", + "safe_glob", + "lsp_find_references", + "lsp_document_symbols", + "lsp_workspace_symbols", + "lsp_diagnostics", + "ast_grep_search", +] + +export function createToolOutputTruncatorHook(ctx: PluginInput) { + const truncator = createDynamicTruncator(ctx) + + const toolExecuteAfter = async ( + input: { tool: string; sessionID: string; callID: string }, + output: { title: string; output: string; metadata: unknown } + ) => { + if (!TRUNCATABLE_TOOLS.includes(input.tool)) return + + try { + const { result, truncated } = await truncator.truncate(input.sessionID, output.output) + if (truncated) { + output.output = result + } + } catch { + // Graceful degradation - don't break tool execution + } + } + + return { + "tool.execute.after": toolExecuteAfter, + } +} diff --git a/src/index.ts b/src/index.ts index 49e306d..360043f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,7 @@ import { createSessionRecoveryHook, createSessionNotification, createCommentCheckerHooks, - createGrepOutputTruncatorHook, + createToolOutputTruncatorHook, createDirectoryAgentsInjectorHook, createDirectoryReadmeInjectorHook, createEmptyTaskResponseDetectorHook, @@ -16,7 +16,7 @@ import { createRulesInjectorHook, createBackgroundNotificationHook, createAutoUpdateCheckerHook, - createUltraworkModeHook, + createKeywordDetectorHook, createAgentUsageReminderHook, } from "./hooks"; import { createGoogleAntigravityAuthPlugin } from "./auth/antigravity"; @@ -178,8 +178,8 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { const commentChecker = isHookEnabled("comment-checker") ? createCommentCheckerHooks() : null; - const grepOutputTruncator = isHookEnabled("grep-output-truncator") - ? createGrepOutputTruncatorHook(ctx) + const toolOutputTruncator = isHookEnabled("tool-output-truncator") + ? createToolOutputTruncatorHook(ctx) : null; const directoryAgentsInjector = isHookEnabled("directory-agents-injector") ? createDirectoryAgentsInjectorHook(ctx) @@ -205,8 +205,8 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { const autoUpdateChecker = isHookEnabled("auto-update-checker") ? createAutoUpdateCheckerHook(ctx) : null; - const ultraworkMode = isHookEnabled("ultrawork-mode") - ? createUltraworkModeHook() + const keywordDetector = isHookEnabled("keyword-detector") + ? createKeywordDetectorHook() : null; const agentUsageReminder = isHookEnabled("agent-usage-reminder") ? createAgentUsageReminderHook(ctx) @@ -240,7 +240,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { "chat.message": async (input, output) => { await claudeCodeHooks["chat.message"]?.(input, output); - await ultraworkMode?.["chat.message"]?.(input, output); + await keywordDetector?.["chat.message"]?.(input, output); }, config: async (config) => { @@ -337,7 +337,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { await rulesInjector?.event(input); await thinkMode?.event(input); await anthropicAutoCompact?.event(input); - await ultraworkMode?.event(input); + await keywordDetector?.event(input); await agentUsageReminder?.event(input); const { event } = input; @@ -451,7 +451,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { "tool.execute.after": async (input, output) => { await claudeCodeHooks["tool.execute.after"](input, output); - await grepOutputTruncator?.["tool.execute.after"](input, output); + await toolOutputTruncator?.["tool.execute.after"](input, output); await contextWindowMonitor?.["tool.execute.after"](input, output); await commentChecker?.["tool.execute.after"](input, output); await directoryAgentsInjector?.["tool.execute.after"](input, output);