skillvault-publisher 0.12.0 → 0.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +588 -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";
@@ -151926,6 +151926,41 @@ var loginCommand = new Command("login").description("Authenticate with the Skill
151926
151926
  headers: { "Content-Type": "application/json" },
151927
151927
  body: JSON.stringify(body2)
151928
151928
  });
151929
+ if (loginRes.status === 403) {
151930
+ const err = await loginRes.json().catch(() => null);
151931
+ if (err?.error === "production_login_disabled") {
151932
+ console.log(chalk.dim("Production server: pivoting to magic-link verification..."));
151933
+ const mlRes = await fetch(`${serverUrl}/auth/magic-link`, {
151934
+ method: "POST",
151935
+ headers: { "Content-Type": "application/json" },
151936
+ body: JSON.stringify({ email: options.email })
151937
+ });
151938
+ if (mlRes.ok) {
151939
+ const mlData = await mlRes.json().catch(() => ({}));
151940
+ if (mlData.status === "sent") {
151941
+ console.log();
151942
+ console.log(chalk.green(" Verification email sent."));
151943
+ console.log();
151944
+ console.log(chalk.bold(" Next steps:"));
151945
+ console.log(` 1. Check ${chalk.cyan(options.email)} for an email from SkillVault`);
151946
+ console.log(" 2. Click the magic link to sign in to the dashboard");
151947
+ console.log(" 3. On the dashboard, go to Settings \u2192 Profile");
151948
+ console.log(" 4. Copy your CLI token and run:");
151949
+ console.log(chalk.cyan(` skillvault-publisher login --token <pasted_token>`));
151950
+ console.log();
151951
+ process.exit(0);
151952
+ }
151953
+ if (mlData.status === "not_found") {
151954
+ console.error(chalk.red(`No account found for ${options.email}.`));
151955
+ console.error(chalk.dim("Create one at https://app.getskillvault.com/login first."));
151956
+ process.exit(1);
151957
+ }
151958
+ }
151959
+ console.error(chalk.red("Failed to send verification email."));
151960
+ console.error(chalk.dim(err.message || "Unknown error"));
151961
+ process.exit(1);
151962
+ }
151963
+ }
151929
151964
  if (!loginRes.ok) {
151930
151965
  const err = await loginRes.json().catch(() => null);
151931
151966
  const reason = err?.message || err?.error || loginRes.statusText || `HTTP ${loginRes.status}`;
@@ -152070,7 +152105,7 @@ var registerCommand = new Command2("register").description("Create a new publish
152070
152105
  let verified = false;
152071
152106
  const maxAttempts = 120;
152072
152107
  for (let i = 0; i < maxAttempts; i++) {
152073
- await new Promise((resolve11) => setTimeout(resolve11, 3e3));
152108
+ await new Promise((resolve12) => setTimeout(resolve12, 3e3));
152074
152109
  try {
152075
152110
  const statusRes = await fetch(`${serverUrl}/publishers/${publisher_id}/verification-status`);
152076
152111
  if (statusRes.ok) {
@@ -153152,7 +153187,8 @@ The server will clean up automatically. If the problem persists, re-run with --f
153152
153187
  }
153153
153188
  const publishResult = await publishRes.json().catch(() => ({}));
153154
153189
  const wasUnlinked = existingManifest === null;
153155
- if (!options.noLink && sessionPublisherId) {
153190
+ const publishAccepted = publishResult.status !== "rejected";
153191
+ if (publishAccepted && !options.noLink && sessionPublisherId) {
153156
153192
  const linkedAt = existingManifest?.linked_at ?? (/* @__PURE__ */ new Date()).toISOString();
153157
153193
  const newManifest = {
153158
153194
  ...existingManifest ?? {},
@@ -153186,6 +153222,26 @@ The server will clean up automatically. If the problem persists, re-run with --f
153186
153222
  if (publishResult.status === "unchanged") {
153187
153223
  console.log(chalk5.yellow(`Content unchanged for ${skillName} v${version}. No new version created.`));
153188
153224
  console.log(chalk5.dim(` Use --force to publish anyway.`));
153225
+ } else if (publishResult.status === "rejected") {
153226
+ const reasonMessage = publishResult.public_reason?.message || "Skill rejected by the security review pipeline.";
153227
+ process.stderr.write(chalk5.red(`
153228
+ Publish rejected: ${reasonMessage}
153229
+ `));
153230
+ process.stderr.write(chalk5.dim(` Run \`skillvault-publisher skill-status ${skillName}\` for more details.
153231
+ `));
153232
+ process.stderr.write(chalk5.dim(` Download a rejection report with \`skillvault-publisher skill-status ${skillName} --review-report <file>\`.
153233
+ `));
153234
+ process.exit(1);
153235
+ } else if (publishResult.status === "under_review") {
153236
+ console.log(chalk5.yellow(`
153237
+ Skill queued for review: ${skillName} v${version}`));
153238
+ if (publishResult.review_id) {
153239
+ console.log(chalk5.dim(` Review ID: ${publishResult.review_id}`));
153240
+ }
153241
+ console.log(chalk5.dim(` Skill ID: ${publishResult.skill_id || "n/a"}`));
153242
+ console.log(chalk5.dim(` Capability: ${capabilityName}`));
153243
+ console.log(chalk5.dim(" Reviews usually complete within a few minutes."));
153244
+ console.log(chalk5.dim(` Check status with \`skillvault-publisher skill-status ${skillName}\` (or listen on your webhook).`));
153189
153245
  } else {
153190
153246
  console.log(chalk5.green(`Published ${skillName} v${version}`));
153191
153247
  console.log(chalk5.dim(` Skill ID: ${publishResult.skill_id || "n/a"}`));
@@ -153674,8 +153730,17 @@ var whoamiCommand = new Command9("whoami").description("Show current user, activ
153674
153730
  console.log(JSON.stringify({
153675
153731
  host_id: data.host_id ?? config.host_id,
153676
153732
  agent_id: data.agent_id ?? config.agent_id,
153677
- ...config.publisher_id ? { publisher_id: config.publisher_id } : {},
153678
- ...config.email ? { email: config.email } : {},
153733
+ ...authMe ? {
153734
+ publisher_id: authMe.publisher_id,
153735
+ publisher_name: authMe.publisher_name,
153736
+ email: authMe.email,
153737
+ role: authMe.role,
153738
+ is_owner: authMe.is_owner,
153739
+ ...authMe.skill_acls ? { skill_acls: authMe.skill_acls } : {}
153740
+ } : {
153741
+ ...config.publisher_id ? { publisher_id: config.publisher_id } : {},
153742
+ ...config.email ? { email: config.email } : {}
153743
+ },
153679
153744
  device_fingerprint: fingerprint,
153680
153745
  server_url: config.server_url,
153681
153746
  status: data.status,
@@ -153683,6 +153748,18 @@ var whoamiCommand = new Command9("whoami").description("Show current user, activ
153683
153748
  }, null, 2));
153684
153749
  return;
153685
153750
  }
153751
+ let skillsById = /* @__PURE__ */ new Map();
153752
+ if (authMe?.role === "member" && authMe.skill_acls && authMe.skill_acls.length > 0) {
153753
+ try {
153754
+ const skillsRes = await fetch(`${config.server_url}/skills`, { headers: ctx.headers });
153755
+ if (skillsRes.ok) {
153756
+ const sd = await skillsRes.json();
153757
+ for (const s of sd.skills)
153758
+ skillsById.set(s.id, s);
153759
+ }
153760
+ } catch {
153761
+ }
153762
+ }
153686
153763
  console.log();
153687
153764
  console.log(chalk10.bold(" Skill Vault Identity"));
153688
153765
  console.log();
@@ -153695,6 +153772,20 @@ var whoamiCommand = new Command9("whoami").description("Show current user, activ
153695
153772
  if (!authMe.is_owner) {
153696
153773
  console.log(` ${chalk10.dim(" (you are a team member of this publisher)".padEnd(22))}`);
153697
153774
  }
153775
+ if (authMe.role === "member" && authMe.skill_acls) {
153776
+ if (authMe.skill_acls.length === 0) {
153777
+ console.log(` ${chalk10.dim("Skill access:".padEnd(22))} ${chalk10.dim("(none yet \u2014 publish a new skill to auto-own it)")}`);
153778
+ } else {
153779
+ console.log(` ${"Skill access:".padEnd(22)}`);
153780
+ for (const a of authMe.skill_acls) {
153781
+ const sk = skillsById.get(a.skill_id);
153782
+ const label = sk?.name || a.skill_id;
153783
+ const roleColor2 = a.role === "owner" ? chalk10.green : a.role === "write" ? chalk10.cyan : chalk10.dim;
153784
+ const action = a.role === "owner" ? "publish + delete" : a.role === "write" ? "publish new versions" : "view only";
153785
+ console.log(` ${chalk10.cyan(label.padEnd(20))} ${roleColor2(a.role.padEnd(8))} ${chalk10.dim(action)}`);
153786
+ }
153787
+ }
153788
+ }
153698
153789
  } else {
153699
153790
  if (config.publisher_id) {
153700
153791
  console.log(` ${"Publisher ID:".padEnd(22)} ${config.publisher_id}`);
@@ -153961,11 +154052,13 @@ var listCommand = new Command13("list").description("List your published skills"
153961
154052
  const nameWidth = Math.max(20, ...skills.map((s) => s.name.length + 2));
153962
154053
  const verWidth = 10;
153963
154054
  const statusWidth = 10;
154055
+ const reviewWidth = 8;
153964
154056
  const capWidth = Math.max(24, ...skills.map((s) => s.capability_name.length + 2));
153965
154057
  const header = [
153966
154058
  chalk14.dim("Name".padEnd(nameWidth)),
153967
154059
  chalk14.dim("Version".padEnd(verWidth)),
153968
154060
  chalk14.dim("Status".padEnd(statusWidth)),
154061
+ chalk14.dim("Review".padEnd(reviewWidth)),
153969
154062
  chalk14.dim("Capability".padEnd(capWidth)),
153970
154063
  chalk14.dim("Created")
153971
154064
  ].join(" ");
@@ -153977,10 +154070,29 @@ var listCommand = new Command13("list").description("List your published skills"
153977
154070
  year: "numeric"
153978
154071
  });
153979
154072
  const statusColor = skill.status === "active" ? chalk14.green : chalk14.dim;
154073
+ let reviewCell;
154074
+ switch (skill.review_state) {
154075
+ case "approved":
154076
+ reviewCell = chalk14.green("ok".padEnd(reviewWidth));
154077
+ break;
154078
+ case "queued":
154079
+ case "running":
154080
+ reviewCell = chalk14.yellow("review".padEnd(reviewWidth));
154081
+ break;
154082
+ case "rejected":
154083
+ reviewCell = chalk14.red("reject".padEnd(reviewWidth));
154084
+ break;
154085
+ case "needs_human_review":
154086
+ reviewCell = chalk14.yellow("human".padEnd(reviewWidth));
154087
+ break;
154088
+ default:
154089
+ reviewCell = chalk14.dim("-".padEnd(reviewWidth));
154090
+ }
153980
154091
  const row = [
153981
154092
  chalk14.cyan(skill.name.padEnd(nameWidth)),
153982
154093
  chalk14.green(("v" + skill.latest_version).padEnd(verWidth)),
153983
154094
  statusColor(skill.status.padEnd(statusWidth)),
154095
+ reviewCell,
153984
154096
  chalk14.dim(skill.capability_name.padEnd(capWidth)),
153985
154097
  chalk14.dim(createdDate)
153986
154098
  ].join(" ");
@@ -155055,7 +155167,9 @@ var skillDeleteCommand = new Command20("skill-delete").description("Permanently
155055
155167
  // dist/commands/skill-status.js
155056
155168
  import { Command as Command21 } from "commander";
155057
155169
  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) => {
155170
+ import { writeFileSync as writeFileSync10 } from "node:fs";
155171
+ import { resolve as resolve9 } from "node:path";
155172
+ 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
155173
  try {
155060
155174
  const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155061
155175
  const skillName = skillNameArg ?? ctx.defaultSkillName ?? void 0;
@@ -155077,17 +155191,56 @@ var skillStatusCommand = new Command21("skill-status").description("Show detaile
155077
155191
  sessionFetch(ctx, "/grants")
155078
155192
  ]);
155079
155193
  const activeGrants = grantsData.grants.filter((g) => g.capability === detail.capability_name && g.status === "active");
155194
+ if (options.reviewReport) {
155195
+ const report = {
155196
+ skill_id: detail.id,
155197
+ capability_name: detail.capability_name,
155198
+ version: detail.latest_version,
155199
+ review_state: detail.review_state ?? null,
155200
+ public_reason_code: detail.latest_review?.public_reason_code ?? null,
155201
+ public_reason_message: detail.latest_review?.public_reason_message ?? null,
155202
+ last_review_at: detail.latest_review?.last_review_at ?? null
155203
+ };
155204
+ const reportPath = resolve9(options.reviewReport);
155205
+ writeFileSync10(reportPath, JSON.stringify(report, null, 2) + "\n");
155206
+ process.stderr.write(chalk18.green(`Wrote review report to ${reportPath}
155207
+ `));
155208
+ }
155080
155209
  if (options.json) {
155081
155210
  console.log(JSON.stringify({ ...detail, active_grants: activeGrants.length }, null, 2));
155082
155211
  return;
155083
155212
  }
155084
155213
  const statusColor = detail.status === "active" ? chalk18.green : detail.status === "archived" ? chalk18.yellow : chalk18.dim;
155085
155214
  const createdDate = new Date(detail.created_at).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
155215
+ const reviewState = detail.review_state ?? "approved";
155216
+ let reviewLabel;
155217
+ switch (reviewState) {
155218
+ case "approved":
155219
+ reviewLabel = chalk18.green("Approved");
155220
+ break;
155221
+ case "queued":
155222
+ case "running":
155223
+ reviewLabel = chalk18.yellow("Under review");
155224
+ break;
155225
+ case "rejected":
155226
+ reviewLabel = chalk18.red("Rejected");
155227
+ break;
155228
+ case "needs_human_review":
155229
+ reviewLabel = chalk18.yellow("Awaiting review");
155230
+ break;
155231
+ default:
155232
+ reviewLabel = chalk18.dim(reviewState);
155233
+ }
155234
+ 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
155235
  console.log();
155087
155236
  console.log(chalk18.bold(` ${detail.name}`));
155088
155237
  console.log();
155089
155238
  console.log(` Capability: ${detail.capability_name}`);
155090
155239
  console.log(` Status: ${statusColor(detail.status)}`);
155240
+ console.log(` Review: ${reviewLabel}${lastReviewAt ? chalk18.dim(` (${lastReviewAt})`) : ""}`);
155241
+ if (reviewState === "rejected" && detail.latest_review?.public_reason_message) {
155242
+ console.log(` Reason: ${chalk18.red(detail.latest_review.public_reason_message)}`);
155243
+ }
155091
155244
  console.log(` Version: ${chalk18.green("v" + detail.latest_version)}`);
155092
155245
  console.log(` Created: ${chalk18.dim(createdDate)}`);
155093
155246
  console.log(` ID: ${chalk18.dim(detail.id)}`);
@@ -155144,10 +155297,199 @@ var skillUnarchiveCommand = new Command22("skill-unarchive").description("Restor
155144
155297
  }
155145
155298
  });
155146
155299
 
155147
- // dist/commands/grants.js
155300
+ // dist/commands/skill-acl.js
155148
155301
  import { Command as Command23 } from "commander";
155149
155302
  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) => {
155303
+ var VALID_ROLES = /* @__PURE__ */ new Set(["read", "write", "owner"]);
155304
+ async function resolveSkill(ctx, skillName) {
155305
+ const data = await sessionFetch(ctx, "/skills");
155306
+ const skill = data.skills.find((s) => s.name.toLowerCase() === skillName.toLowerCase() || s.capability_name.toLowerCase() === skillName.toLowerCase());
155307
+ if (!skill) {
155308
+ process.stderr.write(chalk20.red(`Skill not found: ${skillName}
155309
+ `));
155310
+ process.stderr.write(chalk20.dim("Run `skillvault-publisher list` to see your skills.\n"));
155311
+ process.exit(1);
155312
+ }
155313
+ return skill;
155314
+ }
155315
+ async function runList(ctx, skill, options) {
155316
+ const data = await sessionFetch(ctx, `/skills/${skill.id}/acls`);
155317
+ const acls = data.acls || [];
155318
+ if (options.json) {
155319
+ console.log(JSON.stringify({ skill: skill.name, skill_id: skill.id, acls }, null, 2));
155320
+ return;
155321
+ }
155322
+ console.log();
155323
+ console.log(chalk20.bold(` ACL grants on ${chalk20.cyan(skill.name)}`));
155324
+ console.log();
155325
+ if (acls.length === 0) {
155326
+ console.log(chalk20.dim(" No ACL grants. Account owners and admins always have full access."));
155327
+ console.log(chalk20.dim(` Add a member: skillvault-publisher skill-acl ${skill.name} add <email> --role read|write|owner`));
155328
+ console.log();
155329
+ return;
155330
+ }
155331
+ const emailWidth = Math.max(20, ...acls.map((a) => a.email.length + 2));
155332
+ const roleWidth = 8;
155333
+ const header = [
155334
+ chalk20.dim("Email".padEnd(emailWidth)),
155335
+ chalk20.dim("Role".padEnd(roleWidth)),
155336
+ chalk20.dim("Granted by")
155337
+ ].join(" ");
155338
+ console.log(` ${header}`);
155339
+ console.log(` ${chalk20.dim("-".repeat(emailWidth + roleWidth + 24))}`);
155340
+ for (const a of acls) {
155341
+ const roleColor = a.role === "owner" ? chalk20.green : a.role === "write" ? chalk20.cyan : chalk20.dim;
155342
+ const row = [
155343
+ a.email.padEnd(emailWidth),
155344
+ roleColor(a.role.padEnd(roleWidth)),
155345
+ chalk20.dim(a.granted_by || "(self)")
155346
+ ].join(" ");
155347
+ console.log(` ${row}`);
155348
+ }
155349
+ console.log();
155350
+ }
155351
+ async function runAdd(ctx, skill, email, options) {
155352
+ if (!options.role) {
155353
+ process.stderr.write(chalk20.red("Error: --role is required (read|write|owner)\n"));
155354
+ process.exit(1);
155355
+ }
155356
+ const role = options.role.toLowerCase();
155357
+ if (!VALID_ROLES.has(role)) {
155358
+ process.stderr.write(chalk20.red(`Invalid --role value: ${options.role}
155359
+ `));
155360
+ process.stderr.write(chalk20.dim(" Must be one of: read, write, owner\n"));
155361
+ process.exit(1);
155362
+ }
155363
+ const res = await fetch(`${ctx.serverUrl}/skills/${skill.id}/acls`, {
155364
+ method: "POST",
155365
+ headers: ctx.headers,
155366
+ body: JSON.stringify({ email, role })
155367
+ });
155368
+ const body = await res.json().catch(() => ({}));
155369
+ if (!res.ok) {
155370
+ if (body.error === "not_a_team_member") {
155371
+ process.stderr.write(chalk20.red(`${email} is not a member of this team.
155372
+ `));
155373
+ process.stderr.write(chalk20.dim(`Add them first: skillvault-publisher team add ${email} --role member
155374
+ `));
155375
+ process.exit(1);
155376
+ }
155377
+ process.stderr.write(chalk20.red(`Failed to grant: ${body.message || body.error || res.statusText}
155378
+ `));
155379
+ process.exit(1);
155380
+ }
155381
+ if (options.json) {
155382
+ console.log(JSON.stringify(body, null, 2));
155383
+ return;
155384
+ }
155385
+ if (body.note) {
155386
+ console.log(chalk20.yellow(` ${body.note}`));
155387
+ return;
155388
+ }
155389
+ const acl = body.acl;
155390
+ console.log(chalk20.green(`Granted ${acl.email} ${chalk20.bold(acl.role)} on ${skill.name}`));
155391
+ }
155392
+ async function runRemove(ctx, skill, target, options) {
155393
+ const data = await sessionFetch(ctx, `/skills/${skill.id}/acls`);
155394
+ const acls = data.acls || [];
155395
+ let acl;
155396
+ if (target.startsWith("acl_")) {
155397
+ acl = acls.find((a) => a.id === target);
155398
+ } else {
155399
+ acl = acls.find((a) => a.email.toLowerCase() === target.toLowerCase());
155400
+ }
155401
+ if (!acl) {
155402
+ process.stderr.write(chalk20.red(`No ACL row matches: ${target}
155403
+ `));
155404
+ process.exit(1);
155405
+ }
155406
+ if (!options.yes) {
155407
+ console.log();
155408
+ console.log(chalk20.yellow.bold(" Warning: ") + `This revokes ${acl.role} access on ${chalk20.cyan(skill.name)} for ${chalk20.cyan(acl.email)}.`);
155409
+ console.log(chalk20.dim(" Add --yes to confirm."));
155410
+ console.log();
155411
+ process.exit(0);
155412
+ }
155413
+ const res = await fetch(`${ctx.serverUrl}/skills/${skill.id}/acls/${acl.id}`, {
155414
+ method: "DELETE",
155415
+ headers: ctx.headers
155416
+ });
155417
+ const body = await res.json().catch(() => ({}));
155418
+ if (!res.ok) {
155419
+ if (body.error === "last_owner") {
155420
+ process.stderr.write(chalk20.red("Cannot remove the last owner ACL on this skill.\n"));
155421
+ process.stderr.write(chalk20.dim(" Grant another member owner access first, or have an account admin manage it.\n"));
155422
+ process.exit(1);
155423
+ }
155424
+ process.stderr.write(chalk20.red(`Failed to remove: ${body.message || body.error || res.statusText}
155425
+ `));
155426
+ process.exit(1);
155427
+ }
155428
+ if (options.json) {
155429
+ console.log(JSON.stringify({ removed: true, acl_id: acl.id, email: acl.email, role: acl.role }, null, 2));
155430
+ return;
155431
+ }
155432
+ console.log(chalk20.green(`Removed ${acl.email} (${acl.role}) from ${skill.name}`));
155433
+ }
155434
+ 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) => {
155435
+ try {
155436
+ let skillName = skillNameArg;
155437
+ let action = actionArg;
155438
+ let target = targetArg;
155439
+ const isActionVerb = (s) => s === "list" || s === "add" || s === "remove";
155440
+ if (isActionVerb(skillNameArg) && !isActionVerb(actionArg)) {
155441
+ action = skillNameArg;
155442
+ target = actionArg;
155443
+ skillName = "";
155444
+ }
155445
+ const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155446
+ if (!skillName) {
155447
+ if (!ctx.defaultSkillName) {
155448
+ process.stderr.write(chalk20.red("Error: No skill name provided and no workspace context.\n"));
155449
+ process.stderr.write(chalk20.dim(" Pass <skill-name> or run from a linked workspace directory.\n"));
155450
+ process.exit(1);
155451
+ }
155452
+ skillName = ctx.defaultSkillName;
155453
+ }
155454
+ if (!isActionVerb(action)) {
155455
+ process.stderr.write(chalk20.red(`Unknown action: ${action}
155456
+ `));
155457
+ process.stderr.write(chalk20.dim(" Must be one of: list, add, remove\n"));
155458
+ process.exit(1);
155459
+ }
155460
+ const skill = await resolveSkill(ctx, skillName);
155461
+ if (action === "list") {
155462
+ await runList(ctx, skill, options);
155463
+ return;
155464
+ }
155465
+ if (action === "add") {
155466
+ if (!target) {
155467
+ process.stderr.write(chalk20.red("Error: add requires <email>\n"));
155468
+ process.exit(1);
155469
+ }
155470
+ await runAdd(ctx, skill, target, options);
155471
+ return;
155472
+ }
155473
+ if (action === "remove") {
155474
+ if (!target) {
155475
+ process.stderr.write(chalk20.red("Error: remove requires <email-or-id>\n"));
155476
+ process.exit(1);
155477
+ }
155478
+ await runRemove(ctx, skill, target, options);
155479
+ return;
155480
+ }
155481
+ } catch (err) {
155482
+ const message = err instanceof Error ? err.message : String(err);
155483
+ process.stderr.write(chalk20.red(`skill-acl failed: ${message}
155484
+ `));
155485
+ process.exit(1);
155486
+ }
155487
+ });
155488
+
155489
+ // dist/commands/grants.js
155490
+ import { Command as Command24 } from "commander";
155491
+ import chalk21 from "chalk";
155492
+ 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
155493
  try {
155152
155494
  const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155153
155495
  const data = await sessionFetch(ctx, "/grants");
@@ -155165,18 +155507,18 @@ var grantsCommand = new Command23("grants").description("List capability grants
155165
155507
  return;
155166
155508
  }
155167
155509
  if (grants.length === 0) {
155168
- console.log(chalk20.dim("No grants found."));
155510
+ console.log(chalk21.dim("No grants found."));
155169
155511
  return;
155170
155512
  }
155171
155513
  console.log();
155172
- console.log(chalk20.bold(" Capability Grants"));
155514
+ console.log(chalk21.bold(" Capability Grants"));
155173
155515
  console.log();
155174
155516
  const pad4 = (s, n) => s.padEnd(n).slice(0, n);
155175
155517
  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))}`);
155518
+ console.log(` ${chalk21.dim(header)}`);
155519
+ console.log(` ${chalk21.dim("\u2500".repeat(header.length))}`);
155178
155520
  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;
155521
+ const statusColor = grant.status === "active" ? chalk21.green : grant.status === "revoked" ? chalk21.red : grant.status === "expired" ? chalk21.yellow : chalk21.white;
155180
155522
  const row = [
155181
155523
  pad4(grant.id, 22),
155182
155524
  pad4(grant.capability, 24),
@@ -155188,20 +155530,20 @@ var grantsCommand = new Command23("grants").description("List capability grants
155188
155530
  console.log(` ${row}`);
155189
155531
  }
155190
155532
  console.log();
155191
- console.log(chalk20.dim(` ${grants.length} grant${grants.length !== 1 ? "s" : ""} total`));
155533
+ console.log(chalk21.dim(` ${grants.length} grant${grants.length !== 1 ? "s" : ""} total`));
155192
155534
  console.log();
155193
155535
  } catch (err) {
155194
155536
  const message = err instanceof Error ? err.message : String(err);
155195
- process.stderr.write(chalk20.red(`Error: ${message}
155537
+ process.stderr.write(chalk21.red(`Error: ${message}
155196
155538
  `));
155197
155539
  process.exit(1);
155198
155540
  }
155199
155541
  });
155200
155542
 
155201
155543
  // 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) => {
155544
+ import { Command as Command25 } from "commander";
155545
+ import chalk22 from "chalk";
155546
+ 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
155547
  try {
155206
155548
  const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155207
155549
  if (!options.yes) {
@@ -155212,7 +155554,7 @@ var revokeGrantCommand = new Command24("revoke-grant").description("Revoke a cap
155212
155554
  return;
155213
155555
  }
155214
155556
  console.log();
155215
- console.log(chalk21.bold(" Grant details"));
155557
+ console.log(chalk22.bold(" Grant details"));
155216
155558
  console.log();
155217
155559
  console.log(` ID: ${grant.id}`);
155218
155560
  console.log(` Skill: ${grant.skill}`);
@@ -155221,7 +155563,7 @@ var revokeGrantCommand = new Command24("revoke-grant").description("Revoke a cap
155221
155563
  console.log(` Granted: ${new Date(grant.granted_at).toLocaleDateString()}`);
155222
155564
  console.log(` Expires: ${grant.expires_at ? new Date(grant.expires_at).toLocaleDateString() : "never"}`);
155223
155565
  console.log();
155224
- console.log(chalk21.yellow(" Add --yes to confirm revocation."));
155566
+ console.log(chalk22.yellow(" Add --yes to confirm revocation."));
155225
155567
  console.log();
155226
155568
  return;
155227
155569
  }
@@ -155230,19 +155572,19 @@ var revokeGrantCommand = new Command24("revoke-grant").description("Revoke a cap
155230
155572
  console.log(JSON.stringify(result.grant, null, 2));
155231
155573
  return;
155232
155574
  }
155233
- console.log(chalk21.green(`Revoked grant ${result.grant.id} for ${result.grant.skill}`));
155575
+ console.log(chalk22.green(`Revoked grant ${result.grant.id} for ${result.grant.skill}`));
155234
155576
  } catch (err) {
155235
155577
  const message = err instanceof Error ? err.message : String(err);
155236
- process.stderr.write(chalk21.red(`Error: ${message}
155578
+ process.stderr.write(chalk22.red(`Error: ${message}
155237
155579
  `));
155238
155580
  process.exit(1);
155239
155581
  }
155240
155582
  });
155241
155583
 
155242
155584
  // 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) => {
155585
+ import { Command as Command26 } from "commander";
155586
+ import chalk23 from "chalk";
155587
+ 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
155588
  const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155247
155589
  try {
155248
155590
  const data = await sessionFetch(ctx, "/customers");
@@ -155252,19 +155594,19 @@ var customersCommand = new Command25("customers").description("List your custome
155252
155594
  return;
155253
155595
  }
155254
155596
  if (customers.length === 0) {
155255
- console.log(chalk22.dim("No customers found."));
155597
+ console.log(chalk23.dim("No customers found."));
155256
155598
  return;
155257
155599
  }
155258
155600
  console.log();
155259
- console.log(chalk22.bold(" Customers"));
155601
+ console.log(chalk23.bold(" Customers"));
155260
155602
  console.log();
155261
155603
  const pad4 = (s, n) => s.padEnd(n).slice(0, n);
155262
155604
  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))}`);
155605
+ console.log(` ${chalk23.dim(header)}`);
155606
+ console.log(` ${chalk23.dim("\u2500".repeat(header.length))}`);
155265
155607
  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");
155608
+ const statusColor = c.status === "active" ? chalk23.green : chalk23.dim;
155609
+ const lastActive = c.last_active_at ? new Date(c.last_active_at).toLocaleDateString() : chalk23.dim("never");
155268
155610
  const row = [
155269
155611
  pad4(c.email, 32),
155270
155612
  pad4(String(c.skills_count), 8),
@@ -155275,25 +155617,25 @@ var customersCommand = new Command25("customers").description("List your custome
155275
155617
  console.log(` ${row}`);
155276
155618
  }
155277
155619
  console.log();
155278
- console.log(chalk22.dim(` ${customers.length} customer${customers.length !== 1 ? "s" : ""} total`));
155620
+ console.log(chalk23.dim(` ${customers.length} customer${customers.length !== 1 ? "s" : ""} total`));
155279
155621
  console.log();
155280
155622
  } catch (err) {
155281
155623
  const message = err instanceof Error ? err.message : String(err);
155282
- process.stderr.write(chalk22.red(`Error: ${message}
155624
+ process.stderr.write(chalk23.red(`Error: ${message}
155283
155625
  `));
155284
155626
  process.exit(1);
155285
155627
  }
155286
155628
  });
155287
155629
 
155288
155630
  // 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) => {
155631
+ import { Command as Command27 } from "commander";
155632
+ import chalk24 from "chalk";
155633
+ 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
155634
  const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155293
155635
  try {
155294
155636
  const days = parseInt(options.days, 10);
155295
155637
  if (isNaN(days) || days < 1) {
155296
- process.stderr.write(chalk23.red("--days must be a positive number.\n"));
155638
+ process.stderr.write(chalk24.red("--days must be a positive number.\n"));
155297
155639
  process.exit(1);
155298
155640
  }
155299
155641
  const end = /* @__PURE__ */ new Date();
@@ -155306,11 +155648,11 @@ var analyticsCommand = new Command26("analytics").description("View publisher an
155306
155648
  return;
155307
155649
  }
155308
155650
  console.log();
155309
- console.log(chalk23.bold(" Publisher Analytics"));
155651
+ console.log(chalk24.bold(" Publisher Analytics"));
155310
155652
  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()})`);
155653
+ console.log(` ${chalk24.bold("Active Licenses:")} ${data.active_licenses}`);
155654
+ console.log(` ${chalk24.bold("Total Decryptions:")} ${data.total_decryptions}`);
155655
+ console.log(` ${chalk24.bold("Period:")} Last ${days} day${days !== 1 ? "s" : ""} (${start.toLocaleDateString()} \u2013 ${end.toLocaleDateString()})`);
155314
155656
  const effectiveSkill = options.skill ?? (options.all ? void 0 : ctx.defaultSkillName ?? void 0);
155315
155657
  const filterSkill = (skillName) => !effectiveSkill || skillName.toLowerCase() === effectiveSkill.toLowerCase();
155316
155658
  const statsMap = new Map((data.skill_stats || []).map((s) => [s.skill_name, s]));
@@ -155319,12 +155661,12 @@ var analyticsCommand = new Command26("analytics").description("View publisher an
155319
155661
  }
155320
155662
  if (data.top_skills && data.top_skills.length > 0) {
155321
155663
  console.log();
155322
- console.log(chalk23.bold(" Top Skills"));
155664
+ console.log(chalk24.bold(" Top Skills"));
155323
155665
  console.log();
155324
155666
  const pad4 = (s, n) => s.padEnd(n).slice(0, n);
155325
155667
  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))}`);
155668
+ console.log(` ${chalk24.dim(header)}`);
155669
+ console.log(` ${chalk24.dim("\u2500".repeat(header.length))}`);
155328
155670
  for (const skill of data.top_skills) {
155329
155671
  const stats = statsMap.get(skill.name);
155330
155672
  const row = [
@@ -155336,27 +155678,27 @@ var analyticsCommand = new Command26("analytics").description("View publisher an
155336
155678
  }
155337
155679
  } else {
155338
155680
  console.log();
155339
- console.log(chalk23.dim(" No skill activity in this period."));
155681
+ console.log(chalk24.dim(" No skill activity in this period."));
155340
155682
  }
155341
155683
  console.log();
155342
155684
  } catch (err) {
155343
155685
  const message = err instanceof Error ? err.message : String(err);
155344
- process.stderr.write(chalk23.red(`Error: ${message}
155686
+ process.stderr.write(chalk24.red(`Error: ${message}
155345
155687
  `));
155346
155688
  process.exit(1);
155347
155689
  }
155348
155690
  });
155349
155691
 
155350
155692
  // 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) => {
155693
+ import { Command as Command28 } from "commander";
155694
+ import chalk25 from "chalk";
155695
+ 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
155696
  try {
155355
155697
  const ctx = requireSession();
155356
155698
  switch (action) {
155357
155699
  case "set": {
155358
155700
  if (!options.url) {
155359
- process.stderr.write(chalk24.red("Missing --url option. Usage: skillvault-publisher webhook set --url <url>\n"));
155701
+ process.stderr.write(chalk25.red("Missing --url option. Usage: skillvault-publisher webhook set --url <url>\n"));
155360
155702
  process.exit(1);
155361
155703
  }
155362
155704
  const data = await sessionFetch(ctx, `/publishers/${ctx.publisherId}/webhook`, { method: "POST", body: { url: options.url } });
@@ -155365,12 +155707,12 @@ var webhookCommand = new Command27("webhook").description("Manage publisher webh
155365
155707
  return;
155366
155708
  }
155367
155709
  console.log();
155368
- console.log(chalk24.green(" Webhook configured"));
155710
+ console.log(chalk25.green(" Webhook configured"));
155369
155711
  console.log();
155370
155712
  console.log(` ${"URL:".padEnd(18)} ${data.webhook_url}`);
155371
- console.log(` ${"Signing Secret:".padEnd(18)} ${chalk24.yellow(data.signing_secret)}`);
155713
+ console.log(` ${"Signing Secret:".padEnd(18)} ${chalk25.yellow(data.signing_secret)}`);
155372
155714
  console.log();
155373
- console.log(chalk24.dim(" Store the signing secret securely. It will not be shown again."));
155715
+ console.log(chalk25.dim(" Store the signing secret securely. It will not be shown again."));
155374
155716
  console.log();
155375
155717
  break;
155376
155718
  }
@@ -155381,7 +155723,7 @@ var webhookCommand = new Command27("webhook").description("Manage publisher webh
155381
155723
  return;
155382
155724
  }
155383
155725
  console.log();
155384
- console.log(chalk24.green(" Test event sent to webhook URL"));
155726
+ console.log(chalk25.green(" Test event sent to webhook URL"));
155385
155727
  console.log();
155386
155728
  break;
155387
155729
  }
@@ -155393,36 +155735,36 @@ var webhookCommand = new Command27("webhook").description("Manage publisher webh
155393
155735
  }
155394
155736
  console.log();
155395
155737
  if (data.webhook_url) {
155396
- console.log(chalk24.bold(" Webhook Status"));
155738
+ console.log(chalk25.bold(" Webhook Status"));
155397
155739
  console.log();
155398
155740
  console.log(` ${"URL:".padEnd(12)} ${data.webhook_url}`);
155399
- console.log(` ${"Status:".padEnd(12)} ${chalk24.green("configured")}`);
155741
+ console.log(` ${"Status:".padEnd(12)} ${chalk25.green("configured")}`);
155400
155742
  } else {
155401
- console.log(chalk24.dim(" No webhook configured."));
155743
+ console.log(chalk25.dim(" No webhook configured."));
155402
155744
  console.log();
155403
- console.log(chalk24.dim(" Set one with: skillvault-publisher webhook set --url <url>"));
155745
+ console.log(chalk25.dim(" Set one with: skillvault-publisher webhook set --url <url>"));
155404
155746
  }
155405
155747
  console.log();
155406
155748
  break;
155407
155749
  }
155408
155750
  default:
155409
- process.stderr.write(chalk24.red(`Unknown action: ${action}
155751
+ process.stderr.write(chalk25.red(`Unknown action: ${action}
155410
155752
  `));
155411
- process.stderr.write(chalk24.dim("Valid actions: set, test, status\n"));
155753
+ process.stderr.write(chalk25.dim("Valid actions: set, test, status\n"));
155412
155754
  process.exit(1);
155413
155755
  }
155414
155756
  } catch (err) {
155415
155757
  const message = err instanceof Error ? err.message : String(err);
155416
- process.stderr.write(chalk24.red(`Error: ${message}
155758
+ process.stderr.write(chalk25.red(`Error: ${message}
155417
155759
  `));
155418
155760
  process.exit(1);
155419
155761
  }
155420
155762
  });
155421
155763
 
155422
155764
  // 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) => {
155765
+ import { Command as Command29 } from "commander";
155766
+ import chalk26 from "chalk";
155767
+ 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
155768
  try {
155427
155769
  const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155428
155770
  const effectiveSkill = options.skill ?? (options.all ? void 0 : ctx.defaultSkillName ?? void 0);
@@ -155437,7 +155779,7 @@ var auditCommand = new Command28("audit").description("View audit log events").o
155437
155779
  if (options.export) {
155438
155780
  const format = options.export.toLowerCase();
155439
155781
  if (format !== "csv" && format !== "json") {
155440
- process.stderr.write(chalk25.red('Export format must be "csv" or "json".\n'));
155782
+ process.stderr.write(chalk26.red('Export format must be "csv" or "json".\n'));
155441
155783
  process.exit(1);
155442
155784
  }
155443
155785
  params.set("format", format);
@@ -155456,16 +155798,16 @@ var auditCommand = new Command28("audit").description("View audit log events").o
155456
155798
  return;
155457
155799
  }
155458
155800
  if (events.length === 0) {
155459
- console.log(chalk25.dim("No audit events found."));
155801
+ console.log(chalk26.dim("No audit events found."));
155460
155802
  return;
155461
155803
  }
155462
155804
  console.log();
155463
- console.log(chalk25.bold(" Audit Log"));
155805
+ console.log(chalk26.bold(" Audit Log"));
155464
155806
  console.log();
155465
155807
  const pad4 = (s, n) => s.padEnd(n).slice(0, n);
155466
155808
  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))}`);
155809
+ console.log(` ${chalk26.dim(header)}`);
155810
+ console.log(` ${chalk26.dim("\u2500".repeat(header.length))}`);
155469
155811
  for (const event of events) {
155470
155812
  const skill = event.capability ? event.capability.replace(/^skill\//, "") : "-";
155471
155813
  const agent = event.agent_id ? event.agent_id.slice(0, 18) : "-";
@@ -155479,45 +155821,45 @@ var auditCommand = new Command28("audit").description("View audit log events").o
155479
155821
  console.log(` ${row}`);
155480
155822
  }
155481
155823
  console.log();
155482
- console.log(chalk25.dim(` Showing ${events.length} event${events.length !== 1 ? "s" : ""}`));
155824
+ console.log(chalk26.dim(` Showing ${events.length} event${events.length !== 1 ? "s" : ""}`));
155483
155825
  if (data.has_more) {
155484
- console.log(chalk25.dim(` More results available`));
155826
+ console.log(chalk26.dim(` More results available`));
155485
155827
  }
155486
155828
  console.log();
155487
155829
  } catch (err) {
155488
155830
  const message = err instanceof Error ? err.message : String(err);
155489
- process.stderr.write(chalk25.red(`Error: ${message}
155831
+ process.stderr.write(chalk26.red(`Error: ${message}
155490
155832
  `));
155491
155833
  process.exit(1);
155492
155834
  }
155493
155835
  });
155494
155836
 
155495
155837
  // 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";
155838
+ import { Command as Command30 } from "commander";
155839
+ import chalk27 from "chalk";
155840
+ import { readFileSync as readFileSync15, mkdirSync as mkdirSync9, writeFileSync as writeFileSync11 } from "node:fs";
155499
155841
  import { join as join14 } from "node:path";
155500
- var orange = chalk26.hex("#f97316");
155842
+ var orange = chalk27.hex("#f97316");
155501
155843
  function riskColor2(level) {
155502
155844
  switch (level.toLowerCase()) {
155503
155845
  case "low":
155504
- return chalk26.green;
155846
+ return chalk27.green;
155505
155847
  case "watch":
155506
- return chalk26.yellow;
155848
+ return chalk27.yellow;
155507
155849
  case "alert":
155508
155850
  return orange;
155509
155851
  case "critical":
155510
- return chalk26.red;
155852
+ return chalk27.red;
155511
155853
  default:
155512
- return chalk26.white;
155854
+ return chalk27.white;
155513
155855
  }
155514
155856
  }
155515
155857
  function confidenceColor(c) {
155516
155858
  if (c >= 0.9)
155517
- return chalk26.green;
155859
+ return chalk27.green;
155518
155860
  if (c >= 0.5)
155519
- return chalk26.yellow;
155520
- return chalk26.red;
155861
+ return chalk27.yellow;
155862
+ return chalk27.red;
155521
155863
  }
155522
155864
  function pad(s, n) {
155523
155865
  return s.padEnd(n).slice(0, n);
@@ -155533,30 +155875,30 @@ function toRawGitHubUrl(url) {
155533
155875
  }
155534
155876
  function displayResults(report) {
155535
155877
  console.log();
155536
- console.log(chalk26.bold(" Investigation Results"));
155878
+ console.log(chalk27.bold(" Investigation Results"));
155537
155879
  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()}`);
155880
+ console.log(` ${chalk27.bold("Investigation ID:")} ${report.investigation_id}`);
155881
+ console.log(` ${chalk27.bold("Skill:")} ${report.skill_name}`);
155882
+ console.log(` ${chalk27.bold("Total Licensees:")} ${report.total_licensees}`);
155883
+ console.log(` ${chalk27.bold("Timestamp:")} ${new Date(report.created_at).toLocaleString()}`);
155542
155884
  if (report.heartbeat_matches.length > 0) {
155543
155885
  console.log();
155544
155886
  const maxConf = Math.max(...report.heartbeat_matches.map((m) => m.confidence));
155545
155887
  const confStr = (maxConf * 100).toFixed(0) + "%";
155546
155888
  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" : ""})`);
155889
+ console.log(` ${chalk27.bold("Forensic Match:")} ${confFn(confStr + " confidence")} (${report.heartbeat_matches.length} match${report.heartbeat_matches.length !== 1 ? "es" : ""})`);
155548
155890
  }
155549
155891
  console.log();
155550
155892
  if (report.suspects.length === 0) {
155551
- console.log(chalk26.dim(" No suspects identified."));
155893
+ console.log(chalk27.dim(" No suspects identified."));
155552
155894
  console.log();
155553
155895
  return;
155554
155896
  }
155555
- console.log(chalk26.bold(" Suspect Ranking"));
155897
+ console.log(chalk27.bold(" Suspect Ranking"));
155556
155898
  console.log();
155557
155899
  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))}`);
155900
+ console.log(` ${chalk27.dim(header)}`);
155901
+ console.log(` ${chalk27.dim("\u2500".repeat(header.length))}`);
155560
155902
  for (const s of report.suspects) {
155561
155903
  const colorFn = riskColor2(s.risk_level);
155562
155904
  const label = s.customer_email || s.licensee_id.slice(0, 22);
@@ -155570,8 +155912,8 @@ function displayResults(report) {
155570
155912
  console.log(` ${row}`);
155571
155913
  }
155572
155914
  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."));
155915
+ console.log(chalk27.dim(` Full evidence retained server-side (ID: ${report.investigation_id})`));
155916
+ console.log(chalk27.dim(" Contact investigations@getskillvault.com for the complete evidence package."));
155575
155917
  console.log();
155576
155918
  }
155577
155919
  function buildHtmlReport(report, _auditEvents, metadata) {
@@ -155816,7 +156158,7 @@ ${report.suspects.length > 0 ? `<table>
155816
156158
  </body>
155817
156159
  </html>`;
155818
156160
  }
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) => {
156161
+ 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
156162
  try {
155821
156163
  const ctx = requireSession();
155822
156164
  let leakedContent;
@@ -155824,12 +156166,12 @@ var investigateCommand = new Command29("investigate").description("Investigate a
155824
156166
  if (options.url) {
155825
156167
  const rawUrl = toRawGitHubUrl(options.url);
155826
156168
  if (rawUrl !== options.url) {
155827
- console.log(chalk26.dim(` Auto-converted GitHub blob URL to raw URL`));
156169
+ console.log(chalk27.dim(` Auto-converted GitHub blob URL to raw URL`));
155828
156170
  }
155829
- console.log(chalk26.dim(` Fetching leaked content from ${rawUrl}...`));
156171
+ console.log(chalk27.dim(` Fetching leaked content from ${rawUrl}...`));
155830
156172
  const resp = await fetch(rawUrl);
155831
156173
  if (!resp.ok) {
155832
- process.stderr.write(chalk26.red(`Failed to fetch URL: ${resp.status} ${resp.statusText}
156174
+ process.stderr.write(chalk27.red(`Failed to fetch URL: ${resp.status} ${resp.statusText}
155833
156175
  `));
155834
156176
  process.exit(1);
155835
156177
  }
@@ -155840,24 +156182,24 @@ var investigateCommand = new Command29("investigate").description("Investigate a
155840
156182
  leakedContent = readFileSync15(options.file, "utf-8");
155841
156183
  } catch (err) {
155842
156184
  const msg = err instanceof Error ? err.message : String(err);
155843
- process.stderr.write(chalk26.red(`Failed to read file: ${msg}
156185
+ process.stderr.write(chalk27.red(`Failed to read file: ${msg}
155844
156186
  `));
155845
156187
  process.exit(1);
155846
156188
  }
155847
156189
  sourceLabel = options.file;
155848
156190
  } else {
155849
- process.stderr.write(chalk26.red("Provide leaked content with --url <url> or --file <path>.\n"));
156191
+ process.stderr.write(chalk27.red("Provide leaked content with --url <url> or --file <path>.\n"));
155850
156192
  process.exit(1);
155851
156193
  }
155852
- console.log(chalk26.dim(` Loaded ${leakedContent.length.toLocaleString()} chars of leaked content`));
156194
+ console.log(chalk27.dim(` Loaded ${leakedContent.length.toLocaleString()} chars of leaked content`));
155853
156195
  const skillsData = await sessionFetch(ctx, "/skills");
155854
156196
  const skill = skillsData.skills.find((s) => s.name.toLowerCase() === skillName.toLowerCase());
155855
156197
  if (!skill) {
155856
- process.stderr.write(chalk26.red(`Skill "${skillName}" not found. Use \`skillvault-publisher list\` to see your skills.
156198
+ process.stderr.write(chalk27.red(`Skill "${skillName}" not found. Use \`skillvault-publisher list\` to see your skills.
155857
156199
  `));
155858
156200
  process.exit(1);
155859
156201
  }
155860
- console.log(chalk26.dim(` Running investigation on "${skill.name}"...`));
156202
+ console.log(chalk27.dim(` Running investigation on "${skill.name}"...`));
155861
156203
  const report = await sessionFetch(ctx, `/publishers/${ctx.publisherId}/investigate`, {
155862
156204
  method: "POST",
155863
156205
  body: { skill_id: skill.id, leaked_content: leakedContent }
@@ -155883,13 +156225,13 @@ var investigateCommand = new Command29("investigate").description("Investigate a
155883
156225
  source: sourceLabel,
155884
156226
  notice: "This is an executive summary. Full evidence is retained server-side. Contact investigations@getskillvault.com for the complete evidence package."
155885
156227
  };
155886
- writeFileSync10(join14(dir, "metadata.json"), JSON.stringify(metadata, null, 2) + "\n");
155887
- writeFileSync10(join14(dir, "summary.json"), JSON.stringify({
156228
+ writeFileSync11(join14(dir, "metadata.json"), JSON.stringify(metadata, null, 2) + "\n");
156229
+ writeFileSync11(join14(dir, "summary.json"), JSON.stringify({
155888
156230
  _generated_by: "SkillVault (https://getskillvault.com)",
155889
156231
  ...report
155890
156232
  }, null, 2) + "\n");
155891
156233
  const html = buildHtmlReport(report, [], metadata);
155892
- writeFileSync10(join14(dir, "report.html"), html);
156234
+ writeFileSync11(join14(dir, "report.html"), html);
155893
156235
  const pdfPath = join14(dir, "report.pdf");
155894
156236
  const { generatePdfReport: generatePdfReport2 } = await Promise.resolve().then(() => (init_pdf_report(), pdf_report_exports));
155895
156237
  await generatePdfReport2({
@@ -155903,23 +156245,23 @@ var investigateCommand = new Command29("investigate").description("Investigate a
155903
156245
  heartbeat_matches: report.heartbeat_matches,
155904
156246
  audit_events: []
155905
156247
  }, 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})`));
156248
+ console.log(chalk27.green(` Report saved to ${dir}/`) + chalk27.dim(" (4 files)"));
156249
+ console.log(chalk27.dim(` PDF: report.pdf`));
156250
+ console.log(chalk27.dim(` Full evidence retained server-side (ID: ${report.investigation_id})`));
155909
156251
  console.log();
155910
156252
  }
155911
156253
  } catch (err) {
155912
156254
  const message = err instanceof Error ? err.message : String(err);
155913
- process.stderr.write(chalk26.red(`Error: ${message}
156255
+ process.stderr.write(chalk27.red(`Error: ${message}
155914
156256
  `));
155915
156257
  process.exit(1);
155916
156258
  }
155917
156259
  });
155918
156260
 
155919
156261
  // 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) => {
156262
+ import { Command as Command31 } from "commander";
156263
+ import chalk28 from "chalk";
156264
+ 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
156265
  const ctx = requireCommandContext({ workspaceFlag: options.workspace, quiet: options.quiet });
155924
156266
  try {
155925
156267
  const data = await sessionFetch(ctx, `/publishers/${ctx.publisherId}/watchtower`);
@@ -155930,30 +156272,30 @@ var watchtowerCommand = new Command30("watchtower").description("Watchtower secu
155930
156272
  const { summary } = data;
155931
156273
  const pad4 = (s, n) => s.padEnd(n).slice(0, n);
155932
156274
  console.log();
155933
- console.log(chalk27.bold(" Watchtower \u2014 Security Overview"));
156275
+ console.log(chalk28.bold(" Watchtower \u2014 Security Overview"));
155934
156276
  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"}`);
156277
+ 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
156278
  if (data.flagged_customers && data.flagged_customers.length > 0) {
155937
156279
  console.log();
155938
- console.log(chalk27.bold(" Flagged Customers"));
156280
+ console.log(chalk28.bold(" Flagged Customers"));
155939
156281
  console.log();
155940
156282
  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))}`);
156283
+ console.log(` ${chalk28.dim(header)}`);
156284
+ console.log(` ${chalk28.dim("\u2500".repeat(header.length))}`);
155943
156285
  for (const c of data.flagged_customers) {
155944
156286
  const agentShort = c.agent_id.length > 18 ? c.agent_id.slice(0, 18) + "\u2026" : c.agent_id;
155945
156287
  let levelColored;
155946
156288
  if (c.risk_level === "critical") {
155947
- levelColored = chalk27.red.bold(pad4(c.risk_level, 10));
156289
+ levelColored = chalk28.red.bold(pad4(c.risk_level, 10));
155948
156290
  } else if (c.risk_level === "high") {
155949
- levelColored = chalk27.red(pad4(c.risk_level, 10));
156291
+ levelColored = chalk28.red(pad4(c.risk_level, 10));
155950
156292
  } else if (c.risk_level === "medium") {
155951
- levelColored = chalk27.yellow(pad4(c.risk_level, 10));
156293
+ levelColored = chalk28.yellow(pad4(c.risk_level, 10));
155952
156294
  } else {
155953
- levelColored = chalk27.dim(pad4(c.risk_level, 10));
156295
+ levelColored = chalk28.dim(pad4(c.risk_level, 10));
155954
156296
  }
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");
156297
+ const statusColored = c.status === "suspended" ? chalk28.red(pad4(c.status, 12)) : pad4(c.status, 12);
156298
+ const skills = c.capabilities.length > 0 ? c.capabilities.join(", ") : chalk28.dim("none");
155957
156299
  const row = [
155958
156300
  pad4(agentShort, 20),
155959
156301
  pad4(String(c.risk_score), 12),
@@ -155967,15 +156309,15 @@ var watchtowerCommand = new Command30("watchtower").description("Watchtower secu
155967
156309
  }
155968
156310
  if (data.recent_events && data.recent_events.length > 0) {
155969
156311
  console.log();
155970
- console.log(chalk27.bold(" Recent Security Events"));
156312
+ console.log(chalk28.bold(" Recent Security Events"));
155971
156313
  console.log();
155972
156314
  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))}`);
156315
+ console.log(` ${chalk28.dim(header)}`);
156316
+ console.log(` ${chalk28.dim("\u2500".repeat(header.length))}`);
155975
156317
  const events = data.recent_events.slice(0, 10);
155976
156318
  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("-");
156319
+ const skill = e.capability ? e.capability.replace(/^skill\//, "") : chalk28.dim("-");
156320
+ const agent = e.agent_id ? e.agent_id.slice(0, 18) : chalk28.dim("-");
155979
156321
  const time = new Date(e.created_at).toLocaleString();
155980
156322
  const row = [
155981
156323
  pad4(e.event_type, 28),
@@ -155988,25 +156330,25 @@ var watchtowerCommand = new Command30("watchtower").description("Watchtower secu
155988
156330
  }
155989
156331
  if ((!data.flagged_customers || data.flagged_customers.length === 0) && (!data.recent_events || data.recent_events.length === 0)) {
155990
156332
  console.log();
155991
- console.log(chalk27.green(" All clear \u2014 no security alerts in the last 7 days."));
156333
+ console.log(chalk28.green(" All clear \u2014 no security alerts in the last 7 days."));
155992
156334
  }
155993
156335
  console.log();
155994
156336
  } catch (err) {
155995
156337
  const message = err instanceof Error ? err.message : String(err);
155996
- process.stderr.write(chalk27.red(`Error: ${message}
156338
+ process.stderr.write(chalk28.red(`Error: ${message}
155997
156339
  `));
155998
156340
  process.exit(1);
155999
156341
  }
156000
156342
  });
156001
156343
 
156002
156344
  // dist/commands/watermark-decode.js
156003
- import { Command as Command31 } from "commander";
156004
- import chalk28 from "chalk";
156345
+ import { Command as Command32 } from "commander";
156346
+ import chalk29 from "chalk";
156005
156347
  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) => {
156348
+ 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
156349
  try {
156008
156350
  if (!options.file) {
156009
- process.stderr.write(chalk28.red("Provide --file <path> with the leaked content\n"));
156351
+ process.stderr.write(chalk29.red("Provide --file <path> with the leaked content\n"));
156010
156352
  process.exit(1);
156011
156353
  }
156012
156354
  let content;
@@ -156014,7 +156356,7 @@ var watermarkDecodeCommand = new Command31("watermark-decode").description("Anal
156014
156356
  content = readFileSync16(options.file, "utf8");
156015
156357
  } catch (err) {
156016
156358
  const msg = err instanceof Error ? err.message : String(err);
156017
- process.stderr.write(chalk28.red(`Cannot read file: ${msg}
156359
+ process.stderr.write(chalk29.red(`Cannot read file: ${msg}
156018
156360
  `));
156019
156361
  process.exit(1);
156020
156362
  }
@@ -156044,56 +156386,56 @@ var watermarkDecodeCommand = new Command31("watermark-decode").description("Anal
156044
156386
  return;
156045
156387
  }
156046
156388
  console.log();
156047
- console.log(chalk28.bold(" Watermark Analysis"));
156389
+ console.log(chalk29.bold(" Watermark Analysis"));
156048
156390
  console.log();
156049
- console.log(chalk28.bold(" Zero-Width Watermark"));
156391
+ console.log(chalk29.bold(" Zero-Width Watermark"));
156050
156392
  if (watermark.found) {
156051
- console.log(` Licensee ID: ${chalk28.green.bold(watermark.licenseeId)}`);
156393
+ console.log(` Licensee ID: ${chalk29.green.bold(watermark.licenseeId)}`);
156052
156394
  } else {
156053
- console.log(` ${chalk28.dim("Not found")}`);
156395
+ console.log(` ${chalk29.dim("Not found")}`);
156054
156396
  }
156055
156397
  console.log();
156056
- console.log(chalk28.bold(" Heartbeat Markers"));
156398
+ console.log(chalk29.bold(" Heartbeat Markers"));
156057
156399
  if (heartbeats.hb1) {
156058
- console.log(` HB1: ${chalk28.green(heartbeats.hb1)}`);
156400
+ console.log(` HB1: ${chalk29.green(heartbeats.hb1)}`);
156059
156401
  } else {
156060
- console.log(` HB1: ${chalk28.dim("Not found")}`);
156402
+ console.log(` HB1: ${chalk29.dim("Not found")}`);
156061
156403
  }
156062
156404
  if (heartbeats.hb2) {
156063
- console.log(` HB2: ${chalk28.green(heartbeats.hb2)}`);
156405
+ console.log(` HB2: ${chalk29.green(heartbeats.hb2)}`);
156064
156406
  } else {
156065
- console.log(` HB2: ${chalk28.dim("Not found")}`);
156407
+ console.log(` HB2: ${chalk29.dim("Not found")}`);
156066
156408
  }
156067
156409
  if (candidates.length > 0) {
156068
- console.log(` ${chalk28.dim(`${candidates.length} potential heartbeat candidate${candidates.length !== 1 ? "s" : ""} found`)}`);
156410
+ console.log(` ${chalk29.dim(`${candidates.length} potential heartbeat candidate${candidates.length !== 1 ? "s" : ""} found`)}`);
156069
156411
  }
156070
156412
  console.log();
156071
- console.log(chalk28.bold(" Semantic Fingerprint"));
156413
+ console.log(chalk29.bold(" Semantic Fingerprint"));
156072
156414
  if (hasFingerprint) {
156073
156415
  const binaryStr = fingerprint.map((v) => v === 1 ? "1" : v === -1 ? "X" : "0").join("");
156074
156416
  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`)}`);
156417
+ console.log(` Pattern: ${chalk29.cyan(binaryStr)}`);
156418
+ console.log(` ${chalk29.dim(`${variationPoints} variation point${variationPoints !== 1 ? "s" : ""} detected`)}`);
156077
156419
  } else {
156078
- console.log(` ${chalk28.dim("No variation points detected")}`);
156420
+ console.log(` ${chalk29.dim("No variation points detected")}`);
156079
156421
  }
156080
156422
  console.log();
156081
- const countColor = signalsDetected > 0 ? chalk28.green.bold : chalk28.dim;
156423
+ const countColor = signalsDetected > 0 ? chalk29.green.bold : chalk29.dim;
156082
156424
  console.log(` ${countColor(`${signalsDetected} of 4`)} forensic signals detected`);
156083
156425
  console.log();
156084
156426
  } catch (err) {
156085
156427
  const message = err instanceof Error ? err.message : String(err);
156086
- process.stderr.write(chalk28.red(`Error: ${message}
156428
+ process.stderr.write(chalk29.red(`Error: ${message}
156087
156429
  `));
156088
156430
  process.exit(1);
156089
156431
  }
156090
156432
  });
156091
156433
 
156092
156434
  // dist/commands/link.js
156093
- import { Command as Command32 } from "commander";
156094
- import chalk29 from "chalk";
156435
+ import { Command as Command33 } from "commander";
156436
+ import chalk30 from "chalk";
156095
156437
  import { existsSync as existsSync14, readFileSync as readFileSync17, statSync as statSync6 } from "node:fs";
156096
- import { resolve as resolve9, join as join15 } from "node:path";
156438
+ import { resolve as resolve10, join as join15 } from "node:path";
156097
156439
  function parseFrontmatter4(content) {
156098
156440
  const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
156099
156441
  if (!match)
@@ -156112,12 +156454,12 @@ function parseFrontmatter4(content) {
156112
156454
  }
156113
156455
  return result;
156114
156456
  }
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) => {
156457
+ 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
156458
  try {
156117
156459
  const ctx = requireSession();
156118
- const dirPath = options.workspace ? resolve9(options.workspace) : directory ? resolve9(directory) : process.cwd();
156460
+ const dirPath = options.workspace ? resolve10(options.workspace) : directory ? resolve10(directory) : process.cwd();
156119
156461
  if (!existsSync14(dirPath) || !statSync6(dirPath).isDirectory()) {
156120
- process.stderr.write(chalk29.red(`Error: "${dirPath}" is not a valid directory
156462
+ process.stderr.write(chalk30.red(`Error: "${dirPath}" is not a valid directory
156121
156463
  `));
156122
156464
  process.exit(1);
156123
156465
  }
@@ -156127,17 +156469,17 @@ var linkCommand = new Command32("link").description("Link a skill source directo
156127
156469
  const existing = loadWorkspace(dirPath);
156128
156470
  const skillName = options.name || existing?.skill_name || frontmatter.name;
156129
156471
  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"));
156472
+ process.stderr.write(chalk30.red("Error: Cannot determine skill name.\n"));
156473
+ process.stderr.write(chalk30.dim(" Pass --name <name> or set `name:` in SKILL.md frontmatter.\n"));
156132
156474
  process.exit(1);
156133
156475
  }
156134
156476
  const capabilityName = options.capability || existing?.capability_name || `skill/${skillName.toLowerCase()}`;
156135
156477
  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}.
156478
+ process.stderr.write(chalk30.red(`Error: This directory is already linked to publisher ${existing.publisher_id}.
156137
156479
  `));
156138
- process.stderr.write(chalk29.dim(` You are logged in as ${ctx.publisherId}.
156480
+ process.stderr.write(chalk30.dim(` You are logged in as ${ctx.publisherId}.
156139
156481
  `));
156140
- process.stderr.write(chalk29.cyan(" Use --force to re-link to your account.\n"));
156482
+ process.stderr.write(chalk30.cyan(" Use --force to re-link to your account.\n"));
156141
156483
  process.exit(1);
156142
156484
  }
156143
156485
  const linkedAt = existing?.linked_at ?? (/* @__PURE__ */ new Date()).toISOString();
@@ -156159,41 +156501,41 @@ var linkCommand = new Command32("link").description("Link a skill source directo
156159
156501
  last_published_at: manifest.last_published_at
156160
156502
  });
156161
156503
  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`));
156504
+ console.log(chalk30.green(`${action} "${skillName}" \u2192 ${capabilityName}`));
156505
+ console.log(chalk30.dim(` Directory: ${dirPath}`));
156506
+ console.log(chalk30.dim(` Publisher: ${ctx.publisherId}`));
156507
+ console.log(chalk30.dim(` Manifest: .skillvault-publisher/workspace.json`));
156166
156508
  if (!existing) {
156167
156509
  console.log();
156168
- console.log(chalk29.cyan(" Tip: commit .skillvault-publisher/workspace.json so teammates and CI can find this skill."));
156510
+ console.log(chalk30.cyan(" Tip: commit .skillvault-publisher/workspace.json so teammates and CI can find this skill."));
156169
156511
  }
156170
156512
  } catch (err) {
156171
156513
  const message = err instanceof Error ? err.message : String(err);
156172
- process.stderr.write(chalk29.red(`Link failed: ${message}
156514
+ process.stderr.write(chalk30.red(`Link failed: ${message}
156173
156515
  `));
156174
156516
  process.exit(1);
156175
156517
  }
156176
156518
  });
156177
156519
 
156178
156520
  // dist/commands/unlink.js
156179
- import { Command as Command33 } from "commander";
156180
- import chalk30 from "chalk";
156521
+ import { Command as Command34 } from "commander";
156522
+ import chalk31 from "chalk";
156181
156523
  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) => {
156524
+ import { resolve as resolve11, join as join16 } from "node:path";
156525
+ 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
156526
  try {
156185
- const dirPath = options.workspace ? resolve10(options.workspace) : directory ? resolve10(directory) : process.cwd();
156527
+ const dirPath = options.workspace ? resolve11(options.workspace) : directory ? resolve11(directory) : process.cwd();
156186
156528
  if (!existsSync15(dirPath) || !statSync7(dirPath).isDirectory()) {
156187
- process.stderr.write(chalk30.red(`Error: "${dirPath}" is not a valid directory
156529
+ process.stderr.write(chalk31.red(`Error: "${dirPath}" is not a valid directory
156188
156530
  `));
156189
156531
  process.exit(1);
156190
156532
  }
156191
156533
  const manifest = loadWorkspace(dirPath);
156192
156534
  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")}
156535
+ process.stderr.write(chalk31.red("Error: No workspace manifest found at this directory.\n"));
156536
+ process.stderr.write(chalk31.dim(` Looked for: ${join16(dirPath, ".skillvault-publisher", "workspace.json")}
156195
156537
  `));
156196
- process.stderr.write(chalk30.dim(" Run `skillvault-publisher link` first to create one.\n"));
156538
+ process.stderr.write(chalk31.dim(" Run `skillvault-publisher link` first to create one.\n"));
156197
156539
  process.exit(1);
156198
156540
  }
156199
156541
  const { manifestPath } = workspaceRootsFor(dirPath);
@@ -156201,7 +156543,7 @@ var unlinkCommand = new Command33("unlink").description("Remove the workspace li
156201
156543
  rmSync2(manifestPath);
156202
156544
  } catch (err) {
156203
156545
  const message = err instanceof Error ? err.message : String(err);
156204
- process.stderr.write(chalk30.red(`Failed to remove manifest: ${message}
156546
+ process.stderr.write(chalk31.red(`Failed to remove manifest: ${message}
156205
156547
  `));
156206
156548
  process.exit(1);
156207
156549
  }
@@ -156213,25 +156555,25 @@ var unlinkCommand = new Command33("unlink").description("Remove the workspace li
156213
156555
  if (!options.keepRegistry) {
156214
156556
  unregisterWorkspace(dirPath);
156215
156557
  }
156216
- console.log(chalk30.green(`Unlinked "${manifest.skill_name}" (${manifest.capability_name})`));
156217
- console.log(chalk30.dim(` Directory: ${dirPath}`));
156558
+ console.log(chalk31.green(`Unlinked "${manifest.skill_name}" (${manifest.capability_name})`));
156559
+ console.log(chalk31.dim(` Directory: ${dirPath}`));
156218
156560
  if (options.keepRegistry) {
156219
- console.log(chalk30.dim(" Registry entry kept (--keep-registry)"));
156561
+ console.log(chalk31.dim(" Registry entry kept (--keep-registry)"));
156220
156562
  }
156221
156563
  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."));
156564
+ console.log(chalk31.dim(" Note: SKILL.md and source files are untouched."));
156565
+ console.log(chalk31.dim(" Note: The skill on the server is NOT deleted. Use `skill-delete` for that."));
156224
156566
  } catch (err) {
156225
156567
  const message = err instanceof Error ? err.message : String(err);
156226
- process.stderr.write(chalk30.red(`Unlink failed: ${message}
156568
+ process.stderr.write(chalk31.red(`Unlink failed: ${message}
156227
156569
  `));
156228
156570
  process.exit(1);
156229
156571
  }
156230
156572
  });
156231
156573
 
156232
156574
  // dist/commands/workspaces.js
156233
- import { Command as Command34 } from "commander";
156234
- import chalk31 from "chalk";
156575
+ import { Command as Command35 } from "commander";
156576
+ import chalk32 from "chalk";
156235
156577
  function formatDate(iso) {
156236
156578
  if (!iso)
156237
156579
  return "-";
@@ -156266,8 +156608,8 @@ function listAction(options) {
156266
156608
  return;
156267
156609
  }
156268
156610
  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."));
156611
+ console.log(chalk32.dim("No workspaces linked."));
156612
+ console.log(chalk32.dim(" Run `skillvault-publisher link` from a skill source directory to create one."));
156271
156613
  return;
156272
156614
  }
156273
156615
  const pathWidth = Math.min(Math.max(20, ...filtered.map((w) => w.path.length)), 50);
@@ -156275,27 +156617,27 @@ function listAction(options) {
156275
156617
  const pubWidth = Math.max(10, ...filtered.map((w) => w.publisher_id.length));
156276
156618
  console.log();
156277
156619
  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))}`);
156620
+ console.log(` ${chalk32.dim(header)}`);
156621
+ console.log(` ${chalk32.dim("\u2500".repeat(header.length))}`);
156280
156622
  for (const w of filtered) {
156281
156623
  const isOther = currentAccount !== null && w.publisher_id !== currentAccount;
156282
156624
  const path = w.path.length > pathWidth ? "\u2026" + w.path.slice(-(pathWidth - 1)) : w.path;
156283
156625
  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
156626
  if (isOther) {
156285
- console.log(` ${chalk31.dim(row + " [other account]")}`);
156627
+ console.log(` ${chalk32.dim(row + " [other account]")}`);
156286
156628
  } else {
156287
156629
  console.log(` ${row}`);
156288
156630
  }
156289
156631
  }
156290
156632
  console.log();
156291
- console.log(chalk31.dim(` ${filtered.length} workspace${filtered.length === 1 ? "" : "s"}` + (options.current ? " (filtered to current account)" : "")));
156633
+ console.log(chalk32.dim(` ${filtered.length} workspace${filtered.length === 1 ? "" : "s"}` + (options.current ? " (filtered to current account)" : "")));
156292
156634
  }
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) => {
156635
+ 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
156636
  try {
156295
156637
  listAction(options);
156296
156638
  } catch (err) {
156297
156639
  const message = err instanceof Error ? err.message : String(err);
156298
- process.stderr.write(chalk31.red(`Error: ${message}
156640
+ process.stderr.write(chalk32.red(`Error: ${message}
156299
156641
  `));
156300
156642
  process.exit(1);
156301
156643
  }
@@ -156311,28 +156653,28 @@ workspacesCommand.command("find").description("Print the absolute path of a work
156311
156653
  console.log(match.path);
156312
156654
  } catch (err) {
156313
156655
  const message = err instanceof Error ? err.message : String(err);
156314
- process.stderr.write(chalk31.red(`Error: ${message}
156656
+ process.stderr.write(chalk32.red(`Error: ${message}
156315
156657
  `));
156316
156658
  process.exit(1);
156317
156659
  }
156318
156660
  });
156319
156661
 
156320
156662
  // dist/commands/team.js
156321
- import { Command as Command35 } from "commander";
156322
- import chalk32 from "chalk";
156663
+ import { Command as Command36 } from "commander";
156664
+ import chalk33 from "chalk";
156323
156665
  function formatRole(role) {
156324
156666
  if (role === "owner")
156325
- return chalk32.green("owner");
156667
+ return chalk33.green("owner");
156326
156668
  if (role === "admin")
156327
- return chalk32.cyan("admin");
156328
- return chalk32.dim("member");
156669
+ return chalk33.cyan("admin");
156670
+ return chalk33.dim("member");
156329
156671
  }
156330
156672
  function formatStatus(status) {
156331
156673
  if (status === "active")
156332
- return chalk32.green("active");
156674
+ return chalk33.green("active");
156333
156675
  if (status === "pending")
156334
- return chalk32.yellow("pending");
156335
- return chalk32.dim(status);
156676
+ return chalk33.yellow("pending");
156677
+ return chalk33.dim(status);
156336
156678
  }
156337
156679
  function pad3(s, n) {
156338
156680
  const visible = s.replace(/\x1b\[[0-9;]*m/g, "");
@@ -156340,7 +156682,7 @@ function pad3(s, n) {
156340
156682
  return s;
156341
156683
  return s + " ".repeat(n - visible.length);
156342
156684
  }
156343
- var teamCommand = new Command35("team").description("Manage your publisher team members").option("--json", "Output as JSON").action(async (options) => {
156685
+ var teamCommand = new Command36("team").description("Manage your publisher team members").option("--json", "Output as JSON").action(async (options) => {
156344
156686
  try {
156345
156687
  const ctx = requireSession();
156346
156688
  const data = await sessionFetch(ctx, `/publishers/${ctx.publisherId}/team`);
@@ -156351,27 +156693,27 @@ var teamCommand = new Command35("team").description("Manage your publisher team
156351
156693
  }
156352
156694
  if (members.length === 0) {
156353
156695
  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]"));
156696
+ console.log(chalk33.dim(" No team members yet. Invite someone:"));
156697
+ console.log(chalk33.cyan(" skillvault-publisher team add <email> [--role member|admin]"));
156356
156698
  console.log();
156357
156699
  return;
156358
156700
  }
156359
156701
  console.log();
156360
- console.log(chalk32.bold(` Team members (${members.length})`));
156702
+ console.log(chalk33.bold(` Team members (${members.length})`));
156361
156703
  console.log();
156362
- const header = `${pad3(chalk32.dim("Email"), 36)} ${pad3(chalk32.dim("Role"), 14)} ${pad3(chalk32.dim("Status"), 14)} ${chalk32.dim("Member ID")}`;
156704
+ const header = `${pad3(chalk33.dim("Email"), 36)} ${pad3(chalk33.dim("Role"), 14)} ${pad3(chalk33.dim("Status"), 14)} ${chalk33.dim("Member ID")}`;
156363
156705
  console.log(` ${header}`);
156364
- console.log(` ${chalk32.dim("\u2500".repeat(80))}`);
156706
+ console.log(` ${chalk33.dim("\u2500".repeat(80))}`);
156365
156707
  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)}`;
156708
+ const row = `${pad3(m.email, 36)} ${pad3(formatRole(m.role), 14)} ${pad3(formatStatus(m.status), 14)} ${chalk33.dim(m.id)}`;
156367
156709
  console.log(` ${row}`);
156368
156710
  }
156369
156711
  console.log();
156370
- console.log(chalk32.dim(` Logged in as publisher ${ctx.publisherId}`));
156712
+ console.log(chalk33.dim(` Logged in as publisher ${ctx.publisherId}`));
156371
156713
  console.log();
156372
156714
  } catch (err) {
156373
156715
  const message = err instanceof Error ? err.message : String(err);
156374
- process.stderr.write(chalk32.red(`team list failed: ${message}
156716
+ process.stderr.write(chalk33.red(`team list failed: ${message}
156375
156717
  `));
156376
156718
  process.exit(1);
156377
156719
  }
@@ -156379,7 +156721,7 @@ var teamCommand = new Command35("team").description("Manage your publisher team
156379
156721
  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
156722
  try {
156381
156723
  if (!["member", "admin"].includes(options.role)) {
156382
- process.stderr.write(chalk32.red(`Invalid role "${options.role}". Use --role member or --role admin.
156724
+ process.stderr.write(chalk33.red(`Invalid role "${options.role}". Use --role member or --role admin.
156383
156725
  `));
156384
156726
  process.exit(1);
156385
156727
  }
@@ -156393,17 +156735,17 @@ teamCommand.command("add").description("Invite someone to your publisher team. S
156393
156735
  return;
156394
156736
  }
156395
156737
  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)}`));
156738
+ console.log(chalk33.green(` \u2713 Invited ${email} as ${formatRole(options.role)}`));
156739
+ console.log(chalk33.dim(` Member ID: ${member.id}`));
156740
+ console.log(chalk33.dim(` Status: ${formatStatus(member.status)}`));
156399
156741
  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}`));
156742
+ console.log(chalk33.dim(" A magic-link invitation email has been sent. The new member can"));
156743
+ console.log(chalk33.dim(" click the link to activate, then run:"));
156744
+ console.log(chalk33.cyan(` skillvault-publisher login --email ${email}`));
156403
156745
  console.log();
156404
156746
  } catch (err) {
156405
156747
  const message = err instanceof Error ? err.message : String(err);
156406
- process.stderr.write(chalk32.red(`team add failed: ${message}
156748
+ process.stderr.write(chalk33.red(`team add failed: ${message}
156407
156749
  `));
156408
156750
  process.exit(1);
156409
156751
  }
@@ -156415,30 +156757,30 @@ teamCommand.command("remove").description("Remove a team member by email or memb
156415
156757
  const members = listData.members || [];
156416
156758
  const member = members.find((m) => m.id === target || m.email === target);
156417
156759
  if (!member) {
156418
- process.stderr.write(chalk32.red(`No team member found matching "${target}".
156760
+ process.stderr.write(chalk33.red(`No team member found matching "${target}".
156419
156761
  `));
156420
- process.stderr.write(chalk32.dim("Run `skillvault-publisher team` to see the current list.\n"));
156762
+ process.stderr.write(chalk33.dim("Run `skillvault-publisher team` to see the current list.\n"));
156421
156763
  process.exit(1);
156422
156764
  }
156423
156765
  if (member.role === "owner") {
156424
- process.stderr.write(chalk32.red("Cannot remove the owner of a publisher account.\n"));
156766
+ process.stderr.write(chalk33.red("Cannot remove the owner of a publisher account.\n"));
156425
156767
  process.exit(1);
156426
156768
  }
156427
156769
  if (member.status === "removed") {
156428
- process.stderr.write(chalk32.yellow(`${member.email} is already removed.
156770
+ process.stderr.write(chalk33.yellow(`${member.email} is already removed.
156429
156771
  `));
156430
156772
  process.exit(0);
156431
156773
  }
156432
156774
  if (!options.yes) {
156433
156775
  console.log();
156434
- console.log(chalk32.yellow.bold(" Warning: ") + "This will revoke " + chalk32.bold(member.email) + `'s access to publisher ${ctx.publisherId}.`);
156776
+ console.log(chalk33.yellow.bold(" Warning: ") + "This will revoke " + chalk33.bold(member.email) + `'s access to publisher ${ctx.publisherId}.`);
156435
156777
  console.log();
156436
- console.log(` Email: ${chalk32.cyan(member.email)}`);
156778
+ console.log(` Email: ${chalk33.cyan(member.email)}`);
156437
156779
  console.log(` Role: ${formatRole(member.role)}`);
156438
156780
  console.log(` Status: ${formatStatus(member.status)}`);
156439
- console.log(` Added: ${chalk32.dim(new Date(member.created_at).toLocaleDateString())}`);
156781
+ console.log(` Added: ${chalk33.dim(new Date(member.created_at).toLocaleDateString())}`);
156440
156782
  console.log();
156441
- console.log(chalk32.dim(" Add --yes to confirm."));
156783
+ console.log(chalk33.dim(" Add --yes to confirm."));
156442
156784
  console.log();
156443
156785
  process.exit(0);
156444
156786
  }
@@ -156447,10 +156789,10 @@ teamCommand.command("remove").description("Remove a team member by email or memb
156447
156789
  console.log(JSON.stringify({ removed: true, member_id: member.id, email: member.email }, null, 2));
156448
156790
  return;
156449
156791
  }
156450
- console.log(chalk32.green(` \u2713 Removed ${member.email} from the team`));
156792
+ console.log(chalk33.green(` \u2713 Removed ${member.email} from the team`));
156451
156793
  } catch (err) {
156452
156794
  const message = err instanceof Error ? err.message : String(err);
156453
- process.stderr.write(chalk32.red(`team remove failed: ${message}
156795
+ process.stderr.write(chalk33.red(`team remove failed: ${message}
156454
156796
  `));
156455
156797
  process.exit(1);
156456
156798
  }
@@ -156459,7 +156801,7 @@ teamCommand.command("remove").description("Remove a team member by email or memb
156459
156801
  // dist/index.js
156460
156802
  var __dirname2 = dirname5(fileURLToPath(import.meta.url));
156461
156803
  var pkg = JSON.parse(readFileSync18(join17(__dirname2, "..", "package.json"), "utf8"));
156462
- var program = new Command36();
156804
+ var program = new Command37();
156463
156805
  program.name("skillvault-publisher").description("SkillVault publisher CLI \u2014 publish, manage, and distribute encrypted skills").version(pkg.version).addHelpText("after", `
156464
156806
 
156465
156807
  Getting Started:
@@ -156492,6 +156834,7 @@ program.addCommand(sessionCleanupCommand);
156492
156834
  program.addCommand(skillDeleteCommand);
156493
156835
  program.addCommand(skillStatusCommand);
156494
156836
  program.addCommand(skillUnarchiveCommand);
156837
+ program.addCommand(skillAclCommand);
156495
156838
  program.addCommand(grantsCommand);
156496
156839
  program.addCommand(revokeGrantCommand);
156497
156840
  program.addCommand(customersCommand);