@driftdev/cli 0.42.0 → 1.3.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/drift.js +80 -33
  2. package/package.json +3 -2
package/dist/drift.js CHANGED
@@ -578,7 +578,7 @@ function formatOutput(command, data, startTime, version, humanRenderer, next) {
578
578
  ...next ? { next } : {}
579
579
  };
580
580
  if (humanRenderer && shouldRenderHuman()) {
581
- process.stdout.write(humanRenderer(data));
581
+ process.stdout.write(humanRenderer(data, next));
582
582
  process.stdout.write(`
583
583
  `);
584
584
  } else {
@@ -589,12 +589,16 @@ function formatOutput(command, data, startTime, version, humanRenderer, next) {
589
589
  }
590
590
  return envelope;
591
591
  }
592
- function formatError(command, error, startTime, version) {
592
+ function formatError(command, error, startTime, version, suggestion) {
593
593
  const duration = Date.now() - startTime;
594
594
  if (shouldRenderHuman()) {
595
595
  process.stdout.write(`
596
596
  ${c.red("x")} ${error}
597
-
597
+ `);
598
+ if (suggestion)
599
+ process.stdout.write(` ${c.gray(suggestion)}
600
+ `);
601
+ process.stdout.write(`
598
602
  `);
599
603
  } else {
600
604
  const envelope = {
@@ -609,6 +613,15 @@ function formatError(command, error, startTime, version) {
609
613
  }
610
614
  process.exitCode = 1;
611
615
  }
616
+ function formatWarning(message) {
617
+ if (shouldRenderHuman()) {
618
+ process.stderr.write(` ${c.yellow("!")} ${message}
619
+ `);
620
+ } else {
621
+ process.stderr.write(`warning: ${message}
622
+ `);
623
+ }
624
+ }
612
625
 
613
626
  // src/utils/resolve-specs.ts
614
627
  import { readFileSync as readFileSync5 } from "node:fs";
@@ -845,35 +858,43 @@ function filterPublic(packages) {
845
858
  // src/utils/detect-entry.ts
846
859
  function detectEntry(cwd = process.cwd()) {
847
860
  const pkgPath = path6.join(cwd, "package.json");
861
+ const tried = [];
862
+ function tryResolve(source, filePath) {
863
+ const resolved = resolveToSource(cwd, filePath);
864
+ if (resolved)
865
+ return resolved;
866
+ tried.push(`${source}: ${filePath} -> not found`);
867
+ return null;
868
+ }
848
869
  if (existsSync6(pkgPath)) {
849
870
  try {
850
871
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
851
872
  const typesField = pkg.types || pkg.typings;
852
873
  if (typesField && typeof typesField === "string") {
853
- const resolved = resolveToSource(cwd, typesField);
874
+ const resolved = tryResolve("types", typesField);
854
875
  if (resolved)
855
876
  return resolved;
856
877
  }
857
878
  if (pkg.exports && typeof pkg.exports === "object") {
858
879
  const dot = pkg.exports["."];
859
880
  for (const candidate of collectExportCandidates(dot)) {
860
- const resolved = resolveToSource(cwd, candidate);
881
+ const resolved = tryResolve('exports["."]', candidate);
861
882
  if (resolved)
862
883
  return resolved;
863
884
  }
864
885
  }
865
886
  if (pkg.main && typeof pkg.main === "string") {
866
- const resolved = resolveToSource(cwd, pkg.main);
887
+ const resolved = tryResolve("main", pkg.main);
867
888
  if (resolved)
868
889
  return resolved;
869
890
  }
870
891
  if (pkg.module && typeof pkg.module === "string") {
871
- const resolved = resolveToSource(cwd, pkg.module);
892
+ const resolved = tryResolve("module", pkg.module);
872
893
  if (resolved)
873
894
  return resolved;
874
895
  }
875
896
  for (const binPath of collectBinCandidates(pkg.bin)) {
876
- const resolved = resolveToSource(cwd, binPath);
897
+ const resolved = tryResolve("bin", binPath);
877
898
  if (resolved)
878
899
  return resolved;
879
900
  }
@@ -892,22 +913,28 @@ function detectEntry(cwd = process.cwd()) {
892
913
  const full = path6.join(cwd, f);
893
914
  if (existsSync6(full))
894
915
  return full;
916
+ tried.push(`fallback: ${f} -> not found`);
895
917
  }
896
918
  const workspaces = detectWorkspaces(cwd);
897
919
  if (workspaces) {
898
920
  const dirs = resolveGlobs(cwd, workspaces);
899
- const lines = ["Monorepo detected. Use --cwd <pkg> or --all.", "", " Packages:"];
921
+ const lines2 = ["Monorepo detected. Use --cwd <pkg> or --all.", "", " Packages:"];
900
922
  for (const dir of dirs) {
901
- lines.push(` ${dir}`);
923
+ lines2.push(` ${dir}`);
902
924
  }
903
- lines.push("", " Examples:", ` drift coverage --cwd ${dirs[0] ?? "packages/foo"}`, " drift coverage --all");
904
- throw new Error(lines.join(`
925
+ lines2.push("", " Examples:", ` drift coverage --cwd ${dirs[0] ?? "packages/foo"}`, " drift coverage --all");
926
+ throw new Error(lines2.join(`
905
927
  `));
906
928
  }
907
- throw new Error(`Could not detect entry point.
908
-
909
- Try: drift list src/index.ts
910
- or: cd my-package && drift list`);
929
+ const lines = ["Could not detect entry point."];
930
+ if (tried.length > 0) {
931
+ lines.push("", " Tried:");
932
+ for (const t of tried)
933
+ lines.push(` ${t}`);
934
+ }
935
+ lines.push("", " Try: drift scan ./path/to/entry.ts");
936
+ throw new Error(lines.join(`
937
+ `));
911
938
  }
912
939
  function resolveToSource(cwd, filePath) {
913
940
  const normalized = filePath.replace(/^\.\//, "");
@@ -1798,7 +1825,9 @@ function registerCiCommand(program) {
1798
1825
  name = pkg.name;
1799
1826
  if (pkg.private === true)
1800
1827
  isPrivate = true;
1801
- } catch {}
1828
+ } catch (err) {
1829
+ formatWarning(`Could not parse package.json for ${dir}${err instanceof Error ? `: ${err.message}` : ""}`);
1830
+ }
1802
1831
  }
1803
1832
  if (isPrivate && !options.private) {
1804
1833
  skipped.push(name);
@@ -1870,7 +1899,8 @@ function registerCiCommand(program) {
1870
1899
  diff,
1871
1900
  undocumented
1872
1901
  });
1873
- } catch {
1902
+ } catch (err) {
1903
+ formatWarning(`Analysis failed for ${name}: ${err instanceof Error ? err.message : String(err)}`);
1874
1904
  results.push({
1875
1905
  name,
1876
1906
  coverage: 0,
@@ -2169,7 +2199,8 @@ function registerContextCommand(program) {
2169
2199
  try {
2170
2200
  const { spec } = await cachedExtract(pkg.entry);
2171
2201
  packages.push(buildPackageContext(pkg.name, spec));
2172
- } catch {
2202
+ } catch (err) {
2203
+ formatWarning(`Extraction failed for ${pkg.name}: ${err instanceof Error ? err.message : String(err)}`);
2173
2204
  packages.push({
2174
2205
  name: pkg.name,
2175
2206
  coverage: 0,
@@ -3055,7 +3086,7 @@ import * as path21 from "node:path";
3055
3086
  import { computeDrift as computeDrift3 } from "@driftdev/sdk";
3056
3087
 
3057
3088
  // src/formatters/health.ts
3058
- function renderHealth(data) {
3089
+ function renderHealth(data, next) {
3059
3090
  const lines = [""];
3060
3091
  if (data.packageName) {
3061
3092
  const ver = data.packageVersion ? ` v${data.packageVersion}` : "";
@@ -3088,8 +3119,8 @@ function renderHealth(data) {
3088
3119
  } else {
3089
3120
  lines.push(indent(`${c.green(sym.ok)} Health ${data.health}%`));
3090
3121
  }
3091
- if (data.health < 100) {
3092
- lines.push(indent(c.gray("Fix with /drift-fix in Claude Code, or see details: drift list --drifted")));
3122
+ if (next) {
3123
+ lines.push(indent(c.gray(`-> Next: ${next.suggested} (${next.reason})`)));
3093
3124
  }
3094
3125
  lines.push("");
3095
3126
  return lines.join(`
@@ -3125,7 +3156,8 @@ function getPackageInfo(cwd) {
3125
3156
  try {
3126
3157
  const pkg = JSON.parse(readFileSync15(pkgPath, "utf-8"));
3127
3158
  return { name: pkg.name, version: pkg.version };
3128
- } catch {
3159
+ } catch (err) {
3160
+ formatWarning(`Could not parse package.json${err instanceof Error ? `: ${err.message}` : ""}`);
3129
3161
  return {};
3130
3162
  }
3131
3163
  }
@@ -3632,7 +3664,7 @@ import {
3632
3664
  } from "@driftdev/sdk";
3633
3665
 
3634
3666
  // src/formatters/lint.ts
3635
- function renderLint(data) {
3667
+ function renderLint(data, next) {
3636
3668
  const lines = [""];
3637
3669
  if (data.count === 0) {
3638
3670
  lines.push(indent(`${c.green("ok")} No issues found`));
@@ -3657,6 +3689,9 @@ function renderLint(data) {
3657
3689
  lines.push("");
3658
3690
  }
3659
3691
  lines.push(indent(`${data.count} issue${data.count === 1 ? "" : "s"} found`));
3692
+ if (next) {
3693
+ lines.push(indent(c.gray(`-> Next: ${next.suggested} (${next.reason})`)));
3694
+ }
3660
3695
  lines.push("");
3661
3696
  return lines.join(`
3662
3697
  `);
@@ -3739,7 +3774,9 @@ function registerLintCommand(program) {
3739
3774
  });
3740
3775
  }
3741
3776
  }
3742
- } catch {}
3777
+ } catch (err) {
3778
+ formatWarning(`Prose drift skipped: ${err instanceof Error ? err.message : String(err)}`);
3779
+ }
3743
3780
  const data = { issues, count: issues.length };
3744
3781
  const next = issues.length > 0 ? {
3745
3782
  suggested: "drift-fix skill",
@@ -4220,7 +4257,7 @@ import {
4220
4257
  } from "@driftdev/sdk";
4221
4258
 
4222
4259
  // src/formatters/scan.ts
4223
- function renderScan(data) {
4260
+ function renderScan(data, next) {
4224
4261
  const lines = [""];
4225
4262
  if (data.packageName) {
4226
4263
  const ver = data.packageVersion ? ` v${data.packageVersion}` : "";
@@ -4251,6 +4288,9 @@ function renderScan(data) {
4251
4288
  } else {
4252
4289
  lines.push(indent(`${c.red(sym.x)} Scan failed`));
4253
4290
  }
4291
+ if (next) {
4292
+ lines.push(indent(c.gray(`-> Next: ${next.suggested} (${next.reason})`)));
4293
+ }
4254
4294
  lines.push("");
4255
4295
  return lines.join(`
4256
4296
  `);
@@ -4282,7 +4322,8 @@ function getPackageInfo2(cwd) {
4282
4322
  try {
4283
4323
  const pkg = JSON.parse(readFileSync20(pkgPath, "utf-8"));
4284
4324
  return { name: pkg.name, version: pkg.version };
4285
- } catch {
4325
+ } catch (err) {
4326
+ formatWarning(`Could not parse package.json${err instanceof Error ? `: ${err.message}` : ""}`);
4286
4327
  return {};
4287
4328
  }
4288
4329
  }
@@ -4385,7 +4426,9 @@ function registerScanCommand(program) {
4385
4426
  });
4386
4427
  }
4387
4428
  }
4388
- } catch {}
4429
+ } catch (err) {
4430
+ formatWarning(`Prose drift skipped: ${err instanceof Error ? err.message : String(err)}`);
4431
+ }
4389
4432
  const healthIssues = issues.map((i) => ({ export: i.export, issue: i.issue }));
4390
4433
  const h = computeHealth(total, documented, healthIssues);
4391
4434
  const pkg = getPackageInfo2(process.cwd());
@@ -4602,11 +4645,11 @@ function extractCapabilities(program) {
4602
4645
  }
4603
4646
  ],
4604
4647
  workflows: {
4605
- "detect-drift": ["extract", "lint"],
4606
- "full-scan": ["scan"],
4607
- "detect-and-enrich": ["scan", "context"],
4608
- "ci-pipeline": ["ci"],
4609
- "pre-release": ["scan", "breaking", "release"]
4648
+ "detect-drift": { steps: ["extract", "lint"], description: "Find stale JSDoc and prose drift" },
4649
+ "full-scan": { steps: ["scan"], description: "Coverage + lint + prose in one pass" },
4650
+ "detect-and-enrich": { steps: ["scan", "context"], description: "Scan and generate agent context" },
4651
+ "ci-pipeline": { steps: ["ci"], description: "Run CI checks on changed packages" },
4652
+ "pre-release": { steps: ["scan", "breaking", "release"], description: "Full pre-release quality gate" }
4610
4653
  }
4611
4654
  };
4612
4655
  }
@@ -4654,6 +4697,10 @@ for (const cmd of program.commands) {
4654
4697
  cmd._hidden = true;
4655
4698
  }
4656
4699
  }
4700
+ program.addHelpText("after", `
4701
+ Agent mode:
4702
+ drift --tools JSON manifest of all commands for agent use
4703
+ `);
4657
4704
  if (process.argv.includes("--tools")) {
4658
4705
  const caps = extractCapabilities(program);
4659
4706
  process.stdout.write(`${JSON.stringify(caps, null, 2)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@driftdev/cli",
3
- "version": "0.42.0",
3
+ "version": "1.3.0",
4
4
  "description": "Drift CLI - Documentation coverage and drift detection for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",
@@ -43,7 +43,8 @@
43
43
  "dist"
44
44
  ],
45
45
  "dependencies": {
46
- "@driftdev/sdk": "^0.42.0",
46
+ "@driftdev/clarity-adapter": "workspace:*",
47
+ "@driftdev/sdk": "^1.3.0",
47
48
  "@openpkg-ts/sdk": "^0.37.0",
48
49
  "@openpkg-ts/spec": "^0.37.0",
49
50
  "chalk": "^5.4.1",