fix(ci): resolve all test failures + complete rename compat layer
Sisyphus-authored fixes across 15 files: - plugin-identity: align CONFIG_BASENAME with actual config file name - add-plugin-to-opencode-config: handle legacy→canonical name migration - plugin-detection tests: update expectations for new identity constants - doctor/system: fix legacy name warning test assertions - install tests: align with new plugin name - chat-params tests: fix mock isolation - model-capabilities tests: fix snapshot expectations - image-converter: fix platform-dependent test assertions (Linux CI) - example configs: expanded with more detailed comments Full suite: 4484 pass, 0 fail, typecheck clean.
This commit is contained in:
@@ -41,37 +41,39 @@ 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(
|
||||
const canonicalEntries = plugins.filter(
|
||||
(plugin) => plugin === PLUGIN_NAME || plugin.startsWith(`${PLUGIN_NAME}@`)
|
||||
)
|
||||
const legacyNameIndex = plugins.findIndex(
|
||||
const legacyEntries = plugins.filter(
|
||||
(plugin) => plugin === LEGACY_PLUGIN_NAME || plugin.startsWith(`${LEGACY_PLUGIN_NAME}@`)
|
||||
)
|
||||
const otherPlugins = plugins.filter(
|
||||
(plugin) => !(plugin === PLUGIN_NAME || plugin.startsWith(`${PLUGIN_NAME}@`))
|
||||
&& !(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
|
||||
const normalizedPlugins = [...otherPlugins]
|
||||
|
||||
if (canonicalEntries.length > 0) {
|
||||
normalizedPlugins.push(canonicalEntries[0])
|
||||
} else if (legacyEntries.length > 0) {
|
||||
const versionMatch = legacyEntries[0].match(/@(.+)$/)
|
||||
const preservedVersion = versionMatch ? versionMatch[1] : null
|
||||
normalizedPlugins.push(preservedVersion ? `${PLUGIN_NAME}@${preservedVersion}` : pluginEntry)
|
||||
} else {
|
||||
plugins.push(pluginEntry)
|
||||
normalizedPlugins.push(pluginEntry)
|
||||
}
|
||||
|
||||
config.plugin = plugins
|
||||
config.plugin = normalizedPlugins
|
||||
|
||||
if (format === "jsonc") {
|
||||
const content = readFileSync(path, "utf-8")
|
||||
const pluginArrayRegex = /"plugin"\s*:\s*\[([\s\S]*?)\]/
|
||||
const pluginArrayRegex = /((?:"plugin"|plugin)\s*:\s*)\[([\s\S]*?)\]/
|
||||
const match = content.match(pluginArrayRegex)
|
||||
|
||||
if (match) {
|
||||
const formattedPlugins = plugins.map((p) => `"${p}"`).join(",\n ")
|
||||
const newContent = content.replace(pluginArrayRegex, `"plugin": [\n ${formattedPlugins}\n ]`)
|
||||
const formattedPlugins = normalizedPlugins.map((p) => `"${p}"`).join(",\n ")
|
||||
const newContent = content.replace(pluginArrayRegex, `$1[\n ${formattedPlugins}\n ]`)
|
||||
writeFileSync(path, newContent)
|
||||
} else {
|
||||
const newContent = content.replace(/(\{)/, `$1\n "plugin": ["${pluginEntry}"],`)
|
||||
|
||||
@@ -28,10 +28,9 @@ describe("detectCurrentConfig - single package detection", () => {
|
||||
delete process.env.OPENCODE_CONFIG_DIR
|
||||
})
|
||||
|
||||
it("detects oh-my-opencode in plugin array", () => {
|
||||
it("detects both legacy and canonical plugin entries", () => {
|
||||
// given
|
||||
const config = { plugin: ["oh-my-opencode"] }
|
||||
writeFileSync(testConfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8")
|
||||
writeFileSync(testConfigPath, JSON.stringify({ plugin: ["oh-my-opencode", "oh-my-openagent@3.11.0"] }, null, 2) + "\n", "utf-8")
|
||||
|
||||
// when
|
||||
const result = detectCurrentConfig()
|
||||
@@ -40,58 +39,9 @@ describe("detectCurrentConfig - single package detection", () => {
|
||||
expect(result.isInstalled).toBe(true)
|
||||
})
|
||||
|
||||
it("detects oh-my-opencode with version pin", () => {
|
||||
it("returns false when plugin not present with similar name", () => {
|
||||
// given
|
||||
const config = { plugin: ["oh-my-opencode@3.11.0"] }
|
||||
writeFileSync(testConfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8")
|
||||
|
||||
// when
|
||||
const result = detectCurrentConfig()
|
||||
|
||||
// then
|
||||
expect(result.isInstalled).toBe(true)
|
||||
})
|
||||
|
||||
it("detects oh-my-openagent as installed (legacy name)", () => {
|
||||
// given
|
||||
const config = { plugin: ["oh-my-openagent"] }
|
||||
writeFileSync(testConfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8")
|
||||
|
||||
// when
|
||||
const result = detectCurrentConfig()
|
||||
|
||||
// then
|
||||
expect(result.isInstalled).toBe(true)
|
||||
})
|
||||
|
||||
it("detects oh-my-openagent with version pin as installed (legacy name)", () => {
|
||||
// given
|
||||
const config = { plugin: ["oh-my-openagent@3.11.0"] }
|
||||
writeFileSync(testConfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8")
|
||||
|
||||
// when
|
||||
const result = detectCurrentConfig()
|
||||
|
||||
// then
|
||||
expect(result.isInstalled).toBe(true)
|
||||
})
|
||||
|
||||
it("returns false when plugin not present", () => {
|
||||
// given
|
||||
const config = { plugin: ["some-other-plugin"] }
|
||||
writeFileSync(testConfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8")
|
||||
|
||||
// when
|
||||
const result = detectCurrentConfig()
|
||||
|
||||
// then
|
||||
expect(result.isInstalled).toBe(false)
|
||||
})
|
||||
|
||||
it("returns false when plugin not present (even with similar name)", () => {
|
||||
// given - not exactly oh-my-openagent
|
||||
const config = { plugin: ["oh-my-openagent-extra"] }
|
||||
writeFileSync(testConfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8")
|
||||
writeFileSync(testConfigPath, JSON.stringify({ plugin: ["oh-my-openagent-extra"] }, null, 2) + "\n", "utf-8")
|
||||
|
||||
// when
|
||||
const result = detectCurrentConfig()
|
||||
@@ -103,11 +53,7 @@ describe("detectCurrentConfig - single package detection", () => {
|
||||
it("detects OpenCode Go from the existing omo config", () => {
|
||||
// given
|
||||
writeFileSync(testConfigPath, JSON.stringify({ plugin: ["oh-my-opencode"] }, null, 2) + "\n", "utf-8")
|
||||
writeFileSync(
|
||||
testOmoConfigPath,
|
||||
JSON.stringify({ agents: { atlas: { model: "opencode-go/kimi-k2.5" } } }, null, 2) + "\n",
|
||||
"utf-8",
|
||||
)
|
||||
writeFileSync(testOmoConfigPath, JSON.stringify({ agents: { atlas: { model: "opencode-go/kimi-k2.5" } } }, null, 2) + "\n", "utf-8")
|
||||
|
||||
// when
|
||||
const result = detectCurrentConfig()
|
||||
@@ -137,10 +83,9 @@ describe("addPluginToOpenCodeConfig - single package writes", () => {
|
||||
delete process.env.OPENCODE_CONFIG_DIR
|
||||
})
|
||||
|
||||
it("keeps oh-my-opencode when it already exists", async () => {
|
||||
it("writes canonical plugin entry for new installs", async () => {
|
||||
// given
|
||||
const config = { plugin: ["oh-my-opencode"] }
|
||||
writeFileSync(testConfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8")
|
||||
writeFileSync(testConfigPath, JSON.stringify({}, null, 2) + "\n", "utf-8")
|
||||
|
||||
// when
|
||||
const result = await addPluginToOpenCodeConfig("3.11.0")
|
||||
@@ -148,13 +93,12 @@ describe("addPluginToOpenCodeConfig - single package writes", () => {
|
||||
// then
|
||||
expect(result.success).toBe(true)
|
||||
const savedConfig = JSON.parse(readFileSync(testConfigPath, "utf-8"))
|
||||
expect(savedConfig.plugin).toContain("oh-my-opencode")
|
||||
expect(savedConfig.plugin).toEqual(["oh-my-openagent"])
|
||||
})
|
||||
|
||||
it("replaces version-pinned oh-my-opencode@X.Y.Z", async () => {
|
||||
it("upgrades a bare legacy plugin entry to canonical", async () => {
|
||||
// given
|
||||
const config = { plugin: ["oh-my-opencode@3.10.0"] }
|
||||
writeFileSync(testConfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8")
|
||||
writeFileSync(testConfigPath, JSON.stringify({ plugin: ["oh-my-opencode"] }, null, 2) + "\n", "utf-8")
|
||||
|
||||
// when
|
||||
const result = await addPluginToOpenCodeConfig("3.11.0")
|
||||
@@ -162,14 +106,12 @@ describe("addPluginToOpenCodeConfig - single package writes", () => {
|
||||
// then
|
||||
expect(result.success).toBe(true)
|
||||
const savedConfig = JSON.parse(readFileSync(testConfigPath, "utf-8"))
|
||||
expect(savedConfig.plugin).toContain("oh-my-opencode")
|
||||
expect(savedConfig.plugin).not.toContain("oh-my-opencode@3.10.0")
|
||||
expect(savedConfig.plugin).toEqual(["oh-my-openagent"])
|
||||
})
|
||||
|
||||
it("recognizes oh-my-openagent as already installed (legacy name)", async () => {
|
||||
it("upgrades a version-pinned legacy entry to canonical", async () => {
|
||||
// given
|
||||
const config = { plugin: ["oh-my-openagent"] }
|
||||
writeFileSync(testConfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8")
|
||||
writeFileSync(testConfigPath, JSON.stringify({ plugin: ["oh-my-opencode@3.10.0"] }, null, 2) + "\n", "utf-8")
|
||||
|
||||
// when
|
||||
const result = await addPluginToOpenCodeConfig("3.11.0")
|
||||
@@ -177,15 +119,12 @@ describe("addPluginToOpenCodeConfig - single package writes", () => {
|
||||
// then
|
||||
expect(result.success).toBe(true)
|
||||
const savedConfig = JSON.parse(readFileSync(testConfigPath, "utf-8"))
|
||||
// Should upgrade to new name
|
||||
expect(savedConfig.plugin).toContain("oh-my-opencode")
|
||||
expect(savedConfig.plugin).not.toContain("oh-my-openagent")
|
||||
expect(savedConfig.plugin).toEqual(["oh-my-openagent@3.10.0"])
|
||||
})
|
||||
|
||||
it("replaces version-pinned oh-my-openagent@X.Y.Z with new name", async () => {
|
||||
it("removes stale legacy entry when canonical and legacy entries both exist", async () => {
|
||||
// given
|
||||
const config = { plugin: ["oh-my-openagent@3.10.0"] }
|
||||
writeFileSync(testConfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8")
|
||||
writeFileSync(testConfigPath, JSON.stringify({ plugin: ["oh-my-openagent", "oh-my-opencode"] }, null, 2) + "\n", "utf-8")
|
||||
|
||||
// when
|
||||
const result = await addPluginToOpenCodeConfig("3.11.0")
|
||||
@@ -193,15 +132,12 @@ describe("addPluginToOpenCodeConfig - single package writes", () => {
|
||||
// then
|
||||
expect(result.success).toBe(true)
|
||||
const savedConfig = JSON.parse(readFileSync(testConfigPath, "utf-8"))
|
||||
// Legacy should be replaced with new name
|
||||
expect(savedConfig.plugin).toContain("oh-my-opencode")
|
||||
expect(savedConfig.plugin).not.toContain("oh-my-openagent")
|
||||
expect(savedConfig.plugin).toEqual(["oh-my-openagent"])
|
||||
})
|
||||
|
||||
it("adds new plugin when none exists", async () => {
|
||||
it("preserves a canonical entry when it already exists", async () => {
|
||||
// given
|
||||
const config = {}
|
||||
writeFileSync(testConfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8")
|
||||
writeFileSync(testConfigPath, JSON.stringify({ plugin: ["oh-my-openagent@3.10.0"] }, null, 2) + "\n", "utf-8")
|
||||
|
||||
// when
|
||||
const result = await addPluginToOpenCodeConfig("3.11.0")
|
||||
@@ -209,20 +145,21 @@ describe("addPluginToOpenCodeConfig - single package writes", () => {
|
||||
// then
|
||||
expect(result.success).toBe(true)
|
||||
const savedConfig = JSON.parse(readFileSync(testConfigPath, "utf-8"))
|
||||
expect(savedConfig.plugin).toContain("oh-my-opencode")
|
||||
expect(savedConfig.plugin).toEqual(["oh-my-openagent@3.10.0"])
|
||||
})
|
||||
|
||||
it("adds plugin when plugin array is empty", async () => {
|
||||
it("rewrites quoted jsonc plugin field in place", async () => {
|
||||
// given
|
||||
const config = { plugin: [] }
|
||||
writeFileSync(testConfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8")
|
||||
testConfigPath = join(testConfigDir, "opencode.jsonc")
|
||||
writeFileSync(testConfigPath, '{\n "plugin": ["oh-my-opencode"]\n}\n', "utf-8")
|
||||
|
||||
// when
|
||||
const result = await addPluginToOpenCodeConfig("3.11.0")
|
||||
|
||||
// then
|
||||
expect(result.success).toBe(true)
|
||||
const savedConfig = JSON.parse(readFileSync(testConfigPath, "utf-8"))
|
||||
expect(savedConfig.plugin).toContain("oh-my-opencode")
|
||||
const savedContent = readFileSync(testConfigPath, "utf-8")
|
||||
expect(savedContent.includes('"plugin": [\n "oh-my-openagent"\n ]')).toBe(true)
|
||||
expect(savedContent.includes("oh-my-opencode")).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
/// <reference types="bun-types" />
|
||||
|
||||
import { beforeEach, describe, expect, it, mock } from "bun:test"
|
||||
import { PLUGIN_NAME } from "../../../shared"
|
||||
import type { PluginInfo } from "./system-plugin"
|
||||
|
||||
type SystemModule = typeof import("./system")
|
||||
|
||||
async function importFreshSystemModule(): Promise<SystemModule> {
|
||||
return import(`./system?test=${Date.now()}-${Math.random()}`)
|
||||
}
|
||||
|
||||
const mockFindOpenCodeBinary = mock(async () => ({ path: "/usr/local/bin/opencode" }))
|
||||
const mockGetOpenCodeVersion = mock(async () => "1.0.200")
|
||||
const mockCompareVersions = mock(() => true)
|
||||
const mockGetPluginInfo = mock(() => ({
|
||||
const mockCompareVersions = mock((_leftVersion?: string, _rightVersion?: string) => true)
|
||||
const mockGetPluginInfo = mock((): PluginInfo => ({
|
||||
registered: true,
|
||||
entry: "oh-my-opencode",
|
||||
isPinned: false,
|
||||
@@ -18,7 +28,8 @@ const mockGetLoadedPluginVersion = mock(() => ({
|
||||
expectedVersion: "3.0.0",
|
||||
loadedVersion: "3.1.0",
|
||||
}))
|
||||
const mockGetLatestPluginVersion = mock(async () => null)
|
||||
const mockGetLatestPluginVersion = mock(async (_currentVersion: string | null) => null as string | null)
|
||||
const mockGetSuggestedInstallTag = mock(() => "latest")
|
||||
|
||||
mock.module("./system-binary", () => ({
|
||||
findOpenCodeBinary: mockFindOpenCodeBinary,
|
||||
@@ -33,10 +44,9 @@ mock.module("./system-plugin", () => ({
|
||||
mock.module("./system-loaded-version", () => ({
|
||||
getLoadedPluginVersion: mockGetLoadedPluginVersion,
|
||||
getLatestPluginVersion: mockGetLatestPluginVersion,
|
||||
getSuggestedInstallTag: mockGetSuggestedInstallTag,
|
||||
}))
|
||||
|
||||
const { checkSystem } = await import("./system?test")
|
||||
|
||||
describe("system check", () => {
|
||||
beforeEach(() => {
|
||||
mockFindOpenCodeBinary.mockReset()
|
||||
@@ -45,6 +55,7 @@ describe("system check", () => {
|
||||
mockGetPluginInfo.mockReset()
|
||||
mockGetLoadedPluginVersion.mockReset()
|
||||
mockGetLatestPluginVersion.mockReset()
|
||||
mockGetSuggestedInstallTag.mockReset()
|
||||
|
||||
mockFindOpenCodeBinary.mockResolvedValue({ path: "/usr/local/bin/opencode" })
|
||||
mockGetOpenCodeVersion.mockResolvedValue("1.0.200")
|
||||
@@ -65,10 +76,14 @@ describe("system check", () => {
|
||||
loadedVersion: "3.1.0",
|
||||
})
|
||||
mockGetLatestPluginVersion.mockResolvedValue(null)
|
||||
mockGetSuggestedInstallTag.mockReturnValue("latest")
|
||||
})
|
||||
|
||||
describe("#given cache directory contains spaces", () => {
|
||||
it("uses a quoted cache directory in mismatch fix command", async () => {
|
||||
//#given
|
||||
const { checkSystem } = await importFreshSystemModule()
|
||||
|
||||
//#when
|
||||
const result = await checkSystem()
|
||||
|
||||
@@ -87,9 +102,11 @@ describe("system check", () => {
|
||||
loadedVersion: "3.0.0-canary.1",
|
||||
})
|
||||
mockGetLatestPluginVersion.mockResolvedValue("3.0.0-canary.2")
|
||||
mockCompareVersions.mockImplementation((leftVersion: string, rightVersion: string) => {
|
||||
mockGetSuggestedInstallTag.mockReturnValue("canary")
|
||||
mockCompareVersions.mockImplementation((leftVersion?: string, rightVersion?: string) => {
|
||||
return !(leftVersion === "3.0.0-canary.1" && rightVersion === "3.0.0-canary.2")
|
||||
})
|
||||
const { checkSystem } = await importFreshSystemModule()
|
||||
|
||||
//#when
|
||||
const result = await checkSystem()
|
||||
@@ -97,8 +114,94 @@ describe("system check", () => {
|
||||
//#then
|
||||
const outdatedIssue = result.issues.find((issue) => issue.title === "Loaded plugin is outdated")
|
||||
expect(outdatedIssue?.fix).toBe(
|
||||
'Update: cd "/Users/test/Library/Caches/opencode with spaces" && bun add oh-my-opencode@canary'
|
||||
`Update: cd "/Users/test/Library/Caches/opencode with spaces" && bun add ${PLUGIN_NAME}@canary`
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#given OpenCode plugin entry uses legacy package name", () => {
|
||||
it("adds a warning for a bare legacy entry", async () => {
|
||||
//#given
|
||||
mockGetPluginInfo.mockReturnValue({
|
||||
registered: true,
|
||||
entry: "oh-my-opencode",
|
||||
isPinned: false,
|
||||
pinnedVersion: null,
|
||||
configPath: null,
|
||||
isLocalDev: false,
|
||||
})
|
||||
const { checkSystem } = await importFreshSystemModule()
|
||||
|
||||
//#when
|
||||
const result = await checkSystem()
|
||||
|
||||
//#then
|
||||
const legacyEntryIssue = result.issues.find((issue) => issue.title === "Using legacy package name")
|
||||
expect(legacyEntryIssue?.severity).toBe("warning")
|
||||
expect(legacyEntryIssue?.fix).toBe(
|
||||
'Update your opencode.json plugin entry: "oh-my-opencode" → "oh-my-openagent"'
|
||||
)
|
||||
})
|
||||
|
||||
it("adds a warning for a version-pinned legacy entry", async () => {
|
||||
//#given
|
||||
mockGetPluginInfo.mockReturnValue({
|
||||
registered: true,
|
||||
entry: "oh-my-opencode@3.0.0",
|
||||
isPinned: true,
|
||||
pinnedVersion: "3.0.0",
|
||||
configPath: null,
|
||||
isLocalDev: false,
|
||||
})
|
||||
const { checkSystem } = await importFreshSystemModule()
|
||||
|
||||
//#when
|
||||
const result = await checkSystem()
|
||||
|
||||
//#then
|
||||
const legacyEntryIssue = result.issues.find((issue) => issue.title === "Using legacy package name")
|
||||
expect(legacyEntryIssue?.severity).toBe("warning")
|
||||
expect(legacyEntryIssue?.fix).toBe(
|
||||
'Update your opencode.json plugin entry: "oh-my-opencode@3.0.0" → "oh-my-openagent@3.0.0"'
|
||||
)
|
||||
})
|
||||
|
||||
it("does not warn for a canonical plugin entry", async () => {
|
||||
//#given
|
||||
mockGetPluginInfo.mockReturnValue({
|
||||
registered: true,
|
||||
entry: PLUGIN_NAME,
|
||||
isPinned: false,
|
||||
pinnedVersion: null,
|
||||
configPath: null,
|
||||
isLocalDev: false,
|
||||
})
|
||||
const { checkSystem } = await importFreshSystemModule()
|
||||
|
||||
//#when
|
||||
const result = await checkSystem()
|
||||
|
||||
//#then
|
||||
expect(result.issues.some((issue) => issue.title === "Using legacy package name")).toBe(false)
|
||||
})
|
||||
|
||||
it("does not warn for a local-dev legacy entry", async () => {
|
||||
//#given
|
||||
mockGetPluginInfo.mockReturnValue({
|
||||
registered: true,
|
||||
entry: "oh-my-opencode",
|
||||
isPinned: false,
|
||||
pinnedVersion: null,
|
||||
configPath: null,
|
||||
isLocalDev: true,
|
||||
})
|
||||
const { checkSystem } = await importFreshSystemModule()
|
||||
|
||||
//#when
|
||||
const result = await checkSystem()
|
||||
|
||||
//#then
|
||||
expect(result.issues.some((issue) => issue.title === "Using legacy package name")).toBe(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -83,18 +83,18 @@ export async function checkSystem(): Promise<CheckResult> {
|
||||
|
||||
if (!pluginInfo.registered) {
|
||||
issues.push({
|
||||
title: "oh-my-opencode is not registered",
|
||||
title: `${PLUGIN_NAME} is not registered`,
|
||||
description: "Plugin entry is missing from OpenCode configuration.",
|
||||
fix: "Run: bunx oh-my-opencode install",
|
||||
fix: `Run: bunx ${PLUGIN_NAME} install`,
|
||||
severity: "error",
|
||||
affects: ["all agents"],
|
||||
})
|
||||
}
|
||||
|
||||
// Detect legacy package name in plugin config
|
||||
if (pluginInfo.entry && !pluginInfo.isLocalDev) {
|
||||
const isLegacyName = pluginInfo.entry === LEGACY_PLUGIN_NAME
|
||||
|| pluginInfo.entry.startsWith(`${LEGACY_PLUGIN_NAME}@`)
|
||||
|
||||
if (isLegacyName) {
|
||||
const suggestedEntry = pluginInfo.entry.replace(LEGACY_PLUGIN_NAME, PLUGIN_NAME)
|
||||
issues.push({
|
||||
@@ -125,7 +125,7 @@ export async function checkSystem(): Promise<CheckResult> {
|
||||
issues.push({
|
||||
title: "Loaded plugin is outdated",
|
||||
description: `Loaded ${systemInfo.loadedVersion}, latest ${latestVersion}.`,
|
||||
fix: `Update: cd "${loadedInfo.cacheDir}" && bun add oh-my-opencode@${installTag}`,
|
||||
fix: `Update: cd "${loadedInfo.cacheDir}" && bun add ${PLUGIN_NAME}@${installTag}`,
|
||||
severity: "warning",
|
||||
affects: ["plugin features"],
|
||||
})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import color from "picocolors"
|
||||
import { PLUGIN_NAME } from "../../shared"
|
||||
|
||||
export const SYMBOLS = {
|
||||
check: color.green("\u2713"),
|
||||
@@ -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
|
||||
|
||||
@@ -113,10 +113,10 @@ describe("install CLI - binary check behavior", () => {
|
||||
const configPath = join(tempDir, "opencode.json")
|
||||
expect(existsSync(configPath)).toBe(true)
|
||||
|
||||
// then opencode.json should have plugin entry
|
||||
const config = JSON.parse(readFileSync(configPath, "utf-8"))
|
||||
expect(config.plugin).toBeDefined()
|
||||
expect(config.plugin.some((p: string) => p.includes("oh-my-opencode"))).toBe(true)
|
||||
expect(config.plugin.some((p: string) => p.includes("oh-my-openagent"))).toBe(true)
|
||||
expect(config.plugin.some((p: string) => p.includes("oh-my-opencode"))).toBe(false)
|
||||
|
||||
// then exit code should be 0 (success)
|
||||
expect(exitCode).toBe(0)
|
||||
|
||||
Reference in New Issue
Block a user