skillstore 0.1.3 → 0.1.4
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/dist/cli/index.js +11 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/add.d.ts +41 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +374 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/check.d.ts +12 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +133 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/generate-lock.d.ts +17 -0
- package/dist/commands/generate-lock.d.ts.map +1 -0
- package/dist/commands/generate-lock.js +134 -0
- package/dist/commands/generate-lock.js.map +1 -0
- package/dist/commands/list.d.ts +12 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +97 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/update.d.ts +22 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +203 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/lib/agents.d.ts +38 -0
- package/dist/lib/agents.d.ts.map +1 -0
- package/dist/lib/agents.js +223 -0
- package/dist/lib/agents.js.map +1 -0
- package/dist/lib/installer.d.ts +82 -0
- package/dist/lib/installer.d.ts.map +1 -0
- package/dist/lib/installer.js +226 -0
- package/dist/lib/installer.js.map +1 -0
- package/dist/lib/skill-lock.d.ts +64 -0
- package/dist/lib/skill-lock.d.ts.map +1 -0
- package/dist/lib/skill-lock.js +101 -0
- package/dist/lib/skill-lock.js.map +1 -0
- package/package.json +6 -1
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
const home = homedir();
|
|
5
|
+
const codexHome = process.env.CODEX_HOME?.trim() || join(home, '.codex');
|
|
6
|
+
/** Canonical skill storage location (shared across agents) */
|
|
7
|
+
export const CANONICAL_SKILLS_DIR = join(home, '.agents', 'skills');
|
|
8
|
+
/** Lock file location */
|
|
9
|
+
export const LOCK_FILE_PATH = join(home, '.agents', '.skill-lock.json');
|
|
10
|
+
/** All supported agents */
|
|
11
|
+
export const agents = {
|
|
12
|
+
amp: {
|
|
13
|
+
id: 'amp',
|
|
14
|
+
name: 'Amp',
|
|
15
|
+
projectPath: '.agents/skills',
|
|
16
|
+
globalPath: join(home, '.config/agents/skills'),
|
|
17
|
+
detectInstalled: () => existsSync(join(home, '.config/amp')),
|
|
18
|
+
},
|
|
19
|
+
antigravity: {
|
|
20
|
+
id: 'antigravity',
|
|
21
|
+
name: 'Antigravity',
|
|
22
|
+
projectPath: '.agent/skills',
|
|
23
|
+
globalPath: join(home, '.gemini/antigravity/global_skills'),
|
|
24
|
+
detectInstalled: () => existsSync(join(process.cwd(), '.agent')) ||
|
|
25
|
+
existsSync(join(home, '.gemini/antigravity')),
|
|
26
|
+
},
|
|
27
|
+
'claude-code': {
|
|
28
|
+
id: 'claude-code',
|
|
29
|
+
name: 'Claude Code',
|
|
30
|
+
projectPath: '.claude/skills',
|
|
31
|
+
globalPath: join(home, '.claude/skills'),
|
|
32
|
+
detectInstalled: () => existsSync(join(home, '.claude')),
|
|
33
|
+
},
|
|
34
|
+
clawdbot: {
|
|
35
|
+
id: 'clawdbot',
|
|
36
|
+
name: 'Clawdbot',
|
|
37
|
+
projectPath: 'skills',
|
|
38
|
+
globalPath: join(home, '.clawdbot/skills'),
|
|
39
|
+
detectInstalled: () => existsSync(join(home, '.clawdbot')),
|
|
40
|
+
},
|
|
41
|
+
cline: {
|
|
42
|
+
id: 'cline',
|
|
43
|
+
name: 'Cline',
|
|
44
|
+
projectPath: '.cline/skills',
|
|
45
|
+
globalPath: join(home, '.cline/skills'),
|
|
46
|
+
detectInstalled: () => existsSync(join(home, '.cline')),
|
|
47
|
+
},
|
|
48
|
+
codex: {
|
|
49
|
+
id: 'codex',
|
|
50
|
+
name: 'Codex',
|
|
51
|
+
projectPath: '.codex/skills',
|
|
52
|
+
globalPath: join(codexHome, 'skills'),
|
|
53
|
+
detectInstalled: () => existsSync(codexHome) || existsSync('/etc/codex'),
|
|
54
|
+
},
|
|
55
|
+
'command-code': {
|
|
56
|
+
id: 'command-code',
|
|
57
|
+
name: 'Command Code',
|
|
58
|
+
projectPath: '.commandcode/skills',
|
|
59
|
+
globalPath: join(home, '.commandcode/skills'),
|
|
60
|
+
detectInstalled: () => existsSync(join(home, '.commandcode')),
|
|
61
|
+
},
|
|
62
|
+
continue: {
|
|
63
|
+
id: 'continue',
|
|
64
|
+
name: 'Continue',
|
|
65
|
+
projectPath: '.continue/skills',
|
|
66
|
+
globalPath: join(home, '.continue/skills'),
|
|
67
|
+
detectInstalled: () => existsSync(join(process.cwd(), '.continue')) || existsSync(join(home, '.continue')),
|
|
68
|
+
},
|
|
69
|
+
crush: {
|
|
70
|
+
id: 'crush',
|
|
71
|
+
name: 'Crush',
|
|
72
|
+
projectPath: '.crush/skills',
|
|
73
|
+
globalPath: join(home, '.config/crush/skills'),
|
|
74
|
+
detectInstalled: () => existsSync(join(home, '.config/crush')),
|
|
75
|
+
},
|
|
76
|
+
cursor: {
|
|
77
|
+
id: 'cursor',
|
|
78
|
+
name: 'Cursor',
|
|
79
|
+
projectPath: '.cursor/skills',
|
|
80
|
+
globalPath: join(home, '.cursor/skills'),
|
|
81
|
+
detectInstalled: () => existsSync(join(home, '.cursor')),
|
|
82
|
+
},
|
|
83
|
+
droid: {
|
|
84
|
+
id: 'droid',
|
|
85
|
+
name: 'Droid',
|
|
86
|
+
projectPath: '.factory/skills',
|
|
87
|
+
globalPath: join(home, '.factory/skills'),
|
|
88
|
+
detectInstalled: () => existsSync(join(home, '.factory')),
|
|
89
|
+
},
|
|
90
|
+
'gemini-cli': {
|
|
91
|
+
id: 'gemini-cli',
|
|
92
|
+
name: 'Gemini CLI',
|
|
93
|
+
projectPath: '.gemini/skills',
|
|
94
|
+
globalPath: join(home, '.gemini/skills'),
|
|
95
|
+
detectInstalled: () => existsSync(join(home, '.gemini')),
|
|
96
|
+
},
|
|
97
|
+
'github-copilot': {
|
|
98
|
+
id: 'github-copilot',
|
|
99
|
+
name: 'GitHub Copilot',
|
|
100
|
+
projectPath: '.github/skills',
|
|
101
|
+
globalPath: join(home, '.copilot/skills'),
|
|
102
|
+
detectInstalled: () => existsSync(join(process.cwd(), '.github')) || existsSync(join(home, '.copilot')),
|
|
103
|
+
},
|
|
104
|
+
goose: {
|
|
105
|
+
id: 'goose',
|
|
106
|
+
name: 'Goose',
|
|
107
|
+
projectPath: '.goose/skills',
|
|
108
|
+
globalPath: join(home, '.config/goose/skills'),
|
|
109
|
+
detectInstalled: () => existsSync(join(home, '.config/goose')),
|
|
110
|
+
},
|
|
111
|
+
kilo: {
|
|
112
|
+
id: 'kilo',
|
|
113
|
+
name: 'Kilo Code',
|
|
114
|
+
projectPath: '.kilocode/skills',
|
|
115
|
+
globalPath: join(home, '.kilocode/skills'),
|
|
116
|
+
detectInstalled: () => existsSync(join(home, '.kilocode')),
|
|
117
|
+
},
|
|
118
|
+
'kiro-cli': {
|
|
119
|
+
id: 'kiro-cli',
|
|
120
|
+
name: 'Kiro CLI',
|
|
121
|
+
projectPath: '.kiro/skills',
|
|
122
|
+
globalPath: join(home, '.kiro/skills'),
|
|
123
|
+
detectInstalled: () => existsSync(join(home, '.kiro')),
|
|
124
|
+
},
|
|
125
|
+
mcpjam: {
|
|
126
|
+
id: 'mcpjam',
|
|
127
|
+
name: 'MCPJam',
|
|
128
|
+
projectPath: '.mcpjam/skills',
|
|
129
|
+
globalPath: join(home, '.mcpjam/skills'),
|
|
130
|
+
detectInstalled: () => existsSync(join(home, '.mcpjam')),
|
|
131
|
+
},
|
|
132
|
+
opencode: {
|
|
133
|
+
id: 'opencode',
|
|
134
|
+
name: 'OpenCode',
|
|
135
|
+
projectPath: '.opencode/skills',
|
|
136
|
+
globalPath: join(home, '.config/opencode/skills'),
|
|
137
|
+
detectInstalled: () => existsSync(join(home, '.config/opencode')) || existsSync(join(home, '.claude/skills')),
|
|
138
|
+
},
|
|
139
|
+
openhands: {
|
|
140
|
+
id: 'openhands',
|
|
141
|
+
name: 'OpenHands',
|
|
142
|
+
projectPath: '.openhands/skills',
|
|
143
|
+
globalPath: join(home, '.openhands/skills'),
|
|
144
|
+
detectInstalled: () => existsSync(join(home, '.openhands')),
|
|
145
|
+
},
|
|
146
|
+
pi: {
|
|
147
|
+
id: 'pi',
|
|
148
|
+
name: 'Pi',
|
|
149
|
+
projectPath: '.pi/skills',
|
|
150
|
+
globalPath: join(home, '.pi/agent/skills'),
|
|
151
|
+
detectInstalled: () => existsSync(join(home, '.pi/agent')),
|
|
152
|
+
},
|
|
153
|
+
qoder: {
|
|
154
|
+
id: 'qoder',
|
|
155
|
+
name: 'Qoder',
|
|
156
|
+
projectPath: '.qoder/skills',
|
|
157
|
+
globalPath: join(home, '.qoder/skills'),
|
|
158
|
+
detectInstalled: () => existsSync(join(home, '.qoder')),
|
|
159
|
+
},
|
|
160
|
+
'qwen-code': {
|
|
161
|
+
id: 'qwen-code',
|
|
162
|
+
name: 'Qwen Code',
|
|
163
|
+
projectPath: '.qwen/skills',
|
|
164
|
+
globalPath: join(home, '.qwen/skills'),
|
|
165
|
+
detectInstalled: () => existsSync(join(home, '.qwen')),
|
|
166
|
+
},
|
|
167
|
+
roo: {
|
|
168
|
+
id: 'roo',
|
|
169
|
+
name: 'Roo Code',
|
|
170
|
+
projectPath: '.roo/skills',
|
|
171
|
+
globalPath: join(home, '.roo/skills'),
|
|
172
|
+
detectInstalled: () => existsSync(join(home, '.roo')),
|
|
173
|
+
},
|
|
174
|
+
trae: {
|
|
175
|
+
id: 'trae',
|
|
176
|
+
name: 'Trae',
|
|
177
|
+
projectPath: '.trae/skills',
|
|
178
|
+
globalPath: join(home, '.trae/skills'),
|
|
179
|
+
detectInstalled: () => existsSync(join(home, '.trae')),
|
|
180
|
+
},
|
|
181
|
+
windsurf: {
|
|
182
|
+
id: 'windsurf',
|
|
183
|
+
name: 'Windsurf',
|
|
184
|
+
projectPath: '.windsurf/skills',
|
|
185
|
+
globalPath: join(home, '.codeium/windsurf/skills'),
|
|
186
|
+
detectInstalled: () => existsSync(join(home, '.codeium/windsurf')),
|
|
187
|
+
},
|
|
188
|
+
zencoder: {
|
|
189
|
+
id: 'zencoder',
|
|
190
|
+
name: 'Zencoder',
|
|
191
|
+
projectPath: '.zencoder/skills',
|
|
192
|
+
globalPath: join(home, '.zencoder/skills'),
|
|
193
|
+
detectInstalled: () => existsSync(join(home, '.zencoder')),
|
|
194
|
+
},
|
|
195
|
+
neovate: {
|
|
196
|
+
id: 'neovate',
|
|
197
|
+
name: 'Neovate',
|
|
198
|
+
projectPath: '.neovate/skills',
|
|
199
|
+
globalPath: join(home, '.neovate/skills'),
|
|
200
|
+
detectInstalled: () => existsSync(join(home, '.neovate')),
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
/** Get all agent IDs */
|
|
204
|
+
export function getAllAgentIds() {
|
|
205
|
+
return Object.keys(agents);
|
|
206
|
+
}
|
|
207
|
+
/** Get agent config by ID */
|
|
208
|
+
export function getAgentById(id) {
|
|
209
|
+
return agents[id];
|
|
210
|
+
}
|
|
211
|
+
/** Detect which agents are installed on this system */
|
|
212
|
+
export function detectInstalledAgents() {
|
|
213
|
+
return Object.values(agents).filter((agent) => agent.detectInstalled());
|
|
214
|
+
}
|
|
215
|
+
/** Get agent configs by IDs */
|
|
216
|
+
export function getAgentsByIds(ids) {
|
|
217
|
+
return ids.map((id) => agents[id]).filter(Boolean);
|
|
218
|
+
}
|
|
219
|
+
/** Check if an agent ID is valid */
|
|
220
|
+
export function isValidAgentId(id) {
|
|
221
|
+
return id in agents;
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/lib/agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { type AgentConfig, type AgentId } from './agents.js';
|
|
2
|
+
/**
|
|
3
|
+
* Skill Installer
|
|
4
|
+
*
|
|
5
|
+
* Handles installation of skills to multiple agent directories
|
|
6
|
+
* using symlinks for efficient storage.
|
|
7
|
+
*/
|
|
8
|
+
export type InstallMode = 'symlink' | 'copy';
|
|
9
|
+
export interface InstallResult {
|
|
10
|
+
success: boolean;
|
|
11
|
+
agentId: AgentId;
|
|
12
|
+
path: string;
|
|
13
|
+
canonicalPath?: string;
|
|
14
|
+
mode: InstallMode;
|
|
15
|
+
symlinkFailed?: boolean;
|
|
16
|
+
error?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface MultiAgentInstallResult {
|
|
19
|
+
slug: string;
|
|
20
|
+
canonicalPath: string;
|
|
21
|
+
agents: InstallResult[];
|
|
22
|
+
success: boolean;
|
|
23
|
+
successCount: number;
|
|
24
|
+
failCount: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Sanitizes a filename/directory name to prevent path traversal attacks
|
|
28
|
+
*/
|
|
29
|
+
export declare function sanitizeName(name: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Get canonical skill directory path
|
|
32
|
+
*/
|
|
33
|
+
export declare function getCanonicalSkillPath(slug: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Get agent-specific skill path
|
|
36
|
+
*/
|
|
37
|
+
export declare function getAgentSkillPath(slug: string, agent: AgentConfig, options?: {
|
|
38
|
+
global?: boolean;
|
|
39
|
+
cwd?: string;
|
|
40
|
+
}): string;
|
|
41
|
+
/**
|
|
42
|
+
* Install skill to canonical location (for later symlinking)
|
|
43
|
+
* This should be called AFTER extracting the ZIP to canonical path
|
|
44
|
+
*/
|
|
45
|
+
export declare function ensureCanonicalDir(slug: string): Promise<string>;
|
|
46
|
+
/**
|
|
47
|
+
* Create symlink from agent skill directory to canonical location
|
|
48
|
+
*/
|
|
49
|
+
export declare function symlinkToAgent(slug: string, agent: AgentConfig, options?: {
|
|
50
|
+
global?: boolean;
|
|
51
|
+
cwd?: string;
|
|
52
|
+
}): Promise<InstallResult>;
|
|
53
|
+
/**
|
|
54
|
+
* Install skill to multiple agents
|
|
55
|
+
* Assumes ZIP has already been extracted to canonical location
|
|
56
|
+
*/
|
|
57
|
+
export declare function installToAgents(slug: string, agents: AgentConfig[], options?: {
|
|
58
|
+
global?: boolean;
|
|
59
|
+
cwd?: string;
|
|
60
|
+
}): Promise<MultiAgentInstallResult>;
|
|
61
|
+
/**
|
|
62
|
+
* Check if skill is installed for an agent
|
|
63
|
+
*/
|
|
64
|
+
export declare function isSkillInstalledForAgent(slug: string, agent: AgentConfig, options?: {
|
|
65
|
+
global?: boolean;
|
|
66
|
+
cwd?: string;
|
|
67
|
+
}): Promise<boolean>;
|
|
68
|
+
/**
|
|
69
|
+
* Check if skill exists in canonical location
|
|
70
|
+
*/
|
|
71
|
+
export declare function isSkillInCanonical(slug: string): Promise<boolean>;
|
|
72
|
+
/**
|
|
73
|
+
* Remove skill from canonical location and all agent symlinks
|
|
74
|
+
*/
|
|
75
|
+
export declare function removeSkill(slug: string, agents: AgentConfig[], options?: {
|
|
76
|
+
global?: boolean;
|
|
77
|
+
cwd?: string;
|
|
78
|
+
}): Promise<{
|
|
79
|
+
removed: AgentId[];
|
|
80
|
+
failed: AgentId[];
|
|
81
|
+
}>;
|
|
82
|
+
//# sourceMappingURL=installer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/lib/installer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,OAAO,EAAwB,MAAM,aAAa,CAAC;AAEnF;;;;;GAKG;AAEH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,MAAM,CAAC;AAE7C,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,WAAW,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAcjD;AAYD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAChC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,MAAM,CAUR;AA8CD;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAStE;AAED;;GAEG;AACH,wBAAsB,cAAc,CACnC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,OAAO,CAAC,aAAa,CAAC,CA+CxB;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACpC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,EAAE,EACrB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,OAAO,CAAC,uBAAuB,CAAC,CAmBlC;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC7C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,OAAO,CAAC,OAAO,CAAC,CASlB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASvE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAChC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,EAAE,EACrB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,CAwBpD"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { mkdir, rm, symlink, lstat, readlink, access } from 'node:fs/promises';
|
|
2
|
+
import { join, normalize, resolve, sep, relative } from 'node:path';
|
|
3
|
+
import { platform } from 'node:os';
|
|
4
|
+
import { CANONICAL_SKILLS_DIR } from './agents.js';
|
|
5
|
+
/**
|
|
6
|
+
* Sanitizes a filename/directory name to prevent path traversal attacks
|
|
7
|
+
*/
|
|
8
|
+
export function sanitizeName(name) {
|
|
9
|
+
let sanitized = name.replace(/[\/\\:\0]/g, '');
|
|
10
|
+
sanitized = sanitized.replace(/^[.\s]+|[.\s]+$/g, '');
|
|
11
|
+
sanitized = sanitized.replace(/^\.+/, '');
|
|
12
|
+
if (!sanitized || sanitized.length === 0) {
|
|
13
|
+
sanitized = 'unnamed-skill';
|
|
14
|
+
}
|
|
15
|
+
if (sanitized.length > 255) {
|
|
16
|
+
sanitized = sanitized.substring(0, 255);
|
|
17
|
+
}
|
|
18
|
+
return sanitized;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Validates that a path is within an expected base directory
|
|
22
|
+
*/
|
|
23
|
+
function isPathSafe(basePath, targetPath) {
|
|
24
|
+
const normalizedBase = normalize(resolve(basePath));
|
|
25
|
+
const normalizedTarget = normalize(resolve(targetPath));
|
|
26
|
+
return normalizedTarget.startsWith(normalizedBase + sep) || normalizedTarget === normalizedBase;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get canonical skill directory path
|
|
30
|
+
*/
|
|
31
|
+
export function getCanonicalSkillPath(slug) {
|
|
32
|
+
const sanitized = sanitizeName(slug);
|
|
33
|
+
return join(CANONICAL_SKILLS_DIR, sanitized);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get agent-specific skill path
|
|
37
|
+
*/
|
|
38
|
+
export function getAgentSkillPath(slug, agent, options = {}) {
|
|
39
|
+
const sanitized = sanitizeName(slug);
|
|
40
|
+
const isGlobal = options.global ?? true; // Default to global for skillstore
|
|
41
|
+
if (isGlobal) {
|
|
42
|
+
return join(agent.globalPath, sanitized);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const cwd = options.cwd || process.cwd();
|
|
46
|
+
return join(cwd, agent.projectPath, sanitized);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Creates a symlink, handling cross-platform differences
|
|
51
|
+
* Returns true if symlink was created, false if fallback to copy is needed
|
|
52
|
+
*/
|
|
53
|
+
async function createSymlink(target, linkPath) {
|
|
54
|
+
try {
|
|
55
|
+
// Check if link already exists and points to correct target
|
|
56
|
+
try {
|
|
57
|
+
const stats = await lstat(linkPath);
|
|
58
|
+
if (stats.isSymbolicLink()) {
|
|
59
|
+
const existingTarget = await readlink(linkPath);
|
|
60
|
+
if (resolve(existingTarget) === resolve(target)) {
|
|
61
|
+
return true; // Already correct
|
|
62
|
+
}
|
|
63
|
+
await rm(linkPath);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
await rm(linkPath, { recursive: true });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
// ELOOP = circular symlink, ENOENT = doesn't exist
|
|
71
|
+
if (err && typeof err === 'object' && 'code' in err && err.code === 'ELOOP') {
|
|
72
|
+
try {
|
|
73
|
+
await rm(linkPath, { force: true });
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// If we can't remove it, symlink creation will fail
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Ensure parent directory exists
|
|
81
|
+
const linkDir = join(linkPath, '..');
|
|
82
|
+
await mkdir(linkDir, { recursive: true });
|
|
83
|
+
// Create relative symlink
|
|
84
|
+
const relativePath = relative(linkDir, target);
|
|
85
|
+
const symlinkType = platform() === 'win32' ? 'junction' : undefined;
|
|
86
|
+
await symlink(relativePath, linkPath, symlinkType);
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Install skill to canonical location (for later symlinking)
|
|
95
|
+
* This should be called AFTER extracting the ZIP to canonical path
|
|
96
|
+
*/
|
|
97
|
+
export async function ensureCanonicalDir(slug) {
|
|
98
|
+
const canonicalPath = getCanonicalSkillPath(slug);
|
|
99
|
+
if (!isPathSafe(CANONICAL_SKILLS_DIR, canonicalPath)) {
|
|
100
|
+
throw new Error('Invalid skill name: potential path traversal detected');
|
|
101
|
+
}
|
|
102
|
+
await mkdir(canonicalPath, { recursive: true });
|
|
103
|
+
return canonicalPath;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Create symlink from agent skill directory to canonical location
|
|
107
|
+
*/
|
|
108
|
+
export async function symlinkToAgent(slug, agent, options = {}) {
|
|
109
|
+
const canonicalPath = getCanonicalSkillPath(slug);
|
|
110
|
+
const agentPath = getAgentSkillPath(slug, agent, options);
|
|
111
|
+
// Validate paths
|
|
112
|
+
const agentBase = options.global ?? true ? agent.globalPath : join(options.cwd || process.cwd(), agent.projectPath);
|
|
113
|
+
if (!isPathSafe(agentBase, agentPath)) {
|
|
114
|
+
return {
|
|
115
|
+
success: false,
|
|
116
|
+
agentId: agent.id,
|
|
117
|
+
path: agentPath,
|
|
118
|
+
mode: 'symlink',
|
|
119
|
+
error: 'Invalid skill name: potential path traversal detected',
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
const symlinkCreated = await createSymlink(canonicalPath, agentPath);
|
|
124
|
+
if (!symlinkCreated) {
|
|
125
|
+
return {
|
|
126
|
+
success: true,
|
|
127
|
+
agentId: agent.id,
|
|
128
|
+
path: agentPath,
|
|
129
|
+
canonicalPath,
|
|
130
|
+
mode: 'symlink',
|
|
131
|
+
symlinkFailed: true,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
success: true,
|
|
136
|
+
agentId: agent.id,
|
|
137
|
+
path: agentPath,
|
|
138
|
+
canonicalPath,
|
|
139
|
+
mode: 'symlink',
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
return {
|
|
144
|
+
success: false,
|
|
145
|
+
agentId: agent.id,
|
|
146
|
+
path: agentPath,
|
|
147
|
+
mode: 'symlink',
|
|
148
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Install skill to multiple agents
|
|
154
|
+
* Assumes ZIP has already been extracted to canonical location
|
|
155
|
+
*/
|
|
156
|
+
export async function installToAgents(slug, agents, options = {}) {
|
|
157
|
+
const canonicalPath = getCanonicalSkillPath(slug);
|
|
158
|
+
const results = [];
|
|
159
|
+
for (const agent of agents) {
|
|
160
|
+
const result = await symlinkToAgent(slug, agent, options);
|
|
161
|
+
results.push(result);
|
|
162
|
+
}
|
|
163
|
+
const successCount = results.filter((r) => r.success).length;
|
|
164
|
+
return {
|
|
165
|
+
slug,
|
|
166
|
+
canonicalPath,
|
|
167
|
+
agents: results,
|
|
168
|
+
success: successCount > 0,
|
|
169
|
+
successCount,
|
|
170
|
+
failCount: results.length - successCount,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Check if skill is installed for an agent
|
|
175
|
+
*/
|
|
176
|
+
export async function isSkillInstalledForAgent(slug, agent, options = {}) {
|
|
177
|
+
const agentPath = getAgentSkillPath(slug, agent, options);
|
|
178
|
+
try {
|
|
179
|
+
await access(agentPath);
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Check if skill exists in canonical location
|
|
188
|
+
*/
|
|
189
|
+
export async function isSkillInCanonical(slug) {
|
|
190
|
+
const canonicalPath = getCanonicalSkillPath(slug);
|
|
191
|
+
try {
|
|
192
|
+
await access(canonicalPath);
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Remove skill from canonical location and all agent symlinks
|
|
201
|
+
*/
|
|
202
|
+
export async function removeSkill(slug, agents, options = {}) {
|
|
203
|
+
const removed = [];
|
|
204
|
+
const failed = [];
|
|
205
|
+
// Remove symlinks from agents
|
|
206
|
+
for (const agent of agents) {
|
|
207
|
+
const agentPath = getAgentSkillPath(slug, agent, options);
|
|
208
|
+
try {
|
|
209
|
+
await rm(agentPath, { recursive: true, force: true });
|
|
210
|
+
removed.push(agent.id);
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
failed.push(agent.id);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// Remove canonical directory
|
|
217
|
+
const canonicalPath = getCanonicalSkillPath(slug);
|
|
218
|
+
try {
|
|
219
|
+
await rm(canonicalPath, { recursive: true, force: true });
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
// Ignore errors removing canonical
|
|
223
|
+
}
|
|
224
|
+
return { removed, failed };
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/lib/installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Lock File Management
|
|
3
|
+
*
|
|
4
|
+
* Tracks installed skills with version and hash information
|
|
5
|
+
* for update detection and management.
|
|
6
|
+
*/
|
|
7
|
+
/** Lock file version - increment when schema changes */
|
|
8
|
+
export declare const LOCK_VERSION = 1;
|
|
9
|
+
/** Entry for a single installed skill */
|
|
10
|
+
export interface SkillLockEntry {
|
|
11
|
+
/** Skill slug */
|
|
12
|
+
slug: string;
|
|
13
|
+
/** Skill version */
|
|
14
|
+
version: string;
|
|
15
|
+
/** ZIP file SHA256 hash */
|
|
16
|
+
zipHash: string;
|
|
17
|
+
/** Source (always 'skillstore' for now) */
|
|
18
|
+
source: 'skillstore';
|
|
19
|
+
/** ISO timestamp when installed */
|
|
20
|
+
installedAt: string;
|
|
21
|
+
/** ISO timestamp when last updated */
|
|
22
|
+
updatedAt: string;
|
|
23
|
+
}
|
|
24
|
+
/** Lock file structure */
|
|
25
|
+
export interface SkillLock {
|
|
26
|
+
/** Lock file version */
|
|
27
|
+
version: number;
|
|
28
|
+
/** Map of slug to lock entry */
|
|
29
|
+
skills: Record<string, SkillLockEntry>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Read skill lock file
|
|
33
|
+
* Returns empty lock if file doesn't exist or is invalid
|
|
34
|
+
*/
|
|
35
|
+
export declare function readSkillLock(): Promise<SkillLock>;
|
|
36
|
+
/**
|
|
37
|
+
* Write skill lock file
|
|
38
|
+
*/
|
|
39
|
+
export declare function writeSkillLock(lock: SkillLock): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Add or update a skill in the lock file
|
|
42
|
+
*/
|
|
43
|
+
export declare function addToLock(entry: Omit<SkillLockEntry, 'updatedAt'>): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Remove a skill from the lock file
|
|
46
|
+
*/
|
|
47
|
+
export declare function removeFromLock(slug: string): Promise<boolean>;
|
|
48
|
+
/**
|
|
49
|
+
* Get a single lock entry
|
|
50
|
+
*/
|
|
51
|
+
export declare function getLockEntry(slug: string): Promise<SkillLockEntry | undefined>;
|
|
52
|
+
/**
|
|
53
|
+
* Get all locked skills
|
|
54
|
+
*/
|
|
55
|
+
export declare function getAllLockedSkills(): Promise<SkillLockEntry[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Check if a skill is in the lock file
|
|
58
|
+
*/
|
|
59
|
+
export declare function isSkillLocked(slug: string): Promise<boolean>;
|
|
60
|
+
/**
|
|
61
|
+
* Get count of locked skills
|
|
62
|
+
*/
|
|
63
|
+
export declare function getLockedSkillCount(): Promise<number>;
|
|
64
|
+
//# sourceMappingURL=skill-lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-lock.d.ts","sourceRoot":"","sources":["../../src/lib/skill-lock.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,wDAAwD;AACxD,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC9B,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,MAAM,EAAE,YAAY,CAAC;IACrB,mCAAmC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,0BAA0B;AAC1B,MAAM,WAAW,SAAS;IACzB,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACvC;AAUD;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,SAAS,CAAC,CAexD;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAMnE;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAavF;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUnE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAGpF;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAGpE;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGlE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAG3D"}
|