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:
@@ -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",
|
||||
})
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
export {
|
||||
OhMyOpenCodeConfigSchema,
|
||||
OhMyOpenAgentConfigSchema,
|
||||
} from "./schema"
|
||||
|
||||
export type {
|
||||
OhMyOpenCodeConfig,
|
||||
OhMyOpenAgentConfig,
|
||||
AgentOverrideConfig,
|
||||
AgentOverrides,
|
||||
McpName,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 } }
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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>()
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 []
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>> {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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: {},
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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: {},
|
||||
|
||||
@@ -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 ?? [];
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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>,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}) }
|
||||
|
||||
@@ -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
|
||||
}): (
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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[]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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" },
|
||||
})
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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[]
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user