From 488c89156b516898a180e030114ef2063195bb9d Mon Sep 17 00:00:00 2001 From: justsisyphus Date: Tue, 27 Jan 2026 16:06:03 +0900 Subject: [PATCH] test(config-handler): add tests for plan demote and prometheus mode --- src/plugin-handlers/config-handler.test.ts | 166 ++++++++++++++++++++- 1 file changed, 164 insertions(+), 2 deletions(-) diff --git a/src/plugin-handlers/config-handler.test.ts b/src/plugin-handlers/config-handler.test.ts index 3173d568..eb7bee99 100644 --- a/src/plugin-handlers/config-handler.test.ts +++ b/src/plugin-handlers/config-handler.test.ts @@ -1,6 +1,168 @@ -import { describe, test, expect } from "bun:test" -import { resolveCategoryConfig } from "./config-handler" +import { describe, test, expect, mock, beforeEach } from "bun:test" +import { resolveCategoryConfig, createConfigHandler } from "./config-handler" import type { CategoryConfig } from "../config/schema" +import type { OhMyOpenCodeConfig } from "../config" + +mock.module("../agents", () => ({ + createBuiltinAgents: async () => ({ + sisyphus: { name: "sisyphus", prompt: "test", mode: "primary" }, + oracle: { name: "oracle", prompt: "test", mode: "subagent" }, + }), +})) + +mock.module("../agents/sisyphus-junior", () => ({ + createSisyphusJuniorAgentWithOverrides: () => ({ + name: "sisyphus-junior", + prompt: "test", + mode: "subagent", + }), +})) + +mock.module("../features/claude-code-command-loader", () => ({ + loadUserCommands: async () => ({}), + loadProjectCommands: async () => ({}), + loadOpencodeGlobalCommands: async () => ({}), + loadOpencodeProjectCommands: async () => ({}), +})) + +mock.module("../features/builtin-commands", () => ({ + loadBuiltinCommands: () => ({}), +})) + +mock.module("../features/opencode-skill-loader", () => ({ + loadUserSkills: async () => ({}), + loadProjectSkills: async () => ({}), + loadOpencodeGlobalSkills: async () => ({}), + loadOpencodeProjectSkills: async () => ({}), + discoverUserClaudeSkills: async () => [], + discoverProjectClaudeSkills: async () => [], + discoverOpencodeGlobalSkills: async () => [], + discoverOpencodeProjectSkills: async () => [], +})) + +mock.module("../features/claude-code-agent-loader", () => ({ + loadUserAgents: () => ({}), + loadProjectAgents: () => ({}), +})) + +mock.module("../features/claude-code-mcp-loader", () => ({ + loadMcpConfigs: async () => ({ servers: {} }), +})) + +mock.module("../features/claude-code-plugin-loader", () => ({ + loadAllPluginComponents: async () => ({ + commands: {}, + skills: {}, + agents: {}, + mcpServers: {}, + hooksConfigs: [], + plugins: [], + errors: [], + }), +})) + +mock.module("../mcp", () => ({ + createBuiltinMcps: () => ({}), +})) + +mock.module("../shared", () => ({ + log: () => {}, + fetchAvailableModels: async () => new Set(["anthropic/claude-opus-4-5"]), + readConnectedProvidersCache: () => null, +})) + +mock.module("../shared/opencode-config-dir", () => ({ + getOpenCodeConfigPaths: () => ({ + global: "/tmp/.config/opencode", + project: "/tmp/.opencode", + }), +})) + +mock.module("../shared/permission-compat", () => ({ + migrateAgentConfig: (config: Record) => config, +})) + +mock.module("../shared/migration", () => ({ + AGENT_NAME_MAP: {}, +})) + +mock.module("../shared/model-resolver", () => ({ + resolveModelWithFallback: () => ({ model: "anthropic/claude-opus-4-5" }), +})) + +mock.module("../shared/model-requirements", () => ({ + AGENT_MODEL_REQUIREMENTS: { + prometheus: { fallbackChain: [{ providers: ["anthropic"], model: "claude-opus-4-5" }] }, + }, +})) + +describe("Plan agent demote behavior", () => { + test("plan agent should be demoted to subagent mode when replacePlan is true", async () => { + // #given + const pluginConfig: OhMyOpenCodeConfig = { + sisyphus_agent: { + planner_enabled: true, + replace_plan: true, + }, + } + const config: Record = { + model: "anthropic/claude-opus-4-5", + agent: { + plan: { + name: "plan", + mode: "primary", + prompt: "original plan prompt", + }, + }, + } + const handler = createConfigHandler({ + ctx: { directory: "/tmp" }, + pluginConfig, + modelCacheState: { + anthropicContext1MEnabled: false, + modelContextLimitsCache: new Map(), + }, + }) + + // #when + await handler(config) + + // #then + const agents = config.agent as Record + expect(agents.plan).toBeDefined() + expect(agents.plan.mode).toBe("subagent") + expect(agents.plan.name).toBe("plan") + }) + + test("prometheus should have mode 'all' to be callable via delegate_task", async () => { + // #given + const pluginConfig: OhMyOpenCodeConfig = { + sisyphus_agent: { + planner_enabled: true, + }, + } + const config: Record = { + model: "anthropic/claude-opus-4-5", + agent: {}, + } + const handler = createConfigHandler({ + ctx: { directory: "/tmp" }, + pluginConfig, + modelCacheState: { + anthropicContext1MEnabled: false, + modelContextLimitsCache: new Map(), + }, + }) + + // #when + await handler(config) + + // #then + const agents = config.agent as Record + expect(agents.prometheus).toBeDefined() + expect(agents.prometheus.mode).toBe("all") + }) +}) describe("Prometheus category config resolution", () => { test("resolves ultrabrain category config", () => {