skillstore 0.0.1 → 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.
Files changed (54) hide show
  1. package/dist/cli/index.d.ts +3 -0
  2. package/dist/cli/index.d.ts.map +1 -0
  3. package/dist/cli/index.js +21 -0
  4. package/dist/cli/index.js.map +1 -0
  5. package/dist/commands/install.d.ts +35 -0
  6. package/dist/commands/install.d.ts.map +1 -0
  7. package/dist/commands/install.js +272 -0
  8. package/dist/commands/install.js.map +1 -0
  9. package/dist/commands/plugin/index.d.ts +3 -0
  10. package/dist/commands/plugin/index.d.ts.map +1 -0
  11. package/dist/commands/plugin/index.js +13 -0
  12. package/dist/commands/plugin/index.js.map +1 -0
  13. package/dist/commands/plugin/info.d.ts +9 -0
  14. package/dist/commands/plugin/info.d.ts.map +1 -0
  15. package/dist/commands/plugin/info.js +75 -0
  16. package/dist/commands/plugin/info.js.map +1 -0
  17. package/dist/commands/plugin/install.d.ts +29 -0
  18. package/dist/commands/plugin/install.d.ts.map +1 -0
  19. package/dist/commands/plugin/install.js +140 -0
  20. package/dist/commands/plugin/install.js.map +1 -0
  21. package/dist/commands/plugin/list.d.ts +22 -0
  22. package/dist/commands/plugin/list.d.ts.map +1 -0
  23. package/dist/commands/plugin/list.js +76 -0
  24. package/dist/commands/plugin/list.js.map +1 -0
  25. package/dist/index.d.ts +11 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +13 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/lib/plugin-api.d.ts +155 -0
  30. package/dist/lib/plugin-api.d.ts.map +1 -0
  31. package/dist/lib/plugin-api.js +173 -0
  32. package/dist/lib/plugin-api.js.map +1 -0
  33. package/dist/lib/plugin-config.d.ts +56 -0
  34. package/dist/lib/plugin-config.d.ts.map +1 -0
  35. package/dist/lib/plugin-config.js +64 -0
  36. package/dist/lib/plugin-config.js.map +1 -0
  37. package/dist/lib/plugin-download.d.ts +36 -0
  38. package/dist/lib/plugin-download.d.ts.map +1 -0
  39. package/dist/lib/plugin-download.js +134 -0
  40. package/dist/lib/plugin-download.js.map +1 -0
  41. package/dist/lib/plugin-logger.d.ts +79 -0
  42. package/dist/lib/plugin-logger.d.ts.map +1 -0
  43. package/dist/lib/plugin-logger.js +173 -0
  44. package/dist/lib/plugin-logger.js.map +1 -0
  45. package/dist/lib/plugin-verify.d.ts +36 -0
  46. package/dist/lib/plugin-verify.d.ts.map +1 -0
  47. package/dist/lib/plugin-verify.js +103 -0
  48. package/dist/lib/plugin-verify.js.map +1 -0
  49. package/dist/lib/skill-api.d.ts +33 -0
  50. package/dist/lib/skill-api.d.ts.map +1 -0
  51. package/dist/lib/skill-api.js +64 -0
  52. package/dist/lib/skill-api.js.map +1 -0
  53. package/package.json +56 -17
  54. package/src/index.js +0 -16
@@ -0,0 +1,36 @@
1
+ import type { PluginConfig } from './plugin-config.js';
2
+ import type { ManifestSkill } from './plugin-api.js';
3
+ /**
4
+ * Plugin Skill Downloader
5
+ *
6
+ * Downloads skills from the Skillstore API with concurrent downloads,
7
+ * progress tracking, and content hash verification.
8
+ */
9
+ /** Download result for a single skill */
10
+ export interface SkillDownloadResult {
11
+ slug: string;
12
+ success: boolean;
13
+ path?: string;
14
+ error?: string;
15
+ skipped?: boolean;
16
+ }
17
+ /** Download summary */
18
+ export interface DownloadSummary {
19
+ total: number;
20
+ success: number;
21
+ failed: number;
22
+ skipped: number;
23
+ results: SkillDownloadResult[];
24
+ }
25
+ /**
26
+ * Download all skills from a manifest with concurrent downloads
27
+ */
28
+ export declare function downloadAllSkills(config: PluginConfig, skills: ManifestSkill[], options?: {
29
+ overwrite?: boolean;
30
+ verifyHash?: boolean;
31
+ }): Promise<DownloadSummary>;
32
+ /**
33
+ * Print download summary
34
+ */
35
+ export declare function printDownloadSummary(summary: DownloadSummary): void;
36
+ //# sourceMappingURL=plugin-download.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-download.d.ts","sourceRoot":"","sources":["../../src/lib/plugin-download.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAKrD;;;;;GAKG;AAEH,yCAAyC;AACzC,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,uBAAuB;AACvB,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACtC,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,aAAa,EAAE,EACvB,OAAO,GAAE;IACR,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CAChB,GACJ,OAAO,CAAC,eAAe,CAAC,CA8C1B;AA0ED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAuBnE"}
@@ -0,0 +1,134 @@
1
+ import { mkdir, writeFile, access } from 'node:fs/promises';
2
+ import { dirname, join } from 'node:path';
3
+ import { downloadSkill } from './plugin-api.js';
4
+ import { verifyContentHash } from './plugin-verify.js';
5
+ import { logger } from './plugin-logger.js';
6
+ /**
7
+ * Download all skills from a manifest with concurrent downloads
8
+ */
9
+ export async function downloadAllSkills(config, skills, options = {}) {
10
+ const { overwrite = false, verifyHash = true } = options;
11
+ const results = [];
12
+ let success = 0;
13
+ let failed = 0;
14
+ let skipped = 0;
15
+ // Start progress tracking
16
+ logger.startProgress(skills.length, 'Downloading skills');
17
+ // Process skills in batches for concurrency
18
+ const batchSize = config.maxConcurrent;
19
+ for (let i = 0; i < skills.length; i += batchSize) {
20
+ const batch = skills.slice(i, i + batchSize);
21
+ const batchResults = await Promise.all(batch.map((skill) => downloadSingleSkill(config, skill, { overwrite, verifyHash })));
22
+ for (const result of batchResults) {
23
+ results.push(result);
24
+ if (result.success) {
25
+ if (result.skipped) {
26
+ skipped++;
27
+ }
28
+ else {
29
+ success++;
30
+ }
31
+ }
32
+ else {
33
+ failed++;
34
+ }
35
+ logger.incrementProgress();
36
+ }
37
+ }
38
+ logger.completeProgress();
39
+ return {
40
+ total: skills.length,
41
+ success,
42
+ failed,
43
+ skipped,
44
+ results,
45
+ };
46
+ }
47
+ /**
48
+ * Download a single skill
49
+ */
50
+ async function downloadSingleSkill(config, skill, options) {
51
+ const skillPath = join(config.installDir, `${skill.slug}.md`);
52
+ try {
53
+ // Check if skill already exists
54
+ if (!options.overwrite) {
55
+ try {
56
+ await access(skillPath);
57
+ // File exists, skip
58
+ return {
59
+ slug: skill.slug,
60
+ success: true,
61
+ path: skillPath,
62
+ skipped: true,
63
+ };
64
+ }
65
+ catch {
66
+ // File doesn't exist, continue with download
67
+ }
68
+ }
69
+ // Dry run mode - don't actually download
70
+ if (config.dryRun) {
71
+ return {
72
+ slug: skill.slug,
73
+ success: true,
74
+ path: skillPath,
75
+ skipped: true,
76
+ };
77
+ }
78
+ // Download skill content
79
+ const content = await downloadSkill(config, skill.downloadUrl);
80
+ // Verify content hash if enabled
81
+ if (options.verifyHash && skill.contentHash) {
82
+ const hashValid = verifyContentHash(content, skill.contentHash);
83
+ if (!hashValid) {
84
+ return {
85
+ slug: skill.slug,
86
+ success: false,
87
+ error: 'Content hash verification failed',
88
+ };
89
+ }
90
+ }
91
+ // Ensure directory exists
92
+ await mkdir(dirname(skillPath), { recursive: true });
93
+ // Write skill file
94
+ await writeFile(skillPath, content, 'utf-8');
95
+ return {
96
+ slug: skill.slug,
97
+ success: true,
98
+ path: skillPath,
99
+ };
100
+ }
101
+ catch (err) {
102
+ return {
103
+ slug: skill.slug,
104
+ success: false,
105
+ error: err instanceof Error ? err.message : 'Unknown error',
106
+ };
107
+ }
108
+ }
109
+ /**
110
+ * Print download summary
111
+ */
112
+ export function printDownloadSummary(summary) {
113
+ console.log('');
114
+ console.log('Download Summary:');
115
+ for (const result of summary.results) {
116
+ if (result.success) {
117
+ if (result.skipped) {
118
+ logger.skillSummary(result.slug, 'skipped');
119
+ }
120
+ else {
121
+ logger.skillSummary(result.slug, 'installed');
122
+ }
123
+ }
124
+ else {
125
+ logger.skillSummary(result.slug, 'failed');
126
+ if (result.error) {
127
+ console.log(` Error: ${result.error}`);
128
+ }
129
+ }
130
+ }
131
+ console.log('');
132
+ console.log(`Total: ${summary.total} | Installed: ${summary.success} | Skipped: ${summary.skipped} | Failed: ${summary.failed}`);
133
+ }
134
+ //# sourceMappingURL=plugin-download.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-download.js","sourceRoot":"","sources":["../../src/lib/plugin-download.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ export interface ProgressState {
2
+ current: number;
3
+ total: number;
4
+ label: string;
5
+ }
6
+ declare class PluginLogger {
7
+ private progressState;
8
+ private spinnerInterval;
9
+ private spinnerFrames;
10
+ private spinnerIndex;
11
+ /**
12
+ * Log info message
13
+ */
14
+ info(message: string): void;
15
+ /**
16
+ * Log success message
17
+ */
18
+ success(message: string): void;
19
+ /**
20
+ * Log warning message
21
+ */
22
+ warn(message: string): void;
23
+ /**
24
+ * Log error message
25
+ */
26
+ error(message: string, err?: Error): void;
27
+ /**
28
+ * Log debug message (only in DEBUG mode)
29
+ */
30
+ debug(message: string): void;
31
+ /**
32
+ * Start a spinner with message
33
+ */
34
+ startSpinner(message: string): void;
35
+ /**
36
+ * Stop the spinner
37
+ */
38
+ stopSpinner(): void;
39
+ /**
40
+ * Complete spinner with success
41
+ */
42
+ spinnerSuccess(message: string): void;
43
+ /**
44
+ * Complete spinner with error
45
+ */
46
+ spinnerError(message: string): void;
47
+ /**
48
+ * Start progress tracking
49
+ */
50
+ startProgress(total: number, label: string): void;
51
+ /**
52
+ * Update progress
53
+ */
54
+ updateProgress(current: number): void;
55
+ /**
56
+ * Increment progress by 1
57
+ */
58
+ incrementProgress(): void;
59
+ /**
60
+ * Complete progress
61
+ */
62
+ completeProgress(): void;
63
+ /**
64
+ * Render progress bar
65
+ */
66
+ private renderProgress;
67
+ /**
68
+ * Print a box with content
69
+ */
70
+ box(title: string, content: string[]): void;
71
+ /**
72
+ * Print skill installation summary
73
+ */
74
+ skillSummary(slug: string, status: 'installed' | 'skipped' | 'failed'): void;
75
+ }
76
+ /** Singleton logger instance */
77
+ export declare const logger: PluginLogger;
78
+ export {};
79
+ //# sourceMappingURL=plugin-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-logger.d.ts","sourceRoot":"","sources":["../../src/lib/plugin-logger.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACd;AAED,cAAM,YAAY;IACjB,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,aAAa,CAAsD;IAC3E,OAAO,CAAC,YAAY,CAAK;IAEzB;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI9B;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI;IAOzC;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAM5B;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAcnC;;OAEG;IACH,WAAW,IAAI,IAAI;IAQnB;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKrC;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKnC;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAKjD;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAOrC;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAOzB;;OAEG;IACH,gBAAgB,IAAI,IAAI;IASxB;;OAEG;IACH,OAAO,CAAC,cAAc;IAetB;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAe3C;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,IAAI;CAS5E;AAED,gCAAgC;AAChC,eAAO,MAAM,MAAM,cAAqB,CAAC"}
@@ -0,0 +1,173 @@
1
+ import consola from 'consola';
2
+ /**
3
+ * Plugin CLI Logger
4
+ *
5
+ * Provides styled logging and progress indicators for plugin operations.
6
+ */
7
+ /** Color codes for different log types */
8
+ const colors = {
9
+ info: '\x1b[36m', // Cyan
10
+ success: '\x1b[32m', // Green
11
+ warn: '\x1b[33m', // Yellow
12
+ error: '\x1b[31m', // Red
13
+ dim: '\x1b[90m', // Gray
14
+ reset: '\x1b[0m',
15
+ bold: '\x1b[1m',
16
+ };
17
+ class PluginLogger {
18
+ progressState = null;
19
+ spinnerInterval = null;
20
+ spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
21
+ spinnerIndex = 0;
22
+ /**
23
+ * Log info message
24
+ */
25
+ info(message) {
26
+ consola.info(message);
27
+ }
28
+ /**
29
+ * Log success message
30
+ */
31
+ success(message) {
32
+ consola.success(message);
33
+ }
34
+ /**
35
+ * Log warning message
36
+ */
37
+ warn(message) {
38
+ consola.warn(message);
39
+ }
40
+ /**
41
+ * Log error message
42
+ */
43
+ error(message, err) {
44
+ consola.error(message);
45
+ if (err && process.env.DEBUG) {
46
+ consola.error(err);
47
+ }
48
+ }
49
+ /**
50
+ * Log debug message (only in DEBUG mode)
51
+ */
52
+ debug(message) {
53
+ if (process.env.DEBUG) {
54
+ consola.debug(message);
55
+ }
56
+ }
57
+ /**
58
+ * Start a spinner with message
59
+ */
60
+ startSpinner(message) {
61
+ this.stopSpinner();
62
+ this.spinnerIndex = 0;
63
+ const spin = () => {
64
+ const frame = this.spinnerFrames[this.spinnerIndex];
65
+ process.stdout.write(`\r${colors.info}${frame}${colors.reset} ${message}`);
66
+ this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;
67
+ };
68
+ spin();
69
+ this.spinnerInterval = setInterval(spin, 80);
70
+ }
71
+ /**
72
+ * Stop the spinner
73
+ */
74
+ stopSpinner() {
75
+ if (this.spinnerInterval) {
76
+ clearInterval(this.spinnerInterval);
77
+ this.spinnerInterval = null;
78
+ process.stdout.write('\r\x1b[K'); // Clear line
79
+ }
80
+ }
81
+ /**
82
+ * Complete spinner with success
83
+ */
84
+ spinnerSuccess(message) {
85
+ this.stopSpinner();
86
+ console.log(`${colors.success}✓${colors.reset} ${message}`);
87
+ }
88
+ /**
89
+ * Complete spinner with error
90
+ */
91
+ spinnerError(message) {
92
+ this.stopSpinner();
93
+ console.log(`${colors.error}✗${colors.reset} ${message}`);
94
+ }
95
+ /**
96
+ * Start progress tracking
97
+ */
98
+ startProgress(total, label) {
99
+ this.progressState = { current: 0, total, label };
100
+ this.renderProgress();
101
+ }
102
+ /**
103
+ * Update progress
104
+ */
105
+ updateProgress(current) {
106
+ if (this.progressState) {
107
+ this.progressState.current = current;
108
+ this.renderProgress();
109
+ }
110
+ }
111
+ /**
112
+ * Increment progress by 1
113
+ */
114
+ incrementProgress() {
115
+ if (this.progressState) {
116
+ this.progressState.current++;
117
+ this.renderProgress();
118
+ }
119
+ }
120
+ /**
121
+ * Complete progress
122
+ */
123
+ completeProgress() {
124
+ if (this.progressState) {
125
+ process.stdout.write('\r\x1b[K'); // Clear line
126
+ const { total, label } = this.progressState;
127
+ console.log(`${colors.success}✓${colors.reset} ${label} (${total}/${total})`);
128
+ this.progressState = null;
129
+ }
130
+ }
131
+ /**
132
+ * Render progress bar
133
+ */
134
+ renderProgress() {
135
+ if (!this.progressState)
136
+ return;
137
+ const { current, total, label } = this.progressState;
138
+ const percent = Math.round((current / total) * 100);
139
+ const barWidth = 20;
140
+ const filled = Math.round((current / total) * barWidth);
141
+ const empty = barWidth - filled;
142
+ const bar = `${'█'.repeat(filled)}${'░'.repeat(empty)}`;
143
+ process.stdout.write(`\r${colors.info}↓${colors.reset} ${label} ${colors.dim}[${bar}]${colors.reset} ${current}/${total} (${percent}%)`);
144
+ }
145
+ /**
146
+ * Print a box with content
147
+ */
148
+ box(title, content) {
149
+ const width = Math.max(title.length, ...content.map((c) => c.length)) + 4;
150
+ const border = '─'.repeat(width);
151
+ console.log(`${colors.dim}┌${border}┐${colors.reset}`);
152
+ console.log(`${colors.dim}│${colors.reset} ${colors.bold}${title.padEnd(width - 2)}${colors.reset} ${colors.dim}│${colors.reset}`);
153
+ console.log(`${colors.dim}├${border}┤${colors.reset}`);
154
+ for (const line of content) {
155
+ console.log(`${colors.dim}│${colors.reset} ${line.padEnd(width - 2)} ${colors.dim}│${colors.reset}`);
156
+ }
157
+ console.log(`${colors.dim}└${border}┘${colors.reset}`);
158
+ }
159
+ /**
160
+ * Print skill installation summary
161
+ */
162
+ skillSummary(slug, status) {
163
+ const icons = {
164
+ installed: `${colors.success}✓${colors.reset}`,
165
+ skipped: `${colors.warn}○${colors.reset}`,
166
+ failed: `${colors.error}✗${colors.reset}`,
167
+ };
168
+ console.log(` ${icons[status]} ${slug}`);
169
+ }
170
+ }
171
+ /** Singleton logger instance */
172
+ export const logger = new PluginLogger();
173
+ //# sourceMappingURL=plugin-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-logger.js","sourceRoot":"","sources":["../../src/lib/plugin-logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { PluginManifest } from './plugin-api.js';
2
+ /**
3
+ * Plugin Manifest Verification
4
+ *
5
+ * Verifies HMAC-SHA256 signatures on plugin manifests to ensure integrity.
6
+ */
7
+ /** Verification result */
8
+ export interface VerifyResult {
9
+ valid: boolean;
10
+ error?: string;
11
+ }
12
+ /**
13
+ * Get the signing key from environment
14
+ * In production, this should be a public key or verification endpoint
15
+ * For CLI, we use a shared secret (configured by user or fetched from API)
16
+ */
17
+ export declare function getVerificationKey(): string | null;
18
+ /**
19
+ * Verify manifest signature using HMAC-SHA256
20
+ *
21
+ * The signature is computed over the manifest JSON without the signature field.
22
+ */
23
+ export declare function verifyManifestSignature(manifest: PluginManifest, key: string): VerifyResult;
24
+ /**
25
+ * Verify skill content hash
26
+ *
27
+ * Ensures downloaded skill content matches the hash in the manifest.
28
+ */
29
+ export declare function verifyContentHash(content: string, expectedHash: string): boolean;
30
+ /**
31
+ * Verify entire manifest (signature + metadata)
32
+ */
33
+ export declare function verifyManifest(manifest: PluginManifest, options?: {
34
+ skipSignature?: boolean;
35
+ }): Promise<VerifyResult>;
36
+ //# sourceMappingURL=plugin-verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-verify.d.ts","sourceRoot":"","sources":["../../src/lib/plugin-verify.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;;;GAIG;AAEH,0BAA0B;AAC1B,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAIlD;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACtC,QAAQ,EAAE,cAAc,EACxB,GAAG,EAAE,MAAM,GACT,YAAY,CA6Bd;AAgBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAMhF;AAED;;GAEG;AACH,wBAAsB,cAAc,CACnC,QAAQ,EAAE,cAAc,EACxB,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GACvC,OAAO,CAAC,YAAY,CAAC,CAyCvB"}
@@ -0,0 +1,103 @@
1
+ import { createHmac, createHash, timingSafeEqual as cryptoTimingSafeEqual } from 'node:crypto';
2
+ /**
3
+ * Get the signing key from environment
4
+ * In production, this should be a public key or verification endpoint
5
+ * For CLI, we use a shared secret (configured by user or fetched from API)
6
+ */
7
+ export function getVerificationKey() {
8
+ // The verification key can be set via environment variable
9
+ // In production, this might be fetched from a public endpoint
10
+ return process.env.SKILLSTORE_VERIFY_KEY || null;
11
+ }
12
+ /**
13
+ * Verify manifest signature using HMAC-SHA256
14
+ *
15
+ * The signature is computed over the manifest JSON without the signature field.
16
+ */
17
+ export function verifyManifestSignature(manifest, key) {
18
+ try {
19
+ // Extract signature and create unsigned manifest
20
+ const { signature, ...unsignedManifest } = manifest;
21
+ if (!signature) {
22
+ return { valid: false, error: 'Manifest has no signature' };
23
+ }
24
+ // Compute expected signature (matching server-side implementation)
25
+ const dataToSign = JSON.stringify(unsignedManifest, null, 0);
26
+ const expectedSignature = createHmac('sha256', key)
27
+ .update(dataToSign)
28
+ .digest('hex');
29
+ // Constant-time comparison to prevent timing attacks
30
+ const valid = timingSafeEqual(signature, expectedSignature);
31
+ if (!valid) {
32
+ return { valid: false, error: 'Signature verification failed' };
33
+ }
34
+ return { valid: true };
35
+ }
36
+ catch (err) {
37
+ return {
38
+ valid: false,
39
+ error: `Verification error: ${err instanceof Error ? err.message : 'Unknown error'}`,
40
+ };
41
+ }
42
+ }
43
+ /**
44
+ * Constant-time string comparison to prevent timing attacks
45
+ */
46
+ function timingSafeEqual(a, b) {
47
+ if (a.length !== b.length) {
48
+ return false;
49
+ }
50
+ const bufA = Buffer.from(a, 'utf8');
51
+ const bufB = Buffer.from(b, 'utf8');
52
+ return cryptoTimingSafeEqual(bufA, bufB);
53
+ }
54
+ /**
55
+ * Verify skill content hash
56
+ *
57
+ * Ensures downloaded skill content matches the hash in the manifest.
58
+ */
59
+ export function verifyContentHash(content, expectedHash) {
60
+ const actualHash = createHash('sha256').update(content).digest('hex');
61
+ // Content hash might be truncated, compare common length
62
+ const compareLength = Math.min(actualHash.length, expectedHash.length);
63
+ return actualHash.substring(0, compareLength) === expectedHash.substring(0, compareLength);
64
+ }
65
+ /**
66
+ * Verify entire manifest (signature + metadata)
67
+ */
68
+ export async function verifyManifest(manifest, options = {}) {
69
+ // Validate manifest structure
70
+ if (!manifest.version || manifest.version !== '1.0') {
71
+ return { valid: false, error: 'Unsupported manifest version' };
72
+ }
73
+ if (!manifest.plugin?.slug) {
74
+ return { valid: false, error: 'Missing plugin slug in manifest' };
75
+ }
76
+ if (!Array.isArray(manifest.skills) || manifest.skills.length === 0) {
77
+ return { valid: false, error: 'Manifest contains no skills' };
78
+ }
79
+ // Validate skill entries
80
+ for (const skill of manifest.skills) {
81
+ if (!skill.slug || !skill.downloadUrl) {
82
+ return { valid: false, error: `Invalid skill entry: ${skill.slug || 'unknown'}` };
83
+ }
84
+ }
85
+ // Verify signature unless skipped
86
+ if (!options.skipSignature) {
87
+ const key = getVerificationKey();
88
+ if (!key) {
89
+ // If no key is configured, warn but don't fail
90
+ // This allows installation without signature verification
91
+ return {
92
+ valid: true,
93
+ error: 'Warning: No verification key configured, signature not verified',
94
+ };
95
+ }
96
+ const signatureResult = verifyManifestSignature(manifest, key);
97
+ if (!signatureResult.valid) {
98
+ return signatureResult;
99
+ }
100
+ }
101
+ return { valid: true };
102
+ }
103
+ //# sourceMappingURL=plugin-verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-verify.js","sourceRoot":"","sources":["../../src/lib/plugin-verify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { PluginConfig } from './plugin-config.js';
2
+ /**
3
+ * Skill API Client
4
+ *
5
+ * Handles HTTP requests for single skill operations.
6
+ */
7
+ /** Skill info response */
8
+ export interface SkillInfo {
9
+ slug: string;
10
+ name: string;
11
+ description: string | null;
12
+ category: string | null;
13
+ version: string | null;
14
+ author: string | null;
15
+ riskLevel: string | null;
16
+ qualityScore: number | null;
17
+ pluginPath: string | null;
18
+ }
19
+ /** API Error */
20
+ export declare class SkillApiError extends Error {
21
+ statusCode: number;
22
+ code?: string | undefined;
23
+ constructor(message: string, statusCode: number, code?: string | undefined);
24
+ }
25
+ /**
26
+ * Fetch skill info/details
27
+ */
28
+ export declare function fetchSkillInfo(config: PluginConfig, skillSlug: string): Promise<SkillInfo>;
29
+ /**
30
+ * Download skill as ZIP
31
+ */
32
+ export declare function downloadSkillZip(config: PluginConfig, skillSlug: string): Promise<ArrayBuffer>;
33
+ //# sourceMappingURL=skill-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-api.d.ts","sourceRoot":"","sources":["../../src/lib/skill-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;GAIG;AAEH,0BAA0B;AAC1B,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,gBAAgB;AAChB,qBAAa,aAAc,SAAQ,KAAK;IAG/B,UAAU,EAAE,MAAM;IAClB,IAAI,CAAC,EAAE,MAAM;gBAFpB,OAAO,EAAE,MAAM,EACR,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,MAAM,YAAA;CAKrB;AAgBD;;GAEG;AACH,wBAAsB,cAAc,CACnC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,CAAC,CA6BpB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACrC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,CAAC,CAgBtB"}