github-labels-template 0.8.0 → 0.9.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.
Files changed (2) hide show
  1. package/dist/index.js +172 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { defineCommand as defineCommand7, runMain } from "citty";
4
+ import { defineCommand as defineCommand8, runMain } from "citty";
5
5
 
6
6
  // src/commands/apply.ts
7
7
  import { defineCommand } from "citty";
@@ -1230,13 +1230,17 @@ var check_default = defineCommand6({
1230
1230
  }
1231
1231
  });
1232
1232
 
1233
+ // src/commands/update.ts
1234
+ import { defineCommand as defineCommand7 } from "citty";
1235
+ import { execSync } from "child_process";
1236
+
1233
1237
  // src/ui/banner.ts
1234
1238
  import figlet from "figlet";
1235
1239
  import pc8 from "picocolors";
1236
1240
  // package.json
1237
1241
  var package_default = {
1238
1242
  name: "github-labels-template",
1239
- version: "0.8.0",
1243
+ version: "0.9.0",
1240
1244
  description: "A CLI tool to apply a curated GitHub labels template to any repository using gh CLI.",
1241
1245
  type: "module",
1242
1246
  bin: {
@@ -1300,6 +1304,19 @@ function getVersion() {
1300
1304
  function getAuthor() {
1301
1305
  return package_default.author ?? "unknown";
1302
1306
  }
1307
+ function showUpdateBanner(latestVersion) {
1308
+ const current = getVersion();
1309
+ const visibleLen = (s) => s.replace(/\x1b\[[0-9;]*m/g, "").length;
1310
+ const line1 = ` ${pc8.bold(`Update available: v${current} → v${latestVersion}`)} `;
1311
+ const line2 = ` Run ${pc8.bold("ghlt update")} to upgrade. `;
1312
+ const width = Math.max(visibleLen(line1), visibleLen(line2));
1313
+ const border = "─".repeat(width);
1314
+ console.log(pc8.yellow(`┌${border}┐`));
1315
+ console.log(pc8.yellow("│") + line1 + " ".repeat(width - visibleLen(line1)) + pc8.yellow("│"));
1316
+ console.log(pc8.yellow("│") + line2 + " ".repeat(width - visibleLen(line2)) + pc8.yellow("│"));
1317
+ console.log(pc8.yellow(`└${border}┘`));
1318
+ console.log();
1319
+ }
1303
1320
  function showBanner(minimal = false) {
1304
1321
  console.log(pc8.cyan(`
1305
1322
  ` + LOGO));
@@ -1314,10 +1331,160 @@ function showBanner(minimal = false) {
1314
1331
  console.log();
1315
1332
  }
1316
1333
 
1334
+ // src/utils/updater.ts
1335
+ import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync, renameSync } from "fs";
1336
+ import { join, dirname } from "path";
1337
+ import { homedir, tmpdir } from "os";
1338
+ var CACHE_DIR = join(homedir(), ".ghlt");
1339
+ var CACHE_FILE = join(CACHE_DIR, "update-check.json");
1340
+ var CACHE_TTL_MS = 24 * 60 * 60 * 1000;
1341
+ var REGISTRY_URL = "https://registry.npmjs.org/github-labels-template/latest";
1342
+ function isNewerVersion(latest, current) {
1343
+ const parse = (v) => v.replace(/^v/, "").split(/[-+]/)[0].split(".").map(Number);
1344
+ const [lMaj, lMin, lPatch] = parse(latest);
1345
+ const [cMaj, cMin, cPatch] = parse(current);
1346
+ if ([lMaj, lMin, lPatch, cMaj, cMin, cPatch].some(isNaN))
1347
+ return false;
1348
+ if (lMaj !== cMaj)
1349
+ return lMaj > cMaj;
1350
+ if (lMin !== cMin)
1351
+ return lMin > cMin;
1352
+ return lPatch > cPatch;
1353
+ }
1354
+ function readCache(cacheFile = CACHE_FILE) {
1355
+ try {
1356
+ if (!existsSync2(cacheFile))
1357
+ return null;
1358
+ const raw = readFileSync2(cacheFile, "utf-8");
1359
+ return JSON.parse(raw);
1360
+ } catch {
1361
+ return null;
1362
+ }
1363
+ }
1364
+ function writeCache(data, cacheFile = CACHE_FILE) {
1365
+ try {
1366
+ const dir = dirname(cacheFile);
1367
+ if (!existsSync2(dir))
1368
+ mkdirSync(dir, { recursive: true });
1369
+ const tmp = join(tmpdir(), `ghlt-update-${process.pid}-${Date.now()}.json`);
1370
+ writeFileSync2(tmp, JSON.stringify(data), "utf-8");
1371
+ renameSync(tmp, cacheFile);
1372
+ } catch {}
1373
+ }
1374
+ async function fetchLatestVersion() {
1375
+ try {
1376
+ const res = await fetch(REGISTRY_URL);
1377
+ if (!res.ok)
1378
+ return null;
1379
+ const data = await res.json();
1380
+ return data.version ?? null;
1381
+ } catch (err) {
1382
+ console.debug("Failed to fetch latest version from npm registry:", err);
1383
+ return null;
1384
+ }
1385
+ }
1386
+ function refreshCacheInBackground(cacheFile = CACHE_FILE) {
1387
+ fetchLatestVersion().then((version) => {
1388
+ if (version) {
1389
+ writeCache({ lastChecked: Date.now(), latestVersion: version }, cacheFile);
1390
+ }
1391
+ }).catch(() => {});
1392
+ }
1393
+ function checkForUpdate(cacheFile = CACHE_FILE) {
1394
+ if (process.env.CI === "true" || process.env.CI === "1")
1395
+ return null;
1396
+ if (process.env.NO_UPDATE_NOTIFIER)
1397
+ return null;
1398
+ if (process.argv.includes("--no-update-notifier"))
1399
+ return null;
1400
+ const cache = readCache(cacheFile);
1401
+ const now = Date.now();
1402
+ const isStale = !cache || now - cache.lastChecked > CACHE_TTL_MS;
1403
+ if (isStale) {
1404
+ refreshCacheInBackground(cacheFile);
1405
+ }
1406
+ if (cache?.latestVersion && isNewerVersion(cache.latestVersion, getVersion())) {
1407
+ return cache.latestVersion;
1408
+ }
1409
+ return null;
1410
+ }
1411
+
1412
+ // src/commands/update.ts
1413
+ function detectPackageManager() {
1414
+ try {
1415
+ execSync("bun --version", { stdio: "ignore" });
1416
+ return "bun";
1417
+ } catch {
1418
+ return "npm";
1419
+ }
1420
+ }
1421
+ function getUpdateCommand(pm) {
1422
+ if (pm === "bun")
1423
+ return "bun add -g github-labels-template";
1424
+ return "npm install -g github-labels-template";
1425
+ }
1426
+ var update_default = defineCommand7({
1427
+ meta: {
1428
+ name: "update",
1429
+ description: "Update ghlt to the latest published version"
1430
+ },
1431
+ args: {
1432
+ check: {
1433
+ type: "boolean",
1434
+ default: false,
1435
+ description: "Only check if an update is available without installing"
1436
+ },
1437
+ "dry-run": {
1438
+ type: "boolean",
1439
+ default: false,
1440
+ description: "Alias for --check — report availability without updating"
1441
+ }
1442
+ },
1443
+ async run({ args }) {
1444
+ const current = getVersion();
1445
+ info(`Current version: v${current}`);
1446
+ const latest = await fetchLatestVersion();
1447
+ if (!latest) {
1448
+ error("Could not fetch the latest version. Check your internet connection.");
1449
+ process.exit(1);
1450
+ }
1451
+ info(`Latest version: v${latest}`);
1452
+ writeCache({ lastChecked: Date.now(), latestVersion: latest });
1453
+ if (!isNewerVersion(latest, current)) {
1454
+ success("Already on the latest version.");
1455
+ return;
1456
+ }
1457
+ if (args.check || args["dry-run"]) {
1458
+ info(`Update available: v${current} → v${latest}`);
1459
+ info(`Run 'ghlt update' to upgrade.`);
1460
+ return;
1461
+ }
1462
+ info("Updating ghlt...");
1463
+ try {
1464
+ const pm = detectPackageManager();
1465
+ const cmd = getUpdateCommand(pm);
1466
+ info(`Running: ${cmd}`);
1467
+ execSync(cmd, { stdio: "inherit" });
1468
+ success(`ghlt updated to v${latest}`);
1469
+ } catch {
1470
+ error("Update failed. Try running the update command manually:");
1471
+ console.log(` npm install -g github-labels-template`);
1472
+ process.exit(1);
1473
+ }
1474
+ }
1475
+ });
1476
+
1317
1477
  // src/index.ts
1318
1478
  var isHelp = process.argv.includes("--help") || process.argv.includes("-h");
1479
+ var isUpdateCommand = process.argv.includes("update");
1319
1480
  showBanner(isHelp);
1320
- var main = defineCommand7({
1481
+ if (!isUpdateCommand) {
1482
+ const availableUpdate = checkForUpdate();
1483
+ if (availableUpdate) {
1484
+ showUpdateBanner(availableUpdate);
1485
+ }
1486
+ }
1487
+ var main = defineCommand8({
1321
1488
  meta: {
1322
1489
  name: "ghlt",
1323
1490
  version: getVersion(),
@@ -1336,7 +1503,8 @@ var main = defineCommand7({
1336
1503
  migrate: migrate_default,
1337
1504
  generate: generate_default,
1338
1505
  list: list_default,
1339
- check: check_default
1506
+ check: check_default,
1507
+ update: update_default
1340
1508
  },
1341
1509
  run({ args }) {
1342
1510
  if (args.version) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "github-labels-template",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "A CLI tool to apply a curated GitHub labels template to any repository using gh CLI.",
5
5
  "type": "module",
6
6
  "bin": {