skillvault-publisher 0.11.2 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +411 -114
- package/package.json +6 -2
- package/dist/commands/analytics.js +0 -75
- package/dist/commands/audit.js +0 -96
- package/dist/commands/changelog.js +0 -78
- package/dist/commands/check-session.js +0 -117
- package/dist/commands/customers.js +0 -53
- package/dist/commands/grants.js +0 -69
- package/dist/commands/info.js +0 -30
- package/dist/commands/init.js +0 -83
- package/dist/commands/investigate.js +0 -455
- package/dist/commands/invite.js +0 -198
- package/dist/commands/licenses.js +0 -65
- package/dist/commands/link.js +0 -112
- package/dist/commands/list.js +0 -80
- package/dist/commands/login.js +0 -137
- package/dist/commands/logout.js +0 -11
- package/dist/commands/publish-all.js +0 -336
- package/dist/commands/publish.js +0 -341
- package/dist/commands/register.js +0 -118
- package/dist/commands/report.js +0 -45
- package/dist/commands/revoke-grant.js +0 -49
- package/dist/commands/scan-output.js +0 -201
- package/dist/commands/search.js +0 -89
- package/dist/commands/session-cleanup.js +0 -108
- package/dist/commands/session-common.js +0 -180
- package/dist/commands/session-keepalive.js +0 -215
- package/dist/commands/skill-delete.js +0 -58
- package/dist/commands/skill-status.js +0 -63
- package/dist/commands/skill-unarchive.js +0 -51
- package/dist/commands/unlink.js +0 -67
- package/dist/commands/update.js +0 -221
- package/dist/commands/watchtower.js +0 -109
- package/dist/commands/watermark-decode.js +0 -105
- package/dist/commands/webhook.js +0 -77
- package/dist/commands/whoami.js +0 -118
- package/dist/commands/workspaces.js +0 -108
- package/dist/credentials.js +0 -185
- package/dist/fingerprint.js +0 -51
- package/dist/grant-cache.js +0 -112
- package/dist/hooks-manager.js +0 -202
- package/dist/pdf-report.js +0 -265
- package/dist/projects-registry.js +0 -192
- package/dist/publisher-workspace.js +0 -165
- package/dist/publisher-workspaces-registry.js +0 -133
- package/dist/scope.js +0 -100
- package/dist/session.js +0 -103
package/dist/index.js
CHANGED
|
@@ -237,10 +237,10 @@ var require_utils = __commonJS({
|
|
|
237
237
|
sum += a.length;
|
|
238
238
|
}
|
|
239
239
|
const res = new Uint8Array(sum);
|
|
240
|
-
for (let i = 0,
|
|
240
|
+
for (let i = 0, pad4 = 0; i < arrays.length; i++) {
|
|
241
241
|
const a = arrays[i];
|
|
242
|
-
res.set(a,
|
|
243
|
-
|
|
242
|
+
res.set(a, pad4);
|
|
243
|
+
pad4 += a.length;
|
|
244
244
|
}
|
|
245
245
|
return res;
|
|
246
246
|
}
|
|
@@ -1769,10 +1769,10 @@ var require_utils2 = __commonJS({
|
|
|
1769
1769
|
sum += a.length;
|
|
1770
1770
|
}
|
|
1771
1771
|
const res = new Uint8Array(sum);
|
|
1772
|
-
for (let i = 0,
|
|
1772
|
+
for (let i = 0, pad4 = 0; i < arrays.length; i++) {
|
|
1773
1773
|
const a = arrays[i];
|
|
1774
|
-
res.set(a,
|
|
1775
|
-
|
|
1774
|
+
res.set(a, pad4);
|
|
1775
|
+
pad4 += a.length;
|
|
1776
1776
|
}
|
|
1777
1777
|
return res;
|
|
1778
1778
|
}
|
|
@@ -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(
|
|
3895
|
-
|
|
3894
|
+
return value instanceof P ? value : new P(function(resolve11) {
|
|
3895
|
+
resolve11(value);
|
|
3896
3896
|
});
|
|
3897
3897
|
}
|
|
3898
|
-
return new (P || (P = Promise))(function(
|
|
3898
|
+
return new (P || (P = Promise))(function(resolve11, 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 ?
|
|
3914
|
+
result.done ? resolve11(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(
|
|
4106
|
-
v = o[n](v), settle(
|
|
4105
|
+
return new Promise(function(resolve11, reject) {
|
|
4106
|
+
v = o[n](v), settle(resolve11, reject, v.done, v.value);
|
|
4107
4107
|
});
|
|
4108
4108
|
};
|
|
4109
4109
|
}
|
|
4110
|
-
function settle(
|
|
4110
|
+
function settle(resolve11, reject, d, v) {
|
|
4111
4111
|
Promise.resolve(v).then(function(v2) {
|
|
4112
|
-
|
|
4112
|
+
resolve11({ 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(
|
|
5057
|
+
child = new nativePromise(function(resolve11, reject) {
|
|
5058
5058
|
parent2.then(function(value) {
|
|
5059
|
-
|
|
5059
|
+
resolve11(_clone(value, depth2 - 1));
|
|
5060
5060
|
}, function(err) {
|
|
5061
5061
|
reject(_clone(err, depth2 - 1));
|
|
5062
5062
|
});
|
|
@@ -145431,7 +145431,7 @@ var require_pdfkit = __commonJS({
|
|
|
145431
145431
|
return `${this.ref.id} 0 R`;
|
|
145432
145432
|
}
|
|
145433
145433
|
};
|
|
145434
|
-
var
|
|
145434
|
+
var pad4 = (str, length) => (Array(length + 1).join("0") + str).slice(-length);
|
|
145435
145435
|
var escapableRe = /[\n\r\t\b\f()\\]/g;
|
|
145436
145436
|
var escapable = {
|
|
145437
145437
|
"\n": "\\n",
|
|
@@ -145487,7 +145487,7 @@ var require_pdfkit = __commonJS({
|
|
|
145487
145487
|
} else if (object instanceof PDFAbstractReference || object instanceof PDFTree || object instanceof SpotColor) {
|
|
145488
145488
|
return object.toString();
|
|
145489
145489
|
} else if (object instanceof Date) {
|
|
145490
|
-
let string = `D:${
|
|
145490
|
+
let string = `D:${pad4(object.getUTCFullYear(), 4)}` + pad4(object.getUTCMonth() + 1, 2) + pad4(object.getUTCDate(), 2) + pad4(object.getUTCHours(), 2) + pad4(object.getUTCMinutes(), 2) + pad4(object.getUTCSeconds(), 2) + "Z";
|
|
145491
145491
|
if (encryptFn) {
|
|
145492
145492
|
string = encryptFn(Buffer.from(string, "ascii")).toString("binary");
|
|
145493
145493
|
string = string.replace(escapableRe, (c) => escapable[c]);
|
|
@@ -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((
|
|
151598
|
+
return new Promise((resolve11, 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",
|
|
151745
|
+
stream.on("finish", resolve11);
|
|
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
|
|
151807
|
+
import { Command as Command36 } 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";
|
|
@@ -151813,6 +151813,7 @@ import { dirname as dirname5, join as join17 } from "node:path";
|
|
|
151813
151813
|
import { Command } from "commander";
|
|
151814
151814
|
import chalk from "chalk";
|
|
151815
151815
|
import { randomBytes } from "node:crypto";
|
|
151816
|
+
import { createInterface } from "node:readline/promises";
|
|
151816
151817
|
|
|
151817
151818
|
// dist/credentials.js
|
|
151818
151819
|
import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, rmSync, existsSync as existsSync2, openSync as openSync2, closeSync as closeSync2, unlinkSync as unlinkSync2 } from "node:fs";
|
|
@@ -151861,7 +151862,43 @@ function removeKeypair() {
|
|
|
151861
151862
|
}
|
|
151862
151863
|
|
|
151863
151864
|
// dist/commands/login.js
|
|
151864
|
-
|
|
151865
|
+
async function chooseFromMultiple(available, publisherFlag) {
|
|
151866
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
151867
|
+
if (publisherFlag) {
|
|
151868
|
+
const match = available.find((p) => p.publisher_id === publisherFlag);
|
|
151869
|
+
if (match)
|
|
151870
|
+
return match;
|
|
151871
|
+
console.error(chalk.red(`Publisher ${publisherFlag} not in your accessible list.`));
|
|
151872
|
+
}
|
|
151873
|
+
console.error(chalk.red("Multiple publishers available for this email. Pass --publisher <id> to choose:"));
|
|
151874
|
+
for (const p of available) {
|
|
151875
|
+
console.error(chalk.dim(` --publisher ${p.publisher_id} (${p.publisher_name || "unnamed"}, role: ${p.role})`));
|
|
151876
|
+
}
|
|
151877
|
+
process.exit(1);
|
|
151878
|
+
}
|
|
151879
|
+
console.log();
|
|
151880
|
+
console.log(chalk.bold(" This email has access to multiple publishers:"));
|
|
151881
|
+
console.log();
|
|
151882
|
+
available.forEach((p, idx) => {
|
|
151883
|
+
const roleColor = p.role === "owner" ? chalk.green : p.role === "admin" ? chalk.cyan : chalk.dim;
|
|
151884
|
+
console.log(` ${chalk.bold(`[${idx + 1}]`)} ${p.publisher_name || p.publisher_id} ${chalk.dim(`(${p.publisher_id})`)} ${roleColor(p.role)}`);
|
|
151885
|
+
});
|
|
151886
|
+
console.log();
|
|
151887
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
151888
|
+
try {
|
|
151889
|
+
while (true) {
|
|
151890
|
+
const answer = (await rl.question(` Pick a publisher [1-${available.length}]: `)).trim();
|
|
151891
|
+
const idx = parseInt(answer, 10);
|
|
151892
|
+
if (Number.isInteger(idx) && idx >= 1 && idx <= available.length) {
|
|
151893
|
+
return available[idx - 1];
|
|
151894
|
+
}
|
|
151895
|
+
console.log(chalk.red(` Invalid choice \u2014 enter a number between 1 and ${available.length}`));
|
|
151896
|
+
}
|
|
151897
|
+
} finally {
|
|
151898
|
+
rl.close();
|
|
151899
|
+
}
|
|
151900
|
+
}
|
|
151901
|
+
var loginCommand = new Command("login").description("Authenticate with the Skill Vault server").option("--email <email>", "Your publisher account email").option("--token <token>", "Authenticate with a publisher session JWT (Bearer token from dashboard)").option("--license-key <key>", "Authenticate with a license key (customer)").option("--code <code>", "Redeem an invite code after login").option("--publisher <id>", "Disambiguate when your email has access to multiple publisher accounts").option("--server <url>", "Server URL", "https://api.getskillvault.com").action(async (options) => {
|
|
151865
151902
|
try {
|
|
151866
151903
|
const serverUrl = options.server;
|
|
151867
151904
|
const publisherToken = options.token || process.env.SKILLVAULT_TOKEN || null;
|
|
@@ -151881,22 +151918,52 @@ var loginCommand = new Command("login").description("Authenticate with the Skill
|
|
|
151881
151918
|
publisherIdentity = { publisher_id: me.publisher_id, email: me.email, name: me.name };
|
|
151882
151919
|
} else if (options.email) {
|
|
151883
151920
|
console.log(chalk.dim(`Authenticating as ${options.email}...`));
|
|
151921
|
+
const body2 = { email: options.email };
|
|
151922
|
+
if (options.publisher)
|
|
151923
|
+
body2.publisher_id = options.publisher;
|
|
151884
151924
|
const loginRes = await fetch(`${serverUrl}/auth/login`, {
|
|
151885
151925
|
method: "POST",
|
|
151886
151926
|
headers: { "Content-Type": "application/json" },
|
|
151887
|
-
body: JSON.stringify(
|
|
151927
|
+
body: JSON.stringify(body2)
|
|
151888
151928
|
});
|
|
151889
151929
|
if (!loginRes.ok) {
|
|
151890
|
-
const err = await loginRes.json().catch(() =>
|
|
151891
|
-
|
|
151930
|
+
const err = await loginRes.json().catch(() => null);
|
|
151931
|
+
const reason = err?.message || err?.error || loginRes.statusText || `HTTP ${loginRes.status}`;
|
|
151932
|
+
console.error(chalk.red(`Login failed: ${reason}`));
|
|
151892
151933
|
if (loginRes.status === 404) {
|
|
151893
151934
|
console.error(chalk.dim("No account found. Create one at https://app.getskillvault.com/login"));
|
|
151935
|
+
console.error(chalk.dim("Or ask a team owner to add your email via `skillvault-publisher team add`."));
|
|
151894
151936
|
}
|
|
151895
151937
|
process.exit(1);
|
|
151896
151938
|
}
|
|
151897
151939
|
const loginData = await loginRes.json();
|
|
151898
|
-
|
|
151899
|
-
|
|
151940
|
+
if ("multiple_choice" in loginData && loginData.multiple_choice) {
|
|
151941
|
+
const chosen = await chooseFromMultiple(loginData.available_publishers, options.publisher);
|
|
151942
|
+
const retryRes = await fetch(`${serverUrl}/auth/login`, {
|
|
151943
|
+
method: "POST",
|
|
151944
|
+
headers: { "Content-Type": "application/json" },
|
|
151945
|
+
body: JSON.stringify({ email: options.email, publisher_id: chosen.publisher_id })
|
|
151946
|
+
});
|
|
151947
|
+
if (!retryRes.ok) {
|
|
151948
|
+
const err = await retryRes.json().catch(() => null);
|
|
151949
|
+
const reason = err?.message || err?.error || retryRes.statusText;
|
|
151950
|
+
console.error(chalk.red(`Login retry failed: ${reason}`));
|
|
151951
|
+
process.exit(1);
|
|
151952
|
+
}
|
|
151953
|
+
const retryData = await retryRes.json();
|
|
151954
|
+
sessionToken = retryData.session_token;
|
|
151955
|
+
publisherIdentity = { publisher_id: retryData.publisher_id, email: retryData.email, name: retryData.name };
|
|
151956
|
+
if (retryData.role && retryData.role !== "owner") {
|
|
151957
|
+
console.log(chalk.dim(` Logged in as ${chalk.bold(retryData.role)} of ${chosen.publisher_name || retryData.publisher_id}`));
|
|
151958
|
+
}
|
|
151959
|
+
} else {
|
|
151960
|
+
const single = loginData;
|
|
151961
|
+
sessionToken = single.session_token;
|
|
151962
|
+
publisherIdentity = { publisher_id: single.publisher_id, email: single.email, name: single.name };
|
|
151963
|
+
if (single.role && single.role !== "owner") {
|
|
151964
|
+
console.log(chalk.dim(` Logged in as ${chalk.bold(single.role)} of ${single.publisher_id}`));
|
|
151965
|
+
}
|
|
151966
|
+
}
|
|
151900
151967
|
} else if (!options.licenseKey) {
|
|
151901
151968
|
console.error(chalk.red("Publisher identity required."));
|
|
151902
151969
|
console.error("");
|
|
@@ -152003,7 +152070,7 @@ var registerCommand = new Command2("register").description("Create a new publish
|
|
|
152003
152070
|
let verified = false;
|
|
152004
152071
|
const maxAttempts = 120;
|
|
152005
152072
|
for (let i = 0; i < maxAttempts; i++) {
|
|
152006
|
-
await new Promise((
|
|
152073
|
+
await new Promise((resolve11) => setTimeout(resolve11, 3e3));
|
|
152007
152074
|
try {
|
|
152008
152075
|
const statusRes = await fetch(`${serverUrl}/publishers/${publisher_id}/verification-status`);
|
|
152009
152076
|
if (statusRes.ok) {
|
|
@@ -152094,7 +152161,7 @@ var logoutCommand = new Command3("logout").description("Remove stored credential
|
|
|
152094
152161
|
import { Command as Command4 } from "commander";
|
|
152095
152162
|
import chalk5 from "chalk";
|
|
152096
152163
|
import { readFileSync as readFileSync6, existsSync as existsSync6, statSync as statSync3 } from "node:fs";
|
|
152097
|
-
import { resolve as
|
|
152164
|
+
import { resolve as resolve5, join as join6 } from "node:path";
|
|
152098
152165
|
import { createHash as createHash3 } from "node:crypto";
|
|
152099
152166
|
|
|
152100
152167
|
// ../shared/dist/crypto.js
|
|
@@ -152212,7 +152279,7 @@ function readVaultMetadata(data) {
|
|
|
152212
152279
|
// ../shared/dist/packer.js
|
|
152213
152280
|
import { readFileSync as readFileSync3, readdirSync, existsSync as existsSync3 } from "node:fs";
|
|
152214
152281
|
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "node:fs";
|
|
152215
|
-
import { join as join3, relative } from "node:path";
|
|
152282
|
+
import { join as join3, relative, resolve as resolve2, isAbsolute, sep } from "node:path";
|
|
152216
152283
|
import { createHash as createHash2 } from "node:crypto";
|
|
152217
152284
|
var DEFAULT_IGNORE = /* @__PURE__ */ new Set([
|
|
152218
152285
|
"node_modules",
|
|
@@ -152245,10 +152312,12 @@ function collectFiles(dir, base, ignoreSet) {
|
|
|
152245
152312
|
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
152246
152313
|
if (ignoreSet.has(entry.name))
|
|
152247
152314
|
continue;
|
|
152315
|
+
if (entry.isSymbolicLink())
|
|
152316
|
+
continue;
|
|
152248
152317
|
const fullPath = join3(dir, entry.name);
|
|
152249
152318
|
if (entry.isDirectory()) {
|
|
152250
152319
|
entries.push(...collectFiles(fullPath, base, ignoreSet));
|
|
152251
|
-
} else {
|
|
152320
|
+
} else if (entry.isFile()) {
|
|
152252
152321
|
entries.push({
|
|
152253
152322
|
path: relative(base, fullPath),
|
|
152254
152323
|
content: readFileSync3(fullPath)
|
|
@@ -152529,17 +152598,57 @@ function extractPotentialHeartbeats(content) {
|
|
|
152529
152598
|
return values;
|
|
152530
152599
|
}
|
|
152531
152600
|
|
|
152601
|
+
// ../shared/dist/skill-name.js
|
|
152602
|
+
var MAX_SKILL_NAME_LENGTH = 64;
|
|
152603
|
+
var ALLOWED_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
|
|
152604
|
+
var InvalidSkillNameError = class extends Error {
|
|
152605
|
+
reason;
|
|
152606
|
+
name;
|
|
152607
|
+
constructor(reason, name) {
|
|
152608
|
+
super(`invalid skill name: ${reason}`);
|
|
152609
|
+
this.reason = reason;
|
|
152610
|
+
this.name = name;
|
|
152611
|
+
this.name = "InvalidSkillNameError";
|
|
152612
|
+
}
|
|
152613
|
+
};
|
|
152614
|
+
function validateSkillName(name) {
|
|
152615
|
+
if (typeof name !== "string") {
|
|
152616
|
+
throw new InvalidSkillNameError("must be a string", String(name));
|
|
152617
|
+
}
|
|
152618
|
+
if (name.length === 0) {
|
|
152619
|
+
throw new InvalidSkillNameError("must not be empty", name);
|
|
152620
|
+
}
|
|
152621
|
+
if (name.length > MAX_SKILL_NAME_LENGTH) {
|
|
152622
|
+
throw new InvalidSkillNameError(`exceeds ${MAX_SKILL_NAME_LENGTH} characters`, name);
|
|
152623
|
+
}
|
|
152624
|
+
for (let i = 0; i < name.length; i++) {
|
|
152625
|
+
const code = name.charCodeAt(i);
|
|
152626
|
+
if (code < 32 || code === 127) {
|
|
152627
|
+
throw new InvalidSkillNameError(`contains control character (0x${code.toString(16).padStart(2, "0")})`, name);
|
|
152628
|
+
}
|
|
152629
|
+
}
|
|
152630
|
+
if (name.includes("..")) {
|
|
152631
|
+
throw new InvalidSkillNameError('contains parent-directory segment "..", which is not allowed in path components', name);
|
|
152632
|
+
}
|
|
152633
|
+
if (name.includes("/") || name.includes("\\")) {
|
|
152634
|
+
throw new InvalidSkillNameError("contains a path separator, which is not allowed in skill names", name);
|
|
152635
|
+
}
|
|
152636
|
+
if (!ALLOWED_PATTERN.test(name)) {
|
|
152637
|
+
throw new InvalidSkillNameError(`must match ${ALLOWED_PATTERN.source} (ASCII letters, digits, dashes, underscores; must start with a letter or digit)`, name);
|
|
152638
|
+
}
|
|
152639
|
+
}
|
|
152640
|
+
|
|
152532
152641
|
// dist/session.js
|
|
152533
152642
|
import chalk4 from "chalk";
|
|
152534
152643
|
|
|
152535
152644
|
// dist/publisher-workspace.js
|
|
152536
152645
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, existsSync as existsSync4 } from "node:fs";
|
|
152537
|
-
import { join as join4, dirname as dirname3, resolve as
|
|
152646
|
+
import { join as join4, dirname as dirname3, resolve as resolve3 } from "node:path";
|
|
152538
152647
|
import { homedir as homedir3 } from "node:os";
|
|
152539
152648
|
var MANIFEST_DIRNAME = ".skillvault-publisher";
|
|
152540
152649
|
var MANIFEST_FILENAME = "workspace.json";
|
|
152541
152650
|
function workspaceRootsFor(dir) {
|
|
152542
|
-
const abs =
|
|
152651
|
+
const abs = resolve3(dir);
|
|
152543
152652
|
const manifestPath = join4(abs, MANIFEST_DIRNAME, MANIFEST_FILENAME);
|
|
152544
152653
|
return {
|
|
152545
152654
|
dir: abs,
|
|
@@ -152586,7 +152695,7 @@ function saveWorkspace(dir, manifest) {
|
|
|
152586
152695
|
writeFileSync4(manifestPath, JSON.stringify(manifest, null, 2), { mode: 420 });
|
|
152587
152696
|
}
|
|
152588
152697
|
function findWorkspace(cwd) {
|
|
152589
|
-
const start =
|
|
152698
|
+
const start = resolve3(cwd ?? process.cwd());
|
|
152590
152699
|
const home = homedir3();
|
|
152591
152700
|
let dir = start;
|
|
152592
152701
|
while (true) {
|
|
@@ -152658,8 +152767,9 @@ async function sessionFetch(ctx, path, options) {
|
|
|
152658
152767
|
process.exit(1);
|
|
152659
152768
|
}
|
|
152660
152769
|
if (!res.ok) {
|
|
152661
|
-
const err = await res.json().catch(() =>
|
|
152662
|
-
|
|
152770
|
+
const err = await res.json().catch(() => null);
|
|
152771
|
+
const reason = err?.message || err?.error || res.statusText || `HTTP ${res.status}`;
|
|
152772
|
+
process.stderr.write(chalk4.red(`Error: ${reason}
|
|
152663
152773
|
`));
|
|
152664
152774
|
process.exit(1);
|
|
152665
152775
|
}
|
|
@@ -152696,7 +152806,7 @@ function requireCommandContext(opts = {}) {
|
|
|
152696
152806
|
|
|
152697
152807
|
// dist/publisher-workspaces-registry.js
|
|
152698
152808
|
import { mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5, existsSync as existsSync5, statSync as statSync2 } from "node:fs";
|
|
152699
|
-
import { dirname as dirname4, join as join5, resolve as
|
|
152809
|
+
import { dirname as dirname4, join as join5, resolve as resolve4 } from "node:path";
|
|
152700
152810
|
import { homedir as homedir4 } from "node:os";
|
|
152701
152811
|
var REGISTRY_VERSION = 1;
|
|
152702
152812
|
var MANIFEST_DIRNAME2 = ".skillvault-publisher";
|
|
@@ -152730,7 +152840,7 @@ function listWorkspaces() {
|
|
|
152730
152840
|
const live = [];
|
|
152731
152841
|
let pruned = false;
|
|
152732
152842
|
for (const entry of reg.workspaces) {
|
|
152733
|
-
const path =
|
|
152843
|
+
const path = resolve4(entry.path);
|
|
152734
152844
|
let stillThere = false;
|
|
152735
152845
|
try {
|
|
152736
152846
|
const st = statSync2(path);
|
|
@@ -152755,8 +152865,8 @@ function listWorkspaces() {
|
|
|
152755
152865
|
}
|
|
152756
152866
|
function registerWorkspace(entry) {
|
|
152757
152867
|
const reg = readRegistry();
|
|
152758
|
-
const normalized = { ...entry, path:
|
|
152759
|
-
const idx = reg.workspaces.findIndex((w) =>
|
|
152868
|
+
const normalized = { ...entry, path: resolve4(entry.path) };
|
|
152869
|
+
const idx = reg.workspaces.findIndex((w) => resolve4(w.path) === normalized.path);
|
|
152760
152870
|
if (idx >= 0) {
|
|
152761
152871
|
reg.workspaces[idx] = normalized;
|
|
152762
152872
|
} else {
|
|
@@ -152766,9 +152876,9 @@ function registerWorkspace(entry) {
|
|
|
152766
152876
|
}
|
|
152767
152877
|
function unregisterWorkspace(path) {
|
|
152768
152878
|
const reg = readRegistry();
|
|
152769
|
-
const target =
|
|
152879
|
+
const target = resolve4(path);
|
|
152770
152880
|
const before = reg.workspaces.length;
|
|
152771
|
-
reg.workspaces = reg.workspaces.filter((w) =>
|
|
152881
|
+
reg.workspaces = reg.workspaces.filter((w) => resolve4(w.path) !== target);
|
|
152772
152882
|
if (reg.workspaces.length !== before)
|
|
152773
152883
|
writeRegistry(reg);
|
|
152774
152884
|
}
|
|
@@ -152798,9 +152908,9 @@ var publishCommand = new Command4("publish").description("Encrypt and publish a
|
|
|
152798
152908
|
const config = ctx.config;
|
|
152799
152909
|
const workspaceCtx = resolveWorkspaceContext({
|
|
152800
152910
|
workspaceFlag: options.workspace,
|
|
152801
|
-
cwd: directory ?
|
|
152911
|
+
cwd: directory ? resolve5(directory) : process.cwd()
|
|
152802
152912
|
});
|
|
152803
|
-
const dirPath = options.workspace ?
|
|
152913
|
+
const dirPath = options.workspace ? resolve5(options.workspace) : directory ? resolve5(directory) : workspaceCtx?.dir ?? process.cwd();
|
|
152804
152914
|
if (!existsSync6(dirPath) || !statSync3(dirPath).isDirectory()) {
|
|
152805
152915
|
process.stderr.write(chalk5.red(`Error: "${dirPath}" is not a valid directory
|
|
152806
152916
|
`));
|
|
@@ -152821,6 +152931,17 @@ var publishCommand = new Command4("publish").description("Encrypt and publish a
|
|
|
152821
152931
|
process.stderr.write(chalk5.red("Error: Skill name required \u2014 set in SKILL.md frontmatter or use --name\n"));
|
|
152822
152932
|
process.exit(1);
|
|
152823
152933
|
}
|
|
152934
|
+
try {
|
|
152935
|
+
validateSkillName(skillName);
|
|
152936
|
+
} catch (err) {
|
|
152937
|
+
if (err instanceof InvalidSkillNameError) {
|
|
152938
|
+
process.stderr.write(chalk5.red(`Error: ${err.message}
|
|
152939
|
+
`));
|
|
152940
|
+
process.stderr.write(chalk5.dim("Skill names must be ASCII letters, digits, dashes, or underscores (1-64 chars).\n"));
|
|
152941
|
+
process.exit(1);
|
|
152942
|
+
}
|
|
152943
|
+
throw err;
|
|
152944
|
+
}
|
|
152824
152945
|
if (!description) {
|
|
152825
152946
|
process.stderr.write(chalk5.red("Error: Description required \u2014 set in SKILL.md frontmatter or use --description\n"));
|
|
152826
152947
|
process.exit(1);
|
|
@@ -153092,7 +153213,7 @@ import chalk6 from "chalk";
|
|
|
153092
153213
|
var searchCommand = new Command5("search").description("Search for skills in the registry").argument("<query>", "Search query").option("--type <type>", "Filter by capability type").option("--publisher <publisher>", "Filter by publisher name or ID").option("--mine", "Show only your own published skills").option("--json", "Output results as JSON").action(async (query, options) => {
|
|
153093
153214
|
try {
|
|
153094
153215
|
const config = getConfig();
|
|
153095
|
-
const serverUrl = config?.server_url ?? "
|
|
153216
|
+
const serverUrl = config?.server_url ?? "https://api.getskillvault.com";
|
|
153096
153217
|
let publisherFilter = options.publisher;
|
|
153097
153218
|
if (options.mine) {
|
|
153098
153219
|
if (!config) {
|
|
@@ -153253,7 +153374,7 @@ var licensesCommand = new Command7("licenses").description("List your active ski
|
|
|
153253
153374
|
import { Command as Command8 } from "commander";
|
|
153254
153375
|
import chalk9 from "chalk";
|
|
153255
153376
|
import { readFileSync as readFileSync8, existsSync as existsSync7, statSync as statSync4 } from "node:fs";
|
|
153256
|
-
import { resolve as
|
|
153377
|
+
import { resolve as resolve6, join as join7 } from "node:path";
|
|
153257
153378
|
import { createHash as createHash4 } from "node:crypto";
|
|
153258
153379
|
function parseFrontmatter2(content) {
|
|
153259
153380
|
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
@@ -153304,7 +153425,7 @@ var updateCommand = new Command8("update").description("Push a new version of an
|
|
|
153304
153425
|
try {
|
|
153305
153426
|
const ctx = requireSession();
|
|
153306
153427
|
const config = ctx.config;
|
|
153307
|
-
const dirPath =
|
|
153428
|
+
const dirPath = resolve6(directory);
|
|
153308
153429
|
if (!existsSync7(dirPath) || !statSync4(dirPath).isDirectory()) {
|
|
153309
153430
|
process.stderr.write(chalk9.red(`Error: "${dirPath}" is not a valid directory
|
|
153310
153431
|
`));
|
|
@@ -153487,6 +153608,14 @@ var whoamiCommand = new Command9("whoami").description("Show current user, activ
|
|
|
153487
153608
|
const ctx = requireSession();
|
|
153488
153609
|
const config = ctx.config;
|
|
153489
153610
|
const fingerprint = getDeviceFingerprint();
|
|
153611
|
+
let authMe = null;
|
|
153612
|
+
try {
|
|
153613
|
+
const meRes = await fetch(`${config.server_url}/auth/me`, { headers: ctx.headers });
|
|
153614
|
+
if (meRes.ok) {
|
|
153615
|
+
authMe = await meRes.json();
|
|
153616
|
+
}
|
|
153617
|
+
} catch {
|
|
153618
|
+
}
|
|
153490
153619
|
const response = await fetch(`${config.server_url}/agent/status?agent_id=${encodeURIComponent(config.agent_id)}`, {
|
|
153491
153620
|
headers: ctx.headers
|
|
153492
153621
|
});
|
|
@@ -153495,29 +153624,48 @@ var whoamiCommand = new Command9("whoami").description("Show current user, activ
|
|
|
153495
153624
|
console.log(JSON.stringify({
|
|
153496
153625
|
host_id: config.host_id,
|
|
153497
153626
|
agent_id: config.agent_id,
|
|
153498
|
-
...
|
|
153499
|
-
|
|
153627
|
+
...authMe ? {
|
|
153628
|
+
publisher_id: authMe.publisher_id,
|
|
153629
|
+
publisher_name: authMe.publisher_name,
|
|
153630
|
+
email: authMe.email,
|
|
153631
|
+
role: authMe.role,
|
|
153632
|
+
is_owner: authMe.is_owner
|
|
153633
|
+
} : {
|
|
153634
|
+
...config.publisher_id ? { publisher_id: config.publisher_id } : {},
|
|
153635
|
+
...config.email ? { email: config.email } : {}
|
|
153636
|
+
},
|
|
153500
153637
|
device_fingerprint: fingerprint,
|
|
153501
153638
|
server_url: config.server_url,
|
|
153502
|
-
server_status: "
|
|
153639
|
+
server_status: "agent_status_unreachable"
|
|
153503
153640
|
}, null, 2));
|
|
153504
153641
|
return;
|
|
153505
153642
|
}
|
|
153506
153643
|
console.log();
|
|
153507
153644
|
console.log(chalk10.bold(" Skill Vault Identity"));
|
|
153508
153645
|
console.log();
|
|
153509
|
-
if (
|
|
153510
|
-
|
|
153511
|
-
|
|
153512
|
-
|
|
153513
|
-
|
|
153646
|
+
if (authMe) {
|
|
153647
|
+
const roleColor = authMe.role === "owner" ? chalk10.green : authMe.role === "admin" ? chalk10.cyan : chalk10.dim;
|
|
153648
|
+
const roleLabel = authMe.role || (authMe.is_owner ? "owner" : "member");
|
|
153649
|
+
console.log(` ${"You:".padEnd(22)} ${authMe.email} ${roleColor(`(${roleLabel})`)}`);
|
|
153650
|
+
const publisherDisplay = authMe.publisher_name ? `${authMe.publisher_name} ${chalk10.dim(`(${authMe.publisher_id})`)}` : authMe.publisher_id;
|
|
153651
|
+
console.log(` ${"Publisher:".padEnd(22)} ${publisherDisplay}`);
|
|
153652
|
+
if (!authMe.is_owner) {
|
|
153653
|
+
console.log(` ${chalk10.dim(" (you are a team member of this publisher)".padEnd(22))}`);
|
|
153654
|
+
}
|
|
153655
|
+
} else {
|
|
153656
|
+
if (config.publisher_id) {
|
|
153657
|
+
console.log(` ${"Publisher ID:".padEnd(22)} ${config.publisher_id}`);
|
|
153658
|
+
}
|
|
153659
|
+
if (config.email) {
|
|
153660
|
+
console.log(` ${"Email:".padEnd(22)} ${config.email}`);
|
|
153661
|
+
}
|
|
153514
153662
|
}
|
|
153515
153663
|
console.log(` ${"Host ID:".padEnd(22)} ${config.host_id}`);
|
|
153516
153664
|
console.log(` ${"Agent ID:".padEnd(22)} ${config.agent_id}`);
|
|
153517
153665
|
console.log(` ${"Device Fingerprint:".padEnd(22)} ${fingerprint}`);
|
|
153518
153666
|
console.log(` ${"Server:".padEnd(22)} ${config.server_url}`);
|
|
153519
153667
|
console.log();
|
|
153520
|
-
console.log(chalk10.yellow(`
|
|
153668
|
+
console.log(chalk10.yellow(` Status endpoint unreachable (${response.status}); skipped grants list.`));
|
|
153521
153669
|
console.log();
|
|
153522
153670
|
return;
|
|
153523
153671
|
}
|
|
@@ -153538,11 +153686,22 @@ var whoamiCommand = new Command9("whoami").description("Show current user, activ
|
|
|
153538
153686
|
console.log();
|
|
153539
153687
|
console.log(chalk10.bold(" Skill Vault Identity"));
|
|
153540
153688
|
console.log();
|
|
153541
|
-
if (
|
|
153542
|
-
|
|
153543
|
-
|
|
153544
|
-
|
|
153545
|
-
|
|
153689
|
+
if (authMe) {
|
|
153690
|
+
const roleColor = authMe.role === "owner" ? chalk10.green : authMe.role === "admin" ? chalk10.cyan : chalk10.dim;
|
|
153691
|
+
const roleLabel = authMe.role || (authMe.is_owner ? "owner" : "member");
|
|
153692
|
+
console.log(` ${"You:".padEnd(22)} ${authMe.email} ${roleColor(`(${roleLabel})`)}`);
|
|
153693
|
+
const publisherDisplay = authMe.publisher_name ? `${authMe.publisher_name} ${chalk10.dim(`(${authMe.publisher_id})`)}` : authMe.publisher_id;
|
|
153694
|
+
console.log(` ${"Publisher:".padEnd(22)} ${publisherDisplay}`);
|
|
153695
|
+
if (!authMe.is_owner) {
|
|
153696
|
+
console.log(` ${chalk10.dim(" (you are a team member of this publisher)".padEnd(22))}`);
|
|
153697
|
+
}
|
|
153698
|
+
} else {
|
|
153699
|
+
if (config.publisher_id) {
|
|
153700
|
+
console.log(` ${"Publisher ID:".padEnd(22)} ${config.publisher_id}`);
|
|
153701
|
+
}
|
|
153702
|
+
if (config.email) {
|
|
153703
|
+
console.log(` ${"Email:".padEnd(22)} ${config.email}`);
|
|
153704
|
+
}
|
|
153546
153705
|
}
|
|
153547
153706
|
console.log(` ${"Host ID:".padEnd(22)} ${data.host_id ?? config.host_id}`);
|
|
153548
153707
|
console.log(` ${"Agent ID:".padEnd(22)} ${data.agent_id ?? config.agent_id}`);
|
|
@@ -153627,7 +153786,7 @@ var reportCommand = new Command10("report").description("Report a telemetry even
|
|
|
153627
153786
|
import { Command as Command11 } from "commander";
|
|
153628
153787
|
import chalk12 from "chalk";
|
|
153629
153788
|
import { existsSync as existsSync8, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6 } from "node:fs";
|
|
153630
|
-
import { resolve as
|
|
153789
|
+
import { resolve as resolve7, join as join8 } from "node:path";
|
|
153631
153790
|
function toTitleCase(name) {
|
|
153632
153791
|
return name.split(/[-_]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
153633
153792
|
}
|
|
@@ -153664,7 +153823,7 @@ var initCommand = new Command11("init").description("Scaffold a new skill direct
|
|
|
153664
153823
|
process.stderr.write(chalk12.dim(" skillvault-publisher init my-awesome-skill\n"));
|
|
153665
153824
|
process.exit(1);
|
|
153666
153825
|
}
|
|
153667
|
-
const dirPath =
|
|
153826
|
+
const dirPath = resolve7(name);
|
|
153668
153827
|
if (existsSync8(dirPath)) {
|
|
153669
153828
|
process.stderr.write(chalk12.red(`Error: Directory "${name}" already exists.
|
|
153670
153829
|
`));
|
|
@@ -153779,11 +153938,9 @@ var listCommand = new Command13("list").description("List your published skills"
|
|
|
153779
153938
|
headers: ctx.headers
|
|
153780
153939
|
});
|
|
153781
153940
|
if (!response.ok) {
|
|
153782
|
-
const err = await response.json().catch(() =>
|
|
153783
|
-
|
|
153784
|
-
|
|
153785
|
-
}));
|
|
153786
|
-
process.stderr.write(chalk14.red(`Failed to list skills: ${err.message}
|
|
153941
|
+
const err = await response.json().catch(() => null);
|
|
153942
|
+
const reason = err?.message || err?.error || response.statusText || `HTTP ${response.status}`;
|
|
153943
|
+
process.stderr.write(chalk14.red(`Failed to list skills: ${reason}
|
|
153787
153944
|
`));
|
|
153788
153945
|
process.exit(1);
|
|
153789
153946
|
}
|
|
@@ -153842,7 +153999,7 @@ var listCommand = new Command13("list").description("List your published skills"
|
|
|
153842
153999
|
import { Command as Command14 } from "commander";
|
|
153843
154000
|
import chalk15 from "chalk";
|
|
153844
154001
|
import { readFileSync as readFileSync9, existsSync as existsSync9, statSync as statSync5, readdirSync as readdirSync2 } from "node:fs";
|
|
153845
|
-
import { resolve as
|
|
154002
|
+
import { resolve as resolve8, join as join9, basename } from "node:path";
|
|
153846
154003
|
import { createHash as createHash6 } from "node:crypto";
|
|
153847
154004
|
function parseFrontmatter3(content) {
|
|
153848
154005
|
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
@@ -153990,7 +154147,7 @@ var publishAllCommand = new Command14("publish-all").description("Discover and p
|
|
|
153990
154147
|
skillDirs = entries.map((e) => e.path);
|
|
153991
154148
|
console.log(chalk15.dim(`Iterating ${skillDirs.length} registered workspace${skillDirs.length === 1 ? "" : "s"}` + (options.current ? " (current account only)" : "") + "..."));
|
|
153992
154149
|
} else {
|
|
153993
|
-
const rootDir =
|
|
154150
|
+
const rootDir = resolve8(directory);
|
|
153994
154151
|
if (!existsSync9(rootDir) || !statSync5(rootDir).isDirectory()) {
|
|
153995
154152
|
process.stderr.write(chalk15.red(`Error: "${rootDir}" is not a valid directory
|
|
153996
154153
|
`));
|
|
@@ -154270,12 +154427,12 @@ var inviteListCommand = new Command15("list").description("List all invites").op
|
|
|
154270
154427
|
}
|
|
154271
154428
|
console.log(`Invites (${invites.length}):
|
|
154272
154429
|
`);
|
|
154273
|
-
const
|
|
154274
|
-
console.log(chalk16.dim(`${
|
|
154430
|
+
const pad4 = (s, n) => s.padEnd(n).slice(0, n);
|
|
154431
|
+
console.log(chalk16.dim(`${pad4("Code", 14)} ${pad4("Email", 30)} ${pad4("Status", 10)} ${pad4("Skills", 25)} ${pad4("Created", 12)}`));
|
|
154275
154432
|
console.log(chalk16.dim("\u2500".repeat(95)));
|
|
154276
154433
|
for (const inv of invites) {
|
|
154277
154434
|
const statusColor = inv.status === "redeemed" ? chalk16.green : inv.status === "expired" ? chalk16.dim : chalk16.yellow;
|
|
154278
|
-
console.log(`${
|
|
154435
|
+
console.log(`${pad4(inv.code, 14)} ${pad4(inv.customer_email || "(open)", 30)} ${statusColor(pad4(inv.status, 10))} ${pad4(inv.capabilities.join(", ") || "(none)", 25)} ${pad4(new Date(inv.created_at).toLocaleDateString(), 12)}`);
|
|
154279
154436
|
}
|
|
154280
154437
|
} catch (err) {
|
|
154281
154438
|
process.stderr.write(chalk16.red(`Error: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -155014,18 +155171,18 @@ var grantsCommand = new Command23("grants").description("List capability grants
|
|
|
155014
155171
|
console.log();
|
|
155015
155172
|
console.log(chalk20.bold(" Capability Grants"));
|
|
155016
155173
|
console.log();
|
|
155017
|
-
const
|
|
155018
|
-
const header = `${
|
|
155174
|
+
const pad4 = (s, n) => s.padEnd(n).slice(0, n);
|
|
155175
|
+
const header = `${pad4("Grant ID", 22)} ${pad4("Skill", 24)} ${pad4("Customer", 22)} ${pad4("Status", 10)} ${pad4("Granted", 12)} ${"Expires"}`;
|
|
155019
155176
|
console.log(` ${chalk20.dim(header)}`);
|
|
155020
155177
|
console.log(` ${chalk20.dim("\u2500".repeat(header.length))}`);
|
|
155021
155178
|
for (const grant of grants) {
|
|
155022
155179
|
const statusColor = grant.status === "active" ? chalk20.green : grant.status === "revoked" ? chalk20.red : grant.status === "expired" ? chalk20.yellow : chalk20.white;
|
|
155023
155180
|
const row = [
|
|
155024
|
-
|
|
155025
|
-
|
|
155026
|
-
|
|
155027
|
-
statusColor(
|
|
155028
|
-
|
|
155181
|
+
pad4(grant.id, 22),
|
|
155182
|
+
pad4(grant.capability, 24),
|
|
155183
|
+
pad4(grant.customer_id || "-", 22),
|
|
155184
|
+
statusColor(pad4(grant.status, 10)),
|
|
155185
|
+
pad4(new Date(grant.created_at).toLocaleDateString(), 12),
|
|
155029
155186
|
grant.expires_at ? new Date(grant.expires_at).toLocaleDateString() : "never"
|
|
155030
155187
|
].join(" ");
|
|
155031
155188
|
console.log(` ${row}`);
|
|
@@ -155101,18 +155258,18 @@ var customersCommand = new Command25("customers").description("List your custome
|
|
|
155101
155258
|
console.log();
|
|
155102
155259
|
console.log(chalk22.bold(" Customers"));
|
|
155103
155260
|
console.log();
|
|
155104
|
-
const
|
|
155105
|
-
const header = `${
|
|
155261
|
+
const pad4 = (s, n) => s.padEnd(n).slice(0, n);
|
|
155262
|
+
const header = `${pad4("Email", 32)} ${pad4("Skills", 8)} ${pad4("Loads", 8)} ${pad4("Status", 10)} Last Active`;
|
|
155106
155263
|
console.log(` ${chalk22.dim(header)}`);
|
|
155107
155264
|
console.log(` ${chalk22.dim("\u2500".repeat(header.length))}`);
|
|
155108
155265
|
for (const c of customers) {
|
|
155109
155266
|
const statusColor = c.status === "active" ? chalk22.green : chalk22.dim;
|
|
155110
155267
|
const lastActive = c.last_active_at ? new Date(c.last_active_at).toLocaleDateString() : chalk22.dim("never");
|
|
155111
155268
|
const row = [
|
|
155112
|
-
|
|
155113
|
-
|
|
155114
|
-
|
|
155115
|
-
statusColor(
|
|
155269
|
+
pad4(c.email, 32),
|
|
155270
|
+
pad4(String(c.skills_count), 8),
|
|
155271
|
+
pad4(String(c.total_loads), 8),
|
|
155272
|
+
statusColor(pad4(c.status, 10)),
|
|
155116
155273
|
lastActive
|
|
155117
155274
|
].join(" ");
|
|
155118
155275
|
console.log(` ${row}`);
|
|
@@ -155164,15 +155321,15 @@ var analyticsCommand = new Command26("analytics").description("View publisher an
|
|
|
155164
155321
|
console.log();
|
|
155165
155322
|
console.log(chalk23.bold(" Top Skills"));
|
|
155166
155323
|
console.log();
|
|
155167
|
-
const
|
|
155168
|
-
const header = `${
|
|
155324
|
+
const pad4 = (s, n) => s.padEnd(n).slice(0, n);
|
|
155325
|
+
const header = `${pad4("Skill", 28)} ${pad4("Decryptions", 14)} Active Licenses`;
|
|
155169
155326
|
console.log(` ${chalk23.dim(header)}`);
|
|
155170
155327
|
console.log(` ${chalk23.dim("\u2500".repeat(header.length))}`);
|
|
155171
155328
|
for (const skill of data.top_skills) {
|
|
155172
155329
|
const stats = statsMap.get(skill.name);
|
|
155173
155330
|
const row = [
|
|
155174
|
-
|
|
155175
|
-
|
|
155331
|
+
pad4(skill.name, 28),
|
|
155332
|
+
pad4(String(skill.decryptions), 14),
|
|
155176
155333
|
String(stats?.active_licenses ?? "-")
|
|
155177
155334
|
].join(" ");
|
|
155178
155335
|
console.log(` ${row}`);
|
|
@@ -155305,8 +155462,8 @@ var auditCommand = new Command28("audit").description("View audit log events").o
|
|
|
155305
155462
|
console.log();
|
|
155306
155463
|
console.log(chalk25.bold(" Audit Log"));
|
|
155307
155464
|
console.log();
|
|
155308
|
-
const
|
|
155309
|
-
const header = `${
|
|
155465
|
+
const pad4 = (s, n) => s.padEnd(n).slice(0, n);
|
|
155466
|
+
const header = `${pad4("Event Type", 22)} ${pad4("Skill", 24)} ${pad4("Agent", 20)} ${"Time"}`;
|
|
155310
155467
|
console.log(` ${chalk25.dim(header)}`);
|
|
155311
155468
|
console.log(` ${chalk25.dim("\u2500".repeat(header.length))}`);
|
|
155312
155469
|
for (const event of events) {
|
|
@@ -155314,9 +155471,9 @@ var auditCommand = new Command28("audit").description("View audit log events").o
|
|
|
155314
155471
|
const agent = event.agent_id ? event.agent_id.slice(0, 18) : "-";
|
|
155315
155472
|
const time = new Date(event.created_at).toLocaleString();
|
|
155316
155473
|
const row = [
|
|
155317
|
-
|
|
155318
|
-
|
|
155319
|
-
|
|
155474
|
+
pad4(event.event_type, 22),
|
|
155475
|
+
pad4(skill, 24),
|
|
155476
|
+
pad4(agent, 20),
|
|
155320
155477
|
time
|
|
155321
155478
|
].join(" ");
|
|
155322
155479
|
console.log(` ${row}`);
|
|
@@ -155771,7 +155928,7 @@ var watchtowerCommand = new Command30("watchtower").description("Watchtower secu
|
|
|
155771
155928
|
return;
|
|
155772
155929
|
}
|
|
155773
155930
|
const { summary } = data;
|
|
155774
|
-
const
|
|
155931
|
+
const pad4 = (s, n) => s.padEnd(n).slice(0, n);
|
|
155775
155932
|
console.log();
|
|
155776
155933
|
console.log(chalk27.bold(" Watchtower \u2014 Security Overview"));
|
|
155777
155934
|
console.log();
|
|
@@ -155780,28 +155937,28 @@ var watchtowerCommand = new Command30("watchtower").description("Watchtower secu
|
|
|
155780
155937
|
console.log();
|
|
155781
155938
|
console.log(chalk27.bold(" Flagged Customers"));
|
|
155782
155939
|
console.log();
|
|
155783
|
-
const header = `${
|
|
155940
|
+
const header = `${pad4("Agent ID", 20)} ${pad4("Risk Score", 12)} ${pad4("Level", 10)} ${pad4("Strikes", 9)} ${pad4("Status", 12)} Skills`;
|
|
155784
155941
|
console.log(` ${chalk27.dim(header)}`);
|
|
155785
155942
|
console.log(` ${chalk27.dim("\u2500".repeat(header.length))}`);
|
|
155786
155943
|
for (const c of data.flagged_customers) {
|
|
155787
155944
|
const agentShort = c.agent_id.length > 18 ? c.agent_id.slice(0, 18) + "\u2026" : c.agent_id;
|
|
155788
155945
|
let levelColored;
|
|
155789
155946
|
if (c.risk_level === "critical") {
|
|
155790
|
-
levelColored = chalk27.red.bold(
|
|
155947
|
+
levelColored = chalk27.red.bold(pad4(c.risk_level, 10));
|
|
155791
155948
|
} else if (c.risk_level === "high") {
|
|
155792
|
-
levelColored = chalk27.red(
|
|
155949
|
+
levelColored = chalk27.red(pad4(c.risk_level, 10));
|
|
155793
155950
|
} else if (c.risk_level === "medium") {
|
|
155794
|
-
levelColored = chalk27.yellow(
|
|
155951
|
+
levelColored = chalk27.yellow(pad4(c.risk_level, 10));
|
|
155795
155952
|
} else {
|
|
155796
|
-
levelColored = chalk27.dim(
|
|
155953
|
+
levelColored = chalk27.dim(pad4(c.risk_level, 10));
|
|
155797
155954
|
}
|
|
155798
|
-
const statusColored = c.status === "suspended" ? chalk27.red(
|
|
155955
|
+
const statusColored = c.status === "suspended" ? chalk27.red(pad4(c.status, 12)) : pad4(c.status, 12);
|
|
155799
155956
|
const skills = c.capabilities.length > 0 ? c.capabilities.join(", ") : chalk27.dim("none");
|
|
155800
155957
|
const row = [
|
|
155801
|
-
|
|
155802
|
-
|
|
155958
|
+
pad4(agentShort, 20),
|
|
155959
|
+
pad4(String(c.risk_score), 12),
|
|
155803
155960
|
levelColored,
|
|
155804
|
-
|
|
155961
|
+
pad4(String(c.strike_count), 9),
|
|
155805
155962
|
statusColored,
|
|
155806
155963
|
skills
|
|
155807
155964
|
].join(" ");
|
|
@@ -155812,7 +155969,7 @@ var watchtowerCommand = new Command30("watchtower").description("Watchtower secu
|
|
|
155812
155969
|
console.log();
|
|
155813
155970
|
console.log(chalk27.bold(" Recent Security Events"));
|
|
155814
155971
|
console.log();
|
|
155815
|
-
const header = `${
|
|
155972
|
+
const header = `${pad4("Event Type", 28)} ${pad4("Skill", 24)} ${pad4("Agent", 20)} Time`;
|
|
155816
155973
|
console.log(` ${chalk27.dim(header)}`);
|
|
155817
155974
|
console.log(` ${chalk27.dim("\u2500".repeat(header.length))}`);
|
|
155818
155975
|
const events = data.recent_events.slice(0, 10);
|
|
@@ -155821,9 +155978,9 @@ var watchtowerCommand = new Command30("watchtower").description("Watchtower secu
|
|
|
155821
155978
|
const agent = e.agent_id ? e.agent_id.slice(0, 18) : chalk27.dim("-");
|
|
155822
155979
|
const time = new Date(e.created_at).toLocaleString();
|
|
155823
155980
|
const row = [
|
|
155824
|
-
|
|
155825
|
-
|
|
155826
|
-
|
|
155981
|
+
pad4(e.event_type, 28),
|
|
155982
|
+
pad4(skill, 24),
|
|
155983
|
+
pad4(agent, 20),
|
|
155827
155984
|
time
|
|
155828
155985
|
].join(" ");
|
|
155829
155986
|
console.log(` ${row}`);
|
|
@@ -155936,7 +156093,7 @@ var watermarkDecodeCommand = new Command31("watermark-decode").description("Anal
|
|
|
155936
156093
|
import { Command as Command32 } from "commander";
|
|
155937
156094
|
import chalk29 from "chalk";
|
|
155938
156095
|
import { existsSync as existsSync14, readFileSync as readFileSync17, statSync as statSync6 } from "node:fs";
|
|
155939
|
-
import { resolve as
|
|
156096
|
+
import { resolve as resolve9, join as join15 } from "node:path";
|
|
155940
156097
|
function parseFrontmatter4(content) {
|
|
155941
156098
|
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
155942
156099
|
if (!match)
|
|
@@ -155958,7 +156115,7 @@ function parseFrontmatter4(content) {
|
|
|
155958
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) => {
|
|
155959
156116
|
try {
|
|
155960
156117
|
const ctx = requireSession();
|
|
155961
|
-
const dirPath = options.workspace ?
|
|
156118
|
+
const dirPath = options.workspace ? resolve9(options.workspace) : directory ? resolve9(directory) : process.cwd();
|
|
155962
156119
|
if (!existsSync14(dirPath) || !statSync6(dirPath).isDirectory()) {
|
|
155963
156120
|
process.stderr.write(chalk29.red(`Error: "${dirPath}" is not a valid directory
|
|
155964
156121
|
`));
|
|
@@ -156022,10 +156179,10 @@ var linkCommand = new Command32("link").description("Link a skill source directo
|
|
|
156022
156179
|
import { Command as Command33 } from "commander";
|
|
156023
156180
|
import chalk30 from "chalk";
|
|
156024
156181
|
import { existsSync as existsSync15, rmSync as rmSync2, statSync as statSync7 } from "node:fs";
|
|
156025
|
-
import { resolve as
|
|
156182
|
+
import { resolve as resolve10, join as join16 } from "node:path";
|
|
156026
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) => {
|
|
156027
156184
|
try {
|
|
156028
|
-
const dirPath = options.workspace ?
|
|
156185
|
+
const dirPath = options.workspace ? resolve10(options.workspace) : directory ? resolve10(directory) : process.cwd();
|
|
156029
156186
|
if (!existsSync15(dirPath) || !statSync7(dirPath).isDirectory()) {
|
|
156030
156187
|
process.stderr.write(chalk30.red(`Error: "${dirPath}" is not a valid directory
|
|
156031
156188
|
`));
|
|
@@ -156160,10 +156317,149 @@ workspacesCommand.command("find").description("Print the absolute path of a work
|
|
|
156160
156317
|
}
|
|
156161
156318
|
});
|
|
156162
156319
|
|
|
156320
|
+
// dist/commands/team.js
|
|
156321
|
+
import { Command as Command35 } from "commander";
|
|
156322
|
+
import chalk32 from "chalk";
|
|
156323
|
+
function formatRole(role) {
|
|
156324
|
+
if (role === "owner")
|
|
156325
|
+
return chalk32.green("owner");
|
|
156326
|
+
if (role === "admin")
|
|
156327
|
+
return chalk32.cyan("admin");
|
|
156328
|
+
return chalk32.dim("member");
|
|
156329
|
+
}
|
|
156330
|
+
function formatStatus(status) {
|
|
156331
|
+
if (status === "active")
|
|
156332
|
+
return chalk32.green("active");
|
|
156333
|
+
if (status === "pending")
|
|
156334
|
+
return chalk32.yellow("pending");
|
|
156335
|
+
return chalk32.dim(status);
|
|
156336
|
+
}
|
|
156337
|
+
function pad3(s, n) {
|
|
156338
|
+
const visible = s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
156339
|
+
if (visible.length >= n)
|
|
156340
|
+
return s;
|
|
156341
|
+
return s + " ".repeat(n - visible.length);
|
|
156342
|
+
}
|
|
156343
|
+
var teamCommand = new Command35("team").description("Manage your publisher team members").option("--json", "Output as JSON").action(async (options) => {
|
|
156344
|
+
try {
|
|
156345
|
+
const ctx = requireSession();
|
|
156346
|
+
const data = await sessionFetch(ctx, `/publishers/${ctx.publisherId}/team`);
|
|
156347
|
+
const members = data.members || [];
|
|
156348
|
+
if (options.json) {
|
|
156349
|
+
console.log(JSON.stringify(members, null, 2));
|
|
156350
|
+
return;
|
|
156351
|
+
}
|
|
156352
|
+
if (members.length === 0) {
|
|
156353
|
+
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]"));
|
|
156356
|
+
console.log();
|
|
156357
|
+
return;
|
|
156358
|
+
}
|
|
156359
|
+
console.log();
|
|
156360
|
+
console.log(chalk32.bold(` Team members (${members.length})`));
|
|
156361
|
+
console.log();
|
|
156362
|
+
const header = `${pad3(chalk32.dim("Email"), 36)} ${pad3(chalk32.dim("Role"), 14)} ${pad3(chalk32.dim("Status"), 14)} ${chalk32.dim("Member ID")}`;
|
|
156363
|
+
console.log(` ${header}`);
|
|
156364
|
+
console.log(` ${chalk32.dim("\u2500".repeat(80))}`);
|
|
156365
|
+
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)}`;
|
|
156367
|
+
console.log(` ${row}`);
|
|
156368
|
+
}
|
|
156369
|
+
console.log();
|
|
156370
|
+
console.log(chalk32.dim(` Logged in as publisher ${ctx.publisherId}`));
|
|
156371
|
+
console.log();
|
|
156372
|
+
} catch (err) {
|
|
156373
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
156374
|
+
process.stderr.write(chalk32.red(`team list failed: ${message}
|
|
156375
|
+
`));
|
|
156376
|
+
process.exit(1);
|
|
156377
|
+
}
|
|
156378
|
+
});
|
|
156379
|
+
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
|
+
try {
|
|
156381
|
+
if (!["member", "admin"].includes(options.role)) {
|
|
156382
|
+
process.stderr.write(chalk32.red(`Invalid role "${options.role}". Use --role member or --role admin.
|
|
156383
|
+
`));
|
|
156384
|
+
process.exit(1);
|
|
156385
|
+
}
|
|
156386
|
+
const ctx = requireSession();
|
|
156387
|
+
const member = await sessionFetch(ctx, `/publishers/${ctx.publisherId}/team`, {
|
|
156388
|
+
method: "POST",
|
|
156389
|
+
body: { email, role: options.role, name: options.name || null }
|
|
156390
|
+
});
|
|
156391
|
+
if (options.json) {
|
|
156392
|
+
console.log(JSON.stringify(member, null, 2));
|
|
156393
|
+
return;
|
|
156394
|
+
}
|
|
156395
|
+
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)}`));
|
|
156399
|
+
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}`));
|
|
156403
|
+
console.log();
|
|
156404
|
+
} catch (err) {
|
|
156405
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
156406
|
+
process.stderr.write(chalk32.red(`team add failed: ${message}
|
|
156407
|
+
`));
|
|
156408
|
+
process.exit(1);
|
|
156409
|
+
}
|
|
156410
|
+
});
|
|
156411
|
+
teamCommand.command("remove").description("Remove a team member by email or member ID").argument("<email-or-id>", "The member email address or member ID (tm_xxx)").option("--yes", "Skip confirmation").option("--json", "Output as JSON").action(async (target, options) => {
|
|
156412
|
+
try {
|
|
156413
|
+
const ctx = requireSession();
|
|
156414
|
+
const listData = await sessionFetch(ctx, `/publishers/${ctx.publisherId}/team`);
|
|
156415
|
+
const members = listData.members || [];
|
|
156416
|
+
const member = members.find((m) => m.id === target || m.email === target);
|
|
156417
|
+
if (!member) {
|
|
156418
|
+
process.stderr.write(chalk32.red(`No team member found matching "${target}".
|
|
156419
|
+
`));
|
|
156420
|
+
process.stderr.write(chalk32.dim("Run `skillvault-publisher team` to see the current list.\n"));
|
|
156421
|
+
process.exit(1);
|
|
156422
|
+
}
|
|
156423
|
+
if (member.role === "owner") {
|
|
156424
|
+
process.stderr.write(chalk32.red("Cannot remove the owner of a publisher account.\n"));
|
|
156425
|
+
process.exit(1);
|
|
156426
|
+
}
|
|
156427
|
+
if (member.status === "removed") {
|
|
156428
|
+
process.stderr.write(chalk32.yellow(`${member.email} is already removed.
|
|
156429
|
+
`));
|
|
156430
|
+
process.exit(0);
|
|
156431
|
+
}
|
|
156432
|
+
if (!options.yes) {
|
|
156433
|
+
console.log();
|
|
156434
|
+
console.log(chalk32.yellow.bold(" Warning: ") + "This will revoke " + chalk32.bold(member.email) + `'s access to publisher ${ctx.publisherId}.`);
|
|
156435
|
+
console.log();
|
|
156436
|
+
console.log(` Email: ${chalk32.cyan(member.email)}`);
|
|
156437
|
+
console.log(` Role: ${formatRole(member.role)}`);
|
|
156438
|
+
console.log(` Status: ${formatStatus(member.status)}`);
|
|
156439
|
+
console.log(` Added: ${chalk32.dim(new Date(member.created_at).toLocaleDateString())}`);
|
|
156440
|
+
console.log();
|
|
156441
|
+
console.log(chalk32.dim(" Add --yes to confirm."));
|
|
156442
|
+
console.log();
|
|
156443
|
+
process.exit(0);
|
|
156444
|
+
}
|
|
156445
|
+
await sessionFetch(ctx, `/publishers/${ctx.publisherId}/team/${member.id}`, { method: "DELETE" });
|
|
156446
|
+
if (options.json) {
|
|
156447
|
+
console.log(JSON.stringify({ removed: true, member_id: member.id, email: member.email }, null, 2));
|
|
156448
|
+
return;
|
|
156449
|
+
}
|
|
156450
|
+
console.log(chalk32.green(` \u2713 Removed ${member.email} from the team`));
|
|
156451
|
+
} catch (err) {
|
|
156452
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
156453
|
+
process.stderr.write(chalk32.red(`team remove failed: ${message}
|
|
156454
|
+
`));
|
|
156455
|
+
process.exit(1);
|
|
156456
|
+
}
|
|
156457
|
+
});
|
|
156458
|
+
|
|
156163
156459
|
// dist/index.js
|
|
156164
156460
|
var __dirname2 = dirname5(fileURLToPath(import.meta.url));
|
|
156165
156461
|
var pkg = JSON.parse(readFileSync18(join17(__dirname2, "..", "package.json"), "utf8"));
|
|
156166
|
-
var program = new
|
|
156462
|
+
var program = new Command36();
|
|
156167
156463
|
program.name("skillvault-publisher").description("SkillVault publisher CLI \u2014 publish, manage, and distribute encrypted skills").version(pkg.version).addHelpText("after", `
|
|
156168
156464
|
|
|
156169
156465
|
Getting Started:
|
|
@@ -156208,6 +156504,7 @@ program.addCommand(watermarkDecodeCommand);
|
|
|
156208
156504
|
program.addCommand(linkCommand);
|
|
156209
156505
|
program.addCommand(unlinkCommand);
|
|
156210
156506
|
program.addCommand(workspacesCommand);
|
|
156507
|
+
program.addCommand(teamCommand);
|
|
156211
156508
|
program.parse();
|
|
156212
156509
|
/*! Bundled license information:
|
|
156213
156510
|
|