@kyubiware/commit-mint 0.7.5 → 0.7.6
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/cli.mjs +72 -19
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -29,7 +29,7 @@ var __exportAll = (all, no_symbols) => {
|
|
|
29
29
|
//#region package.json
|
|
30
30
|
var package_default = {
|
|
31
31
|
name: "@kyubiware/commit-mint",
|
|
32
|
-
version: "0.7.
|
|
32
|
+
version: "0.7.6",
|
|
33
33
|
description: "🌿 AI-powered git commit tool — auto-group changed files, generate messages, run pre-commit checks",
|
|
34
34
|
type: "module",
|
|
35
35
|
bin: { "cmint": "./dist/cli.mjs" },
|
|
@@ -2354,7 +2354,8 @@ async function agentCommand(flags) {
|
|
|
2354
2354
|
//#endregion
|
|
2355
2355
|
//#region src/services/update-check.ts
|
|
2356
2356
|
const REGISTRY_URL = "https://registry.npmjs.org/-/package/@kyubiware/commit-mint/dist-tags";
|
|
2357
|
-
const
|
|
2357
|
+
const FRESH_MS = 3600 * 1e3;
|
|
2358
|
+
const STALE_MS = 1440 * 60 * 1e3;
|
|
2358
2359
|
const FETCH_TIMEOUT_MS = 5e3;
|
|
2359
2360
|
let cachePath = join(os.homedir(), ".cache", "commit-mint", "update-check.json");
|
|
2360
2361
|
let fetchImpl = globalThis.fetch;
|
|
@@ -2442,6 +2443,70 @@ function displayNag(current, latest) {
|
|
|
2442
2443
|
log.warn(message);
|
|
2443
2444
|
}
|
|
2444
2445
|
/**
|
|
2446
|
+
* Fire-and-forget cache refresh used by the stale-while-revalidate (SWR) band
|
|
2447
|
+
* (cache age in [FRESH_MS, STALE_MS)). Runs the registry fetch and writes a
|
|
2448
|
+
* fresh cache entry without awaiting — the caller returns immediately with
|
|
2449
|
+
* the cached `latest` so the nag decision is fast.
|
|
2450
|
+
*
|
|
2451
|
+
* Wrapped in try/catch and `void`-ed so the floating promise NEVER rejects
|
|
2452
|
+
* (vitest fails the suite on unhandled rejections). On any failure (network,
|
|
2453
|
+
* HTTP non-ok, malformed JSON, fs write error) the cache file is left
|
|
2454
|
+
* unchanged and the failure is logged via {@link debug} only.
|
|
2455
|
+
*
|
|
2456
|
+
* No abort signal is wired here — the cancellable spinner only runs on the
|
|
2457
|
+
* STALE blocking-fetch path, and FRESH/SWR callers explicitly want this to
|
|
2458
|
+
* complete in the background regardless of user keystrokes.
|
|
2459
|
+
*/
|
|
2460
|
+
function refreshCacheInBackground() {
|
|
2461
|
+
debug("refreshCacheInBackground: starting fire-and-forget refresh");
|
|
2462
|
+
(async () => {
|
|
2463
|
+
try {
|
|
2464
|
+
const latest = await fetchLatest();
|
|
2465
|
+
if (latest === null) {
|
|
2466
|
+
debug("refreshCacheInBackground: fetch returned null, leaving cache unchanged");
|
|
2467
|
+
return;
|
|
2468
|
+
}
|
|
2469
|
+
await saveCache({
|
|
2470
|
+
latest,
|
|
2471
|
+
checkedAt: Date.now()
|
|
2472
|
+
});
|
|
2473
|
+
debug("refreshCacheInBackground: refreshed cache to latest=%s", latest);
|
|
2474
|
+
} catch (err) {
|
|
2475
|
+
debug("refreshCacheInBackground: failed — %s", err instanceof Error ? err.message : String(err));
|
|
2476
|
+
}
|
|
2477
|
+
})();
|
|
2478
|
+
}
|
|
2479
|
+
/**
|
|
2480
|
+
* Resolve the cache-hit branch (FRESH / SWR / stale-or-missing). Returns
|
|
2481
|
+
* `null` when the caller must fall through to the blocking-fetch path; returns
|
|
2482
|
+
* a {@link UpdateCheckStatus} when the cache hit is terminal.
|
|
2483
|
+
*
|
|
2484
|
+
* Side effect: kicks off a fire-and-forget {@link refreshCacheInBackground}
|
|
2485
|
+
* when age is in the SWR band [FRESH_MS, STALE_MS).
|
|
2486
|
+
*/
|
|
2487
|
+
function resolveCacheHit(cached, currentVersion, onNag) {
|
|
2488
|
+
if (cached === null) {
|
|
2489
|
+
debug("runUpdateCheck: no cache, fetching");
|
|
2490
|
+
return null;
|
|
2491
|
+
}
|
|
2492
|
+
const age = Date.now() - cached.checkedAt;
|
|
2493
|
+
if (age >= STALE_MS) {
|
|
2494
|
+
debug("runUpdateCheck: cache stale (>=%dh), refetching", STALE_MS / 36e5);
|
|
2495
|
+
return null;
|
|
2496
|
+
}
|
|
2497
|
+
if (age < FRESH_MS) debug("runUpdateCheck: cache fresh (<%dh), serving from cache", FRESH_MS / 36e5);
|
|
2498
|
+
else {
|
|
2499
|
+
debug("runUpdateCheck: cache in SWR band (<%dh), serving + background refresh", STALE_MS / 36e5);
|
|
2500
|
+
refreshCacheInBackground();
|
|
2501
|
+
}
|
|
2502
|
+
if (semver.gt(cached.latest, currentVersion)) {
|
|
2503
|
+
onNag(currentVersion, cached.latest);
|
|
2504
|
+
return "cache-update";
|
|
2505
|
+
}
|
|
2506
|
+
debug("runUpdateCheck: current >= latest, no nag");
|
|
2507
|
+
return "cache-current";
|
|
2508
|
+
}
|
|
2509
|
+
/**
|
|
2445
2510
|
* Run the full update check. Exported for tests; the public surface is
|
|
2446
2511
|
* {@link checkForUpdatesUpfront}. Accepts an optional AbortSignal that
|
|
2447
2512
|
* propagates to the underlying fetch — used by the cancellable spinner.
|
|
@@ -2462,18 +2527,8 @@ async function runUpdateCheck(currentVersion, parentSignal, onNag = displayNag)
|
|
|
2462
2527
|
return "skipped";
|
|
2463
2528
|
}
|
|
2464
2529
|
try {
|
|
2465
|
-
const
|
|
2466
|
-
if (
|
|
2467
|
-
debug("runUpdateCheck: cache fresh (<%dh), skipping fetch", TTL_MS / 36e5);
|
|
2468
|
-
if (semver.gt(cached.latest, currentVersion)) {
|
|
2469
|
-
onNag(currentVersion, cached.latest);
|
|
2470
|
-
return "cache-update";
|
|
2471
|
-
}
|
|
2472
|
-
debug("runUpdateCheck: current >= latest, no nag");
|
|
2473
|
-
return "cache-current";
|
|
2474
|
-
}
|
|
2475
|
-
if (cached) debug("runUpdateCheck: cache stale, refetching");
|
|
2476
|
-
else debug("runUpdateCheck: no cache, fetching");
|
|
2530
|
+
const cacheStatus = resolveCacheHit(await loadCache(), currentVersion, onNag);
|
|
2531
|
+
if (cacheStatus !== null) return cacheStatus;
|
|
2477
2532
|
const latest = await fetchLatest(parentSignal);
|
|
2478
2533
|
if (latest === null) {
|
|
2479
2534
|
debug("runUpdateCheck: fetch returned null, not saving cache");
|
|
@@ -2515,13 +2570,11 @@ async function checkForUpdatesUpfront(currentVersion) {
|
|
|
2515
2570
|
return;
|
|
2516
2571
|
}
|
|
2517
2572
|
const cached = await loadCache();
|
|
2518
|
-
if (cached && Date.now() - cached.checkedAt <
|
|
2519
|
-
|
|
2520
|
-
if (semver.gt(cached.latest, currentVersion)) displayNag(currentVersion, cached.latest);
|
|
2521
|
-
else debug("checkForUpdatesUpfront: current >= latest, no nag");
|
|
2573
|
+
if (cached && Date.now() - cached.checkedAt < STALE_MS) {
|
|
2574
|
+
await runUpdateCheck(currentVersion);
|
|
2522
2575
|
return;
|
|
2523
2576
|
}
|
|
2524
|
-
if (cached) debug("checkForUpdatesUpfront: cache stale, refetching");
|
|
2577
|
+
if (cached) debug("checkForUpdatesUpfront: cache stale (>=%dh), refetching", STALE_MS / 36e5);
|
|
2525
2578
|
else debug("checkForUpdatesUpfront: no cache, fetching");
|
|
2526
2579
|
const stdin = process.stdin;
|
|
2527
2580
|
if (stdin.isTTY !== true || typeof stdin.setRawMode !== "function") {
|