-
Notifications
You must be signed in to change notification settings - Fork 0
feat(skills): add skill-list, skill-install, skill-update CLI commands #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,197 @@ | ||||||
| /** | ||||||
| * Skills — List, install, and update CLI skills | ||||||
| */ | ||||||
|
|
||||||
| import fs from 'node:fs'; | ||||||
| import path from 'node:path'; | ||||||
| import os from 'node:os'; | ||||||
|
|
||||||
| import { output, error, rethrowCliSignals } from './core.js'; | ||||||
| import { extractFrontmatter } from './frontmatter.js'; | ||||||
|
|
||||||
| // ─── Constants ─────────────────────────────────────────────────────────────── | ||||||
|
|
||||||
| /** Skills installed by MAXSIM (not user-created). */ | ||||||
| const BUILT_IN_SKILLS = [ | ||||||
| 'tdd', | ||||||
| 'systematic-debugging', | ||||||
| 'verification-before-completion', | ||||||
| 'code-review', | ||||||
| 'simplify', | ||||||
| 'memory-management', | ||||||
| 'using-maxsim', | ||||||
| 'batch-execution', | ||||||
| 'subagent-driven-development', | ||||||
| 'writing-plans', | ||||||
| ] as const; | ||||||
|
Comment on lines
+14
to
+26
|
||||||
|
|
||||||
| /** Installed skills directory under the Claude config. */ | ||||||
| function skillsDir(): string { | ||||||
| return path.join(os.homedir(), '.claude', 'agents', 'skills'); | ||||||
| } | ||||||
|
Comment on lines
+28
to
+31
|
||||||
|
|
||||||
| /** Bundled skills directory inside the npm package. */ | ||||||
| function bundledSkillsDir(): string { | ||||||
| return path.resolve(__dirname, 'assets', 'templates', 'skills'); | ||||||
|
||||||
| return path.resolve(__dirname, 'assets', 'templates', 'skills'); | |
| return path.resolve(__dirname, '..', 'assets', 'templates', 'skills'); |
Copilot
AI
Mar 2, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
skillName is used directly in path.join() for both the bundle source and destination paths. Because path.join() will accept .. segments and absolute paths, a crafted skillName could read from / write to unintended filesystem locations (path traversal / arbitrary write), especially since destDir is computed from user input. Validate skillName (e.g., allow only [a-z0-9-]+), reject path separators/absolute paths, and/or verify path.resolve(...) stays within the expected base directories before copying.
Copilot
AI
Mar 2, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fs.rmSync(destSkillDir, { recursive: true }) may fail on Windows or with read-only files (and elsewhere in the codebase rmSync calls often include force: true). Consider adding force: true (or using the existing safeRmDir helper pattern) so skill update is resilient and doesn't leave a partially-updated install.
| fs.rmSync(destSkillDir, { recursive: true }); | |
| fs.rmSync(destSkillDir, { recursive: true, force: true }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New
skillsubcommands are registered here, but there are no E2E coverage additions. The repo already has CLI E2E tests that execute the builtmaxsim-tools.cjs(e.g.tests/e2e/tools.test.ts). Adding tests forskill list/install/updatewould help catch regressions in path resolution (local vs global config) and bundled asset lookups, and should run with an isolated HOME / temp config dir to avoid touching the developer's real~/.claude.