diff --git a/packages/opencode/src/command/index.ts b/packages/opencode/src/command/index.ts index dce7ac8bbc3..521cb806873 100644 --- a/packages/opencode/src/command/index.ts +++ b/packages/opencode/src/command/index.ts @@ -31,7 +31,15 @@ export namespace Command { // workaround for zod not supporting async functions natively so we use getters // https://zod.dev/v4/changelog?id=zfunction template: z.promise(z.string()).or(z.string()), + // AGENTS: The `ignored` property marks commands whose output should not be processed by the model. + // When merging this branch, ensure `ignored` is included in ALL places where commands are loaded: + // 1. The Info schema (here) + // 2. The Config.Command schema in config/config.ts + // 3. Any command loading loops (e.g., state(), loadFreshCommands(), etc.) + // 4. The prompt.ts code that marks text parts as ignored + // DO NOT clobber or omit this property during merges! subtask: z.boolean().optional(), + ignored: z.boolean().optional(), hints: z.array(z.string()), }) .meta({ @@ -81,6 +89,7 @@ export namespace Command { }, } + // AGENTS: When merging, ensure ALL command loading loops include `ignored: command.ignored` for (const [name, command] of Object.entries(cfg.command ?? {})) { result[name] = { name, @@ -92,6 +101,8 @@ export namespace Command { return command.template }, subtask: command.subtask, + // AGENTS: DO NOT omit this line when merging! See comment above on Info schema. + ignored: command.ignored, hints: hints(command.template), } } diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 28aea4d6777..a9eb4521cdf 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -649,7 +649,11 @@ export namespace Config { description: z.string().optional(), agent: z.string().optional(), model: ModelId.optional(), + // AGENTS: The `ignored` property marks commands whose output should not be processed by the model. + // When merging this branch, ensure `ignored` is included here AND in Command.Info schema. + // DO NOT clobber or omit this property during merges! subtask: z.boolean().optional(), + ignored: z.boolean().optional(), }) export type Command = z.infer diff --git a/packages/opencode/src/session/message-v2.ts b/packages/opencode/src/session/message-v2.ts index 178751a2227..6506a59b3d0 100644 --- a/packages/opencode/src/session/message-v2.ts +++ b/packages/opencode/src/session/message-v2.ts @@ -556,11 +556,13 @@ export namespace MessageV2 { } result.push(userMessage) for (const part of msg.parts) { - if (part.type === "text" && !part.ignored) - userMessage.parts.push({ - type: "text", - text: part.text, - }) + if (part.type === "text") { + if (!part.ignored) + userMessage.parts.push({ + type: "text", + text: part.text, + }) + } // text/plain and directory files are converted into text parts, ignore them if (part.type === "file" && part.mime !== "text/plain" && part.mime !== "application/x-directory") userMessage.parts.push({ diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index 75bd3c9dfac..9835dee470b 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -1831,6 +1831,13 @@ NOTE: At any point in time through this workflow you should feel free to ask the } const templateParts = await resolvePromptParts(template) + if (command.ignored) { + for (const part of templateParts) { + if (part.type === "text") { + part.ignored = true + } + } + } const isSubtask = (agent.mode === "subagent" && command.subtask !== false) || command.subtask === true const parts = isSubtask ? [ @@ -1873,6 +1880,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the agent: userAgent, parts, variant: input.variant, + noReply: command.ignored, })) as MessageV2.WithParts Bus.publish(Command.Event.Executed, { diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index be6c00cf445..b3b30f48dfd 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -1302,6 +1302,7 @@ export type Config = { agent?: string model?: string subtask?: boolean + ignored?: boolean } } /** @@ -1836,6 +1837,7 @@ export type Command = { source?: "command" | "mcp" | "skill" template: string subtask?: boolean + ignored?: boolean hints: Array }