fix(hooks): reuse shared legacy plugin migration helper

Replace the legacy toast regex writer with the shared atomic helper and route legacy plugin call sites through small wrappers so existing mock.module tests stop leaking across the suite.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-04-04 01:32:59 +09:00
parent 290f7f9543
commit f03c6700d4
8 changed files with 18 additions and 25 deletions
@@ -0,0 +1,2 @@
export { autoMigrateLegacyPluginEntry } from "./auto-migrate"
export type { MigrationResult } from "./auto-migrate"
+9 -20
View File
@@ -1,9 +1,10 @@
import { existsSync, readFileSync, writeFileSync } from "node:fs"
import { existsSync, readFileSync } from "node:fs"
import { join } from "node:path"
import { parseJsoncSafe } from "../../shared/jsonc-parser"
import { getOpenCodeConfigPaths } from "../../shared/opencode-config-dir"
import { LEGACY_PLUGIN_NAME, PLUGIN_NAME } from "../../shared/plugin-identity"
import { migrateLegacyPluginEntry } from "./plugin-entry-migrator"
export interface MigrationResult {
migrated: boolean
@@ -63,27 +64,15 @@ export function autoMigrateLegacyPluginEntry(overrideConfigDir?: string): Migrat
const hasCanonical = plugins.some(isCanonicalEntry)
const from = legacyEntries[0]
const to = toLegacyCanonical(from)
const migrated = migrateLegacyPluginEntry(configPath)
if (!migrated) return { migrated: false, from: null, to: null, configPath }
const normalized = hasCanonical
? plugins.filter((p) => !isLegacyEntry(p))
: plugins.map((p) => (isLegacyEntry(p) ? toLegacyCanonical(p) : p))
const isJsonc = configPath.endsWith(".jsonc")
if (isJsonc) {
const pluginArrayRegex = /((?:"plugin"|plugin)\s*:\s*)\[([\s\S]*?)\]/
const match = content.match(pluginArrayRegex)
if (match) {
const formattedPlugins = normalized.map((p) => `"${p}"`).join(",\n ")
const newContent = content.replace(pluginArrayRegex, `$1[\n ${formattedPlugins}\n ]`)
writeFileSync(configPath, newContent)
return { migrated: true, from, to, configPath }
}
return {
migrated: true,
from,
to: hasCanonical ? PLUGIN_NAME : to,
configPath,
}
const parsed = JSON.parse(content) as Record<string, unknown>
parsed.plugin = normalized
writeFileSync(configPath, JSON.stringify(parsed, null, 2) + "\n")
return { migrated: true, from, to, configPath }
} catch {
return { migrated: false, from: null, to: null, configPath }
}
+2 -2
View File
@@ -1,5 +1,5 @@
import { afterAll, beforeEach, describe, expect, it, mock } from "bun:test"
import type { MigrationResult } from "./auto-migrate"
import type { MigrationResult } from "./auto-migrate-runner"
const mockCheckForLegacyPluginEntry = mock(() => ({
hasLegacyEntry: false,
@@ -26,7 +26,7 @@ mock.module("../../shared/logger", () => ({
log: mockLog,
}))
mock.module("./auto-migrate", () => ({
mock.module("./auto-migrate-runner", () => ({
autoMigrateLegacyPluginEntry: mockAutoMigrate,
}))
+1 -1
View File
@@ -3,7 +3,7 @@ import type { PluginInput } from "@opencode-ai/plugin"
import { checkForLegacyPluginEntry } from "../../shared/legacy-plugin-warning"
import { log } from "../../shared/logger"
import { LEGACY_PLUGIN_NAME, PLUGIN_NAME } from "../../shared/plugin-identity"
import { autoMigrateLegacyPluginEntry } from "./auto-migrate"
import { autoMigrateLegacyPluginEntry } from "./auto-migrate-runner"
export function createLegacyPluginToastHook(ctx: PluginInput) {
let fired = false
@@ -0,0 +1 @@
export { migrateLegacyPluginEntry } from "../../shared/migrate-legacy-plugin-entry"
@@ -26,7 +26,7 @@ mock.module("./logger", () => ({
log: mockLog,
}))
mock.module("./migrate-legacy-plugin-entry", () => ({
mock.module("./plugin-entry-migrator", () => ({
migrateLegacyPluginEntry: mockMigrateLegacyPluginEntry,
}))
@@ -1,6 +1,6 @@
import { checkForLegacyPluginEntry } from "./legacy-plugin-warning"
import { log } from "./logger"
import { migrateLegacyPluginEntry } from "./migrate-legacy-plugin-entry"
import { migrateLegacyPluginEntry } from "./plugin-entry-migrator"
import { LEGACY_PLUGIN_NAME, PLUGIN_NAME } from "./plugin-identity"
function toCanonicalEntry(entry: string): string {
+1
View File
@@ -0,0 +1 @@
export { migrateLegacyPluginEntry } from "./migrate-legacy-plugin-entry"