@@ -5,7 +5,14 @@ import type {
55 ModelListOutput ,
66 ProviderListOutput ,
77} from "@opencode-ai/client/promise"
8- import { directoryKey , normalizeAgentList , normalizePermissionRequest , normalizeProviderList } from "./utils"
8+ import {
9+ directoryKey ,
10+ enrichProject ,
11+ mergeProjectMeta ,
12+ normalizeAgentList ,
13+ normalizePermissionRequest ,
14+ normalizeProviderList ,
15+ } from "./utils"
916
1017describe ( "normalizeAgentList" , ( ) => {
1118 test ( "adapts current agents to the app agent shape" , ( ) => {
@@ -131,3 +138,86 @@ describe("directoryKey", () => {
131138 expect ( String ( directoryKey ( "/" ) ) ) . toBe ( "/" )
132139 } )
133140} )
141+
142+ type Base = {
143+ worktree : string
144+ name ?: string
145+ icon ?: { color ?: string ; override ?: string }
146+ commands ?: { start ?: string }
147+ }
148+
149+ describe ( "mergeProjectMeta" , ( ) => {
150+ test ( "returns base unchanged when there is no local projectMeta" , ( ) => {
151+ const base : Base = { worktree : "/repo" , name : "Repo" }
152+ expect ( mergeProjectMeta ( base , undefined ) ) . toBe ( base )
153+ } )
154+
155+ test ( "applies local name for projects without a server registration" , ( ) => {
156+ const base : Base = { worktree : "/repo" }
157+ expect ( mergeProjectMeta ( base , { name : "MicroservicesABC" } ) ) . toEqual ( {
158+ worktree : "/repo" ,
159+ name : "MicroservicesABC" ,
160+ } )
161+ } )
162+
163+ test ( "keeps server name when local projectMeta has no name" , ( ) => {
164+ const base : Base = { worktree : "/repo" , name : "SOOK" }
165+ expect ( mergeProjectMeta ( base , { icon : { color : "red" } } ) ) . toEqual ( {
166+ worktree : "/repo" ,
167+ name : "SOOK" ,
168+ icon : { color : "red" } ,
169+ } )
170+ } )
171+
172+ test ( "preserves an empty local name (display falls back to the folder name downstream)" , ( ) => {
173+ const base : Base = { worktree : "/repo" }
174+ expect ( mergeProjectMeta ( base , { name : "" } ) ) . toEqual ( { worktree : "/repo" , name : "" } )
175+ } )
176+
177+ test ( "merges icon and commands overrides" , ( ) => {
178+ const base : Base = { worktree : "/repo" , icon : { color : "blue" } , commands : { start : "" } }
179+ expect (
180+ mergeProjectMeta ( base , { icon : { color : "red" , override : "data:img" } , commands : { start : "bun dev" } } ) ,
181+ ) . toEqual ( {
182+ worktree : "/repo" ,
183+ icon : { color : "red" , override : "data:img" } ,
184+ commands : { start : "bun dev" } ,
185+ } )
186+ } )
187+ } )
188+
189+ describe ( "enrichProject" , ( ) => {
190+ test ( "applies the legacy icon override on top of projectMeta" , ( ) => {
191+ const base : Base = { worktree : "/repo" , name : "Repo" }
192+ expect ( enrichProject ( base , { name : "Renamed" , icon : { color : "red" } } , "data:legacy" , false ) ) . toEqual ( {
193+ worktree : "/repo" ,
194+ name : "Renamed" ,
195+ icon : { color : "red" , override : "data:legacy" } ,
196+ } )
197+ } )
198+
199+ test ( "returns merged base unchanged when there is no legacy icon" , ( ) => {
200+ const base : Base = { worktree : "/repo" }
201+ expect ( enrichProject ( base , { name : "Renamed" } , undefined , false ) ) . toEqual ( {
202+ worktree : "/repo" ,
203+ name : "Renamed" ,
204+ } )
205+ } )
206+
207+ test ( "ignores stale local projectMeta for projects with a server id" , ( ) => {
208+ const base : Base = { worktree : "/repo" , name : "opencode_configaaa" }
209+ expect ( enrichProject ( base , { name : "opencode_config" } , undefined , true ) ) . toEqual ( {
210+ worktree : "/repo" ,
211+ name : "opencode_configaaa" ,
212+ } )
213+ } )
214+
215+ test ( "still applies the legacy icon override for projects with a server id" , ( ) => {
216+ const base : Base = { worktree : "/repo" , name : "opencode_configaaa" }
217+ expect ( enrichProject ( base , { name : "opencode_config" } , "data:legacy" , true ) ) . toEqual ( {
218+ worktree : "/repo" ,
219+ name : "opencode_configaaa" ,
220+ icon : { override : "data:legacy" } ,
221+ } )
222+ } )
223+ } )
0 commit comments