@driftdev/cli 1.5.1 → 1.8.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 (3) hide show
  1. package/README.md +1 -1
  2. package/dist/drift.js +109 -59
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -123,7 +123,7 @@ drift scan --all --private # include private packages
123
123
 
124
124
  ## lint
125
125
 
126
- Cross-reference JSDoc against code signatures. Detects 16 drift types across 4 categories (structural, semantic, example, prose). Prose detection scans markdown files for broken import references and method calls that don't exist on any exported type.
126
+ Cross-reference JSDoc against code signatures. Detects 17 drift types across 4 categories (structural, semantic, example, prose). Prose detection scans markdown files for broken import references, method calls that don't exist on any exported type, and references to deprecated APIs with no deprecation note.
127
127
 
128
128
  ```bash
129
129
  drift lint # single package
package/dist/drift.js CHANGED
@@ -51,8 +51,8 @@ function getGlobalConfigPath() {
51
51
  var init_global = () => {};
52
52
 
53
53
  // src/drift.ts
54
- import { readFileSync as readFileSync22 } from "node:fs";
55
- import * as path30 from "node:path";
54
+ import { readFileSync as readFileSync21 } from "node:fs";
55
+ import * as path31 from "node:path";
56
56
  import { fileURLToPath as fileURLToPath2 } from "node:url";
57
57
  import { Command } from "commander";
58
58
 
@@ -2260,13 +2260,15 @@ function registerContextCommand(program) {
2260
2260
 
2261
2261
  // src/commands/coverage.ts
2262
2262
  import * as path16 from "node:path";
2263
+ import { isExternalExport } from "@driftdev/sdk";
2263
2264
 
2264
2265
  // src/formatters/coverage.ts
2265
2266
  function renderCoverage(data) {
2266
2267
  const lines = [""];
2267
2268
  const color = coverageColor(data.score);
2268
2269
  const bar = progressBar(data.score);
2269
- lines.push(indent(`Coverage ${color(`${data.score}%`)} ${bar} (${data.documented}/${data.total})`));
2270
+ const externalNote = data.external ? c.gray(` +${data.external} external (not resolvable here)`) : "";
2271
+ lines.push(indent(`Coverage ${color(`${data.score}%`)} ${bar} (${data.documented}/${data.total})${externalNote}`));
2270
2272
  lines.push("");
2271
2273
  if (data.undocumented.length > 0) {
2272
2274
  lines.push(indent(c.gray("UNDOCUMENTED")));
@@ -2411,7 +2413,7 @@ function registerCoverageCommand(program) {
2411
2413
  let totalAll = 0;
2412
2414
  for (const pkg of packages) {
2413
2415
  const { spec: spec2 } = await cachedExtract(pkg.entry);
2414
- const exps = spec2.exports ?? [];
2416
+ const exps = (spec2.exports ?? []).filter((e) => !isExternalExport(e));
2415
2417
  let doc = 0;
2416
2418
  for (const e of exps) {
2417
2419
  if (e.description?.trim())
@@ -2445,7 +2447,9 @@ function registerCoverageCommand(program) {
2445
2447
  spec: options.spec,
2446
2448
  abi: options.abi
2447
2449
  });
2448
- const exports = spec.exports ?? [];
2450
+ const allExports = spec.exports ?? [];
2451
+ const exports = allExports.filter((exp) => !isExternalExport(exp));
2452
+ const external = allExports.length - exports.length;
2449
2453
  const total = exports.length;
2450
2454
  const undocumented = [];
2451
2455
  for (const exp of exports) {
@@ -2455,7 +2459,13 @@ function registerCoverageCommand(program) {
2455
2459
  }
2456
2460
  const documented = total - undocumented.length;
2457
2461
  const score = total > 0 ? Math.round(documented / total * 100) : 100;
2458
- const data = { score, documented, total, undocumented };
2462
+ const data = {
2463
+ score,
2464
+ documented,
2465
+ total,
2466
+ undocumented,
2467
+ ...external > 0 ? { external } : {}
2468
+ };
2459
2469
  const next = undocumented.length > 0 ? {
2460
2470
  suggested: "drift-enrich skill",
2461
2471
  reason: `${undocumented.length} exports lack documentation`
@@ -3319,7 +3329,7 @@ function renderNotFound(exportName, suggestions, startTime, version) {
3319
3329
 
3320
3330
  // src/commands/health.ts
3321
3331
  import * as path22 from "node:path";
3322
- import { computeDrift as computeDrift3 } from "@driftdev/sdk";
3332
+ import { computeDrift as computeDrift3, isExternalExport as isExternalExport2 } from "@driftdev/sdk";
3323
3333
 
3324
3334
  // src/formatters/health.ts
3325
3335
  function renderHealth(data, next) {
@@ -3334,7 +3344,8 @@ function renderHealth(data, next) {
3334
3344
  lines.push(indent(`${sym.branch} completeness ${data.completeness}% (${data.undocumented} missing docs)`));
3335
3345
  lines.push(indent(`${sym.end} accuracy ${data.accuracy}% (${data.drifted} stale signatures)`));
3336
3346
  lines.push("");
3337
- lines.push(indent(`${data.totalExports} exports ${c.gray(sym.dot)} ${data.documented} documented ${c.gray(sym.dot)} ${data.drifted} drifted`));
3347
+ const externalNote = data.external ? ` ${c.gray(sym.dot)} ${c.gray(`${data.external} external (not resolvable here)`)}` : "";
3348
+ lines.push(indent(`${data.totalExports} exports ${c.gray(sym.dot)} ${data.documented} documented ${c.gray(sym.dot)} ${data.drifted} drifted${externalNote}`));
3338
3349
  lines.push("");
3339
3350
  if (data.issues.length > 0) {
3340
3351
  lines.push(indent("Top issues"));
@@ -3417,7 +3428,7 @@ function registerHealthCommand(program) {
3417
3428
  let totalAll = 0;
3418
3429
  for (const pkg of packages) {
3419
3430
  const { spec: spec2 } = await cachedExtract(pkg.entry);
3420
- const exps = spec2.exports ?? [];
3431
+ const exps = (spec2.exports ?? []).filter((e) => !isExternalExport2(e));
3421
3432
  let doc = 0;
3422
3433
  for (const e of exps) {
3423
3434
  if (e.description?.trim())
@@ -3447,7 +3458,9 @@ function registerHealthCommand(program) {
3447
3458
  packageName,
3448
3459
  packageVersion
3449
3460
  } = await resolveTruth({ entry: entryFile, lang, spec: options.spec, abi: options.abi });
3450
- const exports = spec.exports ?? [];
3461
+ const allExports = spec.exports ?? [];
3462
+ const exports = allExports.filter((exp) => !isExternalExport2(exp));
3463
+ const external = allExports.length - exports.length;
3451
3464
  const total = exports.length;
3452
3465
  let documented = 0;
3453
3466
  for (const exp of exports) {
@@ -3465,6 +3478,7 @@ function registerHealthCommand(program) {
3465
3478
  const health = computeHealth(total, documented, issues);
3466
3479
  const data = {
3467
3480
  ...health,
3481
+ ...external > 0 ? { external } : {},
3468
3482
  packageName,
3469
3483
  packageVersion
3470
3484
  };
@@ -3894,14 +3908,8 @@ function registerInitCommand(program) {
3894
3908
  }
3895
3909
 
3896
3910
  // src/commands/lint.ts
3897
- import { readFileSync as readFileSync17 } from "node:fs";
3898
- import * as path24 from "node:path";
3899
- import {
3900
- buildExportRegistry,
3901
- computeDrift as computeDrift4,
3902
- detectProseDrift,
3903
- discoverMarkdownFiles
3904
- } from "@driftdev/sdk";
3911
+ import * as path25 from "node:path";
3912
+ import { buildExportRegistry, computeDrift as computeDrift4, detectProseDrift } from "@driftdev/sdk";
3905
3913
 
3906
3914
  // src/formatters/lint.ts
3907
3915
  function renderLint(data, next) {
@@ -3937,9 +3945,47 @@ function renderLint(data, next) {
3937
3945
  `);
3938
3946
  }
3939
3947
 
3948
+ // src/utils/docs-corpus.ts
3949
+ import { readFileSync as readFileSync17, statSync as statSync2 } from "node:fs";
3950
+ import * as path24 from "node:path";
3951
+ import { discoverMarkdownFiles } from "@driftdev/sdk";
3952
+ function resolveDocsCorpus(cwd, docsPatterns, configDocs) {
3953
+ if (!docsPatterns || docsPatterns.length === 0) {
3954
+ return discoverMarkdownFiles(cwd, configDocs);
3955
+ }
3956
+ const include = [];
3957
+ for (const pattern of docsPatterns) {
3958
+ if (isDirectory(path24.resolve(cwd, pattern))) {
3959
+ include.push(path24.join(pattern, "**/*.md"), path24.join(pattern, "**/*.mdx"));
3960
+ } else {
3961
+ include.push(pattern);
3962
+ }
3963
+ }
3964
+ const files = discoverMarkdownFiles(cwd, { include });
3965
+ if (files.length === 0) {
3966
+ formatWarning(`--docs matched no markdown files: ${docsPatterns.join(", ")}`);
3967
+ }
3968
+ return files;
3969
+ }
3970
+ function isDirectory(p) {
3971
+ try {
3972
+ return statSync2(p).isDirectory();
3973
+ } catch {
3974
+ return false;
3975
+ }
3976
+ }
3977
+ function readPackageName(cwd = process.cwd()) {
3978
+ try {
3979
+ const pkgJson = JSON.parse(readFileSync17(path24.resolve(cwd, "package.json"), "utf-8"));
3980
+ return typeof pkgJson.name === "string" ? pkgJson.name : undefined;
3981
+ } catch {
3982
+ return;
3983
+ }
3984
+ }
3985
+
3940
3986
  // src/commands/lint.ts
3941
3987
  function registerLintCommand(program) {
3942
- program.command("lint [entry]").description("Cross-reference docs against the API surface for accuracy issues").option("--all", "Run across all workspace packages").option("--private", "Include private packages in --all mode").option("--lang <language>", "Source language (inferred from --spec/--abi/.clar; default typescript)").option("--abi <path>", "ABI JSON file (required for --lang clarity)").option("--spec <path>", "OpenAPI document: path or URL (implies --lang openapi)").action(async (entry, options) => {
3988
+ program.command("lint [entry]").description("Cross-reference docs against the API surface for accuracy issues").option("--all", "Run across all workspace packages").option("--private", "Include private packages in --all mode").option("--lang <language>", "Source language (inferred from --spec/--abi/.clar; default typescript)").option("--abi <path>", "ABI JSON file (required for --lang clarity)").option("--spec <path>", "OpenAPI document: path or URL (implies --lang openapi)").option("--docs <patterns...>", "Markdown corpus for prose drift: glob patterns or directories (overrides repo-local defaults)").action(async (entry, options) => {
3943
3989
  const startTime = Date.now();
3944
3990
  const version = getVersion();
3945
3991
  try {
@@ -3991,9 +4037,9 @@ function registerLintCommand(program) {
3991
4037
  formatOutput("lint", { issues: [], count: 0 }, startTime, version, renderLint);
3992
4038
  return;
3993
4039
  }
3994
- let entryFile = entry ? path24.resolve(process.cwd(), entry) : undefined;
4040
+ let entryFile = entry ? path25.resolve(process.cwd(), entry) : undefined;
3995
4041
  if (lang === "typescript" && !entryFile) {
3996
- entryFile = config.entry ? path24.resolve(process.cwd(), config.entry) : detectEntry();
4042
+ entryFile = config.entry ? path25.resolve(process.cwd(), config.entry) : detectEntry();
3997
4043
  }
3998
4044
  const { apiSpec: spec } = await resolveTruth({
3999
4045
  entry: entryFile,
@@ -4014,14 +4060,12 @@ function registerLintCommand(program) {
4014
4060
  });
4015
4061
  }
4016
4062
  }
4017
- if (lang === "typescript")
4063
+ if (lang === "typescript" || options.docs)
4018
4064
  try {
4019
- const pkgJsonPath = path24.resolve(process.cwd(), "package.json");
4020
- const pkgJson = JSON.parse(readFileSync17(pkgJsonPath, "utf-8"));
4021
- const packageName = pkgJson.name;
4065
+ const packageName = readPackageName() ?? spec.meta?.name;
4022
4066
  if (packageName) {
4023
4067
  const registry = buildExportRegistry(spec);
4024
- const markdownFiles = discoverMarkdownFiles(process.cwd(), config.docs);
4068
+ const markdownFiles = resolveDocsCorpus(process.cwd(), options.docs, config.docs);
4025
4069
  const proseDrifts = detectProseDrift({ packageName, markdownFiles, registry });
4026
4070
  for (const drift of proseDrifts) {
4027
4071
  issues.push({
@@ -4059,7 +4103,7 @@ function registerLintCommand(program) {
4059
4103
  }
4060
4104
 
4061
4105
  // src/commands/list.ts
4062
- import * as path25 from "node:path";
4106
+ import * as path26 from "node:path";
4063
4107
  import { computeDrift as computeDrift5 } from "@driftdev/sdk";
4064
4108
  import { listExports as listExports2 } from "@openpkg-ts/sdk";
4065
4109
 
@@ -4174,7 +4218,7 @@ function registerListCommand(program) {
4174
4218
  } else {
4175
4219
  let entryFile;
4176
4220
  if (searchOrEntry && looksLikeFilePath(searchOrEntry)) {
4177
- entryFile = path25.resolve(process.cwd(), searchOrEntry);
4221
+ entryFile = path26.resolve(process.cwd(), searchOrEntry);
4178
4222
  } else if (searchOrEntry) {
4179
4223
  entryFile = detectEntry();
4180
4224
  searchTerm = searchOrEntry;
@@ -4250,7 +4294,7 @@ function truthFlags(args) {
4250
4294
  return out;
4251
4295
  }
4252
4296
  function runDrift(cliArgs, cwd) {
4253
- return new Promise((resolve18) => {
4297
+ return new Promise((resolve19) => {
4254
4298
  const child = spawn(process.execPath, [process.argv[1], ...cliArgs, "--json"], {
4255
4299
  cwd: cwd ?? process.cwd(),
4256
4300
  env: { ...process.env, NO_COLOR: "1" },
@@ -4270,9 +4314,9 @@ function runDrift(cliArgs, cwd) {
4270
4314
  try {
4271
4315
  ok = JSON.parse(stdout).ok === true;
4272
4316
  } catch {}
4273
- resolve18({ text, ok });
4317
+ resolve19({ text, ok });
4274
4318
  });
4275
- child.on("error", (err) => resolve18({ text: `Failed to run drift: ${err.message}`, ok: false }));
4319
+ child.on("error", (err) => resolve19({ text: `Failed to run drift: ${err.message}`, ok: false }));
4276
4320
  });
4277
4321
  }
4278
4322
  function toResult({ text, ok }) {
@@ -4386,7 +4430,7 @@ function diffArgs(command, args) {
4386
4430
  // src/commands/release.ts
4387
4431
  import { execSync as execSync4 } from "node:child_process";
4388
4432
  import { existsSync as existsSync14, readFileSync as readFileSync18 } from "node:fs";
4389
- import * as path26 from "node:path";
4433
+ import * as path27 from "node:path";
4390
4434
  import { computeDrift as computeDrift6 } from "@driftdev/sdk";
4391
4435
 
4392
4436
  // src/formatters/release.ts
@@ -4434,7 +4478,7 @@ function getLastTag() {
4434
4478
  }
4435
4479
  }
4436
4480
  function getPackageVersion(cwd) {
4437
- const pkgPath = path26.join(cwd, "package.json");
4481
+ const pkgPath = path27.join(cwd, "package.json");
4438
4482
  if (!existsSync14(pkgPath))
4439
4483
  return null;
4440
4484
  try {
@@ -4450,7 +4494,7 @@ function registerReleaseCommand(program) {
4450
4494
  const cwd = process.cwd();
4451
4495
  try {
4452
4496
  const { config } = loadConfig();
4453
- const entryFile = entry ? path26.resolve(cwd, entry) : config.entry ? path26.resolve(cwd, config.entry) : detectEntry();
4497
+ const entryFile = entry ? path27.resolve(cwd, entry) : config.entry ? path27.resolve(cwd, config.entry) : detectEntry();
4454
4498
  const { spec } = await cachedExtract(entryFile);
4455
4499
  const exports = spec.exports ?? [];
4456
4500
  const total = exports.length;
@@ -4575,7 +4619,7 @@ function renderReport(data) {
4575
4619
  // src/utils/scan-packages.ts
4576
4620
  import { execSync as execSync5 } from "node:child_process";
4577
4621
  import { existsSync as existsSync15, readFileSync as readFileSync19 } from "node:fs";
4578
- import * as path27 from "node:path";
4622
+ import * as path28 from "node:path";
4579
4623
  import { computeDrift as computeDrift7 } from "@driftdev/sdk";
4580
4624
  function detectPackageDirs2(cwd) {
4581
4625
  const workspaces = detectWorkspaces(cwd);
@@ -4594,11 +4638,11 @@ async function scanAllPackages(cwd) {
4594
4638
  const packageDirs = detectPackageDirs2(cwd);
4595
4639
  const results = [];
4596
4640
  for (const dir of packageDirs) {
4597
- const absDir = dir === "." ? cwd : path27.join(cwd, dir);
4641
+ const absDir = dir === "." ? cwd : path28.join(cwd, dir);
4598
4642
  if (!existsSync15(absDir))
4599
4643
  continue;
4600
4644
  let name = dir;
4601
- const pkgPath = path27.join(absDir, "package.json");
4645
+ const pkgPath = path28.join(absDir, "package.json");
4602
4646
  if (existsSync15(pkgPath)) {
4603
4647
  try {
4604
4648
  const pkg = JSON.parse(readFileSync19(pkgPath, "utf-8"));
@@ -4697,13 +4741,12 @@ function registerReportCommand(program) {
4697
4741
  }
4698
4742
 
4699
4743
  // src/commands/scan.ts
4700
- import { readFileSync as readFileSync20 } from "node:fs";
4701
- import * as path28 from "node:path";
4744
+ import * as path29 from "node:path";
4702
4745
  import {
4703
4746
  buildExportRegistry as buildExportRegistry2,
4704
4747
  computeDrift as computeDrift8,
4705
4748
  detectProseDrift as detectProseDrift2,
4706
- discoverMarkdownFiles as discoverMarkdownFiles2
4749
+ isExternalExport as isExternalExport3
4707
4750
  } from "@driftdev/sdk";
4708
4751
 
4709
4752
  // src/formatters/scan.ts
@@ -4716,7 +4759,8 @@ function renderScan(data, next) {
4716
4759
  }
4717
4760
  const hColor = coverageColor(data.health);
4718
4761
  lines.push(indent(`Health ${hColor(`${data.health}%`)}`));
4719
- lines.push(indent(`Coverage ${coverageColor(data.coverage.score)(`${data.coverage.score}%`)} (${data.coverage.documented}/${data.coverage.total} exports)`));
4762
+ const externalNote = data.coverage.external ? c.gray(` +${data.coverage.external} external (not resolvable here)`) : "";
4763
+ lines.push(indent(`Coverage ${coverageColor(data.coverage.score)(`${data.coverage.score}%`)} (${data.coverage.documented}/${data.coverage.total} exports)${externalNote}`));
4720
4764
  lines.push(indent(`Lint ${data.lint.count === 0 ? c.green("0 issues") : c.red(`${data.lint.count} issues`)}`));
4721
4765
  lines.push("");
4722
4766
  if (data.lint.count > 0) {
@@ -4766,7 +4810,7 @@ function renderBatchScan(data) {
4766
4810
 
4767
4811
  // src/commands/scan.ts
4768
4812
  function registerScanCommand(program) {
4769
- program.command("scan [entry]").description("Run coverage + lint + prose drift in one pass").option("--min <n>", "Minimum health threshold (exit 1 if below)").option("--all", "Run across all workspace packages").option("--private", "Include private packages in --all mode").option("--lang <language>", "Source language (inferred from --spec/--abi/.clar; default typescript)").option("--abi <path>", "ABI JSON file (required for --lang clarity)").option("--spec <path>", "OpenAPI document: path or URL (implies --lang openapi)").action(async (entry, options) => {
4813
+ program.command("scan [entry]").description("Run coverage + lint + prose drift in one pass").option("--min <n>", "Minimum health threshold (exit 1 if below)").option("--all", "Run across all workspace packages").option("--private", "Include private packages in --all mode").option("--lang <language>", "Source language (inferred from --spec/--abi/.clar; default typescript)").option("--abi <path>", "ABI JSON file (required for --lang clarity)").option("--spec <path>", "OpenAPI document: path or URL (implies --lang openapi)").option("--docs <patterns...>", "Markdown corpus for prose drift: glob patterns or directories (overrides repo-local defaults)").action(async (entry, options) => {
4770
4814
  const startTime = Date.now();
4771
4815
  const version = getVersion();
4772
4816
  try {
@@ -4804,7 +4848,7 @@ function registerScanCommand(program) {
4804
4848
  let anyFail = false;
4805
4849
  for (const pkg of packages) {
4806
4850
  const { spec } = await cachedExtract(pkg.entry);
4807
- const exps = spec.exports ?? [];
4851
+ const exps = (spec.exports ?? []).filter((e) => !isExternalExport3(e));
4808
4852
  let documented2 = 0;
4809
4853
  for (const e of exps) {
4810
4854
  if (e.description?.trim())
@@ -4841,9 +4885,9 @@ function registerScanCommand(program) {
4841
4885
  return;
4842
4886
  }
4843
4887
  const { config } = loadConfig();
4844
- let entryFile = entry ? path28.resolve(process.cwd(), entry) : undefined;
4888
+ let entryFile = entry ? path29.resolve(process.cwd(), entry) : undefined;
4845
4889
  if (lang === "typescript" && !entryFile) {
4846
- entryFile = config.entry ? path28.resolve(process.cwd(), config.entry) : detectEntry();
4890
+ entryFile = config.entry ? path29.resolve(process.cwd(), config.entry) : detectEntry();
4847
4891
  }
4848
4892
  const { apiSpec, packageName, packageVersion } = await resolveTruth({
4849
4893
  entry: entryFile,
@@ -4851,7 +4895,9 @@ function registerScanCommand(program) {
4851
4895
  spec: options.spec,
4852
4896
  abi: options.abi
4853
4897
  });
4854
- const exports = apiSpec.exports ?? [];
4898
+ const allExports = apiSpec.exports ?? [];
4899
+ const exports = allExports.filter((exp) => !isExternalExport3(exp));
4900
+ const external = allExports.length - exports.length;
4855
4901
  const total = exports.length;
4856
4902
  let documented = 0;
4857
4903
  for (const exp of exports) {
@@ -4872,14 +4918,12 @@ function registerScanCommand(program) {
4872
4918
  });
4873
4919
  }
4874
4920
  }
4875
- if (lang === "typescript") {
4921
+ if (lang === "typescript" || options.docs) {
4876
4922
  try {
4877
- const pkgJsonPath = path28.resolve(process.cwd(), "package.json");
4878
- const pkgJson = JSON.parse(readFileSync20(pkgJsonPath, "utf-8"));
4879
- const pkgName = pkgJson.name;
4923
+ const pkgName = readPackageName() ?? packageName;
4880
4924
  if (pkgName) {
4881
4925
  const registry = buildExportRegistry2(apiSpec);
4882
- const markdownFiles = discoverMarkdownFiles2(process.cwd(), config.docs);
4926
+ const markdownFiles = resolveDocsCorpus(process.cwd(), options.docs, config.docs);
4883
4927
  const proseDrifts = detectProseDrift2({
4884
4928
  packageName: pkgName,
4885
4929
  markdownFiles,
@@ -4908,7 +4952,13 @@ function registerScanCommand(program) {
4908
4952
  }
4909
4953
  const pass = min === undefined || h.health >= min;
4910
4954
  const data = {
4911
- coverage: { score: coverageScore, documented, total, undocumented: total - documented },
4955
+ coverage: {
4956
+ score: coverageScore,
4957
+ documented,
4958
+ total,
4959
+ undocumented: total - documented,
4960
+ ...external > 0 ? { external } : {}
4961
+ },
4912
4962
  lint: { issues, count: issues.length },
4913
4963
  health: h.health,
4914
4964
  pass,
@@ -4981,8 +5031,8 @@ function registerSemverCommand(program) {
4981
5031
  }
4982
5032
 
4983
5033
  // src/commands/validate.ts
4984
- import { readFileSync as readFileSync21 } from "node:fs";
4985
- import * as path29 from "node:path";
5034
+ import { readFileSync as readFileSync20 } from "node:fs";
5035
+ import * as path30 from "node:path";
4986
5036
  import { validateSpec } from "@openpkg-ts/spec";
4987
5037
 
4988
5038
  // src/formatters/validate.ts
@@ -5008,8 +5058,8 @@ function registerValidateCommand(program) {
5008
5058
  const startTime = Date.now();
5009
5059
  const version = getVersion();
5010
5060
  try {
5011
- const filePath = path29.resolve(process.cwd(), file);
5012
- const content = readFileSync21(filePath, "utf-8");
5061
+ const filePath = path30.resolve(process.cwd(), file);
5062
+ const content = readFileSync20(filePath, "utf-8");
5013
5063
  const spec = JSON.parse(content);
5014
5064
  const result = validateSpec(spec);
5015
5065
  const data = {
@@ -5134,13 +5184,13 @@ function extractCapabilities(program) {
5134
5184
 
5135
5185
  // src/drift.ts
5136
5186
  var __filename2 = fileURLToPath2(import.meta.url);
5137
- var __dirname3 = path30.dirname(__filename2);
5138
- var packageJson = JSON.parse(readFileSync22(path30.join(__dirname3, "../package.json"), "utf-8"));
5187
+ var __dirname3 = path31.dirname(__filename2);
5188
+ var packageJson = JSON.parse(readFileSync21(path31.join(__dirname3, "../package.json"), "utf-8"));
5139
5189
  var program = new Command;
5140
5190
  program.name("drift").description("drift — detect when your docs drift from your code").version(packageJson.version).option("--json", "Force JSON output (default when piped)").option("--human", "Force human-readable output (default in terminal)").option("--config <path>", "Path to drift config file").option("--cwd <dir>", "Run as if started in <dir>").option("--no-cache", "Bypass spec cache").option("--tools", "List all available tools for agent use (JSON)").hook("preAction", (_thisCommand) => {
5141
5191
  const opts = program.opts();
5142
5192
  if (opts.cwd) {
5143
- process.chdir(path30.resolve(opts.cwd));
5193
+ process.chdir(path31.resolve(opts.cwd));
5144
5194
  }
5145
5195
  setOutputMode({ json: opts.json, human: opts.human });
5146
5196
  setConfigPath(opts.config);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@driftdev/cli",
3
- "version": "1.5.1",
3
+ "version": "1.8.0",
4
4
  "description": "Drift CLI - detect when your docs drift from your code",
5
5
  "keywords": [
6
6
  "typescript",
@@ -46,7 +46,7 @@
46
46
  "dependencies": {
47
47
  "@driftdev/clarity-adapter": "^1.0.1",
48
48
  "@driftdev/openapi-adapter": "^1.0.1",
49
- "@driftdev/sdk": "^1.4.0",
49
+ "@driftdev/sdk": "^1.8.0",
50
50
  "@modelcontextprotocol/sdk": "^1.29.0",
51
51
  "@openpkg-ts/sdk": "^0.38.0",
52
52
  "@openpkg-ts/spec": "^0.37.0",