skillvault 0.7.4 → 0.7.5
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 +10 -18
- 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, createHmac, createPublicKey, diffieHellman, hkdfSync, generateKeyPairSync, } from 'node:crypto';
|
|
23
|
-
const VERSION = '0.7.
|
|
23
|
+
const VERSION = '0.7.5';
|
|
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');
|
|
@@ -507,7 +507,7 @@ async function installSkillStubs() {
|
|
|
507
507
|
let frontmatter = '';
|
|
508
508
|
let frontmatterFields = {};
|
|
509
509
|
try {
|
|
510
|
-
const { cek } = await fetchCEK(skillName, pub.token);
|
|
510
|
+
const { cek } = await fetchCEK(skillName, pub.token, config.api_url || API_URL);
|
|
511
511
|
const vaultData = readFileSync(vaultPath);
|
|
512
512
|
const vault = decryptVault(vaultData, cek);
|
|
513
513
|
cek.fill(0);
|
|
@@ -533,17 +533,9 @@ async function installSkillStubs() {
|
|
|
533
533
|
// Build frontmatter for stub — copy all fields except body-related ones
|
|
534
534
|
let stubFrontmatter = `name: ${stubName}\n`;
|
|
535
535
|
stubFrontmatter += `description: "${stubDescription.replace(/"/g, '\\"')}"\n`;
|
|
536
|
-
//
|
|
537
|
-
const
|
|
538
|
-
|
|
539
|
-
if (publisherAllowedTools && !publisherAllowedTools.includes('skillvault')) {
|
|
540
|
-
// Merge publisher's allowed-tools with ours
|
|
541
|
-
const merged = publisherAllowedTools.replace(/\]$/, `, ${loadTool}]`);
|
|
542
|
-
stubFrontmatter += `allowed-tools: ${merged}\n`;
|
|
543
|
-
}
|
|
544
|
-
else {
|
|
545
|
-
stubFrontmatter += `allowed-tools: [${loadTool}]\n`;
|
|
546
|
-
}
|
|
536
|
+
// Only allow our specific load tool — do NOT merge publisher-specified allowed-tools
|
|
537
|
+
const loadTool = `"Bash(npx skillvault@${VERSION} --load ${skillName})"`;
|
|
538
|
+
stubFrontmatter += `allowed-tools: [${loadTool}]\n`;
|
|
547
539
|
// Copy through other frontmatter fields the publisher set (for Claude triggering)
|
|
548
540
|
for (const [key, value] of Object.entries(frontmatterFields)) {
|
|
549
541
|
if (!['name', 'description', 'allowed-tools'].includes(key)) {
|
|
@@ -633,10 +625,10 @@ function resolveSkillPublisher(skillName, config) {
|
|
|
633
625
|
}
|
|
634
626
|
return null;
|
|
635
627
|
}
|
|
636
|
-
async function fetchCEK(skillName, publisherToken) {
|
|
628
|
+
async function fetchCEK(skillName, publisherToken, apiUrl) {
|
|
637
629
|
const kp = generateKeyPairSync('x25519');
|
|
638
630
|
const pub = kp.publicKey.export({ type: 'spki', format: 'der' }).toString('base64');
|
|
639
|
-
const res = await fetch(`${
|
|
631
|
+
const res = await fetch(`${apiUrl}/v1/skills/${skillName}/cek`, {
|
|
640
632
|
method: 'POST',
|
|
641
633
|
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${publisherToken}` },
|
|
642
634
|
body: JSON.stringify({ companion_public_key: pub }),
|
|
@@ -689,8 +681,8 @@ function watermarkLayer2(content, id) {
|
|
|
689
681
|
}
|
|
690
682
|
/** Layer 3: Structural fingerprint — HMAC comment tag in code blocks */
|
|
691
683
|
function watermarkLayer3(content, id) {
|
|
692
|
-
const hmac = createHmac('sha256',
|
|
693
|
-
hmac.update(
|
|
684
|
+
const hmac = createHmac('sha256', id);
|
|
685
|
+
hmac.update('skillvault-structural-v1');
|
|
694
686
|
const tag = `// sv:${hmac.digest('hex').slice(0, 12)}`;
|
|
695
687
|
const lines = content.split('\n');
|
|
696
688
|
const result = [];
|
|
@@ -904,7 +896,7 @@ async function loadSkill(skillName) {
|
|
|
904
896
|
let cek;
|
|
905
897
|
let licenseeId;
|
|
906
898
|
try {
|
|
907
|
-
const cekResult = await fetchCEK(skillName, resolved.publisher.token);
|
|
899
|
+
const cekResult = await fetchCEK(skillName, resolved.publisher.token, config.api_url || API_URL);
|
|
908
900
|
cek = cekResult.cek;
|
|
909
901
|
// Use server-provided watermark ID (includes grant ID, customer ID, timestamp)
|
|
910
902
|
// Falls back to local composite if server didn't provide one
|