codecortex-ai 0.3.2 → 0.4.1

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/index.js CHANGED
@@ -24,7 +24,7 @@ import {
24
24
  writeManifest,
25
25
  writeModuleDoc,
26
26
  writeSession
27
- } from "../chunk-HGPK53UQ.js";
27
+ } from "../chunk-HAQM7D7F.js";
28
28
 
29
29
  // src/cli/index.ts
30
30
  import { createRequire as createRequire2 } from "module";
@@ -2317,18 +2317,444 @@ function pad3(str, len) {
2317
2317
  return str.length >= len ? str : str + " ".repeat(len - str.length);
2318
2318
  }
2319
2319
 
2320
+ // src/cli/commands/hook.ts
2321
+ import { resolve as resolve9, join as join3 } from "path";
2322
+ import { existsSync as existsSync11 } from "fs";
2323
+ import { readFile as readFile4, writeFile as writeFile2, chmod, unlink } from "fs/promises";
2324
+ import simpleGit3 from "simple-git";
2325
+ var HOOK_START = "# --- codecortex-hook-start ---";
2326
+ var HOOK_END = "# --- codecortex-hook-end ---";
2327
+ var HOOK_TYPES = ["post-commit", "post-merge"];
2328
+ var HOOK_SCRIPT = `
2329
+ ${HOOK_START}
2330
+ # Auto-update CodeCortex knowledge after git operations
2331
+ # Installed by: codecortex hook install
2332
+ (
2333
+ if command -v codecortex >/dev/null 2>&1; then
2334
+ codecortex update >/dev/null 2>&1
2335
+ elif command -v npx >/dev/null 2>&1; then
2336
+ npx codecortex-ai update >/dev/null 2>&1
2337
+ fi
2338
+ ) &
2339
+ ${HOOK_END}
2340
+ `.trimStart();
2341
+ function hasCodeCortexHook(content) {
2342
+ return content.includes(HOOK_START);
2343
+ }
2344
+ function removeCodeCortexHook(content) {
2345
+ const startIdx = content.indexOf(HOOK_START);
2346
+ if (startIdx === -1) return content;
2347
+ const endIdx = content.indexOf(HOOK_END);
2348
+ if (endIdx === -1) return content;
2349
+ const before = content.slice(0, startIdx);
2350
+ const after = content.slice(endIdx + HOOK_END.length);
2351
+ return before + after.replace(/^\n/, "");
2352
+ }
2353
+ function isEmptyHook(content) {
2354
+ const stripped = content.split("\n").filter((line) => {
2355
+ const trimmed = line.trim();
2356
+ return trimmed !== "" && !trimmed.startsWith("#!") && !trimmed.startsWith("#");
2357
+ }).join("");
2358
+ return stripped.length === 0;
2359
+ }
2360
+ async function getGitHooksDir(root) {
2361
+ const git = simpleGit3(root);
2362
+ const gitDir = (await git.revparse(["--git-dir"])).trim();
2363
+ const resolved = resolve9(root, gitDir);
2364
+ return join3(resolved, "hooks");
2365
+ }
2366
+ async function isCodeCortexIgnored(root) {
2367
+ const gitignorePath = join3(root, ".gitignore");
2368
+ if (!existsSync11(gitignorePath)) return false;
2369
+ try {
2370
+ const content = await readFile4(gitignorePath, "utf-8");
2371
+ return content.split("\n").some((line) => {
2372
+ const trimmed = line.trim();
2373
+ return trimmed === ".codecortex" || trimmed === ".codecortex/" || trimmed === ".codecortex/**";
2374
+ });
2375
+ } catch {
2376
+ return false;
2377
+ }
2378
+ }
2379
+ async function hookInstallCommand(opts) {
2380
+ const root = resolve9(opts.root);
2381
+ if (!await isGitRepo(root)) {
2382
+ console.error("Error: not a git repository.");
2383
+ process.exitCode = 1;
2384
+ return;
2385
+ }
2386
+ if (process.platform === "win32") {
2387
+ console.warn("Warning: shell-based git hooks may not work natively on Windows.");
2388
+ console.warn("Consider using WSL or Git Bash.");
2389
+ }
2390
+ const hooksDir = await getGitHooksDir(root);
2391
+ if (await isCodeCortexIgnored(root)) {
2392
+ console.warn("Warning: .codecortex is in .gitignore \u2014 knowledge won't be shared.");
2393
+ console.warn("Remove .codecortex from .gitignore to commit it alongside code.");
2394
+ console.log("");
2395
+ }
2396
+ for (const hookType of HOOK_TYPES) {
2397
+ const hookPath = join3(hooksDir, hookType);
2398
+ let status;
2399
+ if (existsSync11(hookPath)) {
2400
+ const content = await readFile4(hookPath, "utf-8");
2401
+ if (hasCodeCortexHook(content)) {
2402
+ status = "already installed";
2403
+ } else {
2404
+ const newContent = content.trimEnd() + "\n\n" + HOOK_SCRIPT;
2405
+ await writeFile2(hookPath, newContent, "utf-8");
2406
+ await chmod(hookPath, 493);
2407
+ status = "installed";
2408
+ }
2409
+ } else {
2410
+ const content = "#!/bin/sh\n\n" + HOOK_SCRIPT;
2411
+ await writeFile2(hookPath, content, "utf-8");
2412
+ await chmod(hookPath, 493);
2413
+ status = "installed";
2414
+ }
2415
+ console.log(` ${hookType}: ${status}`);
2416
+ }
2417
+ const allNew = true;
2418
+ console.log("");
2419
+ console.log("Knowledge will auto-update after every commit and merge.");
2420
+ }
2421
+ async function hookUninstallCommand(opts) {
2422
+ const root = resolve9(opts.root);
2423
+ if (!await isGitRepo(root)) {
2424
+ console.error("Error: not a git repository.");
2425
+ process.exitCode = 1;
2426
+ return;
2427
+ }
2428
+ const hooksDir = await getGitHooksDir(root);
2429
+ for (const hookType of HOOK_TYPES) {
2430
+ const hookPath = join3(hooksDir, hookType);
2431
+ let status;
2432
+ if (!existsSync11(hookPath)) {
2433
+ status = "not installed";
2434
+ } else {
2435
+ const content = await readFile4(hookPath, "utf-8");
2436
+ if (!hasCodeCortexHook(content)) {
2437
+ status = "not installed";
2438
+ } else {
2439
+ const cleaned = removeCodeCortexHook(content);
2440
+ if (isEmptyHook(cleaned)) {
2441
+ await unlink(hookPath);
2442
+ } else {
2443
+ await writeFile2(hookPath, cleaned, "utf-8");
2444
+ }
2445
+ status = "removed";
2446
+ }
2447
+ }
2448
+ console.log(` ${hookType}: ${status}`);
2449
+ }
2450
+ }
2451
+ async function hookStatusCommand(opts) {
2452
+ const root = resolve9(opts.root);
2453
+ if (!await isGitRepo(root)) {
2454
+ console.error("Error: not a git repository.");
2455
+ process.exitCode = 1;
2456
+ return;
2457
+ }
2458
+ const hooksDir = await getGitHooksDir(root);
2459
+ for (const hookType of HOOK_TYPES) {
2460
+ const hookPath = join3(hooksDir, hookType);
2461
+ let installed = false;
2462
+ if (existsSync11(hookPath)) {
2463
+ const content = await readFile4(hookPath, "utf-8");
2464
+ installed = hasCodeCortexHook(content);
2465
+ }
2466
+ console.log(` ${hookType}: ${installed ? "installed" : "not installed"}`);
2467
+ }
2468
+ const manifest = await readManifest(root);
2469
+ if (manifest) {
2470
+ const lastUpdated = new Date(manifest.lastUpdated);
2471
+ const ageHours = Math.floor((Date.now() - lastUpdated.getTime()) / (1e3 * 60 * 60));
2472
+ const ageLabel = ageHours < 1 ? "just now" : ageHours < 24 ? `${ageHours} hour${ageHours === 1 ? "" : "s"} ago` : `${Math.floor(ageHours / 24)} day${Math.floor(ageHours / 24) === 1 ? "" : "s"} ago`;
2473
+ console.log(` Knowledge: last updated ${ageLabel}`);
2474
+ } else {
2475
+ console.log(" Knowledge: not initialized (run codecortex init)");
2476
+ }
2477
+ }
2478
+
2479
+ // src/cli/commands/upgrade.ts
2480
+ import { execSync as execSync2 } from "child_process";
2481
+
2482
+ // src/cli/utils/version-check.ts
2483
+ import { tmpdir } from "os";
2484
+ import { join as join4 } from "path";
2485
+ import { readFileSync, writeFileSync } from "fs";
2486
+ var CACHE_FILE = join4(tmpdir(), "codecortex-update-check.json");
2487
+ var CACHE_TTL = 24 * 60 * 60 * 1e3;
2488
+ var REGISTRY_URL = "https://registry.npmjs.org/codecortex-ai/latest";
2489
+ var FETCH_TIMEOUT = 3e3;
2490
+ function readCache() {
2491
+ try {
2492
+ const raw = readFileSync(CACHE_FILE, "utf-8");
2493
+ const data = JSON.parse(raw);
2494
+ if (typeof data === "object" && data !== null && "latest" in data && typeof data.latest === "string" && "lastCheck" in data && typeof data.lastCheck === "number") {
2495
+ return data;
2496
+ }
2497
+ return null;
2498
+ } catch {
2499
+ return null;
2500
+ }
2501
+ }
2502
+ function writeCache(latest) {
2503
+ try {
2504
+ writeFileSync(CACHE_FILE, JSON.stringify({ latest, lastCheck: Date.now() }));
2505
+ } catch {
2506
+ }
2507
+ }
2508
+ function compareVersions(current, latest) {
2509
+ const parse = (v) => v.replace(/^v/, "").split(".").map(Number);
2510
+ const c = parse(current);
2511
+ const l = parse(latest);
2512
+ const cMaj = c[0] ?? 0, cMin = c[1] ?? 0, cPatch = c[2] ?? 0;
2513
+ const lMaj = l[0] ?? 0, lMin = l[1] ?? 0, lPatch = l[2] ?? 0;
2514
+ if (lMaj !== cMaj) return lMaj > cMaj;
2515
+ if (lMin !== cMin) return lMin > cMin;
2516
+ return lPatch > cPatch;
2517
+ }
2518
+ async function fetchLatestVersion() {
2519
+ try {
2520
+ const res = await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(FETCH_TIMEOUT) });
2521
+ if (!res.ok) return null;
2522
+ const data = await res.json();
2523
+ return data.version ?? null;
2524
+ } catch {
2525
+ return null;
2526
+ }
2527
+ }
2528
+ async function checkForUpdate(currentVersion) {
2529
+ const cached = readCache();
2530
+ if (cached && Date.now() - cached.lastCheck < CACHE_TTL) {
2531
+ return {
2532
+ current: currentVersion,
2533
+ latest: cached.latest,
2534
+ isOutdated: compareVersions(currentVersion, cached.latest)
2535
+ };
2536
+ }
2537
+ const latest = await fetchLatestVersion();
2538
+ if (!latest) return null;
2539
+ writeCache(latest);
2540
+ return {
2541
+ current: currentVersion,
2542
+ latest,
2543
+ isOutdated: compareVersions(currentVersion, latest)
2544
+ };
2545
+ }
2546
+ function detectPackageManager() {
2547
+ const ua = process.env.npm_config_user_agent ?? "";
2548
+ if (ua.startsWith("yarn")) return "yarn";
2549
+ if (ua.startsWith("pnpm")) return "pnpm";
2550
+ if (ua.startsWith("bun")) return "bun";
2551
+ const bin = process.argv[1] ?? "";
2552
+ if (bin.includes("yarn")) return "yarn";
2553
+ if (bin.includes("pnpm")) return "pnpm";
2554
+ if (bin.includes("bun")) return "bun";
2555
+ return "npm";
2556
+ }
2557
+ function getUpgradeCommand() {
2558
+ const pm = detectPackageManager();
2559
+ switch (pm) {
2560
+ case "yarn":
2561
+ return "yarn global add codecortex-ai@latest";
2562
+ case "pnpm":
2563
+ return "pnpm add -g codecortex-ai@latest";
2564
+ case "bun":
2565
+ return "bun add -g codecortex-ai@latest";
2566
+ default:
2567
+ return "npm install -g codecortex-ai@latest";
2568
+ }
2569
+ }
2570
+ function shouldNotify() {
2571
+ if (process.env.CI || process.env.BUILD_NUMBER || process.env.RUN_ID) return false;
2572
+ if (process.env.NO_UPDATE_NOTIFIER) return false;
2573
+ if (process.env.NODE_ENV === "test") return false;
2574
+ if (!process.stderr.isTTY) return false;
2575
+ return true;
2576
+ }
2577
+ function renderUpdateNotification(current, latest) {
2578
+ const cmd = getUpgradeCommand();
2579
+ const yellow = "\x1B[33m";
2580
+ const cyan = "\x1B[36m";
2581
+ const dim = "\x1B[2m";
2582
+ const reset = "\x1B[0m";
2583
+ const bold = "\x1B[1m";
2584
+ const line1Text = `Update available: ${current} \u2192 ${latest}`;
2585
+ const line2Text = `Run ${cmd}`;
2586
+ const contentWidth = Math.max(line1Text.length, line2Text.length);
2587
+ const innerWidth = contentWidth + 6;
2588
+ const rpad = (text) => " ".repeat(Math.max(0, contentWidth - text.length + 3));
2589
+ const msg = [
2590
+ "",
2591
+ `${dim}\u256D${"\u2500".repeat(innerWidth)}\u256E${reset}`,
2592
+ `${dim}\u2502${reset}${" ".repeat(innerWidth)}${dim}\u2502${reset}`,
2593
+ `${dim}\u2502${reset} ${yellow}Update available:${reset} ${dim}${current}${reset} \u2192 ${cyan}${bold}${latest}${reset}${rpad(line1Text)}${dim}\u2502${reset}`,
2594
+ `${dim}\u2502${reset} Run ${cyan}${cmd}${reset}${rpad(line2Text)}${dim}\u2502${reset}`,
2595
+ `${dim}\u2502${reset}${" ".repeat(innerWidth)}${dim}\u2502${reset}`,
2596
+ `${dim}\u2570${"\u2500".repeat(innerWidth)}\u256F${reset}`,
2597
+ ""
2598
+ ].join("\n");
2599
+ process.stderr.write(msg);
2600
+ }
2601
+
2602
+ // src/cli/commands/upgrade.ts
2603
+ async function upgradeCommand(currentVersion) {
2604
+ console.log("Checking for updates...");
2605
+ console.log("");
2606
+ const result = await checkForUpdate(currentVersion);
2607
+ if (!result) {
2608
+ console.log("Could not reach the npm registry. Check your internet connection.");
2609
+ return;
2610
+ }
2611
+ if (!result.isOutdated) {
2612
+ console.log(`Already on the latest version (${result.current}).`);
2613
+ return;
2614
+ }
2615
+ const cmd = getUpgradeCommand();
2616
+ console.log(`Update available: ${result.current} \u2192 ${result.latest}`);
2617
+ console.log("");
2618
+ console.log(`Running: ${cmd}`);
2619
+ console.log("");
2620
+ try {
2621
+ execSync2(cmd, { stdio: "inherit" });
2622
+ console.log("");
2623
+ console.log(`Successfully upgraded to ${result.latest}!`);
2624
+ } catch {
2625
+ console.error("");
2626
+ console.error("Upgrade failed. Try running manually:");
2627
+ console.error(` ${cmd}`);
2628
+ console.error("");
2629
+ console.error("If you get a permission error, try:");
2630
+ console.error(` sudo ${cmd}`);
2631
+ }
2632
+ }
2633
+
2634
+ // src/cli/grouped-help.ts
2635
+ var COMMAND_GROUPS = [
2636
+ { title: "Core", commands: ["init", "serve", "update", "status"] },
2637
+ { title: "Query", commands: ["symbols", "search", "modules", "hotspots"] },
2638
+ { title: "Utility", commands: ["hook", "upgrade"] }
2639
+ ];
2640
+ function formatHelp(cmd, helper) {
2641
+ if (cmd.parent) {
2642
+ return defaultFormatHelp(cmd, helper);
2643
+ }
2644
+ const termWidth = helper.padWidth(cmd, helper);
2645
+ const helpWidth = helper.helpWidth ?? 80;
2646
+ const item = (term, desc2) => helper.formatItem(term, termWidth, desc2, helper);
2647
+ const output = [
2648
+ `${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`,
2649
+ ""
2650
+ ];
2651
+ const desc = helper.commandDescription(cmd);
2652
+ if (desc) {
2653
+ output.push(helper.boxWrap(helper.styleCommandDescription(desc), helpWidth), "");
2654
+ }
2655
+ const opts = helper.visibleOptions(cmd);
2656
+ if (opts.length) {
2657
+ output.push(helper.styleTitle("Options:"));
2658
+ for (const opt of opts) {
2659
+ output.push(item(
2660
+ helper.styleOptionTerm(helper.optionTerm(opt)),
2661
+ helper.styleOptionDescription(helper.optionDescription(opt))
2662
+ ));
2663
+ }
2664
+ output.push("");
2665
+ }
2666
+ const allCmds = helper.visibleCommands(cmd);
2667
+ const cmdByName = new Map(allCmds.map((c) => [c.name(), c]));
2668
+ for (const group of COMMAND_GROUPS) {
2669
+ const groupCmds = group.commands.map((name) => cmdByName.get(name)).filter((c) => c !== void 0);
2670
+ if (!groupCmds.length) continue;
2671
+ output.push(helper.styleTitle(`${group.title}:`));
2672
+ for (const c of groupCmds) {
2673
+ output.push(item(
2674
+ helper.styleSubcommandTerm(helper.subcommandTerm(c)),
2675
+ helper.styleSubcommandDescription(helper.subcommandDescription(c))
2676
+ ));
2677
+ }
2678
+ output.push("");
2679
+ for (const c of groupCmds) cmdByName.delete(c.name());
2680
+ }
2681
+ if (cmdByName.size) {
2682
+ for (const c of cmdByName.values()) {
2683
+ output.push(item(
2684
+ helper.styleSubcommandTerm(helper.subcommandTerm(c)),
2685
+ helper.styleSubcommandDescription(helper.subcommandDescription(c))
2686
+ ));
2687
+ }
2688
+ output.push("");
2689
+ }
2690
+ return output.join("\n");
2691
+ }
2692
+ function defaultFormatHelp(cmd, helper) {
2693
+ const termWidth = helper.padWidth(cmd, helper);
2694
+ const helpWidth = helper.helpWidth ?? 80;
2695
+ const item = (term, desc2) => helper.formatItem(term, termWidth, desc2, helper);
2696
+ const output = [
2697
+ `${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`,
2698
+ ""
2699
+ ];
2700
+ const desc = helper.commandDescription(cmd);
2701
+ if (desc) {
2702
+ output.push(helper.boxWrap(helper.styleCommandDescription(desc), helpWidth), "");
2703
+ }
2704
+ const opts = helper.visibleOptions(cmd);
2705
+ if (opts.length) {
2706
+ output.push(helper.styleTitle("Options:"));
2707
+ for (const opt of opts) {
2708
+ output.push(item(
2709
+ helper.styleOptionTerm(helper.optionTerm(opt)),
2710
+ helper.styleOptionDescription(helper.optionDescription(opt))
2711
+ ));
2712
+ }
2713
+ output.push("");
2714
+ }
2715
+ const cmds = helper.visibleCommands(cmd);
2716
+ if (cmds.length) {
2717
+ output.push(helper.styleTitle("Commands:"));
2718
+ for (const c of cmds) {
2719
+ output.push(item(
2720
+ helper.styleSubcommandTerm(helper.subcommandTerm(c)),
2721
+ helper.styleSubcommandDescription(helper.subcommandDescription(c))
2722
+ ));
2723
+ }
2724
+ output.push("");
2725
+ }
2726
+ return output.join("\n");
2727
+ }
2728
+
2320
2729
  // src/cli/index.ts
2321
2730
  var require3 = createRequire2(import.meta.url);
2322
2731
  var { version } = require3("../../package.json");
2732
+ var updateCheckPromise = shouldNotify() ? checkForUpdate(version).catch(() => null) : Promise.resolve(null);
2323
2733
  var program = new Command();
2324
- program.name("codecortex").description("Persistent, AI-powered codebase knowledge layer").version(version);
2325
- program.command("init").description("Initialize codebase knowledge: discover files, extract symbols, analyze git history").option("-r, --root <path>", "Project root directory", process.cwd()).option("-d, --days <number>", "Days of git history to analyze", "90").action(initCommand);
2326
- program.command("serve").description("Start MCP server (stdio transport) for AI agent access").option("-r, --root <path>", "Project root directory", process.cwd()).action(serveCommand);
2327
- program.command("update").description("Update knowledge for changed files since last session").option("-r, --root <path>", "Project root directory", process.cwd()).option("-d, --days <number>", "Days of git history to re-analyze", "90").action(updateCommand);
2328
- program.command("status").description("Show knowledge freshness, stale modules, and symbol counts").option("-r, --root <path>", "Project root directory", process.cwd()).action(statusCommand);
2734
+ program.name("codecortex").description("Permanent codebase memory for AI agents \u2014 extracts symbols, deps, and patterns, serves via MCP").version(version).configureHelp({ formatHelp });
2735
+ program.command("init").description("Initialize knowledge: discover files, extract symbols, analyze git").option("-r, --root <path>", "Project root directory", process.cwd()).option("-d, --days <number>", "Days of git history to analyze", "90").action(initCommand);
2736
+ program.command("serve").description("Start MCP server for AI agent access").option("-r, --root <path>", "Project root directory", process.cwd()).action(serveCommand);
2737
+ program.command("update").description("Update knowledge for changed files").option("-r, --root <path>", "Project root directory", process.cwd()).option("-d, --days <number>", "Days of git history to re-analyze", "90").action(updateCommand);
2738
+ program.command("status").description("Show knowledge freshness and symbol counts").option("-r, --root <path>", "Project root directory", process.cwd()).action(statusCommand);
2329
2739
  program.command("symbols [query]").description("Browse and filter the symbol index").option("-r, --root <path>", "Project root directory", process.cwd()).option("-k, --kind <kind>", "Filter by kind: function, class, interface, type, const, enum, method, property, variable").option("-f, --file <path>", "Filter by file path (partial match)").option("-e, --exported", "Show only exported symbols").option("-l, --limit <number>", "Max results", "30").action((query, opts) => symbolsCommand(query, opts));
2330
- program.command("search <query>").description("Search across all CodeCortex knowledge files").option("-r, --root <path>", "Project root directory", process.cwd()).option("-l, --limit <number>", "Max results", "20").action((query, opts) => searchCommand(query, opts));
2331
- program.command("modules [name]").description("List modules or deep-dive into a specific module").option("-r, --root <path>", "Project root directory", process.cwd()).action((name, opts) => modulesCommand(name, opts));
2332
- program.command("hotspots").description("Show files ranked by risk: churn + coupling + bug history").option("-r, --root <path>", "Project root directory", process.cwd()).option("-l, --limit <number>", "Number of files to show", "15").action(hotspotsCommand);
2333
- program.parse();
2740
+ program.command("search <query>").description("Search across all knowledge files").option("-r, --root <path>", "Project root directory", process.cwd()).option("-l, --limit <number>", "Max results", "20").action((query, opts) => searchCommand(query, opts));
2741
+ program.command("modules [name]").description("List modules or deep-dive into one").option("-r, --root <path>", "Project root directory", process.cwd()).action((name, opts) => modulesCommand(name, opts));
2742
+ program.command("hotspots").description("Files ranked by risk: churn + coupling + bugs").option("-r, --root <path>", "Project root directory", process.cwd()).option("-l, --limit <number>", "Number of files to show", "15").action(hotspotsCommand);
2743
+ var hook = program.command("hook").description("Manage git hooks for auto-updating knowledge");
2744
+ hook.command("install").description("Install post-commit and post-merge hooks").option("-r, --root <path>", "Project root directory", process.cwd()).action(hookInstallCommand);
2745
+ hook.command("uninstall").description("Remove CodeCortex hooks (preserves other hooks)").option("-r, --root <path>", "Project root directory", process.cwd()).action(hookUninstallCommand);
2746
+ hook.command("status").description("Show hook installation state and knowledge freshness").option("-r, --root <path>", "Project root directory", process.cwd()).action(hookStatusCommand);
2747
+ program.command("upgrade").description("Check for and install the latest version").action(() => upgradeCommand(version));
2748
+ async function main() {
2749
+ await program.parseAsync();
2750
+ const commandName = program.args[0];
2751
+ if (commandName !== "serve" && commandName !== "upgrade") {
2752
+ const result = await updateCheckPromise;
2753
+ if (result?.isOutdated) {
2754
+ renderUpdateNotification(result.current, result.latest);
2755
+ }
2756
+ }
2757
+ }
2758
+ main().catch(() => {
2759
+ });
2334
2760
  //# sourceMappingURL=index.js.map