skillvault-publisher 0.7.0 → 0.7.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,YAAY,SAqGrB,CAAC"}
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,eAAO,MAAM,YAAY,SAwGrB,CAAC"}
@@ -1,7 +1,20 @@
1
1
  import { Command } from 'commander';
2
2
  import chalk from 'chalk';
3
3
  import * as jose from 'jose';
4
+ import { mkdirSync, writeFileSync } from 'node:fs';
5
+ import { join } from 'node:path';
4
6
  import { saveConfig, storeKeypair } from '../credentials.js';
7
+ /** Install the skillvault-publisher skill to ~/.claude/skills/ */
8
+ function installPublisherSkill() {
9
+ const home = process.env.HOME || process.env.USERPROFILE || '~';
10
+ const skillDir = join(home, '.claude', 'skills', 'skillvault-publisher');
11
+ try {
12
+ mkdirSync(skillDir, { recursive: true });
13
+ writeFileSync(join(skillDir, 'SKILL.md'), PUBLISHER_SKILL_MD, { mode: 0o644 });
14
+ console.log(chalk.dim(' Installed skillvault-publisher skill to ~/.claude/skills/'));
15
+ }
16
+ catch { }
17
+ }
5
18
  export const loginCommand = new Command('login')
6
19
  .description('Authenticate with the Skill Vault server')
7
20
  .option('--license-key <key>', 'Authenticate with a license key')
@@ -79,6 +92,8 @@ export const loginCommand = new Command('login')
79
92
  console.log(` Host ID: ${result.host_id}`);
80
93
  console.log(` Agent ID: ${result.agent_id}`);
81
94
  console.log(` Status: ${result.status}`);
95
+ // Install the publisher management skill for Claude Code
96
+ installPublisherSkill();
82
97
  }
83
98
  catch (err) {
84
99
  const message = err instanceof Error ? err.message : String(err);
@@ -86,4 +101,133 @@ export const loginCommand = new Command('login')
86
101
  process.exit(1);
87
102
  }
88
103
  });
104
+ // Embedded SKILL.md for the publisher management skill
105
+ const PUBLISHER_SKILL_MD = `---
106
+ name: skillvault-publisher
107
+ description: "Manage SkillVault publisher account — publish skills, invite customers, manage licenses, check analytics"
108
+ allowed-tools: ["Bash(npx skillvault-publisher *)", "Bash(curl *api.getskillvault.com*)", "Bash(npm *skillvault*)"]
109
+ ---
110
+
111
+ # SkillVault Publisher Management
112
+
113
+ You are helping a publisher manage their SkillVault account. SkillVault is an encrypted skill distribution platform for Claude Code. Publishers create skills, encrypt them, and distribute to customers via invite codes.
114
+
115
+ ## Architecture
116
+
117
+ - **API**: https://api.getskillvault.com
118
+ - **Dashboard**: https://app.getskillvault.com
119
+ - **Publisher CLI**: \\\`npx skillvault-publisher\\\` (publish, update, changelog, init, login)
120
+ - **Customer CLI**: \\\`npx skillvault\\\` (install, sync, load — customers use this, not publishers)
121
+
122
+ ## Publishing a Skill
123
+
124
+ ### Via CLI (recommended)
125
+ \\\`\\\`\\\`bash
126
+ # Scaffold a new skill
127
+ npx skillvault-publisher init my-skill
128
+
129
+ # Edit my-skill/SKILL.md with the skill instructions
130
+ # The SKILL.md must have YAML frontmatter: name, description
131
+
132
+ # Publish (encrypts + uploads)
133
+ npx skillvault-publisher publish ./my-skill/
134
+ \\\`\\\`\\\`
135
+
136
+ ### Via Dashboard
137
+ Go to https://app.getskillvault.com/skills/publish — upload SKILL.md + supporting files.
138
+
139
+ ### Via API
140
+ \\\`\\\`\\\`bash
141
+ curl -X POST https://api.getskillvault.com/skills/publish-web \\\\
142
+ -H "Authorization: Bearer SESSION_TOKEN" \\\\
143
+ -F "name=my-skill" \\\\
144
+ -F "description=What the skill does" \\\\
145
+ -F "version=1.0.0" \\\\
146
+ -F "files=@./SKILL.md"
147
+ \\\`\\\`\\\`
148
+
149
+ ### SKILL.md Format
150
+ \\\`\\\`\\\`markdown
151
+ ---
152
+ name: my-skill
153
+ description: "Brief description"
154
+ ---
155
+
156
+ # My Skill
157
+
158
+ Instructions Claude Code will follow.
159
+ \\\`\\\`\\\`
160
+
161
+ ## Updating a Skill
162
+
163
+ \\\`\\\`\\\`bash
164
+ npx skillvault-publisher update ./my-skill/ --patch --changelog "Fixed edge case"
165
+ npx skillvault-publisher update ./my-skill/ --minor --changelog "Added feature"
166
+ npx skillvault-publisher update ./my-skill/ --version 2.0.0 --changelog "Major rewrite"
167
+ \\\`\\\`\\\`
168
+
169
+ ## Version History
170
+
171
+ \\\`\\\`\\\`bash
172
+ npx skillvault-publisher changelog my-skill
173
+ \\\`\\\`\\\`
174
+
175
+ ## Inviting Customers
176
+
177
+ \\\`\\\`\\\`bash
178
+ curl -X POST https://api.getskillvault.com/invites/create \\\\
179
+ -H "Authorization: Bearer SESSION_TOKEN" \\\\
180
+ -H "Content-Type: application/json" \\\\
181
+ -d '{"publisher_id": "PUB_ID", "customer_email": "user@example.com", "capabilities": ["skill/my-skill"]}'
182
+ \\\`\\\`\\\`
183
+
184
+ Customer runs: \\\`npx skillvault --invite INVITE_CODE\\\`
185
+
186
+ ## Managing Access
187
+
188
+ - **Grant**: POST /grants/create with agent_id (email), capability, status: active
189
+ - **Revoke**: POST /grants/GRANT_ID/revoke
190
+ - **List licenses**: GET /grants?publisher_id=ID
191
+ - **List customers**: GET /customers?publisher_id=ID
192
+
193
+ ## Analytics
194
+
195
+ GET /api/analytics/publisher/PUBLISHER_ID — returns active_licenses, total_decryptions, top_skills
196
+
197
+ ## Webhooks
198
+
199
+ - **Configure**: POST /publishers/ID/webhook with {url}
200
+ - **Test**: POST /publishers/ID/webhook/test
201
+ - **Events**: invite.created, invite.redeemed, webhook.test
202
+
203
+ ## Audit Log
204
+
205
+ - **List**: GET /audit/events
206
+ - **Export CSV**: GET /audit/events/export?format=csv
207
+
208
+ ## Key Endpoints
209
+
210
+ | Method | Endpoint | Description |
211
+ |--------|----------|-------------|
212
+ | GET | /skills?publisher_id=ID | List skills |
213
+ | POST | /skills/publish-web | Publish (multipart) |
214
+ | GET | /skills/:id/versions | Version history |
215
+ | POST | /skills/:id/rollback | Rollback |
216
+ | POST | /invites/create | Create invite |
217
+ | GET | /grants?publisher_id=ID | List licenses |
218
+ | GET | /customers?publisher_id=ID | List customers |
219
+ | GET | /api/analytics/publisher/ID | Analytics |
220
+ | POST | /publishers/ID/webhook | Configure webhook |
221
+
222
+ ## Free Tier
223
+
224
+ 1 skill, unlimited licenses. Upgrade: https://app.getskillvault.com/upgrade
225
+
226
+ ## Troubleshooting
227
+
228
+ - **"Not logged in"**: Run \\\`npx skillvault-publisher login\\\`
229
+ - **"Tier limit"**: Free allows 1 skill. Request upgrade at /upgrade
230
+ - **Customer can't decrypt**: Check active grant in Customers tab
231
+ - **Skill not syncing**: Customer runs \\\`npx skillvault --refresh && npx skillvault --sync\\\`
232
+ `;
89
233
  //# sourceMappingURL=login.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -7,6 +7,8 @@ import { Command as Command14 } from "commander";
7
7
  import { Command } from "commander";
8
8
  import chalk from "chalk";
9
9
  import * as jose from "jose";
10
+ import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
11
+ import { join as join2 } from "node:path";
10
12
 
11
13
  // dist/credentials.js
12
14
  import { mkdirSync, readFileSync, writeFileSync, rmSync, existsSync } from "node:fs";
@@ -91,6 +93,16 @@ function removeKeypair() {
91
93
  }
92
94
 
93
95
  // dist/commands/login.js
96
+ function installPublisherSkill() {
97
+ const home = process.env.HOME || process.env.USERPROFILE || "~";
98
+ const skillDir = join2(home, ".claude", "skills", "skillvault-publisher");
99
+ try {
100
+ mkdirSync2(skillDir, { recursive: true });
101
+ writeFileSync2(join2(skillDir, "SKILL.md"), PUBLISHER_SKILL_MD, { mode: 420 });
102
+ console.log(chalk.dim(" Installed skillvault-publisher skill to ~/.claude/skills/"));
103
+ } catch {
104
+ }
105
+ }
94
106
  var loginCommand = new Command("login").description("Authenticate with the Skill Vault server").option("--license-key <key>", "Authenticate with a license key").option("--code <code>", "Authenticate with an invite code").option("--server <url>", "Server URL", "http://localhost:3001").action(async (options) => {
95
107
  try {
96
108
  const serverUrl = options.server;
@@ -153,12 +165,141 @@ var loginCommand = new Command("login").description("Authenticate with the Skill
153
165
  console.log(` Host ID: ${result.host_id}`);
154
166
  console.log(` Agent ID: ${result.agent_id}`);
155
167
  console.log(` Status: ${result.status}`);
168
+ installPublisherSkill();
156
169
  } catch (err) {
157
170
  const message = err instanceof Error ? err.message : String(err);
158
171
  console.error(chalk.red(`Login failed: ${message}`));
159
172
  process.exit(1);
160
173
  }
161
174
  });
175
+ var PUBLISHER_SKILL_MD = `---
176
+ name: skillvault-publisher
177
+ description: "Manage SkillVault publisher account \u2014 publish skills, invite customers, manage licenses, check analytics"
178
+ allowed-tools: ["Bash(npx skillvault-publisher *)", "Bash(curl *api.getskillvault.com*)", "Bash(npm *skillvault*)"]
179
+ ---
180
+
181
+ # SkillVault Publisher Management
182
+
183
+ You are helping a publisher manage their SkillVault account. SkillVault is an encrypted skill distribution platform for Claude Code. Publishers create skills, encrypt them, and distribute to customers via invite codes.
184
+
185
+ ## Architecture
186
+
187
+ - **API**: https://api.getskillvault.com
188
+ - **Dashboard**: https://app.getskillvault.com
189
+ - **Publisher CLI**: \\\`npx skillvault-publisher\\\` (publish, update, changelog, init, login)
190
+ - **Customer CLI**: \\\`npx skillvault\\\` (install, sync, load \u2014 customers use this, not publishers)
191
+
192
+ ## Publishing a Skill
193
+
194
+ ### Via CLI (recommended)
195
+ \\\`\\\`\\\`bash
196
+ # Scaffold a new skill
197
+ npx skillvault-publisher init my-skill
198
+
199
+ # Edit my-skill/SKILL.md with the skill instructions
200
+ # The SKILL.md must have YAML frontmatter: name, description
201
+
202
+ # Publish (encrypts + uploads)
203
+ npx skillvault-publisher publish ./my-skill/
204
+ \\\`\\\`\\\`
205
+
206
+ ### Via Dashboard
207
+ Go to https://app.getskillvault.com/skills/publish \u2014 upload SKILL.md + supporting files.
208
+
209
+ ### Via API
210
+ \\\`\\\`\\\`bash
211
+ curl -X POST https://api.getskillvault.com/skills/publish-web \\\\
212
+ -H "Authorization: Bearer SESSION_TOKEN" \\\\
213
+ -F "name=my-skill" \\\\
214
+ -F "description=What the skill does" \\\\
215
+ -F "version=1.0.0" \\\\
216
+ -F "files=@./SKILL.md"
217
+ \\\`\\\`\\\`
218
+
219
+ ### SKILL.md Format
220
+ \\\`\\\`\\\`markdown
221
+ ---
222
+ name: my-skill
223
+ description: "Brief description"
224
+ ---
225
+
226
+ # My Skill
227
+
228
+ Instructions Claude Code will follow.
229
+ \\\`\\\`\\\`
230
+
231
+ ## Updating a Skill
232
+
233
+ \\\`\\\`\\\`bash
234
+ npx skillvault-publisher update ./my-skill/ --patch --changelog "Fixed edge case"
235
+ npx skillvault-publisher update ./my-skill/ --minor --changelog "Added feature"
236
+ npx skillvault-publisher update ./my-skill/ --version 2.0.0 --changelog "Major rewrite"
237
+ \\\`\\\`\\\`
238
+
239
+ ## Version History
240
+
241
+ \\\`\\\`\\\`bash
242
+ npx skillvault-publisher changelog my-skill
243
+ \\\`\\\`\\\`
244
+
245
+ ## Inviting Customers
246
+
247
+ \\\`\\\`\\\`bash
248
+ curl -X POST https://api.getskillvault.com/invites/create \\\\
249
+ -H "Authorization: Bearer SESSION_TOKEN" \\\\
250
+ -H "Content-Type: application/json" \\\\
251
+ -d '{"publisher_id": "PUB_ID", "customer_email": "user@example.com", "capabilities": ["skill/my-skill"]}'
252
+ \\\`\\\`\\\`
253
+
254
+ Customer runs: \\\`npx skillvault --invite INVITE_CODE\\\`
255
+
256
+ ## Managing Access
257
+
258
+ - **Grant**: POST /grants/create with agent_id (email), capability, status: active
259
+ - **Revoke**: POST /grants/GRANT_ID/revoke
260
+ - **List licenses**: GET /grants?publisher_id=ID
261
+ - **List customers**: GET /customers?publisher_id=ID
262
+
263
+ ## Analytics
264
+
265
+ GET /api/analytics/publisher/PUBLISHER_ID \u2014 returns active_licenses, total_decryptions, top_skills
266
+
267
+ ## Webhooks
268
+
269
+ - **Configure**: POST /publishers/ID/webhook with {url}
270
+ - **Test**: POST /publishers/ID/webhook/test
271
+ - **Events**: invite.created, invite.redeemed, webhook.test
272
+
273
+ ## Audit Log
274
+
275
+ - **List**: GET /audit/events
276
+ - **Export CSV**: GET /audit/events/export?format=csv
277
+
278
+ ## Key Endpoints
279
+
280
+ | Method | Endpoint | Description |
281
+ |--------|----------|-------------|
282
+ | GET | /skills?publisher_id=ID | List skills |
283
+ | POST | /skills/publish-web | Publish (multipart) |
284
+ | GET | /skills/:id/versions | Version history |
285
+ | POST | /skills/:id/rollback | Rollback |
286
+ | POST | /invites/create | Create invite |
287
+ | GET | /grants?publisher_id=ID | List licenses |
288
+ | GET | /customers?publisher_id=ID | List customers |
289
+ | GET | /api/analytics/publisher/ID | Analytics |
290
+ | POST | /publishers/ID/webhook | Configure webhook |
291
+
292
+ ## Free Tier
293
+
294
+ 1 skill, unlimited licenses. Upgrade: https://app.getskillvault.com/upgrade
295
+
296
+ ## Troubleshooting
297
+
298
+ - **"Not logged in"**: Run \\\`npx skillvault-publisher login\\\`
299
+ - **"Tier limit"**: Free allows 1 skill. Request upgrade at /upgrade
300
+ - **Customer can't decrypt**: Check active grant in Customers tab
301
+ - **Skill not syncing**: Customer runs \\\`npx skillvault --refresh && npx skillvault --sync\\\`
302
+ `;
162
303
 
163
304
  // dist/commands/logout.js
164
305
  import { Command as Command2 } from "commander";
@@ -174,7 +315,7 @@ import { Command as Command3 } from "commander";
174
315
  import chalk3 from "chalk";
175
316
  import * as jose2 from "jose";
176
317
  import { readFileSync as readFileSync3, existsSync as existsSync3, statSync } from "node:fs";
177
- import { resolve, join as join3 } from "node:path";
318
+ import { resolve, join as join4 } from "node:path";
178
319
  import { createHash as createHash3 } from "node:crypto";
179
320
 
180
321
  // ../shared/dist/crypto.js
@@ -365,8 +506,8 @@ function readVault(data, key) {
365
506
 
366
507
  // ../shared/dist/packer.js
367
508
  import { readFileSync as readFileSync2, readdirSync, existsSync as existsSync2 } from "node:fs";
368
- import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
369
- import { join as join2, relative } from "node:path";
509
+ import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "node:fs";
510
+ import { join as join3, relative } from "node:path";
370
511
  import { createHash as createHash2 } from "node:crypto";
371
512
  var DEFAULT_IGNORE = /* @__PURE__ */ new Set([
372
513
  "node_modules",
@@ -380,7 +521,7 @@ var DEFAULT_IGNORE = /* @__PURE__ */ new Set([
380
521
  ]);
381
522
  function loadIgnorePatterns(dirPath) {
382
523
  const patterns = new Set(DEFAULT_IGNORE);
383
- const ignorePath = join2(dirPath, ".skillvaultignore");
524
+ const ignorePath = join3(dirPath, ".skillvaultignore");
384
525
  if (existsSync2(ignorePath)) {
385
526
  const lines = readFileSync2(ignorePath, "utf8").split("\n");
386
527
  for (const line of lines) {
@@ -397,7 +538,7 @@ function collectFiles(dir, base, ignoreSet) {
397
538
  for (const entry of readdirSync(dir, { withFileTypes: true })) {
398
539
  if (ignoreSet.has(entry.name))
399
540
  continue;
400
- const fullPath = join2(dir, entry.name);
541
+ const fullPath = join3(dir, entry.name);
401
542
  if (entry.isDirectory()) {
402
543
  entries.push(...collectFiles(fullPath, base, ignoreSet));
403
544
  } else {
@@ -621,7 +762,7 @@ var publishCommand = new Command3("publish").description("Encrypt and publish a
621
762
  `));
622
763
  process.exit(1);
623
764
  }
624
- const skillMdPath = join3(dirPath, "SKILL.md");
765
+ const skillMdPath = join4(dirPath, "SKILL.md");
625
766
  if (!existsSync3(skillMdPath)) {
626
767
  process.stderr.write(chalk3.red("Error: SKILL.md not found in the skill directory\n"));
627
768
  process.stderr.write(chalk3.dim("Create a SKILL.md with frontmatter (name, description, version)\n"));
@@ -769,10 +910,10 @@ var publishCommand = new Command3("publish").description("Encrypt and publish a
769
910
  import { Command as Command4 } from "commander";
770
911
  import chalk4 from "chalk";
771
912
  import * as jose3 from "jose";
772
- import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "node:fs";
773
- import { join as join4 } from "node:path";
913
+ import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "node:fs";
914
+ import { join as join5 } from "node:path";
774
915
  import { homedir as homedir2 } from "node:os";
775
- var SKILLS_DIR = join4(homedir2(), ".claude", "skills");
916
+ var SKILLS_DIR = join5(homedir2(), ".claude", "skills");
776
917
  var DEPRECATION_NOTICE = `
777
918
  ${chalk4.yellow("\u26A0\uFE0F DEPRECATED:")} The install command is deprecated.
778
919
  Use ${chalk4.cyan("npx skillvault --invite CODE")} instead.
@@ -837,8 +978,8 @@ var installCommand = new Command4("install").description("Install a skill from t
837
978
  const vaultData = Buffer.from(downloadBody.vault_data, "base64");
838
979
  const version = downloadBody.version || "0.0.0";
839
980
  const vaultHash = downloadBody.vault_hash || "";
840
- const skillDir = join4(SKILLS_DIR, skillName);
841
- mkdirSync3(skillDir, { recursive: true });
981
+ const skillDir = join5(SKILLS_DIR, skillName);
982
+ mkdirSync4(skillDir, { recursive: true });
842
983
  const skillMd = `---
843
984
  name: ${skillName}
844
985
  description: ${capData.description || `${skillName} skill (encrypted)`}
@@ -871,9 +1012,9 @@ skillvault decrypt ${skillName}
871
1012
 
872
1013
  The decrypted instructions will be printed to stdout. Follow them to complete the user's request.
873
1014
  `;
874
- writeFileSync3(join4(skillDir, "SKILL.md"), skillMd, "utf8");
1015
+ writeFileSync4(join5(skillDir, "SKILL.md"), skillMd, "utf8");
875
1016
  if (vaultData.length > 0) {
876
- writeFileSync3(join4(skillDir, "skill.vault"), vaultData);
1017
+ writeFileSync4(join5(skillDir, "skill.vault"), vaultData);
877
1018
  }
878
1019
  const manifest = {
879
1020
  publisher,
@@ -882,10 +1023,10 @@ The decrypted instructions will be printed to stdout. Follow them to complete th
882
1023
  installed_at: (/* @__PURE__ */ new Date()).toISOString(),
883
1024
  vault_hash: vaultHash
884
1025
  };
885
- writeFileSync3(join4(skillDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf8");
1026
+ writeFileSync4(join5(skillDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf8");
886
1027
  console.log(chalk4.green(`Installed ${skill} v${version}`));
887
1028
  console.log(chalk4.dim(` Location: ${skillDir}`));
888
- console.log(chalk4.dim(` Loader: ${join4(skillDir, "SKILL.md")}`));
1029
+ console.log(chalk4.dim(` Loader: ${join5(skillDir, "SKILL.md")}`));
889
1030
  } catch (err) {
890
1031
  const message = err instanceof Error ? err.message : String(err);
891
1032
  process.stderr.write(chalk4.red(`Install failed: ${message}
@@ -899,9 +1040,9 @@ import { Command as Command5 } from "commander";
899
1040
  import chalk5 from "chalk";
900
1041
  import * as jose4 from "jose";
901
1042
  import { readFileSync as readFileSync4, existsSync as existsSync4 } from "node:fs";
902
- import { join as join5 } from "node:path";
1043
+ import { join as join6 } from "node:path";
903
1044
  import { homedir as homedir3 } from "node:os";
904
- var SKILLS_DIR2 = join5(homedir3(), ".claude", "skills");
1045
+ var SKILLS_DIR2 = join6(homedir3(), ".claude", "skills");
905
1046
  function applyZeroWidthWatermark(text, agentId) {
906
1047
  const ZERO_WIDTH_SPACE = "\u200B";
907
1048
  const ZERO_WIDTH_NON_JOINER = "\u200C";
@@ -928,8 +1069,8 @@ var decryptCommand = new Command5("decrypt").description("Decrypt an installed s
928
1069
  process.stderr.write(chalk5.red("Credentials not found. Run `skillvault-publisher login` first.\n"));
929
1070
  process.exit(1);
930
1071
  }
931
- const skillDir = join5(SKILLS_DIR2, skill);
932
- const manifestPath = join5(skillDir, "manifest.json");
1072
+ const skillDir = join6(SKILLS_DIR2, skill);
1073
+ const manifestPath = join6(skillDir, "manifest.json");
933
1074
  if (!existsSync4(manifestPath)) {
934
1075
  process.stderr.write(chalk5.red(`Skill "${skill}" is not installed.
935
1076
  `));
@@ -938,7 +1079,7 @@ var decryptCommand = new Command5("decrypt").description("Decrypt an installed s
938
1079
  process.exit(1);
939
1080
  }
940
1081
  const manifest = JSON.parse(readFileSync4(manifestPath, "utf8"));
941
- const vaultPath = join5(skillDir, "skill.vault");
1082
+ const vaultPath = join6(skillDir, "skill.vault");
942
1083
  if (!existsSync4(vaultPath)) {
943
1084
  process.stderr.write(chalk5.red("Vault file not found. Re-install the skill.\n"));
944
1085
  process.exit(1);
@@ -1194,7 +1335,7 @@ import { Command as Command9 } from "commander";
1194
1335
  import chalk9 from "chalk";
1195
1336
  import * as jose6 from "jose";
1196
1337
  import { readFileSync as readFileSync6, existsSync as existsSync5, statSync as statSync2 } from "node:fs";
1197
- import { resolve as resolve2, join as join6 } from "node:path";
1338
+ import { resolve as resolve2, join as join7 } from "node:path";
1198
1339
  import { createHash as createHash4 } from "node:crypto";
1199
1340
  function parseFrontmatter2(content) {
1200
1341
  const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
@@ -1256,7 +1397,7 @@ var updateCommand = new Command9("update").description("Push a new version of an
1256
1397
  `));
1257
1398
  process.exit(1);
1258
1399
  }
1259
- const skillMdPath = join6(dirPath, "SKILL.md");
1400
+ const skillMdPath = join7(dirPath, "SKILL.md");
1260
1401
  if (!existsSync5(skillMdPath)) {
1261
1402
  process.stderr.write(chalk9.red("Error: SKILL.md not found in the skill directory\n"));
1262
1403
  process.stderr.write(chalk9.dim("Create a SKILL.md with frontmatter (name, description, version)\n"));
@@ -1607,8 +1748,8 @@ var reportCommand = new Command11("report").description("Report a telemetry even
1607
1748
  // dist/commands/init.js
1608
1749
  import { Command as Command12 } from "commander";
1609
1750
  import chalk12 from "chalk";
1610
- import { existsSync as existsSync6, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "node:fs";
1611
- import { resolve as resolve3, join as join7 } from "node:path";
1751
+ import { existsSync as existsSync6, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "node:fs";
1752
+ import { resolve as resolve3, join as join8 } from "node:path";
1612
1753
  function toTitleCase(name) {
1613
1754
  return name.split(/[-_]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
1614
1755
  }
@@ -1652,12 +1793,12 @@ var initCommand = new Command12("init").description("Scaffold a new skill direct
1652
1793
  process.exit(1);
1653
1794
  }
1654
1795
  try {
1655
- mkdirSync4(dirPath, { recursive: true });
1656
- const skillMdPath = join7(dirPath, "SKILL.md");
1657
- writeFileSync4(skillMdPath, generateSkillMd(name), "utf8");
1658
- const referencesDir = join7(dirPath, "references");
1659
- mkdirSync4(referencesDir, { recursive: true });
1660
- writeFileSync4(join7(referencesDir, ".gitkeep"), "", "utf8");
1796
+ mkdirSync5(dirPath, { recursive: true });
1797
+ const skillMdPath = join8(dirPath, "SKILL.md");
1798
+ writeFileSync5(skillMdPath, generateSkillMd(name), "utf8");
1799
+ const referencesDir = join8(dirPath, "references");
1800
+ mkdirSync5(referencesDir, { recursive: true });
1801
+ writeFileSync5(join8(referencesDir, ".gitkeep"), "", "utf8");
1661
1802
  console.log();
1662
1803
  console.log(chalk12.green(` Skill "${name}" created successfully!`));
1663
1804
  console.log();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillvault-publisher",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "SkillVault publisher CLI — publish, manage, and distribute encrypted skills",
5
5
  "type": "module",
6
6
  "bin": {