11import { existsSync , readFileSync } from 'node:fs'
2- import { dirname , join , relative , sep } from 'node:path'
2+ import { join , relative , resolve , sep } from 'node:path'
33import { fail } from '../cli-error.js'
44import { printWarnings } from '../cli-support.js'
5+ import {
6+ type ProjectContext ,
7+ resolveProjectContext ,
8+ } from '../core/project-context.js'
59
610interface ValidationError {
711 file : string
@@ -28,27 +32,10 @@ function buildValidationFailure(
2832 return lines . join ( '\n' )
2933}
3034
31- function isInsideMonorepo ( root : string ) : boolean {
32- let dir = join ( root , '..' )
33- for ( let i = 0 ; i < 5 ; i ++ ) {
34- const parentPkg = join ( dir , 'package.json' )
35- if ( existsSync ( parentPkg ) ) {
36- try {
37- const parent = JSON . parse ( readFileSync ( parentPkg , 'utf8' ) )
38- return Array . isArray ( parent . workspaces ) || parent . workspaces ?. packages
39- } catch {
40- return false
41- }
42- }
43- const next = dirname ( dir )
44- if ( next === dir ) break
45- dir = next
46- }
47- return false
48- }
35+ function collectPackagingWarnings ( context : ProjectContext ) : Array < string > {
36+ if ( ! context . packageRoot || ! context . targetPackageJsonPath ) return [ ]
4937
50- function collectPackagingWarnings ( root : string ) : Array < string > {
51- const pkgJsonPath = join ( root , 'package.json' )
38+ const pkgJsonPath = context . targetPackageJsonPath
5239 if ( ! existsSync ( pkgJsonPath ) ) return [ ]
5340
5441 let pkgJson : Record < string , unknown >
@@ -81,9 +68,7 @@ function collectPackagingWarnings(root: string): Array<string> {
8168
8269 // In monorepos, _artifacts lives at repo root, not under packages —
8370 // the negation pattern is a no-op and shouldn't be added.
84- const isMonorepoPkg = isInsideMonorepo ( root )
85-
86- if ( ! isMonorepoPkg && ! files . includes ( '!skills/_artifacts' ) ) {
71+ if ( ! context . isMonorepo && ! files . includes ( '!skills/_artifacts' ) ) {
8772 warnings . push (
8873 '"!skills/_artifacts" is not in the "files" array — artifacts will be published unnecessarily' ,
8974 )
@@ -93,31 +78,17 @@ function collectPackagingWarnings(root: string): Array<string> {
9378 return warnings
9479}
9580
96- function resolvePackageRoot ( startDir : string ) : string {
97- let dir = startDir
98-
99- while ( true ) {
100- if ( existsSync ( join ( dir , 'package.json' ) ) ) {
101- return dir
102- }
103-
104- const next = dirname ( dir )
105- if ( next === dir ) {
106- return startDir
107- }
108-
109- dir = next
110- }
111- }
112-
11381export async function runValidateCommand ( dir ?: string ) : Promise < void > {
11482 const [ { parse : parseYaml } , { findSkillFiles } ] = await Promise . all ( [
11583 import ( 'yaml' ) ,
11684 import ( '../utils.js' ) ,
11785 ] )
11886 const targetDir = dir ?? 'skills'
119- const skillsDir = join ( process . cwd ( ) , targetDir )
120- const packageRoot = resolvePackageRoot ( skillsDir )
87+ const context = resolveProjectContext ( {
88+ cwd : process . cwd ( ) ,
89+ targetPath : targetDir ,
90+ } )
91+ const skillsDir = context . targetSkillsDir ?? resolve ( process . cwd ( ) , targetDir )
12192
12293 if ( ! existsSync ( skillsDir ) ) {
12394 fail ( `Skills directory not found: ${ skillsDir } ` )
@@ -197,8 +168,9 @@ export async function runValidateCommand(dir?: string): Promise<void> {
197168 }
198169 }
199170
171+ // In monorepos, _artifacts lives at the workspace root, not under each package's skills/ dir.
200172 const artifactsDir = join ( skillsDir , '_artifacts' )
201- if ( existsSync ( artifactsDir ) ) {
173+ if ( ! context . isMonorepo && existsSync ( artifactsDir ) ) {
202174 const requiredArtifacts = [
203175 'domain_map.yaml' ,
204176 'skill_spec.md' ,
@@ -238,7 +210,7 @@ export async function runValidateCommand(dir?: string): Promise<void> {
238210 }
239211 }
240212
241- const warnings = collectPackagingWarnings ( packageRoot )
213+ const warnings = collectPackagingWarnings ( context )
242214
243215 if ( errors . length > 0 ) {
244216 fail ( buildValidationFailure ( errors , warnings ) )
0 commit comments