@grekt/cli 6.39.0 → 6.40.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.
Files changed (2) hide show
  1. package/dist/index.js +378 -15
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -91853,6 +91853,9 @@ var INDEX_FILE = join8(GREKT_DIR, "index");
91853
91853
 
91854
91854
  // src/shared/filesystem/filesystem.ts
91855
91855
  import { dirname as dirname3, join as join9 } from "path";
91856
+ function normalizePath(path8) {
91857
+ return path8.replace(/\\/g, "/");
91858
+ }
91856
91859
  function ensureDir(filepath) {
91857
91860
  const dir = dirname3(filepath);
91858
91861
  if (!fs.exists(dir)) {
@@ -102326,6 +102329,24 @@ async function loadWorkspace(cwd) {
102326
102329
  artifacts: discovered.artifacts
102327
102330
  };
102328
102331
  }
102332
+ function generateWorkspaceFile(root, artifacts) {
102333
+ const workspacePath = join29(root, "pnpm-workspace.yaml");
102334
+ const rootPackageJsonPath = join29(root, "package.json");
102335
+ const relativePaths = artifacts.map((artifact) => artifact.relativePath);
102336
+ fs.writeFile(workspacePath, $stringify2({ packages: relativePaths }));
102337
+ fs.writeFile(rootPackageJsonPath, JSON.stringify({ name: "workspace-root", private: true }, null, 2) + `
102338
+ `);
102339
+ }
102340
+ function cleanWorkspaceFile(root) {
102341
+ const workspacePath = join29(root, "pnpm-workspace.yaml");
102342
+ const rootPackageJsonPath = join29(root, "package.json");
102343
+ if (fs.exists(workspacePath)) {
102344
+ fs.unlink(workspacePath);
102345
+ }
102346
+ if (fs.exists(rootPackageJsonPath)) {
102347
+ fs.unlink(rootPackageJsonPath);
102348
+ }
102349
+ }
102329
102350
  function generatePackageJsonFiles(artifacts) {
102330
102351
  for (const artifact of artifacts) {
102331
102352
  const packageJsonPath = join29(artifact.path, "package.json");
@@ -103268,11 +103289,12 @@ async function handleExecMode(options2) {
103268
103289
  info(`Would run: ${command}`);
103269
103290
  return;
103270
103291
  }
103271
- const genSpin = spinner("Generating package.json files...");
103292
+ const genSpin = spinner("Generating workspace config files...");
103272
103293
  genSpin.start();
103294
+ generateWorkspaceFile(cwd, workspace.artifacts);
103273
103295
  generatePackageJsonFiles(workspace.artifacts);
103274
103296
  genSpin.stop();
103275
- success(`Generated ${workspace.artifacts.length} package.json file(s)`);
103297
+ success("Generated workspace config files");
103276
103298
  log("");
103277
103299
  info(`Running: ${command}`);
103278
103300
  log("");
@@ -103282,6 +103304,7 @@ async function handleExecMode(options2) {
103282
103304
  stdio: "inherit"
103283
103305
  });
103284
103306
  if (result.status !== 0) {
103307
+ cleanWorkspaceFile(cwd);
103285
103308
  cleanPackageJsonFiles(workspace.artifacts);
103286
103309
  error(`Command failed with exit code ${result.status}`);
103287
103310
  process.exit(result.status ?? 1);
@@ -103292,6 +103315,7 @@ async function handleExecMode(options2) {
103292
103315
  const updatedWorkspace = await loadWorkspace(cwd);
103293
103316
  if (!updatedWorkspace) {
103294
103317
  syncSpin.stop();
103318
+ cleanWorkspaceFile(cwd);
103295
103319
  cleanPackageJsonFiles(workspace.artifacts);
103296
103320
  error("Failed to reload workspace");
103297
103321
  process.exit(1);
@@ -103305,9 +103329,10 @@ async function handleExecMode(options2) {
103305
103329
  }
103306
103330
  const cleanSpin = spinner("Cleaning up...");
103307
103331
  cleanSpin.start();
103332
+ cleanWorkspaceFile(cwd);
103308
103333
  cleanPackageJsonFiles(workspace.artifacts);
103309
103334
  cleanSpin.stop();
103310
- success("Removed temporary package.json files");
103335
+ success("Removed temporary config files");
103311
103336
  log("");
103312
103337
  success("Version update complete");
103313
103338
  }
@@ -103332,6 +103357,343 @@ function findArtifacts(basePath) {
103332
103357
  return artifacts;
103333
103358
  }
103334
103359
 
103360
+ // src/commands/changelog/git.ts
103361
+ function exec(args) {
103362
+ return shell.execFile("git", args).trim();
103363
+ }
103364
+ function execOrNull(args) {
103365
+ try {
103366
+ const result = exec(args);
103367
+ return result || null;
103368
+ } catch {
103369
+ return null;
103370
+ }
103371
+ }
103372
+ function splitLines(output) {
103373
+ if (!output)
103374
+ return [];
103375
+ return output.split(`
103376
+ `).map((line) => line.trim()).filter(Boolean);
103377
+ }
103378
+ function detectDefaultBranch() {
103379
+ const symbolicRef = execOrNull([
103380
+ "symbolic-ref",
103381
+ "refs/remotes/origin/HEAD"
103382
+ ]);
103383
+ if (symbolicRef) {
103384
+ const parts = symbolicRef.split("/");
103385
+ return parts[parts.length - 1] ?? "main";
103386
+ }
103387
+ return "main";
103388
+ }
103389
+ function getFirstCommit() {
103390
+ return execOrNull(["rev-list", "--max-parents=0", "HEAD"]);
103391
+ }
103392
+ function detectBaseRef(overrideSince) {
103393
+ if (overrideSince) {
103394
+ const resolved = execOrNull(["rev-parse", "--verify", overrideSince]);
103395
+ if (!resolved) {
103396
+ throw new Error(`Invalid ref: ${overrideSince}`);
103397
+ }
103398
+ return overrideSince;
103399
+ }
103400
+ const currentBranch = execOrNull(["rev-parse", "--abbrev-ref", "HEAD"]);
103401
+ const defaultBranch = detectDefaultBranch();
103402
+ const isDefaultBranch = currentBranch === defaultBranch || currentBranch === "HEAD";
103403
+ if (isDefaultBranch) {
103404
+ return null;
103405
+ }
103406
+ const hasRemote = execOrNull(["remote"]);
103407
+ if (hasRemote) {
103408
+ return `origin/${defaultBranch}`;
103409
+ }
103410
+ warning("No remote found, falling back to local refs");
103411
+ return defaultBranch;
103412
+ }
103413
+ function detectArtifactBaseRef(artifactName) {
103414
+ const lastTag = execOrNull([
103415
+ "describe",
103416
+ "--tags",
103417
+ "--abbrev=0",
103418
+ "--match",
103419
+ `${artifactName}@*`
103420
+ ]);
103421
+ if (lastTag)
103422
+ return lastTag;
103423
+ const firstCommit = getFirstCommit();
103424
+ if (firstCommit)
103425
+ return firstCommit;
103426
+ warning(`${artifactName}: no tags found, falling back to HEAD~1`);
103427
+ return "HEAD~1";
103428
+ }
103429
+ function getChangedFiles(baseRef, path8) {
103430
+ const baseArgs = ["diff", "--name-only"];
103431
+ const pathFilter = path8 ? ["--", path8] : [];
103432
+ const output = execOrNull([...baseArgs, `${baseRef}...HEAD`, ...pathFilter]) ?? execOrNull([...baseArgs, baseRef, "HEAD", ...pathFilter]);
103433
+ return splitLines(output);
103434
+ }
103435
+ function getCommitsForPath(baseRef, path8) {
103436
+ const output = execOrNull([
103437
+ "log",
103438
+ "--format=%H %s",
103439
+ `${baseRef}..HEAD`,
103440
+ "--",
103441
+ path8
103442
+ ]);
103443
+ return splitLines(output);
103444
+ }
103445
+
103446
+ // src/commands/changelog/conventional-commits.ts
103447
+ var CONVENTIONAL_COMMIT_REGEX = /^([a-f0-9]+)\s+(\w+)(\(.+?\))?(!)?\s*:\s*(.+)$/;
103448
+ function parseConventionalCommit(line) {
103449
+ if (line.includes("\x00"))
103450
+ return null;
103451
+ const match = line.match(CONVENTIONAL_COMMIT_REGEX);
103452
+ if (!match)
103453
+ return null;
103454
+ const hash = match[1] ?? "";
103455
+ const type = match[2] ?? "";
103456
+ const scopeRaw = match[3];
103457
+ const bang = match[4];
103458
+ const message = match[5] ?? "";
103459
+ const scope = scopeRaw ? scopeRaw.slice(1, -1) : null;
103460
+ const breaking = bang === "!" || message.toUpperCase().includes("BREAKING CHANGE");
103461
+ return {
103462
+ hash,
103463
+ type,
103464
+ scope,
103465
+ breaking,
103466
+ message,
103467
+ raw: line
103468
+ };
103469
+ }
103470
+ function determineBumpType(commits) {
103471
+ if (commits.some((commit) => commit.breaking))
103472
+ return "major";
103473
+ if (commits.some((commit) => commit.type === "feat"))
103474
+ return "minor";
103475
+ return "patch";
103476
+ }
103477
+ function mapFilesToArtifacts(changedFiles, artifacts) {
103478
+ const result = new Map;
103479
+ for (const file of changedFiles) {
103480
+ for (const artifact of artifacts) {
103481
+ const normalized = normalizePath(artifact.relativePath);
103482
+ const prefix = normalized.endsWith("/") ? normalized : `${normalized}/`;
103483
+ if (file.startsWith(prefix)) {
103484
+ const existing = result.get(artifact.relativePath) ?? [];
103485
+ existing.push(file);
103486
+ result.set(artifact.relativePath, existing);
103487
+ break;
103488
+ }
103489
+ }
103490
+ }
103491
+ return result;
103492
+ }
103493
+
103494
+ // src/commands/changelog/changeset-output.ts
103495
+ import { join as join31 } from "path";
103496
+ import { randomBytes as randomBytes3 } from "crypto";
103497
+ var CHANGESET_DIR = ".changeset";
103498
+ function generateChangesetFile(artifacts, workspaceRoot) {
103499
+ const changesetDir = join31(workspaceRoot, CHANGESET_DIR);
103500
+ if (!fs.exists(changesetDir)) {
103501
+ fs.mkdir(changesetDir, { recursive: true });
103502
+ }
103503
+ const filename = `${randomBytes3(4).toString("hex")}.md`;
103504
+ const filepath = join31(changesetDir, filename);
103505
+ const content = buildChangesetContent(artifacts);
103506
+ fs.writeFile(filepath, content);
103507
+ return filepath;
103508
+ }
103509
+ function buildChangesetContent(artifacts) {
103510
+ const frontmatterLines = [];
103511
+ const bodyLines = [];
103512
+ for (const entry of artifacts) {
103513
+ const { name: name2 } = entry.artifact.manifest;
103514
+ frontmatterLines.push(`"${name2}": ${entry.calculatedBump}`);
103515
+ if (entry.commits.length > 0) {
103516
+ for (const commit of entry.commits) {
103517
+ bodyLines.push(`- ${name2}: ${commit.type}: ${commit.message}`);
103518
+ }
103519
+ } else {
103520
+ bodyLines.push(`- ${name2}: changed files detected`);
103521
+ }
103522
+ }
103523
+ return ["---", ...frontmatterLines, "---", "", ...bodyLines, ""].join(`
103524
+ `);
103525
+ }
103526
+ function previewChangesetContent(artifacts) {
103527
+ return buildChangesetContent(artifacts);
103528
+ }
103529
+ function toOutputEntry(entry) {
103530
+ return {
103531
+ name: entry.artifact.manifest.name,
103532
+ version: entry.artifact.manifest.version,
103533
+ bump: entry.calculatedBump,
103534
+ commits: entry.commits.map((commit) => ({
103535
+ hash: commit.hash,
103536
+ type: commit.type,
103537
+ scope: commit.scope,
103538
+ breaking: commit.breaking,
103539
+ message: commit.message
103540
+ })),
103541
+ changedFiles: entry.changedFiles
103542
+ };
103543
+ }
103544
+ function formatJson(artifacts, baseRef) {
103545
+ return JSON.stringify({ baseRef, artifacts: artifacts.map(toOutputEntry) }, null, 2);
103546
+ }
103547
+ function formatYaml(artifacts, baseRef) {
103548
+ return $stringify2({
103549
+ baseRef,
103550
+ artifacts: artifacts.map(toOutputEntry)
103551
+ });
103552
+ }
103553
+
103554
+ // src/commands/changelog/changelog.ts
103555
+ var BUMP_CHOICES = [
103556
+ { name: "patch", value: "patch" },
103557
+ { name: "minor", value: "minor" },
103558
+ { name: "major", value: "major" },
103559
+ { name: "skip", value: "skip" }
103560
+ ];
103561
+ var changelogCommand = new Command("changelog").description("Generate changesets from git history for workspace artifacts").option("--ci", "Unattended mode (no prompts, auto-generate from commits)").option("--format <format>", "Output format: changeset (default), json, yaml", "changeset").option("--since <ref>", "Override base ref (auto-detected otherwise)").option("--dry-run", "Preview without writing").action(async (options2) => {
103562
+ const cwd = process.cwd();
103563
+ if (!isWorkspaceRoot(fs, cwd)) {
103564
+ error("Not a workspace (grekt-workspace.yaml not found)");
103565
+ info("Run this command from your workspace root");
103566
+ process.exit(1);
103567
+ }
103568
+ const workspace = await loadWorkspace(cwd);
103569
+ if (!workspace || workspace.artifacts.length === 0) {
103570
+ error("No artifacts found in workspace");
103571
+ process.exit(1);
103572
+ }
103573
+ const globalBaseRef = detectBaseRef(options2.since);
103574
+ const artifactChangelogs = globalBaseRef ? buildFromGlobalRef(workspace.artifacts, globalBaseRef, options2.ci) : buildPerArtifact(workspace.artifacts, options2.ci);
103575
+ if (artifactChangelogs.length === 0) {
103576
+ info("No artifact changes detected");
103577
+ process.exit(0);
103578
+ }
103579
+ const displayRef = globalBaseRef ?? "per-artifact tags";
103580
+ if (options2.ci) {
103581
+ printSummary(artifactChangelogs, displayRef);
103582
+ outputResult(artifactChangelogs, displayRef, cwd, options2);
103583
+ } else {
103584
+ await withPromptHandler(() => handleInteractiveMode(artifactChangelogs, displayRef, cwd, options2));
103585
+ }
103586
+ });
103587
+ function buildFromGlobalRef(artifacts, baseRef, ciMode) {
103588
+ const changedFiles = getChangedFiles(baseRef);
103589
+ if (changedFiles.length === 0)
103590
+ return [];
103591
+ const filesByArtifact = mapFilesToArtifacts(changedFiles, artifacts);
103592
+ const result = [];
103593
+ for (const artifact of artifacts) {
103594
+ const files = filesByArtifact.get(artifact.relativePath);
103595
+ if (!files)
103596
+ continue;
103597
+ result.push(buildArtifactChangelog(artifact, files, baseRef, ciMode));
103598
+ }
103599
+ return result;
103600
+ }
103601
+ function buildPerArtifact(artifacts, ciMode) {
103602
+ const result = [];
103603
+ for (const artifact of artifacts) {
103604
+ const baseRef = detectArtifactBaseRef(artifact.manifest.name);
103605
+ const changedFiles = getChangedFiles(baseRef, artifact.relativePath);
103606
+ if (changedFiles.length === 0)
103607
+ continue;
103608
+ result.push(buildArtifactChangelog(artifact, changedFiles, baseRef, ciMode));
103609
+ }
103610
+ return result;
103611
+ }
103612
+ function buildArtifactChangelog(artifact, changedFiles, baseRef, ciMode) {
103613
+ const commitLines = getCommitsForPath(baseRef, artifact.relativePath);
103614
+ const commits = commitLines.map(parseConventionalCommit).filter((commit) => commit !== null);
103615
+ const nonConventionalCount = commitLines.length - commits.length;
103616
+ if (nonConventionalCount > 0 && ciMode) {
103617
+ warning(`${artifact.manifest.name}: ${nonConventionalCount} non-conventional commit(s) ignored`);
103618
+ }
103619
+ const calculatedBump = commits.length > 0 ? determineBumpType(commits) : "patch";
103620
+ if (commits.length === 0 && ciMode) {
103621
+ warning(`${artifact.manifest.name}: no conventional commits found, defaulting to patch`);
103622
+ }
103623
+ return {
103624
+ artifact,
103625
+ commits,
103626
+ calculatedBump,
103627
+ changedFiles
103628
+ };
103629
+ }
103630
+ function printSummary(artifactChangelogs, baseRef) {
103631
+ newline();
103632
+ info(`Base ref: ${colors5.highlight(baseRef)}`);
103633
+ info(`${artifactChangelogs.length} artifact(s) with changes:`);
103634
+ newline();
103635
+ for (const entry of artifactChangelogs) {
103636
+ const { name: name2, version: version3 } = entry.artifact.manifest;
103637
+ log(` ${name2} ${colors5.dim(`v${version3}`)} ${symbols.arrow} ${colors5.bold(entry.calculatedBump)} ${colors5.dim(`(${entry.commits.length} commit(s))`)}`);
103638
+ }
103639
+ newline();
103640
+ }
103641
+ async function handleInteractiveMode(artifactChangelogs, baseRef, cwd, options2) {
103642
+ printSummary(artifactChangelogs, baseRef);
103643
+ const finalChangelogs = [];
103644
+ for (const entry of artifactChangelogs) {
103645
+ const { name: name2 } = entry.artifact.manifest;
103646
+ const bump = await esm_default6({
103647
+ message: `${name2}: bump type?`,
103648
+ choices: BUMP_CHOICES,
103649
+ default: entry.calculatedBump
103650
+ });
103651
+ if (bump === "skip") {
103652
+ info(`Skipping ${name2}`);
103653
+ continue;
103654
+ }
103655
+ finalChangelogs.push({
103656
+ ...entry,
103657
+ calculatedBump: bump
103658
+ });
103659
+ }
103660
+ if (finalChangelogs.length === 0) {
103661
+ newline();
103662
+ info("All artifacts skipped");
103663
+ return;
103664
+ }
103665
+ newline();
103666
+ const confirmed = await esm_default3({
103667
+ message: `Generate changeset for ${finalChangelogs.length} artifact(s)?`,
103668
+ default: true
103669
+ });
103670
+ if (!confirmed) {
103671
+ info("Cancelled");
103672
+ return;
103673
+ }
103674
+ outputResult(finalChangelogs, baseRef, cwd, options2);
103675
+ }
103676
+ function outputResult(artifactChangelogs, baseRef, cwd, options2) {
103677
+ const format = options2.format ?? "changeset";
103678
+ if (format === "json") {
103679
+ log(formatJson(artifactChangelogs, baseRef));
103680
+ return;
103681
+ }
103682
+ if (format === "yaml") {
103683
+ log(formatYaml(artifactChangelogs, baseRef));
103684
+ return;
103685
+ }
103686
+ if (options2.dryRun) {
103687
+ newline();
103688
+ info("Dry run — changeset content:");
103689
+ newline();
103690
+ log(previewChangesetContent(artifactChangelogs));
103691
+ return;
103692
+ }
103693
+ const filepath = generateChangesetFile(artifactChangelogs, cwd);
103694
+ newline();
103695
+ success(`Changeset written to ${filepath}`);
103696
+ }
103335
103697
  // src/commands/workspace/workspace.ts
103336
103698
  var listSubcommand = new Command("list").description("List all artifacts in the workspace").action(async () => {
103337
103699
  const cwd = process.cwd();
@@ -103355,7 +103717,7 @@ var listSubcommand = new Command("list").description("List all artifacts in the
103355
103717
  });
103356
103718
  var workspaceCommand = new Command("workspace").description("Manage monorepo workspaces").addCommand(listSubcommand);
103357
103719
  // src/commands/worktree/worktree.ts
103358
- import { join as join31, dirname as dirname11, isAbsolute as isAbsolute4 } from "path";
103720
+ import { join as join32, dirname as dirname11, isAbsolute as isAbsolute4 } from "path";
103359
103721
  var GREKT_DIR2 = ".grekt";
103360
103722
  function getGitCommonDir() {
103361
103723
  try {
@@ -103372,7 +103734,7 @@ function getWorktreeRoot() {
103372
103734
  }
103373
103735
  }
103374
103736
  function resolveOriginalRepoRoot(commonDir, worktreeRoot) {
103375
- const absoluteCommonDir = isAbsolute4(commonDir) ? commonDir : join31(worktreeRoot, commonDir);
103737
+ const absoluteCommonDir = isAbsolute4(commonDir) ? commonDir : join32(worktreeRoot, commonDir);
103376
103738
  return dirname11(absoluteCommonDir);
103377
103739
  }
103378
103740
  function isInsideWorktree(commonDir) {
@@ -103395,8 +103757,8 @@ var syncSubcommand = new Command("sync").description("Copy .grekt/ from the orig
103395
103757
  process.exit(1);
103396
103758
  }
103397
103759
  const originalRepoRoot = resolveOriginalRepoRoot(commonDir, worktreeRoot);
103398
- const sourcePath = join31(originalRepoRoot, GREKT_DIR2);
103399
- const destPath = join31(worktreeRoot, GREKT_DIR2);
103760
+ const sourcePath = join32(originalRepoRoot, GREKT_DIR2);
103761
+ const destPath = join32(worktreeRoot, GREKT_DIR2);
103400
103762
  if (!fs.exists(sourcePath)) {
103401
103763
  info("No .grekt/ directory found in the original repository");
103402
103764
  process.exit(0);
@@ -103419,7 +103781,7 @@ var syncSubcommand = new Command("sync").description("Copy .grekt/ from the orig
103419
103781
  });
103420
103782
  var worktreeCommand = new Command("worktree").description("Manage git worktree integration").addCommand(syncSubcommand);
103421
103783
  // src/commands/scan.ts
103422
- import { join as join32, resolve as resolve8 } from "path";
103784
+ import { join as join33, resolve as resolve8 } from "path";
103423
103785
  var VALID_BADGES = ["certified", "conditional", "suspicious", "rejected"];
103424
103786
  var BADGE_COLORS = {
103425
103787
  certified: colors5.success,
@@ -103515,7 +103877,7 @@ var scanCommand = new Command("scan").description("Scan artifacts for security i
103515
103877
  });
103516
103878
  async function scanRemoteArtifact(source, projectRoot, jsonOutput, failOnThreshold) {
103517
103879
  const displayName = getSourceDisplayName(source);
103518
- const tempDir = join32(projectRoot, ARTIFACTS_DIR, `.tmp-scan-${cryptoProvider.randomUUID()}`);
103880
+ const tempDir = join33(projectRoot, ARTIFACTS_DIR, `.tmp-scan-${cryptoProvider.randomUUID()}`);
103519
103881
  try {
103520
103882
  if (!jsonOutput) {
103521
103883
  const spin = spinner(`Downloading ${colors5.highlight(displayName)}...`);
@@ -103641,14 +104003,14 @@ async function scanAllInstalled(projectRoot, jsonOutput, failOnThreshold) {
103641
104003
  }
103642
104004
  const config = getConfig(projectRoot);
103643
104005
  const trustKey = process.env.GREKT_TRUST_KEY;
103644
- const artifactsDir = join32(projectRoot, ARTIFACTS_DIR);
104006
+ const artifactsDir = join33(projectRoot, ARTIFACTS_DIR);
103645
104007
  const results = [];
103646
104008
  const errors4 = [];
103647
104009
  if (!jsonOutput) {
103648
104010
  log(`Scanning ${colors5.bold(String(artifactIds.length))} artifact${artifactIds.length === 1 ? "" : "s"}...`);
103649
104011
  }
103650
104012
  for (const artifactId of artifactIds) {
103651
- const artifactDir = join32(artifactsDir, artifactId);
104013
+ const artifactDir = join33(artifactsDir, artifactId);
103652
104014
  if (!fs.exists(artifactDir)) {
103653
104015
  errors4.push({ artifactId, message: "Not installed (directory missing)" });
103654
104016
  continue;
@@ -103996,7 +104358,7 @@ var whoamiCommand = new Command("whoami").description("Show current user").actio
103996
104358
  // package.json
103997
104359
  var package_default = {
103998
104360
  name: "@grekt/cli",
103999
- version: "6.39.0",
104361
+ version: "6.40.1",
104000
104362
  description: "AI tools versioned, synced, and shared across tools and teams",
104001
104363
  type: "module",
104002
104364
  bin: {
@@ -104065,13 +104427,13 @@ var package_default = {
104065
104427
  // src/update-check/update-check.ts
104066
104428
  import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
104067
104429
  import { homedir as homedir3 } from "os";
104068
- import { join as join33 } from "path";
104430
+ import { join as join34 } from "path";
104069
104431
  var CACHE_FILENAME = ".update-check";
104070
104432
  var STALENESS_MS = 24 * 60 * 60 * 1000;
104071
104433
  var FETCH_TIMEOUT_MS = 1500;
104072
104434
  var GITHUB_RELEASES_URL = "https://api.github.com/repos/grekt-labs/cli/releases/latest";
104073
104435
  function getCachePath() {
104074
- return join33(homedir3(), ".grekt", CACHE_FILENAME);
104436
+ return join34(homedir3(), ".grekt", CACHE_FILENAME);
104075
104437
  }
104076
104438
  function isOptedOut() {
104077
104439
  return process.env.GREKT_NO_UPDATE_CHECK === "1";
@@ -104090,7 +104452,7 @@ function readCache() {
104090
104452
  }
104091
104453
  function writeCache(cache2) {
104092
104454
  try {
104093
- const dir = join33(homedir3(), ".grekt");
104455
+ const dir = join34(homedir3(), ".grekt");
104094
104456
  if (!existsSync2(dir)) {
104095
104457
  mkdirSync3(dir, { recursive: true });
104096
104458
  }
@@ -104198,6 +104560,7 @@ program2.addCommand(versionsCommand);
104198
104560
  program2.addCommand(outdatedCommand);
104199
104561
  program2.addCommand(upgradeCommand);
104200
104562
  program2.addCommand(versionCommand);
104563
+ program2.addCommand(changelogCommand);
104201
104564
  program2.addCommand(workspaceCommand);
104202
104565
  program2.addCommand(worktreeCommand);
104203
104566
  program2.addCommand(scanCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grekt/cli",
3
- "version": "6.39.0",
3
+ "version": "6.40.1",
4
4
  "description": "AI tools versioned, synced, and shared across tools and teams",
5
5
  "type": "module",
6
6
  "bin": {