@@ -252,8 +252,8 @@ describe("migration maps", () => {
252252} )
253253
254254describe ( "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
0 commit comments