diff --git a/src/agents/build.ts b/src/agents/build.ts new file mode 100644 index 0000000..b0c9d90 --- /dev/null +++ b/src/agents/build.ts @@ -0,0 +1,77 @@ +export const BUILD_AGENT_PROMPT_EXTENSION = ` +# Agent Orchestration & Task Management + +You are not just a coder - you are an **ORCHESTRATOR**. Your primary job is to delegate work to specialized agents and track progress obsessively. + +## Think Before Acting + +When you receive a user request, STOP and think deeply: + +1. **What specialized agents can handle this better than me?** + - explore: File search, codebase navigation, pattern matching + - librarian: Documentation lookup, API references, implementation examples + - oracle: Architecture decisions, code review, complex logic analysis + - frontend-ui-ux-engineer: UI/UX implementation, component design + - document-writer: Documentation, README, technical writing + +2. **Can I parallelize this work?** + - Fire multiple background_task calls simultaneously + - Continue working on other parts while agents investigate + - Aggregate results when notified + +3. **Have I planned this in my TODO list?** + - Break down the task into atomic steps FIRST + - Track every investigation, every delegation + +## TODO Tool Obsession + +**USE TODO TOOLS AGGRESSIVELY.** This is non-negotiable. + +### When to Use TodoWrite: +- IMMEDIATELY after receiving a user request +- Before ANY multi-step task (even if it seems "simple") +- When delegating to agents (track what you delegated) +- After completing each step (mark it done) + +### TODO Workflow: +\`\`\` +User Request → TodoWrite (plan) → Mark in_progress → Execute/Delegate → Mark complete → Next +\`\`\` + +### Rules: +- Only ONE task in_progress at a time +- Mark complete IMMEDIATELY after finishing (never batch) +- Never proceed without updating TODO status + +## Delegation Pattern + +\`\`\`typescript +// 1. PLAN with TODO first +todowrite([ + { id: "research", content: "Research X implementation", status: "in_progress", priority: "high" }, + { id: "impl", content: "Implement X feature", status: "pending", priority: "high" }, + { id: "test", content: "Test X feature", status: "pending", priority: "medium" } +]) + +// 2. DELEGATE research in parallel +background_task(agent="explore", prompt="Find all files related to X") +background_task(agent="librarian", prompt="Look up X documentation") + +// 3. CONTINUE working on implementation skeleton while agents research +// 4. When notified, INTEGRATE findings and mark TODO complete +\`\`\` + +## Anti-Patterns (AVOID): +- Doing everything yourself when agents can help +- Skipping TODO planning for "quick" tasks +- Forgetting to mark tasks complete +- Sequential execution when parallel is possible +- Direct tool calls without considering delegation + +## Remember: +- You are the **team lead**, not the grunt worker +- Your context window is precious - delegate to preserve it +- Agents have specialized expertise - USE THEM +- TODO tracking gives users visibility into your progress +- Parallel execution = faster results +`; diff --git a/src/agents/index.ts b/src/agents/index.ts index 8f2c3ed..65b7a78 100644 --- a/src/agents/index.ts +++ b/src/agents/index.ts @@ -17,3 +17,4 @@ export const builtinAgents: Record = { export * from "./types" export { createBuiltinAgents } from "./utils" +export { BUILD_AGENT_PROMPT_EXTENSION } from "./build" diff --git a/src/agents/types.ts b/src/agents/types.ts index e24d04d..2ecc2df 100644 --- a/src/agents/types.ts +++ b/src/agents/types.ts @@ -1,6 +1,6 @@ import type { AgentConfig } from "@opencode-ai/sdk" -export type AgentName = +export type BuiltinAgentName = | "oracle" | "librarian" | "explore" @@ -8,6 +8,12 @@ export type AgentName = | "document-writer" | "multimodal-looker" +export type OverridableAgentName = + | "build" + | BuiltinAgentName + +export type AgentName = BuiltinAgentName + export type AgentOverrideConfig = Partial -export type AgentOverrides = Partial> +export type AgentOverrides = Partial> diff --git a/src/agents/utils.ts b/src/agents/utils.ts index 64eca40..997a449 100644 --- a/src/agents/utils.ts +++ b/src/agents/utils.ts @@ -1,5 +1,5 @@ import type { AgentConfig } from "@opencode-ai/sdk" -import type { AgentName, AgentOverrideConfig, AgentOverrides } from "./types" +import type { BuiltinAgentName, AgentOverrideConfig, AgentOverrides } from "./types" import { oracleAgent } from "./oracle" import { librarianAgent } from "./librarian" import { exploreAgent } from "./explore" @@ -8,7 +8,7 @@ import { documentWriterAgent } from "./document-writer" import { multimodalLookerAgent } from "./multimodal-looker" import { deepMerge } from "../shared" -const allBuiltinAgents: Record = { +const allBuiltinAgents: Record = { oracle: oracleAgent, librarian: librarianAgent, explore: exploreAgent, @@ -25,13 +25,13 @@ function mergeAgentConfig( } export function createBuiltinAgents( - disabledAgents: AgentName[] = [], + disabledAgents: BuiltinAgentName[] = [], agentOverrides: AgentOverrides = {} ): Record { const result: Record = {} for (const [name, config] of Object.entries(allBuiltinAgents)) { - const agentName = name as AgentName + const agentName = name as BuiltinAgentName if (disabledAgents.includes(agentName)) { continue diff --git a/src/config/schema.ts b/src/config/schema.ts index 883770b..0eff0bd 100644 --- a/src/config/schema.ts +++ b/src/config/schema.ts @@ -16,7 +16,7 @@ const AgentPermissionSchema = z.object({ external_directory: PermissionValue.optional(), }) -export const AgentNameSchema = z.enum([ +export const BuiltinAgentNameSchema = z.enum([ "oracle", "librarian", "explore", @@ -25,6 +25,18 @@ export const AgentNameSchema = z.enum([ "multimodal-looker", ]) +export const OverridableAgentNameSchema = z.enum([ + "build", + "oracle", + "librarian", + "explore", + "frontend-ui-ux-engineer", + "document-writer", + "multimodal-looker", +]) + +export const AgentNameSchema = BuiltinAgentNameSchema + export const HookNameSchema = z.enum([ "todo-continuation-enforcer", "context-window-monitor", @@ -62,6 +74,7 @@ export const AgentOverrideConfigSchema = z.object({ export const AgentOverridesSchema = z .object({ + build: AgentOverrideConfigSchema.optional(), oracle: AgentOverrideConfigSchema.optional(), librarian: AgentOverrideConfigSchema.optional(), explore: AgentOverrideConfigSchema.optional(), @@ -82,7 +95,7 @@ export const ClaudeCodeConfigSchema = z.object({ export const OhMyOpenCodeConfigSchema = z.object({ $schema: z.string().optional(), disabled_mcps: z.array(McpNameSchema).optional(), - disabled_agents: z.array(AgentNameSchema).optional(), + disabled_agents: z.array(BuiltinAgentNameSchema).optional(), disabled_hooks: z.array(HookNameSchema).optional(), agents: AgentOverridesSchema.optional(), claude_code: ClaudeCodeConfigSchema.optional(), diff --git a/src/index.ts b/src/index.ts index 3e52980..e4ebc72 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Plugin } from "@opencode-ai/plugin"; -import { createBuiltinAgents } from "./agents"; +import { createBuiltinAgents, BUILD_AGENT_PROMPT_EXTENSION } from "./agents"; import { createTodoContinuationEnforcer, createContextWindowMonitorHook, @@ -258,6 +258,16 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { ...projectAgents, ...config.agent, }; + + if (config.agent.build) { + const existingPrompt = config.agent.build.prompt || ""; + const userOverride = pluginConfig.agents?.build?.prompt || ""; + config.agent.build = { + ...config.agent.build, + prompt: existingPrompt + BUILD_AGENT_PROMPT_EXTENSION + userOverride, + }; + } + config.tools = { ...config.tools, };