@driftdev/cli 0.40.0 → 0.41.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 +116 -76
  2. package/package.json +2 -3
package/dist/drift.js CHANGED
@@ -1388,6 +1388,30 @@ function renderContextMarkdown(data) {
1388
1388
  lines.push(`**Average coverage**: ${avgCoverage}% `);
1389
1389
  lines.push(`**Total lint issues**: ${totalIssues}`);
1390
1390
  lines.push("");
1391
+ for (const pkg of data.packages) {
1392
+ if (pkg.issues && pkg.issues.length > 0) {
1393
+ lines.push(`### ${pkg.name} — Issues`);
1394
+ lines.push("");
1395
+ lines.push("| Export | Type | Location | Fixable |");
1396
+ lines.push("|--------|------|----------|---------|");
1397
+ for (const issue of pkg.issues) {
1398
+ const loc = issue.filePath ? `${issue.filePath}${issue.line ? `:${issue.line}` : ""}` : "—";
1399
+ lines.push(`| ${issue.export} | ${issue.type} | ${loc} | ${issue.fixable ? "yes" : "no"} |`);
1400
+ }
1401
+ lines.push("");
1402
+ }
1403
+ if (pkg.undocumentedExports && pkg.undocumentedExports.length > 0) {
1404
+ lines.push(`### ${pkg.name} — Undocumented Exports`);
1405
+ lines.push("");
1406
+ lines.push("| Export | Kind | Location |");
1407
+ lines.push("|--------|------|----------|");
1408
+ for (const exp of pkg.undocumentedExports) {
1409
+ const loc = exp.filePath ? `${exp.filePath}${exp.line ? `:${exp.line}` : ""}` : "—";
1410
+ lines.push(`| ${exp.name} | ${exp.kind} | ${loc} |`);
1411
+ }
1412
+ lines.push("");
1413
+ }
1414
+ }
1391
1415
  }
1392
1416
  if (data.history.length > 0) {
1393
1417
  lines.push("## Recent Activity");
@@ -2039,7 +2063,7 @@ function registerConfigCommand(program) {
2039
2063
  import { execSync as execSync3 } from "node:child_process";
2040
2064
  import { readFileSync as readFileSync12 } from "node:fs";
2041
2065
  import * as path14 from "node:path";
2042
- import { computeDrift as computeDrift2 } from "@driftdev/sdk";
2066
+ import { computeDrift as computeDrift2, isFixableDrift } from "@driftdev/sdk";
2043
2067
 
2044
2068
  // src/formatters/context.ts
2045
2069
  function renderContext(data) {
@@ -2061,6 +2085,53 @@ function getCommitSha2() {
2061
2085
  return null;
2062
2086
  }
2063
2087
  }
2088
+ function buildPackageContext(name, spec) {
2089
+ const exports = spec.exports ?? [];
2090
+ let documented = 0;
2091
+ const undocumented = [];
2092
+ const undocumentedExports = [];
2093
+ for (const exp of exports) {
2094
+ if (exp.description?.trim()) {
2095
+ documented++;
2096
+ } else {
2097
+ undocumented.push(exp.name);
2098
+ undocumentedExports.push({
2099
+ name: exp.name,
2100
+ kind: exp.kind,
2101
+ filePath: exp.source?.file,
2102
+ line: exp.source?.line
2103
+ });
2104
+ }
2105
+ }
2106
+ const coverage = exports.length > 0 ? Math.round(documented / exports.length * 100) : 100;
2107
+ const driftResult = computeDrift2(spec);
2108
+ const issues = [];
2109
+ let lintIssues = 0;
2110
+ for (const [exportName, drifts] of driftResult.exports) {
2111
+ lintIssues += drifts.length;
2112
+ const exp = exports.find((e) => e.name === exportName);
2113
+ for (const drift of drifts) {
2114
+ issues.push({
2115
+ export: exportName,
2116
+ type: drift.type,
2117
+ issue: drift.issue,
2118
+ filePath: drift.filePath ?? exp?.source?.file,
2119
+ line: drift.line ?? exp?.source?.line,
2120
+ fixable: isFixableDrift(drift)
2121
+ });
2122
+ }
2123
+ }
2124
+ return {
2125
+ name,
2126
+ coverage,
2127
+ lintIssues,
2128
+ exports: exports.length,
2129
+ documented,
2130
+ undocumented,
2131
+ issues: issues.length > 0 ? issues : undefined,
2132
+ undocumentedExports: undocumentedExports.length > 0 ? undocumentedExports : undefined
2133
+ };
2134
+ }
2064
2135
  function registerContextCommand(program) {
2065
2136
  program.command("context [entry]").description("Generate agent context file with project state").option("--all", "Include all workspace packages").option("--private", "Include private packages in --all mode").option("--output <path>", "Output path (default: ~/.drift/projects/<slug>/context.md)").action(async (entry, options) => {
2066
2137
  const startTime = Date.now();
@@ -2078,28 +2149,7 @@ function registerContextCommand(program) {
2078
2149
  for (const pkg of pkgs) {
2079
2150
  try {
2080
2151
  const { spec } = await cachedExtract(pkg.entry);
2081
- const exports = spec.exports ?? [];
2082
- let documented = 0;
2083
- const undocumented = [];
2084
- for (const exp of exports) {
2085
- if (exp.description?.trim())
2086
- documented++;
2087
- else
2088
- undocumented.push(exp.name);
2089
- }
2090
- const coverage = exports.length > 0 ? Math.round(documented / exports.length * 100) : 100;
2091
- const driftResult = computeDrift2(spec);
2092
- let lintIssues = 0;
2093
- for (const [, drifts] of driftResult.exports)
2094
- lintIssues += drifts.length;
2095
- packages.push({
2096
- name: pkg.name,
2097
- coverage,
2098
- lintIssues,
2099
- exports: exports.length,
2100
- documented,
2101
- undocumented
2102
- });
2152
+ packages.push(buildPackageContext(pkg.name, spec));
2103
2153
  } catch {
2104
2154
  packages.push({
2105
2155
  name: pkg.name,
@@ -2114,64 +2164,22 @@ function registerContextCommand(program) {
2114
2164
  } else {
2115
2165
  const entryFile = config.entry ? path14.resolve(cwd, config.entry) : detectEntry();
2116
2166
  const { spec } = await cachedExtract(entryFile);
2117
- const exports = spec.exports ?? [];
2118
- let documented = 0;
2119
- const undocumented = [];
2120
- for (const exp of exports) {
2121
- if (exp.description?.trim())
2122
- documented++;
2123
- else
2124
- undocumented.push(exp.name);
2125
- }
2126
- const coverage = exports.length > 0 ? Math.round(documented / exports.length * 100) : 100;
2127
- const driftResult = computeDrift2(spec);
2128
- let lintIssues = 0;
2129
- for (const [, drifts] of driftResult.exports)
2130
- lintIssues += drifts.length;
2131
2167
  const pkgJsonPath = path14.resolve(cwd, "package.json");
2132
2168
  let name = path14.basename(cwd);
2133
2169
  try {
2134
2170
  name = JSON.parse(readFileSync12(pkgJsonPath, "utf-8")).name ?? name;
2135
2171
  } catch {}
2136
- packages.push({
2137
- name,
2138
- coverage,
2139
- lintIssues,
2140
- exports: exports.length,
2141
- documented,
2142
- undocumented
2143
- });
2172
+ packages.push(buildPackageContext(name, spec));
2144
2173
  }
2145
2174
  } else {
2146
2175
  const entryFile = path14.resolve(cwd, entry);
2147
2176
  const { spec } = await cachedExtract(entryFile);
2148
- const exports = spec.exports ?? [];
2149
- let documented = 0;
2150
- const undocumented = [];
2151
- for (const exp of exports) {
2152
- if (exp.description?.trim())
2153
- documented++;
2154
- else
2155
- undocumented.push(exp.name);
2156
- }
2157
- const coverage = exports.length > 0 ? Math.round(documented / exports.length * 100) : 100;
2158
- const driftResult = computeDrift2(spec);
2159
- let lintIssues = 0;
2160
- for (const [, drifts] of driftResult.exports)
2161
- lintIssues += drifts.length;
2162
2177
  const pkgJsonPath = path14.resolve(cwd, "package.json");
2163
2178
  let name = path14.basename(cwd);
2164
2179
  try {
2165
2180
  name = JSON.parse(readFileSync12(pkgJsonPath, "utf-8")).name ?? name;
2166
2181
  } catch {}
2167
- packages.push({
2168
- name,
2169
- coverage,
2170
- lintIssues,
2171
- exports: exports.length,
2172
- documented,
2173
- undocumented
2174
- });
2182
+ packages.push(buildPackageContext(name, spec));
2175
2183
  }
2176
2184
  const contextData = { packages, history, config, commit: commit ?? null };
2177
2185
  if (options.output) {
@@ -3602,7 +3610,7 @@ import {
3602
3610
  computeDrift as computeDrift4,
3603
3611
  detectProseDrift,
3604
3612
  discoverMarkdownFiles,
3605
- isFixableDrift
3613
+ isFixableDrift as isFixableDrift2
3606
3614
  } from "@driftdev/sdk";
3607
3615
 
3608
3616
  // src/formatters/lint.ts
@@ -3718,7 +3726,7 @@ function registerLintCommand(program) {
3718
3726
  let fixableCount = 0;
3719
3727
  for (const [, drifts] of driftResult.exports) {
3720
3728
  for (const d of drifts) {
3721
- if (isFixableDrift(d))
3729
+ if (isFixableDrift2(d))
3722
3730
  fixableCount++;
3723
3731
  }
3724
3732
  }
@@ -4198,7 +4206,7 @@ import {
4198
4206
  computeDrift as computeDrift8,
4199
4207
  detectProseDrift as detectProseDrift2,
4200
4208
  discoverMarkdownFiles as discoverMarkdownFiles2,
4201
- isFixableDrift as isFixableDrift2
4209
+ isFixableDrift as isFixableDrift3
4202
4210
  } from "@driftdev/sdk";
4203
4211
 
4204
4212
  // src/formatters/scan.ts
@@ -4390,7 +4398,7 @@ function registerScanCommand(program) {
4390
4398
  let fixableCount = 0;
4391
4399
  for (const [, drs] of driftResult.exports) {
4392
4400
  for (const d of drs) {
4393
- if (isFixableDrift2(d))
4401
+ if (isFixableDrift3(d))
4394
4402
  fixableCount++;
4395
4403
  }
4396
4404
  }
@@ -4516,6 +4524,29 @@ function extractFlags(cmd) {
4516
4524
  type: optionType(opt)
4517
4525
  }));
4518
4526
  }
4527
+ var COMMAND_EXAMPLES = {
4528
+ scan: ["drift scan --json", "drift scan --all --json", "drift scan --ci --json"],
4529
+ lint: ["drift lint --json", "drift lint --all --json"],
4530
+ coverage: ["drift coverage --json", "drift coverage --min 80 --json"],
4531
+ extract: ["drift extract --json"],
4532
+ list: ["drift list --json"],
4533
+ get: ["drift get createClient --json"],
4534
+ diff: ["drift diff --base main --json"],
4535
+ breaking: ["drift breaking --base main --json"],
4536
+ semver: ["drift semver --base main --json"],
4537
+ changelog: ["drift changelog --base main --json"],
4538
+ ci: ["drift ci --json", "drift ci --all --json"],
4539
+ release: ["drift release --json"],
4540
+ context: ["drift context --json", "drift context --all --json"],
4541
+ examples: ["drift examples --typecheck --json"],
4542
+ health: ["drift health --json"],
4543
+ config: ["drift config list --json", "drift config get coverage.min --json"],
4544
+ init: ["drift init --json"],
4545
+ validate: ["drift validate spec.json --json"],
4546
+ filter: ["drift filter spec.json --kind function --json"],
4547
+ report: ["drift report --json"],
4548
+ cache: ["drift cache status", "drift cache clear"]
4549
+ };
4519
4550
  function extractCapabilities(program) {
4520
4551
  const commands = [];
4521
4552
  for (const cmd of program.commands) {
@@ -4524,11 +4555,14 @@ function extractCapabilities(program) {
4524
4555
  name: cmd.name(),
4525
4556
  description: cmd.description(),
4526
4557
  flags: extractFlags(cmd),
4527
- ...positionalArgs.length > 0 ? { positional: positionalArgs.map((a) => a.name()).join(" ") } : {}
4558
+ ...positionalArgs.length > 0 ? { positional: positionalArgs.map((a) => a.name()).join(" ") } : {},
4559
+ ...COMMAND_EXAMPLES[cmd.name()] ? { examples: COMMAND_EXAMPLES[cmd.name()] } : {}
4528
4560
  });
4529
4561
  }
4530
4562
  return {
4531
4563
  version: program.version() ?? "0.0.0",
4564
+ hint: "Run 'drift' for human output. Use these primitives with --json for agent workflows.",
4565
+ humanCommands: ["scan", "ci", "init"],
4532
4566
  commands,
4533
4567
  globalFlags: extractFlags(program),
4534
4568
  entities: [
@@ -4579,7 +4613,7 @@ var __filename2 = fileURLToPath2(import.meta.url);
4579
4613
  var __dirname3 = path29.dirname(__filename2);
4580
4614
  var packageJson = JSON.parse(readFileSync22(path29.join(__dirname3, "../package.json"), "utf-8"));
4581
4615
  var program = new Command;
4582
- program.name("drift").description("drift — documentation quality primitives for TypeScript").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").hook("preAction", (_thisCommand) => {
4616
+ program.name("drift").description("drift — documentation quality for TypeScript").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) => {
4583
4617
  const opts = program.opts();
4584
4618
  if (opts.cwd) {
4585
4619
  process.chdir(path29.resolve(opts.cwd));
@@ -4610,18 +4644,24 @@ registerInitCommand(program);
4610
4644
  registerConfigCommand(program);
4611
4645
  registerContextCommand(program);
4612
4646
  registerCacheCommand(program);
4613
- if (process.argv.includes("--capabilities")) {
4647
+ var HUMAN_COMMANDS = new Set(["scan", "ci", "init"]);
4648
+ for (const cmd of program.commands) {
4649
+ if (!HUMAN_COMMANDS.has(cmd.name())) {
4650
+ cmd._hidden = true;
4651
+ }
4652
+ }
4653
+ if (process.argv.includes("--tools")) {
4614
4654
  const caps = extractCapabilities(program);
4615
4655
  process.stdout.write(`${JSON.stringify(caps, null, 2)}
4616
4656
  `);
4617
4657
  process.exit(0);
4618
4658
  }
4619
4659
  var rawArgs = process.argv.slice(2);
4620
- var hasHelpOrVersion = rawArgs.some((a) => ["-h", "--help", "-V", "--version"].includes(a));
4660
+ var hasHelpOrVersion = rawArgs.some((a) => ["-h", "--help", "-V", "--version", "--tools"].includes(a));
4621
4661
  var userArgs = rawArgs.filter((a) => !a.startsWith("-"));
4622
4662
  if (userArgs.length === 0 && !hasHelpOrVersion) {
4623
4663
  const { configPath } = loadConfig();
4624
- const subcommand = configPath ? "health" : "init";
4664
+ const subcommand = configPath ? "scan" : "init";
4625
4665
  process.argv.splice(2, 0, subcommand);
4626
4666
  }
4627
4667
  program.parseAsync().catch(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@driftdev/cli",
3
- "version": "0.40.0",
3
+ "version": "0.41.0",
4
4
  "description": "Drift CLI - Documentation coverage and drift detection for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",
@@ -43,8 +43,7 @@
43
43
  "dist"
44
44
  ],
45
45
  "dependencies": {
46
- "@driftdev/sdk": "^0.39.0",
47
- "@driftdev/spec": "^0.36.0",
46
+ "@driftdev/sdk": "^0.41.0",
48
47
  "@openpkg-ts/sdk": "^0.37.0",
49
48
  "@openpkg-ts/spec": "^0.37.0",
50
49
  "chalk": "^5.4.1",