Skip to content

Commit e79daac

Browse files
committed
fix: Resolve relative paths from cwd instead of git root
The linter was resolving relative paths from the git repository root instead of the current working directory, causing relative paths like '../skills/ui5-best-practices' to fail. Changed both resolveSkillPaths() and validateSkillPath() to: 1. Resolve paths from process.cwd() (for relative paths) 2. Use git root only for workspace boundary validation This matches standard CLI tool behavior where relative paths are resolved from the user's current directory. Fixes: - 'npm test && node bin/skill-lint.js lint ../skills/ui5-best-practices' - Multi-skill mode: 'node bin/skill-lint.js lint ../skills/' - All relative path scenarios Absolute paths continue to work as before.
1 parent 5c473d5 commit e79daac

1 file changed

Lines changed: 12 additions & 5 deletions

File tree

  • plugins/ui5/skill-lint/src/cli/commands

plugins/ui5/skill-lint/src/cli/commands/lint.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,20 @@ async function resolveSkillPaths(skillPath: string): Promise<string[]> {
119119
throw new Error(`Invalid skill path: ${error instanceof Error ? error.message : String(error)}`);
120120
}
121121

122-
const workspaceRoot = await findGitRoot() || process.cwd();
123-
const resolved = resolve(workspaceRoot, sanitized);
122+
// Resolve from cwd (for relative paths) or as-is (for absolute paths)
123+
const resolved = resolve(process.cwd(), sanitized);
124124

125125
if (!existsSync(resolved)) {
126126
throw new Error(`Skill path does not exist: ${skillPath}`);
127127
}
128128

129+
// Validate that resolved path is within workspace
130+
const workspaceRoot = await findGitRoot() || process.cwd();
131+
const rel = relative(workspaceRoot, resolved);
132+
if (rel.startsWith('..') || isAbsolute(rel)) {
133+
throw new Error(`Skill path must be within workspace: ${skillPath}`);
134+
}
135+
129136
// If it's a file, treat as single skill
130137
const stats = await stat(resolved);
131138
if (stats.isFile()) {
@@ -173,9 +180,8 @@ async function validateSkillPath(skillPath: string): Promise<string> {
173180
throw new Error(`Invalid skill path: ${error instanceof Error ? error.message : String(error)}`);
174181
}
175182

176-
// Use git root as workspace root if available, otherwise cwd
177-
const workspaceRoot = await findGitRoot() || process.cwd();
178-
const resolved = resolve(workspaceRoot, sanitized);
183+
// Resolve from cwd (for relative paths) or as-is (for absolute paths)
184+
const resolved = resolve(process.cwd(), sanitized);
179185

180186
// Check if path exists
181187
if (!existsSync(resolved)) {
@@ -191,6 +197,7 @@ async function validateSkillPath(skillPath: string): Promise<string> {
191197
}
192198

193199
// Ensure path is within workspace (prevents path traversal)
200+
const workspaceRoot = await findGitRoot() || process.cwd();
194201
const rel = relative(workspaceRoot, realPath);
195202
if (rel.startsWith('..') || isAbsolute(rel)) {
196203
throw new Error(`Skill path must be within workspace: ${skillPath}`);

0 commit comments

Comments
 (0)