skillvault-publisher 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 (65) hide show
  1. package/dist/commands/decrypt.d.ts +3 -0
  2. package/dist/commands/decrypt.d.ts.map +1 -0
  3. package/dist/commands/decrypt.js +152 -0
  4. package/dist/commands/decrypt.js.map +1 -0
  5. package/dist/commands/info.d.ts +3 -0
  6. package/dist/commands/info.d.ts.map +1 -0
  7. package/dist/commands/info.js +30 -0
  8. package/dist/commands/info.js.map +1 -0
  9. package/dist/commands/init.d.ts +3 -0
  10. package/dist/commands/init.d.ts.map +1 -0
  11. package/dist/commands/init.js +83 -0
  12. package/dist/commands/init.js.map +1 -0
  13. package/dist/commands/install.d.ts +3 -0
  14. package/dist/commands/install.d.ts.map +1 -0
  15. package/dist/commands/install.js +149 -0
  16. package/dist/commands/install.js.map +1 -0
  17. package/dist/commands/licenses.d.ts +3 -0
  18. package/dist/commands/licenses.d.ts.map +1 -0
  19. package/dist/commands/licenses.js +96 -0
  20. package/dist/commands/licenses.js.map +1 -0
  21. package/dist/commands/login.d.ts +3 -0
  22. package/dist/commands/login.d.ts.map +1 -0
  23. package/dist/commands/login.js +89 -0
  24. package/dist/commands/login.js.map +1 -0
  25. package/dist/commands/logout.d.ts +3 -0
  26. package/dist/commands/logout.d.ts.map +1 -0
  27. package/dist/commands/logout.js +11 -0
  28. package/dist/commands/logout.js.map +1 -0
  29. package/dist/commands/publish.d.ts +3 -0
  30. package/dist/commands/publish.d.ts.map +1 -0
  31. package/dist/commands/publish.js +215 -0
  32. package/dist/commands/publish.js.map +1 -0
  33. package/dist/commands/report.d.ts +3 -0
  34. package/dist/commands/report.d.ts.map +1 -0
  35. package/dist/commands/report.js +72 -0
  36. package/dist/commands/report.js.map +1 -0
  37. package/dist/commands/search.d.ts +3 -0
  38. package/dist/commands/search.d.ts.map +1 -0
  39. package/dist/commands/search.js +79 -0
  40. package/dist/commands/search.js.map +1 -0
  41. package/dist/commands/update.d.ts +3 -0
  42. package/dist/commands/update.d.ts.map +1 -0
  43. package/dist/commands/update.js +152 -0
  44. package/dist/commands/update.js.map +1 -0
  45. package/dist/commands/whoami.d.ts +3 -0
  46. package/dist/commands/whoami.d.ts.map +1 -0
  47. package/dist/commands/whoami.js +128 -0
  48. package/dist/commands/whoami.js.map +1 -0
  49. package/dist/credentials.d.ts +32 -0
  50. package/dist/credentials.d.ts.map +1 -0
  51. package/dist/credentials.js +106 -0
  52. package/dist/credentials.js.map +1 -0
  53. package/dist/fingerprint.d.ts +18 -0
  54. package/dist/fingerprint.d.ts.map +1 -0
  55. package/dist/fingerprint.js +51 -0
  56. package/dist/fingerprint.js.map +1 -0
  57. package/dist/grant-cache.d.ts +40 -0
  58. package/dist/grant-cache.d.ts.map +1 -0
  59. package/dist/grant-cache.js +112 -0
  60. package/dist/grant-cache.js.map +1 -0
  61. package/dist/index.d.ts +3 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +33 -0
  64. package/dist/index.js.map +1 -0
  65. package/package.json +35 -0
@@ -0,0 +1,89 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import * as jose from 'jose';
4
+ import { saveConfig, storeKeypair } from '../credentials.js';
5
+ export const loginCommand = new Command('login')
6
+ .description('Authenticate with the Skill Vault server')
7
+ .option('--license-key <key>', 'Authenticate with a license key')
8
+ .option('--code <code>', 'Authenticate with an invite code')
9
+ .option('--server <url>', 'Server URL', 'http://localhost:3001')
10
+ .action(async (options) => {
11
+ try {
12
+ const serverUrl = options.server;
13
+ // Generate Ed25519 host keypair
14
+ const { publicKey, privateKey } = await jose.generateKeyPair('EdDSA', { crv: 'Ed25519', extractable: true });
15
+ const publicKeyJWK = await jose.exportJWK(publicKey);
16
+ publicKeyJWK.alg = 'EdDSA';
17
+ const privateKeyJWK = await jose.exportJWK(privateKey);
18
+ const thumbprint = await jose.calculateJwkThumbprint(publicKeyJWK, 'sha256');
19
+ // Generate agent keypair
20
+ const { publicKey: agentPub, privateKey: agentPriv } = await jose.generateKeyPair('EdDSA', { crv: 'Ed25519', extractable: true });
21
+ const agentPubJWK = await jose.exportJWK(agentPub);
22
+ agentPubJWK.alg = 'EdDSA';
23
+ const agentPrivJWK = await jose.exportJWK(agentPriv);
24
+ // Sign host JWT
25
+ const hostJWT = await new jose.SignJWT({
26
+ iss: thumbprint,
27
+ aud: serverUrl,
28
+ host_public_key: publicKeyJWK,
29
+ agent_public_key: agentPubJWK,
30
+ jti: crypto.randomUUID(),
31
+ })
32
+ .setProtectedHeader({ alg: 'EdDSA', typ: 'host+jwt' })
33
+ .setIssuedAt()
34
+ .setExpirationTime('60s')
35
+ .sign(privateKey);
36
+ // Register with server
37
+ const body = {
38
+ name: `cli-${process.env.USER || 'user'}`,
39
+ capabilities: [],
40
+ mode: 'delegated',
41
+ };
42
+ if (options.licenseKey) {
43
+ body.license_key = options.licenseKey;
44
+ }
45
+ const response = await fetch(`${serverUrl}/agent/register`, {
46
+ method: 'POST',
47
+ headers: {
48
+ 'Content-Type': 'application/json',
49
+ Authorization: `Bearer ${hostJWT}`,
50
+ },
51
+ body: JSON.stringify(body),
52
+ });
53
+ if (!response.ok) {
54
+ const err = await response.json().catch(() => ({ error: 'unknown', message: response.statusText }));
55
+ console.error(chalk.red(`Login failed: ${err.message}`));
56
+ process.exit(1);
57
+ }
58
+ const result = await response.json();
59
+ // Handle invite code redemption
60
+ if (options.code) {
61
+ const redeemRes = await fetch(`${serverUrl}/invites/redeem`, {
62
+ method: 'POST',
63
+ headers: { 'Content-Type': 'application/json' },
64
+ body: JSON.stringify({ code: options.code, host_public_key: publicKeyJWK }),
65
+ });
66
+ if (!redeemRes.ok) {
67
+ console.warn(chalk.yellow('Warning: Invite code redemption failed'));
68
+ }
69
+ }
70
+ // Store credentials
71
+ storeKeypair({ host: privateKeyJWK, agent: agentPrivJWK }, { host: publicKeyJWK, agent: agentPubJWK });
72
+ saveConfig({
73
+ server_url: serverUrl,
74
+ host_id: result.host_id,
75
+ agent_id: result.agent_id,
76
+ host_thumbprint: thumbprint,
77
+ });
78
+ console.log(chalk.green('Logged in successfully.'));
79
+ console.log(` Host ID: ${result.host_id}`);
80
+ console.log(` Agent ID: ${result.agent_id}`);
81
+ console.log(` Status: ${result.status}`);
82
+ }
83
+ catch (err) {
84
+ const message = err instanceof Error ? err.message : String(err);
85
+ console.error(chalk.red(`Login failed: ${message}`));
86
+ process.exit(1);
87
+ }
88
+ });
89
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const logoutCommand: Command;
3
+ //# sourceMappingURL=logout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,aAAa,SAMtB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { removeConfig, removeKeypair } from '../credentials.js';
4
+ export const logoutCommand = new Command('logout')
5
+ .description('Remove stored credentials')
6
+ .action(() => {
7
+ removeKeypair();
8
+ removeConfig();
9
+ console.log(chalk.green('Logged out successfully'));
10
+ });
11
+ //# sourceMappingURL=logout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEhE,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,2BAA2B,CAAC;KACxC,MAAM,CAAC,GAAG,EAAE;IACX,aAAa,EAAE,CAAC;IAChB,YAAY,EAAE,CAAC;IACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const publishCommand: Command;
3
+ //# sourceMappingURL=publish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyBpC,eAAO,MAAM,cAAc,SAuNvB,CAAC"}
@@ -0,0 +1,215 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import * as jose from 'jose';
4
+ import { readFileSync, existsSync, statSync } from 'node:fs';
5
+ import { resolve, join } from 'node:path';
6
+ import { createHash } from 'node:crypto';
7
+ import { packSkillDirectory, writeVault, generateCEK } from 'skillvault-shared';
8
+ import { getConfig, getKeypair } from '../credentials.js';
9
+ /** Minimal frontmatter parser for SKILL.md */
10
+ function parseFrontmatter(content) {
11
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
12
+ if (!match)
13
+ return {};
14
+ const result = {};
15
+ for (const line of match[1].split('\n')) {
16
+ const idx = line.indexOf(':');
17
+ if (idx === -1)
18
+ continue;
19
+ const key = line.slice(0, idx).trim();
20
+ const value = line.slice(idx + 1).trim();
21
+ result[key] = value;
22
+ }
23
+ return result;
24
+ }
25
+ export const publishCommand = new Command('publish')
26
+ .description('Encrypt and publish a skill to the registry')
27
+ .argument('[directory]', 'Skill directory to publish', '.')
28
+ .option('--name <name>', 'Skill name (overrides SKILL.md frontmatter)')
29
+ .option('--price <price>', 'Price per month (e.g. 9.99/month)')
30
+ .option('--description <desc>', 'Description (overrides SKILL.md frontmatter)')
31
+ .option('--force', 'Force re-publish even if content unchanged')
32
+ .option('--changelog <message>', 'Changelog message for this version')
33
+ .option('--publisher <id>', 'Publisher ID (defaults to host_id from login)')
34
+ .action(async (directory, options) => {
35
+ try {
36
+ const config = getConfig();
37
+ if (!config) {
38
+ process.stderr.write(chalk.red('Not logged in. Run `skillvault login` first.\n'));
39
+ process.exit(1);
40
+ }
41
+ const keypair = getKeypair();
42
+ if (!keypair) {
43
+ process.stderr.write(chalk.red('Credentials not found. Run `skillvault login` first.\n'));
44
+ process.exit(1);
45
+ }
46
+ const dirPath = resolve(directory);
47
+ if (!existsSync(dirPath) || !statSync(dirPath).isDirectory()) {
48
+ process.stderr.write(chalk.red(`Error: "${dirPath}" is not a valid directory\n`));
49
+ process.exit(1);
50
+ }
51
+ // Validate SKILL.md exists
52
+ const skillMdPath = join(dirPath, 'SKILL.md');
53
+ if (!existsSync(skillMdPath)) {
54
+ process.stderr.write(chalk.red('Error: SKILL.md not found in the skill directory\n'));
55
+ process.stderr.write(chalk.dim('Create a SKILL.md with frontmatter (name, description, version)\n'));
56
+ process.exit(1);
57
+ }
58
+ // Parse SKILL.md frontmatter
59
+ const skillMdContent = readFileSync(skillMdPath, 'utf8');
60
+ const frontmatter = parseFrontmatter(skillMdContent);
61
+ const skillName = options.name || frontmatter.name;
62
+ const description = options.description || frontmatter.description;
63
+ const version = frontmatter.version;
64
+ if (!skillName) {
65
+ process.stderr.write(chalk.red('Error: Skill name required — set in SKILL.md frontmatter or use --name\n'));
66
+ process.exit(1);
67
+ }
68
+ if (!description) {
69
+ process.stderr.write(chalk.red('Error: Description required — set in SKILL.md frontmatter or use --description\n'));
70
+ process.exit(1);
71
+ }
72
+ if (!version) {
73
+ process.stderr.write(chalk.red('Error: Version required in SKILL.md frontmatter (e.g. version: 1.0.0)\n'));
74
+ process.exit(1);
75
+ }
76
+ // Pack directory
77
+ const packed = packSkillDirectory(dirPath);
78
+ const fileCount = Object.keys(packed.files).length;
79
+ // Generate CEK and encrypt
80
+ const cek = generateCEK();
81
+ const contentHash = createHash('sha256')
82
+ .update(Buffer.concat(Object.values(packed.files)))
83
+ .digest('hex');
84
+ const metadata = {
85
+ name: skillName,
86
+ description,
87
+ version,
88
+ publisher: config.host_thumbprint,
89
+ publishedAt: new Date().toISOString(),
90
+ contentHash,
91
+ fileCount,
92
+ };
93
+ const vaultData = writeVault({
94
+ files: packed.files,
95
+ metadata,
96
+ key: cek,
97
+ });
98
+ // Compute SHA-256 of vault for integrity
99
+ const vaultHash = createHash('sha256').update(vaultData).digest('hex');
100
+ // Prepare signing key for host JWTs
101
+ const hostPrivJWK = keypair.privateKey.host;
102
+ const hostPubJWK = keypair.publicKey.host;
103
+ const hostPrivKey = await jose.importJWK(hostPrivJWK, 'EdDSA');
104
+ const hostThumbprint = config.host_thumbprint;
105
+ const serverUrl = config.server_url;
106
+ async function makeAuthHeaders() {
107
+ const jwt = await new jose.SignJWT({
108
+ iss: hostThumbprint,
109
+ aud: serverUrl,
110
+ host_public_key: hostPubJWK,
111
+ jti: crypto.randomUUID(),
112
+ })
113
+ .setProtectedHeader({ alg: 'EdDSA', typ: 'host+jwt' })
114
+ .setIssuedAt()
115
+ .setExpirationTime('60s')
116
+ .sign(hostPrivKey);
117
+ return {
118
+ 'Content-Type': 'application/json',
119
+ Authorization: `Bearer ${jwt}`,
120
+ };
121
+ }
122
+ // Register capability with server
123
+ const capabilityName = `skill/${skillName}`;
124
+ const registerBody = {
125
+ name: capabilityName,
126
+ description,
127
+ type: 'encrypted-skill',
128
+ vault_format: {
129
+ algorithm: 'aes-256-gcm',
130
+ format_version: '1',
131
+ },
132
+ billing: options.price
133
+ ? {
134
+ model: 'subscription',
135
+ price: options.price.replace('/month', ''),
136
+ currency: 'usd',
137
+ }
138
+ : undefined,
139
+ watermark_policy: {
140
+ enabled: true,
141
+ methods: ['zero-width'],
142
+ },
143
+ delivery: {
144
+ mode: 'bundle',
145
+ },
146
+ publisher_id: options.publisher || config.publisher_id || config.host_id,
147
+ };
148
+ const registerRes = await fetch(`${config.server_url}/capability/register`, {
149
+ method: 'POST',
150
+ headers: await makeAuthHeaders(),
151
+ body: JSON.stringify(registerBody),
152
+ });
153
+ if (!registerRes.ok) {
154
+ const err = await registerRes.json().catch(() => ({
155
+ error: 'unknown',
156
+ message: registerRes.statusText,
157
+ }));
158
+ // If capability already exists and no --force, check hash
159
+ if (err.error === 'already_granted' && !options.force) {
160
+ process.stderr.write(chalk.yellow(`Capability '${capabilityName}' already exists. Use --force to re-publish.\n`));
161
+ process.exit(1);
162
+ }
163
+ else if (err.error !== 'already_granted') {
164
+ process.stderr.write(chalk.red(`Failed to register capability: ${err.message}\n`));
165
+ process.exit(1);
166
+ }
167
+ // If --force and already_granted, continue to publish new version
168
+ }
169
+ // Publish skill version to server
170
+ const publishBody = {
171
+ capability_name: capabilityName,
172
+ name: skillName,
173
+ version,
174
+ description,
175
+ vault_data: vaultData.toString('base64'),
176
+ vault_hash: vaultHash,
177
+ content_hash: contentHash,
178
+ cek: cek.toString('base64'),
179
+ file_count: fileCount,
180
+ changelog: options.changelog || null,
181
+ };
182
+ const publishRes = await fetch(`${config.server_url}/skills/publish`, {
183
+ method: 'POST',
184
+ headers: await makeAuthHeaders(),
185
+ body: JSON.stringify(publishBody),
186
+ });
187
+ if (!publishRes.ok) {
188
+ const err = await publishRes.json().catch(() => ({
189
+ error: 'unknown',
190
+ message: publishRes.statusText,
191
+ }));
192
+ // Handle content-unchanged case
193
+ if (err.error === 'content_unchanged' && !options.force) {
194
+ process.stderr.write(chalk.yellow(`Content unchanged for ${skillName} v${version}. Use --force to re-publish.\n`));
195
+ process.exit(0);
196
+ }
197
+ process.stderr.write(chalk.red(`Failed to publish: ${err.message}\n`));
198
+ process.exit(1);
199
+ }
200
+ console.log(chalk.green(`Published ${skillName} v${version}`));
201
+ console.log(chalk.dim(` Vault hash: ${vaultHash.substring(0, 16)}...`));
202
+ console.log(chalk.dim(` Files: ${fileCount}`));
203
+ console.log(chalk.dim(` Capability: ${capabilityName}`));
204
+ console.log('');
205
+ console.log(chalk.yellow(' Tip: Your SKILL.md frontmatter (name, description) is visible'));
206
+ console.log(chalk.yellow(' to customers and used for skill discovery. Keep IP in the body,'));
207
+ console.log(chalk.yellow(' not the frontmatter. The body stays encrypted until runtime.'));
208
+ }
209
+ catch (err) {
210
+ const message = err instanceof Error ? err.message : String(err);
211
+ process.stderr.write(chalk.red(`Publish failed: ${message}\n`));
212
+ process.exit(1);
213
+ }
214
+ });
215
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const reportCommand: Command;
3
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/commands/report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,aAAa,SAwEtB,CAAC"}
@@ -0,0 +1,72 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import * as jose from 'jose';
4
+ import { getConfig, getKeypair } from '../credentials.js';
5
+ export const reportCommand = new Command('report')
6
+ .description('Report a telemetry event (metadata only, no conversation content)')
7
+ .option('--skill <name>', 'Skill name associated with the event')
8
+ .option('--event <type>', 'Event type (e.g. decrypt, error, usage)', 'usage')
9
+ .option('--status <status>', 'Event status (success, failure, error)', 'success')
10
+ .option('--detail <detail>', 'Additional detail string')
11
+ .action(async (options) => {
12
+ try {
13
+ const config = getConfig();
14
+ if (!config) {
15
+ process.stderr.write(chalk.red('Not logged in. Run `skillvault login` first.\n'));
16
+ process.exit(1);
17
+ }
18
+ const keypair = getKeypair();
19
+ if (!keypair) {
20
+ process.stderr.write(chalk.red('Credentials not found. Run `skillvault login` first.\n'));
21
+ process.exit(1);
22
+ }
23
+ // Sign agent JWT
24
+ const agentPrivJWK = keypair.privateKey.agent;
25
+ const agentPubJWK = keypair.publicKey.agent;
26
+ const agentPrivKey = await jose.importJWK(agentPrivJWK, 'EdDSA');
27
+ const agentJWT = await new jose.SignJWT({
28
+ iss: config.host_thumbprint,
29
+ sub: config.agent_id,
30
+ aud: config.server_url,
31
+ agent_public_key: agentPubJWK,
32
+ jti: crypto.randomUUID(),
33
+ })
34
+ .setProtectedHeader({ alg: 'EdDSA', typ: 'agent+jwt' })
35
+ .setIssuedAt()
36
+ .setExpirationTime('60s')
37
+ .sign(agentPrivKey);
38
+ // POST telemetry event
39
+ const eventBody = {
40
+ event_type: options.event,
41
+ skill: options.skill || null,
42
+ status: options.status,
43
+ detail: options.detail || null,
44
+ agent_id: config.agent_id,
45
+ host_id: config.host_id,
46
+ timestamp: new Date().toISOString(),
47
+ };
48
+ const response = await fetch(`${config.server_url}/telemetry/events`, {
49
+ method: 'POST',
50
+ headers: {
51
+ 'Content-Type': 'application/json',
52
+ Authorization: `Bearer ${agentJWT}`,
53
+ },
54
+ body: JSON.stringify(eventBody),
55
+ });
56
+ if (!response.ok) {
57
+ const err = await response.json().catch(() => ({
58
+ error: 'unknown',
59
+ message: response.statusText,
60
+ }));
61
+ process.stderr.write(chalk.red(`Report failed: ${err.message}\n`));
62
+ process.exit(1);
63
+ }
64
+ console.log(chalk.dim('Event reported.'));
65
+ }
66
+ catch (err) {
67
+ const message = err instanceof Error ? err.message : String(err);
68
+ process.stderr.write(chalk.red(`Report failed: ${message}\n`));
69
+ process.exit(1);
70
+ }
71
+ });
72
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/commands/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const searchCommand: Command;
3
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,eAAO,MAAM,aAAa,SAkFtB,CAAC"}
@@ -0,0 +1,79 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { getConfig } from '../credentials.js';
4
+ export const searchCommand = new Command('search')
5
+ .description('Search for skills in the registry')
6
+ .argument('<query>', 'Search query')
7
+ .option('--type <type>', 'Filter by capability type')
8
+ .option('--publisher <publisher>', 'Filter by publisher')
9
+ .option('--json', 'Output results as JSON')
10
+ .action(async (query, options) => {
11
+ try {
12
+ const config = getConfig();
13
+ const serverUrl = config?.server_url ?? 'http://localhost:3001';
14
+ // Build query parameters
15
+ const params = new URLSearchParams({ q: query });
16
+ if (options.type)
17
+ params.set('type', options.type);
18
+ if (options.publisher)
19
+ params.set('publisher', options.publisher);
20
+ const response = await fetch(`${serverUrl}/api/skills/search?${params.toString()}`);
21
+ if (!response.ok) {
22
+ const err = await response.json().catch(() => ({ message: response.statusText }));
23
+ console.error(chalk.red(`Search failed: ${err.message}`));
24
+ process.exit(1);
25
+ }
26
+ const data = await response.json();
27
+ // JSON output mode
28
+ if (options.json) {
29
+ console.log(JSON.stringify(data, null, 2));
30
+ return;
31
+ }
32
+ // No results
33
+ if (!data.results || data.results.length === 0) {
34
+ console.log(chalk.yellow(`\n No skills found for "${query}".`));
35
+ if (data.suggestions && data.suggestions.length > 0) {
36
+ console.log(chalk.dim(`\n Did you mean: ${data.suggestions.join(', ')}?`));
37
+ }
38
+ console.log(chalk.dim(`\n Try a broader search or check https://skillvault.dev/explore\n`));
39
+ return;
40
+ }
41
+ // Display results as formatted table
42
+ console.log();
43
+ console.log(chalk.bold(` Found ${data.total ?? data.results.length} skill${data.results.length === 1 ? '' : 's'}:`));
44
+ console.log();
45
+ // Column widths
46
+ const nameWidth = Math.max(20, ...data.results.map((r) => r.name.length + 2));
47
+ const pubWidth = Math.max(12, ...data.results.map((r) => r.publisher.length + 2));
48
+ const verWidth = 10;
49
+ const typeWidth = 12;
50
+ // Header
51
+ const header = [
52
+ chalk.dim('Name'.padEnd(nameWidth)),
53
+ chalk.dim('Publisher'.padEnd(pubWidth)),
54
+ chalk.dim('Version'.padEnd(verWidth)),
55
+ chalk.dim('Type'.padEnd(typeWidth)),
56
+ chalk.dim('Description'),
57
+ ].join(' ');
58
+ console.log(` ${header}`);
59
+ console.log(` ${chalk.dim('-'.repeat(nameWidth + pubWidth + verWidth + typeWidth + 30))}`);
60
+ // Rows
61
+ for (const skill of data.results) {
62
+ const row = [
63
+ chalk.cyan(skill.name.padEnd(nameWidth)),
64
+ skill.publisher.padEnd(pubWidth),
65
+ chalk.green(skill.version.padEnd(verWidth)),
66
+ chalk.dim((skill.type ?? '-').padEnd(typeWidth)),
67
+ chalk.dim(skill.description.length > 50 ? skill.description.substring(0, 47) + '...' : skill.description),
68
+ ].join(' ');
69
+ console.log(` ${row}`);
70
+ }
71
+ console.log();
72
+ }
73
+ catch (err) {
74
+ const message = err instanceof Error ? err.message : String(err);
75
+ console.error(chalk.red(`Search failed: ${message}`));
76
+ process.exit(1);
77
+ }
78
+ });
79
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const updateCommand: Command;
3
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0BpC,eAAO,MAAM,aAAa,SA6KtB,CAAC"}