@titan-design/code-read 0.1.9 → 0.2.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/README.md +111 -3
- package/dist/chunk-7FNTXO7C.js +2344 -0
- package/dist/chunk-7FNTXO7C.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +133 -3
- package/dist/index.js.map +1 -1
- package/dist/query/index.d.ts +1283 -5
- package/dist/query/index.js +77 -1
- package/package.json +5 -5
- package/dist/chunk-VXQFCVGB.js +0 -1326
- package/dist/chunk-VXQFCVGB.js.map +0 -1
package/README.md
CHANGED
|
@@ -16,22 +16,28 @@ Tier 2 of the titan-platform DAG (TP-184). Depends on `code-graph`, `registry`,
|
|
|
16
16
|
| `@titan-design/code-read/query` | browser or Node | the contract (`CONTRACT`, `CODE_READ_API_VERSION`, zod schemas), `ReadModel` and `buildReadModel`, the `ReadSource` seam, `QUERIES`, `createQueryResolver` |
|
|
17
17
|
| `@titan-design/code-read` | Node | everything in `./query`, plus `loadReadModel`, `createLiveSource` (SQLite plus an LRU of models), and `registerCodeReadCommands` |
|
|
18
18
|
|
|
19
|
-
`./query` imports only its own files, `zod`,
|
|
19
|
+
`./query` imports only its own files, `zod`, `rpc-protocol`, and code-graph's browser-safe
|
|
20
|
+
`./analysis` subpath, never code-graph's root. Three rules in
|
|
20
21
|
`.codewatch/check.json` (`code-read-query-*`) and `src/browser-safe.test.ts` enforce that.
|
|
21
22
|
The test bundles the subpath with esbuild for `platform: "browser"` and expects no warnings.
|
|
22
23
|
|
|
23
|
-
## Commands (contract 0.1.
|
|
24
|
+
## Commands (contract 0.1.8)
|
|
24
25
|
|
|
25
26
|
| Command | Args | Result |
|
|
26
27
|
| --- | --- | --- |
|
|
27
28
|
| `api.describe` | none | `api`, `dataset`, `commands`, `newest`, `indexVersions`, `capabilities`, `metrics` (catalogue descriptors with provenance), `rules` |
|
|
28
29
|
| `snapshot.list` | `ref?`, `limit` (1 to 500, default 50) | `snapshots`, newest first |
|
|
29
30
|
| `hierarchy.get` | `snapshot?`, `root?`, `depth` (1 to 8, default 2), `metrics` (default `["loc"]`), `baseline?`, `include_symbols`, `exclude_roles` | `snapshotId`, `baselineSnapshotId?`, `comparable?`, `nodes` (flat, shallowest first, with `parentId`, `depth`, `childCount`, `values`, `missing?`, `deltas?`), `truncated` |
|
|
30
|
-
| `node.get` | `snapshot?`, `id`, `baseline?`, `metrics` (default: every one that applies) | `node`, `ancestors` (repo first), `childCounts`, `metrics` (value, `direction`, `rollup`, `percentile`, `siblingMedian`, `siblingRank`, `siblingCount`, `baseline?`, `delta?`, `missing?`) |
|
|
31
|
+
| `node.get` | `snapshot?`, `id`, `baseline?`, `metrics` (default: every one that applies), `lenses` (any of `exports`, `score`, `centrality`, `coupling`, `tests`; default none), `window` (`30d` default, for `score`) | `node`, `ancestors` (repo first), `childCounts`, `metrics` (value, `direction`, `rollup`, `percentile`, `siblingMedian`, `siblingRank`, `siblingCount`, `baseline?`, `delta?`, `missing?`), `lenses?` (one key per lens asked for) |
|
|
31
32
|
| `node.resolve` | exactly one of `query` or `path`, plus `line?` with `path`, `limit` (1 to 50, default 10) | `candidates`: `node`, `score`, `match` |
|
|
32
33
|
| `findings.list` | `snapshot?`, `baseline?`, `scope?`, filters `rule`, `severity`, `tool`, `provenance`, `kind`, `status` (arrays, empty means all), `sort` (`severity` default, `excess`, `value`, `path`, `rule`), `order` (`desc` default), `offset`, `limit` (0 to 500, default 20), `facets` | `snapshotId`, `baselineSnapshotId?`, `comparable?`, `rows` (`Finding`), `total`, `facets?` |
|
|
33
34
|
| `finding.get` | `snapshot?`, `id`, `baseline?`, `context_lines` (0 to 20, default 5) | `finding`, `rule` (with `text`), `measured`, `why`, `excerpt` (or null with `excerptMissing`), `related` (at most 10) |
|
|
34
35
|
| `node.neighbors` | `snapshot?`, `id` (a stored node), `direction` (`both` default), `edge_kinds`, `metrics` (default `loc`, `utilization`), `offset`, `limit` (1 to 100, default 20) | `snapshotId`, `node`, `inbound`, `outbound` (each `node`, `kind`, `weight`, `specifier?`, `values`), `total` per side |
|
|
36
|
+
| `hotspots.list` | `snapshot?`, `baseline?`, `grain` (`file` default, `symbol`), `window` (`30d` default, any `<n>d`, or `lifetime`), `cutoff?`, `offset`, `limit` (0 to 500, default 20) | `snapshotId`, `baselineSnapshotId?`, `comparable?`, `rows` (`node`, `churn`, `complexity`, `recency`, `score`, `utilization?`, `baselineScore?`, `mark?`), `total` |
|
|
37
|
+
| `overview.get` | `snapshot?`, `baseline?`, `window` (`30d` default), `cutoff` (default 3000), `weights` (per signal, defaults from code-graph's `DEFAULT_HEALTH_WEIGHTS`), `exclude_rules`, `combined` (default false), `reading_limit` (default 6), `look_limit` (default 8; both 0 to 50) | `snapshotId`, `baselineSnapshotId?`, `comparable?`, `kpis`, `signals` (`key`, `label`, `penalty`, `cap`, `measured`, `detail`), `combined?`, `readingOrder` (`node`, `centrality`), `lookFirst` (`node`, `score`, `churn`, `complexity`, `recency`, `reasons`) |
|
|
38
|
+
| `changes.get` | `baseline` (required), `snapshot?`, `window` (`30d` default), `cutoff` (default 3000), `limit` (rows per list, 0 to 500, default 20) | `snapshotId`, `baselineSnapshotId`, `comparable`, `files` (`crossedCutoff`, `added`), `findings` (`new`, `worsened`, `improved`, `resolved`), `coupling` (`measured`, `added`), `regressions` (`node`, `before`, `after`, `delta`, `findings`), `counts` |
|
|
39
|
+
| `paths.impact` | `paths` (up to 500), `snapshot?`, `baseline?`, `root?` (absolute checkout directory), `window` (`30d` default) | `snapshotId`, `baselineSnapshotId?`, `comparable?`, `rows` (by `status`: `indexed` with `node`, `complexity`, `hotspot` (`score`, `rank`), `findings`, `delta?`; `not-indexed` with `path`; `outside-repo`), `ranked`, `rollup` |
|
|
40
|
+
| `packages.stats` | `snapshot?`, `packages?` (package roots, up to 500; default every package the tier config declares) | `snapshotId`, `packagesFrom` (`args`, `tiers`, `none`), `modularity`, `totalEdges`, `unassignedFiles`, `packages` (`id`, `name`, `fileCount`, `internalEdges`, `outgoingEdges`, `incomingEdges`, `cohesion`, `instability`, `abstractness`, `band`, `flags`, `layer`), `crossEdges` (`from`, `to`, `edges`, `intensity`, `flag`) |
|
|
35
41
|
|
|
36
42
|
Arguments are snake_case and results are camelCase. `snapshot` and `baseline` take an id, a
|
|
37
43
|
digit string, or a ref name (that ref's newest snapshot). The rest of the design's 14
|
|
@@ -132,6 +138,108 @@ back. A finding's `status` also depends on the baseline you pass: the same row i
|
|
|
132
138
|
`carryover` against one snapshot and `new` against another. Do not persist a derived id
|
|
133
139
|
as if it were durable until the findings store lands.
|
|
134
140
|
|
|
141
|
+
## Hotspots
|
|
142
|
+
|
|
143
|
+
`hotspots.list` computes nothing of its own. It runs code-graph's report derivations from
|
|
144
|
+
the browser-safe `@titan-design/code-graph/analysis` subpath, so the daemon and a static
|
|
145
|
+
dataset rank alike.
|
|
146
|
+
|
|
147
|
+
- **File grain** is `topHotspots`: `round(churn_<window> × complexity × recency_<window>)`,
|
|
148
|
+
where complexity is `cognitive_max`, else `cyclomatic_max`. A file with no churn or no
|
|
149
|
+
complexity has no row, and generated files are left out.
|
|
150
|
+
- **Symbol grain** is `buildBlastRadius`: `utilization × complexity × file churn`, with the
|
|
151
|
+
symbol's own `symbol_cognitive`, else its file's. It applies no recency, so `recency` is 1.
|
|
152
|
+
Symbols of generated files are left out.
|
|
153
|
+
- **Marks** come from `computeReportDrift` over every row: `new` when the node had no row at
|
|
154
|
+
the baseline, `worsened` when its score rose. `baselineScore` is null for a new row.
|
|
155
|
+
- **Cutoff** is the caller's policy, such as the dashboard's 3000. It filters before paging,
|
|
156
|
+
and `total` counts the rows it keeps. Marks do not depend on it.
|
|
157
|
+
|
|
158
|
+
## Overview
|
|
159
|
+
|
|
160
|
+
`overview.get` answers "where do I look first" with named attention signals, not a risk or
|
|
161
|
+
defect score. It also reuses code-graph's derivations from `./analysis`:
|
|
162
|
+
|
|
163
|
+
- **Signals** are `computeHealth`'s components, weighted and capped by the caller's
|
|
164
|
+
`weights`: files over `cutoff`, open findings (new and carried over weigh apart), max
|
|
165
|
+
complexity over budget, and hidden coupling, which is unmeasured until co-change pairs
|
|
166
|
+
are stored. `combined` (100 minus the penalties) is optional and secondary.
|
|
167
|
+
- **Reading order** is `topCentralFiles`: PageRank over files and structural edges.
|
|
168
|
+
- **Look first** is the file-grain hotspots, highest first. Each row names its reasons:
|
|
169
|
+
`over-cutoff`, `findings`, or else `churn-complexity`.
|
|
170
|
+
|
|
171
|
+
## Node lenses
|
|
172
|
+
|
|
173
|
+
`node.get` takes optional `lenses`. With none, the result has no `lenses` field and is the
|
|
174
|
+
same as before. Each lens reuses a code-graph derivation from `./analysis`, and answers
|
|
175
|
+
`null` on a node kind it does not describe: `score` describes files and symbols, the rest
|
|
176
|
+
describe files only.
|
|
177
|
+
|
|
178
|
+
- **exports** is `buildHotExports`: the file's top 8 exported and top 8 internal symbols,
|
|
179
|
+
each with utilization, its own cognitive complexity, and how many files reference it
|
|
180
|
+
(`computeSymbolConsumers`).
|
|
181
|
+
- **score** is the node's row in `hotspots.list` at its grain for `window`: the score, its
|
|
182
|
+
factors, and its rank among non-zero scores. A node scoring 0 has no factors and no rank.
|
|
183
|
+
- **centrality** is `topCentralFiles` with no limit, the ranking behind `overview.get`'s
|
|
184
|
+
reading order, so every file in it has a rank. Generated code is left out and gets null.
|
|
185
|
+
- **coupling** is `measured: false` until co-change pairs are stored.
|
|
186
|
+
- **tests** lists tests linked by path convention (`linkTestsToSources` with no co-edit
|
|
187
|
+
pairs) beside the index's `linked_test_count`, which also counts co-edit links.
|
|
188
|
+
|
|
189
|
+
## Changes
|
|
190
|
+
|
|
191
|
+
`changes.get` answers "what moved since the baseline". It recomputes nothing code-graph
|
|
192
|
+
already derives:
|
|
193
|
+
|
|
194
|
+
- **Files** come from `computeReportDrift` over every file-grain hotspot. `crossedCutoff`
|
|
195
|
+
holds files below `cutoff` at the baseline and at or above it now; `added` holds files the
|
|
196
|
+
baseline does not hold, generated files left out.
|
|
197
|
+
- **Findings** are bucketed by `bucketViolations`, the store-free core of `diffCheckResults`:
|
|
198
|
+
new, worsened or improved by value, and resolved. Ids match as they are; following
|
|
199
|
+
renames is TP-187.
|
|
200
|
+
- **Coupling** is unmeasured (`measured: false`) until co-change pairs are stored.
|
|
201
|
+
- **Regressions** are files whose score rose that carry an open finding now.
|
|
202
|
+
- Across index versions `comparable` is false and every list is empty.
|
|
203
|
+
|
|
204
|
+
## Path impact
|
|
205
|
+
|
|
206
|
+
`paths.impact` answers "what do these files weigh", for a set such as the files a change
|
|
207
|
+
touches. It ranks nothing a second way:
|
|
208
|
+
|
|
209
|
+
- **Complexity** is the factor the file hotspot score multiplies (`hotspotComplexityOf`:
|
|
210
|
+
max cognitive, else max cyclomatic), read even for a file with no churn.
|
|
211
|
+
- **Hotspot** is the file's row in `hotspots.list` at `window`: `rank` is its row number
|
|
212
|
+
there and `ranked` the list's total. A file scoring 0 has rank null.
|
|
213
|
+
- **Findings** are the open findings on the file or a symbol in it, worst first.
|
|
214
|
+
- **Delta**, only with `baseline`: score, complexity, and findings counts against the
|
|
215
|
+
baseline, findings bucketed by `bucketViolations` as `changes.get` buckets them, and each
|
|
216
|
+
open finding gets a `status`. Without a baseline `delta` is absent; across index versions
|
|
217
|
+
it is null.
|
|
218
|
+
- **Paths** are repo-relative. A leading `./`, `.` and `..` segments, and doubled slashes are
|
|
219
|
+
normalized; an absolute path counts only under `root`. A path the snapshot holds no file
|
|
220
|
+
for is a `not-indexed` row and one outside the repo an `outside-repo` row, never an error.
|
|
221
|
+
- The **rollup** counts each status, sums scores and open findings, and takes the top
|
|
222
|
+
complexity and best rank; with a comparable baseline it sums the deltas, a new file adding
|
|
223
|
+
its whole score.
|
|
224
|
+
|
|
225
|
+
## Package stats
|
|
226
|
+
|
|
227
|
+
`packages.stats` is code-graph's `computePartitionQuality` over a set of package roots, the
|
|
228
|
+
numbers codewatch's `graph arch --health` prints:
|
|
229
|
+
|
|
230
|
+
- **Roots** are repo-relative path prefixes. Given as `packages`, those; otherwise every root a
|
|
231
|
+
`layered-deps` rule names, the repo's tier config. `packagesFrom` says which, and is `none`
|
|
232
|
+
when neither names one. A file sits in the longest root it falls under; the rest count as
|
|
233
|
+
`unassignedFiles`.
|
|
234
|
+
- **Edges** are the structural layer the store reads by default, so `references` and `calls`
|
|
235
|
+
edges are left out, as are test and fixture files, as `computeArch` leaves them out.
|
|
236
|
+
- **Per package**: file count, internal, outgoing, and incoming edges, `cohesion`,
|
|
237
|
+
`instability`, `abstractness` (the share of `types` files), the measured `band`, and flags.
|
|
238
|
+
- **Layer** is declared, not measured: the root's tier in the first `layered-deps` rule that
|
|
239
|
+
names it, 0 the lowest. A root no rule names has `layer: { status: "undeclared" }`.
|
|
240
|
+
- **Cross edges** are the package-to-package counts with their intensity and flag, and
|
|
241
|
+
`modularity` is the partition's Newman-Girvan Q.
|
|
242
|
+
|
|
135
243
|
## Serving the commands
|
|
136
244
|
|
|
137
245
|
```ts
|