1+ import path from 'node:path' ;
12import { describe , expect , it } from 'vitest' ;
23import { MANAGED_SECTION_BEGIN , TARGETS } from './agent-targets.js' ;
34import type { OutputMode } from './output.js' ;
@@ -14,59 +15,70 @@ import {
1415// ---------------------------------------------------------------------------
1516
1617describe ( 'isVerifySkillInstalled' , ( ) => {
18+ const projDir = path . resolve ( 'proj' ) ;
19+
1720 it ( 'true when the claude own-file SKILL.md exists' , ( ) => {
18- const existsSync = ( p : string ) => p . endsWith ( '.claude/skills/testsprite-verify/SKILL.md' ) ;
19- expect ( isVerifySkillInstalled ( '/proj' , { existsSync } ) ) . toBe ( true ) ;
21+ const landing = path . join ( projDir , TARGETS . claude . path ) ;
22+ const existsSync = ( p : string ) => p === landing ;
23+ expect ( isVerifySkillInstalled ( projDir , { existsSync } ) ) . toBe ( true ) ;
2024 } ) ;
2125
2226 it ( 'true for the cursor .mdc landing file' , ( ) => {
23- const existsSync = ( p : string ) => p . endsWith ( '.cursor/rules/testsprite-verify.mdc' ) ;
24- expect ( isVerifySkillInstalled ( '/proj' , { existsSync } ) ) . toBe ( true ) ;
27+ const landing = path . join ( projDir , TARGETS . cursor . path ) ;
28+ const existsSync = ( p : string ) => p === landing ;
29+ expect ( isVerifySkillInstalled ( projDir , { existsSync } ) ) . toBe ( true ) ;
2530 } ) ;
2631
2732 it ( 'true for the cline landing file' , ( ) => {
28- const existsSync = ( p : string ) => p . endsWith ( '.clinerules/testsprite-verify.md' ) ;
29- expect ( isVerifySkillInstalled ( '/proj' , { existsSync } ) ) . toBe ( true ) ;
33+ const landing = path . join ( projDir , TARGETS . cline . path ) ;
34+ const existsSync = ( p : string ) => p === landing ;
35+ expect ( isVerifySkillInstalled ( projDir , { existsSync } ) ) . toBe ( true ) ;
3036 } ) ;
3137
3238 it ( 'true for the antigravity landing file' , ( ) => {
33- const existsSync = ( p : string ) => p . endsWith ( '.agents/skills/testsprite-verify/SKILL.md' ) ;
34- expect ( isVerifySkillInstalled ( '/proj' , { existsSync } ) ) . toBe ( true ) ;
39+ const landing = path . join ( projDir , TARGETS . antigravity . path ) ;
40+ const existsSync = ( p : string ) => p === landing ;
41+ expect ( isVerifySkillInstalled ( projDir , { existsSync } ) ) . toBe ( true ) ;
3542 } ) ;
3643
3744 it ( 'true when AGENTS.md exists AND carries our BEGIN sentinel' , ( ) => {
38- const existsSync = ( p : string ) => p . endsWith ( 'AGENTS.md' ) ;
45+ const landing = path . join ( projDir , TARGETS . codex . path ) ;
46+ const existsSync = ( p : string ) => p === landing ;
3947 const readFileSync = ( ) => `# project\n${ MANAGED_SECTION_BEGIN } \n...skill...\n` ;
40- expect ( isVerifySkillInstalled ( '/proj' , { existsSync, readFileSync } ) ) . toBe ( true ) ;
48+ expect ( isVerifySkillInstalled ( projDir , { existsSync, readFileSync } ) ) . toBe ( true ) ;
4149 } ) ;
4250
4351 it ( 'false when only a bare AGENTS.md (no sentinel) exists' , ( ) => {
44- const existsSync = ( p : string ) => p . endsWith ( 'AGENTS.md' ) ;
52+ const landing = path . join ( projDir , TARGETS . codex . path ) ;
53+ const existsSync = ( p : string ) => p === landing ;
4554 const readFileSync = ( ) => '# my project\nNothing TestSprite here.\n' ;
46- expect ( isVerifySkillInstalled ( '/proj' , { existsSync, readFileSync } ) ) . toBe ( false ) ;
55+ expect ( isVerifySkillInstalled ( projDir , { existsSync, readFileSync } ) ) . toBe ( false ) ;
4756 } ) ;
4857
4958 it ( 'false when an unreadable AGENTS.md is the only candidate' , ( ) => {
50- const existsSync = ( p : string ) => p . endsWith ( 'AGENTS.md' ) ;
59+ const landing = path . join ( projDir , TARGETS . codex . path ) ;
60+ const existsSync = ( p : string ) => p === landing ;
5161 const readFileSync = ( ) => {
5262 throw new Error ( 'EACCES' ) ;
5363 } ;
54- expect ( isVerifySkillInstalled ( '/proj' , { existsSync, readFileSync } ) ) . toBe ( false ) ;
64+ expect ( isVerifySkillInstalled ( projDir , { existsSync, readFileSync } ) ) . toBe ( false ) ;
5565 } ) ;
5666
5767 it ( 'false when nothing is present' , ( ) => {
58- expect ( isVerifySkillInstalled ( '/proj' , { existsSync : ( ) => false } ) ) . toBe ( false ) ;
68+ expect ( isVerifySkillInstalled ( projDir , { existsSync : ( ) => false } ) ) . toBe ( false ) ;
5969 } ) ;
6070
6171 it ( 'checks paths under the supplied dir' , ( ) => {
72+ const root = path . resolve ( 'some' , 'proj' ) ;
6273 const seen : string [ ] = [ ] ;
63- isVerifySkillInstalled ( '/some/proj' , {
74+ isVerifySkillInstalled ( root , {
6475 existsSync : ( p : string ) => {
6576 seen . push ( p ) ;
6677 return false ;
6778 } ,
6879 } ) ;
69- expect ( seen . every ( p => p . startsWith ( '/some/proj' ) ) ) . toBe ( true ) ;
80+ const resolvedRoot = path . resolve ( root ) ;
81+ expect ( seen . every ( p => path . resolve ( p ) . startsWith ( resolvedRoot ) ) ) . toBe ( true ) ;
7082 // One probe per target landing path.
7183 expect ( seen ) . toHaveLength ( Object . keys ( TARGETS ) . length ) ;
7284 } ) ;
@@ -181,16 +193,18 @@ describe('maybeEmitSkillNudge', () => {
181193 } ) ;
182194
183195 it ( 'passes the cwd through to the presence check' , ( ) => {
196+ const cwd = path . resolve ( 'work' , 'here' ) ;
184197 const probed : string [ ] = [ ] ;
185198 const { ctx } = makeCtx ( {
186- cwd : '/work/here' ,
199+ cwd,
187200 existsSync : ( p : string ) => {
188201 probed . push ( p ) ;
189202 return false ;
190203 } ,
191204 } ) ;
192205 maybeEmitSkillNudge ( ctx ) ;
193206 expect ( probed . length ) . toBeGreaterThan ( 0 ) ;
194- expect ( probed . every ( p => p . startsWith ( '/work/here' ) ) ) . toBe ( true ) ;
207+ const resolvedCwd = path . resolve ( cwd ) ;
208+ expect ( probed . every ( p => path . resolve ( p ) . startsWith ( resolvedCwd ) ) ) . toBe ( true ) ;
195209 } ) ;
196210} ) ;
0 commit comments