@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.
- package/dist/drift.js +116 -76
- 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
|
-
|
|
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 (
|
|
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
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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 ? "
|
|
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.
|
|
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.
|
|
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",
|