@skill-map/cli 0.61.5 → 0.62.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/cli.js +1346 -479
- package/dist/index.js +368 -96
- package/dist/kernel/index.d.ts +232 -25
- package/dist/kernel/index.js +368 -96
- package/dist/migrations/001_initial.sql +18 -8
- package/dist/ui/{chunk-4N3NRZEH.js → chunk-276RLZR4.js} +1 -1
- package/dist/ui/{chunk-MGWGV4VD.js → chunk-34ZZDYNQ.js} +1 -1
- package/dist/ui/chunk-56CBK7LB.js +1 -0
- package/dist/ui/{chunk-OVVTCPBJ.js → chunk-7ANZW2OI.js} +1 -1
- package/dist/ui/chunk-BJ6X6WBO.js +4 -0
- package/dist/ui/{chunk-5SSKJ7AM.js → chunk-BOVJVOLH.js} +1 -1
- package/dist/ui/chunk-C42H2UHU.js +3 -0
- package/dist/ui/{chunk-GKQA75EF.js → chunk-CJURGJTN.js} +1 -1
- package/dist/ui/chunk-CM4YB7L4.js +2 -0
- package/dist/ui/{chunk-Q4PXVDJA.js → chunk-CZSLV6YD.js} +1 -1
- package/dist/ui/{chunk-7X3DZNG4.js → chunk-DLYJHLJX.js} +2 -2
- package/dist/ui/chunk-ECKRC6XD.js +1843 -0
- package/dist/ui/{chunk-JTCIY3SL.js → chunk-FC22ZJQZ.js} +1 -1
- package/dist/ui/{chunk-FRUHVCND.js → chunk-FYATUDAH.js} +1 -1
- package/dist/ui/chunk-IYC5ZW4L.js +2 -0
- package/dist/ui/{chunk-MBBJJEUX.js → chunk-JZ2YF7EL.js} +1 -1
- package/dist/ui/{chunk-HQ6M2HXK.js → chunk-LPDD2DHE.js} +1 -1
- package/dist/ui/{chunk-I52OQIZQ.js → chunk-NC3HOVDG.js} +1 -1
- package/dist/ui/{chunk-N6MUHKWR.js → chunk-UTRZTB6V.js} +1 -1
- package/dist/ui/chunk-VHEFRMK3.js +1 -0
- package/dist/ui/chunk-Y2Z26SRI.js +1 -0
- package/dist/ui/index.html +1 -1
- package/dist/ui/main-RW5YGD6H.js +4 -0
- package/migrations/001_initial.sql +18 -8
- package/package.json +2 -2
- package/dist/ui/chunk-6NYH7LND.js +0 -3
- package/dist/ui/chunk-7VUEZZFJ.js +0 -1
- package/dist/ui/chunk-AKKFFP7Y.js +0 -1
- package/dist/ui/chunk-L34EUS75.js +0 -2
- package/dist/ui/chunk-UTGLW5ON.js +0 -1843
- package/dist/ui/chunk-ZYPXVXYF.js +0 -4
- package/dist/ui/main-OTDMPZHD.js +0 -4
package/dist/kernel/index.d.ts
CHANGED
|
@@ -1341,19 +1341,33 @@ interface ScanResult {
|
|
|
1341
1341
|
*/
|
|
1342
1342
|
tokenizer?: string;
|
|
1343
1343
|
/**
|
|
1344
|
-
* Effective
|
|
1345
|
-
*
|
|
1346
|
-
*
|
|
1347
|
-
*
|
|
1348
|
-
*
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
*
|
|
1355
|
-
|
|
1356
|
-
|
|
1344
|
+
* Effective walk ceiling for this scan (`--max-scan <N>` override on
|
|
1345
|
+
* `sm scan` / `sm watch` / `sm serve`, else `scan.maxScan` from
|
|
1346
|
+
* settings, default 50000). The scan walks, parses, analyzes, and
|
|
1347
|
+
* reference-validates the full corpus up to this number, so references
|
|
1348
|
+
* resolve across the whole project regardless of how many nodes the
|
|
1349
|
+
* map renders. Mirrors `scan_meta.scan_ceiling`. Absent on synthetic
|
|
1350
|
+
* fixtures that bypass the walker.
|
|
1351
|
+
*/
|
|
1352
|
+
scanCeiling?: number;
|
|
1353
|
+
/**
|
|
1354
|
+
* True when the walker reached `scanCeiling` and dropped files in
|
|
1355
|
+
* stable provider-walker order, false otherwise. Drives the CLI "scan
|
|
1356
|
+
* truncated" notice and the UI persistent banner pointing at the
|
|
1357
|
+
* `.skillmapignore` editor. Mirrors `scan_meta.scan_truncated`. Absent
|
|
1358
|
+
* on synthetic fixtures that bypass the walker.
|
|
1359
|
+
*/
|
|
1360
|
+
scanTruncated?: boolean;
|
|
1361
|
+
/**
|
|
1362
|
+
* Effective map render cap for this scan (`--max-nodes <N>` override,
|
|
1363
|
+
* else `scan.maxNodes` from settings, default 256). Does NOT bound the
|
|
1364
|
+
* scan (the full corpus up to `scanCeiling` is persisted and the
|
|
1365
|
+
* folders tree shows all of it); it only bounds the graph projection.
|
|
1366
|
+
* The UI projects the selected folder branch capped at this number and
|
|
1367
|
+
* raises an in-view banner when a branch exceeds it. Mirrors
|
|
1368
|
+
* `scan_meta.max_render_nodes`. Absent on synthetic fixtures.
|
|
1369
|
+
*/
|
|
1370
|
+
maxRenderNodes?: number;
|
|
1357
1371
|
/**
|
|
1358
1372
|
* Files the walker skipped because their on-disk size exceeded
|
|
1359
1373
|
* `scan.maxFileSizeBytes` (default 1 MiB). Each entry is the
|
|
@@ -1779,6 +1793,59 @@ interface INodeCounts {
|
|
|
1779
1793
|
links: number;
|
|
1780
1794
|
issues: number;
|
|
1781
1795
|
}
|
|
1796
|
+
/**
|
|
1797
|
+
* Lightweight per-node projection for the BFF `/api/folders` endpoint.
|
|
1798
|
+
* Carries only the cheap scalar columns the SPA folders tree needs
|
|
1799
|
+
* (`path`, `kind`, the two link counts, total tokens, mtime), never the
|
|
1800
|
+
* full `Node` (no frontmatter, body, links, signals, contributions).
|
|
1801
|
+
* Pushed straight from `scan_nodes` so a 50K corpus does not hydrate the
|
|
1802
|
+
* whole `ScanResult` into memory.
|
|
1803
|
+
*/
|
|
1804
|
+
interface ILiteNode {
|
|
1805
|
+
path: string;
|
|
1806
|
+
kind: string;
|
|
1807
|
+
linksInCount: number;
|
|
1808
|
+
linksOutCount: number;
|
|
1809
|
+
tokensTotal: number | null;
|
|
1810
|
+
modifiedAtMs: number | null;
|
|
1811
|
+
/**
|
|
1812
|
+
* The persisted `scan_nodes.sidecar_status`, null when there is no
|
|
1813
|
+
* parseable sidecar. Lets the folders rail flag staleness corpus-wide,
|
|
1814
|
+
* sibling of the issue counts.
|
|
1815
|
+
*/
|
|
1816
|
+
sidecarStatus: string | null;
|
|
1817
|
+
}
|
|
1818
|
+
/**
|
|
1819
|
+
* Per-node issue incidence counts by severity, output of
|
|
1820
|
+
* `port.scans.issueCountsByPath()`. One entry per node that has at least
|
|
1821
|
+
* one error- or warn-severity issue whose `nodeIds` array includes the
|
|
1822
|
+
* path; nodes with no error / warn issues are absent from the map. The
|
|
1823
|
+
* `info` severity is intentionally ignored (the SPA badges only error /
|
|
1824
|
+
* warn). Counts are issue incidence (one per matching issue), the same
|
|
1825
|
+
* semantics the UI's `countIssuesByPath` rolls up per node.
|
|
1826
|
+
*/
|
|
1827
|
+
interface IIssueIncidenceCount {
|
|
1828
|
+
error: number;
|
|
1829
|
+
warn: number;
|
|
1830
|
+
}
|
|
1831
|
+
/**
|
|
1832
|
+
* Output of `port.scans.loadBranch(...)`, the prefix-union + capped
|
|
1833
|
+
* graph projection the BFF `/api/branch` endpoint returns. `nodes` is
|
|
1834
|
+
* the first `LIMIT` nodes of the union (every requested prefix's
|
|
1835
|
+
* subtree) in stable path order (`ORDER BY path`); `links` carries only
|
|
1836
|
+
* edges whose source AND target are both in that node set; `issues`
|
|
1837
|
+
* carries only those whose `nodeIds` intersect it. `total` is the count
|
|
1838
|
+
* of nodes in the union BEFORE the cap (so the route can compute
|
|
1839
|
+
* `truncated`). `paths` echoes the (de-duped) requested prefixes; the
|
|
1840
|
+
* whole-corpus case (no prefix) echoes `[]`.
|
|
1841
|
+
*/
|
|
1842
|
+
interface IBranchProjection {
|
|
1843
|
+
nodes: Node[];
|
|
1844
|
+
links: Link[];
|
|
1845
|
+
issues: Issue[];
|
|
1846
|
+
total: number;
|
|
1847
|
+
paths: string[];
|
|
1848
|
+
}
|
|
1782
1849
|
/**
|
|
1783
1850
|
* Lightweight option bag for `port.scans.persist`. Mirrors the optional
|
|
1784
1851
|
* inputs of the `persistScanResult(db, result, inputs)` free function
|
|
@@ -2310,6 +2377,26 @@ interface IRawNode {
|
|
|
2310
2377
|
* Empty / undefined on the happy path.
|
|
2311
2378
|
*/
|
|
2312
2379
|
parseIssues?: readonly IParseIssue[];
|
|
2380
|
+
/**
|
|
2381
|
+
* Incremental-walk fast path. `true` when the walker matched this
|
|
2382
|
+
* file's on-disk `mtime` against the prior scan snapshot (via
|
|
2383
|
+
* `IProviderWalkOptions.priorMtimes`) and SKIPPED reading + parsing the
|
|
2384
|
+
* body, the dominant per-file cost. For such a record `body` /
|
|
2385
|
+
* `frontmatter` / `frontmatterRaw` are empty placeholders: the
|
|
2386
|
+
* orchestrator reuses the prior node verbatim and reads the body
|
|
2387
|
+
* (through `reread`) ONLY when a sidecar change forces re-extraction.
|
|
2388
|
+
* Absent / `false` means a normal record whose body was read eagerly.
|
|
2389
|
+
*/
|
|
2390
|
+
unchanged?: boolean;
|
|
2391
|
+
/**
|
|
2392
|
+
* Present only on an `unchanged` record: a lazy reader that performs
|
|
2393
|
+
* the deferred `readFile` + parse and returns the body / frontmatter
|
|
2394
|
+
* the walker skipped. The orchestrator calls it only when it must
|
|
2395
|
+
* actually re-extract (a sidecar edit on an otherwise-unchanged file).
|
|
2396
|
+
* Keeps the read + parse logic in the walker (single source) rather
|
|
2397
|
+
* than duplicating it in the orchestrator.
|
|
2398
|
+
*/
|
|
2399
|
+
reread?: () => Promise<Pick<IRawNode, 'body' | 'frontmatterRaw' | 'frontmatter' | 'parseIssues'>>;
|
|
2313
2400
|
}
|
|
2314
2401
|
/**
|
|
2315
2402
|
* Runtime descriptor of one Provider kind, populated by the loader from
|
|
@@ -2809,6 +2896,30 @@ interface IProviderWalkOptions {
|
|
|
2809
2896
|
path: string;
|
|
2810
2897
|
bytes: number;
|
|
2811
2898
|
}) => void;
|
|
2899
|
+
/**
|
|
2900
|
+
* Incremental-walk hint: prior-scan file mtimes keyed by root-relative
|
|
2901
|
+
* path (the same form as `IRawNode.path`). When supplied, the kernel
|
|
2902
|
+
* walker compares each file's on-disk `mtime` against this map and, on
|
|
2903
|
+
* a match, yields a lightweight `unchanged` record WITHOUT reading or
|
|
2904
|
+
* parsing the body (the dominant cost on a re-scan). The orchestrator
|
|
2905
|
+
* builds this from the prior snapshot only when cache reuse is on and
|
|
2906
|
+
* the tokenizer is unchanged; absent means "read every file" (the
|
|
2907
|
+
* full-scan default). A Provider shipping its own `walk()` MAY honour
|
|
2908
|
+
* it for the same speedup but is not required to.
|
|
2909
|
+
*/
|
|
2910
|
+
priorMtimes?: ReadonlyMap<string, number>;
|
|
2911
|
+
/**
|
|
2912
|
+
* Scoped-walk hint for the watcher's incremental path: an explicit
|
|
2913
|
+
* list of ABSOLUTE file paths to read instead of traversing the
|
|
2914
|
+
* roots. When supplied, the kernel walker skips traversal entirely and
|
|
2915
|
+
* reads ONLY these paths (those matching the provider's `extensions`,
|
|
2916
|
+
* existing on disk, passing the size guard), yielding a normal
|
|
2917
|
+
* `IRawNode` per match. Built by the orchestrator from chokidar's
|
|
2918
|
+
* changed-path list; absent means "traverse the roots" (the full-scan
|
|
2919
|
+
* default). A Provider shipping its own `walk()` MAY honour it for the
|
|
2920
|
+
* same speedup but is not required to.
|
|
2921
|
+
*/
|
|
2922
|
+
scopedPaths?: readonly string[];
|
|
2812
2923
|
}
|
|
2813
2924
|
/**
|
|
2814
2925
|
* Declarative read config a Provider declares via `IProvider.read`.
|
|
@@ -4081,21 +4192,35 @@ interface RunScanOptions {
|
|
|
4081
4192
|
*/
|
|
4082
4193
|
activeProvider?: string | null;
|
|
4083
4194
|
/**
|
|
4084
|
-
*
|
|
4085
|
-
*
|
|
4086
|
-
*
|
|
4087
|
-
* `ScanResult.
|
|
4088
|
-
*
|
|
4089
|
-
*
|
|
4195
|
+
* Walk-intake ceiling (mirror of `scan.maxScan` in settings, default
|
|
4196
|
+
* 50000). Threaded through to `walkAndExtract` so the ceiling can fire
|
|
4197
|
+
* (dropping extra files in stable order) and so `ScanResult.scanCeiling`
|
|
4198
|
+
* / `ScanResult.scanTruncated` are populated. Absent → the orchestrator
|
|
4199
|
+
* falls back to 50000 (the design default), keeping out-of-band callers
|
|
4200
|
+
* and synthetic fixtures safe.
|
|
4090
4201
|
*/
|
|
4091
|
-
|
|
4202
|
+
scanCeiling?: number;
|
|
4092
4203
|
/**
|
|
4093
|
-
* Per-invocation override of the
|
|
4094
|
-
*
|
|
4095
|
-
*
|
|
4096
|
-
*
|
|
4204
|
+
* Per-invocation override of the walk ceiling (when `--max-scan <N>`
|
|
4205
|
+
* was passed). `null` (or absent) means no override; the configured
|
|
4206
|
+
* ceiling applies. Bidirectional: any positive integer replaces the
|
|
4207
|
+
* ceiling for the duration of this scan.
|
|
4097
4208
|
*/
|
|
4098
|
-
|
|
4209
|
+
overrideScanCeiling?: number | null;
|
|
4210
|
+
/**
|
|
4211
|
+
* Map render cap (mirror of `scan.maxNodes` in settings, default 256).
|
|
4212
|
+
* Pure metadata: it does NOT bound the walk. Threaded through to
|
|
4213
|
+
* `walkAndExtract` only so `ScanResult.maxRenderNodes` is populated and
|
|
4214
|
+
* the UI knows how many nodes to project onto the canvas. Absent → the
|
|
4215
|
+
* orchestrator falls back to 256.
|
|
4216
|
+
*/
|
|
4217
|
+
maxRenderNodes?: number;
|
|
4218
|
+
/**
|
|
4219
|
+
* Per-invocation override of the render cap (when `--max-nodes <N>`
|
|
4220
|
+
* was passed). `null` (or absent) means no override; the configured
|
|
4221
|
+
* render cap applies. Bidirectional. Never bounds the walk.
|
|
4222
|
+
*/
|
|
4223
|
+
overrideMaxRenderNodes?: number | null;
|
|
4099
4224
|
/**
|
|
4100
4225
|
* Mirror of `scan.maxFileSizeBytes` (default 1 MiB). Threaded into
|
|
4101
4226
|
* `walkAndExtract` so the walker skips any file larger than this
|
|
@@ -4104,6 +4229,38 @@ interface RunScanOptions {
|
|
|
4104
4229
|
* size limit (out-of-band callers and synthetic fixtures stay safe).
|
|
4105
4230
|
*/
|
|
4106
4231
|
maxFileSizeBytes?: number;
|
|
4232
|
+
/**
|
|
4233
|
+
* Watcher-only incremental fast path (pure perf, identical output to a
|
|
4234
|
+
* full scan). When supplied AND a prior snapshot exists AND
|
|
4235
|
+
* `enableCache` is on AND the tokenizer is unchanged, the orchestrator
|
|
4236
|
+
* does NOT traverse the directory tree. Instead it:
|
|
4237
|
+
*
|
|
4238
|
+
* - re-reads + re-extracts ONLY the files in `changed` (scoped read,
|
|
4239
|
+
* no `readdir`), and
|
|
4240
|
+
* - injects every other prior node as an `unchanged` record through
|
|
4241
|
+
* the SAME cache machinery the mtime-gate uses (`applyFullCacheHit`),
|
|
4242
|
+
* reusing its node + links + extractor runs verbatim, and
|
|
4243
|
+
* - drops the files in `removed` (the rename / orphan heuristic over
|
|
4244
|
+
* prior-vs-merged handles the disappearance + any rename).
|
|
4245
|
+
*
|
|
4246
|
+
* Paths are root-relative POSIX (the same form as `node.path`). A
|
|
4247
|
+
* sidecar (`.sm`) path in either set is mapped to its `.md` node so a
|
|
4248
|
+
* sidecar edit re-processes the node. The downstream analysis phases
|
|
4249
|
+
* (resolver, post-walk transforms, analyzers, broken-ref,
|
|
4250
|
+
* name-collision) always run over the fully-merged graph, so global
|
|
4251
|
+
* validation stays correct (a changed file's new link to an unchanged
|
|
4252
|
+
* file resolves; an unchanged file's link to a removed file breaks).
|
|
4253
|
+
*
|
|
4254
|
+
* `filesWalked` reflects only the scoped reads (far fewer than the
|
|
4255
|
+
* corpus), `scanTruncated` stays `false` (the ceiling never fires on a
|
|
4256
|
+
* scoped read). Absent (boot, `sm scan`, `sm scan --changed`,
|
|
4257
|
+
* meta-file change) falls back to the full-traversal + mtime-gate path,
|
|
4258
|
+
* byte-identical to today.
|
|
4259
|
+
*/
|
|
4260
|
+
incrementalChangedPaths?: {
|
|
4261
|
+
changed: ReadonlySet<string>;
|
|
4262
|
+
removed: ReadonlySet<string>;
|
|
4263
|
+
};
|
|
4107
4264
|
}
|
|
4108
4265
|
/**
|
|
4109
4266
|
* Same as `runScan` but also returns the rename heuristic's `RenameOp[]`
|
|
@@ -4608,6 +4765,15 @@ interface StoragePort {
|
|
|
4608
4765
|
* `node.kind` is open string per `node.schema.json`).
|
|
4609
4766
|
*/
|
|
4610
4767
|
load(): Promise<ScanResult>;
|
|
4768
|
+
/**
|
|
4769
|
+
* Metadata-only `ScanResult`: every scalar field plus real
|
|
4770
|
+
* `COUNT(*)` stats, but empty `nodes` / `links` / `issues` arrays.
|
|
4771
|
+
* Reads only the single `scan_meta` row plus the counts, never the
|
|
4772
|
+
* node / link / issue tables, so the BFF `GET /api/scan?meta=1` boot
|
|
4773
|
+
* fetch stays cheap on a large corpus. The SPA pairs it with
|
|
4774
|
+
* `/api/folders` (tree) and `/api/branch` (map).
|
|
4775
|
+
*/
|
|
4776
|
+
loadMeta(): Promise<ScanResult>;
|
|
4611
4777
|
/**
|
|
4612
4778
|
* Spec § A.9, fine-grained extractor-runs cache breadcrumbs.
|
|
4613
4779
|
* Returns `Map<nodePath, Map<qualifiedExtractorId, IPriorExtractorRun>>`.
|
|
@@ -4629,6 +4795,47 @@ interface StoragePort {
|
|
|
4629
4795
|
* is not in the persisted scan.
|
|
4630
4796
|
*/
|
|
4631
4797
|
findNode(path: string): Promise<INodeBundle | null>;
|
|
4798
|
+
/**
|
|
4799
|
+
* Lightweight full-corpus node list `{ path, kind }[]`, ordered by
|
|
4800
|
+
* `path` ASC. Backs the BFF `/api/folders` endpoint: the SPA folders
|
|
4801
|
+
* tree renders the whole scanned corpus (up to `scan.maxScan`)
|
|
4802
|
+
* without hydrating the full `ScanResult`. Pushes the projection to
|
|
4803
|
+
* SQL (`SELECT path, kind`), never loads the rest of the row.
|
|
4804
|
+
*/
|
|
4805
|
+
listLiteNodes(): Promise<ILiteNode[]>;
|
|
4806
|
+
/**
|
|
4807
|
+
* Per-node issue incidence counts by severity, keyed by node path.
|
|
4808
|
+
* Expands every `scan_issues.node_ids_json` array with SQLite
|
|
4809
|
+
* `json_each` and groups by `(value, severity)` so the count is
|
|
4810
|
+
* computed in SQL, not by loading every issue into memory. Only
|
|
4811
|
+
* error / warn severities are tallied (the SPA badges ignore
|
|
4812
|
+
* `info`); nodes with no error / warn issue are absent from the
|
|
4813
|
+
* map. Backs the `errorCount` / `warnCount` fields on `/api/folders`.
|
|
4814
|
+
*/
|
|
4815
|
+
issueCountsByPath(): Promise<Map<string, IIssueIncidenceCount>>;
|
|
4816
|
+
/**
|
|
4817
|
+
* Effective map-render cap recorded by the latest scan
|
|
4818
|
+
* (`scan_meta.max_render_nodes`). Returns the design default (256)
|
|
4819
|
+
* when no `scan_meta` row exists (DB freshly migrated / never
|
|
4820
|
+
* scanned). Backs the `/api/branch` cap default + clamp ceiling.
|
|
4821
|
+
*/
|
|
4822
|
+
effectiveMaxRenderNodes(): Promise<number>;
|
|
4823
|
+
/**
|
|
4824
|
+
* Prefix-union, capped graph projection for the BFF `/api/branch`
|
|
4825
|
+
* endpoint. A node is in the branch when, for ANY prefix in
|
|
4826
|
+
* `prefixes`, its `path === prefix` or starts with `prefix + '/'`;
|
|
4827
|
+
* the per-prefix subtrees are UNIONed. An empty `prefixes` array
|
|
4828
|
+
* selects the whole corpus. Identical prefixes are de-duped
|
|
4829
|
+
* defensively. `nodes` is the first `limit` matching nodes of the
|
|
4830
|
+
* union in stable path order (`ORDER BY path LIMIT`); `links`
|
|
4831
|
+
* carries only edges whose source AND target are both in `nodes`;
|
|
4832
|
+
* `issues` carries only those whose `nodeIds` intersect `nodes`.
|
|
4833
|
+
* `total` is the count of union nodes BEFORE the cap (so the route
|
|
4834
|
+
* can compute `truncated`); `paths` echoes the de-duped prefixes.
|
|
4835
|
+
* All scoping + capping happens in SQL so a 50K corpus never
|
|
4836
|
+
* hydrates into memory.
|
|
4837
|
+
*/
|
|
4838
|
+
loadBranch(prefixes: string[], limit: number): Promise<IBranchProjection>;
|
|
4632
4839
|
};
|
|
4633
4840
|
/**
|
|
4634
4841
|
* Phase 3 / View contribution system, read access to
|