Skip to content

Commit 2f0cd8c

Browse files
committed
fix: update schema URLs to use fork repository
- Update config-manager.ts to generate fork schema URL - Update build-schema.ts to use fork URL - Update schema.json with fork URL
1 parent a1eb223 commit 2f0cd8c

File tree

7 files changed

+46
-120
lines changed

7 files changed

+46
-120
lines changed

assets/oh-my-opencode.schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "http://json-schema.org/draft-07/schema#",
3-
"$id": "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json",
3+
"$id": "https://raw.githubusercontent.com/ReinaMacCredy/oh-my-opencode/main/assets/oh-my-opencode.schema.json",
44
"title": "Oh My OpenCode Configuration",
55
"description": "Configuration schema for oh-my-opencode plugin",
66
"type": "object",

bun.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
"@openauthjs/openauth": "^0.4.3",
6969
"@opencode-ai/plugin": "^1.1.1",
7070
"@opencode-ai/sdk": "^1.1.1",
71+
"@reinamaccredy/oh-my-opencode": "^3.0.0-beta.13",
7172
"commander": "^14.0.2",
7273
"hono": "^4.10.4",
7374
"js-yaml": "^4.1.1",

script/build-schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ async function main() {
1414

1515
const finalSchema = {
1616
$schema: "http://json-schema.org/draft-07/schema#",
17-
$id: "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json",
17+
$id: "https://raw.githubusercontent.com/ReinaMacCredy/oh-my-opencode/main/assets/oh-my-opencode.schema.json",
1818
title: "Oh My OpenCode Configuration",
1919
description: "Configuration schema for oh-my-opencode plugin",
2020
...jsonSchema,

src/cli/config-manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ function deepMerge<T extends Record<string, unknown>>(target: T, source: Partial
264264

265265
export function generateOmoConfig(installConfig: InstallConfig): Record<string, unknown> {
266266
const config: Record<string, unknown> = {
267-
$schema: "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json",
267+
$schema: "https://raw.githubusercontent.com/ReinaMacCredy/oh-my-opencode/main/assets/oh-my-opencode.schema.json",
268268
}
269269

270270
if (installConfig.hasProxyPal || installConfig.hasGemini) {

src/shared/migration.test.ts

Lines changed: 34 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,8 @@ describe("migration maps", () => {
252252
})
253253

254254
describe("migrateAgentConfigToCategory", () => {
255-
test("migrates model to category when mapping exists", () => {
256-
// #given: Config with a model that has a category mapping
255+
test("does not migrate proxypal models (installer-generated)", () => {
256+
// #given: Config with proxypal model (set by installer, should not be migrated)
257257
const config = {
258258
model: "proxypal/gemini-3-pro-preview",
259259
temperature: 0.5,
@@ -263,12 +263,9 @@ describe("migrateAgentConfigToCategory", () => {
263263
// #when: Migrate agent config to category
264264
const { migrated, changed } = migrateAgentConfigToCategory(config)
265265

266-
// #then: Model should be replaced with category
267-
expect(changed).toBe(true)
268-
expect(migrated.category).toBe("visual-engineering")
269-
expect(migrated.model).toBeUndefined()
270-
expect(migrated.temperature).toBe(0.5)
271-
expect(migrated.top_p).toBe(0.9)
266+
// #then: Config should remain unchanged (proxypal models not in migration map)
267+
expect(changed).toBe(false)
268+
expect(migrated).toEqual(config)
272269
})
273270

274271
test("does not migrate when model is not in map", () => {
@@ -301,8 +298,8 @@ describe("migrateAgentConfigToCategory", () => {
301298
expect(migrated).toEqual(config)
302299
})
303300

304-
test("handles all mapped models correctly", () => {
305-
// #given: Configs for each mapped model (using proxypal/ prefix)
301+
test("proxypal models are not migrated to categories", () => {
302+
// #given: Configs with proxypal models (intentionally set by installer)
306303
const configs = [
307304
{ model: "proxypal/gemini-3-pro-preview" },
308305
{ model: "proxypal/gpt-5.2-codex" },
@@ -311,21 +308,18 @@ describe("migrateAgentConfigToCategory", () => {
311308
{ model: "proxypal/gemini-claude-sonnet-4-5-thinking" },
312309
]
313310

314-
const expectedCategories = ["visual-engineering", "ultrabrain", "quick", "most-capable", "general"]
315-
316311
// #when: Migrate each config
317312
const results = configs.map(migrateAgentConfigToCategory)
318313

319-
// #then: Each model should map to correct category
314+
// #then: None should be migrated (MODEL_TO_CATEGORY_MAP is empty to prevent backup loop)
320315
results.forEach((result, index) => {
321-
expect(result.changed).toBe(true)
322-
expect(result.migrated.category).toBe(expectedCategories[index])
323-
expect(result.migrated.model).toBeUndefined()
316+
expect(result.changed).toBe(false)
317+
expect(result.migrated).toEqual(configs[index])
324318
})
325319
})
326320

327-
test("preserves non-model fields during migration", () => {
328-
// #given: Config with multiple fields
321+
test("preserves all fields when no migration needed", () => {
322+
// #given: Config with multiple fields and proxypal model
329323
const config = {
330324
model: "proxypal/gpt-5.2-codex",
331325
temperature: 0.1,
@@ -335,14 +329,11 @@ describe("migrateAgentConfigToCategory", () => {
335329
}
336330

337331
// #when: Migrate agent config to category
338-
const { migrated } = migrateAgentConfigToCategory(config)
332+
const { migrated, changed } = migrateAgentConfigToCategory(config)
339333

340-
// #then: All non-model fields should be preserved
341-
expect(migrated.category).toBe("ultrabrain")
342-
expect(migrated.temperature).toBe(0.1)
343-
expect(migrated.top_p).toBe(0.95)
344-
expect(migrated.maxTokens).toBe(4096)
345-
expect(migrated.prompt_append).toBe("custom instruction")
334+
// #then: All fields should be preserved unchanged
335+
expect(changed).toBe(false)
336+
expect(migrated).toEqual(config)
346337
})
347338
})
348339

@@ -460,13 +451,13 @@ describe("migrateConfigFile with backup", () => {
460451
})
461452
})
462453

463-
test("creates backup file with timestamp when migration needed", () => {
464-
// #given: Config file path and config needing migration
454+
test("creates backup file when agent name migration needed", () => {
455+
// #given: Config file with legacy agent name needing migration
465456
const testConfigPath = "/tmp/test-config-migration.json"
466-
const testConfigContent = globalThis.JSON.stringify({ agents: { oracle: { model: "proxypal/gpt-5.2-codex" } } }, null, 2)
457+
const testConfigContent = globalThis.JSON.stringify({ agents: { omo: { model: "anthropic/claude-opus-4-5" } } }, null, 2)
467458
const rawConfig: Record<string, unknown> = {
468459
agents: {
469-
oracle: { model: "proxypal/gpt-5.2-codex" },
460+
omo: { model: "anthropic/claude-opus-4-5" },
470461
},
471462
}
472463

@@ -495,70 +486,29 @@ describe("migrateConfigFile with backup", () => {
495486
expect(backupContent).toBe(testConfigContent)
496487
})
497488

498-
test("deletes agent config when all fields match category defaults", () => {
499-
// #given: Config with agent matching category defaults
500-
const testConfigPath = "/tmp/test-config-delete.json"
501-
const rawConfig: Record<string, unknown> = {
502-
agents: {
503-
oracle: {
504-
model: "proxypal/gpt-5.2-codex",
505-
temperature: 0.1,
506-
},
507-
},
508-
}
509-
510-
fs.writeFileSync(testConfigPath, globalThis.JSON.stringify({ agents: { oracle: { model: "proxypal/gpt-5.2-codex" } } }, null, 2))
511-
cleanupPaths.push(testConfigPath)
512-
513-
// #when: Migrate config file
514-
const needsWrite = migrateConfigFile(testConfigPath, rawConfig)
515-
516-
// #then: Agent should be deleted (matches strategic category defaults)
517-
expect(needsWrite).toBe(true)
518-
519-
const migratedConfig = JSON.parse(fs.readFileSync(testConfigPath, "utf-8"))
520-
expect(migratedConfig.agents).toEqual({})
521-
522-
const dir = path.dirname(testConfigPath)
523-
const basename = path.basename(testConfigPath)
524-
const files = fs.readdirSync(dir)
525-
const backupFiles = files.filter((f) => f.startsWith(`${basename}.bak.`))
526-
backupFiles.forEach((f) => cleanupPaths.push(path.join(dir, f)))
527-
})
528-
529-
test("keeps agent config with category when fields differ from defaults", () => {
530-
// #given: Config with agent having custom temperature override
531-
const testConfigPath = "/tmp/test-config-keep.json"
489+
test("does not migrate proxypal models (prevents backup loop)", () => {
490+
// #given: Config with proxypal model (set by installer)
491+
const testConfigPath = "/tmp/test-config-proxypal.json"
532492
const rawConfig: Record<string, unknown> = {
533493
agents: {
534-
oracle: {
535-
model: "proxypal/gpt-5.2-codex",
536-
temperature: 0.5,
537-
},
494+
oracle: { model: "proxypal/gpt-5.2-codex" },
538495
},
539496
}
540497

541-
fs.writeFileSync(testConfigPath, globalThis.JSON.stringify({ agents: { oracle: { model: "proxypal/gpt-5.2-codex" } } }, null, 2))
498+
fs.writeFileSync(testConfigPath, globalThis.JSON.stringify(rawConfig, null, 2))
542499
cleanupPaths.push(testConfigPath)
543500

544501
// #when: Migrate config file
545502
const needsWrite = migrateConfigFile(testConfigPath, rawConfig)
546503

547-
// #then: Agent should be kept with category and custom override
548-
expect(needsWrite).toBe(true)
549-
550-
const migratedConfig = JSON.parse(fs.readFileSync(testConfigPath, "utf-8"))
551-
const agents = migratedConfig.agents as Record<string, unknown>
552-
expect(agents.oracle).toBeDefined()
553-
expect((agents.oracle as Record<string, unknown>).category).toBe("ultrabrain")
554-
expect((agents.oracle as Record<string, unknown>).temperature).toBe(0.5)
555-
expect((agents.oracle as Record<string, unknown>).model).toBeUndefined()
504+
// #then: No migration should occur (prevents backup file loop)
505+
expect(needsWrite).toBe(false)
556506

557507
const dir = path.dirname(testConfigPath)
558508
const basename = path.basename(testConfigPath)
559509
const files = fs.readdirSync(dir)
560510
const backupFiles = files.filter((f) => f.startsWith(`${basename}.bak.`))
561-
backupFiles.forEach((f) => cleanupPaths.push(path.join(dir, f)))
511+
expect(backupFiles.length).toBe(0)
562512
})
563513

564514
test("does not write when no migration needed", () => {
@@ -586,8 +536,8 @@ describe("migrateConfigFile with backup", () => {
586536
expect(backupFiles.length).toBe(0)
587537
})
588538

589-
test("handles multiple agent migrations correctly", () => {
590-
// #given: Config with multiple agents needing migration (proxypal models)
539+
test("multiple proxypal agents do not trigger migration", () => {
540+
// #given: Config with multiple proxypal models (all set by installer)
591541
const testConfigPath = "/tmp/test-config-multi-agent.json"
592542
const rawConfig: Record<string, unknown> = {
593543
agents: {
@@ -600,43 +550,20 @@ describe("migrateConfigFile with backup", () => {
600550
},
601551
}
602552

603-
fs.writeFileSync(
604-
testConfigPath,
605-
globalThis.JSON.stringify(
606-
{
607-
agents: {
608-
oracle: { model: "proxypal/gpt-5.2-codex" },
609-
librarian: { model: "proxypal/gemini-claude-sonnet-4-5-thinking" },
610-
frontend: { model: "proxypal/gemini-3-pro-preview" },
611-
},
612-
},
613-
null,
614-
2,
615-
),
616-
)
553+
fs.writeFileSync(testConfigPath, globalThis.JSON.stringify(rawConfig, null, 2))
617554
cleanupPaths.push(testConfigPath)
618555

619556
// #when: Migrate config file
620557
const needsWrite = migrateConfigFile(testConfigPath, rawConfig)
621558

622-
// #then: Should migrate correctly
623-
expect(needsWrite).toBe(true)
624-
625-
const migratedConfig = JSON.parse(fs.readFileSync(testConfigPath, "utf-8"))
626-
const agents = migratedConfig.agents as Record<string, unknown>
627-
628-
expect(agents.oracle).toBeUndefined()
629-
expect(agents.librarian).toBeUndefined()
630-
631-
expect(agents.frontend).toBeDefined()
632-
expect((agents.frontend as Record<string, unknown>).category).toBe("visual-engineering")
633-
expect((agents.frontend as Record<string, unknown>).temperature).toBe(0.9)
559+
// #then: No migration should occur
560+
expect(needsWrite).toBe(false)
634561

635562
const dir = path.dirname(testConfigPath)
636563
const basename = path.basename(testConfigPath)
637564
const files = fs.readdirSync(dir)
638565
const backupFiles = files.filter((f) => f.startsWith(`${basename}.bak.`))
639-
backupFiles.forEach((f) => cleanupPaths.push(path.join(dir, f)))
566+
expect(backupFiles.length).toBe(0)
640567
})
641568
})
642569

src/shared/migration.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,11 @@ export const GOOGLE_TO_PROXYPAL_MODEL_MAP: Record<string, string> = {
4040
"google/gemini-3-pro-low": "proxypal/gemini-3-pro-preview",
4141
}
4242

43-
// Model to category mapping for auto-migration
44-
// NOTE: This fork uses proxypal/ prefix instead of google/ for Gemini models.
45-
// When merging from upstream, replace google/gemini-* with proxypal/gemini-* equivalents.
46-
export const MODEL_TO_CATEGORY_MAP: Record<string, string> = {
47-
"proxypal/gemini-3-pro-preview": "visual-engineering",
48-
"proxypal/gpt-5.2-codex": "ultrabrain",
49-
"proxypal/gemini-3-flash-preview": "quick",
50-
"proxypal/gemini-claude-opus-4-5-thinking": "most-capable",
51-
"proxypal/gemini-claude-sonnet-4-5-thinking": "general",
52-
}
43+
/**
44+
* LEGACY model to category mapping - only for deprecated models needing migration.
45+
* WARNING: Do NOT add installer-generated models (proxypal/*) - causes backup loop.
46+
*/
47+
export const MODEL_TO_CATEGORY_MAP: Record<string, string> = {}
5348

5449
export function migrateGoogleToProxypalModel(model: string): { migrated: string; changed: boolean } {
5550
const proxypalModel = GOOGLE_TO_PROXYPAL_MODEL_MAP[model]

0 commit comments

Comments
 (0)