@cantemizyurek/skillz 0.1.8 → 0.1.10
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.cjs +498 -60
- package/dist/index.cjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -11282,6 +11282,262 @@ var scopeSchema = external_exports.enum(SCOPE_VALUES);
|
|
|
11282
11282
|
// src/index.ts
|
|
11283
11283
|
var import_commander = require("commander");
|
|
11284
11284
|
|
|
11285
|
+
// package.json
|
|
11286
|
+
var package_default = {
|
|
11287
|
+
name: "@cantemizyurek/skillz",
|
|
11288
|
+
version: "0.1.9",
|
|
11289
|
+
publishConfig: {
|
|
11290
|
+
access: "public"
|
|
11291
|
+
},
|
|
11292
|
+
files: [
|
|
11293
|
+
"dist"
|
|
11294
|
+
],
|
|
11295
|
+
type: "module",
|
|
11296
|
+
bin: {
|
|
11297
|
+
skillz: "./dist/index.cjs"
|
|
11298
|
+
},
|
|
11299
|
+
main: "./dist/index.cjs",
|
|
11300
|
+
types: "./dist/index.d.cts",
|
|
11301
|
+
exports: {
|
|
11302
|
+
".": {
|
|
11303
|
+
types: "./dist/index.d.cts",
|
|
11304
|
+
default: "./dist/index.cjs"
|
|
11305
|
+
}
|
|
11306
|
+
},
|
|
11307
|
+
scripts: {
|
|
11308
|
+
dev: "tsx src/index.ts",
|
|
11309
|
+
build: "tsup src/index.ts --format cjs --dts --sourcemap --clean",
|
|
11310
|
+
lint: "tsc --noEmit",
|
|
11311
|
+
test: "vitest run"
|
|
11312
|
+
},
|
|
11313
|
+
dependencies: {
|
|
11314
|
+
"@inquirer/prompts": "^7.3.2",
|
|
11315
|
+
"@vercel/blob": "^0.27.0",
|
|
11316
|
+
commander: "^13.1.0",
|
|
11317
|
+
tar: "^7.4.3",
|
|
11318
|
+
"tar-stream": "^3.1.7"
|
|
11319
|
+
},
|
|
11320
|
+
devDependencies: {
|
|
11321
|
+
"@cantemizyurek/shared": "workspace:*",
|
|
11322
|
+
"@types/node": "^22.13.9",
|
|
11323
|
+
tsup: "^8.4.0",
|
|
11324
|
+
tsx: "^4.19.3",
|
|
11325
|
+
typescript: "^5.7.0",
|
|
11326
|
+
vitest: "^3.0.7"
|
|
11327
|
+
}
|
|
11328
|
+
};
|
|
11329
|
+
|
|
11330
|
+
// src/auto-update.ts
|
|
11331
|
+
var DEFAULT_AUTO_UPDATE_INTERVAL_HOURS = 24;
|
|
11332
|
+
var MIN_AUTO_UPDATE_INTERVAL_HOURS = 1;
|
|
11333
|
+
var MAX_AUTO_UPDATE_INTERVAL_HOURS = 24 * 30;
|
|
11334
|
+
function resolveAutoUpdateSettings(config) {
|
|
11335
|
+
return {
|
|
11336
|
+
enabled: typeof config.autoUpdateEnabled === "boolean" ? config.autoUpdateEnabled : true,
|
|
11337
|
+
intervalHours: normalizeAutoUpdateInterval(config.autoUpdateIntervalHours),
|
|
11338
|
+
lastCheckedAt: typeof config.autoUpdateLastCheckedAt === "string" ? config.autoUpdateLastCheckedAt : void 0
|
|
11339
|
+
};
|
|
11340
|
+
}
|
|
11341
|
+
function shouldRunAutoUpdateNow(config, now = /* @__PURE__ */ new Date()) {
|
|
11342
|
+
const settings = resolveAutoUpdateSettings(config);
|
|
11343
|
+
if (!settings.enabled) {
|
|
11344
|
+
return false;
|
|
11345
|
+
}
|
|
11346
|
+
if (!settings.lastCheckedAt) {
|
|
11347
|
+
return true;
|
|
11348
|
+
}
|
|
11349
|
+
const lastCheckedAt = new Date(settings.lastCheckedAt);
|
|
11350
|
+
if (Number.isNaN(lastCheckedAt.getTime())) {
|
|
11351
|
+
return true;
|
|
11352
|
+
}
|
|
11353
|
+
const elapsedMs = now.getTime() - lastCheckedAt.getTime();
|
|
11354
|
+
if (elapsedMs < 0) {
|
|
11355
|
+
return true;
|
|
11356
|
+
}
|
|
11357
|
+
return elapsedMs >= settings.intervalHours * 60 * 60 * 1e3;
|
|
11358
|
+
}
|
|
11359
|
+
function parseAutoUpdateIntervalHours(input) {
|
|
11360
|
+
const parsed = Number(input);
|
|
11361
|
+
if (!Number.isFinite(parsed) || !Number.isInteger(parsed)) {
|
|
11362
|
+
throw new Error("Auto-update interval must be an integer number of hours");
|
|
11363
|
+
}
|
|
11364
|
+
if (parsed < MIN_AUTO_UPDATE_INTERVAL_HOURS || parsed > MAX_AUTO_UPDATE_INTERVAL_HOURS) {
|
|
11365
|
+
throw new Error(
|
|
11366
|
+
`Auto-update interval must be between ${MIN_AUTO_UPDATE_INTERVAL_HOURS} and ${MAX_AUTO_UPDATE_INTERVAL_HOURS} hours`
|
|
11367
|
+
);
|
|
11368
|
+
}
|
|
11369
|
+
return parsed;
|
|
11370
|
+
}
|
|
11371
|
+
function normalizeAutoUpdateInterval(input) {
|
|
11372
|
+
if (typeof input !== "number" || !Number.isFinite(input)) {
|
|
11373
|
+
return DEFAULT_AUTO_UPDATE_INTERVAL_HOURS;
|
|
11374
|
+
}
|
|
11375
|
+
const rounded = Math.round(input);
|
|
11376
|
+
if (rounded < MIN_AUTO_UPDATE_INTERVAL_HOURS) {
|
|
11377
|
+
return MIN_AUTO_UPDATE_INTERVAL_HOURS;
|
|
11378
|
+
}
|
|
11379
|
+
if (rounded > MAX_AUTO_UPDATE_INTERVAL_HOURS) {
|
|
11380
|
+
return MAX_AUTO_UPDATE_INTERVAL_HOURS;
|
|
11381
|
+
}
|
|
11382
|
+
return rounded;
|
|
11383
|
+
}
|
|
11384
|
+
|
|
11385
|
+
// src/cli-self-update.ts
|
|
11386
|
+
var import_node_child_process = require("child_process");
|
|
11387
|
+
var NPM_REGISTRY_BASE_URL = "https://registry.npmjs.org";
|
|
11388
|
+
var SUPPORTED_PACKAGE_MANAGERS = ["pnpm", "npm", "yarn", "bun"];
|
|
11389
|
+
async function runCliSelfUpdate(input) {
|
|
11390
|
+
const latestVersion = await fetchLatestPackageVersion(input.packageName);
|
|
11391
|
+
if (!shouldUpdateCli(input.currentVersion, latestVersion)) {
|
|
11392
|
+
return {
|
|
11393
|
+
latestVersion,
|
|
11394
|
+
updated: false
|
|
11395
|
+
};
|
|
11396
|
+
}
|
|
11397
|
+
const manager = await resolveInstalledPackageManager(
|
|
11398
|
+
input.preferredPackageManager ?? null
|
|
11399
|
+
);
|
|
11400
|
+
if (!manager) {
|
|
11401
|
+
throw new Error(
|
|
11402
|
+
"No supported package manager found (pnpm, npm, yarn, bun)"
|
|
11403
|
+
);
|
|
11404
|
+
}
|
|
11405
|
+
const installCommand = buildSelfUpdateInstallCommand(manager, input.packageName);
|
|
11406
|
+
await runCommand(installCommand.command, installCommand.args);
|
|
11407
|
+
return {
|
|
11408
|
+
latestVersion,
|
|
11409
|
+
updated: true,
|
|
11410
|
+
manager
|
|
11411
|
+
};
|
|
11412
|
+
}
|
|
11413
|
+
async function fetchLatestPackageVersion(packageName) {
|
|
11414
|
+
const encodedPackageName = encodeURIComponent(packageName);
|
|
11415
|
+
const response = await fetch(
|
|
11416
|
+
`${NPM_REGISTRY_BASE_URL}/${encodedPackageName}/latest`,
|
|
11417
|
+
{
|
|
11418
|
+
method: "GET",
|
|
11419
|
+
headers: {
|
|
11420
|
+
accept: "application/json"
|
|
11421
|
+
}
|
|
11422
|
+
}
|
|
11423
|
+
);
|
|
11424
|
+
if (!response.ok) {
|
|
11425
|
+
throw new Error(
|
|
11426
|
+
`Failed to check latest CLI version (status ${response.status})`
|
|
11427
|
+
);
|
|
11428
|
+
}
|
|
11429
|
+
const body = await response.json();
|
|
11430
|
+
return typeof body.version === "string" ? body.version : null;
|
|
11431
|
+
}
|
|
11432
|
+
function shouldUpdateCli(currentVersion, latestVersion) {
|
|
11433
|
+
if (!latestVersion) {
|
|
11434
|
+
return false;
|
|
11435
|
+
}
|
|
11436
|
+
return isSemverGreater(latestVersion, currentVersion);
|
|
11437
|
+
}
|
|
11438
|
+
function resolvePreferredPackageManager(env) {
|
|
11439
|
+
const explicit = env.SKILLZ_AUTO_UPDATE_MANAGER?.trim().toLowerCase();
|
|
11440
|
+
if (explicit && isPackageManager(explicit)) {
|
|
11441
|
+
return explicit;
|
|
11442
|
+
}
|
|
11443
|
+
const userAgentManager = parsePackageManagerFromUserAgent(
|
|
11444
|
+
env.npm_config_user_agent
|
|
11445
|
+
);
|
|
11446
|
+
if (userAgentManager) {
|
|
11447
|
+
return userAgentManager;
|
|
11448
|
+
}
|
|
11449
|
+
return null;
|
|
11450
|
+
}
|
|
11451
|
+
function parsePackageManagerFromUserAgent(userAgent) {
|
|
11452
|
+
if (!userAgent) {
|
|
11453
|
+
return null;
|
|
11454
|
+
}
|
|
11455
|
+
const normalized = userAgent.trim().toLowerCase();
|
|
11456
|
+
for (const manager of SUPPORTED_PACKAGE_MANAGERS) {
|
|
11457
|
+
if (normalized.startsWith(`${manager}/`)) {
|
|
11458
|
+
return manager;
|
|
11459
|
+
}
|
|
11460
|
+
}
|
|
11461
|
+
return null;
|
|
11462
|
+
}
|
|
11463
|
+
function buildSelfUpdateInstallCommand(manager, packageName) {
|
|
11464
|
+
const packageSpecifier = `${packageName}@latest`;
|
|
11465
|
+
switch (manager) {
|
|
11466
|
+
case "pnpm":
|
|
11467
|
+
return {
|
|
11468
|
+
command: "pnpm",
|
|
11469
|
+
args: ["add", "-g", packageSpecifier]
|
|
11470
|
+
};
|
|
11471
|
+
case "npm":
|
|
11472
|
+
return {
|
|
11473
|
+
command: "npm",
|
|
11474
|
+
args: ["install", "-g", packageSpecifier]
|
|
11475
|
+
};
|
|
11476
|
+
case "yarn":
|
|
11477
|
+
return {
|
|
11478
|
+
command: "yarn",
|
|
11479
|
+
args: ["global", "add", packageSpecifier]
|
|
11480
|
+
};
|
|
11481
|
+
case "bun":
|
|
11482
|
+
return {
|
|
11483
|
+
command: "bun",
|
|
11484
|
+
args: ["add", "-g", packageSpecifier]
|
|
11485
|
+
};
|
|
11486
|
+
default: {
|
|
11487
|
+
const _exhaustiveCheck = manager;
|
|
11488
|
+
throw new Error(`Unsupported package manager: ${_exhaustiveCheck}`);
|
|
11489
|
+
}
|
|
11490
|
+
}
|
|
11491
|
+
}
|
|
11492
|
+
async function resolveInstalledPackageManager(preferred) {
|
|
11493
|
+
if (preferred && await commandExists(preferred)) {
|
|
11494
|
+
return preferred;
|
|
11495
|
+
}
|
|
11496
|
+
for (const manager of SUPPORTED_PACKAGE_MANAGERS) {
|
|
11497
|
+
if (await commandExists(manager)) {
|
|
11498
|
+
return manager;
|
|
11499
|
+
}
|
|
11500
|
+
}
|
|
11501
|
+
return null;
|
|
11502
|
+
}
|
|
11503
|
+
async function commandExists(command) {
|
|
11504
|
+
return new Promise((resolve) => {
|
|
11505
|
+
const child = (0, import_node_child_process.spawn)(command, ["--version"], {
|
|
11506
|
+
stdio: "ignore"
|
|
11507
|
+
});
|
|
11508
|
+
child.once("error", () => {
|
|
11509
|
+
resolve(false);
|
|
11510
|
+
});
|
|
11511
|
+
child.once("exit", (code) => {
|
|
11512
|
+
resolve(typeof code === "number" && code === 0);
|
|
11513
|
+
});
|
|
11514
|
+
});
|
|
11515
|
+
}
|
|
11516
|
+
async function runCommand(command, args) {
|
|
11517
|
+
return new Promise((resolve, reject) => {
|
|
11518
|
+
const child = (0, import_node_child_process.spawn)(command, args, {
|
|
11519
|
+
stdio: "inherit"
|
|
11520
|
+
});
|
|
11521
|
+
child.once("error", (error) => {
|
|
11522
|
+
reject(error);
|
|
11523
|
+
});
|
|
11524
|
+
child.once("exit", (code) => {
|
|
11525
|
+
if (code === 0) {
|
|
11526
|
+
resolve();
|
|
11527
|
+
return;
|
|
11528
|
+
}
|
|
11529
|
+
reject(
|
|
11530
|
+
new Error(
|
|
11531
|
+
`${command} ${args.join(" ")} failed with exit code ${code ?? "unknown"}`
|
|
11532
|
+
)
|
|
11533
|
+
);
|
|
11534
|
+
});
|
|
11535
|
+
});
|
|
11536
|
+
}
|
|
11537
|
+
function isPackageManager(value) {
|
|
11538
|
+
return SUPPORTED_PACKAGE_MANAGERS.includes(value);
|
|
11539
|
+
}
|
|
11540
|
+
|
|
11285
11541
|
// src/client.ts
|
|
11286
11542
|
var RegistryClient = class {
|
|
11287
11543
|
constructor(baseUrl, token) {
|
|
@@ -11421,9 +11677,9 @@ var import_node_process = __toESM(require("process"), 1);
|
|
|
11421
11677
|
var import_prompts = require("@inquirer/prompts");
|
|
11422
11678
|
|
|
11423
11679
|
// src/git.ts
|
|
11424
|
-
var
|
|
11680
|
+
var import_node_child_process2 = require("child_process");
|
|
11425
11681
|
var import_node_util = require("util");
|
|
11426
|
-
var execFileAsync = (0, import_node_util.promisify)(
|
|
11682
|
+
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process2.execFile);
|
|
11427
11683
|
async function detectRepoRoot(cwd) {
|
|
11428
11684
|
try {
|
|
11429
11685
|
const { stdout } = await execFileAsync("git", ["rev-parse", "--show-toplevel"], {
|
|
@@ -11763,9 +12019,82 @@ async function upsertManifestEntry(entry) {
|
|
|
11763
12019
|
await saveManifest(manifest);
|
|
11764
12020
|
}
|
|
11765
12021
|
|
|
12022
|
+
// src/update.ts
|
|
12023
|
+
async function updateInstalledSkills(input) {
|
|
12024
|
+
if (!input.config.token) {
|
|
12025
|
+
throw new Error("Not logged in. Run skillz login.");
|
|
12026
|
+
}
|
|
12027
|
+
const candidateGroups = groupManifestEntriesBySource(input.entries);
|
|
12028
|
+
let updatedCount = 0;
|
|
12029
|
+
for (const group of candidateGroups) {
|
|
12030
|
+
const installed = group[0];
|
|
12031
|
+
if (installed.registryBaseUrl !== input.expectedRegistryBaseUrl) {
|
|
12032
|
+
if (!input.skipRegistryMismatchLogs) {
|
|
12033
|
+
input.onMessage?.(
|
|
12034
|
+
`Skipping ${installed.namespace}/${installed.name} because it belongs to ${installed.registryBaseUrl}`
|
|
12035
|
+
);
|
|
12036
|
+
}
|
|
12037
|
+
continue;
|
|
12038
|
+
}
|
|
12039
|
+
const client = new RegistryClient(installed.registryBaseUrl, input.config.token);
|
|
12040
|
+
const versions = await client.skillVersions(installed.namespace, installed.name);
|
|
12041
|
+
const latestVersion = versions.versions[0]?.version;
|
|
12042
|
+
if (!latestVersion || !group.some((entry) => isSemverGreater(latestVersion, entry.version))) {
|
|
12043
|
+
continue;
|
|
12044
|
+
}
|
|
12045
|
+
const sourcePath = installed.sourceInstallPath ?? installed.installPath;
|
|
12046
|
+
const writePath = await resolveInstallWritePath(sourcePath);
|
|
12047
|
+
await downloadAndInstallSkill(
|
|
12048
|
+
client,
|
|
12049
|
+
{
|
|
12050
|
+
namespace: installed.namespace,
|
|
12051
|
+
name: installed.name
|
|
12052
|
+
},
|
|
12053
|
+
latestVersion,
|
|
12054
|
+
writePath
|
|
12055
|
+
);
|
|
12056
|
+
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
12057
|
+
for (const entry of group) {
|
|
12058
|
+
entry.version = latestVersion;
|
|
12059
|
+
entry.installedAt = updatedAt;
|
|
12060
|
+
}
|
|
12061
|
+
updatedCount += group.length;
|
|
12062
|
+
input.onMessage?.(
|
|
12063
|
+
`Updated ${installed.namespace}/${installed.name} to ${latestVersion} (${group.map((entry) => entry.agent).join(", ")})`
|
|
12064
|
+
);
|
|
12065
|
+
}
|
|
12066
|
+
if (updatedCount > 0) {
|
|
12067
|
+
await saveManifest(input.manifest);
|
|
12068
|
+
}
|
|
12069
|
+
return {
|
|
12070
|
+
updatedCount
|
|
12071
|
+
};
|
|
12072
|
+
}
|
|
12073
|
+
function groupManifestEntriesBySource(entries) {
|
|
12074
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
12075
|
+
for (const entry of entries) {
|
|
12076
|
+
const sourcePath = entry.sourceInstallPath ?? entry.installPath;
|
|
12077
|
+
const key = [
|
|
12078
|
+
entry.registryBaseUrl,
|
|
12079
|
+
entry.namespace,
|
|
12080
|
+
entry.name,
|
|
12081
|
+
sourcePath
|
|
12082
|
+
].join("::");
|
|
12083
|
+
const group = grouped.get(key);
|
|
12084
|
+
if (group) {
|
|
12085
|
+
group.push(entry);
|
|
12086
|
+
} else {
|
|
12087
|
+
grouped.set(key, [entry]);
|
|
12088
|
+
}
|
|
12089
|
+
}
|
|
12090
|
+
return Array.from(grouped.values());
|
|
12091
|
+
}
|
|
12092
|
+
|
|
11766
12093
|
// src/index.ts
|
|
12094
|
+
var CLI_VERSION = typeof package_default.version === "string" ? package_default.version : "0.0.0";
|
|
12095
|
+
var CLI_PACKAGE_NAME = typeof package_default.name === "string" ? package_default.name : "@cantemizyurek/skillz";
|
|
11767
12096
|
var program = new import_commander.Command();
|
|
11768
|
-
program.name("skillz").description("Private Skills Registry CLI").option("--registry <url>", "registry base URL");
|
|
12097
|
+
program.name("skillz").description("Private Skills Registry CLI").version(CLI_VERSION, "-V, --version", "display Skillz CLI version").option("--registry <url>", "registry base URL");
|
|
11769
12098
|
program.command("register").description("Register a user account using an invite code").option("--invite <code>", "invite code").option("--username <username>", "username").option("--password <password>", "password").action(async (options2, command) => {
|
|
11770
12099
|
const { client } = await makeClient(command, false);
|
|
11771
12100
|
const inviteCode = options2.invite ?? await (0, import_prompts2.input)({ message: "Invite code" });
|
|
@@ -11810,6 +12139,104 @@ program.command("whoami").description("Show current authenticated user").action(
|
|
|
11810
12139
|
const me = await client.whoami();
|
|
11811
12140
|
console.log(`${me.user.username} (${me.user.role})`);
|
|
11812
12141
|
});
|
|
12142
|
+
program.command("version").description("Show CLI version and auto-update settings").action(async () => {
|
|
12143
|
+
const config = await loadConfig();
|
|
12144
|
+
const autoUpdate = resolveAutoUpdateSettings(config);
|
|
12145
|
+
console.log(`skillz ${CLI_VERSION}`);
|
|
12146
|
+
console.log(
|
|
12147
|
+
`Auto updates: ${autoUpdate.enabled ? "enabled" : "disabled"} (every ${autoUpdate.intervalHours}h)`
|
|
12148
|
+
);
|
|
12149
|
+
console.log(`Last auto-update check: ${autoUpdate.lastCheckedAt ?? "never"}`);
|
|
12150
|
+
});
|
|
12151
|
+
program.command("auto-update").description("Configure automatic CLI self-updates").option("--enable", "enable automatic updates").option("--disable", "disable automatic updates").option(
|
|
12152
|
+
"--interval-hours <hours>",
|
|
12153
|
+
"check interval in hours (1-720)",
|
|
12154
|
+
parseAutoUpdateIntervalHours
|
|
12155
|
+
).option("--check-now", "run the auto-update check immediately").action(async (options2) => {
|
|
12156
|
+
if (options2.enable && options2.disable) {
|
|
12157
|
+
throw new Error("Use either --enable or --disable, not both");
|
|
12158
|
+
}
|
|
12159
|
+
const config = await loadConfig();
|
|
12160
|
+
const nextConfig = {
|
|
12161
|
+
...config
|
|
12162
|
+
};
|
|
12163
|
+
let changed = false;
|
|
12164
|
+
if (options2.enable) {
|
|
12165
|
+
nextConfig.autoUpdateEnabled = true;
|
|
12166
|
+
changed = true;
|
|
12167
|
+
} else if (options2.disable) {
|
|
12168
|
+
nextConfig.autoUpdateEnabled = false;
|
|
12169
|
+
changed = true;
|
|
12170
|
+
}
|
|
12171
|
+
if (typeof options2.intervalHours === "number") {
|
|
12172
|
+
nextConfig.autoUpdateIntervalHours = options2.intervalHours;
|
|
12173
|
+
changed = true;
|
|
12174
|
+
}
|
|
12175
|
+
if (changed) {
|
|
12176
|
+
await saveConfig(nextConfig);
|
|
12177
|
+
}
|
|
12178
|
+
let lastCheckedAt = nextConfig.autoUpdateLastCheckedAt;
|
|
12179
|
+
if (options2.checkNow) {
|
|
12180
|
+
const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
12181
|
+
try {
|
|
12182
|
+
const result = await runCliSelfUpdate({
|
|
12183
|
+
packageName: CLI_PACKAGE_NAME,
|
|
12184
|
+
currentVersion: CLI_VERSION,
|
|
12185
|
+
preferredPackageManager: resolvePreferredPackageManager(import_node_process2.default.env)
|
|
12186
|
+
});
|
|
12187
|
+
if (result.updated) {
|
|
12188
|
+
console.log(
|
|
12189
|
+
`Updated skillz CLI to ${result.latestVersion} using ${result.manager}.`
|
|
12190
|
+
);
|
|
12191
|
+
console.log("Re-run your command to use the new version.");
|
|
12192
|
+
} else {
|
|
12193
|
+
console.log(
|
|
12194
|
+
`skillz CLI is already up to date (${result.latestVersion ?? CLI_VERSION}).`
|
|
12195
|
+
);
|
|
12196
|
+
}
|
|
12197
|
+
} finally {
|
|
12198
|
+
await saveConfig({
|
|
12199
|
+
...nextConfig,
|
|
12200
|
+
autoUpdateLastCheckedAt: checkedAt
|
|
12201
|
+
});
|
|
12202
|
+
lastCheckedAt = checkedAt;
|
|
12203
|
+
}
|
|
12204
|
+
}
|
|
12205
|
+
const resolved = resolveAutoUpdateSettings({
|
|
12206
|
+
...nextConfig,
|
|
12207
|
+
autoUpdateLastCheckedAt: lastCheckedAt
|
|
12208
|
+
});
|
|
12209
|
+
console.log(
|
|
12210
|
+
`Auto updates: ${resolved.enabled ? "enabled" : "disabled"} (every ${resolved.intervalHours}h)`
|
|
12211
|
+
);
|
|
12212
|
+
console.log(`Last auto-update check: ${resolved.lastCheckedAt ?? "never"}`);
|
|
12213
|
+
});
|
|
12214
|
+
program.command("self-update").description("Update skillz CLI to the latest published version").action(async () => {
|
|
12215
|
+
const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
12216
|
+
try {
|
|
12217
|
+
const result = await runCliSelfUpdate({
|
|
12218
|
+
packageName: CLI_PACKAGE_NAME,
|
|
12219
|
+
currentVersion: CLI_VERSION,
|
|
12220
|
+
preferredPackageManager: resolvePreferredPackageManager(import_node_process2.default.env)
|
|
12221
|
+
});
|
|
12222
|
+
if (result.updated) {
|
|
12223
|
+
console.log(
|
|
12224
|
+
`Updated skillz CLI to ${result.latestVersion} using ${result.manager}.`
|
|
12225
|
+
);
|
|
12226
|
+
console.log("Re-run your command to use the new version.");
|
|
12227
|
+
return;
|
|
12228
|
+
}
|
|
12229
|
+
console.log(
|
|
12230
|
+
`skillz CLI is already up to date (${result.latestVersion ?? CLI_VERSION}).`
|
|
12231
|
+
);
|
|
12232
|
+
} finally {
|
|
12233
|
+
const config = await loadConfig();
|
|
12234
|
+
await saveConfig({
|
|
12235
|
+
...config,
|
|
12236
|
+
autoUpdateLastCheckedAt: checkedAt
|
|
12237
|
+
});
|
|
12238
|
+
}
|
|
12239
|
+
});
|
|
11813
12240
|
program.command("list").description("List skills by download count (descending)").argument("[namespace]", "optional namespace").action(async (namespaceInput, _options, command) => {
|
|
11814
12241
|
const { client } = await makeClient(command, true);
|
|
11815
12242
|
const namespace = namespaceInput ? namespaceSchema.parse(namespaceInput) : void 0;
|
|
@@ -11979,51 +12406,17 @@ program.command("update").description("Update installed skills").argument("[name
|
|
|
11979
12406
|
console.log("No matching installed skills to update.");
|
|
11980
12407
|
return;
|
|
11981
12408
|
}
|
|
11982
|
-
|
|
11983
|
-
|
|
11984
|
-
|
|
11985
|
-
|
|
11986
|
-
|
|
11987
|
-
|
|
11988
|
-
|
|
11989
|
-
if (installed.registryBaseUrl !== resolveRegistryBaseUrl(command, config)) {
|
|
11990
|
-
console.log(
|
|
11991
|
-
`Skipping ${installed.namespace}/${installed.name} because it belongs to ${installed.registryBaseUrl}`
|
|
11992
|
-
);
|
|
11993
|
-
continue;
|
|
11994
|
-
}
|
|
11995
|
-
const client = new RegistryClient(installed.registryBaseUrl, config.token);
|
|
11996
|
-
const versions = await client.skillVersions(installed.namespace, installed.name);
|
|
11997
|
-
const latestVersion = versions.versions[0]?.version;
|
|
11998
|
-
if (!latestVersion || !group.some((entry) => isSemverGreater(latestVersion, entry.version))) {
|
|
11999
|
-
continue;
|
|
12000
|
-
}
|
|
12001
|
-
const sourcePath = installed.sourceInstallPath ?? installed.installPath;
|
|
12002
|
-
const writePath = await resolveInstallWritePath(sourcePath);
|
|
12003
|
-
await downloadAndInstallSkill(
|
|
12004
|
-
client,
|
|
12005
|
-
{
|
|
12006
|
-
namespace: installed.namespace,
|
|
12007
|
-
name: installed.name
|
|
12008
|
-
},
|
|
12009
|
-
latestVersion,
|
|
12010
|
-
writePath
|
|
12011
|
-
);
|
|
12012
|
-
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
12013
|
-
for (const entry of group) {
|
|
12014
|
-
entry.version = latestVersion;
|
|
12015
|
-
entry.installedAt = updatedAt;
|
|
12016
|
-
}
|
|
12017
|
-
updatedCount += group.length;
|
|
12018
|
-
console.log(
|
|
12019
|
-
`Updated ${installed.namespace}/${installed.name} to ${latestVersion} (${group.map((entry) => entry.agent).join(", ")})`
|
|
12020
|
-
);
|
|
12021
|
-
}
|
|
12409
|
+
const { updatedCount } = await updateInstalledSkills({
|
|
12410
|
+
config,
|
|
12411
|
+
expectedRegistryBaseUrl: resolveRegistryBaseUrl(command, config),
|
|
12412
|
+
manifest,
|
|
12413
|
+
entries: candidates,
|
|
12414
|
+
onMessage: (message) => console.log(message)
|
|
12415
|
+
});
|
|
12022
12416
|
if (updatedCount === 0) {
|
|
12023
12417
|
console.log("All matching skills are already up to date.");
|
|
12024
12418
|
return;
|
|
12025
12419
|
}
|
|
12026
|
-
await saveManifest(manifest);
|
|
12027
12420
|
console.log(`Updated ${updatedCount} skill(s).`);
|
|
12028
12421
|
});
|
|
12029
12422
|
program.command("publish").description("Publish a skill folder").argument("<path-to-skill-folder>", "path to the skill folder").requiredOption("--version <x.y.z>", "version to publish").action(async (skillPath, options2, command) => {
|
|
@@ -12045,6 +12438,9 @@ invitesCommand.command("create").description("Create a single-use invite code (a
|
|
|
12045
12438
|
const invite = await client.createInvite();
|
|
12046
12439
|
console.log(invite.inviteCode);
|
|
12047
12440
|
});
|
|
12441
|
+
program.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
12442
|
+
await maybeRunAutoUpdate(actionCommand);
|
|
12443
|
+
});
|
|
12048
12444
|
program.parseAsync(import_node_process2.default.argv).catch((error) => {
|
|
12049
12445
|
const message = error instanceof Error ? error.message : String(error);
|
|
12050
12446
|
console.error(`Error: ${message}`);
|
|
@@ -12124,24 +12520,66 @@ function truncateText(value, maxLength) {
|
|
|
12124
12520
|
function clamp(value, min, max) {
|
|
12125
12521
|
return Math.min(Math.max(value, min), max);
|
|
12126
12522
|
}
|
|
12127
|
-
function
|
|
12128
|
-
|
|
12129
|
-
|
|
12130
|
-
|
|
12131
|
-
|
|
12132
|
-
|
|
12133
|
-
|
|
12134
|
-
|
|
12135
|
-
|
|
12136
|
-
|
|
12137
|
-
const
|
|
12138
|
-
|
|
12139
|
-
|
|
12140
|
-
|
|
12141
|
-
|
|
12523
|
+
async function maybeRunAutoUpdate(actionCommand) {
|
|
12524
|
+
if (isAutoUpdateDisabledByEnv() || shouldSkipAutoUpdate(actionCommand)) {
|
|
12525
|
+
return;
|
|
12526
|
+
}
|
|
12527
|
+
const config = await loadConfig();
|
|
12528
|
+
if (!shouldRunAutoUpdateNow(config)) {
|
|
12529
|
+
return;
|
|
12530
|
+
}
|
|
12531
|
+
const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
12532
|
+
try {
|
|
12533
|
+
const result = await runCliSelfUpdate({
|
|
12534
|
+
packageName: CLI_PACKAGE_NAME,
|
|
12535
|
+
currentVersion: CLI_VERSION,
|
|
12536
|
+
preferredPackageManager: resolvePreferredPackageManager(import_node_process2.default.env)
|
|
12537
|
+
});
|
|
12538
|
+
if (result.updated) {
|
|
12539
|
+
console.log(
|
|
12540
|
+
`[auto-update] Updated skillz CLI to ${result.latestVersion} using ${result.manager}.`
|
|
12541
|
+
);
|
|
12542
|
+
console.log("[auto-update] Re-run your command to use the new version.");
|
|
12543
|
+
}
|
|
12544
|
+
} catch (error) {
|
|
12545
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
12546
|
+
console.warn(`Auto-update check failed: ${message}`);
|
|
12547
|
+
} finally {
|
|
12548
|
+
await saveConfig({
|
|
12549
|
+
...config,
|
|
12550
|
+
autoUpdateLastCheckedAt: checkedAt
|
|
12551
|
+
});
|
|
12552
|
+
}
|
|
12553
|
+
}
|
|
12554
|
+
function shouldSkipAutoUpdate(command) {
|
|
12555
|
+
const blocked = /* @__PURE__ */ new Set([
|
|
12556
|
+
"auto-update",
|
|
12557
|
+
"help",
|
|
12558
|
+
"login",
|
|
12559
|
+
"logout",
|
|
12560
|
+
"register",
|
|
12561
|
+
"self-update",
|
|
12562
|
+
"update",
|
|
12563
|
+
"version"
|
|
12564
|
+
]);
|
|
12565
|
+
const commandPath = resolveCommandPath(command);
|
|
12566
|
+
return commandPath.some((name) => blocked.has(name));
|
|
12567
|
+
}
|
|
12568
|
+
function resolveCommandPath(command) {
|
|
12569
|
+
const pathParts = [];
|
|
12570
|
+
let cursor = command;
|
|
12571
|
+
while (cursor && cursor.parent) {
|
|
12572
|
+
const name = cursor.name();
|
|
12573
|
+
if (name) {
|
|
12574
|
+
pathParts.push(name);
|
|
12142
12575
|
}
|
|
12576
|
+
cursor = cursor.parent;
|
|
12143
12577
|
}
|
|
12144
|
-
return
|
|
12578
|
+
return pathParts.reverse();
|
|
12579
|
+
}
|
|
12580
|
+
function isAutoUpdateDisabledByEnv() {
|
|
12581
|
+
const rawValue = import_node_process2.default.env.SKILLZ_AUTO_UPDATE?.trim().toLowerCase();
|
|
12582
|
+
return rawValue === "0" || rawValue === "false" || rawValue === "off" || rawValue === "no";
|
|
12145
12583
|
}
|
|
12146
12584
|
/*! Bundled license information:
|
|
12147
12585
|
|