From 418cf3588663e0f0f1693a2e7817781eb883b0ab Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Mon, 2 Feb 2026 15:04:53 +0900 Subject: [PATCH] format: apply prettier to index.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode) --- src/index.ts | 387 +++++++++++++++++++++++++++++---------------------- 1 file changed, 220 insertions(+), 167 deletions(-) diff --git a/src/index.ts b/src/index.ts index 8f5232dda..7c78f450c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,7 +19,6 @@ import { createAgentUsageReminderHook, createNonInteractiveEnvHook, createInteractiveBashSessionHook, - createThinkingBlockValidatorHook, createCategorySkillReminderHook, createRalphLoopHook, @@ -41,7 +40,11 @@ import { contextCollector, createContextInjectorMessagesTransformHook, } from "./features/context-injector"; -import { applyAgentVariant, resolveAgentVariant, resolveVariantForModel } from "./shared/agent-variant"; +import { + applyAgentVariant, + resolveAgentVariant, + resolveVariantForModel, +} from "./shared/agent-variant"; import { createFirstMessageVariantGate } from "./shared/first-message-variant"; import { discoverUserClaudeSkills, @@ -84,13 +87,24 @@ import { initTaskToastManager } from "./features/task-toast-manager"; import { TmuxSessionManager } from "./features/tmux-subagent"; import { clearBoulderState } from "./features/boulder-state"; import { type HookName } from "./config"; -import { log, detectExternalNotificationPlugin, getNotificationConflictWarning, resetMessageCursor, hasConnectedProvidersCache, getOpenCodeVersion, isOpenCodeVersionAtLeast, OPENCODE_NATIVE_AGENTS_INJECTION_VERSION } from "./shared"; +import { + log, + detectExternalNotificationPlugin, + getNotificationConflictWarning, + resetMessageCursor, + hasConnectedProvidersCache, + getOpenCodeVersion, + isOpenCodeVersionAtLeast, + OPENCODE_NATIVE_AGENTS_INJECTION_VERSION, +} from "./shared"; import { loadPluginConfig } from "./plugin-config"; import { createModelCacheState } from "./plugin-state"; import { createConfigHandler } from "./plugin-handlers"; const OhMyOpenCodePlugin: Plugin = async (ctx) => { - log("[OhMyOpenCodePlugin] ENTRY - plugin loading", { directory: ctx.directory }) + log("[OhMyOpenCodePlugin] ENTRY - plugin loading", { + directory: ctx.directory, + }); // Start background tmux check immediately startTmuxCheck(); @@ -100,7 +114,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { const tmuxConfig = { enabled: pluginConfig.tmux?.enabled ?? false, - layout: pluginConfig.tmux?.layout ?? 'main-vertical', + layout: pluginConfig.tmux?.layout ?? "main-vertical", main_pane_size: pluginConfig.tmux?.main_pane_size ?? 60, main_pane_min_width: pluginConfig.tmux?.main_pane_min_width ?? 120, agent_pane_min_width: pluginConfig.tmux?.agent_pane_min_width ?? 40, @@ -113,15 +127,17 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { ? createContextWindowMonitorHook(ctx) : null; const sessionRecovery = isHookEnabled("session-recovery") - ? createSessionRecoveryHook(ctx, { experimental: pluginConfig.experimental }) + ? createSessionRecoveryHook(ctx, { + experimental: pluginConfig.experimental, + }) : null; - + // Check for conflicting notification plugins before creating session-notification let sessionNotification = null; if (isHookEnabled("session-notification")) { const forceEnable = pluginConfig.notification?.force_enable ?? false; const externalNotifier = detectExternalNotificationPlugin(ctx.directory); - + if (externalNotifier.detected && !forceEnable) { // External notification plugin detected - skip our notification to avoid conflicts log(getNotificationConflictWarning(externalNotifier.pluginName!)); @@ -146,14 +162,18 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { let directoryAgentsInjector = null; if (isHookEnabled("directory-agents-injector")) { const currentVersion = getOpenCodeVersion(); - const hasNativeSupport = currentVersion !== null && + const hasNativeSupport = + currentVersion !== null && isOpenCodeVersionAtLeast(OPENCODE_NATIVE_AGENTS_INJECTION_VERSION); if (hasNativeSupport) { - log("directory-agents-injector auto-disabled due to native OpenCode support", { - currentVersion, - nativeVersion: OPENCODE_NATIVE_AGENTS_INJECTION_VERSION, - }); + log( + "directory-agents-injector auto-disabled due to native OpenCode support", + { + currentVersion, + nativeVersion: OPENCODE_NATIVE_AGENTS_INJECTION_VERSION, + }, + ); } else { directoryAgentsInjector = createDirectoryAgentsInjectorHook(ctx); } @@ -161,20 +181,23 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { const directoryReadmeInjector = isHookEnabled("directory-readme-injector") ? createDirectoryReadmeInjectorHook(ctx) : null; - const emptyTaskResponseDetector = isHookEnabled("empty-task-response-detector") + const emptyTaskResponseDetector = isHookEnabled( + "empty-task-response-detector", + ) ? createEmptyTaskResponseDetectorHook(ctx) : null; const thinkMode = isHookEnabled("think-mode") ? createThinkModeHook() : null; const claudeCodeHooks = createClaudeCodeHooksHook( ctx, { - disabledHooks: (pluginConfig.claude_code?.hooks ?? true) ? undefined : true, + disabledHooks: + (pluginConfig.claude_code?.hooks ?? true) ? undefined : true, keywordDetectorDisabled: !isHookEnabled("keyword-detector"), }, - contextCollector + contextCollector, ); const anthropicContextWindowLimitRecovery = isHookEnabled( - "anthropic-context-window-limit-recovery" + "anthropic-context-window-limit-recovery", ) ? createAnthropicContextWindowLimitRecoveryHook(ctx, { experimental: pluginConfig.experimental, @@ -247,32 +270,36 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { const tmuxSessionManager = new TmuxSessionManager(ctx, tmuxConfig); - const backgroundManager = new BackgroundManager(ctx, pluginConfig.background_task, { - tmuxConfig, - onSubagentSessionCreated: async (event) => { - log("[index] onSubagentSessionCreated callback received", { - sessionID: event.sessionID, - parentID: event.parentID, - title: event.title, - }); - await tmuxSessionManager.onSessionCreated({ - type: "session.created", - properties: { - info: { - id: event.sessionID, - parentID: event.parentID, - title: event.title, + const backgroundManager = new BackgroundManager( + ctx, + pluginConfig.background_task, + { + tmuxConfig, + onSubagentSessionCreated: async (event) => { + log("[index] onSubagentSessionCreated callback received", { + sessionID: event.sessionID, + parentID: event.parentID, + title: event.title, + }); + await tmuxSessionManager.onSessionCreated({ + type: "session.created", + properties: { + info: { + id: event.sessionID, + parentID: event.parentID, + title: event.title, + }, }, - }, - }); - log("[index] onSubagentSessionCreated callback completed"); + }); + log("[index] onSubagentSessionCreated callback completed"); + }, + onShutdown: () => { + tmuxSessionManager.cleanup().catch((error) => { + log("[index] tmux cleanup error during shutdown:", error); + }); + }, }, - onShutdown: () => { - tmuxSessionManager.cleanup().catch((error) => { - log("[index] tmux cleanup error during shutdown:", error) - }) - }, - }); + ); const atlasHook = isHookEnabled("atlas") ? createAtlasHook(ctx, { directory: ctx.directory, backgroundManager }) @@ -297,36 +324,40 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { const unstableAgentBabysitter = isHookEnabled("unstable-agent-babysitter") ? createUnstableAgentBabysitterHook( - { - directory: ctx.directory, - client: { - session: { - messages: async (args) => { - const result = await ctx.client.session.messages(args) - if (Array.isArray(result)) return result - if (typeof result === "object" && result !== null && "data" in result) { - const record = result as Record - return { data: record.data } - } - return [] - }, - prompt: async (args) => { - await ctx.client.session.prompt(args) - }, + { + directory: ctx.directory, + client: { + session: { + messages: async (args) => { + const result = await ctx.client.session.messages(args); + if (Array.isArray(result)) return result; + if ( + typeof result === "object" && + result !== null && + "data" in result + ) { + const record = result as Record; + return { data: record.data }; + } + return []; + }, + prompt: async (args) => { + await ctx.client.session.prompt(args); }, }, }, - { - backgroundManager, - config: pluginConfig.babysitting, - } - ) - : null; + }, + { + backgroundManager, + config: pluginConfig.babysitting, + }, + ) + : null; if (sessionRecovery && todoContinuationEnforcer) { sessionRecovery.setOnAbortCallback(todoContinuationEnforcer.markRecovering); sessionRecovery.setOnRecoveryCompleteCallback( - todoContinuationEnforcer.markRecoveryComplete + todoContinuationEnforcer.markRecoveryComplete, ); } @@ -337,10 +368,11 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { const callOmoAgent = createCallOmoAgent(ctx, backgroundManager); const isMultimodalLookerEnabled = !(pluginConfig.disabled_agents ?? []).some( - (agent) => agent.toLowerCase() === "multimodal-looker" + (agent) => agent.toLowerCase() === "multimodal-looker", ); const lookAt = isMultimodalLookerEnabled ? createLookAt(ctx) : null; - const browserProvider = pluginConfig.browser_automation_engine?.provider ?? "playwright"; + const browserProvider = + pluginConfig.browser_automation_engine?.provider ?? "playwright"; const delegateTask = createDelegateTask({ manager: backgroundManager, client: ctx.client, @@ -369,29 +401,32 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { }); const disabledSkills = new Set(pluginConfig.disabled_skills ?? []); const systemMcpNames = getSystemMcpServerNames(); - const builtinSkills = createBuiltinSkills({ browserProvider }).filter((skill) => { - if (disabledSkills.has(skill.name as never)) return false; - if (skill.mcpConfig) { - for (const mcpName of Object.keys(skill.mcpConfig)) { - if (systemMcpNames.has(mcpName)) return false; + const builtinSkills = createBuiltinSkills({ browserProvider }).filter( + (skill) => { + if (disabledSkills.has(skill.name as never)) return false; + if (skill.mcpConfig) { + for (const mcpName of Object.keys(skill.mcpConfig)) { + if (systemMcpNames.has(mcpName)) return false; + } } - } - return true; - }); + return true; + }, + ); const includeClaudeSkills = pluginConfig.claude_code?.skills !== false; - const [userSkills, globalSkills, projectSkills, opencodeProjectSkills] = await Promise.all([ - includeClaudeSkills ? discoverUserClaudeSkills() : Promise.resolve([]), - discoverOpencodeGlobalSkills(), - includeClaudeSkills ? discoverProjectClaudeSkills() : Promise.resolve([]), - discoverOpencodeProjectSkills(), - ]); + const [userSkills, globalSkills, projectSkills, opencodeProjectSkills] = + await Promise.all([ + includeClaudeSkills ? discoverUserClaudeSkills() : Promise.resolve([]), + discoverOpencodeGlobalSkills(), + includeClaudeSkills ? discoverProjectClaudeSkills() : Promise.resolve([]), + discoverOpencodeProjectSkills(), + ]); const mergedSkills = mergeSkills( builtinSkills, pluginConfig.skills, userSkills, globalSkills, projectSkills, - opencodeProjectSkills + opencodeProjectSkills, ); const skillMcpManager = new SkillMcpManager(); const getSessionIDForMcp = () => getMainSessionID() || ""; @@ -424,12 +459,14 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { }); const newTaskSystemEnabled = pluginConfig.new_task_system_enabled ?? false; - const taskToolsRecord: Record = newTaskSystemEnabled ? { - task_create: createTaskCreateTool(pluginConfig), - task_get: createTaskGetTool(pluginConfig), - task_list: createTaskList(pluginConfig), - task_update: createTaskUpdateTool(pluginConfig), - } : {}; + const taskToolsRecord: Record = newTaskSystemEnabled + ? { + task_create: createTaskCreateTool(pluginConfig, ctx), + task_get: createTaskGetTool(pluginConfig), + task_list: createTaskList(pluginConfig), + task_update: createTaskUpdateTool(pluginConfig, ctx), + } + : {}; return { tool: { @@ -450,23 +487,28 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { setSessionAgent(input.sessionID, input.agent); } - const message = (output as { message: { variant?: string } }).message + const message = (output as { message: { variant?: string } }).message; if (firstMessageVariantGate.shouldOverride(input.sessionID)) { - const variant = input.model && input.agent - ? resolveVariantForModel(pluginConfig, input.agent, input.model) - : resolveAgentVariant(pluginConfig, input.agent) + const variant = + input.model && input.agent + ? resolveVariantForModel(pluginConfig, input.agent, input.model) + : resolveAgentVariant(pluginConfig, input.agent); if (variant !== undefined) { - message.variant = variant + message.variant = variant; } - firstMessageVariantGate.markApplied(input.sessionID) + firstMessageVariantGate.markApplied(input.sessionID); } else { if (input.model && input.agent && message.variant === undefined) { - const variant = resolveVariantForModel(pluginConfig, input.agent, input.model) + const variant = resolveVariantForModel( + pluginConfig, + input.agent, + input.model, + ); if (variant !== undefined) { - message.variant = variant + message.variant = variant; } } else { - applyAgentVariant(pluginConfig, input.agent, message) + applyAgentVariant(pluginConfig, input.agent, message); } } @@ -477,14 +519,17 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { await startWork?.["chat.message"]?.(input, output); if (!hasConnectedProvidersCache()) { - ctx.client.tui.showToast({ - body: { - title: "⚠️ Provider Cache Missing", - message: "Model filtering disabled. RESTART OpenCode to enable full functionality.", - variant: "warning" as const, - duration: 6000, - }, - }).catch(() => {}); + ctx.client.tui + .showToast({ + body: { + title: "⚠️ Provider Cache Missing", + message: + "Model filtering disabled. RESTART OpenCode to enable full functionality.", + variant: "warning" as const, + duration: 6000, + }, + }) + .catch(() => {}); } if (ralphLoop) { @@ -502,12 +547,12 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { promptText.includes("You are starting a Ralph Loop") && promptText.includes(""); const isCancelRalphTemplate = promptText.includes( - "Cancel the currently active Ralph Loop" + "Cancel the currently active Ralph Loop", ); if (isRalphLoopTemplate) { const taskMatch = promptText.match( - /\s*([\s\S]*?)\s*<\/user-task>/i + /\s*([\s\S]*?)\s*<\/user-task>/i, ); const rawTask = taskMatch?.[1]?.trim() || ""; @@ -519,7 +564,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { const maxIterMatch = rawTask.match(/--max-iterations=(\d+)/i); const promiseMatch = rawTask.match( - /--completion-promise=["']?([^"'\s]+)["']?/i + /--completion-promise=["']?([^"'\s]+)["']?/i, ); log("[ralph-loop] Starting loop from chat.message", { @@ -543,15 +588,16 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { "experimental.chat.messages.transform": async ( input: Record, - output: { messages: Array<{ info: unknown; parts: unknown[] }> } + output: { messages: Array<{ info: unknown; parts: unknown[] }> }, ) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any - await contextInjectorMessagesTransform?.["experimental.chat.messages.transform"]?.(input, output as any); + await contextInjectorMessagesTransform?.[ + "experimental.chat.messages.transform" + ]?.(input, output as any); await thinkingBlockValidator?.[ "experimental.chat.messages.transform" // eslint-disable-next-line @typescript-eslint/no-explicit-any ]?.(input, output as any); - }, config: configHandler, @@ -579,36 +625,41 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { const { event } = input; const props = event.properties as Record | undefined; - if (event.type === "session.created") { - const sessionInfo = props?.info as - | { id?: string; title?: string; parentID?: string } - | undefined; - log("[event] session.created", { sessionInfo, props }); - if (!sessionInfo?.parentID) { - setMainSession(sessionInfo?.id); - } - firstMessageVariantGate.markSessionCreated(sessionInfo); - await tmuxSessionManager.onSessionCreated( - event as { type: string; properties?: { info?: { id?: string; parentID?: string; title?: string } } } - ); - } + if (event.type === "session.created") { + const sessionInfo = props?.info as + | { id?: string; title?: string; parentID?: string } + | undefined; + log("[event] session.created", { sessionInfo, props }); + if (!sessionInfo?.parentID) { + setMainSession(sessionInfo?.id); + } + firstMessageVariantGate.markSessionCreated(sessionInfo); + await tmuxSessionManager.onSessionCreated( + event as { + type: string; + properties?: { + info?: { id?: string; parentID?: string; title?: string }; + }; + }, + ); + } - if (event.type === "session.deleted") { - const sessionInfo = props?.info as { id?: string } | undefined; - if (sessionInfo?.id === getMainSessionID()) { - setMainSession(undefined); - } - if (sessionInfo?.id) { - clearSessionAgent(sessionInfo.id); - resetMessageCursor(sessionInfo.id); - firstMessageVariantGate.clear(sessionInfo.id); - await skillMcpManager.disconnectSession(sessionInfo.id); - await lspManager.cleanupTempDirectoryClients(); - await tmuxSessionManager.onSessionDeleted({ - sessionID: sessionInfo.id, - }); - } - } + if (event.type === "session.deleted") { + const sessionInfo = props?.info as { id?: string } | undefined; + if (sessionInfo?.id === getMainSessionID()) { + setMainSession(undefined); + } + if (sessionInfo?.id) { + clearSessionAgent(sessionInfo.id); + resetMessageCursor(sessionInfo.id); + firstMessageVariantGate.clear(sessionInfo.id); + await skillMcpManager.disconnectSession(sessionInfo.id); + await lspManager.cleanupTempDirectoryClients(); + await tmuxSessionManager.onSessionDeleted({ + sessionID: sessionInfo.id, + }); + } + } if (event.type === "message.updated") { const info = props?.info as Record | undefined; @@ -669,7 +720,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { const args = output.args as Record; const subagentType = args.subagent_type as string; const isExploreOrLibrarian = ["explore", "librarian"].some( - (name) => name.toLowerCase() === (subagentType ?? "").toLowerCase() + (name) => name.toLowerCase() === (subagentType ?? "").toLowerCase(), ); args.tools = { @@ -695,7 +746,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { const maxIterMatch = rawArgs.match(/--max-iterations=(\d+)/i); const promiseMatch = rawArgs.match( - /--completion-promise=["']?([^"'\s]+)["']?/i + /--completion-promise=["']?([^"'\s]+)["']?/i, ); ralphLoop.startLoop(sessionID, prompt, { @@ -704,30 +755,30 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { : undefined, completionPromise: promiseMatch?.[1], }); - } else if (command === "cancel-ralph" && sessionID) { - ralphLoop.cancelLoop(sessionID); - } else if (command === "ulw-loop" && sessionID) { - const rawArgs = - args?.command?.replace(/^\/?(ulw-loop)\s*/i, "") || ""; - const taskMatch = rawArgs.match(/^["'](.+?)["']/); - const prompt = - taskMatch?.[1] || - rawArgs.split(/\s+--/)[0]?.trim() || - "Complete the task as instructed"; + } else if (command === "cancel-ralph" && sessionID) { + ralphLoop.cancelLoop(sessionID); + } else if (command === "ulw-loop" && sessionID) { + const rawArgs = + args?.command?.replace(/^\/?(ulw-loop)\s*/i, "") || ""; + const taskMatch = rawArgs.match(/^["'](.+?)["']/); + const prompt = + taskMatch?.[1] || + rawArgs.split(/\s+--/)[0]?.trim() || + "Complete the task as instructed"; - const maxIterMatch = rawArgs.match(/--max-iterations=(\d+)/i); - const promiseMatch = rawArgs.match( - /--completion-promise=["']?([^"'\s]+)["']?/i - ); + const maxIterMatch = rawArgs.match(/--max-iterations=(\d+)/i); + const promiseMatch = rawArgs.match( + /--completion-promise=["']?([^"'\s]+)["']?/i, + ); - ralphLoop.startLoop(sessionID, prompt, { - ultrawork: true, - maxIterations: maxIterMatch - ? parseInt(maxIterMatch[1], 10) - : undefined, - completionPromise: promiseMatch?.[1], - }); - } + ralphLoop.startLoop(sessionID, prompt, { + ultrawork: true, + maxIterations: maxIterMatch + ? parseInt(maxIterMatch[1], 10) + : undefined, + completionPromise: promiseMatch?.[1], + }); + } } if (input.tool === "slashcommand") { @@ -740,7 +791,9 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { todoContinuationEnforcer?.cancelAllCountdowns(); ralphLoop?.cancelLoop(sessionID); clearBoulderState(ctx.directory); - log("[stop-continuation] All continuation mechanisms stopped", { sessionID }); + log("[stop-continuation] All continuation mechanisms stopped", { + sessionID, + }); } } }, @@ -761,9 +814,9 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { await agentUsageReminder?.["tool.execute.after"](input, output); await categorySkillReminder?.["tool.execute.after"](input, output); await interactiveBashSession?.["tool.execute.after"](input, output); -await editErrorRecovery?.["tool.execute.after"](input, output); - await delegateTaskRetry?.["tool.execute.after"](input, output); - await atlasHook?.["tool.execute.after"]?.(input, output); + await editErrorRecovery?.["tool.execute.after"](input, output); + await delegateTaskRetry?.["tool.execute.after"](input, output); + await atlasHook?.["tool.execute.after"]?.(input, output); await taskResumeInfo["tool.execute.after"](input, output); },