lmskills-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +185 -0
- package/dist/github.d.ts +13 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +166 -0
- package/dist/github.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +4 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +98 -0
- package/dist/install.js.map +1 -0
- package/dist/list.d.ts +4 -0
- package/dist/list.d.ts.map +1 -0
- package/dist/list.js +27 -0
- package/dist/list.js.map +1 -0
- package/dist/remove.d.ts +4 -0
- package/dist/remove.d.ts.map +1 -0
- package/dist/remove.js +30 -0
- package/dist/remove.js.map +1 -0
- package/dist/types.d.ts +28 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +48 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +147 -0
- package/dist/utils.js.map +1 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# lmskills-cli
|
|
2
|
+
|
|
3
|
+
A command-line tool to easily fetch and install Claude skills from GitHub repositories.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### Option 1: Use with npx (Recommended)
|
|
8
|
+
|
|
9
|
+
No installation required! Run directly:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx lmskills-cli <command>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Option 2: Install Globally
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g lmskills-cli
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Then use the shorter command:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
lmskills <command>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### Install a Skill
|
|
30
|
+
|
|
31
|
+
Install a skill from a GitHub subdirectory URL:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Install locally (project-specific .claude directory)
|
|
35
|
+
lmskills install https://github.com/owner/repo/tree/main/path/to/skill
|
|
36
|
+
|
|
37
|
+
# Install globally (user-wide .claude directory)
|
|
38
|
+
lmskills install https://github.com/owner/repo/tree/main/path/to/skill --global
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The CLI will:
|
|
42
|
+
- Parse the GitHub URL to identify the repository and subdirectory
|
|
43
|
+
- Download all files from that subdirectory
|
|
44
|
+
- Copy them to `.claude/skills/<skill-name>/` (local or global)
|
|
45
|
+
- Track the installation in metadata for easy management
|
|
46
|
+
|
|
47
|
+
### List Installed Skills
|
|
48
|
+
|
|
49
|
+
View all installed skills:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# List local skills
|
|
53
|
+
lmskills list
|
|
54
|
+
|
|
55
|
+
# List global skills
|
|
56
|
+
lmskills list --global
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Remove a Skill
|
|
60
|
+
|
|
61
|
+
Uninstall a skill:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Remove local skill
|
|
65
|
+
lmskills remove <skill-name>
|
|
66
|
+
|
|
67
|
+
# Remove global skill
|
|
68
|
+
lmskills remove <skill-name> --global
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Alias: `lmskills rm <skill-name>`
|
|
72
|
+
|
|
73
|
+
## Examples
|
|
74
|
+
|
|
75
|
+
### Using npx (no installation required)
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Install a skill locally
|
|
79
|
+
npx lmskills-cli install https://github.com/anthropics/claude-code/tree/main/skills/example-skill
|
|
80
|
+
|
|
81
|
+
# Install a skill globally
|
|
82
|
+
npx lmskills-cli install https://github.com/user/skills/tree/main/my-awesome-skill -g
|
|
83
|
+
|
|
84
|
+
# List all local skills
|
|
85
|
+
npx lmskills-cli list
|
|
86
|
+
|
|
87
|
+
# Remove a skill
|
|
88
|
+
npx lmskills-cli rm example-skill
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Using global installation
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Install a skill locally
|
|
95
|
+
lmskills install https://github.com/anthropics/claude-code/tree/main/skills/example-skill
|
|
96
|
+
|
|
97
|
+
# Install a skill globally
|
|
98
|
+
lmskills install https://github.com/user/skills/tree/main/my-awesome-skill -g
|
|
99
|
+
|
|
100
|
+
# List all local skills
|
|
101
|
+
lmskills list
|
|
102
|
+
|
|
103
|
+
# Remove a skill
|
|
104
|
+
lmskills rm example-skill
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Directory Structure
|
|
108
|
+
|
|
109
|
+
### Local Installation
|
|
110
|
+
Skills are installed to `.claude/skills/` in your current working directory:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
your-project/
|
|
114
|
+
└── .claude/
|
|
115
|
+
└── skills/
|
|
116
|
+
├── .lmskills-metadata.json
|
|
117
|
+
├── skill-one/
|
|
118
|
+
│ ├── SKILL.md
|
|
119
|
+
│ └── ...
|
|
120
|
+
└── skill-two/
|
|
121
|
+
├── SKILL.md
|
|
122
|
+
└── ...
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Global Installation
|
|
126
|
+
Skills are installed to `.claude/skills/` in your home directory:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
~/.claude/
|
|
130
|
+
└── skills/
|
|
131
|
+
├── .lmskills-metadata.json
|
|
132
|
+
└── skill-name/
|
|
133
|
+
├── SKILL.md
|
|
134
|
+
└── ...
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Metadata
|
|
138
|
+
|
|
139
|
+
The CLI maintains a `.lmskills-metadata.json` file in the skills directory to track:
|
|
140
|
+
- Skill name
|
|
141
|
+
- Source GitHub URL
|
|
142
|
+
- Installation timestamp
|
|
143
|
+
- Installation path
|
|
144
|
+
- Whether it's a global or local installation
|
|
145
|
+
|
|
146
|
+
## Requirements
|
|
147
|
+
|
|
148
|
+
- Node.js 18.0.0 or higher
|
|
149
|
+
- Git repository URL must be in the format: `https://github.com/owner/repo/tree/branch/path/to/skill`
|
|
150
|
+
|
|
151
|
+
## GitHub API
|
|
152
|
+
|
|
153
|
+
The CLI uses the GitHub API without authentication, which has rate limits:
|
|
154
|
+
- 60 requests per hour for unauthenticated requests
|
|
155
|
+
- To increase the limit, you can set a GitHub personal access token as an environment variable (feature coming soon)
|
|
156
|
+
|
|
157
|
+
## Development
|
|
158
|
+
|
|
159
|
+
To work on the CLI locally:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# Clone the repository
|
|
163
|
+
git clone https://github.com/your-org/lmskills.git
|
|
164
|
+
cd lmskills/cli
|
|
165
|
+
|
|
166
|
+
# Install dependencies
|
|
167
|
+
npm install
|
|
168
|
+
|
|
169
|
+
# Build the TypeScript code
|
|
170
|
+
npm run build
|
|
171
|
+
|
|
172
|
+
# Link for local testing
|
|
173
|
+
npm link
|
|
174
|
+
|
|
175
|
+
# Now you can use 'lmskills' command globally
|
|
176
|
+
lmskills --help
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## License
|
|
180
|
+
|
|
181
|
+
MIT
|
|
182
|
+
|
|
183
|
+
## Contributing
|
|
184
|
+
|
|
185
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
package/dist/github.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ParsedGitHubUrl } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Parse a GitHub URL to extract owner, repo, branch, and path
|
|
4
|
+
* Supports formats like:
|
|
5
|
+
* - https://github.com/owner/repo/tree/branch/path/to/skill
|
|
6
|
+
* - https://github.com/owner/repo/tree/main/path/to/skill
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseGitHubUrl(url: string): ParsedGitHubUrl;
|
|
9
|
+
/**
|
|
10
|
+
* Download an entire subdirectory from a GitHub repository
|
|
11
|
+
*/
|
|
12
|
+
export declare function downloadGitHubDirectory(parsedUrl: ParsedGitHubUrl, targetDir: string): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAsC,MAAM,SAAS,CAAC;AAE9E;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAkB3D;AAuGD;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,eAAe,EAC1B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAyCf"}
|
package/dist/github.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.parseGitHubUrl = parseGitHubUrl;
|
|
40
|
+
exports.downloadGitHubDirectory = downloadGitHubDirectory;
|
|
41
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
/**
|
|
45
|
+
* Parse a GitHub URL to extract owner, repo, branch, and path
|
|
46
|
+
* Supports formats like:
|
|
47
|
+
* - https://github.com/owner/repo/tree/branch/path/to/skill
|
|
48
|
+
* - https://github.com/owner/repo/tree/main/path/to/skill
|
|
49
|
+
*/
|
|
50
|
+
function parseGitHubUrl(url) {
|
|
51
|
+
const regex = /github\.com\/([^\/]+)\/([^\/]+)\/tree\/([^\/]+)\/(.+)/;
|
|
52
|
+
const match = url.match(regex);
|
|
53
|
+
if (!match) {
|
|
54
|
+
throw new Error('Invalid GitHub URL format. Expected: https://github.com/owner/repo/tree/branch/path/to/skill');
|
|
55
|
+
}
|
|
56
|
+
const [, owner, repo, branch, pathStr] = match;
|
|
57
|
+
return {
|
|
58
|
+
owner,
|
|
59
|
+
repo,
|
|
60
|
+
branch,
|
|
61
|
+
path: pathStr,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Fetch the Git tree for a specific path in a repository
|
|
66
|
+
*/
|
|
67
|
+
async function fetchGitTree(owner, repo, treeSha) {
|
|
68
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/git/trees/${treeSha}?recursive=1`;
|
|
69
|
+
const response = await (0, node_fetch_1.default)(url, {
|
|
70
|
+
headers: {
|
|
71
|
+
'Accept': 'application/vnd.github.v3+json',
|
|
72
|
+
'User-Agent': 'lmskills-cli',
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
throw new Error(`GitHub API error: ${response.statusText}`);
|
|
77
|
+
}
|
|
78
|
+
return await response.json();
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get the SHA for a specific branch
|
|
82
|
+
*/
|
|
83
|
+
async function getBranchSha(owner, repo, branch) {
|
|
84
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/git/ref/heads/${branch}`;
|
|
85
|
+
const response = await (0, node_fetch_1.default)(url, {
|
|
86
|
+
headers: {
|
|
87
|
+
'Accept': 'application/vnd.github.v3+json',
|
|
88
|
+
'User-Agent': 'lmskills-cli',
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
if (!response.ok) {
|
|
92
|
+
throw new Error(`Failed to fetch branch: ${response.statusText}`);
|
|
93
|
+
}
|
|
94
|
+
const data = await response.json();
|
|
95
|
+
return data.object.sha;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get the tree SHA for a commit
|
|
99
|
+
*/
|
|
100
|
+
async function getCommitTreeSha(owner, repo, commitSha) {
|
|
101
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/git/commits/${commitSha}`;
|
|
102
|
+
const response = await (0, node_fetch_1.default)(url, {
|
|
103
|
+
headers: {
|
|
104
|
+
'Accept': 'application/vnd.github.v3+json',
|
|
105
|
+
'User-Agent': 'lmskills-cli',
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
if (!response.ok) {
|
|
109
|
+
throw new Error(`Failed to fetch commit: ${response.statusText}`);
|
|
110
|
+
}
|
|
111
|
+
const data = await response.json();
|
|
112
|
+
return data.tree.sha;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Download a blob (file) from GitHub
|
|
116
|
+
*/
|
|
117
|
+
async function downloadBlob(owner, repo, sha) {
|
|
118
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/git/blobs/${sha}`;
|
|
119
|
+
const response = await (0, node_fetch_1.default)(url, {
|
|
120
|
+
headers: {
|
|
121
|
+
'Accept': 'application/vnd.github.v3+json',
|
|
122
|
+
'User-Agent': 'lmskills-cli',
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
if (!response.ok) {
|
|
126
|
+
throw new Error(`Failed to download file: ${response.statusText}`);
|
|
127
|
+
}
|
|
128
|
+
const data = await response.json();
|
|
129
|
+
// GitHub returns base64-encoded content
|
|
130
|
+
return Buffer.from(data.content, 'base64');
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Download an entire subdirectory from a GitHub repository
|
|
134
|
+
*/
|
|
135
|
+
async function downloadGitHubDirectory(parsedUrl, targetDir) {
|
|
136
|
+
const { owner, repo, branch, path: subPath } = parsedUrl;
|
|
137
|
+
// Get the commit SHA for the branch
|
|
138
|
+
const commitSha = await getBranchSha(owner, repo, branch);
|
|
139
|
+
// Get the tree SHA for this commit
|
|
140
|
+
const treeSha = await getCommitTreeSha(owner, repo, commitSha);
|
|
141
|
+
// Fetch the full repository tree
|
|
142
|
+
const tree = await fetchGitTree(owner, repo, treeSha);
|
|
143
|
+
// Filter tree items that are within the target subdirectory
|
|
144
|
+
// Must match exact path or be inside the directory (with trailing slash)
|
|
145
|
+
const relevantItems = tree.tree.filter(item => item.path === subPath || item.path.startsWith(subPath + '/'));
|
|
146
|
+
if (relevantItems.length === 0) {
|
|
147
|
+
throw new Error(`No files found at path: ${subPath}`);
|
|
148
|
+
}
|
|
149
|
+
// Download each file
|
|
150
|
+
for (const item of relevantItems) {
|
|
151
|
+
if (item.type === 'blob') {
|
|
152
|
+
// Calculate relative path within the skill directory
|
|
153
|
+
const relativePath = item.path.substring(subPath.length + 1);
|
|
154
|
+
if (!relativePath)
|
|
155
|
+
continue; // Skip if empty
|
|
156
|
+
const targetPath = path.join(targetDir, relativePath);
|
|
157
|
+
// Ensure directory exists
|
|
158
|
+
const dir = path.dirname(targetPath);
|
|
159
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
160
|
+
// Download and save the file
|
|
161
|
+
const content = await downloadBlob(owner, repo, item.sha);
|
|
162
|
+
fs.writeFileSync(targetPath, content);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const install_1 = require("./install");
|
|
10
|
+
const list_1 = require("./list");
|
|
11
|
+
const remove_1 = require("./remove");
|
|
12
|
+
const program = new commander_1.Command();
|
|
13
|
+
program
|
|
14
|
+
.name('lmskills')
|
|
15
|
+
.description('CLI tool to fetch and install Claude skills from GitHub')
|
|
16
|
+
.version('0.1.0');
|
|
17
|
+
program
|
|
18
|
+
.command('install <github-url>')
|
|
19
|
+
.description('Install a skill from a GitHub subdirectory URL')
|
|
20
|
+
.option('-g, --global', 'Install globally instead of in the current project')
|
|
21
|
+
.action(async (githubUrl, options) => {
|
|
22
|
+
await (0, install_1.installSkill)(githubUrl, options);
|
|
23
|
+
});
|
|
24
|
+
program
|
|
25
|
+
.command('list')
|
|
26
|
+
.description('List installed skills')
|
|
27
|
+
.option('-g, --global', 'List global skills instead of local')
|
|
28
|
+
.action((options) => {
|
|
29
|
+
(0, list_1.listSkills)(options);
|
|
30
|
+
});
|
|
31
|
+
program
|
|
32
|
+
.command('remove <skill-name>')
|
|
33
|
+
.alias('rm')
|
|
34
|
+
.description('Remove an installed skill')
|
|
35
|
+
.option('-g, --global', 'Remove from global skills instead of local')
|
|
36
|
+
.action((skillName, options) => {
|
|
37
|
+
(0, remove_1.removeSkill)(skillName, options);
|
|
38
|
+
});
|
|
39
|
+
// Handle unknown commands with helpful error messages
|
|
40
|
+
program.on('command:*', (operands) => {
|
|
41
|
+
const unknownCommand = operands[0];
|
|
42
|
+
console.error(chalk_1.default.red(`\nError: Unknown command '${unknownCommand}'`));
|
|
43
|
+
// Check if it looks like a GitHub URL
|
|
44
|
+
if (unknownCommand.includes('github.com')) {
|
|
45
|
+
console.log(chalk_1.default.yellow('\nIt looks like you provided a GitHub URL.'));
|
|
46
|
+
console.log(chalk_1.default.yellow('Did you mean to run:\n'));
|
|
47
|
+
console.log(chalk_1.default.cyan(` lmskills install ${unknownCommand}`));
|
|
48
|
+
console.log(chalk_1.default.gray('\nOr with npx:'));
|
|
49
|
+
console.log(chalk_1.default.cyan(` npx lmskills-cli install ${unknownCommand}`));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
console.log(chalk_1.default.gray('\nRun "lmskills --help" to see available commands.'));
|
|
53
|
+
}
|
|
54
|
+
process.exit(1);
|
|
55
|
+
});
|
|
56
|
+
program.parse(process.argv);
|
|
57
|
+
// Show help if no command provided
|
|
58
|
+
if (!process.argv.slice(2).length) {
|
|
59
|
+
program.outputHelp();
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAEA,yCAAoC;AACpC,kDAA0B;AAC1B,uCAAyC;AACzC,iCAAoC;AACpC,qCAAuC;AAEvC,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,yDAAyD,CAAC;KACtE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,sBAAsB,CAAC;KAC/B,WAAW,CAAC,gDAAgD,CAAC;KAC7D,MAAM,CAAC,cAAc,EAAE,oDAAoD,CAAC;KAC5E,MAAM,CAAC,KAAK,EAAE,SAAiB,EAAE,OAA6B,EAAE,EAAE;IACjE,MAAM,IAAA,sBAAY,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,uBAAuB,CAAC;KACpC,MAAM,CAAC,cAAc,EAAE,qCAAqC,CAAC;KAC7D,MAAM,CAAC,CAAC,OAA6B,EAAE,EAAE;IACxC,IAAA,iBAAU,EAAC,OAAO,CAAC,CAAC;AACtB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,qBAAqB,CAAC;KAC9B,KAAK,CAAC,IAAI,CAAC;KACX,WAAW,CAAC,2BAA2B,CAAC;KACxC,MAAM,CAAC,cAAc,EAAE,4CAA4C,CAAC;KACpE,MAAM,CAAC,CAAC,SAAiB,EAAE,OAA6B,EAAE,EAAE;IAC3D,IAAA,oBAAW,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAClC,CAAC,CAAC,CAAC;AAEL,sDAAsD;AACtD,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,EAAE;IACnC,MAAM,cAAc,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAEnC,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,6BAA6B,cAAc,GAAG,CAAC,CAAC,CAAC;IAEzE,sCAAsC;IACtC,IAAI,cAAc,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,4CAA4C,CAAC,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,sBAAsB,cAAc,EAAE,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,8BAA8B,cAAc,EAAE,CAAC,CAAC,CAAC;IAC1E,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC,CAAC;IAChF,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5B,mCAAmC;AACnC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAClC,OAAO,CAAC,UAAU,EAAE,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAcA,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5B,OAAO,CAAC,IAAI,CAAC,CAyEf"}
|
package/dist/install.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.installSkill = installSkill;
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
42
|
+
const ora_1 = __importDefault(require("ora"));
|
|
43
|
+
const github_1 = require("./github");
|
|
44
|
+
const utils_1 = require("./utils");
|
|
45
|
+
async function installSkill(githubUrl, options) {
|
|
46
|
+
const isGlobal = options.global || false;
|
|
47
|
+
const spinner = (0, ora_1.default)();
|
|
48
|
+
try {
|
|
49
|
+
// Parse the GitHub URL
|
|
50
|
+
spinner.start('Parsing GitHub URL...');
|
|
51
|
+
const parsedUrl = (0, github_1.parseGitHubUrl)(githubUrl);
|
|
52
|
+
spinner.succeed(`Parsed: ${parsedUrl.owner}/${parsedUrl.repo} (${parsedUrl.path})`);
|
|
53
|
+
// Derive skill name from the path
|
|
54
|
+
const skillName = (0, utils_1.getSkillDirName)(parsedUrl.path);
|
|
55
|
+
// Check if already installed
|
|
56
|
+
const metadata = (0, utils_1.readMetadata)(isGlobal);
|
|
57
|
+
const existing = metadata.find(s => s.name === skillName);
|
|
58
|
+
if (existing) {
|
|
59
|
+
console.log(chalk_1.default.yellow(`\nSkill "${skillName}" is already installed at: ${existing.path}`));
|
|
60
|
+
console.log(chalk_1.default.yellow('Reinstalling will overwrite the existing skill.\n'));
|
|
61
|
+
}
|
|
62
|
+
// Ensure skills directory exists
|
|
63
|
+
(0, utils_1.ensureSkillsDir)(isGlobal);
|
|
64
|
+
// Determine target directory
|
|
65
|
+
const skillsPath = (0, utils_1.getSkillsPath)(isGlobal);
|
|
66
|
+
const targetDir = path.join(skillsPath, skillName);
|
|
67
|
+
// Remove existing installation if present
|
|
68
|
+
if (existing) {
|
|
69
|
+
(0, utils_1.deleteDirectory)(targetDir);
|
|
70
|
+
}
|
|
71
|
+
// Download the skill
|
|
72
|
+
spinner.start(`Downloading skill from GitHub...`);
|
|
73
|
+
await (0, github_1.downloadGitHubDirectory)(parsedUrl, targetDir);
|
|
74
|
+
spinner.succeed(`Downloaded skill to ${targetDir}`);
|
|
75
|
+
// Save metadata
|
|
76
|
+
const skillMetadata = {
|
|
77
|
+
name: skillName,
|
|
78
|
+
source: githubUrl,
|
|
79
|
+
installedAt: new Date().toISOString(),
|
|
80
|
+
path: targetDir,
|
|
81
|
+
isGlobal,
|
|
82
|
+
};
|
|
83
|
+
(0, utils_1.addSkillMetadata)(skillMetadata, isGlobal);
|
|
84
|
+
console.log(chalk_1.default.green(`\n✓ Successfully installed "${skillName}" ${isGlobal ? 'globally' : 'locally'}`));
|
|
85
|
+
console.log(chalk_1.default.gray(` Path: ${targetDir}`));
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
spinner.fail('Installation failed');
|
|
89
|
+
if (error instanceof Error) {
|
|
90
|
+
console.error(chalk_1.default.red(`\nError: ${error.message}`));
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
console.error(chalk_1.default.red('\nAn unknown error occurred'));
|
|
94
|
+
}
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
|
package/dist/list.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../src/list.ts"],"names":[],"mappings":"AAGA,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAyB9D"}
|
package/dist/list.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.listSkills = listSkills;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const utils_1 = require("./utils");
|
|
9
|
+
function listSkills(options) {
|
|
10
|
+
const isGlobal = options.global || false;
|
|
11
|
+
const metadata = (0, utils_1.readMetadata)(isGlobal);
|
|
12
|
+
const scope = isGlobal ? 'global' : 'local';
|
|
13
|
+
if (metadata.length === 0) {
|
|
14
|
+
console.log(chalk_1.default.yellow(`No ${scope} skills installed.`));
|
|
15
|
+
console.log(chalk_1.default.gray(`\nTo install a skill, run:\n lmskills install <github-url> ${isGlobal ? '--global' : ''}`));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
console.log(chalk_1.default.bold(`\n${scope.toUpperCase()} SKILLS (${metadata.length}):\n`));
|
|
19
|
+
metadata.forEach(skill => {
|
|
20
|
+
console.log(chalk_1.default.cyan(` ${skill.name}`));
|
|
21
|
+
console.log(chalk_1.default.gray(` Source: ${skill.source}`));
|
|
22
|
+
console.log(chalk_1.default.gray(` Installed: ${new Date(skill.installedAt).toLocaleString()}`));
|
|
23
|
+
console.log(chalk_1.default.gray(` Path: ${skill.path}`));
|
|
24
|
+
console.log();
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=list.js.map
|
package/dist/list.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../src/list.ts"],"names":[],"mappings":";;;;;AAGA,gCAyBC;AA5BD,kDAA0B;AAC1B,mCAAuC;AAEvC,SAAgB,UAAU,CAAC,OAA6B;IACtD,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC;IACzC,MAAM,QAAQ,GAAG,IAAA,oBAAY,EAAC,QAAQ,CAAC,CAAC;IAExC,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IAE5C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,MAAM,KAAK,oBAAoB,CAAC,CAAC,CAAC;QAC3D,OAAO,CAAC,GAAG,CACT,eAAK,CAAC,IAAI,CACR,+DAA+D,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAC5F,CACF,CAAC;QACF,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,WAAW,EAAE,YAAY,QAAQ,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC;IAEnF,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACvB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC;QAC1F,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/remove.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../src/remove.ts"],"names":[],"mappings":"AAOA,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5B,IAAI,CAsCN"}
|
package/dist/remove.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.removeSkill = removeSkill;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const utils_1 = require("./utils");
|
|
9
|
+
function removeSkill(skillName, options) {
|
|
10
|
+
const isGlobal = options.global || false;
|
|
11
|
+
const metadata = (0, utils_1.readMetadata)(isGlobal);
|
|
12
|
+
const skill = metadata.find(s => s.name === skillName);
|
|
13
|
+
if (!skill) {
|
|
14
|
+
console.error(chalk_1.default.red(`\nSkill "${skillName}" not found in ${isGlobal ? 'global' : 'local'} installations.`));
|
|
15
|
+
console.log(chalk_1.default.gray(`\nRun "lmskills list${isGlobal ? ' --global' : ''}" to see installed skills.`));
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
// Delete the skill directory
|
|
20
|
+
(0, utils_1.deleteDirectory)(skill.path);
|
|
21
|
+
// Remove from metadata
|
|
22
|
+
(0, utils_1.removeSkillMetadata)(skillName, isGlobal);
|
|
23
|
+
console.log(chalk_1.default.green(`\n✓ Successfully removed "${skillName}" from ${isGlobal ? 'global' : 'local'} installations`));
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
console.error(chalk_1.default.red(`\nError removing skill: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=remove.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove.js","sourceRoot":"","sources":["../src/remove.ts"],"names":[],"mappings":";;;;;AAOA,kCAyCC;AAhDD,kDAA0B;AAC1B,mCAIiB;AAEjB,SAAgB,WAAW,CACzB,SAAiB,EACjB,OAA6B;IAE7B,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC;IACzC,MAAM,QAAQ,GAAG,IAAA,oBAAY,EAAC,QAAQ,CAAC,CAAC;IAExC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IAEvD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CACX,eAAK,CAAC,GAAG,CACP,YAAY,SAAS,kBAAkB,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,iBAAiB,CACtF,CACF,CAAC;QACF,OAAO,CAAC,GAAG,CACT,eAAK,CAAC,IAAI,CACR,uBAAuB,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,4BAA4B,CAC/E,CACF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,6BAA6B;QAC7B,IAAA,uBAAe,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE5B,uBAAuB;QACvB,IAAA,2BAAmB,EAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAEzC,OAAO,CAAC,GAAG,CACT,eAAK,CAAC,KAAK,CACT,6BAA6B,SAAS,UAAU,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,gBAAgB,CAC9F,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,eAAK,CAAC,GAAG,CAAC,2BAA2B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CACjG,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface SkillMetadata {
|
|
2
|
+
name: string;
|
|
3
|
+
source: string;
|
|
4
|
+
installedAt: string;
|
|
5
|
+
path: string;
|
|
6
|
+
isGlobal: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface GitHubTreeItem {
|
|
9
|
+
path: string;
|
|
10
|
+
mode: string;
|
|
11
|
+
type: 'blob' | 'tree';
|
|
12
|
+
sha: string;
|
|
13
|
+
size?: number;
|
|
14
|
+
url: string;
|
|
15
|
+
}
|
|
16
|
+
export interface GitHubTreeResponse {
|
|
17
|
+
sha: string;
|
|
18
|
+
url: string;
|
|
19
|
+
tree: GitHubTreeItem[];
|
|
20
|
+
truncated: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface ParsedGitHubUrl {
|
|
23
|
+
owner: string;
|
|
24
|
+
repo: string;
|
|
25
|
+
branch: string;
|
|
26
|
+
path: string;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { SkillMetadata } from './types';
|
|
2
|
+
export declare const SKILLS_DIR = "skills";
|
|
3
|
+
export declare const METADATA_FILE = ".lmskills-metadata.json";
|
|
4
|
+
/**
|
|
5
|
+
* Get the path to the local .claude directory (project-specific)
|
|
6
|
+
*/
|
|
7
|
+
export declare function getLocalClaudePath(): string;
|
|
8
|
+
/**
|
|
9
|
+
* Get the path to the global .claude directory (user-wide)
|
|
10
|
+
*/
|
|
11
|
+
export declare function getGlobalClaudePath(): string;
|
|
12
|
+
/**
|
|
13
|
+
* Get the skills directory path
|
|
14
|
+
*/
|
|
15
|
+
export declare function getSkillsPath(isGlobal: boolean): string;
|
|
16
|
+
/**
|
|
17
|
+
* Ensure the skills directory exists
|
|
18
|
+
*/
|
|
19
|
+
export declare function ensureSkillsDir(isGlobal: boolean): void;
|
|
20
|
+
/**
|
|
21
|
+
* Get metadata file path
|
|
22
|
+
*/
|
|
23
|
+
export declare function getMetadataPath(isGlobal: boolean): string;
|
|
24
|
+
/**
|
|
25
|
+
* Read metadata for all installed skills
|
|
26
|
+
*/
|
|
27
|
+
export declare function readMetadata(isGlobal: boolean): SkillMetadata[];
|
|
28
|
+
/**
|
|
29
|
+
* Write metadata for installed skills
|
|
30
|
+
*/
|
|
31
|
+
export declare function writeMetadata(metadata: SkillMetadata[], isGlobal: boolean): void;
|
|
32
|
+
/**
|
|
33
|
+
* Add a skill to metadata
|
|
34
|
+
*/
|
|
35
|
+
export declare function addSkillMetadata(skill: SkillMetadata, isGlobal: boolean): void;
|
|
36
|
+
/**
|
|
37
|
+
* Remove a skill from metadata
|
|
38
|
+
*/
|
|
39
|
+
export declare function removeSkillMetadata(skillName: string, isGlobal: boolean): void;
|
|
40
|
+
/**
|
|
41
|
+
* Get a skill's directory name from its source URL
|
|
42
|
+
*/
|
|
43
|
+
export declare function getSkillDirName(source: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Delete a directory recursively
|
|
46
|
+
*/
|
|
47
|
+
export declare function deleteDirectory(dirPath: string): void;
|
|
48
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,eAAO,MAAM,UAAU,WAAW,CAAC;AACnC,eAAO,MAAM,aAAa,4BAA4B,CAAC;AAEvD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAG3C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAGvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAGvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAGzD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,GAAG,aAAa,EAAE,CAc/D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAGhF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAQ9E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAI9E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOtD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAIrD"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.METADATA_FILE = exports.SKILLS_DIR = void 0;
|
|
37
|
+
exports.getLocalClaudePath = getLocalClaudePath;
|
|
38
|
+
exports.getGlobalClaudePath = getGlobalClaudePath;
|
|
39
|
+
exports.getSkillsPath = getSkillsPath;
|
|
40
|
+
exports.ensureSkillsDir = ensureSkillsDir;
|
|
41
|
+
exports.getMetadataPath = getMetadataPath;
|
|
42
|
+
exports.readMetadata = readMetadata;
|
|
43
|
+
exports.writeMetadata = writeMetadata;
|
|
44
|
+
exports.addSkillMetadata = addSkillMetadata;
|
|
45
|
+
exports.removeSkillMetadata = removeSkillMetadata;
|
|
46
|
+
exports.getSkillDirName = getSkillDirName;
|
|
47
|
+
exports.deleteDirectory = deleteDirectory;
|
|
48
|
+
const fs = __importStar(require("fs"));
|
|
49
|
+
const path = __importStar(require("path"));
|
|
50
|
+
const os = __importStar(require("os"));
|
|
51
|
+
exports.SKILLS_DIR = 'skills';
|
|
52
|
+
exports.METADATA_FILE = '.lmskills-metadata.json';
|
|
53
|
+
/**
|
|
54
|
+
* Get the path to the local .claude directory (project-specific)
|
|
55
|
+
*/
|
|
56
|
+
function getLocalClaudePath() {
|
|
57
|
+
const cwd = process.cwd();
|
|
58
|
+
return path.join(cwd, '.claude');
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get the path to the global .claude directory (user-wide)
|
|
62
|
+
*/
|
|
63
|
+
function getGlobalClaudePath() {
|
|
64
|
+
return path.join(os.homedir(), '.claude');
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get the skills directory path
|
|
68
|
+
*/
|
|
69
|
+
function getSkillsPath(isGlobal) {
|
|
70
|
+
const claudePath = isGlobal ? getGlobalClaudePath() : getLocalClaudePath();
|
|
71
|
+
return path.join(claudePath, exports.SKILLS_DIR);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Ensure the skills directory exists
|
|
75
|
+
*/
|
|
76
|
+
function ensureSkillsDir(isGlobal) {
|
|
77
|
+
const skillsPath = getSkillsPath(isGlobal);
|
|
78
|
+
fs.mkdirSync(skillsPath, { recursive: true });
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get metadata file path
|
|
82
|
+
*/
|
|
83
|
+
function getMetadataPath(isGlobal) {
|
|
84
|
+
const skillsPath = getSkillsPath(isGlobal);
|
|
85
|
+
return path.join(skillsPath, exports.METADATA_FILE);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Read metadata for all installed skills
|
|
89
|
+
*/
|
|
90
|
+
function readMetadata(isGlobal) {
|
|
91
|
+
const metadataPath = getMetadataPath(isGlobal);
|
|
92
|
+
if (!fs.existsSync(metadataPath)) {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
const content = fs.readFileSync(metadataPath, 'utf-8');
|
|
97
|
+
return JSON.parse(content);
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
console.error(`Error reading metadata: ${error}`);
|
|
101
|
+
return [];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Write metadata for installed skills
|
|
106
|
+
*/
|
|
107
|
+
function writeMetadata(metadata, isGlobal) {
|
|
108
|
+
const metadataPath = getMetadataPath(isGlobal);
|
|
109
|
+
fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2));
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Add a skill to metadata
|
|
113
|
+
*/
|
|
114
|
+
function addSkillMetadata(skill, isGlobal) {
|
|
115
|
+
const metadata = readMetadata(isGlobal);
|
|
116
|
+
// Remove existing entry if it exists
|
|
117
|
+
const filtered = metadata.filter(s => s.name !== skill.name);
|
|
118
|
+
filtered.push(skill);
|
|
119
|
+
writeMetadata(filtered, isGlobal);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Remove a skill from metadata
|
|
123
|
+
*/
|
|
124
|
+
function removeSkillMetadata(skillName, isGlobal) {
|
|
125
|
+
const metadata = readMetadata(isGlobal);
|
|
126
|
+
const filtered = metadata.filter(s => s.name !== skillName);
|
|
127
|
+
writeMetadata(filtered, isGlobal);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get a skill's directory name from its source URL
|
|
131
|
+
*/
|
|
132
|
+
function getSkillDirName(source) {
|
|
133
|
+
// Extract a clean name from the GitHub URL
|
|
134
|
+
const parts = source.split('/').filter(Boolean);
|
|
135
|
+
const lastPart = parts[parts.length - 1];
|
|
136
|
+
// Remove .git suffix if present
|
|
137
|
+
return lastPart.replace(/\.git$/, '');
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Delete a directory recursively
|
|
141
|
+
*/
|
|
142
|
+
function deleteDirectory(dirPath) {
|
|
143
|
+
if (fs.existsSync(dirPath)) {
|
|
144
|
+
fs.rmSync(dirPath, { recursive: true, force: true });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lmskills-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI tool to fetch and install Claude skills from GitHub",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"lmskills": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "tsc --watch",
|
|
12
|
+
"prepublishOnly": "npm run build"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"claude",
|
|
16
|
+
"skills",
|
|
17
|
+
"cli",
|
|
18
|
+
"ai",
|
|
19
|
+
"llm"
|
|
20
|
+
],
|
|
21
|
+
"author": "",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/flinstonedev/lmskills.git",
|
|
26
|
+
"directory": "cli"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/flinstonedev/lmskills/tree/main/cli#readme",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/flinstonedev/lmskills/issues"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"commander": "^12.1.0",
|
|
34
|
+
"chalk": "^4.1.2",
|
|
35
|
+
"node-fetch": "^2.7.0",
|
|
36
|
+
"ora": "^5.4.1"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^22.10.5",
|
|
40
|
+
"@types/node-fetch": "^2.6.12",
|
|
41
|
+
"typescript": "^5.7.2"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18.0.0"
|
|
45
|
+
}
|
|
46
|
+
}
|