fix: guard install path + robust frontmatter parsing (#47) (#54)

Reapplies @MatrixNeoKozak's PR #47 onto current main (resolves the
bin/cli.mjs conflict with the star-nudge changes):
- resolve() the install target and refuse system-critical dirs
  (/, /usr, /etc, /root, ...) so a typo'd --target can't clobber the system
- skillcheck frontmatter parser tolerates leading whitespace and CRLF/LF



Claude-Session: https://claude.ai/code/session_016JWn5jRD5tcEFKrubjQ6Px

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: MatrixNeoKozak <MatrixNeoKozak@users.noreply.github.com>
This commit is contained in:
mohitagw15856
2026-06-18 20:43:45 +01:00
committed by GitHub
parent 83bfff4f2f
commit 66249df30b
2 changed files with 14 additions and 4 deletions
+10 -2
View File
@@ -13,7 +13,7 @@
// --link symlink instead of copy (native agents; falls back to copy)
// --dry-run print what would happen without writing
import { readdirSync, existsSync, mkdirSync, rmSync, cpSync, symlinkSync, copyFileSync, statSync } from 'node:fs';
import { join, dirname, basename } from 'node:path';
import { join, dirname, basename, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { homedir } from 'node:os';
import { createRequire } from 'node:module';
@@ -79,7 +79,15 @@ function add(opts) {
}
const skillsDir = join(PKG_ROOT, 'skills');
if (!existsSync(skillsDir)) { console.error(`Error: bundled skills/ not found at ${skillsDir}.`); process.exit(1); }
const target = opts.target || defaultTarget(agent);
const target = resolve(opts.target || defaultTarget(agent));
// Guard against installing into system-critical directories (e.g. a typo'd --target).
const criticalPaths = ['/', '/usr', '/bin', '/etc', '/var', '/root', '/boot', '/proc', '/sys', '/dev'];
if (criticalPaths.includes(target)) {
console.error(`Error: Cannot install into a system-critical directory: ${target}`);
process.exit(1);
}
let count = 0;
console.log(`${opts.dryRun ? '[dry-run] ' : ''}Installing for '${agent}' into ${target}`);