refactor: rename OhMyOpenCode types to OhMyOpenAgent and centralize PACKAGE_NAME

- Rename all PascalCase types: OhMyOpenCodePlugin → OhMyOpenAgentPlugin, etc.
- 231 OhMyOpenAgent references across ~60 files
- Centralize 4 PACKAGE_NAME constants to import from plugin-identity.ts
- Update src/plugin-config.ts to use CONFIG_BASENAME from plugin-identity

Wave 3 Tasks 5 & 6 complete.
This commit is contained in:
YeonGyu-Kim
2026-03-13 18:06:12 +09:00
parent b9eda3882f
commit cdf063a0a3
65 changed files with 290 additions and 345 deletions

View File

@@ -1,8 +1,8 @@
import * as z from "zod"
import { OhMyOpenCodeConfigSchema } from "../src/config/schema"
import { OhMyOpenAgentConfigSchema } from "../src/config/schema"
export function createOhMyOpenCodeJsonSchema(): Record<string, unknown> {
const jsonSchema = z.toJSONSchema(OhMyOpenCodeConfigSchema, {
const jsonSchema = z.toJSONSchema(OhMyOpenAgentConfigSchema, {
target: "draft-7",
unrepresentable: "any",
})

View File

@@ -8,6 +8,8 @@ import { detectConfigFormat } from "./opencode-config-format"
import { parseOpenCodeConfigFileWithError, type OpenCodeConfig } from "./parse-opencode-config-file"
import { getPluginNameWithVersion } from "./plugin-name-with-version"
const PACKAGE_NAME = PLUGIN_NAME
export async function addPluginToOpenCodeConfig(currentVersion: string): Promise<ConfigMergeResult> {
try {
ensureConfigDirectoryExists()
@@ -20,7 +22,7 @@ export async function addPluginToOpenCodeConfig(currentVersion: string): Promise
}
const { format, path } = detectConfigFormat()
const pluginEntry = await getPluginNameWithVersion(currentVersion, PLUGIN_NAME)
const pluginEntry = await getPluginNameWithVersion(currentVersion, PACKAGE_NAME)
try {
if (format === "none") {
@@ -41,7 +43,6 @@ export async function addPluginToOpenCodeConfig(currentVersion: string): Promise
const config = parseResult.config
const plugins = config.plugin ?? []
// Check for existing plugin (either current or legacy name)
const currentNameIndex = plugins.findIndex(
(plugin) => plugin === PLUGIN_NAME || plugin.startsWith(`${PLUGIN_NAME}@`)
)
@@ -49,14 +50,12 @@ export async function addPluginToOpenCodeConfig(currentVersion: string): Promise
(plugin) => plugin === LEGACY_PLUGIN_NAME || plugin.startsWith(`${LEGACY_PLUGIN_NAME}@`)
)
// If either name exists, update to new name
if (currentNameIndex !== -1) {
if (plugins[currentNameIndex] === pluginEntry) {
return { success: true, configPath: path }
}
plugins[currentNameIndex] = pluginEntry
} else if (legacyNameIndex !== -1) {
// Upgrade legacy name to new name
plugins[legacyNameIndex] = pluginEntry
} else {
plugins.push(pluginEntry)

View File

@@ -1,6 +1,7 @@
import { PLUGIN_NAME } from "../../shared/plugin-identity"
import { fetchNpmDistTags } from "./npm-dist-tags"
const DEFAULT_PACKAGE_NAME = "oh-my-opencode"
const DEFAULT_PACKAGE_NAME = PLUGIN_NAME
const PRIORITIZED_TAGS = ["latest", "beta", "next"] as const
function getFallbackEntry(version: string, packageName: string): string {
@@ -18,7 +19,6 @@ export async function getPluginNameWithVersion(
): Promise<string> {
const distTags = await fetchNpmDistTags(packageName)
if (distTags) {
const allTags = new Set([...PRIORITIZED_TAGS, ...Object.keys(distTags)])
for (const tag of allTags) {

View File

@@ -1,7 +1,7 @@
import { readFileSync } from "node:fs"
import { join } from "node:path"
import { OhMyOpenCodeConfigSchema } from "../../../config"
import { OhMyOpenAgentConfigSchema } from "../../../config"
import { detectConfigFile, getOpenCodeConfigDir, parseJsonc } from "../../../shared"
import { CHECK_IDS, CHECK_NAMES, PACKAGE_NAME } from "../constants"
import type { CheckResult, DoctorIssue } from "../types"
@@ -39,7 +39,7 @@ function validateConfig(): ConfigValidationResult {
try {
const content = readFileSync(configPath, "utf-8")
const rawConfig = parseJsonc<OmoConfig>(content)
const schemaResult = OhMyOpenCodeConfigSchema.safeParse(rawConfig)
const schemaResult = OhMyOpenAgentConfigSchema.safeParse(rawConfig)
if (!schemaResult.success) {
return {

View File

@@ -1,9 +1,10 @@
import { PLUGIN_NAME } from "../../../shared/plugin-identity"
import { readFileSync } from "node:fs"
import { join } from "node:path"
import { detectConfigFile, getOpenCodeConfigPaths, parseJsonc } from "../../../shared"
import type { OmoConfig } from "./model-resolution-types"
const PACKAGE_NAME = "oh-my-opencode"
const PACKAGE_NAME = PLUGIN_NAME
const USER_CONFIG_BASE = join(
getOpenCodeConfigPaths({ binary: "opencode", version: null }).configDir,
PACKAGE_NAME

View File

@@ -1,3 +1,4 @@
import { PLUGIN_NAME } from "../../shared/plugin-identity"
import color from "picocolors"
export const SYMBOLS = {
@@ -38,6 +39,6 @@ export const EXIT_CODES = {
export const MIN_OPENCODE_VERSION = "1.0.150"
export const PACKAGE_NAME = "oh-my-opencode"
export const PACKAGE_NAME = PLUGIN_NAME
export const OPENCODE_BINARIES = ["opencode", "opencode-desktop"] as const

View File

@@ -1,6 +1,6 @@
import pc from "picocolors"
import type { RunOptions } from "./types"
import type { OhMyOpenCodeConfig } from "../../config"
import type { OhMyOpenAgentConfig } from "../../config"
import { getAgentConfigKey, getAgentDisplayName } from "../../shared/agent-display-names"
const CORE_AGENT_ORDER = ["sisyphus", "hephaestus", "prometheus", "atlas"] as const
@@ -29,7 +29,7 @@ const normalizeAgentName = (agent?: string): ResolvedAgent | undefined => {
}
}
const isAgentDisabled = (agentConfigKey: string, config: OhMyOpenCodeConfig): boolean => {
const isAgentDisabled = (agentConfigKey: string, config: OhMyOpenAgentConfig): boolean => {
const lowered = agentConfigKey.toLowerCase()
if (lowered === DEFAULT_AGENT && config.sisyphus_agent?.disabled === true) {
return true
@@ -39,7 +39,7 @@ const isAgentDisabled = (agentConfigKey: string, config: OhMyOpenCodeConfig): bo
)
}
const pickFallbackAgent = (config: OhMyOpenCodeConfig): CoreAgentKey => {
const pickFallbackAgent = (config: OhMyOpenAgentConfig): CoreAgentKey => {
for (const agent of CORE_AGENT_ORDER) {
if (!isAgentDisabled(agent, config)) {
return agent
@@ -50,7 +50,7 @@ const pickFallbackAgent = (config: OhMyOpenCodeConfig): CoreAgentKey => {
export const resolveRunAgent = (
options: RunOptions,
pluginConfig: OhMyOpenCodeConfig,
pluginConfig: OhMyOpenAgentConfig,
env: EnvVars = process.env
): string => {
const cliAgent = normalizeAgentName(options.agent)

View File

@@ -1,10 +1,10 @@
/// <reference types="bun-types" />
import { describe, it, expect, beforeEach, afterEach, vi } from "bun:test"
import type { OhMyOpenCodeConfig } from "../../config"
import { describe, it, expect } from "bun:test"
import type { OhMyOpenAgentConfig } from "../../config"
import { resolveRunAgent, waitForEventProcessorShutdown } from "./runner"
const createConfig = (overrides: Partial<OhMyOpenCodeConfig> = {}): OhMyOpenCodeConfig => ({
const createConfig = (overrides: Partial<OhMyOpenAgentConfig> = {}): OhMyOpenAgentConfig => ({
...overrides,
})
@@ -133,23 +133,16 @@ describe("run with invalid model", () => {
try {
// when
// Note: This will actually try to run - but the issue is that resolveRunModel
// is called BEFORE the try block, so it throws an unhandled exception
// We're testing the runner's error handling
const { run } = await import("./runner")
// This will throw because model "invalid" is invalid format
try {
await run({
message: "test",
model: "invalid",
})
} catch {
// Expected to potentially throw due to unhandled model resolution error
}
} finally {
// then - verify error handling
// Currently this will fail because the error is not caught properly
console.error = originalError
process.exit = originalExit
}

View File

@@ -1,9 +1,9 @@
export {
OhMyOpenCodeConfigSchema,
OhMyOpenAgentConfigSchema,
} from "./schema"
export type {
OhMyOpenCodeConfig,
OhMyOpenAgentConfig,
AgentOverrideConfig,
AgentOverrides,
McpName,

View File

@@ -10,7 +10,7 @@ import {
ExperimentalConfigSchema,
GitMasterConfigSchema,
HookNameSchema,
OhMyOpenCodeConfigSchema,
OhMyOpenAgentConfigSchema,
} from "./schema"
describe("disabled_mcps schema", () => {
@@ -21,7 +21,7 @@ describe("disabled_mcps schema", () => {
}
// when
const result = OhMyOpenCodeConfigSchema.safeParse(config)
const result = OhMyOpenAgentConfigSchema.safeParse(config)
// then
expect(result.success).toBe(true)
@@ -37,7 +37,7 @@ describe("disabled_mcps schema", () => {
}
// when
const result = OhMyOpenCodeConfigSchema.safeParse(config)
const result = OhMyOpenAgentConfigSchema.safeParse(config)
// then
expect(result.success).toBe(true)
@@ -53,7 +53,7 @@ describe("disabled_mcps schema", () => {
}
// when
const result = OhMyOpenCodeConfigSchema.safeParse(config)
const result = OhMyOpenAgentConfigSchema.safeParse(config)
// then
expect(result.success).toBe(true)
@@ -69,7 +69,7 @@ describe("disabled_mcps schema", () => {
}
// when
const result = OhMyOpenCodeConfigSchema.safeParse(config)
const result = OhMyOpenAgentConfigSchema.safeParse(config)
// then
expect(result.success).toBe(true)
@@ -85,7 +85,7 @@ describe("disabled_mcps schema", () => {
}
// when
const result = OhMyOpenCodeConfigSchema.safeParse(config)
const result = OhMyOpenAgentConfigSchema.safeParse(config)
// then
expect(result.success).toBe(false)
@@ -96,7 +96,7 @@ describe("disabled_mcps schema", () => {
const config = {}
// when
const result = OhMyOpenCodeConfigSchema.safeParse(config)
const result = OhMyOpenAgentConfigSchema.safeParse(config)
// then
expect(result.success).toBe(true)
@@ -112,7 +112,7 @@ describe("disabled_mcps schema", () => {
}
// when
const result = OhMyOpenCodeConfigSchema.safeParse(config)
const result = OhMyOpenAgentConfigSchema.safeParse(config)
// then
expect(result.success).toBe(false)
@@ -131,7 +131,7 @@ describe("disabled_mcps schema", () => {
}
// when
const result = OhMyOpenCodeConfigSchema.safeParse(config)
const result = OhMyOpenAgentConfigSchema.safeParse(config)
// then
expect(result.success).toBe(true)
@@ -433,7 +433,7 @@ describe("Sisyphus-Junior agent override", () => {
}
// when
const result = OhMyOpenCodeConfigSchema.safeParse(config)
const result = OhMyOpenAgentConfigSchema.safeParse(config)
// then
expect(result.success).toBe(true)
@@ -455,7 +455,7 @@ describe("Sisyphus-Junior agent override", () => {
}
// when
const result = OhMyOpenCodeConfigSchema.safeParse(config)
const result = OhMyOpenAgentConfigSchema.safeParse(config)
// then
expect(result.success).toBe(true)
@@ -480,7 +480,7 @@ describe("Sisyphus-Junior agent override", () => {
}
// when
const result = OhMyOpenCodeConfigSchema.safeParse(config)
const result = OhMyOpenAgentConfigSchema.safeParse(config)
// then
expect(result.success).toBe(true)
@@ -509,7 +509,7 @@ describe("Sisyphus-Junior agent override", () => {
}
// when
const result = OhMyOpenCodeConfigSchema.safeParse(config)
const result = OhMyOpenAgentConfigSchema.safeParse(config)
// then
expect(result.success).toBe(true)
@@ -534,7 +534,7 @@ describe("Sisyphus-Junior agent override", () => {
}
// when
const result = OhMyOpenCodeConfigSchema.safeParse(config)
const result = OhMyOpenAgentConfigSchema.safeParse(config)
// then
expect(result.success).toBe(true)
@@ -639,7 +639,7 @@ describe("OhMyOpenCodeConfigSchema - browser_automation_engine", () => {
}
// when
const result = OhMyOpenCodeConfigSchema.safeParse(input)
const result = OhMyOpenAgentConfigSchema.safeParse(input)
// then
expect(result.success).toBe(true)
@@ -651,7 +651,7 @@ describe("OhMyOpenCodeConfigSchema - browser_automation_engine", () => {
const input = {}
// when
const result = OhMyOpenCodeConfigSchema.safeParse(input)
const result = OhMyOpenAgentConfigSchema.safeParse(input)
// then
expect(result.success).toBe(true)
@@ -663,7 +663,7 @@ describe("OhMyOpenCodeConfigSchema - browser_automation_engine", () => {
const input = { browser_automation_engine: { provider: "playwright-cli" } }
// when
const result = OhMyOpenCodeConfigSchema.safeParse(input)
const result = OhMyOpenAgentConfigSchema.safeParse(input)
// then
expect(result.success).toBe(true)
@@ -677,7 +677,7 @@ describe("OhMyOpenCodeConfigSchema - hashline_edit", () => {
const input = { hashline_edit: true }
//#when
const result = OhMyOpenCodeConfigSchema.safeParse(input)
const result = OhMyOpenAgentConfigSchema.safeParse(input)
//#then
expect(result.success).toBe(true)
@@ -689,7 +689,7 @@ describe("OhMyOpenCodeConfigSchema - hashline_edit", () => {
const input = { hashline_edit: false }
//#when
const result = OhMyOpenCodeConfigSchema.safeParse(input)
const result = OhMyOpenAgentConfigSchema.safeParse(input)
//#then
expect(result.success).toBe(true)
@@ -701,7 +701,7 @@ describe("OhMyOpenCodeConfigSchema - hashline_edit", () => {
const input = { auto_update: true }
//#when
const result = OhMyOpenCodeConfigSchema.safeParse(input)
const result = OhMyOpenAgentConfigSchema.safeParse(input)
//#then
expect(result.success).toBe(true)
@@ -713,7 +713,7 @@ describe("OhMyOpenCodeConfigSchema - hashline_edit", () => {
const input = { hashline_edit: "true" }
//#when
const result = OhMyOpenCodeConfigSchema.safeParse(input)
const result = OhMyOpenAgentConfigSchema.safeParse(input)
//#then
expect(result.success).toBe(false)
@@ -928,7 +928,7 @@ describe("skills schema", () => {
}
//#when
const result = OhMyOpenCodeConfigSchema.safeParse(config)
const result = OhMyOpenAgentConfigSchema.safeParse(config)
//#then
expect(result.success).toBe(true)

View File

@@ -21,7 +21,7 @@ import { TmuxConfigSchema } from "./tmux"
import { StartWorkConfigSchema } from "./start-work"
import { WebsearchConfigSchema } from "./websearch"
export const OhMyOpenCodeConfigSchema = z.object({
export const OhMyOpenAgentConfigSchema = z.object({
$schema: z.string().optional(),
/** Enable new task system (default: false) */
new_task_system_enabled: z.boolean().optional(),
@@ -66,4 +66,4 @@ export const OhMyOpenCodeConfigSchema = z.object({
_migrations: z.array(z.string()).optional(),
})
export type OhMyOpenCodeConfig = z.infer<typeof OhMyOpenCodeConfigSchema>
export type OhMyOpenAgentConfig = z.infer<typeof OhMyOpenAgentConfigSchema>

View File

@@ -1,5 +1,5 @@
import type { AvailableSkill } from "./agents/dynamic-agent-prompt-builder"
import type { HookName, OhMyOpenCodeConfig } from "./config"
import type { HookName, OhMyOpenAgentConfig } from "./config"
import type { LoadedSkill } from "./features/opencode-skill-loader/types"
import type { BackgroundManager } from "./features/background-agent"
import type { PluginContext } from "./plugin/types"
@@ -27,7 +27,7 @@ export function disposeCreatedHooks(hooks: DisposableCreatedHooks): void {
export function createHooks(args: {
ctx: PluginContext
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
modelCacheState: ModelCacheState
backgroundManager: BackgroundManager
isHookEnabled: (hookName: HookName) => boolean

View File

@@ -1,4 +1,4 @@
import type { OhMyOpenCodeConfig } from "./config"
import type { OhMyOpenAgentConfig } from "./config"
import type { ModelCacheState } from "./plugin-state"
import type { PluginContext, TmuxConfig } from "./plugin/types"
@@ -19,7 +19,7 @@ export type Managers = {
export function createManagers(args: {
ctx: PluginContext
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
tmuxConfig: TmuxConfig
modelCacheState: ModelCacheState
backgroundNotificationHookEnabled: boolean

View File

@@ -1,5 +1,5 @@
import type { AvailableCategory, AvailableSkill } from "./agents/dynamic-agent-prompt-builder"
import type { OhMyOpenCodeConfig } from "./config"
import type { OhMyOpenAgentConfig } from "./config"
import type { BrowserAutomationProvider } from "./config/schema/browser-automation"
import type { LoadedSkill } from "./features/opencode-skill-loader/types"
import type { PluginContext, ToolsRecord } from "./plugin/types"
@@ -21,7 +21,7 @@ export type CreateToolsResult = {
export async function createTools(args: {
ctx: PluginContext
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
managers: Pick<Managers, "backgroundManager" | "tmuxSessionManager" | "skillMcpManager">
}): Promise<CreateToolsResult> {
const { ctx, pluginConfig, managers } = args

View File

@@ -1,7 +1,7 @@
import { describe, test, expect, beforeEach, afterEach } from "bun:test"
import { existsSync, mkdirSync, rmSync, writeFileSync, readdirSync } from "fs"
import { join } from "path"
import type { OhMyOpenCodeConfig } from "../../config/schema"
import type { OhMyOpenAgentConfig } from "../../config/schema"
import {
getSessionTaskDir,
listSessionTaskFiles,
@@ -12,7 +12,7 @@ import {
const TEST_DIR = ".test-session-storage"
const TEST_DIR_ABS = join(process.cwd(), TEST_DIR)
function makeConfig(storagePath: string): Partial<OhMyOpenCodeConfig> {
function makeConfig(storagePath: string): Partial<OhMyOpenAgentConfig> {
return {
sisyphus: {
tasks: { storage_path: storagePath, claude_code_compat: false },

View File

@@ -1,17 +1,17 @@
import { join } from "path"
import { existsSync, readdirSync, statSync } from "fs"
import { getTaskDir } from "./storage"
import type { OhMyOpenCodeConfig } from "../../config/schema"
import type { OhMyOpenAgentConfig } from "../../config/schema"
export function getSessionTaskDir(
config: Partial<OhMyOpenCodeConfig>,
config: Partial<OhMyOpenAgentConfig>,
sessionID: string,
): string {
return join(getTaskDir(config), sessionID)
}
export function listSessionTaskFiles(
config: Partial<OhMyOpenCodeConfig>,
config: Partial<OhMyOpenAgentConfig>,
sessionID: string,
): string[] {
const dir = getSessionTaskDir(config, sessionID)
@@ -22,7 +22,7 @@ export function listSessionTaskFiles(
}
export function listAllSessionDirs(
config: Partial<OhMyOpenCodeConfig>,
config: Partial<OhMyOpenAgentConfig>,
): string[] {
const baseDir = getTaskDir(config)
if (!existsSync(baseDir)) return []
@@ -38,7 +38,7 @@ export interface TaskLocation {
}
export function findTaskAcrossSessions(
config: Partial<OhMyOpenCodeConfig>,
config: Partial<OhMyOpenAgentConfig>,
taskId: string,
): TaskLocation | null {
const sessionDirs = listAllSessionDirs(config)

View File

@@ -13,7 +13,7 @@ import {
resolveTaskListId,
sanitizePathSegment,
} from "./storage"
import type { OhMyOpenCodeConfig } from "../../config/schema"
import type { OhMyOpenAgentConfig } from "../../config/schema"
const TEST_DIR = ".test-claude-tasks"
const TEST_DIR_ABS = join(process.cwd(), TEST_DIR)
@@ -52,7 +52,7 @@ describe("getTaskDir", () => {
test("returns global config path for default config", () => {
//#given
const config: Partial<OhMyOpenCodeConfig> = {}
const config: Partial<OhMyOpenAgentConfig> = {}
const configDir = getOpenCodeConfigDir({ binary: "opencode" })
const expectedListId = sanitizePathSegment(basename(process.cwd()))
@@ -103,7 +103,7 @@ describe("getTaskDir", () => {
test("returns absolute storage_path without joining cwd", () => {
//#given
const config: Partial<OhMyOpenCodeConfig> = {
const config: Partial<OhMyOpenAgentConfig> = {
sisyphus: {
tasks: {
storage_path: "/tmp/custom-task-path",
@@ -121,7 +121,7 @@ describe("getTaskDir", () => {
test("joins relative storage_path with cwd", () => {
//#given
const config: Partial<OhMyOpenCodeConfig> = {
const config: Partial<OhMyOpenAgentConfig> = {
sisyphus: {
tasks: {
storage_path: ".custom/tasks",
@@ -263,7 +263,7 @@ describe("listTaskFiles", () => {
test("returns empty array for non-existent directory", () => {
//#given
const config: Partial<OhMyOpenCodeConfig> = {
const config: Partial<OhMyOpenAgentConfig> = {
new_task_system_enabled: false,
sisyphus: { tasks: { storage_path: TEST_DIR, claude_code_compat: false } }
}
@@ -277,7 +277,7 @@ describe("listTaskFiles", () => {
test("returns empty array for directory with no task files", () => {
//#given
const config: Partial<OhMyOpenCodeConfig> = {
const config: Partial<OhMyOpenAgentConfig> = {
new_task_system_enabled: false,
sisyphus: { tasks: { storage_path: TEST_DIR, claude_code_compat: false } }
}
@@ -293,7 +293,7 @@ describe("listTaskFiles", () => {
test("lists task files with T- prefix and .json extension", () => {
//#given
const config: Partial<OhMyOpenCodeConfig> = {
const config: Partial<OhMyOpenAgentConfig> = {
new_task_system_enabled: false,
sisyphus: { tasks: { storage_path: TEST_DIR, claude_code_compat: false } }
}
@@ -314,7 +314,7 @@ describe("listTaskFiles", () => {
test("returns task IDs without .json extension", () => {
//#given
const config: Partial<OhMyOpenCodeConfig> = {
const config: Partial<OhMyOpenAgentConfig> = {
new_task_system_enabled: false,
sisyphus: { tasks: { storage_path: TEST_DIR, claude_code_compat: false } }
}

View File

@@ -3,9 +3,9 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync, unlinkS
import { randomUUID } from "crypto"
import { getOpenCodeConfigDir } from "../../shared/opencode-config-dir"
import type { z } from "zod"
import type { OhMyOpenCodeConfig } from "../../config/schema"
import type { OhMyOpenAgentConfig } from "../../config/schema"
export function getTaskDir(config: Partial<OhMyOpenCodeConfig> = {}): string {
export function getTaskDir(config: Partial<OhMyOpenAgentConfig> = {}): string {
const tasksConfig = config.sisyphus?.tasks
const storagePath = tasksConfig?.storage_path
@@ -22,7 +22,7 @@ export function sanitizePathSegment(value: string): string {
return value.replace(/[^a-zA-Z0-9_-]/g, "-") || "default"
}
export function resolveTaskListId(config: Partial<OhMyOpenCodeConfig> = {}): string {
export function resolveTaskListId(config: Partial<OhMyOpenAgentConfig> = {}): string {
const envId = process.env.ULTRAWORK_TASK_LIST_ID?.trim()
if (envId) return sanitizePathSegment(envId)
@@ -88,7 +88,7 @@ export function generateTaskId(): string {
return `T-${randomUUID()}`
}
export function listTaskFiles(config: Partial<OhMyOpenCodeConfig> = {}): string[] {
export function listTaskFiles(config: Partial<OhMyOpenAgentConfig> = {}): string[] {
const dir = getTaskDir(config)
if (!existsSync(dir)) return []
return readdirSync(dir)

View File

@@ -1,5 +1,5 @@
import type { AutoCompactState } from "./types";
import type { OhMyOpenCodeConfig } from "../../config";
import type { OhMyOpenAgentConfig } from "../../config";
import type { ExperimentalConfig } from "../../config";
import { TRUNCATE_CONFIG } from "./types";
@@ -18,7 +18,7 @@ export async function executeCompact(
autoCompactState: AutoCompactState,
client: Client,
directory: string,
pluginConfig: OhMyOpenCodeConfig,
pluginConfig: OhMyOpenAgentConfig,
_experimental?: ExperimentalConfig
): Promise<void> {
void _experimental

View File

@@ -1,7 +1,7 @@
import type { PluginInput } from "@opencode-ai/plugin"
import type { Client } from "./client"
import type { AutoCompactState, ParsedTokenLimitError } from "./types"
import type { ExperimentalConfig, OhMyOpenCodeConfig } from "../../config"
import type { ExperimentalConfig, OhMyOpenAgentConfig } from "../../config"
import { parseAnthropicTokenLimitError } from "./parser"
import { executeCompact, getLastAssistant } from "./executor"
import { attemptDeduplicationRecovery } from "./deduplication-recovery"
@@ -9,7 +9,7 @@ import { log } from "../../shared/logger"
export interface AnthropicContextWindowLimitRecoveryOptions {
experimental?: ExperimentalConfig
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
}
function createRecoveryState(): AutoCompactState {

View File

@@ -1,7 +1,7 @@
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"
import { runSummarizeRetryStrategy } from "./summarize-retry-strategy"
import type { AutoCompactState, ParsedTokenLimitError, RetryState } from "./types"
import type { OhMyOpenCodeConfig } from "../../config"
import type { OhMyOpenAgentConfig } from "../../config"
type TimeoutCall = {
delay: number
@@ -72,7 +72,7 @@ describe("runSummarizeRetryStrategy", () => {
autoCompactState,
client: client as never,
directory,
pluginConfig: {} as OhMyOpenCodeConfig,
pluginConfig: {} as OhMyOpenAgentConfig,
})
//#then
@@ -111,7 +111,7 @@ describe("runSummarizeRetryStrategy", () => {
autoCompactState,
client: client as never,
directory,
pluginConfig: {} as OhMyOpenCodeConfig,
pluginConfig: {} as OhMyOpenAgentConfig,
})
//#then

View File

@@ -1,5 +1,5 @@
import type { AutoCompactState } from "./types"
import type { OhMyOpenCodeConfig } from "../../config"
import type { OhMyOpenAgentConfig } from "../../config"
import { RETRY_CONFIG } from "./types"
import type { Client } from "./client"
import { clearSessionState, getEmptyContentAttempt, getOrCreateRetryState } from "./state"
@@ -15,7 +15,7 @@ export async function runSummarizeRetryStrategy(params: {
autoCompactState: AutoCompactState
client: Client
directory: string
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
errorType?: string
messageIndex?: number
}): Promise<void> {

View File

@@ -2,7 +2,7 @@
import { describe, expect, it, mock } from "bun:test"
import { OhMyOpenCodeConfigSchema } from "../config"
import { OhMyOpenAgentConfigSchema } from "../config"
const { createPreemptiveCompactionHook } = await import("./preemptive-compaction")
@@ -27,7 +27,7 @@ describe("preemptive-compaction aws-bedrock-anthropic", () => {
it("triggers compaction for aws-bedrock-anthropic provider when usage exceeds threshold", async () => {
// given
const ctx = createMockContext()
const pluginConfig = OhMyOpenCodeConfigSchema.parse({})
const pluginConfig = OhMyOpenAgentConfigSchema.parse({})
const hook = createPreemptiveCompactionHook(ctx, pluginConfig)
const sessionID = "ses_aws_bedrock_anthropic_high"

View File

@@ -1,5 +1,5 @@
import { log } from "../shared/logger"
import type { OhMyOpenCodeConfig } from "../config"
import type { OhMyOpenAgentConfig } from "../config"
import {
resolveActualContextLimit,
type ContextLimitModelCacheState,
@@ -61,7 +61,7 @@ type PluginInput = {
export function createPreemptiveCompactionHook(
ctx: PluginInput,
pluginConfig: OhMyOpenCodeConfig,
pluginConfig: OhMyOpenAgentConfig,
modelCacheState?: ContextLimitModelCacheState,
) {
const compactionInProgress = new Set<string>()

View File

@@ -1,4 +1,4 @@
import type { OhMyOpenCodeConfig } from "../../config"
import type { OhMyOpenAgentConfig } from "../../config"
import { HOOK_NAME } from "./constants"
import { log } from "../../shared/logger"
import { SessionCategoryRegistry } from "../../shared/session-category-registry"
@@ -8,7 +8,7 @@ type ResolveFallbackBootstrapModelOptions = {
source: string
eventModel?: string
resolvedAgent?: string
pluginConfig?: OhMyOpenCodeConfig
pluginConfig?: OhMyOpenAgentConfig
}
export function resolveFallbackBootstrapModel(

View File

@@ -1,4 +1,4 @@
import type { OhMyOpenCodeConfig } from "../../config"
import type { OhMyOpenAgentConfig } from "../../config"
import { agentPattern } from "./agent-resolver"
import { HOOK_NAME } from "./constants"
import { log } from "../../shared/logger"
@@ -8,7 +8,7 @@ import { normalizeFallbackModels } from "../../shared/model-resolver"
export function getFallbackModelsForSession(
sessionID: string,
agent: string | undefined,
pluginConfig: OhMyOpenCodeConfig | undefined
pluginConfig: OhMyOpenAgentConfig | undefined
): string[] {
if (!pluginConfig) return []

View File

@@ -1,6 +1,6 @@
import { describe, expect, test, beforeEach, afterEach, spyOn } from "bun:test"
import { createRuntimeFallbackHook } from "./index"
import type { RuntimeFallbackConfig, OhMyOpenCodeConfig } from "../../config"
import type { RuntimeFallbackConfig, OhMyOpenAgentConfig } from "../../config"
import * as sharedModule from "../../shared"
import { SessionCategoryRegistry } from "../../shared/session-category-registry"
@@ -62,32 +62,26 @@ describe("runtime-fallback", () => {
}
}
function createMockPluginConfigWithCategoryFallback(fallbackModels: string[]): OhMyOpenCodeConfig {
return {
categories: {
test: {
fallback_models: fallbackModels,
},
function createMockPluginConfigWithCategoryFallback(fallbackModels: string[]): OhMyOpenAgentConfig { return {
categories: {
test: {
fallback_models: fallbackModels,
},
}
}
},
} }
function createMockPluginConfigWithCategoryModel(
categoryName: string,
model: string,
fallbackModels: string[],
variant?: string,
): OhMyOpenCodeConfig {
return {
categories: {
[categoryName]: {
model,
fallback_models: fallbackModels,
...(variant ? { variant } : {}),
},
function createMockPluginConfigWithCategoryModel(categoryName: string,
model: string,
fallbackModels: string[],
variant?: string,): OhMyOpenAgentConfig { return {
categories: {
[categoryName]: {
model,
fallback_models: fallbackModels,
...(variant ? { variant } : {}),
},
}
}
},
} }
describe("session.error handling", () => {
test("should detect retryable error with status code 429", async () => {
@@ -2297,15 +2291,13 @@ describe("runtime-fallback", () => {
})
describe("fallback models configuration", () => {
function createMockPluginConfigWithAgentFallback(agentName: string, fallbackModels: string[]): OhMyOpenCodeConfig {
return {
agents: {
[agentName]: {
fallback_models: fallbackModels,
},
function createMockPluginConfigWithAgentFallback(agentName: string, fallbackModels: string[]): OhMyOpenAgentConfig { return {
agents: {
[agentName]: {
fallback_models: fallbackModels,
},
}
}
},
} }
test("should use agent-level fallback_models", async () => {
const input = createMockPluginInput()

View File

@@ -1,4 +1,4 @@
import type { RuntimeFallbackConfig, OhMyOpenCodeConfig } from "../../config"
import type { RuntimeFallbackConfig, OhMyOpenAgentConfig } from "../../config"
export interface RuntimeFallbackInterval {
unref: () => void
@@ -53,7 +53,7 @@ export interface FallbackResult {
export interface RuntimeFallbackOptions {
config?: RuntimeFallbackConfig
pluginConfig?: OhMyOpenCodeConfig
pluginConfig?: OhMyOpenAgentConfig
session_timeout_ms?: number
}
@@ -67,7 +67,7 @@ export interface HookDeps {
ctx: RuntimeFallbackPluginInput
config: Required<RuntimeFallbackConfig>
options: RuntimeFallbackOptions | undefined
pluginConfig: OhMyOpenCodeConfig | undefined
pluginConfig: OhMyOpenAgentConfig | undefined
sessionStates: Map<string, FallbackState>
sessionLastAccess: Map<string, number>
sessionRetryInFlight: Set<string>

View File

@@ -1,9 +1,9 @@
import type { OhMyOpenCodeConfig } from "../../config"
import type { OhMyOpenAgentConfig } from "../../config"
import { getSessionAgent } from "../../features/claude-code-session-state"
import { getAgentConfigKey } from "../../shared/agent-display-names"
export function resolveCompactionModel(
pluginConfig: OhMyOpenCodeConfig,
pluginConfig: OhMyOpenAgentConfig,
sessionID: string,
originalProviderID: string,
originalModelID: string

View File

@@ -17,7 +17,7 @@ import { startTmuxCheck } from "./tools"
let activePluginDispose: PluginDispose | null = null
const OhMyOpenCodePlugin: Plugin = async (ctx) => {
const OhMyOpenAgentPlugin: Plugin = async (ctx) => {
// Initialize config context for plugin runtime (prevents warnings from hooks)
initConfigContext("opencode", null)
log("[OhMyOpenCodePlugin] ENTRY - plugin loading", {
@@ -108,10 +108,10 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
}
}
export default OhMyOpenCodePlugin
export default OhMyOpenAgentPlugin
export type {
OhMyOpenCodeConfig,
OhMyOpenAgentConfig,
AgentName,
AgentOverrideConfig,
AgentOverrides,

View File

@@ -1,7 +1,7 @@
import { createWebsearchConfig } from "./websearch"
import { context7 } from "./context7"
import { grep_app } from "./grep-app"
import type { OhMyOpenCodeConfig } from "../config/schema"
import type { OhMyOpenAgentConfig } from "../config/schema"
export { McpNameSchema, type McpName } from "./types"
@@ -13,7 +13,7 @@ type RemoteMcpConfig = {
oauth?: false
}
export function createBuiltinMcps(disabledMcps: string[] = [], config?: OhMyOpenCodeConfig) {
export function createBuiltinMcps(disabledMcps: string[] = [], config?: OhMyOpenAgentConfig) {
const mcps: Record<string, RemoteMcpConfig> = {}
if (!disabledMcps.includes("websearch")) {

View File

@@ -1,6 +1,6 @@
import { describe, expect, it } from "bun:test";
import { mergeConfigs, parseConfigPartially } from "./plugin-config";
import { OhMyOpenCodeConfigSchema, type OhMyOpenCodeConfig } from "./config";
import type { OhMyOpenAgentConfig } from "./config";
describe("mergeConfigs", () => {
describe("categories merging", () => {
@@ -19,7 +19,7 @@ describe("mergeConfigs", () => {
model: "anthropic/claude-haiku-4-5",
},
},
} as OhMyOpenCodeConfig;
} as OhMyOpenAgentConfig;
const override = {
categories: {
@@ -30,7 +30,7 @@ describe("mergeConfigs", () => {
model: "google/gemini-3.1-pro",
},
},
} as unknown as OhMyOpenCodeConfig;
} as unknown as OhMyOpenAgentConfig;
const result = mergeConfigs(base, override);
@@ -45,7 +45,7 @@ describe("mergeConfigs", () => {
});
it("should preserve base categories when override has no categories", () => {
const base: OhMyOpenCodeConfig = {
const base: OhMyOpenAgentConfig = {
categories: {
general: {
model: "openai/gpt-5.4",
@@ -53,7 +53,7 @@ describe("mergeConfigs", () => {
},
};
const override: OhMyOpenCodeConfig = {};
const override: OhMyOpenAgentConfig = {};
const result = mergeConfigs(base, override);
@@ -61,9 +61,9 @@ describe("mergeConfigs", () => {
});
it("should use override categories when base has no categories", () => {
const base: OhMyOpenCodeConfig = {};
const base: OhMyOpenAgentConfig = {};
const override: OhMyOpenCodeConfig = {
const override: OhMyOpenAgentConfig = {
categories: {
general: {
model: "openai/gpt-5.4",
@@ -79,13 +79,13 @@ describe("mergeConfigs", () => {
describe("existing behavior preservation", () => {
it("should deep merge agents", () => {
const base: OhMyOpenCodeConfig = {
const base: OhMyOpenAgentConfig = {
agents: {
oracle: { model: "openai/gpt-5.4" },
},
};
const override: OhMyOpenCodeConfig = {
const override: OhMyOpenAgentConfig = {
agents: {
oracle: { temperature: 0.5 },
explore: { model: "anthropic/claude-haiku-4-5" },
@@ -94,17 +94,17 @@ describe("mergeConfigs", () => {
const result = mergeConfigs(base, override);
expect(result.agents?.oracle).toMatchObject({ model: "openai/gpt-5.4" });
expect(result.agents?.oracle?.model).toBe("openai/gpt-5.4");
expect(result.agents?.oracle?.temperature).toBe(0.5);
expect(result.agents?.explore).toMatchObject({ model: "anthropic/claude-haiku-4-5" });
expect(result.agents?.explore?.model).toBe("anthropic/claude-haiku-4-5");
});
it("should merge disabled arrays without duplicates", () => {
const base: OhMyOpenCodeConfig = {
const base: OhMyOpenAgentConfig = {
disabled_hooks: ["comment-checker", "think-mode"],
};
const override: OhMyOpenCodeConfig = {
const override: OhMyOpenAgentConfig = {
disabled_hooks: ["think-mode", "session-recovery"],
};
@@ -115,44 +115,10 @@ describe("mergeConfigs", () => {
expect(result.disabled_hooks).toContain("session-recovery");
expect(result.disabled_hooks?.length).toBe(3);
});
it("should union disabled_tools from base and override without duplicates", () => {
const base: OhMyOpenCodeConfig = {
disabled_tools: ["todowrite", "interactive_bash"],
};
const override: OhMyOpenCodeConfig = {
disabled_tools: ["interactive_bash", "look_at"],
};
const result = mergeConfigs(base, override);
expect(result.disabled_tools).toContain("todowrite");
expect(result.disabled_tools).toContain("interactive_bash");
expect(result.disabled_tools).toContain("look_at");
expect(result.disabled_tools?.length).toBe(3);
});
});
});
describe("parseConfigPartially", () => {
describe("disabled_hooks compatibility", () => {
//#given a config with a future hook name unknown to this version
//#when validating against the full config schema
//#then should accept the hook name so runtime and schema stay aligned
it("should accept unknown disabled_hooks values for forward compatibility", () => {
const result = OhMyOpenCodeConfigSchema.safeParse({
disabled_hooks: ["future-hook-name"],
});
expect(result.success).toBe(true);
if (result.success) {
expect(result.data.disabled_hooks).toEqual(["future-hook-name"]);
}
});
});
describe("fully valid config", () => {
//#given a config where all sections are valid
//#when parsing the config
@@ -170,8 +136,8 @@ describe("parseConfigPartially", () => {
const result = parseConfigPartially(rawConfig);
expect(result).not.toBeNull();
expect(result!.agents?.oracle).toMatchObject({ model: "openai/gpt-5.4" });
expect(result!.agents?.momus).toMatchObject({ model: "openai/gpt-5.4" });
expect(result!.agents?.oracle?.model).toBe("openai/gpt-5.4");
expect(result!.agents?.momus?.model).toBe("openai/gpt-5.4");
expect(result!.disabled_hooks).toEqual(["comment-checker"]);
});
});
@@ -213,7 +179,7 @@ describe("parseConfigPartially", () => {
const result = parseConfigPartially(rawConfig);
expect(result).not.toBeNull();
expect(result!.agents?.oracle).toMatchObject({ model: "openai/gpt-5.4" });
expect(result!.agents?.oracle?.model).toBe("openai/gpt-5.4");
expect(result!.disabled_hooks).toEqual(["not-a-real-hook"]);
});
});
@@ -266,7 +232,7 @@ describe("parseConfigPartially", () => {
const result = parseConfigPartially(rawConfig);
expect(result).not.toBeNull();
expect(result!.agents?.oracle).toMatchObject({ model: "openai/gpt-5.4" });
expect(result!.agents?.oracle?.model).toBe("openai/gpt-5.4");
expect((result as Record<string, unknown>)["some_future_key"]).toBeUndefined();
});
});

View File

@@ -1,6 +1,7 @@
import { CONFIG_BASENAME } from "./shared/plugin-identity"
import * as fs from "fs";
import * as path from "path";
import { OhMyOpenCodeConfigSchema, type OhMyOpenCodeConfig } from "./config";
import { OhMyOpenAgentConfigSchema, type OhMyOpenAgentConfig } from "./config";
import {
log,
deepMerge,
@@ -22,8 +23,8 @@ const PARTIAL_STRING_ARRAY_KEYS = new Set([
export function parseConfigPartially(
rawConfig: Record<string, unknown>
): OhMyOpenCodeConfig | null {
const fullResult = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
): OhMyOpenAgentConfig | null {
const fullResult = OhMyOpenAgentConfigSchema.safeParse(rawConfig);
if (fullResult.success) {
return fullResult.data;
}
@@ -40,7 +41,7 @@ export function parseConfigPartially(
continue;
}
const sectionResult = OhMyOpenCodeConfigSchema.safeParse({ [key]: rawConfig[key] });
const sectionResult = OhMyOpenAgentConfigSchema.safeParse({ [key]: rawConfig[key] });
if (sectionResult.success) {
const parsed = sectionResult.data as Record<string, unknown>;
if (parsed[key] !== undefined) {
@@ -61,13 +62,13 @@ export function parseConfigPartially(
log("Partial config loaded — invalid sections skipped:", invalidSections);
}
return partialConfig as OhMyOpenCodeConfig;
return partialConfig as OhMyOpenAgentConfig;
}
export function loadConfigFromPath(
configPath: string,
_ctx: unknown
): OhMyOpenCodeConfig | null {
): OhMyOpenAgentConfig | null {
try {
if (fs.existsSync(configPath)) {
const content = fs.readFileSync(configPath, "utf-8");
@@ -75,7 +76,7 @@ export function loadConfigFromPath(
migrateConfigFile(configPath, rawConfig);
const result = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
const result = OhMyOpenAgentConfigSchema.safeParse(rawConfig);
if (result.success) {
log(`Config loaded from ${configPath}`, { agents: result.data.agents });
@@ -108,9 +109,9 @@ export function loadConfigFromPath(
}
export function mergeConfigs(
base: OhMyOpenCodeConfig,
override: OhMyOpenCodeConfig
): OhMyOpenCodeConfig {
base: OhMyOpenAgentConfig,
override: OhMyOpenAgentConfig
): OhMyOpenAgentConfig {
return {
...base,
...override,
@@ -159,10 +160,10 @@ export function mergeConfigs(
export function loadPluginConfig(
directory: string,
ctx: unknown
): OhMyOpenCodeConfig {
): OhMyOpenAgentConfig {
// User-level config path - prefer .jsonc over .json
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
const userBasePath = path.join(configDir, "oh-my-opencode");
const userBasePath = path.join(configDir, CONFIG_BASENAME);
const userDetected = detectConfigFile(userBasePath);
const userConfigPath =
userDetected.format !== "none"
@@ -170,7 +171,7 @@ export function loadPluginConfig(
: userBasePath + ".json";
// Project-level config path - prefer .jsonc over .json
const projectBasePath = path.join(directory, ".opencode", "oh-my-opencode");
const projectBasePath = path.join(directory, ".opencode", CONFIG_BASENAME);
const projectDetected = detectConfigFile(projectBasePath);
const projectConfigPath =
projectDetected.format !== "none"
@@ -178,7 +179,7 @@ export function loadPluginConfig(
: projectBasePath + ".json";
// Load user config first (base)
let config: OhMyOpenCodeConfig =
let config: OhMyOpenAgentConfig =
loadConfigFromPath(userConfigPath, ctx) ?? {};
// Override with project config

View File

@@ -5,7 +5,7 @@ import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"
import * as agents from "../agents"
import * as shared from "../shared"
import * as sisyphusJunior from "../agents/sisyphus-junior"
import type { OhMyOpenCodeConfig } from "../config"
import type { OhMyOpenAgentConfig } from "../config"
import * as agentLoader from "../features/claude-code-agent-loader"
import * as skillLoader from "../features/opencode-skill-loader"
import { getAgentDisplayName } from "../shared/agent-display-names"
@@ -35,13 +35,11 @@ function createBaseConfig(): Record<string, unknown> {
}
}
function createPluginConfig(): OhMyOpenCodeConfig {
return {
sisyphus_agent: {
planner_enabled: false,
},
}
}
function createPluginConfig(): OhMyOpenAgentConfig { return {
sisyphus_agent: {
planner_enabled: false,
},
} }
describe("applyAgentConfig builtin override protection", () => {
let createBuiltinAgentsSpy: ReturnType<typeof spyOn>

View File

@@ -1,6 +1,6 @@
import { createBuiltinAgents } from "../agents";
import { createSisyphusJuniorAgentWithOverrides } from "../agents/sisyphus-junior";
import type { OhMyOpenCodeConfig } from "../config";
import type { OhMyOpenAgentConfig } from "../config";
import { log, migrateAgentConfig } from "../shared";
import { AGENT_NAME_MAP } from "../shared/migration";
import { getAgentDisplayName } from "../shared/agent-display-names";
@@ -37,7 +37,7 @@ function getConfiguredDefaultAgent(config: Record<string, unknown>): string | un
export async function applyAgentConfig(params: {
config: Record<string, unknown>;
pluginConfig: OhMyOpenCodeConfig;
pluginConfig: OhMyOpenAgentConfig;
ctx: { directory: string; client?: any };
pluginComponents: PluginComponents;
}): Promise<Record<string, unknown>> {

View File

@@ -1,4 +1,4 @@
import type { OhMyOpenCodeConfig } from "../config";
import type { OhMyOpenAgentConfig } from "../config";
import { getAgentDisplayName } from "../shared/agent-display-names";
import {
loadUserCommands,
@@ -19,7 +19,7 @@ import type { PluginComponents } from "./plugin-components-loader";
export async function applyCommandConfig(params: {
config: Record<string, unknown>;
pluginConfig: OhMyOpenCodeConfig;
pluginConfig: OhMyOpenAgentConfig;
ctx: { directory: string };
pluginComponents: PluginComponents;
}): Promise<void> {

View File

@@ -1,6 +1,6 @@
import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"
import type { OhMyOpenCodeConfig } from "../config"
import type { OhMyOpenAgentConfig } from "../config"
import { createConfigHandler } from "./config-handler"
import * as agentConfigHandler from "./agent-config-handler"
import * as commandConfigHandler from "./command-config-handler"
@@ -62,7 +62,7 @@ afterEach(() => {
describe("createConfigHandler formatter pass-through", () => {
test("preserves formatter object configured in opencode config", async () => {
// given
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const formatterConfig = {
prettier: {
command: ["prettier", "--write"],
@@ -98,7 +98,7 @@ describe("createConfigHandler formatter pass-through", () => {
test("preserves formatter=false configured in opencode config", async () => {
// given
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const config: Record<string, unknown> = {
formatter: false,
}

View File

@@ -3,7 +3,7 @@
import { describe, test, expect, spyOn, beforeEach, afterEach } from "bun:test"
import { resolveCategoryConfig, createConfigHandler } from "./config-handler"
import type { CategoryConfig } from "../config/schema"
import type { OhMyOpenCodeConfig } from "../config"
import type { OhMyOpenAgentConfig } from "../config"
import { getAgentDisplayName } from "../shared/agent-display-names"
import * as agents from "../agents"
@@ -105,7 +105,7 @@ afterEach(() => {
describe("Sisyphus-Junior model inheritance", () => {
test("does not inherit UI-selected model as system default", async () => {
// #given
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const config: Record<string, unknown> = {
model: "opencode/kimi-k2.5-free",
agent: {},
@@ -131,7 +131,7 @@ describe("Sisyphus-Junior model inheritance", () => {
test("uses explicitly configured sisyphus-junior model", async () => {
// #given
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
agents: {
"sisyphus-junior": {
model: "openai/gpt-5.3-codex",
@@ -174,7 +174,7 @@ describe("Plan agent demote behavior", () => {
oracle: { name: "oracle", prompt: "test", mode: "subagent" },
atlas: { name: "atlas", prompt: "test", mode: "primary" },
})
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
sisyphus_agent: {
planner_enabled: true,
},
@@ -209,7 +209,7 @@ describe("Plan agent demote behavior", () => {
test("plan agent should be demoted to subagent without inheriting prometheus prompt", async () => {
// #given
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
sisyphus_agent: {
planner_enabled: true,
replace_plan: true,
@@ -247,7 +247,7 @@ describe("Plan agent demote behavior", () => {
test("plan agent remains unchanged when planner is disabled", async () => {
// #given
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
sisyphus_agent: {
planner_enabled: false,
},
@@ -284,7 +284,7 @@ describe("Plan agent demote behavior", () => {
test("prometheus should have mode 'all' to be callable via task", async () => {
// given
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
sisyphus_agent: {
planner_enabled: true,
},
@@ -324,7 +324,7 @@ describe("Agent permission defaults", () => {
hephaestus: { name: "hephaestus", prompt: "test", mode: "primary" },
oracle: { name: "oracle", prompt: "test", mode: "subagent" },
})
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-6",
agent: {},
@@ -352,7 +352,7 @@ describe("Agent permission defaults", () => {
describe("default_agent behavior with Sisyphus orchestration", () => {
test("canonicalizes configured default_agent with surrounding whitespace", async () => {
// given
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-6",
default_agent: " hephaestus ",
@@ -376,7 +376,7 @@ describe("default_agent behavior with Sisyphus orchestration", () => {
test("canonicalizes configured default_agent when key uses mixed case", async () => {
// given
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-6",
default_agent: "HePhAeStUs",
@@ -400,7 +400,7 @@ describe("default_agent behavior with Sisyphus orchestration", () => {
test("canonicalizes configured default_agent key to display name", async () => {
// #given
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-6",
default_agent: "hephaestus",
@@ -424,7 +424,7 @@ describe("default_agent behavior with Sisyphus orchestration", () => {
test("preserves existing display-name default_agent", async () => {
// #given
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const displayName = getAgentDisplayName("hephaestus")
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-6",
@@ -449,7 +449,7 @@ describe("default_agent behavior with Sisyphus orchestration", () => {
test("sets default_agent to sisyphus when missing", async () => {
// #given
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-6",
agent: {},
@@ -472,7 +472,7 @@ describe("default_agent behavior with Sisyphus orchestration", () => {
test("sets default_agent to sisyphus when configured default_agent is empty after trim", async () => {
// given
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-6",
default_agent: " ",
@@ -496,7 +496,7 @@ describe("default_agent behavior with Sisyphus orchestration", () => {
test("preserves custom default_agent names while trimming whitespace", async () => {
// given
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-6",
default_agent: " Custom Agent ",
@@ -520,7 +520,7 @@ describe("default_agent behavior with Sisyphus orchestration", () => {
test("does not normalize configured default_agent when Sisyphus is disabled", async () => {
// given
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
sisyphus_agent: {
disabled: true,
},
@@ -650,7 +650,7 @@ describe("Prometheus category config resolution", () => {
describe("Prometheus direct override priority over category", () => {
test("direct reasoningEffort takes priority over category reasoningEffort", async () => {
// given - category has reasoningEffort=xhigh, direct override says "low"
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
sisyphus_agent: {
planner_enabled: true,
},
@@ -692,7 +692,7 @@ describe("Prometheus direct override priority over category", () => {
test("category reasoningEffort applied when no direct override", async () => {
// given - category has reasoningEffort but no direct override
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
sisyphus_agent: {
planner_enabled: true,
},
@@ -733,7 +733,7 @@ describe("Prometheus direct override priority over category", () => {
test("direct temperature takes priority over category temperature", async () => {
// given
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
sisyphus_agent: {
planner_enabled: true,
},
@@ -776,7 +776,7 @@ describe("Prometheus direct override priority over category", () => {
test("prometheus prompt_append is appended to base prompt", async () => {
// #given - prometheus override with prompt_append
const customInstructions = "## Custom Project Rules\nUse max 2 commits."
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
sisyphus_agent: {
planner_enabled: true,
},
@@ -820,7 +820,7 @@ describe("Plan agent model inheritance from prometheus", () => {
provenance: "provider-fallback",
variant: "max",
})
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
sisyphus_agent: {
planner_enabled: true,
replace_plan: true,
@@ -864,7 +864,7 @@ describe("Plan agent model inheritance from prometheus", () => {
provenance: "override",
variant: "high",
})
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
sisyphus_agent: {
planner_enabled: true,
replace_plan: true,
@@ -919,7 +919,7 @@ describe("Plan agent model inheritance from prometheus", () => {
provenance: "provider-fallback",
variant: "max",
})
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
sisyphus_agent: {
planner_enabled: true,
replace_plan: true,
@@ -962,7 +962,7 @@ describe("Plan agent model inheritance from prometheus", () => {
provenance: "provider-fallback",
variant: "max",
})
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
sisyphus_agent: {
planner_enabled: true,
replace_plan: true,
@@ -1001,7 +1001,7 @@ describe("Deadlock prevention - fetchAvailableModels must not receive client", (
// - Server waits for plugin init to complete before handling requests
const fetchSpy = spyOn(shared, "fetchAvailableModels" as any).mockResolvedValue(new Set<string>())
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
sisyphus_agent: {
planner_enabled: true,
},
@@ -1041,7 +1041,7 @@ describe("config-handler plugin loading error boundary (#1559)", () => {
//#given
;(pluginLoader.loadAllPluginComponents as any).mockRestore?.()
spyOn(pluginLoader, "loadAllPluginComponents" as any).mockRejectedValue(new Error("crash"))
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-6",
agent: {},
@@ -1068,7 +1068,7 @@ describe("config-handler plugin loading error boundary (#1559)", () => {
spyOn(pluginLoader, "loadAllPluginComponents" as any).mockImplementation(
() => new Promise(() => {})
)
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
experimental: { plugin_load_timeout_ms: 100 },
}
const config: Record<string, unknown> = {
@@ -1096,7 +1096,7 @@ describe("config-handler plugin loading error boundary (#1559)", () => {
;(pluginLoader.loadAllPluginComponents as any).mockRestore?.()
spyOn(pluginLoader, "loadAllPluginComponents" as any).mockRejectedValue(new Error("crash"))
const logSpy = shared.log as ReturnType<typeof spyOn>
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-6",
agent: {},
@@ -1133,7 +1133,7 @@ describe("config-handler plugin loading error boundary (#1559)", () => {
plugins: [{ name: "test-plugin", version: "1.0.0" }],
errors: [],
})
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-6",
agent: {},
@@ -1179,7 +1179,7 @@ describe("per-agent todowrite/todoread deny when task_system enabled", () => {
oracle: { name: "oracle", prompt: "test", mode: "subagent" },
})
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
experimental: { task_system: true },
}
const config: Record<string, unknown> = {
@@ -1216,7 +1216,7 @@ describe("per-agent todowrite/todoread deny when task_system enabled", () => {
hephaestus: { name: "hephaestus", prompt: "test", mode: "primary" },
})
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
experimental: { task_system: false },
}
const config: Record<string, unknown> = {
@@ -1252,7 +1252,7 @@ describe("per-agent todowrite/todoread deny when task_system enabled", () => {
sisyphus: { name: "sisyphus", prompt: "test", mode: "primary" },
})
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-6",
agent: {},
@@ -1287,7 +1287,7 @@ describe("disable_omo_env pass-through", () => {
sisyphus: { name: "sisyphus", prompt: "without-env", mode: "primary" },
})
const pluginConfig: OhMyOpenCodeConfig = {
const pluginConfig: OhMyOpenAgentConfig = {
experimental: { disable_omo_env: true },
}
const config: Record<string, unknown> = {
@@ -1323,7 +1323,7 @@ describe("disable_omo_env pass-through", () => {
sisyphus: { name: "sisyphus", prompt: "with-env", mode: "primary" },
})
const pluginConfig: OhMyOpenCodeConfig = {}
const pluginConfig: OhMyOpenAgentConfig = {}
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-6",
agent: {},

View File

@@ -1,4 +1,4 @@
import type { OhMyOpenCodeConfig } from "../config";
import type { OhMyOpenAgentConfig } from "../config";
import type { ModelCacheState } from "../plugin-state";
import { log } from "../shared";
import { applyAgentConfig } from "./agent-config-handler";
@@ -12,7 +12,7 @@ export { resolveCategoryConfig } from "./category-config-resolver";
export interface ConfigHandlerDeps {
ctx: { directory: string; client?: any };
pluginConfig: OhMyOpenCodeConfig;
pluginConfig: OhMyOpenAgentConfig;
modelCacheState: ModelCacheState;
}

View File

@@ -1,7 +1,7 @@
/// <reference types="bun-types" />
import { describe, test, expect, spyOn, beforeEach, afterEach } from "bun:test"
import type { OhMyOpenCodeConfig } from "../config"
import type { OhMyOpenAgentConfig } from "../config"
import * as mcpLoader from "../features/claude-code-mcp-loader"
import * as mcpModule from "../mcp"
@@ -24,12 +24,10 @@ afterEach(() => {
;(shared.log as any)?.mockRestore?.()
})
function createPluginConfig(overrides: Partial<OhMyOpenCodeConfig> = {}): OhMyOpenCodeConfig {
return {
disabled_mcps: [],
...overrides,
} as OhMyOpenCodeConfig
}
function createPluginConfig(overrides: Partial<OhMyOpenAgentConfig> = {}): OhMyOpenAgentConfig { return {
disabled_mcps: [],
...overrides,
} as OhMyOpenAgentConfig }
const EMPTY_PLUGIN_COMPONENTS = {
commands: {},

View File

@@ -1,4 +1,4 @@
import type { OhMyOpenCodeConfig } from "../config";
import type { OhMyOpenAgentConfig } from "../config";
import { loadMcpConfigs } from "../features/claude-code-mcp-loader";
import { createBuiltinMcps } from "../mcp";
import type { PluginComponents } from "./plugin-components-loader";
@@ -27,7 +27,7 @@ function captureUserDisabledMcps(
export async function applyMcpConfig(params: {
config: Record<string, unknown>;
pluginConfig: OhMyOpenCodeConfig;
pluginConfig: OhMyOpenAgentConfig;
pluginComponents: PluginComponents;
}): Promise<void> {
const disabledMcps = params.pluginConfig.disabled_mcps ?? [];

View File

@@ -1,4 +1,4 @@
import type { OhMyOpenCodeConfig } from "../config";
import type { OhMyOpenAgentConfig } from "../config";
import { loadAllPluginComponents } from "../features/claude-code-plugin-loader";
import { addConfigLoadError, log } from "../shared";
@@ -23,7 +23,7 @@ const EMPTY_PLUGIN_COMPONENTS: PluginComponents = {
};
export async function loadPluginComponents(params: {
pluginConfig: OhMyOpenCodeConfig;
pluginConfig: OhMyOpenAgentConfig;
}): Promise<PluginComponents> {
const pluginsEnabled = params.pluginConfig.claude_code?.plugins ?? true;
if (!pluginsEnabled) {

View File

@@ -1,6 +1,6 @@
import { describe, it, expect, beforeEach, afterEach } from "bun:test"
import { applyToolConfig } from "./tool-config-handler"
import type { OhMyOpenCodeConfig } from "../config"
import type { OhMyOpenAgentConfig } from "../config"
function createParams(overrides: {
taskSystem?: boolean
@@ -15,7 +15,7 @@ function createParams(overrides: {
config: { tools: {}, permission: {} } as Record<string, unknown>,
pluginConfig: {
experimental: { task_system: overrides.taskSystem ?? false },
} as OhMyOpenCodeConfig,
} as OhMyOpenAgentConfig,
agentResult: agentResult as Record<string, unknown>,
}
}

View File

@@ -1,4 +1,4 @@
import type { OhMyOpenCodeConfig } from "../config";
import type { OhMyOpenAgentConfig } from "../config";
import { getAgentDisplayName } from "../shared/agent-display-names";
type AgentWithPermission = { permission?: Record<string, unknown> };
@@ -22,7 +22,7 @@ function agentByKey(agentResult: Record<string, unknown>, key: string): AgentWit
export function applyToolConfig(params: {
config: Record<string, unknown>;
pluginConfig: OhMyOpenCodeConfig;
pluginConfig: OhMyOpenAgentConfig;
agentResult: Record<string, unknown>;
}): void {
const denyTodoTools = params.pluginConfig.experimental?.task_system

View File

@@ -1,5 +1,5 @@
import type { PluginContext, PluginInterface, ToolsRecord } from "./plugin/types"
import type { OhMyOpenCodeConfig } from "./config"
import type { OhMyOpenAgentConfig } from "./config"
import { createChatParamsHandler } from "./plugin/chat-params"
import { createChatHeadersHandler } from "./plugin/chat-headers"
@@ -15,7 +15,7 @@ import type { Managers } from "./create-managers"
export function createPluginInterface(args: {
ctx: PluginContext
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
firstMessageVariantGate: {
shouldOverride: (sessionID: string) => boolean
markApplied: (sessionID: string) => void

View File

@@ -1,24 +1,20 @@
import type { AvailableCategory } from "../agents/dynamic-agent-prompt-builder"
import type { OhMyOpenCodeConfig } from "../config"
import type { OhMyOpenAgentConfig } from "../config"
import { CATEGORY_DESCRIPTIONS } from "../tools/delegate-task/constants"
import { mergeCategories } from "../shared/merge-categories"
export function createAvailableCategories(
pluginConfig: OhMyOpenCodeConfig,
): AvailableCategory[] {
const categories = mergeCategories(pluginConfig.categories)
export function createAvailableCategories(pluginConfig: OhMyOpenAgentConfig): AvailableCategory[] { const categories = mergeCategories(pluginConfig.categories)
return Object.entries(categories).map(([name, categoryConfig]) => {
const model =
typeof categoryConfig.model === "string" ? categoryConfig.model : undefined
return Object.entries(categories).map(([name, categoryConfig]) => {
const model =
typeof categoryConfig.model === "string" ? categoryConfig.model : undefined
return {
name,
description:
pluginConfig.categories?.[name]?.description ??
CATEGORY_DESCRIPTIONS[name] ??
"General tasks",
model,
}
})
}
return {
name,
description:
pluginConfig.categories?.[name]?.description ??
CATEGORY_DESCRIPTIONS[name] ??
"General tasks",
model,
}
}) }

View File

@@ -1,4 +1,4 @@
import type { OhMyOpenCodeConfig } from "../config"
import type { OhMyOpenAgentConfig } from "../config"
import type { PluginContext } from "./types"
import { hasConnectedProvidersCache } from "../shared"
@@ -37,7 +37,7 @@ function isStartWorkHookOutput(value: unknown): value is StartWorkHookOutput {
export function createChatMessageHandler(args: {
ctx: PluginContext
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
firstMessageVariantGate: FirstMessageVariantGate
hooks: CreatedHooks
}): (

View File

@@ -1,4 +1,4 @@
import type { OhMyOpenCodeConfig } from "../config";
import type { OhMyOpenAgentConfig } from "../config";
import type { PluginContext } from "./types";
import {
@@ -107,7 +107,7 @@ function applyUserConfiguredFallbackChain(
sessionID: string,
agentName: string,
currentProviderID: string,
pluginConfig: OhMyOpenCodeConfig,
pluginConfig: OhMyOpenAgentConfig,
): void {
const agentKey = getAgentConfigKey(agentName);
const configuredFallbackModels = getFallbackModelsForSession(sessionID, agentKey, pluginConfig);
@@ -127,7 +127,7 @@ function isCompactionAgent(agent: string): boolean {
type EventInput = Parameters<NonNullable<NonNullable<CreatedHooks["writeExistingFileGuard"]>["event"]>>[0];
export function createEventHandler(args: {
ctx: PluginContext;
pluginConfig: OhMyOpenCodeConfig;
pluginConfig: OhMyOpenAgentConfig;
firstMessageVariantGate: FirstMessageVariantGate;
managers: Managers;
hooks: CreatedHooks;

View File

@@ -1,4 +1,4 @@
import type { HookName, OhMyOpenCodeConfig } from "../../config"
import type { HookName, OhMyOpenAgentConfig } from "../../config"
import type { BackgroundManager } from "../../features/background-agent"
import type { PluginContext } from "../types"
@@ -32,7 +32,7 @@ type SessionRecovery = {
export function createContinuationHooks(args: {
ctx: PluginContext
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
isHookEnabled: (hookName: HookName) => boolean
safeHookEnabled: boolean
backgroundManager: BackgroundManager

View File

@@ -1,4 +1,4 @@
import type { HookName, OhMyOpenCodeConfig } from "../../config"
import type { HookName, OhMyOpenAgentConfig } from "../../config"
import type { PluginContext } from "../types"
import type { ModelCacheState } from "../../plugin-state"
@@ -8,7 +8,7 @@ import { createTransformHooks } from "./create-transform-hooks"
export function createCoreHooks(args: {
ctx: PluginContext
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
modelCacheState: ModelCacheState
isHookEnabled: (hookName: HookName) => boolean
safeHookEnabled: boolean

View File

@@ -1,4 +1,4 @@
import type { OhMyOpenCodeConfig, HookName } from "../../config"
import type { OhMyOpenAgentConfig, HookName } from "../../config"
import type { ModelCacheState } from "../../plugin-state"
import type { PluginContext } from "../types"
@@ -64,7 +64,7 @@ export type SessionHooks = {
export function createSessionHooks(args: {
ctx: PluginContext
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
modelCacheState: ModelCacheState
isHookEnabled: (hookName: HookName) => boolean
safeHookEnabled: boolean

View File

@@ -1,5 +1,5 @@
import type { AvailableSkill } from "../../agents/dynamic-agent-prompt-builder"
import type { HookName, OhMyOpenCodeConfig } from "../../config"
import type { HookName, OhMyOpenAgentConfig } from "../../config"
import type { LoadedSkill } from "../../features/opencode-skill-loader/types"
import type { PluginContext } from "../types"
@@ -13,7 +13,7 @@ export type SkillHooks = {
export function createSkillHooks(args: {
ctx: PluginContext
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
isHookEnabled: (hookName: HookName) => boolean
safeHookEnabled: boolean
mergedSkills: LoadedSkill[]

View File

@@ -1,4 +1,4 @@
import type { HookName, OhMyOpenCodeConfig } from "../../config"
import type { HookName, OhMyOpenAgentConfig } from "../../config"
import type { ModelCacheState } from "../../plugin-state"
import type { PluginContext } from "../types"
@@ -41,7 +41,7 @@ export type ToolGuardHooks = {
export function createToolGuardHooks(args: {
ctx: PluginContext
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
modelCacheState: ModelCacheState
isHookEnabled: (hookName: HookName) => boolean
safeHookEnabled: boolean

View File

@@ -1,4 +1,4 @@
import type { OhMyOpenCodeConfig } from "../../config"
import type { OhMyOpenAgentConfig } from "../../config"
import type { PluginContext } from "../types"
import {
@@ -21,7 +21,7 @@ export type TransformHooks = {
export function createTransformHooks(args: {
ctx: PluginContext
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
isHookEnabled: (hookName: string) => boolean
safeHookEnabled?: boolean
}): TransformHooks {

View File

@@ -3,7 +3,7 @@ import { mkdirSync, rmSync, writeFileSync } from "node:fs"
import { tmpdir } from "node:os"
import { join } from "node:path"
import { OhMyOpenCodeConfigSchema } from "../config"
import { OhMyOpenAgentConfigSchema } from "../config"
import * as mcpLoader from "../features/claude-code-mcp-loader"
import * as skillLoader from "../features/opencode-skill-loader"
import { createSkillContext } from "./skill-context"
@@ -60,7 +60,7 @@ describe("createSkillContext", () => {
"getSystemMcpServerNames",
).mockReturnValue(new Set<string>())
const pluginConfig = OhMyOpenCodeConfigSchema.parse({
const pluginConfig = OhMyOpenAgentConfigSchema.parse({
browser_automation_engine: { provider: "agent-browser" },
})

View File

@@ -1,5 +1,5 @@
import type { AvailableSkill } from "../agents/dynamic-agent-prompt-builder"
import type { OhMyOpenCodeConfig } from "../config"
import type { OhMyOpenAgentConfig } from "../config"
import type { BrowserAutomationProvider } from "../config/schema/browser-automation"
import type {
LoadedSkill,
@@ -49,7 +49,7 @@ function filterProviderGatedSkills(
export async function createSkillContext(args: {
directory: string
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
}): Promise<SkillContext> {
const { directory, pluginConfig } = args

View File

@@ -3,7 +3,7 @@ import type { ToolDefinition } from "@opencode-ai/plugin"
import type {
AvailableCategory,
} from "../agents/dynamic-agent-prompt-builder"
import type { OhMyOpenCodeConfig } from "../config"
import type { OhMyOpenAgentConfig } from "../config"
import type { PluginContext, ToolsRecord } from "./types"
import {
@@ -41,7 +41,7 @@ export type ToolRegistryResult = {
export function createToolRegistry(args: {
ctx: PluginContext
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
managers: Pick<Managers, "backgroundManager" | "tmuxSessionManager" | "skillMcpManager">
skillContext: SkillContext
availableCategories: AvailableCategory[]

View File

@@ -1,4 +1,4 @@
import type { OhMyOpenCodeConfig } from "../config"
import type { OhMyOpenAgentConfig } from "../config"
import type { AgentOverrides } from "../config/schema/agent-overrides"
import { getSessionAgent } from "../features/claude-code-session-state"
import { log } from "../shared"
@@ -58,7 +58,7 @@ function getMessageModel(current: unknown): ModelDescriptor | undefined {
}
export function resolveUltraworkOverride(
pluginConfig: OhMyOpenCodeConfig,
pluginConfig: OhMyOpenAgentConfig,
inputAgentName: string | undefined,
output: {
message: Record<string, unknown>
@@ -146,7 +146,7 @@ function applyResolvedUltraworkOverride(args: {
}
export function applyUltraworkModelOverrideOnMessage(
pluginConfig: OhMyOpenCodeConfig,
pluginConfig: OhMyOpenAgentConfig,
inputAgentName: string | undefined,
output: {
message: Record<string, unknown>

View File

@@ -1,4 +1,4 @@
import type { OhMyOpenCodeConfig } from "../config"
import type { OhMyOpenAgentConfig } from "../config"
import type { PluginContext } from "./types"
import { createUnstableAgentBabysitterHook } from "../hooks"
@@ -7,7 +7,7 @@ import type { BackgroundManager } from "../features/background-agent"
export function createUnstableAgentBabysitter(args: {
ctx: PluginContext
backgroundManager: BackgroundManager
pluginConfig: OhMyOpenCodeConfig
pluginConfig: OhMyOpenAgentConfig
}) {
const { ctx, backgroundManager, pluginConfig } = args

View File

@@ -1,11 +1,11 @@
import { describe, expect, test } from "bun:test"
import type { OhMyOpenCodeConfig } from "../config"
import type { OhMyOpenAgentConfig } from "../config"
import { applyAgentVariant, resolveAgentVariant, resolveVariantForModel } from "./agent-variant"
describe("resolveAgentVariant", () => {
test("returns undefined when agent name missing", () => {
// given
const config = {} as OhMyOpenCodeConfig
const config = {} as OhMyOpenAgentConfig
// when
const variant = resolveAgentVariant(config)
@@ -20,7 +20,7 @@ describe("resolveAgentVariant", () => {
agents: {
sisyphus: { variant: "low" },
},
} as OhMyOpenCodeConfig
} as OhMyOpenAgentConfig
// when
const variant = resolveAgentVariant(config, "sisyphus")
@@ -38,7 +38,7 @@ describe("resolveAgentVariant", () => {
categories: {
ultrabrain: { model: "openai/gpt-5.4", variant: "xhigh" },
},
} as OhMyOpenCodeConfig
} as OhMyOpenAgentConfig
// when
const variant = resolveAgentVariant(config, "sisyphus")
@@ -55,7 +55,7 @@ describe("applyAgentVariant", () => {
agents: {
sisyphus: { variant: "low" },
},
} as OhMyOpenCodeConfig
} as OhMyOpenAgentConfig
const message: { variant?: string } = {}
// when
@@ -71,7 +71,7 @@ describe("applyAgentVariant", () => {
agents: {
sisyphus: { variant: "low" },
},
} as OhMyOpenCodeConfig
} as OhMyOpenAgentConfig
const message = { variant: "max" }
// when
@@ -90,7 +90,7 @@ describe("resolveVariantForModel", () => {
agents: {
sisyphus: { variant: "high" },
},
} as OhMyOpenCodeConfig
} as OhMyOpenAgentConfig
const model = { providerID: "anthropic", modelID: "claude-opus-4-6" }
// when
@@ -102,7 +102,7 @@ describe("resolveVariantForModel", () => {
test("returns correct variant for anthropic provider", () => {
// given
const config = {} as OhMyOpenCodeConfig
const config = {} as OhMyOpenAgentConfig
const model = { providerID: "anthropic", modelID: "claude-opus-4-6" }
// when
@@ -114,7 +114,7 @@ describe("resolveVariantForModel", () => {
test("returns correct variant for openai provider (hephaestus agent)", () => {
// #given hephaestus has openai/gpt-5.3-codex with variant "medium" in its chain
const config = {} as OhMyOpenCodeConfig
const config = {} as OhMyOpenAgentConfig
const model = { providerID: "openai", modelID: "gpt-5.3-codex" }
// #when
@@ -126,7 +126,7 @@ describe("resolveVariantForModel", () => {
test("returns medium for openai/gpt-5.4 in sisyphus chain", () => {
// #given openai/gpt-5.4 is now in sisyphus fallback chain with variant medium
const config = {} as OhMyOpenCodeConfig
const config = {} as OhMyOpenAgentConfig
const model = { providerID: "openai", modelID: "gpt-5.4" }
// when
@@ -138,7 +138,7 @@ describe("resolveVariantForModel", () => {
test("returns undefined for provider not in chain", () => {
// given
const config = {} as OhMyOpenCodeConfig
const config = {} as OhMyOpenAgentConfig
const model = { providerID: "unknown-provider", modelID: "some-model" }
// when
@@ -150,7 +150,7 @@ describe("resolveVariantForModel", () => {
test("returns undefined for unknown agent", () => {
// given
const config = {} as OhMyOpenCodeConfig
const config = {} as OhMyOpenAgentConfig
const model = { providerID: "anthropic", modelID: "claude-opus-4-6" }
// when
@@ -162,7 +162,7 @@ describe("resolveVariantForModel", () => {
test("returns variant for zai-coding-plan provider without variant", () => {
// given
const config = {} as OhMyOpenCodeConfig
const config = {} as OhMyOpenAgentConfig
const model = { providerID: "zai-coding-plan", modelID: "glm-5" }
// when
@@ -178,7 +178,7 @@ describe("resolveVariantForModel", () => {
agents: {
"custom-agent": { category: "ultrabrain" },
},
} as OhMyOpenCodeConfig
} as OhMyOpenAgentConfig
const model = { providerID: "openai", modelID: "gpt-5.4" }
// when
@@ -190,7 +190,7 @@ describe("resolveVariantForModel", () => {
test("returns correct variant for oracle agent with openai", () => {
// given
const config = {} as OhMyOpenCodeConfig
const config = {} as OhMyOpenAgentConfig
const model = { providerID: "openai", modelID: "gpt-5.4" }
// when
@@ -202,7 +202,7 @@ describe("resolveVariantForModel", () => {
test("returns correct variant for oracle agent with anthropic", () => {
// given
const config = {} as OhMyOpenCodeConfig
const config = {} as OhMyOpenAgentConfig
const model = { providerID: "anthropic", modelID: "claude-opus-4-6" }
// when

View File

@@ -1,8 +1,8 @@
import type { OhMyOpenCodeConfig } from "../config"
import type { OhMyOpenAgentConfig } from "../config"
import { AGENT_MODEL_REQUIREMENTS, CATEGORY_MODEL_REQUIREMENTS } from "./model-requirements"
export function resolveAgentVariant(
config: OhMyOpenCodeConfig,
config: OhMyOpenAgentConfig,
agentName?: string
): string | undefined {
if (!agentName) {
@@ -33,7 +33,7 @@ export function resolveAgentVariant(
}
export function resolveVariantForModel(
config: OhMyOpenCodeConfig,
config: OhMyOpenAgentConfig,
agentName: string,
currentModel: { providerID: string; modelID: string },
): string | undefined {
@@ -87,7 +87,7 @@ function findVariantInChain(
}
export function applyAgentVariant(
config: OhMyOpenCodeConfig,
config: OhMyOpenAgentConfig,
agentName: string | undefined,
message: { variant?: string }
): void {

View File

@@ -1,7 +1,7 @@
import type { PluginInput } from "@opencode-ai/plugin";
import { tool, type ToolDefinition } from "@opencode-ai/plugin/tool";
import { join } from "path";
import type { OhMyOpenCodeConfig } from "../../config/schema";
import type { OhMyOpenAgentConfig } from "../../config/schema";
import type { TaskObject } from "./types";
import { TaskObjectSchema, TaskCreateInputSchema } from "./types";
import {
@@ -13,7 +13,7 @@ import {
import { syncTaskTodoUpdate } from "./todo-sync";
export function createTaskCreateTool(
config: Partial<OhMyOpenCodeConfig>,
config: Partial<OhMyOpenAgentConfig>,
ctx?: PluginInput,
): ToolDefinition {
return tool({
@@ -58,7 +58,7 @@ Calculate dependencies carefully to maximize parallel execution:
async function handleCreate(
args: Record<string, unknown>,
config: Partial<OhMyOpenCodeConfig>,
config: Partial<OhMyOpenAgentConfig>,
ctx: PluginInput | undefined,
context: { sessionID: string },
): Promise<string> {

View File

@@ -1,6 +1,6 @@
import { tool, type ToolDefinition } from "@opencode-ai/plugin/tool"
import { join } from "path"
import type { OhMyOpenCodeConfig } from "../../config/schema"
import type { OhMyOpenAgentConfig } from "../../config/schema"
import { TaskGetInputSchema, TaskObjectSchema } from "./types"
import { getTaskDir, readJsonSafe } from "../../features/claude-tasks/storage"
@@ -11,7 +11,7 @@ function parseTaskId(id: string): string | null {
return id
}
export function createTaskGetTool(config: Partial<OhMyOpenCodeConfig>): ToolDefinition {
export function createTaskGetTool(config: Partial<OhMyOpenAgentConfig>): ToolDefinition {
return tool({
description: `Retrieve a task by ID.

View File

@@ -1,7 +1,7 @@
import { tool, type ToolDefinition } from "@opencode-ai/plugin/tool"
import { join } from "path"
import { existsSync, readdirSync } from "fs"
import type { OhMyOpenCodeConfig } from "../../config/schema"
import type { OhMyOpenAgentConfig } from "../../config/schema"
import type { TaskObject, TaskStatus } from "./types"
import { TaskObjectSchema } from "./types"
import { readJsonSafe, getTaskDir } from "../../features/claude-tasks/storage"
@@ -14,7 +14,7 @@ interface TaskSummary {
blockedBy: string[]
}
export function createTaskList(config: Partial<OhMyOpenCodeConfig>): ToolDefinition {
export function createTaskList(config: Partial<OhMyOpenAgentConfig>): ToolDefinition {
return tool({
description: `List all active tasks with summary information.

View File

@@ -1,7 +1,7 @@
import type { PluginInput } from "@opencode-ai/plugin";
import { tool, type ToolDefinition } from "@opencode-ai/plugin/tool";
import { join } from "path";
import type { OhMyOpenCodeConfig } from "../../config/schema";
import type { OhMyOpenAgentConfig } from "../../config/schema";
import { TaskObjectSchema, TaskUpdateInputSchema } from "./types";
import {
getTaskDir,
@@ -19,7 +19,7 @@ function parseTaskId(id: string): string | null {
}
export function createTaskUpdateTool(
config: Partial<OhMyOpenCodeConfig>,
config: Partial<OhMyOpenAgentConfig>,
ctx?: PluginInput,
): ToolDefinition {
return tool({
@@ -70,7 +70,7 @@ Properly managed dependencies enable maximum parallel execution.`,
async function handleUpdate(
args: Record<string, unknown>,
config: Partial<OhMyOpenCodeConfig>,
config: Partial<OhMyOpenAgentConfig>,
ctx: PluginInput | undefined,
context: { sessionID: string },
): Promise<string> {