@danielsimonjr/repo-tools 2.2.3 → 2.2.4
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 +22 -0
- package/README.md +2 -2
- package/dist/cli.js +23 -14
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,28 @@ All notable changes to this project are recorded in this file. The format follow
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [2.2.4] - 2026-10-19
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- `repo-tools map` and `repo-tools docs` read a `.js`, `.mjs` or `.cjs` file with the TSX grammar. These files used
|
|
14
|
+
the TypeScript grammar, which cannot read JSX. A JavaScript file that holds JSX then gave error nodes, and a
|
|
15
|
+
`docs` run counted the file as unparsed. A JavaScript file cannot hold an angle-bracket type assertion, which
|
|
16
|
+
TSX cannot read. The measurement used 2446 tracked JavaScript files in 87 repositories. It skipped build-output
|
|
17
|
+
and vendor folders, minified files and files over 1.5 MB. The TSX grammar added no error node to any file. It
|
|
18
|
+
removed the error nodes of the one file that held JSX. No export count changed. A `.ts` file keeps the
|
|
19
|
+
TypeScript grammar.
|
|
20
|
+
|
|
21
|
+
- `repo-tools map` writes `duplicate-symbols.md` and `unused-analysis.md` with text that passes `repo-tools ste`. A
|
|
22
|
+
TypeScript repository got a 70-word introduction in `duplicate-symbols.md`. `unused-analysis.md` held caveat
|
|
23
|
+
sentences of 28 and 44 words and an ambiguous "This is". For C#, it held four more findings (three long sentences
|
|
24
|
+
and one ambiguous reference), and for Rust one long sentence. A hand edit of a generated report is lost at the
|
|
25
|
+
next run, so the generator text had to change. The introduction of `duplicate-symbols.md` is now three short
|
|
26
|
+
sentences and a list of the four tags. Each long caveat is split into short sentences. No fact changed, and no
|
|
27
|
+
opt-out marker is added. The new test `map-reports-ste.test.ts` maps a TypeScript, a C#, a Rust and a Python
|
|
28
|
+
repository and expects no STE finding in either report. A repository that commits these reports sees a one-time
|
|
29
|
+
diff at its next `repo-tools map`.
|
|
30
|
+
|
|
9
31
|
## [2.2.3] - 2026-10-16
|
|
10
32
|
|
|
11
33
|
### 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.4.
|
|
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.4):
|
|
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.4",
|
|
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",
|
|
@@ -10895,8 +10895,9 @@ function loadGrammar(name2) {
|
|
|
10895
10895
|
}
|
|
10896
10896
|
return pending;
|
|
10897
10897
|
}
|
|
10898
|
+
var TSX_SUFFIXES = [".tsx", ".jsx", ".js", ".mjs", ".cjs"];
|
|
10898
10899
|
function grammarFor(path) {
|
|
10899
|
-
return
|
|
10900
|
+
return TSX_SUFFIXES.some((suffix) => path.endsWith(suffix)) ? "tsx" : "typescript";
|
|
10900
10901
|
}
|
|
10901
10902
|
function parserFor(name2) {
|
|
10902
10903
|
const parser = parsers.get(name2);
|
|
@@ -13104,7 +13105,7 @@ var UNUSED_CAVEATS = [
|
|
|
13104
13105
|
"A literal relative `import(...)` is a graph edge. A runtime call is a namespace use (`*`), so the exports of that file count as used. A type-position `import(...).Name` counts only `Name`, and `typeof import(...)` counts none. A dynamic import built from a variable or a template, and other runtime loads (e.g. `new Worker(path)`), are still invisible -- a file or export reached ONLY through one of those is reported as no-importer/unreferenced even though it may be live.",
|
|
13105
13106
|
"`noImporterFiles` is NOT a deletion-candidate list. A file with zero in-repo importers is expected, not suspicious, for: a standalone script invoked directly (e.g. a smoketest run via `node script.mjs`, never `import`ed by anything), or a build/lint config file loaded by its own tool rather than by source code (e.g. `eslint.config.mjs`, read by eslint itself). Cross-check against package.json scripts / tool configs before treating any entry here as dead.",
|
|
13106
13107
|
"Only NAMED exports are analysed (`FileNode.exports` carries named exports only) -- `export default` usage is not checked here.",
|
|
13107
|
-
"The `referencedInModule`
|
|
13108
|
+
"The split of exports into `referencedInModule` and `unreferencedAnywhere` is a TEXT-LEVEL heuristic. The analysis counts whole-identifier occurrences in the source of the defining file, minus the declaration site itself. The count is not an AST reference count. The analysis can over-count a name that also appears in a string literal or comment. When the source text cannot be read (no `RepoGraph.root_path`, or the file is missing), the export lands in `unclassifiedExports`. The analysis does not guess a bucket for it.",
|
|
13108
13109
|
"`unreferencedAnywhereNotes`'s dynamic-import check (`_dynamic_import_referrers`) only sees `import(...)` calls with a LITERAL string specifier. A dynamic import built from a variable or template literal (e.g. `import(`./cmds/${name}.js`)`, a command-dispatcher pattern) is invisible to it -- 'found none' in a note means no LITERAL match was found, NOT that nothing imports the file."
|
|
13109
13110
|
];
|
|
13110
13111
|
var IMPORTS_NAME_SYMBOLS = {
|
|
@@ -13114,8 +13115,8 @@ var IMPORTS_NAME_SYMBOLS = {
|
|
|
13114
13115
|
rust: true
|
|
13115
13116
|
};
|
|
13116
13117
|
var PUBLIC_API_LANGUAGES = new Set(["rust"]);
|
|
13117
|
-
var PUBLIC_API_CAVEAT = "A `pub` item with no user inside this crate is normally PUBLIC API, not dead code. `unused-analysis`
|
|
13118
|
-
var NAMESPACE_IMPORT_CAVEAT = "
|
|
13118
|
+
var PUBLIC_API_CAVEAT = "A `pub` item with no user inside this crate is normally PUBLIC API, not dead code. `unused-analysis` sees only the repository. A library crate's public surface exists for DOWNSTREAM consumers. These consumers are not in the graph. Therefore, 'no importer here' is the expected state for most public items. The state is not a finding. Measured on one real crate: 2,635 of 2,739 exports (96%) had no in-crate user, and essentially all of them were live API. Treat this list as 'candidates to check against the crate's intended surface', never as a deletion list.";
|
|
13119
|
+
var NAMESPACE_IMPORT_CAVEAT = "In this language, an import names a namespace, not the symbols that it brings in (C#'s `using App.Hosting;`). The import edges therefore cannot show the use of one symbol. Usage here is a whole-identifier text search across every scanned file instead. The search is the same class of TEXT-LEVEL heuristic as the `referencedInModule` split above. The limit is the same: a name in the comment or string literal of another file counts as a use. The search is conservative. It UNDER-reports dead code and never invents it. That direction is safe for a list whose entries read as deletion candidates. Neither the import edges nor the text search can see a type that only reflection reaches (`Activator.CreateInstance`, DI-by-convention) or that only a .csproj/XAML file names.";
|
|
13119
13120
|
var IDENTIFIER = new RegExp(`${B}[A-Za-z_]${W}*`, "gu");
|
|
13120
13121
|
function readSourceText(rootPath, rel) {
|
|
13121
13122
|
if (rootPath === null)
|
|
@@ -14194,14 +14195,22 @@ function generateDuplicateSymbolsMarkdown(report) {
|
|
|
14194
14195
|
let md = `# Duplicate Symbols
|
|
14195
14196
|
|
|
14196
14197
|
`;
|
|
14197
|
-
md += "
|
|
14198
|
-
md += "
|
|
14199
|
-
md += "
|
|
14200
|
-
md += "
|
|
14201
|
-
md += "
|
|
14202
|
-
md += "
|
|
14203
|
-
md +=
|
|
14204
|
-
|
|
14198
|
+
md += "A name is listed here when two or more distinct files across the monorepo define it. ";
|
|
14199
|
+
md += "A file that only re-exports the name does not count. ";
|
|
14200
|
+
md += "Each name carries one tag (see `DupEntryTag`), so the actionable subset is clear:\n\n";
|
|
14201
|
+
md += "- `TRUE_DUPLICATE`: a real merge target.\n";
|
|
14202
|
+
md += "- `DISPATCH_VARIANT`: two or more `mathTyped(...)` registrations of the same public name. ";
|
|
14203
|
+
md += "The registrations are distinct dispatch surfaces and Bucket C delegation candidates, ";
|
|
14204
|
+
md += `not copy-paste bodies.
|
|
14205
|
+
`;
|
|
14206
|
+
md += "- `ALIAS_DELEGATION`: a `const X = importedY` forward. ";
|
|
14207
|
+
md += `The entry is excluded once fewer than two real bodies remain.
|
|
14208
|
+
`;
|
|
14209
|
+
md += "- `ALLOWLISTED`: the name matches `duplicate-allowlist.json`. ";
|
|
14210
|
+
md += "Examples are hot-path `is*` guards, AssemblyScript mirrors and per-package `VERSION` ";
|
|
14211
|
+
md += `strings.
|
|
14212
|
+
|
|
14213
|
+
`;
|
|
14205
14214
|
md += `> **Note:** ${report.note}
|
|
14206
14215
|
|
|
14207
14216
|
`;
|
|
@@ -14357,7 +14366,7 @@ function unusedMarkdown(unused, graph) {
|
|
|
14357
14366
|
lines.push("Source files that only a test reaches. They ship nothing, but a test uses them.", "");
|
|
14358
14367
|
bulletList(lines, testOnly);
|
|
14359
14368
|
lines.push("## Files with no in-repo importer", "");
|
|
14360
|
-
lines.push("No file of this repository imports these files.
|
|
14369
|
+
lines.push("No file of this repository imports these files. Do not use the list as a deletion list.", "");
|
|
14361
14370
|
bulletList(lines, unused.noImporterFiles ?? []);
|
|
14362
14371
|
bucket(lines, "Exports unreferenced anywhere", "No other file imports these names, and their own module does not use them.", unused.unreferencedAnywhere ?? {});
|
|
14363
14372
|
const notes = unused.unreferencedAnywhereNotes ?? {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danielsimonjr/repo-tools",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.4",
|
|
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",
|