1+ import path from 'node:path' ;
12import { describe , expect , it } from 'vitest' ;
23import { MANAGED_SECTION_BEGIN , MANAGED_SECTION_END , TARGETS } from './agent-targets.js' ;
34import type { OutputMode } from './output.js' ;
@@ -14,66 +15,78 @@ 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 = ( ) =>
4048 `# project\n${ MANAGED_SECTION_BEGIN } \n...skill...\n${ MANAGED_SECTION_END } \n` ;
41- expect ( isVerifySkillInstalled ( '/proj' , { existsSync, readFileSync } ) ) . toBe ( true ) ;
49+ expect ( isVerifySkillInstalled ( projDir , { existsSync, readFileSync } ) ) . toBe ( true ) ;
4250 } ) ;
4351
4452 it ( 'false when AGENTS.md has only the BEGIN sentinel without a complete managed section' , ( ) => {
45- const existsSync = ( p : string ) => p . endsWith ( 'AGENTS.md' ) ;
53+ const landing = path . join ( projDir , TARGETS . codex . path ) ;
54+ const existsSync = ( p : string ) => p === landing ;
4655 const readFileSync = ( ) => `# project\n${ MANAGED_SECTION_BEGIN } \n...partial skill...\n` ;
47- expect ( isVerifySkillInstalled ( '/proj' , { existsSync, readFileSync } ) ) . toBe ( false ) ;
56+ expect ( isVerifySkillInstalled ( projDir , { existsSync, readFileSync } ) ) . toBe ( false ) ;
4857 } ) ;
4958
5059 it ( 'false when only a bare AGENTS.md (no sentinel) exists' , ( ) => {
51- const existsSync = ( p : string ) => p . endsWith ( 'AGENTS.md' ) ;
60+ const landing = path . join ( projDir , TARGETS . codex . path ) ;
61+ const existsSync = ( p : string ) => p === landing ;
5262 const readFileSync = ( ) => '# my project\nNothing TestSprite here.\n' ;
53- expect ( isVerifySkillInstalled ( '/proj' , { existsSync, readFileSync } ) ) . toBe ( false ) ;
63+ expect ( isVerifySkillInstalled ( projDir , { existsSync, readFileSync } ) ) . toBe ( false ) ;
5464 } ) ;
5565
5666 it ( 'false when an unreadable AGENTS.md is the only candidate' , ( ) => {
57- const existsSync = ( p : string ) => p . endsWith ( 'AGENTS.md' ) ;
67+ const landing = path . join ( projDir , TARGETS . codex . path ) ;
68+ const existsSync = ( p : string ) => p === landing ;
5869 const readFileSync = ( ) => {
5970 throw new Error ( 'EACCES' ) ;
6071 } ;
61- expect ( isVerifySkillInstalled ( '/proj' , { existsSync, readFileSync } ) ) . toBe ( false ) ;
72+ expect ( isVerifySkillInstalled ( projDir , { existsSync, readFileSync } ) ) . toBe ( false ) ;
6273 } ) ;
6374
6475 it ( 'false when nothing is present' , ( ) => {
65- expect ( isVerifySkillInstalled ( '/proj' , { existsSync : ( ) => false } ) ) . toBe ( false ) ;
76+ expect ( isVerifySkillInstalled ( projDir , { existsSync : ( ) => false } ) ) . toBe ( false ) ;
6677 } ) ;
6778
6879 it ( 'checks paths under the supplied dir' , ( ) => {
80+ const root = path . resolve ( 'some' , 'proj' ) ;
6981 const seen : string [ ] = [ ] ;
70- isVerifySkillInstalled ( '/some/proj' , {
82+ isVerifySkillInstalled ( root , {
7183 existsSync : ( p : string ) => {
7284 seen . push ( p ) ;
7385 return false ;
7486 } ,
7587 } ) ;
76- expect ( seen . every ( p => p . startsWith ( '/some/proj' ) ) ) . toBe ( true ) ;
88+ const resolvedRoot = path . resolve ( root ) ;
89+ expect ( seen . every ( p => path . resolve ( p ) . startsWith ( resolvedRoot ) ) ) . toBe ( true ) ;
7790 // One probe per target landing path.
7891 expect ( seen ) . toHaveLength ( Object . keys ( TARGETS ) . length ) ;
7992 } ) ;
@@ -188,16 +201,18 @@ describe('maybeEmitSkillNudge', () => {
188201 } ) ;
189202
190203 it ( 'passes the cwd through to the presence check' , ( ) => {
204+ const cwd = path . resolve ( 'work' , 'here' ) ;
191205 const probed : string [ ] = [ ] ;
192206 const { ctx } = makeCtx ( {
193- cwd : '/work/here' ,
207+ cwd,
194208 existsSync : ( p : string ) => {
195209 probed . push ( p ) ;
196210 return false ;
197211 } ,
198212 } ) ;
199213 maybeEmitSkillNudge ( ctx ) ;
200214 expect ( probed . length ) . toBeGreaterThan ( 0 ) ;
201- expect ( probed . every ( p => p . startsWith ( '/work/here' ) ) ) . toBe ( true ) ;
215+ const resolvedCwd = path . resolve ( cwd ) ;
216+ expect ( probed . every ( p => path . resolve ( p ) . startsWith ( resolvedCwd ) ) ) . toBe ( true ) ;
202217 } ) ;
203218} ) ;
0 commit comments