skillvault-publisher 0.12.0 → 0.13.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.
Files changed (2) hide show
  1. package/dist/index.js +553 -245
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3891,11 +3891,11 @@ function __metadata(metadataKey, metadataValue) {
3891
3891
  }
3892
3892
  function __awaiter(thisArg, _arguments, P, generator) {
3893
3893
  function adopt(value) {
3894
- return value instanceof P ? value : new P(function(resolve11) {
3895
- resolve11(value);
3894
+ return value instanceof P ? value : new P(function(resolve12) {
3895
+ resolve12(value);
3896
3896
  });
3897
3897
  }
3898
- return new (P || (P = Promise))(function(resolve11, reject) {
3898
+ return new (P || (P = Promise))(function(resolve12, reject) {
3899
3899
  function fulfilled(value) {
3900
3900
  try {
3901
3901
  step(generator.next(value));
@@ -3911,7 +3911,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
3911
3911
  }
3912
3912
  }
3913
3913
  function step(result) {
3914
- result.done ? resolve11(result.value) : adopt(result.value).then(fulfilled, rejected);
3914
+ result.done ? resolve12(result.value) : adopt(result.value).then(fulfilled, rejected);
3915
3915
  }
3916
3916
  step((generator = generator.apply(thisArg, _arguments || [])).next());
3917
3917
  });
@@ -4102,14 +4102,14 @@ function __asyncValues(o) {
4102
4102
  }, i);
4103
4103
  function verb(n) {
4104
4104
  i[n] = o[n] && function(v) {
4105
- return new Promise(function(resolve11, reject) {
4106
- v = o[n](v), settle(resolve11, reject, v.done, v.value);
4105
+ return new Promise(function(resolve12, reject) {
4106
+ v = o[n](v), settle(resolve12, reject, v.done, v.value);
4107
4107
  });
4108
4108
  };
4109
4109
  }
4110
- function settle(resolve11, reject, d, v) {
4110
+ function settle(resolve12, reject, d, v) {
4111
4111
  Promise.resolve(v).then(function(v2) {
4112
- resolve11({ value: v2, done: d });
4112
+ resolve12({ value: v2, done: d });
4113
4113
  }, reject);
4114
4114
  }
4115
4115
  }
@@ -5054,9 +5054,9 @@ var require_clone = __commonJS({
5054
5054
  } else if (_instanceof(parent2, nativeSet)) {
5055
5055
  child = new nativeSet();
5056
5056
  } else if (_instanceof(parent2, nativePromise)) {
5057
- child = new nativePromise(function(resolve11, reject) {
5057
+ child = new nativePromise(function(resolve12, reject) {
5058
5058
  parent2.then(function(value) {
5059
- resolve11(_clone(value, depth2 - 1));
5059
+ resolve12(_clone(value, depth2 - 1));
5060
5060
  }, function(err) {
5061
5061
  reject(_clone(err, depth2 - 1));
5062
5062
  });
@@ -151595,7 +151595,7 @@ function confColor(c) {
151595
151595
  return SV.sirenRed500;
151596
151596
  }
151597
151597
  async function generatePdfReport(data, outputPath) {
151598
- return new Promise((resolve11, reject) => {
151598
+ return new Promise((resolve12, reject) => {
151599
151599
  const doc = new import_pdfkit.default({
151600
151600
  size: "A4",
151601
151601
  margins: { top: 72, bottom: 0, left: 56, right: 56 },
@@ -151742,7 +151742,7 @@ async function generatePdfReport(data, outputPath) {
151742
151742
  yPos += 72;
151743
151743
  drawPageFooter(doc, leftMargin, contentWidth, pageWidth, pageNum);
151744
151744
  doc.end();
151745
- stream.on("finish", resolve11);
151745
+ stream.on("finish", resolve12);
151746
151746
  stream.on("error", reject);
151747
151747
  });
151748
151748
  }
@@ -151804,7 +151804,7 @@ var init_pdf_report = __esm({
151804
151804
  });
151805
151805
 
151806
151806
  // dist/index.js
151807
- import { Command as Command36 } from "commander";
151807
+ import { Command as Command37 } from "commander";
151808
151808
  import { readFileSync as readFileSync18 } from "node:fs";
151809
151809
  import { fileURLToPath } from "node:url";
151810
151810
  import { dirname as dirname5, join as join17 } from "node:path";
@@ -152070,7 +152070,7 @@ var registerCommand = new Command2("register").description("Create a new publish
152070
152070
  let verified = false;
152071
152071
  const maxAttempts = 120;
152072
152072
  for (let i = 0; i < maxAttempts; i++) {
152073
- await new Promise((resolve11) => setTimeout(resolve11, 3e3));
152073
+ await new Promise((resolve12) => setTimeout(resolve12, 3e3));
152074
152074
  try {
152075
152075
  const statusRes = await fetch(`${serverUrl}/publishers/${publisher_id}/verification-status`);
152076
152076
  if (statusRes.ok) {
@@ -153152,7 +153152,8 @@ The server will clean up automatically. If the problem persists, re-run with --f
153152
153152
  }
153153
153153
  const publishResult = await publishRes.json().catch(() => ({}));
153154
153154
  const wasUnlinked = existingManifest === null;
153155
- if (!options.noLink && sessionPublisherId) {
153155
+ const publishAccepted = publishResult.status !== "rejected";
153156
+ if (publishAccepted && !options.noLink && sessionPublisherId) {
153156
153157
  const linkedAt = existingManifest?.linked_at ?? (/* @__PURE__ */ new Date()).toISOString();
153157
153158
  const newManifest = {
153158
153159
  ...existingManifest ?? {},
@@ -153186,6 +153187,26 @@ The server will clean up automatically. If the problem persists, re-run with --f
153186
153187
  if (publishResult.status === "unchanged") {
153187
153188
  console.log(chalk5.yellow(`Content unchanged for ${skillName} v${version}. No new version created.`));
153188
153189
  console.log(chalk5.dim(` Use --force to publish anyway.`));
153190
+ } else if (publishResult.status === "rejected") {
153191
+ const reasonMessage = publishResult.public_reason?.message || "Skill rejected by the security review pipeline.";
153192
+ process.stderr.write(chalk5.red(`
153193
+ Publish rejected: ${reasonMessage}
153194
+ `));
153195
+ process.stderr.write(chalk5.dim(` Run \`skillvault-publisher skill-status ${skillName}\` for more details.
153196
+ `));
153197
+ process.stderr.write(chalk5.dim(` Download a rejection report with \`skillvault-publisher skill-status ${skillName} --review-report <file>\`.
153198
+ `));
153199
+ process.exit(1);
153200
+ } else if (publishResult.status === "under_review") {
153201
+ console.log(chalk5.yellow(`
153202
+ Skill queued for review: ${skillName} v${version}`));
153203
+ if (publishResult.review_id) {
153204
+ console.log(chalk5.dim(` Review ID: ${publishResult.review_id}`));
153205
+ }
153206
+ console.log(chalk5.dim(` Skill ID: ${publishResult.skill_id || "n/a"}`));
153207
+ console.log(chalk5.dim(` Capability: ${capabilityName}`));
153208
+ console.log(chalk5.dim(" Reviews usually complete within a few minutes."));
153209
+ console.log(chalk5.dim(` Check status with \`skillvault-publisher skill-status ${skillName}\` (or listen on your webhook).`));
153189
153210
  } else {
153190
153211
  console.log(chalk5.green(`Published ${skillName} v${version}`));
153191
153212
  console.log(chalk5.dim(` Skill ID: ${publishResult.skill_id || "n/a"}`));
@@ -153674,8 +153695,17 @@ var whoamiCommand = new Command9("whoami").description("Show current user, activ
153674
153695
  console.log(JSON.stringify({
153675
153696
  host_id: data.host_id ?? config.host_id,
153676
153697
  agent_id: data.agent_id ?? config.agent_id,
153677
- ...config.publisher_id ? { publisher_id: config.publisher_id } : {},
153678
- ...config.email ? { email: config.email } : {},
153698
+ ...authMe ? {
153699
+ publisher_id: authMe.publisher_id,
153700
+ publisher_name: authMe.publisher_name,
153701
+ email: authMe.email,
153702
+ role: authMe.role,
153703
+ is_owner: authMe.is_owner,
153704
+ ...authMe.skill_acls ? { skill_acls: authMe.skill_acls } : {}
153705
+ } : {
153706
+ ...config.publisher_id ? { publisher_id: config.publisher_id } : {},
153707
+ ...config.email ? { email: config.email } : {}
153708
+ },
153679
153709
  device_fingerprint: fingerprint,
153680
153710
  server_url: config.server_url,
153681
153711
  status: data.status,
@@ -153683,6 +153713,18 @@ var whoamiCommand = new Command9("whoami").description("Show current user, activ
153683
153713
  }, null, 2));
153684
153714
  return;
153685
153715
  }
153716
+ let skillsById = /* @__PURE__ */ new Map();
153717
+ if (authMe?.role === "member" && authMe.skill_acls && authMe.skill_acls.length > 0) {
153718
+ try {
153719
+ const skillsRes = await fetch(`${config.server_url}/skills`, { headers: ctx.headers });
153720
+ if (skillsRes.ok) {
153721
+ const sd = await skillsRes.json();
153722
+ for (const s of sd.skills)
153723
+ skillsById.set(s.id, s);
153724
+ }
153725
+ } catch {
153726
+ }
153727
+ }
153686
153728
  console.log();
153687
153729
  console.log(chalk10.bold(" Skill Vault Identity"));
153688
153730
  console.log();
@@ -153695,6 +153737,20 @@ var whoamiCommand = new Command9("whoami").description("Show current user, activ
153695
153737
  if (!authMe.is_owner) {
153696
153738
  console.log(` ${chalk10.dim(" (you are a team member of this publisher)".padEnd(22))}`);
153697
153739
  }
153740
+ if (authMe.role === "member" && authMe.skill_acls) {
153741
+ if (authMe.skill_acls.length === 0) {
153742
+ console.log(` ${chalk10.dim("Skill access:".padEnd(22))} ${chalk10.dim("(none yet \u2014 publish a new skill to auto-own it)")}`);
153743
+ } else {
153744
+ console.log(` ${"Skill access:".padEnd(22)}`);
153745
+ for (const a of authMe.skill_acls) {
153746
+ const sk = skillsById.get(a.skill_id);
153747
+ const label = sk?.name || a.skill_id;
153748
+ const roleColor2 = a.role === "owner" ? chalk10.green : a.role === "write" ? chalk10.cyan : chalk10.dim;
153749
+ const action = a.role === "owner" ? "publish + delete" : a.role === "write" ? "publish new versions" : "view only";
153750
+ console.log(` ${chalk10.cyan(label.padEnd(20))} ${roleColor2(a.role.padEnd(8))} ${chalk10.dim(action)}`);
153751
+ }
153752
+ }
153753
+ }
153698
153754
  } else {
153699
153755
  if (config.publisher_id) {
153700
153756
  console.log(` ${"Publisher ID:".padEnd(22)} ${config.publisher_id}`);
@@ -153961,11 +154017,13 @@ var listCommand = new Command13("list").description("List your published skills"
153961
154017
  const nameWidth = Math.max(20, ...skills.map((s) => s.name.length + 2));
153962
154018
  const verWidth = 10;
153963
154019
  const statusWidth = 10;
154020
+ const reviewWidth = 8;
153964
154021
  const capWidth = Math.max(24, ...skills.map((s) => s.capability_name.length + 2));
153965
154022
  const header = [
153966
154023
  chalk14.dim("Name".padEnd(nameWidth)),
153967
154024
  chalk14.dim("Version".padEnd(verWidth)),
153968
154025
  chalk14.dim("Status".padEnd(statusWidth)),
154026
+ chalk14.dim("Review".padEnd(reviewWidth)),
153969
154027
  chalk14.dim("Capability".padEnd(capWidth)),
153970
154028
  chalk14.dim("Created")
153971
154029
  ].join(" ");
@@ -153977,10 +154035,29 @@ var listCommand = new Command13("list").description("List your published skills"
153977
154035
  year: "numeric"
153978
154036
  });
153979
154037
  const statusColor = skill.status === "active" ? chalk14.green : chalk14.dim;
154038
+ let reviewCell;
154039
+ switch (skill.review_state) {
154040
+ case "approved":
154041
+ reviewCell = chalk14.green("ok".padEnd(reviewWidth));
154042
+ break;
154043
+ case "queued":
154044
+ case "running":
154045
+ reviewCell = chalk14.yellow("review".padEnd(reviewWidth));
154046
+ break;
154047
+ case "rejected":
154048
+ reviewCell = chalk14.red("reject".padEnd(reviewWidth));
154049
+ break;
154050
+ case "needs_human_review":
154051
+ reviewCell = chalk14.yellow("human".padEnd(reviewWidth));
154052
+ break;
154053
+ default:
154054
+ reviewCell = chalk14.dim("-".padEnd(reviewWidth));
154055
+ }
153980
154056
  const row = [
153981
154057
  chalk14.cyan(skill.name.padEnd(nameWidth)),
153982
154058
  chalk14.green(("v" + skill.latest_version).padEnd(verWidth)),
153983
154059
  statusColor(skill.status.padEnd(statusWidth)),
154060
+ reviewCell,
153984
154061
  chalk14.dim(skill.capability_name.padEnd(capWidth)),
153985
154062
  chalk14.dim(createdDate)
153986
154063
  ].join(" ");
@@ -155055,7 +155132,9 @@ var skillDeleteCommand = new Command20("skill-delete").description("Permanently
155055
155132
  // dist/commands/skill-status.js
155056
155133
  import { Command as Command21 } from "commander";
155057
155134
  import chalk18 from "chalk";
155058
- var skillStatusCommand = new Command21("skill-status").description("Show detailed status for a skill").argument("[skill-name]", "Name of the skill to inspect (defaults to workspace skill)").option("--json", "Output as JSON").option("--workspace <path>", "Use workspace at <path> to default skill-name").option("--quiet", 'Suppress the "(using workspace \u2026)" stderr note').action(async (skillNameArg, options) => {
155135
+ import { writeFileSync as writeFileSync10 } from "node:fs";
155136
+ import { resolve as resolve9 } from "node:path";
155137
+ var skillStatusCommand = new Command21("skill-status").description("Show detailed status for a skill").argument("[skill-name]", "Name of the skill to inspect (defaults to workspace skill)").option("--json", "Output as JSON").option("--workspace <path>", "Use workspace at <path> to default skill-name").option("--quiet", 'Suppress the "(using workspace \u2026)" stderr note').option("--review-report <file>", "Write a public review report (JSON) to <file>").action(async (skillNameArg, options) => {
155059
155138
  try {
155060
155139
  const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155061
155140
  const skillName = skillNameArg ?? ctx.defaultSkillName ?? void 0;
@@ -155077,17 +155156,56 @@ var skillStatusCommand = new Command21("skill-status").description("Show detaile
155077
155156
  sessionFetch(ctx, "/grants")
155078
155157
  ]);
155079
155158
  const activeGrants = grantsData.grants.filter((g) => g.capability === detail.capability_name && g.status === "active");
155159
+ if (options.reviewReport) {
155160
+ const report = {
155161
+ skill_id: detail.id,
155162
+ capability_name: detail.capability_name,
155163
+ version: detail.latest_version,
155164
+ review_state: detail.review_state ?? null,
155165
+ public_reason_code: detail.latest_review?.public_reason_code ?? null,
155166
+ public_reason_message: detail.latest_review?.public_reason_message ?? null,
155167
+ last_review_at: detail.latest_review?.last_review_at ?? null
155168
+ };
155169
+ const reportPath = resolve9(options.reviewReport);
155170
+ writeFileSync10(reportPath, JSON.stringify(report, null, 2) + "\n");
155171
+ process.stderr.write(chalk18.green(`Wrote review report to ${reportPath}
155172
+ `));
155173
+ }
155080
155174
  if (options.json) {
155081
155175
  console.log(JSON.stringify({ ...detail, active_grants: activeGrants.length }, null, 2));
155082
155176
  return;
155083
155177
  }
155084
155178
  const statusColor = detail.status === "active" ? chalk18.green : detail.status === "archived" ? chalk18.yellow : chalk18.dim;
155085
155179
  const createdDate = new Date(detail.created_at).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
155180
+ const reviewState = detail.review_state ?? "approved";
155181
+ let reviewLabel;
155182
+ switch (reviewState) {
155183
+ case "approved":
155184
+ reviewLabel = chalk18.green("Approved");
155185
+ break;
155186
+ case "queued":
155187
+ case "running":
155188
+ reviewLabel = chalk18.yellow("Under review");
155189
+ break;
155190
+ case "rejected":
155191
+ reviewLabel = chalk18.red("Rejected");
155192
+ break;
155193
+ case "needs_human_review":
155194
+ reviewLabel = chalk18.yellow("Awaiting review");
155195
+ break;
155196
+ default:
155197
+ reviewLabel = chalk18.dim(reviewState);
155198
+ }
155199
+ const lastReviewAt = detail.latest_review?.last_review_at ? new Date(detail.latest_review.last_review_at).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }) : null;
155086
155200
  console.log();
155087
155201
  console.log(chalk18.bold(` ${detail.name}`));
155088
155202
  console.log();
155089
155203
  console.log(` Capability: ${detail.capability_name}`);
155090
155204
  console.log(` Status: ${statusColor(detail.status)}`);
155205
+ console.log(` Review: ${reviewLabel}${lastReviewAt ? chalk18.dim(` (${lastReviewAt})`) : ""}`);
155206
+ if (reviewState === "rejected" && detail.latest_review?.public_reason_message) {
155207
+ console.log(` Reason: ${chalk18.red(detail.latest_review.public_reason_message)}`);
155208
+ }
155091
155209
  console.log(` Version: ${chalk18.green("v" + detail.latest_version)}`);
155092
155210
  console.log(` Created: ${chalk18.dim(createdDate)}`);
155093
155211
  console.log(` ID: ${chalk18.dim(detail.id)}`);
@@ -155144,10 +155262,199 @@ var skillUnarchiveCommand = new Command22("skill-unarchive").description("Restor
155144
155262
  }
155145
155263
  });
155146
155264
 
155147
- // dist/commands/grants.js
155265
+ // dist/commands/skill-acl.js
155148
155266
  import { Command as Command23 } from "commander";
155149
155267
  import chalk20 from "chalk";
155150
- var grantsCommand = new Command23("grants").description("List capability grants issued to customers").option("--status <status>", "Filter by status: active, revoked, expired").option("--skill <name>", "Filter to grants for a specific skill (capability)").option("--json", "Output as JSON").option("--workspace <path>", "Use workspace at <path> to default --skill").option("--quiet", 'Suppress the "(using workspace \u2026)" stderr note').option("--all", "Disable workspace --skill default; show grants for all skills").action(async (options) => {
155268
+ var VALID_ROLES = /* @__PURE__ */ new Set(["read", "write", "owner"]);
155269
+ async function resolveSkill(ctx, skillName) {
155270
+ const data = await sessionFetch(ctx, "/skills");
155271
+ const skill = data.skills.find((s) => s.name.toLowerCase() === skillName.toLowerCase() || s.capability_name.toLowerCase() === skillName.toLowerCase());
155272
+ if (!skill) {
155273
+ process.stderr.write(chalk20.red(`Skill not found: ${skillName}
155274
+ `));
155275
+ process.stderr.write(chalk20.dim("Run `skillvault-publisher list` to see your skills.\n"));
155276
+ process.exit(1);
155277
+ }
155278
+ return skill;
155279
+ }
155280
+ async function runList(ctx, skill, options) {
155281
+ const data = await sessionFetch(ctx, `/skills/${skill.id}/acls`);
155282
+ const acls = data.acls || [];
155283
+ if (options.json) {
155284
+ console.log(JSON.stringify({ skill: skill.name, skill_id: skill.id, acls }, null, 2));
155285
+ return;
155286
+ }
155287
+ console.log();
155288
+ console.log(chalk20.bold(` ACL grants on ${chalk20.cyan(skill.name)}`));
155289
+ console.log();
155290
+ if (acls.length === 0) {
155291
+ console.log(chalk20.dim(" No ACL grants. Account owners and admins always have full access."));
155292
+ console.log(chalk20.dim(` Add a member: skillvault-publisher skill-acl ${skill.name} add <email> --role read|write|owner`));
155293
+ console.log();
155294
+ return;
155295
+ }
155296
+ const emailWidth = Math.max(20, ...acls.map((a) => a.email.length + 2));
155297
+ const roleWidth = 8;
155298
+ const header = [
155299
+ chalk20.dim("Email".padEnd(emailWidth)),
155300
+ chalk20.dim("Role".padEnd(roleWidth)),
155301
+ chalk20.dim("Granted by")
155302
+ ].join(" ");
155303
+ console.log(` ${header}`);
155304
+ console.log(` ${chalk20.dim("-".repeat(emailWidth + roleWidth + 24))}`);
155305
+ for (const a of acls) {
155306
+ const roleColor = a.role === "owner" ? chalk20.green : a.role === "write" ? chalk20.cyan : chalk20.dim;
155307
+ const row = [
155308
+ a.email.padEnd(emailWidth),
155309
+ roleColor(a.role.padEnd(roleWidth)),
155310
+ chalk20.dim(a.granted_by || "(self)")
155311
+ ].join(" ");
155312
+ console.log(` ${row}`);
155313
+ }
155314
+ console.log();
155315
+ }
155316
+ async function runAdd(ctx, skill, email, options) {
155317
+ if (!options.role) {
155318
+ process.stderr.write(chalk20.red("Error: --role is required (read|write|owner)\n"));
155319
+ process.exit(1);
155320
+ }
155321
+ const role = options.role.toLowerCase();
155322
+ if (!VALID_ROLES.has(role)) {
155323
+ process.stderr.write(chalk20.red(`Invalid --role value: ${options.role}
155324
+ `));
155325
+ process.stderr.write(chalk20.dim(" Must be one of: read, write, owner\n"));
155326
+ process.exit(1);
155327
+ }
155328
+ const res = await fetch(`${ctx.serverUrl}/skills/${skill.id}/acls`, {
155329
+ method: "POST",
155330
+ headers: ctx.headers,
155331
+ body: JSON.stringify({ email, role })
155332
+ });
155333
+ const body = await res.json().catch(() => ({}));
155334
+ if (!res.ok) {
155335
+ if (body.error === "not_a_team_member") {
155336
+ process.stderr.write(chalk20.red(`${email} is not a member of this team.
155337
+ `));
155338
+ process.stderr.write(chalk20.dim(`Add them first: skillvault-publisher team add ${email} --role member
155339
+ `));
155340
+ process.exit(1);
155341
+ }
155342
+ process.stderr.write(chalk20.red(`Failed to grant: ${body.message || body.error || res.statusText}
155343
+ `));
155344
+ process.exit(1);
155345
+ }
155346
+ if (options.json) {
155347
+ console.log(JSON.stringify(body, null, 2));
155348
+ return;
155349
+ }
155350
+ if (body.note) {
155351
+ console.log(chalk20.yellow(` ${body.note}`));
155352
+ return;
155353
+ }
155354
+ const acl = body.acl;
155355
+ console.log(chalk20.green(`Granted ${acl.email} ${chalk20.bold(acl.role)} on ${skill.name}`));
155356
+ }
155357
+ async function runRemove(ctx, skill, target, options) {
155358
+ const data = await sessionFetch(ctx, `/skills/${skill.id}/acls`);
155359
+ const acls = data.acls || [];
155360
+ let acl;
155361
+ if (target.startsWith("acl_")) {
155362
+ acl = acls.find((a) => a.id === target);
155363
+ } else {
155364
+ acl = acls.find((a) => a.email.toLowerCase() === target.toLowerCase());
155365
+ }
155366
+ if (!acl) {
155367
+ process.stderr.write(chalk20.red(`No ACL row matches: ${target}
155368
+ `));
155369
+ process.exit(1);
155370
+ }
155371
+ if (!options.yes) {
155372
+ console.log();
155373
+ console.log(chalk20.yellow.bold(" Warning: ") + `This revokes ${acl.role} access on ${chalk20.cyan(skill.name)} for ${chalk20.cyan(acl.email)}.`);
155374
+ console.log(chalk20.dim(" Add --yes to confirm."));
155375
+ console.log();
155376
+ process.exit(0);
155377
+ }
155378
+ const res = await fetch(`${ctx.serverUrl}/skills/${skill.id}/acls/${acl.id}`, {
155379
+ method: "DELETE",
155380
+ headers: ctx.headers
155381
+ });
155382
+ const body = await res.json().catch(() => ({}));
155383
+ if (!res.ok) {
155384
+ if (body.error === "last_owner") {
155385
+ process.stderr.write(chalk20.red("Cannot remove the last owner ACL on this skill.\n"));
155386
+ process.stderr.write(chalk20.dim(" Grant another member owner access first, or have an account admin manage it.\n"));
155387
+ process.exit(1);
155388
+ }
155389
+ process.stderr.write(chalk20.red(`Failed to remove: ${body.message || body.error || res.statusText}
155390
+ `));
155391
+ process.exit(1);
155392
+ }
155393
+ if (options.json) {
155394
+ console.log(JSON.stringify({ removed: true, acl_id: acl.id, email: acl.email, role: acl.role }, null, 2));
155395
+ return;
155396
+ }
155397
+ console.log(chalk20.green(`Removed ${acl.email} (${acl.role}) from ${skill.name}`));
155398
+ }
155399
+ var skillAclCommand = new Command23("skill-acl").description("Manage per-skill ACL grants for team members").argument("<skill-name>", 'Skill to manage (or "list"/"add"/"remove" if using a workspace default)').argument("<action>", "Action: list | add | remove").argument("[target]", "Email (for add/remove) \u2014 not used by list").option("--role <role>", "Role for add: read | write | owner").option("--yes", "Skip confirmation on remove").option("--workspace <path>", "Use workspace at <path> to default skill-name").option("--quiet", 'Suppress the "(using workspace \u2026)" stderr note').option("--json", "Output as JSON").action(async (skillNameArg, actionArg, targetArg, options) => {
155400
+ try {
155401
+ let skillName = skillNameArg;
155402
+ let action = actionArg;
155403
+ let target = targetArg;
155404
+ const isActionVerb = (s) => s === "list" || s === "add" || s === "remove";
155405
+ if (isActionVerb(skillNameArg) && !isActionVerb(actionArg)) {
155406
+ action = skillNameArg;
155407
+ target = actionArg;
155408
+ skillName = "";
155409
+ }
155410
+ const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155411
+ if (!skillName) {
155412
+ if (!ctx.defaultSkillName) {
155413
+ process.stderr.write(chalk20.red("Error: No skill name provided and no workspace context.\n"));
155414
+ process.stderr.write(chalk20.dim(" Pass <skill-name> or run from a linked workspace directory.\n"));
155415
+ process.exit(1);
155416
+ }
155417
+ skillName = ctx.defaultSkillName;
155418
+ }
155419
+ if (!isActionVerb(action)) {
155420
+ process.stderr.write(chalk20.red(`Unknown action: ${action}
155421
+ `));
155422
+ process.stderr.write(chalk20.dim(" Must be one of: list, add, remove\n"));
155423
+ process.exit(1);
155424
+ }
155425
+ const skill = await resolveSkill(ctx, skillName);
155426
+ if (action === "list") {
155427
+ await runList(ctx, skill, options);
155428
+ return;
155429
+ }
155430
+ if (action === "add") {
155431
+ if (!target) {
155432
+ process.stderr.write(chalk20.red("Error: add requires <email>\n"));
155433
+ process.exit(1);
155434
+ }
155435
+ await runAdd(ctx, skill, target, options);
155436
+ return;
155437
+ }
155438
+ if (action === "remove") {
155439
+ if (!target) {
155440
+ process.stderr.write(chalk20.red("Error: remove requires <email-or-id>\n"));
155441
+ process.exit(1);
155442
+ }
155443
+ await runRemove(ctx, skill, target, options);
155444
+ return;
155445
+ }
155446
+ } catch (err) {
155447
+ const message = err instanceof Error ? err.message : String(err);
155448
+ process.stderr.write(chalk20.red(`skill-acl failed: ${message}
155449
+ `));
155450
+ process.exit(1);
155451
+ }
155452
+ });
155453
+
155454
+ // dist/commands/grants.js
155455
+ import { Command as Command24 } from "commander";
155456
+ import chalk21 from "chalk";
155457
+ var grantsCommand = new Command24("grants").description("List capability grants issued to customers").option("--status <status>", "Filter by status: active, revoked, expired").option("--skill <name>", "Filter to grants for a specific skill (capability)").option("--json", "Output as JSON").option("--workspace <path>", "Use workspace at <path> to default --skill").option("--quiet", 'Suppress the "(using workspace \u2026)" stderr note').option("--all", "Disable workspace --skill default; show grants for all skills").action(async (options) => {
155151
155458
  try {
155152
155459
  const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155153
155460
  const data = await sessionFetch(ctx, "/grants");
@@ -155165,18 +155472,18 @@ var grantsCommand = new Command23("grants").description("List capability grants
155165
155472
  return;
155166
155473
  }
155167
155474
  if (grants.length === 0) {
155168
- console.log(chalk20.dim("No grants found."));
155475
+ console.log(chalk21.dim("No grants found."));
155169
155476
  return;
155170
155477
  }
155171
155478
  console.log();
155172
- console.log(chalk20.bold(" Capability Grants"));
155479
+ console.log(chalk21.bold(" Capability Grants"));
155173
155480
  console.log();
155174
155481
  const pad4 = (s, n) => s.padEnd(n).slice(0, n);
155175
155482
  const header = `${pad4("Grant ID", 22)} ${pad4("Skill", 24)} ${pad4("Customer", 22)} ${pad4("Status", 10)} ${pad4("Granted", 12)} ${"Expires"}`;
155176
- console.log(` ${chalk20.dim(header)}`);
155177
- console.log(` ${chalk20.dim("\u2500".repeat(header.length))}`);
155483
+ console.log(` ${chalk21.dim(header)}`);
155484
+ console.log(` ${chalk21.dim("\u2500".repeat(header.length))}`);
155178
155485
  for (const grant of grants) {
155179
- const statusColor = grant.status === "active" ? chalk20.green : grant.status === "revoked" ? chalk20.red : grant.status === "expired" ? chalk20.yellow : chalk20.white;
155486
+ const statusColor = grant.status === "active" ? chalk21.green : grant.status === "revoked" ? chalk21.red : grant.status === "expired" ? chalk21.yellow : chalk21.white;
155180
155487
  const row = [
155181
155488
  pad4(grant.id, 22),
155182
155489
  pad4(grant.capability, 24),
@@ -155188,20 +155495,20 @@ var grantsCommand = new Command23("grants").description("List capability grants
155188
155495
  console.log(` ${row}`);
155189
155496
  }
155190
155497
  console.log();
155191
- console.log(chalk20.dim(` ${grants.length} grant${grants.length !== 1 ? "s" : ""} total`));
155498
+ console.log(chalk21.dim(` ${grants.length} grant${grants.length !== 1 ? "s" : ""} total`));
155192
155499
  console.log();
155193
155500
  } catch (err) {
155194
155501
  const message = err instanceof Error ? err.message : String(err);
155195
- process.stderr.write(chalk20.red(`Error: ${message}
155502
+ process.stderr.write(chalk21.red(`Error: ${message}
155196
155503
  `));
155197
155504
  process.exit(1);
155198
155505
  }
155199
155506
  });
155200
155507
 
155201
155508
  // dist/commands/revoke-grant.js
155202
- import { Command as Command24 } from "commander";
155203
- import chalk21 from "chalk";
155204
- var revokeGrantCommand = new Command24("revoke-grant").description("Revoke a capability grant by ID").argument("<grant-id>", "Grant ID to revoke (e.g., gnt_xxx)").option("--yes", "Skip confirmation and revoke immediately").option("--json", "Output as JSON").option("--workspace <path>", "Resolve workspace context (informational only \u2014 grant ID is authoritative)").option("--quiet", 'Suppress the "(using workspace \u2026)" stderr note').action(async (grantId, options) => {
155509
+ import { Command as Command25 } from "commander";
155510
+ import chalk22 from "chalk";
155511
+ var revokeGrantCommand = new Command25("revoke-grant").description("Revoke a capability grant by ID").argument("<grant-id>", "Grant ID to revoke (e.g., gnt_xxx)").option("--yes", "Skip confirmation and revoke immediately").option("--json", "Output as JSON").option("--workspace <path>", "Resolve workspace context (informational only \u2014 grant ID is authoritative)").option("--quiet", 'Suppress the "(using workspace \u2026)" stderr note').action(async (grantId, options) => {
155205
155512
  try {
155206
155513
  const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155207
155514
  if (!options.yes) {
@@ -155212,7 +155519,7 @@ var revokeGrantCommand = new Command24("revoke-grant").description("Revoke a cap
155212
155519
  return;
155213
155520
  }
155214
155521
  console.log();
155215
- console.log(chalk21.bold(" Grant details"));
155522
+ console.log(chalk22.bold(" Grant details"));
155216
155523
  console.log();
155217
155524
  console.log(` ID: ${grant.id}`);
155218
155525
  console.log(` Skill: ${grant.skill}`);
@@ -155221,7 +155528,7 @@ var revokeGrantCommand = new Command24("revoke-grant").description("Revoke a cap
155221
155528
  console.log(` Granted: ${new Date(grant.granted_at).toLocaleDateString()}`);
155222
155529
  console.log(` Expires: ${grant.expires_at ? new Date(grant.expires_at).toLocaleDateString() : "never"}`);
155223
155530
  console.log();
155224
- console.log(chalk21.yellow(" Add --yes to confirm revocation."));
155531
+ console.log(chalk22.yellow(" Add --yes to confirm revocation."));
155225
155532
  console.log();
155226
155533
  return;
155227
155534
  }
@@ -155230,19 +155537,19 @@ var revokeGrantCommand = new Command24("revoke-grant").description("Revoke a cap
155230
155537
  console.log(JSON.stringify(result.grant, null, 2));
155231
155538
  return;
155232
155539
  }
155233
- console.log(chalk21.green(`Revoked grant ${result.grant.id} for ${result.grant.skill}`));
155540
+ console.log(chalk22.green(`Revoked grant ${result.grant.id} for ${result.grant.skill}`));
155234
155541
  } catch (err) {
155235
155542
  const message = err instanceof Error ? err.message : String(err);
155236
- process.stderr.write(chalk21.red(`Error: ${message}
155543
+ process.stderr.write(chalk22.red(`Error: ${message}
155237
155544
  `));
155238
155545
  process.exit(1);
155239
155546
  }
155240
155547
  });
155241
155548
 
155242
155549
  // dist/commands/customers.js
155243
- import { Command as Command25 } from "commander";
155244
- import chalk22 from "chalk";
155245
- var customersCommand = new Command25("customers").description("List your customers").option("--json", "Output as JSON").option("--workspace <path>", "Resolve workspace context (defaults from CWD)").option("--quiet", 'Suppress the "(using workspace \u2026)" stderr note').action(async (options) => {
155550
+ import { Command as Command26 } from "commander";
155551
+ import chalk23 from "chalk";
155552
+ var customersCommand = new Command26("customers").description("List your customers").option("--json", "Output as JSON").option("--workspace <path>", "Resolve workspace context (defaults from CWD)").option("--quiet", 'Suppress the "(using workspace \u2026)" stderr note').action(async (options) => {
155246
155553
  const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155247
155554
  try {
155248
155555
  const data = await sessionFetch(ctx, "/customers");
@@ -155252,19 +155559,19 @@ var customersCommand = new Command25("customers").description("List your custome
155252
155559
  return;
155253
155560
  }
155254
155561
  if (customers.length === 0) {
155255
- console.log(chalk22.dim("No customers found."));
155562
+ console.log(chalk23.dim("No customers found."));
155256
155563
  return;
155257
155564
  }
155258
155565
  console.log();
155259
- console.log(chalk22.bold(" Customers"));
155566
+ console.log(chalk23.bold(" Customers"));
155260
155567
  console.log();
155261
155568
  const pad4 = (s, n) => s.padEnd(n).slice(0, n);
155262
155569
  const header = `${pad4("Email", 32)} ${pad4("Skills", 8)} ${pad4("Loads", 8)} ${pad4("Status", 10)} Last Active`;
155263
- console.log(` ${chalk22.dim(header)}`);
155264
- console.log(` ${chalk22.dim("\u2500".repeat(header.length))}`);
155570
+ console.log(` ${chalk23.dim(header)}`);
155571
+ console.log(` ${chalk23.dim("\u2500".repeat(header.length))}`);
155265
155572
  for (const c of customers) {
155266
- const statusColor = c.status === "active" ? chalk22.green : chalk22.dim;
155267
- const lastActive = c.last_active_at ? new Date(c.last_active_at).toLocaleDateString() : chalk22.dim("never");
155573
+ const statusColor = c.status === "active" ? chalk23.green : chalk23.dim;
155574
+ const lastActive = c.last_active_at ? new Date(c.last_active_at).toLocaleDateString() : chalk23.dim("never");
155268
155575
  const row = [
155269
155576
  pad4(c.email, 32),
155270
155577
  pad4(String(c.skills_count), 8),
@@ -155275,25 +155582,25 @@ var customersCommand = new Command25("customers").description("List your custome
155275
155582
  console.log(` ${row}`);
155276
155583
  }
155277
155584
  console.log();
155278
- console.log(chalk22.dim(` ${customers.length} customer${customers.length !== 1 ? "s" : ""} total`));
155585
+ console.log(chalk23.dim(` ${customers.length} customer${customers.length !== 1 ? "s" : ""} total`));
155279
155586
  console.log();
155280
155587
  } catch (err) {
155281
155588
  const message = err instanceof Error ? err.message : String(err);
155282
- process.stderr.write(chalk22.red(`Error: ${message}
155589
+ process.stderr.write(chalk23.red(`Error: ${message}
155283
155590
  `));
155284
155591
  process.exit(1);
155285
155592
  }
155286
155593
  });
155287
155594
 
155288
155595
  // dist/commands/analytics.js
155289
- import { Command as Command26 } from "commander";
155290
- import chalk23 from "chalk";
155291
- var analyticsCommand = new Command26("analytics").description("View publisher analytics").option("--days <n>", "Number of days to look back", "30").option("--skill <name>", "Filter top skills/stats to a specific skill").option("--json", "Output as JSON").option("--workspace <path>", "Use workspace at <path> to default --skill").option("--quiet", 'Suppress the "(using workspace \u2026)" stderr note').option("--all", "Disable workspace --skill default; show analytics for all skills").action(async (options) => {
155596
+ import { Command as Command27 } from "commander";
155597
+ import chalk24 from "chalk";
155598
+ var analyticsCommand = new Command27("analytics").description("View publisher analytics").option("--days <n>", "Number of days to look back", "30").option("--skill <name>", "Filter top skills/stats to a specific skill").option("--json", "Output as JSON").option("--workspace <path>", "Use workspace at <path> to default --skill").option("--quiet", 'Suppress the "(using workspace \u2026)" stderr note').option("--all", "Disable workspace --skill default; show analytics for all skills").action(async (options) => {
155292
155599
  const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155293
155600
  try {
155294
155601
  const days = parseInt(options.days, 10);
155295
155602
  if (isNaN(days) || days < 1) {
155296
- process.stderr.write(chalk23.red("--days must be a positive number.\n"));
155603
+ process.stderr.write(chalk24.red("--days must be a positive number.\n"));
155297
155604
  process.exit(1);
155298
155605
  }
155299
155606
  const end = /* @__PURE__ */ new Date();
@@ -155306,11 +155613,11 @@ var analyticsCommand = new Command26("analytics").description("View publisher an
155306
155613
  return;
155307
155614
  }
155308
155615
  console.log();
155309
- console.log(chalk23.bold(" Publisher Analytics"));
155616
+ console.log(chalk24.bold(" Publisher Analytics"));
155310
155617
  console.log();
155311
- console.log(` ${chalk23.bold("Active Licenses:")} ${data.active_licenses}`);
155312
- console.log(` ${chalk23.bold("Total Decryptions:")} ${data.total_decryptions}`);
155313
- console.log(` ${chalk23.bold("Period:")} Last ${days} day${days !== 1 ? "s" : ""} (${start.toLocaleDateString()} \u2013 ${end.toLocaleDateString()})`);
155618
+ console.log(` ${chalk24.bold("Active Licenses:")} ${data.active_licenses}`);
155619
+ console.log(` ${chalk24.bold("Total Decryptions:")} ${data.total_decryptions}`);
155620
+ console.log(` ${chalk24.bold("Period:")} Last ${days} day${days !== 1 ? "s" : ""} (${start.toLocaleDateString()} \u2013 ${end.toLocaleDateString()})`);
155314
155621
  const effectiveSkill = options.skill ?? (options.all ? void 0 : ctx.defaultSkillName ?? void 0);
155315
155622
  const filterSkill = (skillName) => !effectiveSkill || skillName.toLowerCase() === effectiveSkill.toLowerCase();
155316
155623
  const statsMap = new Map((data.skill_stats || []).map((s) => [s.skill_name, s]));
@@ -155319,12 +155626,12 @@ var analyticsCommand = new Command26("analytics").description("View publisher an
155319
155626
  }
155320
155627
  if (data.top_skills && data.top_skills.length > 0) {
155321
155628
  console.log();
155322
- console.log(chalk23.bold(" Top Skills"));
155629
+ console.log(chalk24.bold(" Top Skills"));
155323
155630
  console.log();
155324
155631
  const pad4 = (s, n) => s.padEnd(n).slice(0, n);
155325
155632
  const header = `${pad4("Skill", 28)} ${pad4("Decryptions", 14)} Active Licenses`;
155326
- console.log(` ${chalk23.dim(header)}`);
155327
- console.log(` ${chalk23.dim("\u2500".repeat(header.length))}`);
155633
+ console.log(` ${chalk24.dim(header)}`);
155634
+ console.log(` ${chalk24.dim("\u2500".repeat(header.length))}`);
155328
155635
  for (const skill of data.top_skills) {
155329
155636
  const stats = statsMap.get(skill.name);
155330
155637
  const row = [
@@ -155336,27 +155643,27 @@ var analyticsCommand = new Command26("analytics").description("View publisher an
155336
155643
  }
155337
155644
  } else {
155338
155645
  console.log();
155339
- console.log(chalk23.dim(" No skill activity in this period."));
155646
+ console.log(chalk24.dim(" No skill activity in this period."));
155340
155647
  }
155341
155648
  console.log();
155342
155649
  } catch (err) {
155343
155650
  const message = err instanceof Error ? err.message : String(err);
155344
- process.stderr.write(chalk23.red(`Error: ${message}
155651
+ process.stderr.write(chalk24.red(`Error: ${message}
155345
155652
  `));
155346
155653
  process.exit(1);
155347
155654
  }
155348
155655
  });
155349
155656
 
155350
155657
  // dist/commands/webhook.js
155351
- import { Command as Command27 } from "commander";
155352
- import chalk24 from "chalk";
155353
- var webhookCommand = new Command27("webhook").description("Manage publisher webhook (set, test, status)").argument("<action>", "Action: set, test, or status").option("--url <url>", "Webhook URL (required for set)").option("--json", "Output as JSON").action(async (action, options) => {
155658
+ import { Command as Command28 } from "commander";
155659
+ import chalk25 from "chalk";
155660
+ var webhookCommand = new Command28("webhook").description("Manage publisher webhook (set, test, status)").argument("<action>", "Action: set, test, or status").option("--url <url>", "Webhook URL (required for set)").option("--json", "Output as JSON").action(async (action, options) => {
155354
155661
  try {
155355
155662
  const ctx = requireSession();
155356
155663
  switch (action) {
155357
155664
  case "set": {
155358
155665
  if (!options.url) {
155359
- process.stderr.write(chalk24.red("Missing --url option. Usage: skillvault-publisher webhook set --url <url>\n"));
155666
+ process.stderr.write(chalk25.red("Missing --url option. Usage: skillvault-publisher webhook set --url <url>\n"));
155360
155667
  process.exit(1);
155361
155668
  }
155362
155669
  const data = await sessionFetch(ctx, `/publishers/${ctx.publisherId}/webhook`, { method: "POST", body: { url: options.url } });
@@ -155365,12 +155672,12 @@ var webhookCommand = new Command27("webhook").description("Manage publisher webh
155365
155672
  return;
155366
155673
  }
155367
155674
  console.log();
155368
- console.log(chalk24.green(" Webhook configured"));
155675
+ console.log(chalk25.green(" Webhook configured"));
155369
155676
  console.log();
155370
155677
  console.log(` ${"URL:".padEnd(18)} ${data.webhook_url}`);
155371
- console.log(` ${"Signing Secret:".padEnd(18)} ${chalk24.yellow(data.signing_secret)}`);
155678
+ console.log(` ${"Signing Secret:".padEnd(18)} ${chalk25.yellow(data.signing_secret)}`);
155372
155679
  console.log();
155373
- console.log(chalk24.dim(" Store the signing secret securely. It will not be shown again."));
155680
+ console.log(chalk25.dim(" Store the signing secret securely. It will not be shown again."));
155374
155681
  console.log();
155375
155682
  break;
155376
155683
  }
@@ -155381,7 +155688,7 @@ var webhookCommand = new Command27("webhook").description("Manage publisher webh
155381
155688
  return;
155382
155689
  }
155383
155690
  console.log();
155384
- console.log(chalk24.green(" Test event sent to webhook URL"));
155691
+ console.log(chalk25.green(" Test event sent to webhook URL"));
155385
155692
  console.log();
155386
155693
  break;
155387
155694
  }
@@ -155393,36 +155700,36 @@ var webhookCommand = new Command27("webhook").description("Manage publisher webh
155393
155700
  }
155394
155701
  console.log();
155395
155702
  if (data.webhook_url) {
155396
- console.log(chalk24.bold(" Webhook Status"));
155703
+ console.log(chalk25.bold(" Webhook Status"));
155397
155704
  console.log();
155398
155705
  console.log(` ${"URL:".padEnd(12)} ${data.webhook_url}`);
155399
- console.log(` ${"Status:".padEnd(12)} ${chalk24.green("configured")}`);
155706
+ console.log(` ${"Status:".padEnd(12)} ${chalk25.green("configured")}`);
155400
155707
  } else {
155401
- console.log(chalk24.dim(" No webhook configured."));
155708
+ console.log(chalk25.dim(" No webhook configured."));
155402
155709
  console.log();
155403
- console.log(chalk24.dim(" Set one with: skillvault-publisher webhook set --url <url>"));
155710
+ console.log(chalk25.dim(" Set one with: skillvault-publisher webhook set --url <url>"));
155404
155711
  }
155405
155712
  console.log();
155406
155713
  break;
155407
155714
  }
155408
155715
  default:
155409
- process.stderr.write(chalk24.red(`Unknown action: ${action}
155716
+ process.stderr.write(chalk25.red(`Unknown action: ${action}
155410
155717
  `));
155411
- process.stderr.write(chalk24.dim("Valid actions: set, test, status\n"));
155718
+ process.stderr.write(chalk25.dim("Valid actions: set, test, status\n"));
155412
155719
  process.exit(1);
155413
155720
  }
155414
155721
  } catch (err) {
155415
155722
  const message = err instanceof Error ? err.message : String(err);
155416
- process.stderr.write(chalk24.red(`Error: ${message}
155723
+ process.stderr.write(chalk25.red(`Error: ${message}
155417
155724
  `));
155418
155725
  process.exit(1);
155419
155726
  }
155420
155727
  });
155421
155728
 
155422
155729
  // dist/commands/audit.js
155423
- import { Command as Command28 } from "commander";
155424
- import chalk25 from "chalk";
155425
- var auditCommand = new Command28("audit").description("View audit log events").option("--type <event_type>", "Filter by event type").option("--skill <name>", "Filter by capability/skill name").option("--since <date>", "Filter events since ISO date").option("--limit <n>", "Number of events to return", "20").option("--export <format>", "Export as csv or json").option("--json", "Output as JSON").option("--workspace <path>", "Use workspace at <path> to default --skill").option("--quiet", 'Suppress the "(using workspace \u2026)" stderr note').option("--all", "Disable workspace --skill default; show events for all skills").action(async (options) => {
155730
+ import { Command as Command29 } from "commander";
155731
+ import chalk26 from "chalk";
155732
+ var auditCommand = new Command29("audit").description("View audit log events").option("--type <event_type>", "Filter by event type").option("--skill <name>", "Filter by capability/skill name").option("--since <date>", "Filter events since ISO date").option("--limit <n>", "Number of events to return", "20").option("--export <format>", "Export as csv or json").option("--json", "Output as JSON").option("--workspace <path>", "Use workspace at <path> to default --skill").option("--quiet", 'Suppress the "(using workspace \u2026)" stderr note').option("--all", "Disable workspace --skill default; show events for all skills").action(async (options) => {
155426
155733
  try {
155427
155734
  const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155428
155735
  const effectiveSkill = options.skill ?? (options.all ? void 0 : ctx.defaultSkillName ?? void 0);
@@ -155437,7 +155744,7 @@ var auditCommand = new Command28("audit").description("View audit log events").o
155437
155744
  if (options.export) {
155438
155745
  const format = options.export.toLowerCase();
155439
155746
  if (format !== "csv" && format !== "json") {
155440
- process.stderr.write(chalk25.red('Export format must be "csv" or "json".\n'));
155747
+ process.stderr.write(chalk26.red('Export format must be "csv" or "json".\n'));
155441
155748
  process.exit(1);
155442
155749
  }
155443
155750
  params.set("format", format);
@@ -155456,16 +155763,16 @@ var auditCommand = new Command28("audit").description("View audit log events").o
155456
155763
  return;
155457
155764
  }
155458
155765
  if (events.length === 0) {
155459
- console.log(chalk25.dim("No audit events found."));
155766
+ console.log(chalk26.dim("No audit events found."));
155460
155767
  return;
155461
155768
  }
155462
155769
  console.log();
155463
- console.log(chalk25.bold(" Audit Log"));
155770
+ console.log(chalk26.bold(" Audit Log"));
155464
155771
  console.log();
155465
155772
  const pad4 = (s, n) => s.padEnd(n).slice(0, n);
155466
155773
  const header = `${pad4("Event Type", 22)} ${pad4("Skill", 24)} ${pad4("Agent", 20)} ${"Time"}`;
155467
- console.log(` ${chalk25.dim(header)}`);
155468
- console.log(` ${chalk25.dim("\u2500".repeat(header.length))}`);
155774
+ console.log(` ${chalk26.dim(header)}`);
155775
+ console.log(` ${chalk26.dim("\u2500".repeat(header.length))}`);
155469
155776
  for (const event of events) {
155470
155777
  const skill = event.capability ? event.capability.replace(/^skill\//, "") : "-";
155471
155778
  const agent = event.agent_id ? event.agent_id.slice(0, 18) : "-";
@@ -155479,45 +155786,45 @@ var auditCommand = new Command28("audit").description("View audit log events").o
155479
155786
  console.log(` ${row}`);
155480
155787
  }
155481
155788
  console.log();
155482
- console.log(chalk25.dim(` Showing ${events.length} event${events.length !== 1 ? "s" : ""}`));
155789
+ console.log(chalk26.dim(` Showing ${events.length} event${events.length !== 1 ? "s" : ""}`));
155483
155790
  if (data.has_more) {
155484
- console.log(chalk25.dim(` More results available`));
155791
+ console.log(chalk26.dim(` More results available`));
155485
155792
  }
155486
155793
  console.log();
155487
155794
  } catch (err) {
155488
155795
  const message = err instanceof Error ? err.message : String(err);
155489
- process.stderr.write(chalk25.red(`Error: ${message}
155796
+ process.stderr.write(chalk26.red(`Error: ${message}
155490
155797
  `));
155491
155798
  process.exit(1);
155492
155799
  }
155493
155800
  });
155494
155801
 
155495
155802
  // dist/commands/investigate.js
155496
- import { Command as Command29 } from "commander";
155497
- import chalk26 from "chalk";
155498
- import { readFileSync as readFileSync15, mkdirSync as mkdirSync9, writeFileSync as writeFileSync10 } from "node:fs";
155803
+ import { Command as Command30 } from "commander";
155804
+ import chalk27 from "chalk";
155805
+ import { readFileSync as readFileSync15, mkdirSync as mkdirSync9, writeFileSync as writeFileSync11 } from "node:fs";
155499
155806
  import { join as join14 } from "node:path";
155500
- var orange = chalk26.hex("#f97316");
155807
+ var orange = chalk27.hex("#f97316");
155501
155808
  function riskColor2(level) {
155502
155809
  switch (level.toLowerCase()) {
155503
155810
  case "low":
155504
- return chalk26.green;
155811
+ return chalk27.green;
155505
155812
  case "watch":
155506
- return chalk26.yellow;
155813
+ return chalk27.yellow;
155507
155814
  case "alert":
155508
155815
  return orange;
155509
155816
  case "critical":
155510
- return chalk26.red;
155817
+ return chalk27.red;
155511
155818
  default:
155512
- return chalk26.white;
155819
+ return chalk27.white;
155513
155820
  }
155514
155821
  }
155515
155822
  function confidenceColor(c) {
155516
155823
  if (c >= 0.9)
155517
- return chalk26.green;
155824
+ return chalk27.green;
155518
155825
  if (c >= 0.5)
155519
- return chalk26.yellow;
155520
- return chalk26.red;
155826
+ return chalk27.yellow;
155827
+ return chalk27.red;
155521
155828
  }
155522
155829
  function pad(s, n) {
155523
155830
  return s.padEnd(n).slice(0, n);
@@ -155533,30 +155840,30 @@ function toRawGitHubUrl(url) {
155533
155840
  }
155534
155841
  function displayResults(report) {
155535
155842
  console.log();
155536
- console.log(chalk26.bold(" Investigation Results"));
155843
+ console.log(chalk27.bold(" Investigation Results"));
155537
155844
  console.log();
155538
- console.log(` ${chalk26.bold("Investigation ID:")} ${report.investigation_id}`);
155539
- console.log(` ${chalk26.bold("Skill:")} ${report.skill_name}`);
155540
- console.log(` ${chalk26.bold("Total Licensees:")} ${report.total_licensees}`);
155541
- console.log(` ${chalk26.bold("Timestamp:")} ${new Date(report.created_at).toLocaleString()}`);
155845
+ console.log(` ${chalk27.bold("Investigation ID:")} ${report.investigation_id}`);
155846
+ console.log(` ${chalk27.bold("Skill:")} ${report.skill_name}`);
155847
+ console.log(` ${chalk27.bold("Total Licensees:")} ${report.total_licensees}`);
155848
+ console.log(` ${chalk27.bold("Timestamp:")} ${new Date(report.created_at).toLocaleString()}`);
155542
155849
  if (report.heartbeat_matches.length > 0) {
155543
155850
  console.log();
155544
155851
  const maxConf = Math.max(...report.heartbeat_matches.map((m) => m.confidence));
155545
155852
  const confStr = (maxConf * 100).toFixed(0) + "%";
155546
155853
  const confFn = confidenceColor(maxConf);
155547
- console.log(` ${chalk26.bold("Forensic Match:")} ${confFn(confStr + " confidence")} (${report.heartbeat_matches.length} match${report.heartbeat_matches.length !== 1 ? "es" : ""})`);
155854
+ console.log(` ${chalk27.bold("Forensic Match:")} ${confFn(confStr + " confidence")} (${report.heartbeat_matches.length} match${report.heartbeat_matches.length !== 1 ? "es" : ""})`);
155548
155855
  }
155549
155856
  console.log();
155550
155857
  if (report.suspects.length === 0) {
155551
- console.log(chalk26.dim(" No suspects identified."));
155858
+ console.log(chalk27.dim(" No suspects identified."));
155552
155859
  console.log();
155553
155860
  return;
155554
155861
  }
155555
- console.log(chalk26.bold(" Suspect Ranking"));
155862
+ console.log(chalk27.bold(" Suspect Ranking"));
155556
155863
  console.log();
155557
155864
  const header = `${pad("Suspect", 24)} ${pad("Risk Level", 12)} ${pad("Confidence", 12)} ${pad("Anomalies", 10)} ${"Strikes"}`;
155558
- console.log(` ${chalk26.dim(header)}`);
155559
- console.log(` ${chalk26.dim("\u2500".repeat(header.length))}`);
155865
+ console.log(` ${chalk27.dim(header)}`);
155866
+ console.log(` ${chalk27.dim("\u2500".repeat(header.length))}`);
155560
155867
  for (const s of report.suspects) {
155561
155868
  const colorFn = riskColor2(s.risk_level);
155562
155869
  const label = s.customer_email || s.licensee_id.slice(0, 22);
@@ -155570,8 +155877,8 @@ function displayResults(report) {
155570
155877
  console.log(` ${row}`);
155571
155878
  }
155572
155879
  console.log();
155573
- console.log(chalk26.dim(` Full evidence retained server-side (ID: ${report.investigation_id})`));
155574
- console.log(chalk26.dim(" Contact investigations@getskillvault.com for the complete evidence package."));
155880
+ console.log(chalk27.dim(` Full evidence retained server-side (ID: ${report.investigation_id})`));
155881
+ console.log(chalk27.dim(" Contact investigations@getskillvault.com for the complete evidence package."));
155575
155882
  console.log();
155576
155883
  }
155577
155884
  function buildHtmlReport(report, _auditEvents, metadata) {
@@ -155816,7 +156123,7 @@ ${report.suspects.length > 0 ? `<table>
155816
156123
  </body>
155817
156124
  </html>`;
155818
156125
  }
155819
- var investigateCommand = new Command29("investigate").description("Investigate a suspected skill leak").argument("<skill-name>", "Name of the skill to investigate").option("--url <url>", "Fetch leaked content from a URL (GitHub raw, gist, etc.)").option("--file <path>", "Read leaked content from a local file").option("--report <dir>", "Generate full investigation report package to directory").option("--json", "Output as JSON").action(async (skillName, options) => {
156126
+ var investigateCommand = new Command30("investigate").description("Investigate a suspected skill leak").argument("<skill-name>", "Name of the skill to investigate").option("--url <url>", "Fetch leaked content from a URL (GitHub raw, gist, etc.)").option("--file <path>", "Read leaked content from a local file").option("--report <dir>", "Generate full investigation report package to directory").option("--json", "Output as JSON").action(async (skillName, options) => {
155820
156127
  try {
155821
156128
  const ctx = requireSession();
155822
156129
  let leakedContent;
@@ -155824,12 +156131,12 @@ var investigateCommand = new Command29("investigate").description("Investigate a
155824
156131
  if (options.url) {
155825
156132
  const rawUrl = toRawGitHubUrl(options.url);
155826
156133
  if (rawUrl !== options.url) {
155827
- console.log(chalk26.dim(` Auto-converted GitHub blob URL to raw URL`));
156134
+ console.log(chalk27.dim(` Auto-converted GitHub blob URL to raw URL`));
155828
156135
  }
155829
- console.log(chalk26.dim(` Fetching leaked content from ${rawUrl}...`));
156136
+ console.log(chalk27.dim(` Fetching leaked content from ${rawUrl}...`));
155830
156137
  const resp = await fetch(rawUrl);
155831
156138
  if (!resp.ok) {
155832
- process.stderr.write(chalk26.red(`Failed to fetch URL: ${resp.status} ${resp.statusText}
156139
+ process.stderr.write(chalk27.red(`Failed to fetch URL: ${resp.status} ${resp.statusText}
155833
156140
  `));
155834
156141
  process.exit(1);
155835
156142
  }
@@ -155840,24 +156147,24 @@ var investigateCommand = new Command29("investigate").description("Investigate a
155840
156147
  leakedContent = readFileSync15(options.file, "utf-8");
155841
156148
  } catch (err) {
155842
156149
  const msg = err instanceof Error ? err.message : String(err);
155843
- process.stderr.write(chalk26.red(`Failed to read file: ${msg}
156150
+ process.stderr.write(chalk27.red(`Failed to read file: ${msg}
155844
156151
  `));
155845
156152
  process.exit(1);
155846
156153
  }
155847
156154
  sourceLabel = options.file;
155848
156155
  } else {
155849
- process.stderr.write(chalk26.red("Provide leaked content with --url <url> or --file <path>.\n"));
156156
+ process.stderr.write(chalk27.red("Provide leaked content with --url <url> or --file <path>.\n"));
155850
156157
  process.exit(1);
155851
156158
  }
155852
- console.log(chalk26.dim(` Loaded ${leakedContent.length.toLocaleString()} chars of leaked content`));
156159
+ console.log(chalk27.dim(` Loaded ${leakedContent.length.toLocaleString()} chars of leaked content`));
155853
156160
  const skillsData = await sessionFetch(ctx, "/skills");
155854
156161
  const skill = skillsData.skills.find((s) => s.name.toLowerCase() === skillName.toLowerCase());
155855
156162
  if (!skill) {
155856
- process.stderr.write(chalk26.red(`Skill "${skillName}" not found. Use \`skillvault-publisher list\` to see your skills.
156163
+ process.stderr.write(chalk27.red(`Skill "${skillName}" not found. Use \`skillvault-publisher list\` to see your skills.
155857
156164
  `));
155858
156165
  process.exit(1);
155859
156166
  }
155860
- console.log(chalk26.dim(` Running investigation on "${skill.name}"...`));
156167
+ console.log(chalk27.dim(` Running investigation on "${skill.name}"...`));
155861
156168
  const report = await sessionFetch(ctx, `/publishers/${ctx.publisherId}/investigate`, {
155862
156169
  method: "POST",
155863
156170
  body: { skill_id: skill.id, leaked_content: leakedContent }
@@ -155883,13 +156190,13 @@ var investigateCommand = new Command29("investigate").description("Investigate a
155883
156190
  source: sourceLabel,
155884
156191
  notice: "This is an executive summary. Full evidence is retained server-side. Contact investigations@getskillvault.com for the complete evidence package."
155885
156192
  };
155886
- writeFileSync10(join14(dir, "metadata.json"), JSON.stringify(metadata, null, 2) + "\n");
155887
- writeFileSync10(join14(dir, "summary.json"), JSON.stringify({
156193
+ writeFileSync11(join14(dir, "metadata.json"), JSON.stringify(metadata, null, 2) + "\n");
156194
+ writeFileSync11(join14(dir, "summary.json"), JSON.stringify({
155888
156195
  _generated_by: "SkillVault (https://getskillvault.com)",
155889
156196
  ...report
155890
156197
  }, null, 2) + "\n");
155891
156198
  const html = buildHtmlReport(report, [], metadata);
155892
- writeFileSync10(join14(dir, "report.html"), html);
156199
+ writeFileSync11(join14(dir, "report.html"), html);
155893
156200
  const pdfPath = join14(dir, "report.pdf");
155894
156201
  const { generatePdfReport: generatePdfReport2 } = await Promise.resolve().then(() => (init_pdf_report(), pdf_report_exports));
155895
156202
  await generatePdfReport2({
@@ -155903,23 +156210,23 @@ var investigateCommand = new Command29("investigate").description("Investigate a
155903
156210
  heartbeat_matches: report.heartbeat_matches,
155904
156211
  audit_events: []
155905
156212
  }, pdfPath);
155906
- console.log(chalk26.green(` Report saved to ${dir}/`) + chalk26.dim(" (4 files)"));
155907
- console.log(chalk26.dim(` PDF: report.pdf`));
155908
- console.log(chalk26.dim(` Full evidence retained server-side (ID: ${report.investigation_id})`));
156213
+ console.log(chalk27.green(` Report saved to ${dir}/`) + chalk27.dim(" (4 files)"));
156214
+ console.log(chalk27.dim(` PDF: report.pdf`));
156215
+ console.log(chalk27.dim(` Full evidence retained server-side (ID: ${report.investigation_id})`));
155909
156216
  console.log();
155910
156217
  }
155911
156218
  } catch (err) {
155912
156219
  const message = err instanceof Error ? err.message : String(err);
155913
- process.stderr.write(chalk26.red(`Error: ${message}
156220
+ process.stderr.write(chalk27.red(`Error: ${message}
155914
156221
  `));
155915
156222
  process.exit(1);
155916
156223
  }
155917
156224
  });
155918
156225
 
155919
156226
  // dist/commands/watchtower.js
155920
- import { Command as Command30 } from "commander";
155921
- import chalk27 from "chalk";
155922
- var watchtowerCommand = new Command30("watchtower").description("Watchtower security dashboard").option("--json", "Output as JSON").option("--workspace <path>", "Resolve workspace context (defaults from CWD)").option("--quiet", 'Suppress the "(using workspace \u2026)" stderr note').action(async (options) => {
156227
+ import { Command as Command31 } from "commander";
156228
+ import chalk28 from "chalk";
156229
+ var watchtowerCommand = new Command31("watchtower").description("Watchtower security dashboard").option("--json", "Output as JSON").option("--workspace <path>", "Resolve workspace context (defaults from CWD)").option("--quiet", 'Suppress the "(using workspace \u2026)" stderr note').action(async (options) => {
155923
156230
  const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155924
156231
  try {
155925
156232
  const data = await sessionFetch(ctx, `/publishers/${ctx.publisherId}/watchtower`);
@@ -155930,30 +156237,30 @@ var watchtowerCommand = new Command30("watchtower").description("Watchtower secu
155930
156237
  const { summary } = data;
155931
156238
  const pad4 = (s, n) => s.padEnd(n).slice(0, n);
155932
156239
  console.log();
155933
- console.log(chalk27.bold(" Watchtower \u2014 Security Overview"));
156240
+ console.log(chalk28.bold(" Watchtower \u2014 Security Overview"));
155934
156241
  console.log();
155935
- console.log(` ${chalk27.bold("Skills")} ${summary.total_skills} ${chalk27.dim("|")} ${chalk27.bold("Licenses")} ${summary.total_licenses} ${chalk27.dim("|")} ${chalk27.bold("Alerts (7d)")} ${summary.active_alerts > 0 ? chalk27.yellow(String(summary.active_alerts)) : "0"} ${chalk27.dim("|")} ${chalk27.bold("Flagged")} ${summary.flagged_customers > 0 ? chalk27.red(String(summary.flagged_customers)) : "0"} ${chalk27.dim("|")} ${chalk27.bold("Suspended")} ${summary.suspended_grants > 0 ? chalk27.red(String(summary.suspended_grants)) : "0"}`);
156242
+ console.log(` ${chalk28.bold("Skills")} ${summary.total_skills} ${chalk28.dim("|")} ${chalk28.bold("Licenses")} ${summary.total_licenses} ${chalk28.dim("|")} ${chalk28.bold("Alerts (7d)")} ${summary.active_alerts > 0 ? chalk28.yellow(String(summary.active_alerts)) : "0"} ${chalk28.dim("|")} ${chalk28.bold("Flagged")} ${summary.flagged_customers > 0 ? chalk28.red(String(summary.flagged_customers)) : "0"} ${chalk28.dim("|")} ${chalk28.bold("Suspended")} ${summary.suspended_grants > 0 ? chalk28.red(String(summary.suspended_grants)) : "0"}`);
155936
156243
  if (data.flagged_customers && data.flagged_customers.length > 0) {
155937
156244
  console.log();
155938
- console.log(chalk27.bold(" Flagged Customers"));
156245
+ console.log(chalk28.bold(" Flagged Customers"));
155939
156246
  console.log();
155940
156247
  const header = `${pad4("Agent ID", 20)} ${pad4("Risk Score", 12)} ${pad4("Level", 10)} ${pad4("Strikes", 9)} ${pad4("Status", 12)} Skills`;
155941
- console.log(` ${chalk27.dim(header)}`);
155942
- console.log(` ${chalk27.dim("\u2500".repeat(header.length))}`);
156248
+ console.log(` ${chalk28.dim(header)}`);
156249
+ console.log(` ${chalk28.dim("\u2500".repeat(header.length))}`);
155943
156250
  for (const c of data.flagged_customers) {
155944
156251
  const agentShort = c.agent_id.length > 18 ? c.agent_id.slice(0, 18) + "\u2026" : c.agent_id;
155945
156252
  let levelColored;
155946
156253
  if (c.risk_level === "critical") {
155947
- levelColored = chalk27.red.bold(pad4(c.risk_level, 10));
156254
+ levelColored = chalk28.red.bold(pad4(c.risk_level, 10));
155948
156255
  } else if (c.risk_level === "high") {
155949
- levelColored = chalk27.red(pad4(c.risk_level, 10));
156256
+ levelColored = chalk28.red(pad4(c.risk_level, 10));
155950
156257
  } else if (c.risk_level === "medium") {
155951
- levelColored = chalk27.yellow(pad4(c.risk_level, 10));
156258
+ levelColored = chalk28.yellow(pad4(c.risk_level, 10));
155952
156259
  } else {
155953
- levelColored = chalk27.dim(pad4(c.risk_level, 10));
156260
+ levelColored = chalk28.dim(pad4(c.risk_level, 10));
155954
156261
  }
155955
- const statusColored = c.status === "suspended" ? chalk27.red(pad4(c.status, 12)) : pad4(c.status, 12);
155956
- const skills = c.capabilities.length > 0 ? c.capabilities.join(", ") : chalk27.dim("none");
156262
+ const statusColored = c.status === "suspended" ? chalk28.red(pad4(c.status, 12)) : pad4(c.status, 12);
156263
+ const skills = c.capabilities.length > 0 ? c.capabilities.join(", ") : chalk28.dim("none");
155957
156264
  const row = [
155958
156265
  pad4(agentShort, 20),
155959
156266
  pad4(String(c.risk_score), 12),
@@ -155967,15 +156274,15 @@ var watchtowerCommand = new Command30("watchtower").description("Watchtower secu
155967
156274
  }
155968
156275
  if (data.recent_events && data.recent_events.length > 0) {
155969
156276
  console.log();
155970
- console.log(chalk27.bold(" Recent Security Events"));
156277
+ console.log(chalk28.bold(" Recent Security Events"));
155971
156278
  console.log();
155972
156279
  const header = `${pad4("Event Type", 28)} ${pad4("Skill", 24)} ${pad4("Agent", 20)} Time`;
155973
- console.log(` ${chalk27.dim(header)}`);
155974
- console.log(` ${chalk27.dim("\u2500".repeat(header.length))}`);
156280
+ console.log(` ${chalk28.dim(header)}`);
156281
+ console.log(` ${chalk28.dim("\u2500".repeat(header.length))}`);
155975
156282
  const events = data.recent_events.slice(0, 10);
155976
156283
  for (const e of events) {
155977
- const skill = e.capability ? e.capability.replace(/^skill\//, "") : chalk27.dim("-");
155978
- const agent = e.agent_id ? e.agent_id.slice(0, 18) : chalk27.dim("-");
156284
+ const skill = e.capability ? e.capability.replace(/^skill\//, "") : chalk28.dim("-");
156285
+ const agent = e.agent_id ? e.agent_id.slice(0, 18) : chalk28.dim("-");
155979
156286
  const time = new Date(e.created_at).toLocaleString();
155980
156287
  const row = [
155981
156288
  pad4(e.event_type, 28),
@@ -155988,25 +156295,25 @@ var watchtowerCommand = new Command30("watchtower").description("Watchtower secu
155988
156295
  }
155989
156296
  if ((!data.flagged_customers || data.flagged_customers.length === 0) && (!data.recent_events || data.recent_events.length === 0)) {
155990
156297
  console.log();
155991
- console.log(chalk27.green(" All clear \u2014 no security alerts in the last 7 days."));
156298
+ console.log(chalk28.green(" All clear \u2014 no security alerts in the last 7 days."));
155992
156299
  }
155993
156300
  console.log();
155994
156301
  } catch (err) {
155995
156302
  const message = err instanceof Error ? err.message : String(err);
155996
- process.stderr.write(chalk27.red(`Error: ${message}
156303
+ process.stderr.write(chalk28.red(`Error: ${message}
155997
156304
  `));
155998
156305
  process.exit(1);
155999
156306
  }
156000
156307
  });
156001
156308
 
156002
156309
  // dist/commands/watermark-decode.js
156003
- import { Command as Command31 } from "commander";
156004
- import chalk28 from "chalk";
156310
+ import { Command as Command32 } from "commander";
156311
+ import chalk29 from "chalk";
156005
156312
  import { readFileSync as readFileSync16 } from "node:fs";
156006
- var watermarkDecodeCommand = new Command31("watermark-decode").description("Analyze leaked content for forensic watermarks (local-only)").option("--file <path>", "Path to file with leaked content").option("--json", "Output as JSON").action(async (options) => {
156313
+ var watermarkDecodeCommand = new Command32("watermark-decode").description("Analyze leaked content for forensic watermarks (local-only)").option("--file <path>", "Path to file with leaked content").option("--json", "Output as JSON").action(async (options) => {
156007
156314
  try {
156008
156315
  if (!options.file) {
156009
- process.stderr.write(chalk28.red("Provide --file <path> with the leaked content\n"));
156316
+ process.stderr.write(chalk29.red("Provide --file <path> with the leaked content\n"));
156010
156317
  process.exit(1);
156011
156318
  }
156012
156319
  let content;
@@ -156014,7 +156321,7 @@ var watermarkDecodeCommand = new Command31("watermark-decode").description("Anal
156014
156321
  content = readFileSync16(options.file, "utf8");
156015
156322
  } catch (err) {
156016
156323
  const msg = err instanceof Error ? err.message : String(err);
156017
- process.stderr.write(chalk28.red(`Cannot read file: ${msg}
156324
+ process.stderr.write(chalk29.red(`Cannot read file: ${msg}
156018
156325
  `));
156019
156326
  process.exit(1);
156020
156327
  }
@@ -156044,56 +156351,56 @@ var watermarkDecodeCommand = new Command31("watermark-decode").description("Anal
156044
156351
  return;
156045
156352
  }
156046
156353
  console.log();
156047
- console.log(chalk28.bold(" Watermark Analysis"));
156354
+ console.log(chalk29.bold(" Watermark Analysis"));
156048
156355
  console.log();
156049
- console.log(chalk28.bold(" Zero-Width Watermark"));
156356
+ console.log(chalk29.bold(" Zero-Width Watermark"));
156050
156357
  if (watermark.found) {
156051
- console.log(` Licensee ID: ${chalk28.green.bold(watermark.licenseeId)}`);
156358
+ console.log(` Licensee ID: ${chalk29.green.bold(watermark.licenseeId)}`);
156052
156359
  } else {
156053
- console.log(` ${chalk28.dim("Not found")}`);
156360
+ console.log(` ${chalk29.dim("Not found")}`);
156054
156361
  }
156055
156362
  console.log();
156056
- console.log(chalk28.bold(" Heartbeat Markers"));
156363
+ console.log(chalk29.bold(" Heartbeat Markers"));
156057
156364
  if (heartbeats.hb1) {
156058
- console.log(` HB1: ${chalk28.green(heartbeats.hb1)}`);
156365
+ console.log(` HB1: ${chalk29.green(heartbeats.hb1)}`);
156059
156366
  } else {
156060
- console.log(` HB1: ${chalk28.dim("Not found")}`);
156367
+ console.log(` HB1: ${chalk29.dim("Not found")}`);
156061
156368
  }
156062
156369
  if (heartbeats.hb2) {
156063
- console.log(` HB2: ${chalk28.green(heartbeats.hb2)}`);
156370
+ console.log(` HB2: ${chalk29.green(heartbeats.hb2)}`);
156064
156371
  } else {
156065
- console.log(` HB2: ${chalk28.dim("Not found")}`);
156372
+ console.log(` HB2: ${chalk29.dim("Not found")}`);
156066
156373
  }
156067
156374
  if (candidates.length > 0) {
156068
- console.log(` ${chalk28.dim(`${candidates.length} potential heartbeat candidate${candidates.length !== 1 ? "s" : ""} found`)}`);
156375
+ console.log(` ${chalk29.dim(`${candidates.length} potential heartbeat candidate${candidates.length !== 1 ? "s" : ""} found`)}`);
156069
156376
  }
156070
156377
  console.log();
156071
- console.log(chalk28.bold(" Semantic Fingerprint"));
156378
+ console.log(chalk29.bold(" Semantic Fingerprint"));
156072
156379
  if (hasFingerprint) {
156073
156380
  const binaryStr = fingerprint.map((v) => v === 1 ? "1" : v === -1 ? "X" : "0").join("");
156074
156381
  const variationPoints = fingerprint.filter((v) => v !== 0).length;
156075
- console.log(` Pattern: ${chalk28.cyan(binaryStr)}`);
156076
- console.log(` ${chalk28.dim(`${variationPoints} variation point${variationPoints !== 1 ? "s" : ""} detected`)}`);
156382
+ console.log(` Pattern: ${chalk29.cyan(binaryStr)}`);
156383
+ console.log(` ${chalk29.dim(`${variationPoints} variation point${variationPoints !== 1 ? "s" : ""} detected`)}`);
156077
156384
  } else {
156078
- console.log(` ${chalk28.dim("No variation points detected")}`);
156385
+ console.log(` ${chalk29.dim("No variation points detected")}`);
156079
156386
  }
156080
156387
  console.log();
156081
- const countColor = signalsDetected > 0 ? chalk28.green.bold : chalk28.dim;
156388
+ const countColor = signalsDetected > 0 ? chalk29.green.bold : chalk29.dim;
156082
156389
  console.log(` ${countColor(`${signalsDetected} of 4`)} forensic signals detected`);
156083
156390
  console.log();
156084
156391
  } catch (err) {
156085
156392
  const message = err instanceof Error ? err.message : String(err);
156086
- process.stderr.write(chalk28.red(`Error: ${message}
156393
+ process.stderr.write(chalk29.red(`Error: ${message}
156087
156394
  `));
156088
156395
  process.exit(1);
156089
156396
  }
156090
156397
  });
156091
156398
 
156092
156399
  // dist/commands/link.js
156093
- import { Command as Command32 } from "commander";
156094
- import chalk29 from "chalk";
156400
+ import { Command as Command33 } from "commander";
156401
+ import chalk30 from "chalk";
156095
156402
  import { existsSync as existsSync14, readFileSync as readFileSync17, statSync as statSync6 } from "node:fs";
156096
- import { resolve as resolve9, join as join15 } from "node:path";
156403
+ import { resolve as resolve10, join as join15 } from "node:path";
156097
156404
  function parseFrontmatter4(content) {
156098
156405
  const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
156099
156406
  if (!match)
@@ -156112,12 +156419,12 @@ function parseFrontmatter4(content) {
156112
156419
  }
156113
156420
  return result;
156114
156421
  }
156115
- var linkCommand = new Command32("link").description("Link a skill source directory to your publisher account").argument("[directory]", "Skill directory to link (defaults to CWD)").option("--workspace <path>", "Explicit workspace directory (precedence over positional)").option("--force", "Overwrite an existing link to a different publisher_id").option("--name <name>", "Override skill name (defaults to SKILL.md frontmatter name)").option("--capability <cap>", "Override capability_name (advanced \u2014 usually matches skill name)").action(async (directory, options) => {
156422
+ var linkCommand = new Command33("link").description("Link a skill source directory to your publisher account").argument("[directory]", "Skill directory to link (defaults to CWD)").option("--workspace <path>", "Explicit workspace directory (precedence over positional)").option("--force", "Overwrite an existing link to a different publisher_id").option("--name <name>", "Override skill name (defaults to SKILL.md frontmatter name)").option("--capability <cap>", "Override capability_name (advanced \u2014 usually matches skill name)").action(async (directory, options) => {
156116
156423
  try {
156117
156424
  const ctx = requireSession();
156118
- const dirPath = options.workspace ? resolve9(options.workspace) : directory ? resolve9(directory) : process.cwd();
156425
+ const dirPath = options.workspace ? resolve10(options.workspace) : directory ? resolve10(directory) : process.cwd();
156119
156426
  if (!existsSync14(dirPath) || !statSync6(dirPath).isDirectory()) {
156120
- process.stderr.write(chalk29.red(`Error: "${dirPath}" is not a valid directory
156427
+ process.stderr.write(chalk30.red(`Error: "${dirPath}" is not a valid directory
156121
156428
  `));
156122
156429
  process.exit(1);
156123
156430
  }
@@ -156127,17 +156434,17 @@ var linkCommand = new Command32("link").description("Link a skill source directo
156127
156434
  const existing = loadWorkspace(dirPath);
156128
156435
  const skillName = options.name || existing?.skill_name || frontmatter.name;
156129
156436
  if (!skillName) {
156130
- process.stderr.write(chalk29.red("Error: Cannot determine skill name.\n"));
156131
- process.stderr.write(chalk29.dim(" Pass --name <name> or set `name:` in SKILL.md frontmatter.\n"));
156437
+ process.stderr.write(chalk30.red("Error: Cannot determine skill name.\n"));
156438
+ process.stderr.write(chalk30.dim(" Pass --name <name> or set `name:` in SKILL.md frontmatter.\n"));
156132
156439
  process.exit(1);
156133
156440
  }
156134
156441
  const capabilityName = options.capability || existing?.capability_name || `skill/${skillName.toLowerCase()}`;
156135
156442
  if (existing && existing.publisher_id !== ctx.publisherId && !options.force) {
156136
- process.stderr.write(chalk29.red(`Error: This directory is already linked to publisher ${existing.publisher_id}.
156443
+ process.stderr.write(chalk30.red(`Error: This directory is already linked to publisher ${existing.publisher_id}.
156137
156444
  `));
156138
- process.stderr.write(chalk29.dim(` You are logged in as ${ctx.publisherId}.
156445
+ process.stderr.write(chalk30.dim(` You are logged in as ${ctx.publisherId}.
156139
156446
  `));
156140
- process.stderr.write(chalk29.cyan(" Use --force to re-link to your account.\n"));
156447
+ process.stderr.write(chalk30.cyan(" Use --force to re-link to your account.\n"));
156141
156448
  process.exit(1);
156142
156449
  }
156143
156450
  const linkedAt = existing?.linked_at ?? (/* @__PURE__ */ new Date()).toISOString();
@@ -156159,41 +156466,41 @@ var linkCommand = new Command32("link").description("Link a skill source directo
156159
156466
  last_published_at: manifest.last_published_at
156160
156467
  });
156161
156468
  const action = existing ? "Re-linked" : "Linked";
156162
- console.log(chalk29.green(`${action} "${skillName}" \u2192 ${capabilityName}`));
156163
- console.log(chalk29.dim(` Directory: ${dirPath}`));
156164
- console.log(chalk29.dim(` Publisher: ${ctx.publisherId}`));
156165
- console.log(chalk29.dim(` Manifest: .skillvault-publisher/workspace.json`));
156469
+ console.log(chalk30.green(`${action} "${skillName}" \u2192 ${capabilityName}`));
156470
+ console.log(chalk30.dim(` Directory: ${dirPath}`));
156471
+ console.log(chalk30.dim(` Publisher: ${ctx.publisherId}`));
156472
+ console.log(chalk30.dim(` Manifest: .skillvault-publisher/workspace.json`));
156166
156473
  if (!existing) {
156167
156474
  console.log();
156168
- console.log(chalk29.cyan(" Tip: commit .skillvault-publisher/workspace.json so teammates and CI can find this skill."));
156475
+ console.log(chalk30.cyan(" Tip: commit .skillvault-publisher/workspace.json so teammates and CI can find this skill."));
156169
156476
  }
156170
156477
  } catch (err) {
156171
156478
  const message = err instanceof Error ? err.message : String(err);
156172
- process.stderr.write(chalk29.red(`Link failed: ${message}
156479
+ process.stderr.write(chalk30.red(`Link failed: ${message}
156173
156480
  `));
156174
156481
  process.exit(1);
156175
156482
  }
156176
156483
  });
156177
156484
 
156178
156485
  // dist/commands/unlink.js
156179
- import { Command as Command33 } from "commander";
156180
- import chalk30 from "chalk";
156486
+ import { Command as Command34 } from "commander";
156487
+ import chalk31 from "chalk";
156181
156488
  import { existsSync as existsSync15, rmSync as rmSync2, statSync as statSync7 } from "node:fs";
156182
- import { resolve as resolve10, join as join16 } from "node:path";
156183
- var unlinkCommand = new Command33("unlink").description("Remove the workspace link from a skill source directory").argument("[directory]", "Skill directory to unlink (defaults to CWD)").option("--workspace <path>", "Explicit workspace directory (precedence over positional)").option("--keep-registry", "Remove the manifest file but leave the registry entry").action(async (directory, options) => {
156489
+ import { resolve as resolve11, join as join16 } from "node:path";
156490
+ var unlinkCommand = new Command34("unlink").description("Remove the workspace link from a skill source directory").argument("[directory]", "Skill directory to unlink (defaults to CWD)").option("--workspace <path>", "Explicit workspace directory (precedence over positional)").option("--keep-registry", "Remove the manifest file but leave the registry entry").action(async (directory, options) => {
156184
156491
  try {
156185
- const dirPath = options.workspace ? resolve10(options.workspace) : directory ? resolve10(directory) : process.cwd();
156492
+ const dirPath = options.workspace ? resolve11(options.workspace) : directory ? resolve11(directory) : process.cwd();
156186
156493
  if (!existsSync15(dirPath) || !statSync7(dirPath).isDirectory()) {
156187
- process.stderr.write(chalk30.red(`Error: "${dirPath}" is not a valid directory
156494
+ process.stderr.write(chalk31.red(`Error: "${dirPath}" is not a valid directory
156188
156495
  `));
156189
156496
  process.exit(1);
156190
156497
  }
156191
156498
  const manifest = loadWorkspace(dirPath);
156192
156499
  if (!manifest) {
156193
- process.stderr.write(chalk30.red("Error: No workspace manifest found at this directory.\n"));
156194
- process.stderr.write(chalk30.dim(` Looked for: ${join16(dirPath, ".skillvault-publisher", "workspace.json")}
156500
+ process.stderr.write(chalk31.red("Error: No workspace manifest found at this directory.\n"));
156501
+ process.stderr.write(chalk31.dim(` Looked for: ${join16(dirPath, ".skillvault-publisher", "workspace.json")}
156195
156502
  `));
156196
- process.stderr.write(chalk30.dim(" Run `skillvault-publisher link` first to create one.\n"));
156503
+ process.stderr.write(chalk31.dim(" Run `skillvault-publisher link` first to create one.\n"));
156197
156504
  process.exit(1);
156198
156505
  }
156199
156506
  const { manifestPath } = workspaceRootsFor(dirPath);
@@ -156201,7 +156508,7 @@ var unlinkCommand = new Command33("unlink").description("Remove the workspace li
156201
156508
  rmSync2(manifestPath);
156202
156509
  } catch (err) {
156203
156510
  const message = err instanceof Error ? err.message : String(err);
156204
- process.stderr.write(chalk30.red(`Failed to remove manifest: ${message}
156511
+ process.stderr.write(chalk31.red(`Failed to remove manifest: ${message}
156205
156512
  `));
156206
156513
  process.exit(1);
156207
156514
  }
@@ -156213,25 +156520,25 @@ var unlinkCommand = new Command33("unlink").description("Remove the workspace li
156213
156520
  if (!options.keepRegistry) {
156214
156521
  unregisterWorkspace(dirPath);
156215
156522
  }
156216
- console.log(chalk30.green(`Unlinked "${manifest.skill_name}" (${manifest.capability_name})`));
156217
- console.log(chalk30.dim(` Directory: ${dirPath}`));
156523
+ console.log(chalk31.green(`Unlinked "${manifest.skill_name}" (${manifest.capability_name})`));
156524
+ console.log(chalk31.dim(` Directory: ${dirPath}`));
156218
156525
  if (options.keepRegistry) {
156219
- console.log(chalk30.dim(" Registry entry kept (--keep-registry)"));
156526
+ console.log(chalk31.dim(" Registry entry kept (--keep-registry)"));
156220
156527
  }
156221
156528
  console.log();
156222
- console.log(chalk30.dim(" Note: SKILL.md and source files are untouched."));
156223
- console.log(chalk30.dim(" Note: The skill on the server is NOT deleted. Use `skill-delete` for that."));
156529
+ console.log(chalk31.dim(" Note: SKILL.md and source files are untouched."));
156530
+ console.log(chalk31.dim(" Note: The skill on the server is NOT deleted. Use `skill-delete` for that."));
156224
156531
  } catch (err) {
156225
156532
  const message = err instanceof Error ? err.message : String(err);
156226
- process.stderr.write(chalk30.red(`Unlink failed: ${message}
156533
+ process.stderr.write(chalk31.red(`Unlink failed: ${message}
156227
156534
  `));
156228
156535
  process.exit(1);
156229
156536
  }
156230
156537
  });
156231
156538
 
156232
156539
  // dist/commands/workspaces.js
156233
- import { Command as Command34 } from "commander";
156234
- import chalk31 from "chalk";
156540
+ import { Command as Command35 } from "commander";
156541
+ import chalk32 from "chalk";
156235
156542
  function formatDate(iso) {
156236
156543
  if (!iso)
156237
156544
  return "-";
@@ -156266,8 +156573,8 @@ function listAction(options) {
156266
156573
  return;
156267
156574
  }
156268
156575
  if (filtered.length === 0) {
156269
- console.log(chalk31.dim("No workspaces linked."));
156270
- console.log(chalk31.dim(" Run `skillvault-publisher link` from a skill source directory to create one."));
156576
+ console.log(chalk32.dim("No workspaces linked."));
156577
+ console.log(chalk32.dim(" Run `skillvault-publisher link` from a skill source directory to create one."));
156271
156578
  return;
156272
156579
  }
156273
156580
  const pathWidth = Math.min(Math.max(20, ...filtered.map((w) => w.path.length)), 50);
@@ -156275,27 +156582,27 @@ function listAction(options) {
156275
156582
  const pubWidth = Math.max(10, ...filtered.map((w) => w.publisher_id.length));
156276
156583
  console.log();
156277
156584
  const header = `${pad2("PATH", pathWidth)} ${pad2("PUBLISHER", pubWidth)} ${pad2("SKILL", skillWidth)} ${pad2("VERSION", 10)} ${pad2("LAST PUBLISHED", 14)} SOURCE`;
156278
- console.log(` ${chalk31.dim(header)}`);
156279
- console.log(` ${chalk31.dim("\u2500".repeat(header.length))}`);
156585
+ console.log(` ${chalk32.dim(header)}`);
156586
+ console.log(` ${chalk32.dim("\u2500".repeat(header.length))}`);
156280
156587
  for (const w of filtered) {
156281
156588
  const isOther = currentAccount !== null && w.publisher_id !== currentAccount;
156282
156589
  const path = w.path.length > pathWidth ? "\u2026" + w.path.slice(-(pathWidth - 1)) : w.path;
156283
156590
  const row = `${pad2(path, pathWidth)} ${pad2(w.publisher_id, pubWidth)} ${pad2(w.skill_name, skillWidth)} ${pad2(w.last_published_version ?? "-", 10)} ${pad2(formatDate(w.last_published_at), 14)} ${w.source}`;
156284
156591
  if (isOther) {
156285
- console.log(` ${chalk31.dim(row + " [other account]")}`);
156592
+ console.log(` ${chalk32.dim(row + " [other account]")}`);
156286
156593
  } else {
156287
156594
  console.log(` ${row}`);
156288
156595
  }
156289
156596
  }
156290
156597
  console.log();
156291
- console.log(chalk31.dim(` ${filtered.length} workspace${filtered.length === 1 ? "" : "s"}` + (options.current ? " (filtered to current account)" : "")));
156598
+ console.log(chalk32.dim(` ${filtered.length} workspace${filtered.length === 1 ? "" : "s"}` + (options.current ? " (filtered to current account)" : "")));
156292
156599
  }
156293
- var workspacesCommand = new Command34("workspaces").description("List linked skill source directories (workspaces)").option("--json", "Output as JSON").option("--current", "Only show workspaces matching the current logged-in publisher").action((options) => {
156600
+ var workspacesCommand = new Command35("workspaces").description("List linked skill source directories (workspaces)").option("--json", "Output as JSON").option("--current", "Only show workspaces matching the current logged-in publisher").action((options) => {
156294
156601
  try {
156295
156602
  listAction(options);
156296
156603
  } catch (err) {
156297
156604
  const message = err instanceof Error ? err.message : String(err);
156298
- process.stderr.write(chalk31.red(`Error: ${message}
156605
+ process.stderr.write(chalk32.red(`Error: ${message}
156299
156606
  `));
156300
156607
  process.exit(1);
156301
156608
  }
@@ -156311,28 +156618,28 @@ workspacesCommand.command("find").description("Print the absolute path of a work
156311
156618
  console.log(match.path);
156312
156619
  } catch (err) {
156313
156620
  const message = err instanceof Error ? err.message : String(err);
156314
- process.stderr.write(chalk31.red(`Error: ${message}
156621
+ process.stderr.write(chalk32.red(`Error: ${message}
156315
156622
  `));
156316
156623
  process.exit(1);
156317
156624
  }
156318
156625
  });
156319
156626
 
156320
156627
  // dist/commands/team.js
156321
- import { Command as Command35 } from "commander";
156322
- import chalk32 from "chalk";
156628
+ import { Command as Command36 } from "commander";
156629
+ import chalk33 from "chalk";
156323
156630
  function formatRole(role) {
156324
156631
  if (role === "owner")
156325
- return chalk32.green("owner");
156632
+ return chalk33.green("owner");
156326
156633
  if (role === "admin")
156327
- return chalk32.cyan("admin");
156328
- return chalk32.dim("member");
156634
+ return chalk33.cyan("admin");
156635
+ return chalk33.dim("member");
156329
156636
  }
156330
156637
  function formatStatus(status) {
156331
156638
  if (status === "active")
156332
- return chalk32.green("active");
156639
+ return chalk33.green("active");
156333
156640
  if (status === "pending")
156334
- return chalk32.yellow("pending");
156335
- return chalk32.dim(status);
156641
+ return chalk33.yellow("pending");
156642
+ return chalk33.dim(status);
156336
156643
  }
156337
156644
  function pad3(s, n) {
156338
156645
  const visible = s.replace(/\x1b\[[0-9;]*m/g, "");
@@ -156340,7 +156647,7 @@ function pad3(s, n) {
156340
156647
  return s;
156341
156648
  return s + " ".repeat(n - visible.length);
156342
156649
  }
156343
- var teamCommand = new Command35("team").description("Manage your publisher team members").option("--json", "Output as JSON").action(async (options) => {
156650
+ var teamCommand = new Command36("team").description("Manage your publisher team members").option("--json", "Output as JSON").action(async (options) => {
156344
156651
  try {
156345
156652
  const ctx = requireSession();
156346
156653
  const data = await sessionFetch(ctx, `/publishers/${ctx.publisherId}/team`);
@@ -156351,27 +156658,27 @@ var teamCommand = new Command35("team").description("Manage your publisher team
156351
156658
  }
156352
156659
  if (members.length === 0) {
156353
156660
  console.log();
156354
- console.log(chalk32.dim(" No team members yet. Invite someone:"));
156355
- console.log(chalk32.cyan(" skillvault-publisher team add <email> [--role member|admin]"));
156661
+ console.log(chalk33.dim(" No team members yet. Invite someone:"));
156662
+ console.log(chalk33.cyan(" skillvault-publisher team add <email> [--role member|admin]"));
156356
156663
  console.log();
156357
156664
  return;
156358
156665
  }
156359
156666
  console.log();
156360
- console.log(chalk32.bold(` Team members (${members.length})`));
156667
+ console.log(chalk33.bold(` Team members (${members.length})`));
156361
156668
  console.log();
156362
- const header = `${pad3(chalk32.dim("Email"), 36)} ${pad3(chalk32.dim("Role"), 14)} ${pad3(chalk32.dim("Status"), 14)} ${chalk32.dim("Member ID")}`;
156669
+ const header = `${pad3(chalk33.dim("Email"), 36)} ${pad3(chalk33.dim("Role"), 14)} ${pad3(chalk33.dim("Status"), 14)} ${chalk33.dim("Member ID")}`;
156363
156670
  console.log(` ${header}`);
156364
- console.log(` ${chalk32.dim("\u2500".repeat(80))}`);
156671
+ console.log(` ${chalk33.dim("\u2500".repeat(80))}`);
156365
156672
  for (const m of members) {
156366
- const row = `${pad3(m.email, 36)} ${pad3(formatRole(m.role), 14)} ${pad3(formatStatus(m.status), 14)} ${chalk32.dim(m.id)}`;
156673
+ const row = `${pad3(m.email, 36)} ${pad3(formatRole(m.role), 14)} ${pad3(formatStatus(m.status), 14)} ${chalk33.dim(m.id)}`;
156367
156674
  console.log(` ${row}`);
156368
156675
  }
156369
156676
  console.log();
156370
- console.log(chalk32.dim(` Logged in as publisher ${ctx.publisherId}`));
156677
+ console.log(chalk33.dim(` Logged in as publisher ${ctx.publisherId}`));
156371
156678
  console.log();
156372
156679
  } catch (err) {
156373
156680
  const message = err instanceof Error ? err.message : String(err);
156374
- process.stderr.write(chalk32.red(`team list failed: ${message}
156681
+ process.stderr.write(chalk33.red(`team list failed: ${message}
156375
156682
  `));
156376
156683
  process.exit(1);
156377
156684
  }
@@ -156379,7 +156686,7 @@ var teamCommand = new Command35("team").description("Manage your publisher team
156379
156686
  teamCommand.command("add").description("Invite someone to your publisher team. Sends a magic-link email.").argument("<email>", "The email address to invite").option("--role <role>", "Role: member (default) or admin", "member").option("--name <name>", "Display name for the invitee (optional)").option("--json", "Output as JSON").action(async (email, options) => {
156380
156687
  try {
156381
156688
  if (!["member", "admin"].includes(options.role)) {
156382
- process.stderr.write(chalk32.red(`Invalid role "${options.role}". Use --role member or --role admin.
156689
+ process.stderr.write(chalk33.red(`Invalid role "${options.role}". Use --role member or --role admin.
156383
156690
  `));
156384
156691
  process.exit(1);
156385
156692
  }
@@ -156393,17 +156700,17 @@ teamCommand.command("add").description("Invite someone to your publisher team. S
156393
156700
  return;
156394
156701
  }
156395
156702
  console.log();
156396
- console.log(chalk32.green(` \u2713 Invited ${email} as ${formatRole(options.role)}`));
156397
- console.log(chalk32.dim(` Member ID: ${member.id}`));
156398
- console.log(chalk32.dim(` Status: ${formatStatus(member.status)}`));
156703
+ console.log(chalk33.green(` \u2713 Invited ${email} as ${formatRole(options.role)}`));
156704
+ console.log(chalk33.dim(` Member ID: ${member.id}`));
156705
+ console.log(chalk33.dim(` Status: ${formatStatus(member.status)}`));
156399
156706
  console.log();
156400
- console.log(chalk32.dim(" A magic-link invitation email has been sent. The new member can"));
156401
- console.log(chalk32.dim(" click the link to activate, then run:"));
156402
- console.log(chalk32.cyan(` skillvault-publisher login --email ${email}`));
156707
+ console.log(chalk33.dim(" A magic-link invitation email has been sent. The new member can"));
156708
+ console.log(chalk33.dim(" click the link to activate, then run:"));
156709
+ console.log(chalk33.cyan(` skillvault-publisher login --email ${email}`));
156403
156710
  console.log();
156404
156711
  } catch (err) {
156405
156712
  const message = err instanceof Error ? err.message : String(err);
156406
- process.stderr.write(chalk32.red(`team add failed: ${message}
156713
+ process.stderr.write(chalk33.red(`team add failed: ${message}
156407
156714
  `));
156408
156715
  process.exit(1);
156409
156716
  }
@@ -156415,30 +156722,30 @@ teamCommand.command("remove").description("Remove a team member by email or memb
156415
156722
  const members = listData.members || [];
156416
156723
  const member = members.find((m) => m.id === target || m.email === target);
156417
156724
  if (!member) {
156418
- process.stderr.write(chalk32.red(`No team member found matching "${target}".
156725
+ process.stderr.write(chalk33.red(`No team member found matching "${target}".
156419
156726
  `));
156420
- process.stderr.write(chalk32.dim("Run `skillvault-publisher team` to see the current list.\n"));
156727
+ process.stderr.write(chalk33.dim("Run `skillvault-publisher team` to see the current list.\n"));
156421
156728
  process.exit(1);
156422
156729
  }
156423
156730
  if (member.role === "owner") {
156424
- process.stderr.write(chalk32.red("Cannot remove the owner of a publisher account.\n"));
156731
+ process.stderr.write(chalk33.red("Cannot remove the owner of a publisher account.\n"));
156425
156732
  process.exit(1);
156426
156733
  }
156427
156734
  if (member.status === "removed") {
156428
- process.stderr.write(chalk32.yellow(`${member.email} is already removed.
156735
+ process.stderr.write(chalk33.yellow(`${member.email} is already removed.
156429
156736
  `));
156430
156737
  process.exit(0);
156431
156738
  }
156432
156739
  if (!options.yes) {
156433
156740
  console.log();
156434
- console.log(chalk32.yellow.bold(" Warning: ") + "This will revoke " + chalk32.bold(member.email) + `'s access to publisher ${ctx.publisherId}.`);
156741
+ console.log(chalk33.yellow.bold(" Warning: ") + "This will revoke " + chalk33.bold(member.email) + `'s access to publisher ${ctx.publisherId}.`);
156435
156742
  console.log();
156436
- console.log(` Email: ${chalk32.cyan(member.email)}`);
156743
+ console.log(` Email: ${chalk33.cyan(member.email)}`);
156437
156744
  console.log(` Role: ${formatRole(member.role)}`);
156438
156745
  console.log(` Status: ${formatStatus(member.status)}`);
156439
- console.log(` Added: ${chalk32.dim(new Date(member.created_at).toLocaleDateString())}`);
156746
+ console.log(` Added: ${chalk33.dim(new Date(member.created_at).toLocaleDateString())}`);
156440
156747
  console.log();
156441
- console.log(chalk32.dim(" Add --yes to confirm."));
156748
+ console.log(chalk33.dim(" Add --yes to confirm."));
156442
156749
  console.log();
156443
156750
  process.exit(0);
156444
156751
  }
@@ -156447,10 +156754,10 @@ teamCommand.command("remove").description("Remove a team member by email or memb
156447
156754
  console.log(JSON.stringify({ removed: true, member_id: member.id, email: member.email }, null, 2));
156448
156755
  return;
156449
156756
  }
156450
- console.log(chalk32.green(` \u2713 Removed ${member.email} from the team`));
156757
+ console.log(chalk33.green(` \u2713 Removed ${member.email} from the team`));
156451
156758
  } catch (err) {
156452
156759
  const message = err instanceof Error ? err.message : String(err);
156453
- process.stderr.write(chalk32.red(`team remove failed: ${message}
156760
+ process.stderr.write(chalk33.red(`team remove failed: ${message}
156454
156761
  `));
156455
156762
  process.exit(1);
156456
156763
  }
@@ -156459,7 +156766,7 @@ teamCommand.command("remove").description("Remove a team member by email or memb
156459
156766
  // dist/index.js
156460
156767
  var __dirname2 = dirname5(fileURLToPath(import.meta.url));
156461
156768
  var pkg = JSON.parse(readFileSync18(join17(__dirname2, "..", "package.json"), "utf8"));
156462
- var program = new Command36();
156769
+ var program = new Command37();
156463
156770
  program.name("skillvault-publisher").description("SkillVault publisher CLI \u2014 publish, manage, and distribute encrypted skills").version(pkg.version).addHelpText("after", `
156464
156771
 
156465
156772
  Getting Started:
@@ -156492,6 +156799,7 @@ program.addCommand(sessionCleanupCommand);
156492
156799
  program.addCommand(skillDeleteCommand);
156493
156800
  program.addCommand(skillStatusCommand);
156494
156801
  program.addCommand(skillUnarchiveCommand);
156802
+ program.addCommand(skillAclCommand);
156495
156803
  program.addCommand(grantsCommand);
156496
156804
  program.addCommand(revokeGrantCommand);
156497
156805
  program.addCommand(customersCommand);