bip-skills 1.4.9 → 1.4.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.
Files changed (2) hide show
  1. package/dist/cli.mjs +209 -97
  2. package/package.json +16 -18
package/dist/cli.mjs CHANGED
@@ -9,11 +9,10 @@ import { t as require_gray_matter } from "./_chunks/libs/gray-matter.mjs";
9
9
  import "./_chunks/libs/extend-shallow.mjs";
10
10
  import "./_chunks/libs/esprima.mjs";
11
11
  import { t as xdgConfig } from "./_chunks/libs/xdg-basedir.mjs";
12
- import { execSync, spawn, spawnSync } from "child_process";
12
+ import { execSync, spawnSync } from "child_process";
13
13
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
14
14
  import { basename, dirname, isAbsolute, join, normalize, posix, relative, resolve, sep } from "path";
15
15
  import { homedir, platform, tmpdir } from "os";
16
- import { createHash } from "crypto";
17
16
  import { fileURLToPath } from "url";
18
17
  import * as readline from "readline";
19
18
  import { Writable } from "stream";
@@ -21,6 +20,7 @@ import { Buffer } from "node:buffer";
21
20
  import { access, cp, lstat, mkdir, mkdtemp, readFile, readdir, readlink, realpath, rm, stat, symlink, writeFile } from "fs/promises";
22
21
  import http from "node:http";
23
22
  import https from "node:https";
23
+ import { createHash } from "crypto";
24
24
  var import_picocolors = /* @__PURE__ */ __toESM(require_picocolors(), 1);
25
25
  const AGENTS_DIR$2 = ".agents";
26
26
  const SKILLS_SUBDIR = "skills";
@@ -2070,7 +2070,7 @@ function createEmptyLocalLock() {
2070
2070
  skills: {}
2071
2071
  };
2072
2072
  }
2073
- var version$1 = "1.4.9";
2073
+ var version$1 = "1.4.10";
2074
2074
  const isCancelled$1 = (value) => typeof value === "symbol";
2075
2075
  async function isSourcePrivate(source) {
2076
2076
  const ownerRepo = parseOwnerRepo(source);
@@ -2083,6 +2083,14 @@ function initTelemetry(version) {
2083
2083
  function getWellKnownFileCount(skill) {
2084
2084
  return skill.declaredFiles.length > 0 ? skill.declaredFiles.length : skill.files.size;
2085
2085
  }
2086
+ function getWellKnownSkillHash(skill) {
2087
+ return skill.indexEntry.hash || skill.indexEntry.contentHash || skill.indexEntry.skillFolderHash || "";
2088
+ }
2089
+ function getWellKnownSkillPath(skill) {
2090
+ if (skill.indexEntry.entry) return skill.indexEntry.entry;
2091
+ if (skill.installTarget.type === "inline") return skill.installTarget.skillRoot ? posix.join(skill.installTarget.skillRoot, "SKILL.md") : "SKILL.md";
2092
+ return skill.installTarget.subpath ? posix.join(skill.installTarget.subpath, "SKILL.md") : "SKILL.md";
2093
+ }
2086
2094
  function getWellKnownEmptyStateMessage(status, totalSkillCount, invalidSkillCount) {
2087
2095
  switch (status) {
2088
2096
  case "no-valid-entries": return totalSkillCount > 0 ? `Found a skills index, but all ${totalSkillCount} entr${totalSkillCount === 1 ? "y is" : "ies are"} invalid. Check that each entry has a top-level SKILL.md in files[].` : "Found a skills index, but it does not contain any valid skill entries.";
@@ -2590,7 +2598,8 @@ async function handleWellKnownSkills(source, url, options, spinner, allowFallbac
2590
2598
  source: sourceIdentifier,
2591
2599
  sourceType: "well-known",
2592
2600
  sourceUrl: skill.sourceUrl,
2593
- skillFolderHash: ""
2601
+ skillPath: getWellKnownSkillPath(skill),
2602
+ skillFolderHash: getWellKnownSkillHash(skill)
2594
2603
  });
2595
2604
  } catch {}
2596
2605
  }
@@ -4106,6 +4115,146 @@ function parseRemoveOptions(args) {
4106
4115
  options
4107
4116
  };
4108
4117
  }
4118
+ function getUpdateCheckApiBase() {
4119
+ return process.env.SKILLS_API_URL || DEFAULT_SEARCH_API_BASE;
4120
+ }
4121
+ function canCheckWithServer(skill) {
4122
+ return skill.entry.sourceType !== "github";
4123
+ }
4124
+ function canCheckWithGitHub(skill) {
4125
+ return skill.entry.sourceType === "github" && Boolean(skill.entry.skillFolderHash) && Boolean(skill.entry.skillPath);
4126
+ }
4127
+ function buildUpdateCheckRequest(skills) {
4128
+ return {
4129
+ forceRefresh: true,
4130
+ skills: skills.map(({ name, entry }) => ({
4131
+ name,
4132
+ source: entry.source,
4133
+ sourceType: entry.sourceType,
4134
+ sourceUrl: entry.sourceUrl,
4135
+ skillPath: entry.skillPath,
4136
+ skillFolderHash: entry.skillFolderHash
4137
+ }))
4138
+ };
4139
+ }
4140
+ async function checkServerUpdates(skills, apiBaseUrl) {
4141
+ if (skills.length === 0) return {
4142
+ checkedCount: 0,
4143
+ skippedCount: 0,
4144
+ updates: [],
4145
+ errors: []
4146
+ };
4147
+ const byName = new Map(skills.map((skill) => [skill.name, skill]));
4148
+ const url = `${apiBaseUrl.replace(/\/$/, "")}/api/check-updates`;
4149
+ const request = buildUpdateCheckRequest(skills);
4150
+ debugLog(`[update] requesting update check: ${url}`);
4151
+ debugLog(`[update] update check request: ${JSON.stringify(request)}`);
4152
+ const response = await fetchWithSelectiveTls(url, {
4153
+ method: "POST",
4154
+ headers: {
4155
+ "Content-Type": "application/json",
4156
+ Accept: "application/json"
4157
+ },
4158
+ body: JSON.stringify(request)
4159
+ });
4160
+ debugLog(`[update] update check response status: ${response.status} ${response.statusText}`);
4161
+ if (!response.ok) throw new Error(`Update check failed with status ${response.status}`);
4162
+ const responseText = await response.text();
4163
+ debugLog(`[update] update check response body: ${responseText}`);
4164
+ const data = JSON.parse(responseText);
4165
+ return {
4166
+ checkedCount: data.checked ?? skills.length,
4167
+ skippedCount: data.skipped ?? 0,
4168
+ updates: (data.updates || []).flatMap((update) => {
4169
+ const skill = byName.get(update.name);
4170
+ if (!skill) return [];
4171
+ return [{
4172
+ name: update.name,
4173
+ source: update.source,
4174
+ entry: skill.entry,
4175
+ currentHash: update.currentHash,
4176
+ latestHash: update.latestHash
4177
+ }];
4178
+ }),
4179
+ errors: data.errors || []
4180
+ };
4181
+ }
4182
+ async function checkGitHubUpdates(skills, token) {
4183
+ const updates = [];
4184
+ const errors = [];
4185
+ for (const { name, entry } of skills) try {
4186
+ const latestHash = await fetchSkillFolderHash(entry.source, entry.skillPath, token);
4187
+ if (!latestHash) {
4188
+ errors.push({
4189
+ name,
4190
+ source: entry.source,
4191
+ error: "Could not fetch from GitHub"
4192
+ });
4193
+ continue;
4194
+ }
4195
+ if (latestHash !== entry.skillFolderHash) updates.push({
4196
+ name,
4197
+ source: entry.source,
4198
+ entry,
4199
+ currentHash: entry.skillFolderHash,
4200
+ latestHash
4201
+ });
4202
+ } catch (err) {
4203
+ errors.push({
4204
+ name,
4205
+ source: entry.source,
4206
+ error: err instanceof Error ? err.message : "Unknown error"
4207
+ });
4208
+ }
4209
+ return {
4210
+ checkedCount: skills.length,
4211
+ skippedCount: 0,
4212
+ updates,
4213
+ errors
4214
+ };
4215
+ }
4216
+ async function checkSkillUpdates(skills, options = {}) {
4217
+ const serverSkills = skills.filter(canCheckWithServer);
4218
+ const githubSkills = skills.filter(canCheckWithGitHub);
4219
+ let checkedCount = 0;
4220
+ let skippedCount = skills.length - serverSkills.length - githubSkills.length;
4221
+ const updates = [];
4222
+ const errors = [];
4223
+ debugLog(`[update] prepared ${serverSkills.length} server skill(s), ${githubSkills.length} github skill(s), ${skippedCount} skipped`);
4224
+ for (const skill of skills) {
4225
+ if (serverSkills.includes(skill)) {
4226
+ debugLog(`[update] server check ${skill.name}: sourceType=${skill.entry.sourceType} hash=${skill.entry.skillFolderHash || "(empty)"}`);
4227
+ continue;
4228
+ }
4229
+ if (githubSkills.includes(skill)) {
4230
+ debugLog(`[update] github check ${skill.name}: path=${skill.entry.skillPath || "(missing)"} hash=${skill.entry.skillFolderHash || "(empty)"}`);
4231
+ continue;
4232
+ }
4233
+ debugLog(`[update] skipped ${skill.name}: sourceType=${skill.entry.sourceType} path=${skill.entry.skillPath || "(missing)"} hash=${skill.entry.skillFolderHash || "(empty)"}`);
4234
+ }
4235
+ if (serverSkills.length > 0) try {
4236
+ const serverResult = await checkServerUpdates(serverSkills, options.apiBaseUrl || getUpdateCheckApiBase());
4237
+ checkedCount += serverResult.checkedCount;
4238
+ skippedCount += serverResult.skippedCount;
4239
+ updates.push(...serverResult.updates);
4240
+ errors.push(...serverResult.errors);
4241
+ } catch (err) {
4242
+ debugLog(`[update] server update check failed: ${err instanceof Error ? err.message : "Unknown error"}`);
4243
+ }
4244
+ if (githubSkills.length > 0) {
4245
+ const githubResult = await checkGitHubUpdates(githubSkills, options.githubToken);
4246
+ checkedCount += githubResult.checkedCount;
4247
+ skippedCount += githubResult.skippedCount;
4248
+ updates.push(...githubResult.updates);
4249
+ errors.push(...githubResult.errors);
4250
+ }
4251
+ return {
4252
+ checkedCount,
4253
+ skippedCount,
4254
+ updates,
4255
+ errors
4256
+ };
4257
+ }
4109
4258
  const __dirname = dirname(fileURLToPath(import.meta.url));
4110
4259
  function getVersion() {
4111
4260
  try {
@@ -4122,12 +4271,12 @@ const BOLD = "\x1B[1m";
4122
4271
  const DIM = "\x1B[38;5;102m";
4123
4272
  const TEXT = "\x1B[38;5;145m";
4124
4273
  const LOGO_LINES = [
4125
- "███████╗██╗ ██╗██╗██╗ ██╗ ███████╗",
4126
- "██╔════╝██║ ██╔╝██║██║ ██║ ██╔════╝",
4127
- "███████╗█████╔╝ ██║██║ ██║ ███████╗",
4128
- "╚════██║██╔═██╗ ██║██║ ██║ ╚════██║",
4129
- "███████║██║ ██╗██║███████╗███████╗███████║",
4130
- "╚══════╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚══════╝"
4274
+ "██████╗ ██╗ ██████╗ ███████╗██╗ ██╗██╗██╗ ██╗ ███████╗",
4275
+ "██╔══██╗ ██║ ██╔══██╗ ██╔════╝██║ ██╔╝██║██║ ██║ ██╔════╝",
4276
+ "██████╔╝ ██║ ██████╔╝█████╗███████╗█████╔╝ ██║██║ ██║ ███████╗",
4277
+ "██╔══██╗ ██║ ██╔═══╝ ╚════╝╚════██║██╔═██╗ ██║██║ ██║ ╚════██║",
4278
+ "██████╔╝ ██║ ██║ ███████║██║ ██╗██║███████╗███████╗███████║",
4279
+ "╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚══════╝"
4131
4280
  ];
4132
4281
  const GRAYS = [
4133
4282
  "\x1B[38;5;250m",
@@ -4146,6 +4295,8 @@ function showLogo() {
4146
4295
  function showBanner() {
4147
4296
  showLogo();
4148
4297
  console.log();
4298
+ console.log(`${BOLD}${TEXT}BIP-SKILLS${RESET}`);
4299
+ console.log();
4149
4300
  console.log(`${DIM}The open agent skills ecosystem${RESET}`);
4150
4301
  console.log();
4151
4302
  console.log(` ${DIM}$${RESET} ${TEXT}${CLI_NPX_COMMAND} add ${DIM}<package>${RESET} ${DIM}Add a new skill${RESET}`);
@@ -4343,82 +4494,69 @@ function readSkillLock() {
4343
4494
  };
4344
4495
  }
4345
4496
  }
4497
+ function getLockedSkillsForUpdate(lock) {
4498
+ return Object.entries(lock.skills).map(([name, entry]) => ({
4499
+ name,
4500
+ entry
4501
+ }));
4502
+ }
4503
+ function buildWellKnownUpdateUrl(name, entry) {
4504
+ try {
4505
+ if (entry.sourceUrl.startsWith("http://") || entry.sourceUrl.startsWith("https://")) {
4506
+ const parsed = new URL(entry.sourceUrl);
4507
+ const markerIndex = parsed.pathname.indexOf("/.well-known/skills");
4508
+ const basePath = markerIndex >= 0 ? parsed.pathname.slice(0, markerIndex) : "";
4509
+ return `${parsed.origin}${basePath}@${name}`;
4510
+ }
4511
+ } catch {}
4512
+ if (entry.source.startsWith("http://") || entry.source.startsWith("https://")) return `${entry.source.replace(/\/$/, "")}@${name}`;
4513
+ if (entry.source.includes(".")) return `https://${entry.source.replace(/\/$/, "")}@${name}`;
4514
+ return entry.sourceUrl;
4515
+ }
4516
+ function buildUpdateInstallUrl(name, entry) {
4517
+ if (entry.sourceType === "well-known") return buildWellKnownUpdateUrl(name, entry);
4518
+ if (entry.sourceType !== "github" || !entry.skillPath) return entry.sourceUrl;
4519
+ let skillFolder = entry.skillPath;
4520
+ if (skillFolder.endsWith("/SKILL.md")) skillFolder = skillFolder.slice(0, -9);
4521
+ else if (skillFolder.endsWith("SKILL.md")) skillFolder = skillFolder.slice(0, -8);
4522
+ if (skillFolder.endsWith("/")) skillFolder = skillFolder.slice(0, -1);
4523
+ return `${entry.sourceUrl.replace(/\.git$/, "").replace(/\/$/, "")}/tree/main/${skillFolder}`;
4524
+ }
4346
4525
  async function runCheck(args = []) {
4347
4526
  console.log(`${TEXT}Checking for skill updates...${RESET}`);
4348
4527
  console.log();
4349
4528
  const lock = readSkillLock();
4350
- const skillNames = Object.keys(lock.skills);
4351
- if (skillNames.length === 0) {
4529
+ if (Object.keys(lock.skills).length === 0) {
4352
4530
  console.log(`${DIM}No skills tracked in lock file.${RESET}`);
4353
4531
  console.log(`${DIM}Install skills with${RESET} ${TEXT}${CLI_NPX_COMMAND} add <package>${RESET}`);
4354
4532
  return;
4355
4533
  }
4356
- const token = getGitHubToken();
4357
- const skillsBySource = /* @__PURE__ */ new Map();
4358
- let skippedCount = 0;
4359
- for (const skillName of skillNames) {
4360
- const entry = lock.skills[skillName];
4361
- if (!entry) continue;
4362
- if (entry.sourceType !== "github" || !entry.skillFolderHash || !entry.skillPath) {
4363
- skippedCount++;
4364
- continue;
4365
- }
4366
- const existing = skillsBySource.get(entry.source) || [];
4367
- existing.push({
4368
- name: skillName,
4369
- entry
4370
- });
4371
- skillsBySource.set(entry.source, existing);
4372
- }
4373
- const totalSkills = skillNames.length - skippedCount;
4374
- if (totalSkills === 0) {
4375
- console.log(`${DIM}No GitHub skills to check.${RESET}`);
4534
+ const result = await checkSkillUpdates(getLockedSkillsForUpdate(lock), { githubToken: getGitHubToken() });
4535
+ if (result.checkedCount === 0) {
4536
+ console.log(`${DIM}No skills to check.${RESET}`);
4376
4537
  return;
4377
4538
  }
4378
- console.log(`${DIM}Checking ${totalSkills} skill(s) for updates...${RESET}`);
4379
- const updates = [];
4380
- const errors = [];
4381
- for (const [source, skills] of skillsBySource) for (const { name, entry } of skills) try {
4382
- const latestHash = await fetchSkillFolderHash(source, entry.skillPath, token);
4383
- if (!latestHash) {
4384
- errors.push({
4385
- name,
4386
- source,
4387
- error: "Could not fetch from GitHub"
4388
- });
4389
- continue;
4390
- }
4391
- if (latestHash !== entry.skillFolderHash) updates.push({
4392
- name,
4393
- source
4394
- });
4395
- } catch (err) {
4396
- errors.push({
4397
- name,
4398
- source,
4399
- error: err instanceof Error ? err.message : "Unknown error"
4400
- });
4401
- }
4539
+ console.log(`${DIM}Checking ${result.checkedCount} skill(s) for updates...${RESET}`);
4402
4540
  console.log();
4403
- if (updates.length === 0) console.log(`${TEXT}✓ All skills are up to date${RESET}`);
4541
+ if (result.updates.length === 0) console.log(`${TEXT}✓ All skills are up to date${RESET}`);
4404
4542
  else {
4405
- console.log(`${TEXT}${updates.length} update(s) available:${RESET}`);
4543
+ console.log(`${TEXT}${result.updates.length} update(s) available:${RESET}`);
4406
4544
  console.log();
4407
- for (const update of updates) {
4545
+ for (const update of result.updates) {
4408
4546
  console.log(` ${TEXT}↑${RESET} ${update.name}`);
4409
4547
  console.log(` ${DIM}source: ${update.source}${RESET}`);
4410
4548
  }
4411
4549
  console.log();
4412
4550
  console.log(`${DIM}Run${RESET} ${TEXT}${CLI_NPX_COMMAND} update${RESET} ${DIM}to update all skills${RESET}`);
4413
4551
  }
4414
- if (errors.length > 0) {
4552
+ if (result.errors.length > 0) {
4415
4553
  console.log();
4416
- console.log(`${DIM}Could not check ${errors.length} skill(s) (may need reinstall)${RESET}`);
4554
+ console.log(`${DIM}Could not check ${result.errors.length} skill(s) (may need reinstall)${RESET}`);
4417
4555
  }
4418
4556
  track({
4419
4557
  event: "check",
4420
- skillCount: String(totalSkills),
4421
- updatesAvailable: String(updates.length)
4558
+ skillCount: String(result.checkedCount),
4559
+ updatesAvailable: String(result.updates.length)
4422
4560
  });
4423
4561
  console.log();
4424
4562
  }
@@ -4426,58 +4564,32 @@ async function runUpdate() {
4426
4564
  console.log(`${TEXT}Checking for skill updates...${RESET}`);
4427
4565
  console.log();
4428
4566
  const lock = readSkillLock();
4429
- const skillNames = Object.keys(lock.skills);
4430
- if (skillNames.length === 0) {
4567
+ if (Object.keys(lock.skills).length === 0) {
4431
4568
  console.log(`${DIM}No skills tracked in lock file.${RESET}`);
4432
4569
  console.log(`${DIM}Install skills with${RESET} ${TEXT}${CLI_NPX_COMMAND} add <package>${RESET}`);
4433
4570
  return;
4434
4571
  }
4435
- const token = getGitHubToken();
4436
- const updates = [];
4437
- let checkedCount = 0;
4438
- for (const skillName of skillNames) {
4439
- const entry = lock.skills[skillName];
4440
- if (!entry) continue;
4441
- if (entry.sourceType !== "github" || !entry.skillFolderHash || !entry.skillPath) continue;
4442
- checkedCount++;
4443
- try {
4444
- const latestHash = await fetchSkillFolderHash(entry.source, entry.skillPath, token);
4445
- if (latestHash && latestHash !== entry.skillFolderHash) updates.push({
4446
- name: skillName,
4447
- source: entry.source,
4448
- entry
4449
- });
4450
- } catch {}
4451
- }
4452
- if (checkedCount === 0) {
4572
+ const result = await checkSkillUpdates(getLockedSkillsForUpdate(lock), { githubToken: getGitHubToken() });
4573
+ if (result.checkedCount === 0) {
4453
4574
  console.log(`${DIM}No skills to check.${RESET}`);
4454
4575
  return;
4455
4576
  }
4456
- if (updates.length === 0) {
4577
+ if (result.updates.length === 0) {
4457
4578
  console.log(`${TEXT}✓ All skills are up to date${RESET}`);
4458
4579
  console.log();
4459
4580
  return;
4460
4581
  }
4461
- console.log(`${TEXT}Found ${updates.length} update(s)${RESET}`);
4582
+ console.log(`${TEXT}Found ${result.updates.length} update(s)${RESET}`);
4462
4583
  console.log();
4463
4584
  let successCount = 0;
4464
4585
  let failCount = 0;
4465
- for (const update of updates) {
4586
+ for (const update of result.updates) {
4466
4587
  console.log(`${TEXT}Updating ${update.name}...${RESET}`);
4467
- let installUrl = update.entry.sourceUrl;
4468
- if (update.entry.skillPath) {
4469
- let skillFolder = update.entry.skillPath;
4470
- if (skillFolder.endsWith("/SKILL.md")) skillFolder = skillFolder.slice(0, -9);
4471
- else if (skillFolder.endsWith("SKILL.md")) skillFolder = skillFolder.slice(0, -8);
4472
- if (skillFolder.endsWith("/")) skillFolder = skillFolder.slice(0, -1);
4473
- installUrl = update.entry.sourceUrl.replace(/\.git$/, "").replace(/\/$/, "");
4474
- installUrl = `${installUrl}/tree/main/${skillFolder}`;
4475
- }
4476
4588
  if (spawnSync("npx", [
4477
4589
  "-y",
4478
4590
  CLI_PACKAGE_NAME,
4479
4591
  "add",
4480
- installUrl,
4592
+ buildUpdateInstallUrl(update.name, update.entry),
4481
4593
  "-g",
4482
4594
  "-y"
4483
4595
  ], { stdio: [
@@ -4497,7 +4609,7 @@ async function runUpdate() {
4497
4609
  if (failCount > 0) console.log(`${DIM}Failed to update ${failCount} skill(s)${RESET}`);
4498
4610
  track({
4499
4611
  event: "update",
4500
- skillCount: String(updates.length),
4612
+ skillCount: String(result.updates.length),
4501
4613
  successCount: String(successCount),
4502
4614
  failCount: String(failCount)
4503
4615
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bip-skills",
3
- "version": "1.4.9",
3
+ "version": "1.4.10",
4
4
  "description": "The open agent skills ecosystem",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,20 +14,6 @@
14
14
  "README.md",
15
15
  "ThirdPartyNoticeText.txt"
16
16
  ],
17
- "scripts": {
18
- "build": "obuild && node scripts/generate-licenses.ts",
19
- "generate-licenses": "node scripts/generate-licenses.ts",
20
- "dev": "node src/cli.ts",
21
- "exec:test": "node scripts/execute-tests.ts",
22
- "pack:check": "npm pack --dry-run --ignore-scripts --cache .npm-cache",
23
- "prepublishOnly": "npm run build",
24
- "format": "prettier --write 'src/**/*.ts' 'scripts/**/*.ts'",
25
- "format:check": "prettier --check 'src/**/*.ts' 'scripts/**/*.ts'",
26
- "prepare": "husky",
27
- "test": "vitest",
28
- "type-check": "tsc --noEmit",
29
- "publish:snapshot": "npm version prerelease --preid=snapshot --no-git-tag-version && npm publish --tag snapshot"
30
- },
31
17
  "lint-staged": {
32
18
  "src/**/*.ts": "prettier --write",
33
19
  "scripts/**/*.ts": "prettier --write",
@@ -88,7 +74,8 @@
88
74
  "author": "",
89
75
  "license": "MIT",
90
76
  "publishConfig": {
91
- "access": "public"
77
+ "access": "public",
78
+ "registry": "https://registry.npmjs.org/"
92
79
  },
93
80
  "devDependencies": {
94
81
  "@clack/prompts": "^0.11.0",
@@ -108,5 +95,16 @@
108
95
  "engines": {
109
96
  "node": ">=18"
110
97
  },
111
- "packageManager": "pnpm@10.17.1"
112
- }
98
+ "scripts": {
99
+ "build": "obuild && node scripts/generate-licenses.ts",
100
+ "generate-licenses": "node scripts/generate-licenses.ts",
101
+ "dev": "node src/cli.ts",
102
+ "exec:test": "node scripts/execute-tests.ts",
103
+ "pack:check": "npm pack --dry-run --ignore-scripts --cache .npm-cache",
104
+ "format": "prettier --write 'src/**/*.ts' 'scripts/**/*.ts'",
105
+ "format:check": "prettier --check 'src/**/*.ts' 'scripts/**/*.ts'",
106
+ "test": "vitest",
107
+ "type-check": "tsc --noEmit",
108
+ "publish:snapshot": "npm version prerelease --preid=snapshot --no-git-tag-version && npm publish --tag snapshot"
109
+ }
110
+ }