@danielsimonjr/repo-tools 2.2.6 → 2.2.7
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/CHANGELOG.md +20 -0
- package/README.md +2 -2
- package/dist/cli.js +22 -18
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,26 @@ All notable changes to this project are recorded in this file. The format follow
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [2.2.7] - 2026-10-22
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- `repo-tools ste` exits 2 when any path in the argument list does not exist, and prints `ERROR: path does not exist:
|
|
14
|
+
<path>` on stderr for each such path. Before, a mistyped path among valid paths was ignored and the run exited 0.
|
|
15
|
+
The report of each valid path is still printed.
|
|
16
|
+
- The warning that `repo-tools map` writes for a `package.json` entry that does not resolve is shorter (15 words).
|
|
17
|
+
It had 30 words, so `repo-tools ste` flagged the generated `FILE_INVENTORY.md`. A test now checks the word limit
|
|
18
|
+
of every warning and that the generated report passes `repo-tools ste`.
|
|
19
|
+
- `repo-tools map` reads a folder named `test/` as a tests folder, as version 1.x did. Before, only `tests/` counted,
|
|
20
|
+
so a file such as `test/setup.ts` got the area `src` in `FILE_INVENTORY.md` and counted as a source file in
|
|
21
|
+
`TEST_COVERAGE.md`. The disposition legend and the `--tests` message name both folders.
|
|
22
|
+
- The `TEST_COVERAGE.md` note on the coverage policy no longer links `COVERAGE_POLICY.md`, a file that the tool does
|
|
23
|
+
not write, and no longer names mathjs or AssemblyScript.
|
|
24
|
+
- The `Expected test` hint in `TEST_COVERAGE.md` names `tests/unit/<module>/`. It appears only when the repository
|
|
25
|
+
keeps tests in `tests/unit/`. Other repositories get the plain list of untested files.
|
|
26
|
+
- The text of `duplicate-symbols.md` and of the `duplicate-symbols.json` note no longer names `Bucket C` or
|
|
27
|
+
`AssemblyScript`.
|
|
28
|
+
|
|
9
29
|
## [2.2.6] - 2026-10-22
|
|
10
30
|
|
|
11
31
|
### Fixed
|
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
| `query` | Answers structural questions from the graph of `map`, and writes two derived reports. |
|
|
14
14
|
| `ste` | Checks Markdown or docstring prose against Simplified Technical English. |
|
|
15
15
|
|
|
16
|
-
Status: version 2.2.
|
|
16
|
+
Status: version 2.2.7.
|
|
17
17
|
|
|
18
18
|
- `map`, `check` and `query` read their settings from `repo-tools.config.json` in the root. The
|
|
19
19
|
section of `map` is `map` (its old name, `depgraph`, is also read). `--config=<file>` makes any
|
|
@@ -41,7 +41,7 @@ repo-tools --version
|
|
|
41
41
|
|
|
42
42
|
The executable holds the tool and the Bun runtime. It needs no Bun, Node or `node_modules`.
|
|
43
43
|
Download the file for your platform and `SHA256SUMS` from the
|
|
44
|
-
[GitHub release](https://github.com/danielsimonjr/repo-tools/releases/tag/v2.2.
|
|
44
|
+
[GitHub release](https://github.com/danielsimonjr/repo-tools/releases/tag/v2.2.7):
|
|
45
45
|
|
|
46
46
|
| Platform | File |
|
|
47
47
|
|---|---|
|
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// package.json
|
|
3
3
|
var package_default = {
|
|
4
4
|
name: "@danielsimonjr/repo-tools",
|
|
5
|
-
version: "2.2.
|
|
5
|
+
version: "2.2.7",
|
|
6
6
|
description: "One CLI for repository analysis: dependency graphs creation and query with per-export API facts, file chunking, and context compression. TypeScript on Bun, compiled to a single executable.",
|
|
7
7
|
type: "module",
|
|
8
8
|
license: "MIT",
|
|
@@ -974,7 +974,7 @@ function mergeDepgraphConfig(cli, file) {
|
|
|
974
974
|
// src/depgraph/args.ts
|
|
975
975
|
var SCAN_SCOPE_FLAGS = {
|
|
976
976
|
"--src": "the census finds the source files itself; the area of a file comes from its path",
|
|
977
|
-
"--tests": "a test file is found by its name or its tests/ folder",
|
|
977
|
+
"--tests": "a test file is found by its name or by its test/ or tests/ folder",
|
|
978
978
|
"--exclude": "the census reads the files that git tracks; list a file in .gitignore instead",
|
|
979
979
|
"--also-exclude": "the census reads the files that git tracks; list a file in .gitignore instead",
|
|
980
980
|
"--all": "the graph always holds every file; the disposition of each file shows reachability",
|
|
@@ -1372,7 +1372,7 @@ var TYPE_DUP_CATEGORIES = [
|
|
|
1372
1372
|
{ cat: "type", key: "types" },
|
|
1373
1373
|
{ cat: "enum", key: "enums" }
|
|
1374
1374
|
];
|
|
1375
|
-
var DUPLICATE_SYMBOLS_NOTE = "This report groups names by OWN definition, not by call graph, then classifies each " + "flagged name (see DupEntryTag): TRUE_DUPLICATE (the actionable merge targets), " + "DISPATCH_VARIANT (>=2 mathTyped(...) registrations of the same public name — distinct " + "dispatch surfaces,
|
|
1375
|
+
var DUPLICATE_SYMBOLS_NOTE = "This report groups names by OWN definition, not by call graph, then classifies each " + "flagged name (see DupEntryTag): TRUE_DUPLICATE (the actionable merge targets), " + "DISPATCH_VARIANT (>=2 mathTyped(...) registrations of the same public name — distinct " + "dispatch surfaces, not copy-paste bodies), " + "ALIAS_DELEGATION (a const-alias forward to an imported symbol, not an independent body — " + "excluded once fewer than 2 real bodies remain), and ALLOWLISTED (matches " + "duplicate-allowlist.json: for example hot-path is* guards, mirrors in another language, " + "per-package VERSION strings). NOT detected: same-file typed-dispatch overload polymorphism for " + "different argument shapes within one registration — a human still triages TRUE_DUPLICATE " + "entries using the defining files + public flags before merging anything.";
|
|
1376
1376
|
var DUP_ENTRY_TAG_SORT_ORDER = {
|
|
1377
1377
|
TRUE_DUPLICATE: 0,
|
|
1378
1378
|
DISPATCH_VARIANT: 1,
|
|
@@ -6378,7 +6378,7 @@ function classifyArea(relPath) {
|
|
|
6378
6378
|
}
|
|
6379
6379
|
if (CONFIG_PATTERN.test(relPath))
|
|
6380
6380
|
return "config";
|
|
6381
|
-
if (isTestFile || /(^|\/)tests
|
|
6381
|
+
if (isTestFile || /(^|\/)tests?\//.test(relPath))
|
|
6382
6382
|
return "tests";
|
|
6383
6383
|
if (/^(bench|benchmarks)\//.test(relPath) || /\.bench\.\w+$/.test(relPath))
|
|
6384
6384
|
return "benchmarks";
|
|
@@ -12435,7 +12435,7 @@ function packageJsonRoots(root, known) {
|
|
|
12435
12435
|
continue;
|
|
12436
12436
|
const mapped = mapDistToSrc(spec, known) ?? launcherEntry(root, spec, known) ?? declaredSource(spec, known);
|
|
12437
12437
|
if (mapped === null) {
|
|
12438
|
-
warnings.push(`package.json entry ${pyRepr(spec)} did not resolve to a known source file
|
|
12438
|
+
warnings.push(`package.json entry ${pyRepr(spec)} did not resolve to a known source file. The entry is ignored.`);
|
|
12439
12439
|
continue;
|
|
12440
12440
|
}
|
|
12441
12441
|
if (!roots.includes(mapped))
|
|
@@ -13631,7 +13631,7 @@ function generateTestCoverageMarkdown(coverage, options = {}) {
|
|
|
13631
13631
|
lines.push("");
|
|
13632
13632
|
lines.push(...basisNote);
|
|
13633
13633
|
const policyPath = options.policyPath ?? "docs/architecture/coverage-policy.json";
|
|
13634
|
-
lines.push("> The raw figure counts every source file the
|
|
13634
|
+
lines.push("> The raw figure counts every source file the map finds, including files that no test " + "imports directly by design (for example generated code, type-only barrels and code in " + `another language). The **effective** figure excludes the files that \`${policyPath}\` ` + "classifies, so it shows the active code only.");
|
|
13635
13635
|
lines.push("");
|
|
13636
13636
|
lines.push("### Untested-file breakdown by category");
|
|
13637
13637
|
lines.push("");
|
|
@@ -14227,7 +14227,7 @@ function emitTestCoverage(graph, root, outDir, options = {}) {
|
|
|
14227
14227
|
const jsonPath = join16(outDir, "test-coverage.json");
|
|
14228
14228
|
const namespaceImportBasis = !importsNameSymbols(graph.language);
|
|
14229
14229
|
const markdown = generateTestCoverageMarkdown(coverage, {
|
|
14230
|
-
expectedTestHint: graph.language === "typescript",
|
|
14230
|
+
expectedTestHint: graph.language === "typescript" && tests.some((t) => t.path.startsWith("tests/unit/")),
|
|
14231
14231
|
policyPath: options.policyNote ?? "docs/architecture/coverage-policy.json",
|
|
14232
14232
|
namespaceImportBasis
|
|
14233
14233
|
});
|
|
@@ -14287,17 +14287,14 @@ function generateDuplicateSymbolsMarkdown(report) {
|
|
|
14287
14287
|
md += "Each name carries one tag (see `DupEntryTag`), so the actionable subset is clear:\n\n";
|
|
14288
14288
|
md += "- `TRUE_DUPLICATE`: a real merge target.\n";
|
|
14289
14289
|
md += "- `DISPATCH_VARIANT`: two or more `mathTyped(...)` registrations of the same public name. ";
|
|
14290
|
-
md +=
|
|
14291
|
-
md += `not copy-paste bodies.
|
|
14290
|
+
md += `The registrations are distinct dispatch surfaces, not copy-paste bodies.
|
|
14292
14291
|
`;
|
|
14293
14292
|
md += "- `ALIAS_DELEGATION`: a `const X = importedY` forward. ";
|
|
14294
14293
|
md += `The entry is excluded once fewer than two real bodies remain.
|
|
14295
14294
|
`;
|
|
14296
14295
|
md += "- `ALLOWLISTED`: the name matches `duplicate-allowlist.json`. ";
|
|
14297
|
-
md += "Examples are hot-path `is*` guards,
|
|
14298
|
-
md += `strings
|
|
14299
|
-
|
|
14300
|
-
`;
|
|
14296
|
+
md += "Examples are hot-path `is*` guards, mirrors in another language and per-package ";
|
|
14297
|
+
md += "`VERSION` strings.\n\n";
|
|
14301
14298
|
md += `> **Note:** ${report.note}
|
|
14302
14299
|
|
|
14303
14300
|
`;
|
|
@@ -14313,7 +14310,7 @@ function generateDuplicateSymbolsMarkdown(report) {
|
|
|
14313
14310
|
|
|
14314
14311
|
`;
|
|
14315
14312
|
md += renderTaggedSection("TRUE_DUPLICATE — actionable merge targets", report.runtime, "TRUE_DUPLICATE");
|
|
14316
|
-
md += renderTaggedSection("DISPATCH_VARIANT — distinct public typed-dispatch surfaces
|
|
14313
|
+
md += renderTaggedSection("DISPATCH_VARIANT — distinct public typed-dispatch surfaces", report.runtime, "DISPATCH_VARIANT");
|
|
14317
14314
|
md += renderTaggedSection("ALIAS_DELEGATION — const-alias forwards (not independent bodies)", report.runtime, "ALIAS_DELEGATION");
|
|
14318
14315
|
md += renderTaggedSection("ALLOWLISTED — accepted layering (see duplicate-allowlist.json)", report.runtime, "ALLOWLISTED");
|
|
14319
14316
|
md += `## Type duplicates (lower priority)
|
|
@@ -14332,7 +14329,7 @@ var DISPOSITION_LEGEND = [
|
|
|
14332
14329
|
["build-entry", "A `src`-area file that is an entry root."],
|
|
14333
14330
|
["test-only", "A `src`-area file that only a test reaches."],
|
|
14334
14331
|
["orphan", "A `src`-area file that nothing reaches. Delete it, or wire it to a root."],
|
|
14335
|
-
["test", "A file in a `tests/` folder, or a `*.test.ts` or `*.spec.ts` file."],
|
|
14332
|
+
["test", "A file in a `test/` or `tests/` folder, or a `*.test.ts` or `*.spec.ts` file."],
|
|
14336
14333
|
["tool", "A file in a `tools/` or `scripts/` folder outside `src/`."],
|
|
14337
14334
|
["config", "A `*.config.*` file of TypeScript or JavaScript."],
|
|
14338
14335
|
["example", "A file in `examples/` or `docs/`."],
|
|
@@ -19975,8 +19972,8 @@ identifiers are not checked. A file whose first five lines hold
|
|
|
19975
19972
|
--help, -h Show this help.
|
|
19976
19973
|
|
|
19977
19974
|
Exit codes: 0 when no finding (Markdown mode) or always (--prose mode). 1 when a
|
|
19978
|
-
Markdown finding exists. 2 on a usage error, when
|
|
19979
|
-
or when a file is not UTF-8.
|
|
19975
|
+
Markdown finding exists. 2 on a usage error, when a path does not exist, when no
|
|
19976
|
+
Markdown file was examined, or when a file is not UTF-8.
|
|
19980
19977
|
`;
|
|
19981
19978
|
var HISTORICAL_MARKER = "<!-- ste:historical-record -->";
|
|
19982
19979
|
function readText(path) {
|
|
@@ -20060,7 +20057,10 @@ async function run7(argv, io) {
|
|
|
20060
20057
|
let total = 0;
|
|
20061
20058
|
let checked = 0;
|
|
20062
20059
|
let skipped = 0;
|
|
20060
|
+
const missing = [];
|
|
20063
20061
|
for (const arg of argv) {
|
|
20062
|
+
if (!existsSync13(arg))
|
|
20063
|
+
missing.push(arg);
|
|
20064
20064
|
for (const target of targetsFor(arg)) {
|
|
20065
20065
|
const name2 = basename10(target);
|
|
20066
20066
|
if (isHistoricalRecord(target)) {
|
|
@@ -20093,12 +20093,16 @@ async function run7(argv, io) {
|
|
|
20093
20093
|
const tail = skipped > 0 ? `; ${skipped} skipped as historical record(s)` : "";
|
|
20094
20094
|
io.stdout(`
|
|
20095
20095
|
TOTAL: ${total} problem(s) in ${checked} file(s)${tail}
|
|
20096
|
+
`);
|
|
20097
|
+
for (const path of missing)
|
|
20098
|
+
io.stderr(`ERROR: path does not exist: ${path}
|
|
20096
20099
|
`);
|
|
20097
20100
|
if (checked === 0) {
|
|
20098
20101
|
io.stderr(`ERROR: no Markdown file was examined. This is a failure, not a clean result -- check the path(s) given.
|
|
20099
20102
|
`);
|
|
20100
|
-
return 2;
|
|
20101
20103
|
}
|
|
20104
|
+
if (missing.length > 0 || checked === 0)
|
|
20105
|
+
return 2;
|
|
20102
20106
|
return total > 0 ? 1 : 0;
|
|
20103
20107
|
}
|
|
20104
20108
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danielsimonjr/repo-tools",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.7",
|
|
4
4
|
"description": "One CLI for repository analysis: dependency graphs creation and query with per-export API facts, file chunking, and context compression. TypeScript on Bun, compiled to a single executable.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|