skillvault 0.7.0 → 0.7.1
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.js +76 -11
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, rmSync } from 'node:fs';
|
|
21
21
|
import { join } from 'node:path';
|
|
22
22
|
import { createDecipheriv, createPublicKey, diffieHellman, hkdfSync, generateKeyPairSync, } from 'node:crypto';
|
|
23
|
-
const VERSION = '0.7.
|
|
23
|
+
const VERSION = '0.7.1';
|
|
24
24
|
const HOME = process.env.HOME || process.env.USERPROFILE || '~';
|
|
25
25
|
const API_URL = process.env.SKILLVAULT_API_URL || 'https://api.getskillvault.com';
|
|
26
26
|
const CONFIG_DIR = join(HOME, '.skillvault');
|
|
@@ -107,6 +107,19 @@ async function setup(code) {
|
|
|
107
107
|
if (!response.ok) {
|
|
108
108
|
const err = await response.json().catch(() => ({ message: response.statusText }));
|
|
109
109
|
console.error(` ❌ Failed: ${err.message}`);
|
|
110
|
+
console.error('');
|
|
111
|
+
if (err.message.includes('404') || err.message.includes('not found')) {
|
|
112
|
+
console.error(' The invite code was not found. Check that you entered it correctly.');
|
|
113
|
+
console.error(' Invite codes are 8 characters (e.g. A1B2C3D4).');
|
|
114
|
+
}
|
|
115
|
+
else if (err.message.includes('400') || err.message.includes('expired')) {
|
|
116
|
+
console.error(' This invite code has already been used or has expired.');
|
|
117
|
+
console.error(' Ask the publisher for a new invite code.');
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
console.error(' Could not reach the SkillVault server. Check your internet connection.');
|
|
121
|
+
console.error(` Server: ${API_URL}`);
|
|
122
|
+
}
|
|
110
123
|
process.exit(1);
|
|
111
124
|
}
|
|
112
125
|
const data = await response.json();
|
|
@@ -327,14 +340,14 @@ async function refreshTokens() {
|
|
|
327
340
|
anyRefreshed = true;
|
|
328
341
|
}
|
|
329
342
|
else if (res.status === 401) {
|
|
330
|
-
console.error('❌ expired —
|
|
343
|
+
console.error('❌ expired — ask the publisher for a new invite code');
|
|
331
344
|
}
|
|
332
345
|
else {
|
|
333
|
-
console.error(`❌ server error (${res.status})
|
|
346
|
+
console.error(`❌ server error (${res.status}). Try again later or contact the publisher.`);
|
|
334
347
|
}
|
|
335
348
|
}
|
|
336
349
|
catch {
|
|
337
|
-
console.error('❌ offline');
|
|
350
|
+
console.error('❌ offline — check your internet connection');
|
|
338
351
|
}
|
|
339
352
|
}
|
|
340
353
|
if (anyRefreshed) {
|
|
@@ -362,7 +375,7 @@ async function syncSkills() {
|
|
|
362
375
|
signal: AbortSignal.timeout(10000),
|
|
363
376
|
});
|
|
364
377
|
if (!res.ok) {
|
|
365
|
-
errors.push(`${pub.name}: ${res.status === 401 ? 'auth expired' : `
|
|
378
|
+
errors.push(`${pub.name}: ${res.status === 401 ? 'auth expired — run npx skillvault --refresh' : `server returned ${res.status}`}`);
|
|
366
379
|
continue;
|
|
367
380
|
}
|
|
368
381
|
const data = await res.json();
|
|
@@ -715,12 +728,19 @@ async function backgroundSyncAll(config) {
|
|
|
715
728
|
*/
|
|
716
729
|
async function loadSkill(skillName) {
|
|
717
730
|
if (!validateSkillName(skillName)) {
|
|
718
|
-
console.error('Error: Invalid skill name.');
|
|
731
|
+
console.error('Error: Invalid skill name. Skill names can only contain letters, numbers, hyphens, and underscores (max 128 chars).');
|
|
732
|
+
console.error('Example: npx skillvault --load my-skill-name');
|
|
719
733
|
process.exit(1);
|
|
720
734
|
}
|
|
721
735
|
const config = loadConfig();
|
|
722
736
|
if (!config) {
|
|
723
|
-
console.error('Error:
|
|
737
|
+
console.error('Error: SkillVault is not configured on this machine.');
|
|
738
|
+
console.error('');
|
|
739
|
+
console.error('To set up, you need an invite code from a skill publisher.');
|
|
740
|
+
console.error('Run: npx skillvault --invite YOUR_INVITE_CODE');
|
|
741
|
+
console.error('');
|
|
742
|
+
console.error('If you already set up SkillVault, the config file may be missing:');
|
|
743
|
+
console.error(` Expected: ${CONFIG_PATH}`);
|
|
724
744
|
process.exit(1);
|
|
725
745
|
}
|
|
726
746
|
// Pre-load sync: ensure we have the latest vault for this skill
|
|
@@ -738,8 +758,30 @@ async function loadSkill(skillName) {
|
|
|
738
758
|
resolved = resolveSkillPublisher(skillName, config);
|
|
739
759
|
}
|
|
740
760
|
if (!resolved) {
|
|
741
|
-
console.error(`Error:
|
|
742
|
-
console.error('
|
|
761
|
+
console.error(`Error: Skill "${skillName}" not found after syncing with server.`);
|
|
762
|
+
console.error('');
|
|
763
|
+
console.error('Possible causes:');
|
|
764
|
+
console.error(' 1. You don\'t have a license for this skill — ask the publisher for an invite');
|
|
765
|
+
console.error(' 2. The skill name is misspelled — check the exact name with: npx skillvault --status');
|
|
766
|
+
console.error(' 3. Your token expired — refresh with: npx skillvault --refresh');
|
|
767
|
+
console.error('');
|
|
768
|
+
console.error('Available skills on this machine:');
|
|
769
|
+
const localConfig = loadConfig();
|
|
770
|
+
if (localConfig) {
|
|
771
|
+
for (const pub of localConfig.publishers) {
|
|
772
|
+
const pubVaultDir = join(VAULT_DIR, pub.id);
|
|
773
|
+
try {
|
|
774
|
+
if (existsSync(pubVaultDir)) {
|
|
775
|
+
const vaults = readdirSync(pubVaultDir).filter(f => f.endsWith('.vault'));
|
|
776
|
+
for (const v of vaults)
|
|
777
|
+
console.error(` - ${v.replace('.vault', '')} (from ${pub.name})`);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
catch { }
|
|
781
|
+
}
|
|
782
|
+
if (localConfig.publishers.length === 0)
|
|
783
|
+
console.error(' (none — no publishers configured)');
|
|
784
|
+
}
|
|
743
785
|
process.exit(1);
|
|
744
786
|
}
|
|
745
787
|
// Kick off background sync for all other skills (non-blocking)
|
|
@@ -751,8 +793,27 @@ async function loadSkill(skillName) {
|
|
|
751
793
|
cek = await fetchCEK(skillName, resolved.publisher.token);
|
|
752
794
|
}
|
|
753
795
|
catch (err) {
|
|
754
|
-
|
|
755
|
-
console.error(
|
|
796
|
+
const errMsg = err instanceof Error ? err.message : 'unknown';
|
|
797
|
+
console.error(`Error: License check failed for "${skillName}" — ${errMsg}`);
|
|
798
|
+
console.error('');
|
|
799
|
+
if (errMsg.includes('403') || errMsg.includes('no_license')) {
|
|
800
|
+
console.error('Your license for this skill has been revoked or expired.');
|
|
801
|
+
console.error('Contact the skill publisher to request a new license.');
|
|
802
|
+
}
|
|
803
|
+
else if (errMsg.includes('401')) {
|
|
804
|
+
console.error('Your authentication token has expired.');
|
|
805
|
+
console.error('Fix: npx skillvault --refresh');
|
|
806
|
+
}
|
|
807
|
+
else if (errMsg.includes('fetch') || errMsg.includes('ECONNREFUSED')) {
|
|
808
|
+
console.error('Could not reach the SkillVault server. Check your internet connection.');
|
|
809
|
+
console.error(`Server: ${API_URL}`);
|
|
810
|
+
}
|
|
811
|
+
else {
|
|
812
|
+
console.error('The server rejected the license check. This could mean:');
|
|
813
|
+
console.error(' - Your license was revoked');
|
|
814
|
+
console.error(' - Your token expired (fix: npx skillvault --refresh)');
|
|
815
|
+
console.error(' - The server is temporarily unavailable');
|
|
816
|
+
}
|
|
756
817
|
process.exit(1);
|
|
757
818
|
}
|
|
758
819
|
// Decrypt in memory
|
|
@@ -773,6 +834,10 @@ async function loadSkill(skillName) {
|
|
|
773
834
|
catch (err) {
|
|
774
835
|
cek.fill(0);
|
|
775
836
|
console.error(`Error: Decryption failed — ${err instanceof Error ? err.message : 'unknown'}`);
|
|
837
|
+
console.error('');
|
|
838
|
+
console.error('The vault file may be corrupted or the CEK may not match.');
|
|
839
|
+
console.error('Try re-syncing: npx skillvault --sync');
|
|
840
|
+
console.error('If the problem persists, the skill may need to be republished by the publisher.');
|
|
776
841
|
process.exit(1);
|
|
777
842
|
}
|
|
778
843
|
}
|