Skip to content

Commit 732bcaa

Browse files
authored
fix: correct skills directory path resolution in getSkillsDir (#79)
* fix: correct skills directory path resolution in getSkillsDir The path walked up 3 levels assuming dist/src/commands/ structure, but tsconfig rootDir strips the src/ prefix, producing dist/commands/. This caused ENOENT when running install-skill. * refactor: add getPackageRoot() to replace fragile path traversals Walks up to package.json instead of counting '../' segments from compiled output. Prevents path resolution from silently breaking when tsconfig output structure changes.
1 parent b9f1b3f commit 732bcaa

3 files changed

Lines changed: 23 additions & 10 deletions

File tree

src/commands/install-skill.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { homedir } from 'os';
2-
import { join, dirname } from 'path';
2+
import { join } from 'path';
33
import { existsSync } from 'fs';
44
import { mkdir, copyFile, readdir } from 'fs/promises';
5-
import { fileURLToPath } from 'url';
65
import chalk from 'chalk';
6+
import { getPackageRoot } from '../utils/paths.js';
77

88
export interface AgentConfig {
99
name: string;
@@ -48,9 +48,7 @@ export interface InstallSkillOptions {
4848
}
4949

5050
export function getSkillsDir(): string {
51-
const currentFile = fileURLToPath(import.meta.url);
52-
// From dist/src/commands/install-skill.js -> skills/
53-
return join(dirname(currentFile), '..', '..', '..', 'skills');
51+
return join(getPackageRoot(import.meta.url), 'skills');
5452
}
5553

5654
export async function discoverSkills(skillsDir: string): Promise<string[]> {

src/lib/agent-interface.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import path from 'path';
7-
import { fileURLToPath } from 'url';
7+
import { getPackageRoot } from '../utils/paths.js';
88
import { debug, logInfo, logWarn, logError, initLogFile, getLogFilePath } from '../utils/debug.js';
99
import type { InstallerOptions } from '../utils/types.js';
1010
import { analytics } from '../utils/analytics.js';
@@ -577,10 +577,7 @@ export async function runAgent(
577577
};
578578

579579
// Load plugin with bundled skills
580-
// Path from dist/lib/ back to package root
581-
const __filename = fileURLToPath(import.meta.url);
582-
const __dirname = path.dirname(__filename);
583-
const pluginPath = path.join(__dirname, '../..');
580+
const pluginPath = getPackageRoot(import.meta.url);
584581
logInfo('Loading plugin from:', pluginPath);
585582

586583
const response = query({

src/utils/paths.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { dirname, join } from 'path';
2+
import { existsSync } from 'fs';
3+
import { fileURLToPath } from 'url';
4+
5+
/**
6+
* Resolve the package root by walking up from a compiled file until we find package.json.
7+
* Immune to changes in tsconfig outDir/rootDir structure.
8+
*/
9+
export function getPackageRoot(metaUrl: string): string {
10+
let dir = dirname(fileURLToPath(metaUrl));
11+
while (dir !== dirname(dir)) {
12+
if (existsSync(join(dir, 'package.json'))) {
13+
return dir;
14+
}
15+
dir = dirname(dir);
16+
}
17+
throw new Error('Could not find package root (no package.json found in parent directories)');
18+
}

0 commit comments

Comments
 (0)