@@ -35,6 +35,7 @@ async function inFakeHome(fn: (home: string) => Promise<void>): Promise<void> {
3535 HERMES_HOME : process . env . HERMES_HOME ,
3636 AUTOHAND_HOME : process . env . AUTOHAND_HOME ,
3737 GROK_HOME : process . env . GROK_HOME ,
38+ DSH_HOME : process . env . DSH_HOME ,
3839 APPDATA : process . env . APPDATA ,
3940 FLATPAK_XDG_CONFIG_HOME : process . env . FLATPAK_XDG_CONFIG_HOME ,
4041 } ;
@@ -50,6 +51,7 @@ async function inFakeHome(fn: (home: string) => Promise<void>): Promise<void> {
5051 "HERMES_HOME" ,
5152 "AUTOHAND_HOME" ,
5253 "GROK_HOME" ,
54+ "DSH_HOME" ,
5355 "APPDATA" ,
5456 "FLATPAK_XDG_CONFIG_HOME" ,
5557 ] ) {
@@ -79,7 +81,7 @@ test("agents: registry mirrors upstream agent list minus non-symlinkable agents"
7981 const ids = getAgentTargets ( ) . map ( ( agent ) => agent . id ) ;
8082 expect ( ids ) . toContain ( "universal" ) ;
8183 expect ( ids ) . toContain ( "universal-xdg" ) ;
82- expect ( getAgentTargets ( ) ) . toHaveLength ( 65 ) ;
84+ expect ( getAgentTargets ( ) ) . toHaveLength ( 68 ) ;
8385 // eve (no global dir, upstream forces direct writes) and promptscript (project-only)
8486 // cannot participate in global symlink fan-out
8587 expect ( ids ) . not . toContain ( "eve" ) ;
@@ -100,12 +102,13 @@ test("agents: expanded registry detects per-agent config dirs", async () => {
100102 await inFakeHome ( async ( home ) => {
101103 mkdirSync ( join ( home , ".roo" ) , { recursive : true } ) ;
102104 mkdirSync ( join ( home , ".trae" ) , { recursive : true } ) ;
105+ mkdirSync ( join ( home , ".traecli" ) , { recursive : true } ) ;
103106 mkdirSync ( join ( home , ".gemini" ) , { recursive : true } ) ;
104107 mkdirSync ( join ( home , ".codeium" , "windsurf" ) , { recursive : true } ) ;
105108 mkdirSync ( join ( home , ".snowflake" , "cortex" ) , { recursive : true } ) ;
106109
107110 const detected = detectInstalledAgents ( ) . map ( ( agent ) => agent . id ) ;
108- expect ( detected ) . toEqual ( [ "cortex" , "gemini-cli" , "roo" , "trae" , "windsurf" ] ) ;
111+ expect ( detected ) . toEqual ( [ "cortex" , "gemini-cli" , "roo" , "trae" , "trae-cli" , " windsurf"] ) ;
109112
110113 // skills dirs follow each agent's own convention
111114 const targets = getAgentTargets ( ) ;
@@ -118,6 +121,33 @@ test("agents: expanded registry detects per-agent config dirs", async () => {
118121 } ) ;
119122} ) ;
120123
124+ test ( "agents: WorkBuddy/Trae CLI/DSH use their official global skills dirs" , async ( ) => {
125+ await inFakeHome ( async ( home ) => {
126+ mkdirSync ( join ( home , ".workbuddy" ) , { recursive : true } ) ;
127+ mkdirSync ( join ( home , ".traecli" ) , { recursive : true } ) ;
128+ mkdirSync ( join ( home , ".dsh" ) , { recursive : true } ) ;
129+
130+ const detected = detectInstalledAgents ( ) ;
131+ expect ( detected . map ( ( agent ) => agent . id ) ) . toEqual ( [ "dsh" , "trae-cli" , "workbuddy" ] ) ;
132+ expect ( detected . find ( ( agent ) => agent . id === "workbuddy" ) ?. skillsDir ) . toBe (
133+ join ( home , ".workbuddy" , "skills" ) ,
134+ ) ;
135+ expect ( detected . find ( ( agent ) => agent . id === "trae-cli" ) ?. skillsDir ) . toBe (
136+ join ( home , ".traecli" , "skills" ) ,
137+ ) ;
138+ expect ( detected . find ( ( agent ) => agent . id === "dsh" ) ?. skillsDir ) . toBe (
139+ join ( home , ".dsh" , "skills" ) ,
140+ ) ;
141+
142+ seedCanonicalSkill ( "demo" ) ;
143+ const results = linkSkillToAgents ( "demo" ) ;
144+ expect ( results . map ( ( result ) => result . agent ) ) . toEqual ( [ "dsh" , "trae-cli" , "workbuddy" ] ) ;
145+ expect ( lstatSync ( join ( home , ".workbuddy" , "skills" , "demo" ) ) . isSymbolicLink ( ) ) . toBe ( true ) ;
146+ expect ( lstatSync ( join ( home , ".traecli" , "skills" , "demo" ) ) . isSymbolicLink ( ) ) . toBe ( true ) ;
147+ expect ( lstatSync ( join ( home , ".dsh" , "skills" , "demo" ) ) . isSymbolicLink ( ) ) . toBe ( true ) ;
148+ } ) ;
149+ } ) ;
150+
121151test ( "agents: shared-dir agents (Warp/Zed/Kimi/…) light up the universal target" , async ( ) => {
122152 await inFakeHome ( async ( home ) => {
123153 mkdirSync ( join ( home , ".warp" ) , { recursive : true } ) ;
@@ -165,18 +195,20 @@ test("agents: OpenClaw historical alias dirs are detected and link into the exis
165195 } ) ;
166196} ) ;
167197
168- test ( "agents: VIBE_HOME/HERMES_HOME/AUTOHAND_HOME/GROK_HOME relocate their agents" , async ( ) => {
198+ test ( "agents: VIBE_HOME/HERMES_HOME/AUTOHAND_HOME/GROK_HOME/DSH_HOME relocate their agents" , async ( ) => {
169199 await inFakeHome ( async ( home ) => {
170200 const customDirs = {
171201 "mistral-vibe" : join ( home , "custom-vibe" ) ,
172202 hermes : join ( home , "custom-hermes" ) ,
173203 "autohand-code" : join ( home , "custom-autohand" ) ,
174204 grok : join ( home , "custom-grok" ) ,
205+ dsh : join ( home , "custom-dsh" ) ,
175206 } ;
176207 process . env . VIBE_HOME = customDirs [ "mistral-vibe" ] ;
177208 process . env . HERMES_HOME = customDirs . hermes ;
178209 process . env . AUTOHAND_HOME = customDirs [ "autohand-code" ] ;
179210 process . env . GROK_HOME = customDirs . grok ;
211+ process . env . DSH_HOME = customDirs . dsh ;
180212 for ( const dir of Object . values ( customDirs ) ) {
181213 mkdirSync ( dir , { recursive : true } ) ;
182214 }
0 commit comments