@shrkcrft/inspector 0.1.0-alpha.31 → 0.1.0-alpha.32
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/agent-task-prep.d.ts.map +1 -1
- package/dist/agent-task-prep.js +9 -1
- package/dist/codemod-assist.d.ts.map +1 -1
- package/dist/codemod-assist.js +3 -1
- package/dist/comment-syntax.d.ts +15 -0
- package/dist/comment-syntax.d.ts.map +1 -0
- package/dist/comment-syntax.js +15 -0
- package/dist/contribution-load-failures.d.ts +18 -2
- package/dist/contribution-load-failures.d.ts.map +1 -1
- package/dist/contribution-load-failures.js +20 -3
- package/dist/contributions-report.js +2 -2
- package/dist/convention-applicability.d.ts +46 -0
- package/dist/convention-applicability.d.ts.map +1 -0
- package/dist/convention-applicability.js +247 -0
- package/dist/convention-filter-level.d.ts +13 -0
- package/dist/convention-filter-level.d.ts.map +1 -0
- package/dist/convention-filter-level.js +13 -0
- package/dist/convention-registry.d.ts +29 -4
- package/dist/convention-registry.d.ts.map +1 -1
- package/dist/convention-registry.js +58 -23
- package/dist/custom-checks.d.ts.map +1 -1
- package/dist/custom-checks.js +6 -4
- package/dist/decision-records.d.ts +4 -0
- package/dist/decision-records.d.ts.map +1 -1
- package/dist/decision-records.js +165 -66
- package/dist/declared-reference-coverage.d.ts +1 -1
- package/dist/declared-reference-coverage.d.ts.map +1 -1
- package/dist/declared-reference-coverage.js +6 -1
- package/dist/feedback-ingestion.d.ts.map +1 -1
- package/dist/feedback-ingestion.js +7 -1
- package/dist/file-languages.d.ts +9 -0
- package/dist/file-languages.d.ts.map +1 -0
- package/dist/file-languages.js +91 -0
- package/dist/fix-preview.d.ts.map +1 -1
- package/dist/fix-preview.js +78 -17
- package/dist/fuzzy-impact.d.ts.map +1 -1
- package/dist/fuzzy-impact.js +2 -1
- package/dist/git-helpers.d.ts +29 -4
- package/dist/git-helpers.d.ts.map +1 -1
- package/dist/git-helpers.js +69 -10
- package/dist/i-contribution-file-validation.d.ts +8 -0
- package/dist/i-contribution-file-validation.d.ts.map +1 -1
- package/dist/i-convention-applicability-reason.d.ts +29 -0
- package/dist/i-convention-applicability-reason.d.ts.map +1 -0
- package/dist/i-convention-applicability-reason.js +1 -0
- package/dist/i-convention-applicability.d.ts +9 -0
- package/dist/i-convention-applicability.d.ts.map +1 -0
- package/dist/i-convention-applicability.js +1 -0
- package/dist/i-convention-scope.d.ts +19 -0
- package/dist/i-convention-scope.d.ts.map +1 -0
- package/dist/i-convention-scope.js +1 -0
- package/dist/i-file-language.d.ts +11 -0
- package/dist/i-file-language.d.ts.map +1 -0
- package/dist/i-file-language.js +1 -0
- package/dist/i-not-applicable-convention.d.ts +17 -0
- package/dist/i-not-applicable-convention.d.ts.map +1 -0
- package/dist/i-not-applicable-convention.js +1 -0
- package/dist/i-reference-pack-origin.d.ts +13 -0
- package/dist/i-reference-pack-origin.d.ts.map +1 -0
- package/dist/i-reference-pack-origin.js +1 -0
- package/dist/i-stale-path-hint-input.d.ts +18 -0
- package/dist/i-stale-path-hint-input.d.ts.map +1 -0
- package/dist/i-stale-path-hint-input.js +1 -0
- package/dist/i-unverifiable-remedy-group.d.ts +10 -0
- package/dist/i-unverifiable-remedy-group.d.ts.map +1 -0
- package/dist/i-unverifiable-remedy-group.js +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -0
- package/dist/knowledge-authoring.d.ts +1 -1
- package/dist/knowledge-authoring.d.ts.map +1 -1
- package/dist/knowledge-authoring.js +7 -6
- package/dist/knowledge-contribution-slots.d.ts +18 -0
- package/dist/knowledge-contribution-slots.d.ts.map +1 -0
- package/dist/knowledge-contribution-slots.js +25 -0
- package/dist/knowledge-entry-rejections.d.ts +17 -0
- package/dist/knowledge-entry-rejections.d.ts.map +1 -0
- package/dist/knowledge-entry-rejections.js +79 -0
- package/dist/knowledge-entry-verdict-record.d.ts +12 -0
- package/dist/knowledge-entry-verdict-record.d.ts.map +1 -1
- package/dist/knowledge-min-referenced-valve.d.ts +12 -0
- package/dist/knowledge-min-referenced-valve.d.ts.map +1 -0
- package/dist/knowledge-min-referenced-valve.js +12 -0
- package/dist/knowledge-rejected-entry.d.ts +28 -0
- package/dist/knowledge-rejected-entry.d.ts.map +1 -0
- package/dist/knowledge-rejected-entry.js +1 -0
- package/dist/knowledge-rename-command.d.ts +20 -0
- package/dist/knowledge-rename-command.d.ts.map +1 -0
- package/dist/knowledge-rename-command.js +34 -0
- package/dist/knowledge-rename-verb.d.ts +11 -0
- package/dist/knowledge-rename-verb.d.ts.map +1 -0
- package/dist/knowledge-rename-verb.js +11 -0
- package/dist/knowledge-rename.d.ts +1 -1
- package/dist/knowledge-rename.d.ts.map +1 -1
- package/dist/knowledge-rename.js +6 -5
- package/dist/knowledge-stale-gate.d.ts +2 -0
- package/dist/knowledge-stale-gate.d.ts.map +1 -1
- package/dist/knowledge-stale-gate.js +75 -3
- package/dist/knowledge-stale-quality-gate.d.ts.map +1 -1
- package/dist/knowledge-stale-quality-gate.js +34 -4
- package/dist/knowledge-stale.d.ts +10 -0
- package/dist/knowledge-stale.d.ts.map +1 -1
- package/dist/knowledge-stale.js +227 -33
- package/dist/knowledge-unverifiable-remedy.d.ts +56 -0
- package/dist/knowledge-unverifiable-remedy.d.ts.map +1 -0
- package/dist/knowledge-unverifiable-remedy.js +0 -0
- package/dist/pack-contributions-inventory.d.ts.map +1 -1
- package/dist/pack-contributions-inventory.js +4 -2
- package/dist/propose-knowledge.js +3 -2
- package/dist/reference-pack-origin.d.ts +18 -0
- package/dist/reference-pack-origin.d.ts.map +1 -0
- package/dist/reference-pack-origin.js +38 -0
- package/dist/repository-stats.d.ts.map +1 -1
- package/dist/repository-stats.js +3 -77
- package/dist/resolve-project-config.d.ts.map +1 -1
- package/dist/resolve-project-config.js +10 -1
- package/dist/self-config-doctor-v2.d.ts +1 -1
- package/dist/self-config-doctor-v2.d.ts.map +1 -1
- package/dist/self-config-doctor-v2.js +76 -12
- package/dist/self-config-doctor.d.ts.map +1 -1
- package/dist/self-config-doctor.js +2 -1
- package/dist/sharkcraft-inspector.d.ts.map +1 -1
- package/dist/sharkcraft-inspector.js +52 -12
- package/dist/stale-path-hint.d.ts +3 -0
- package/dist/stale-path-hint.d.ts.map +1 -0
- package/dist/stale-path-hint.js +47 -0
- package/dist/template-authoring.d.ts +1 -1
- package/dist/template-authoring.d.ts.map +1 -1
- package/dist/template-authoring.js +2 -1
- package/dist/validate-contribution-file.d.ts.map +1 -1
- package/dist/validate-contribution-file.js +15 -10
- package/dist/why-file.d.ts.map +1 -1
- package/dist/why-file.js +5 -4
- package/package.json +17 -17
package/dist/knowledge-stale.js
CHANGED
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
25
25
|
import * as nodePath from 'node:path';
|
|
26
26
|
import { globListSelects, globToRegex } from '@shrkcrft/boundaries';
|
|
27
|
-
import {
|
|
27
|
+
import { KnowledgeReferenceRoot } from '@shrkcrft/core';
|
|
28
|
+
import { KNOWLEDGE_REFERENCE_KINDS, referenceRootProblem, anchorShapeProblem, anchorsListProblem, declaredAnchorItems, declaredReferenceItems, knowledgeAnchors, knowledgeSourceFormat, referenceShapeProblem, referencesListProblem, todayUtcIso, verifiedOnAgeDays, } from '@shrkcrft/knowledge';
|
|
28
29
|
import { isCacheBackedKind, isReferenceCacheWarm, referenceIdExists, referenceIdsFor, } from "./reference-registry.js";
|
|
29
30
|
import { listPolicyDeclarations } from "./policy-registry.js";
|
|
30
31
|
import { checkReferenceContent, checkReferenceCount, hasContentAssertion, } from "./reference-content-check.js";
|
|
@@ -32,13 +33,28 @@ import { ReferenceFailure } from "./reference-failure.js";
|
|
|
32
33
|
import { KnowledgeEntryVerdict } from "./knowledge-entry-verdict.js";
|
|
33
34
|
import { KnowledgeUnverifiableReason } from "./knowledge-unverifiable-reason.js";
|
|
34
35
|
import { KnowledgeAdvisoryCode } from "./knowledge-advisory-code.js";
|
|
36
|
+
import { knowledgeRejectedEntries } from "./knowledge-entry-rejections.js";
|
|
35
37
|
import { ReferenceAssetKind } from "./reference-asset-kind.js";
|
|
38
|
+
import { stalePathHint } from "./stale-path-hint.js";
|
|
36
39
|
import { buildSymbolIndex } from "./symbol-index.js";
|
|
37
40
|
// The `command` reference case (and its anchor twin) — one injected resolver.
|
|
38
41
|
import { COMMAND_INDEX_NOT_INJECTED, resolveShrkCommandReference } from "./reference-registry.js";
|
|
39
42
|
import { CommandResolutionStatus } from "./command-resolution-status.js";
|
|
40
43
|
import { resolveSymbolInFile, SymbolResolution } from "./symbol-index.js";
|
|
44
|
+
import { packOriginByName, packOriginOfFile } from "./reference-pack-origin.js";
|
|
41
45
|
export const KNOWLEDGE_STALE_SCHEMA = 'sharkcraft.knowledge-stale/v1';
|
|
46
|
+
/** The `byReferenceKind` bucket of an item with no kind to bucket under (a string, a non-list value). */
|
|
47
|
+
const MALFORMED_KIND_BUCKET = '(malformed)';
|
|
48
|
+
/**
|
|
49
|
+
* A declared value as a check row carries it: `null` / `undefined` become their
|
|
50
|
+
* text, so no renderer dereferences them; anything else as declared
|
|
51
|
+
* (`formatKnowledgeReference` renders a non-object as written). The CHECK reads
|
|
52
|
+
* the original, so a `null` item says "is not an object (got null)" — the
|
|
53
|
+
* validator's words — not "is the string \"null\"".
|
|
54
|
+
*/
|
|
55
|
+
function displayedReference(value) {
|
|
56
|
+
return (value === null || value === undefined ? String(value) : value);
|
|
57
|
+
}
|
|
42
58
|
export var ReferenceCheckOutcome;
|
|
43
59
|
(function (ReferenceCheckOutcome) {
|
|
44
60
|
ReferenceCheckOutcome["Ok"] = "ok";
|
|
@@ -269,11 +285,20 @@ function workspacePackages(inspection) {
|
|
|
269
285
|
WORKSPACE_PACKAGES.set(inspection, out);
|
|
270
286
|
return out;
|
|
271
287
|
}
|
|
272
|
-
function checkPackageReference(inspection, id) {
|
|
288
|
+
function checkPackageReference(inspection, id, origin) {
|
|
273
289
|
const dir = workspacePackages(inspection).get(id);
|
|
274
290
|
if (dir) {
|
|
275
291
|
return { outcome: ReferenceCheckOutcome.Ok, message: `Package exists: ${id} (${dir})` };
|
|
276
292
|
}
|
|
293
|
+
// A pack's entry naming the pack that ships it (round 15 follow-up): the
|
|
294
|
+
// consumer's root package.json names neither its installed packs nor their
|
|
295
|
+
// names, but the contributing pack is installed by definition.
|
|
296
|
+
if (origin && origin.packageName === id) {
|
|
297
|
+
return {
|
|
298
|
+
outcome: ReferenceCheckOutcome.Ok,
|
|
299
|
+
message: `Package exists: ${id} (the contributing pack, installed at ${origin.displayRoot})`,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
277
302
|
// Last-resort backstop for repos without a `workspaces` field — reported as
|
|
278
303
|
// probable, because a directory name is not a package name.
|
|
279
304
|
const rel = id.startsWith('@') ? (id.split('/')[1] ?? '') : id;
|
|
@@ -479,14 +504,102 @@ function escapeRe(s) {
|
|
|
479
504
|
* `contains` / `matches` / `count`, does the target still say what the asset
|
|
480
505
|
* claims. Every non-ok result carries a {@link ReferenceFailure}.
|
|
481
506
|
*/
|
|
482
|
-
function checkReference(inspection, ref, graph, excludeDirs = []) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
if (
|
|
507
|
+
function checkReference(inspection, ref, graph, excludeDirs = [], origin, subject) {
|
|
508
|
+
// THE item-shape predicate the validator applies (a string the grammar
|
|
509
|
+
// refused, a number, a non-string `path`): MALFORMED here — never a crash in a
|
|
510
|
+
// path join, never a silent row.
|
|
511
|
+
const shape = referenceShapeProblem(ref);
|
|
512
|
+
if (shape) {
|
|
513
|
+
return {
|
|
514
|
+
outcome: ReferenceCheckOutcome.Invalid,
|
|
515
|
+
failure: ReferenceFailure.Malformed,
|
|
516
|
+
message: `malformed reference: ${shape}.`,
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
// THE `root` predicate the validator applies (round 15 follow-up): `root:
|
|
520
|
+
// pack` on an asset no pack contributes is MALFORMED — never a silent
|
|
521
|
+
// fallback to the project root, which would read a different file.
|
|
522
|
+
const rootProblem = referenceRootProblem(ref, origin !== undefined);
|
|
523
|
+
if (rootProblem?.severity === 'error') {
|
|
524
|
+
return {
|
|
525
|
+
outcome: ReferenceCheckOutcome.Invalid,
|
|
526
|
+
failure: ReferenceFailure.Malformed,
|
|
527
|
+
message: `malformed reference: ${rootProblem.message}.`,
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
// A `root: pack` that has an effect (the predicate's warning means none)
|
|
531
|
+
// moves every path read — the target, `contains` / `matches`, a `count`
|
|
532
|
+
// source — into the contributing pack's directory. The consumer's code graph
|
|
533
|
+
// never indexes a pack's files, and its count exclusions are consumer paths.
|
|
534
|
+
const pack = origin !== undefined && rootProblem === undefined && isPackRooted(ref) ? origin : undefined;
|
|
535
|
+
const rootDir = pack ? pack.packageRoot : inspection.projectRoot;
|
|
536
|
+
const base = checkReferenceTarget(inspection, ref, pack ? undefined : graph, rootDir, origin);
|
|
537
|
+
const asserted = base.outcome === ReferenceCheckOutcome.Ok ? applyAssertions(rootDir, ref, base, pack ? [] : excludeDirs) : base;
|
|
538
|
+
const result = asserted.outcome === ReferenceCheckOutcome.Ok || asserted.failure !== undefined
|
|
539
|
+
? asserted
|
|
540
|
+
: { ...asserted, failure: defaultFailure(ref.kind, asserted.outcome) };
|
|
541
|
+
const labelled = pack ? packRootedResult(result, pack) : result;
|
|
542
|
+
return withStalePathHint(labelled, ref, origin, pack !== undefined, subject);
|
|
543
|
+
}
|
|
544
|
+
/** A reference whose path resolves against its contributing pack's directory (`root: pack`). */
|
|
545
|
+
function isPackRooted(ref) {
|
|
546
|
+
return ref !== null && typeof ref === 'object' && ref.root === KnowledgeReferenceRoot.Pack;
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Every row of a pack-rooted reference names the root it resolved against —
|
|
550
|
+
* the renderers (text, gate violations, markdown, MCP) all print the message.
|
|
551
|
+
* A missing path is fixed in the pack, never by a consumer-side rename (the
|
|
552
|
+
* hint is {@link stalePathHint}'s).
|
|
553
|
+
*/
|
|
554
|
+
function packRootedResult(result, pack) {
|
|
555
|
+
return { ...result, message: `${result.message} (root: pack — ${pack.packageName} at ${pack.displayRoot})` };
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* A missing path's hint, from THE authority ({@link stalePathHint}, round 15
|
|
559
|
+
* closing A3): who declared the reference decides who fixes it — a pack (the
|
|
560
|
+
* round-15 repro: a pack doc referencing its own file read STALE, with a hint
|
|
561
|
+
* to rename a file the consumer does not own), a Markdown entry's frontmatter,
|
|
562
|
+
* or a rename. No other code path sets a missing path's `suggestion`.
|
|
563
|
+
*/
|
|
564
|
+
function withStalePathHint(result, ref, origin, packRooted, subject) {
|
|
565
|
+
if (result.failure !== ReferenceFailure.PathMissing || typeof ref.path !== 'string' || ref.path === '')
|
|
488
566
|
return result;
|
|
489
|
-
|
|
567
|
+
const suggestion = stalePathHint({
|
|
568
|
+
kind: String(ref.kind),
|
|
569
|
+
path: normalizeRel(ref.path),
|
|
570
|
+
packRooted,
|
|
571
|
+
...(origin !== undefined ? { pack: origin } : {}),
|
|
572
|
+
...(subject?.sourceFormat !== undefined ? { sourceFormat: subject.sourceFormat } : {}),
|
|
573
|
+
...(subject?.source !== undefined ? { source: subject.source } : {}),
|
|
574
|
+
});
|
|
575
|
+
return suggestion === undefined ? result : { ...result, suggestion };
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* A reference as the changeset scope sees it: a pack-rooted path — and a
|
|
579
|
+
* pack-rooted `count` source's globs, the tree the count is MEASURED over —
|
|
580
|
+
* made project-relative. Unprefixed, a count over the pack's `src/*.ts` was
|
|
581
|
+
* scoped in by a change to the CONSUMER's `src/` and never by the pack's.
|
|
582
|
+
*/
|
|
583
|
+
function scopedReference(ref, origin) {
|
|
584
|
+
if (!origin || !isPackRooted(ref) || origin.displayRoot === '.')
|
|
585
|
+
return ref;
|
|
586
|
+
const at = (rel) => `${origin.displayRoot}/${normalizeRel(rel)}`;
|
|
587
|
+
const globs = ref.count?.source?.files;
|
|
588
|
+
return {
|
|
589
|
+
...ref,
|
|
590
|
+
...(typeof ref.path === 'string' ? { path: at(ref.path) } : {}),
|
|
591
|
+
...(ref.count && Array.isArray(globs)
|
|
592
|
+
? {
|
|
593
|
+
count: {
|
|
594
|
+
...ref.count,
|
|
595
|
+
source: {
|
|
596
|
+
...ref.count.source,
|
|
597
|
+
files: globs.map((g) => (typeof g === 'string' && g.startsWith('!') ? `!${at(g.slice(1))}` : at(String(g)))),
|
|
598
|
+
},
|
|
599
|
+
},
|
|
600
|
+
}
|
|
601
|
+
: {}),
|
|
602
|
+
};
|
|
490
603
|
}
|
|
491
604
|
/** The failure mode of a non-ok check that did not name one. */
|
|
492
605
|
function defaultFailure(kind, outcome) {
|
|
@@ -543,8 +656,10 @@ function assertionFailure(base, a, what) {
|
|
|
543
656
|
};
|
|
544
657
|
}
|
|
545
658
|
/** Does the reference's TARGET exist? (Assertions are layered on by {@link checkReference}.) */
|
|
546
|
-
function checkReferenceTarget(inspection, ref, graph) {
|
|
547
|
-
|
|
659
|
+
function checkReferenceTarget(inspection, ref, graph, rootDir = inspection.projectRoot, origin) {
|
|
660
|
+
// The directory a path resolves against: the project root, or the
|
|
661
|
+
// contributing pack's directory for a `root: pack` reference.
|
|
662
|
+
const projectRoot = rootDir;
|
|
548
663
|
switch (ref.kind) {
|
|
549
664
|
case 'file': {
|
|
550
665
|
if (!ref.path)
|
|
@@ -564,7 +679,7 @@ function checkReferenceTarget(inspection, ref, graph) {
|
|
|
564
679
|
outcome: ReferenceCheckOutcome.Stale,
|
|
565
680
|
failure: ReferenceFailure.PathMissing,
|
|
566
681
|
message: `Directory missing: ${ref.path}`,
|
|
567
|
-
|
|
682
|
+
// The hint is {@link stalePathHint}'s — who declared it decides (A3).
|
|
568
683
|
};
|
|
569
684
|
}
|
|
570
685
|
case 'symbol': {
|
|
@@ -615,7 +730,7 @@ function checkReferenceTarget(inspection, ref, graph) {
|
|
|
615
730
|
case 'package': {
|
|
616
731
|
if (!ref.id)
|
|
617
732
|
return missingField('package', 'id');
|
|
618
|
-
return checkPackageReference(inspection, ref.id);
|
|
733
|
+
return checkPackageReference(inspection, ref.id, origin);
|
|
619
734
|
}
|
|
620
735
|
case 'url': {
|
|
621
736
|
// We never fetch URLs. Mark them unknown unless we can resolve to a
|
|
@@ -643,12 +758,12 @@ function missingField(kind, field) {
|
|
|
643
758
|
message: `malformed reference: ${kind} reference missing required field \`${field}\`.`,
|
|
644
759
|
};
|
|
645
760
|
}
|
|
761
|
+
/** A missing file — its hint is {@link stalePathHint}'s, who declared the reference decides (A3). */
|
|
646
762
|
function staleFile(rel) {
|
|
647
763
|
return {
|
|
648
764
|
outcome: ReferenceCheckOutcome.Stale,
|
|
649
765
|
failure: ReferenceFailure.PathMissing,
|
|
650
766
|
message: `File missing: ${rel}`,
|
|
651
|
-
suggestion: 'Restore the file or run `shrk knowledge rename-file <old> <new> --dry-run`.',
|
|
652
767
|
};
|
|
653
768
|
}
|
|
654
769
|
function staleId(kind, id) {
|
|
@@ -700,7 +815,10 @@ function subjectTouchesChangedFiles(subject, changed) {
|
|
|
700
815
|
if (changedList.includes(normalizeScopePath(subject.source)))
|
|
701
816
|
return true;
|
|
702
817
|
for (const ref of subject.references ?? []) {
|
|
703
|
-
|
|
818
|
+
// A malformed item (a string, a number) points at no path.
|
|
819
|
+
if (ref === null || typeof ref !== 'object')
|
|
820
|
+
continue;
|
|
821
|
+
if (pathTouched(typeof ref.path === 'string' ? ref.path : undefined, changedList))
|
|
704
822
|
return true;
|
|
705
823
|
// The scope the count is MEASURED over (`inspectSource` selects through
|
|
706
824
|
// `globListSelects`), so a change to a file its `!` excludes is no touch.
|
|
@@ -822,10 +940,14 @@ const PATH_ONLY_ADVISORY_CAP = 5;
|
|
|
822
940
|
* — the strong form (`symbol` pinned to the path) catches it. Never gating.
|
|
823
941
|
*/
|
|
824
942
|
function pathOnlyAdvisories(projectRoot, entry, refs, cache) {
|
|
825
|
-
|
|
943
|
+
// A malformed item (a string, a null, a non-string path) earns no advisory — it is an INVALID row.
|
|
944
|
+
if (refs.length === 0 ||
|
|
945
|
+
!refs.every((r) => referenceShapeProblem(r) === undefined && (r.kind === 'file' || r.kind === 'directory'))) {
|
|
826
946
|
return [];
|
|
947
|
+
}
|
|
827
948
|
const files = refs
|
|
828
|
-
|
|
949
|
+
// A pack-rooted path names a file in the pack, not in this tree (round 15 follow-up).
|
|
950
|
+
.filter((r) => r.kind === 'file' && r.path !== undefined && TS_SOURCE.test(r.path) && !isPackRooted(r))
|
|
829
951
|
.map((r) => r.path);
|
|
830
952
|
if (files.length === 0)
|
|
831
953
|
return [];
|
|
@@ -916,12 +1038,12 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
|
|
|
916
1038
|
* for a knowledge entry, a boundary rule and a policy check, so every asset
|
|
917
1039
|
* kind is verified by one checker.
|
|
918
1040
|
*/
|
|
919
|
-
const checkOne = (subjectId, ref, assetKind) => {
|
|
920
|
-
const result = checkReference(inspection, ref, options.graph, excludeDirs);
|
|
1041
|
+
const checkOne = (subjectId, ref, assetKind, origin, subject) => {
|
|
1042
|
+
const result = checkReference(inspection, ref, options.graph, excludeDirs, origin, subject);
|
|
921
1043
|
const outcome = result.outcome;
|
|
922
1044
|
const check = {
|
|
923
1045
|
entryId: subjectId,
|
|
924
|
-
reference: ref,
|
|
1046
|
+
reference: displayedReference(ref),
|
|
925
1047
|
outcome,
|
|
926
1048
|
message: result.message,
|
|
927
1049
|
...(result.confidence ? { symbolConfidence: result.confidence } : {}),
|
|
@@ -931,10 +1053,16 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
|
|
|
931
1053
|
...(result.actual !== undefined ? { actual: result.actual } : {}),
|
|
932
1054
|
...(assetKind ? { assetKind } : {}),
|
|
933
1055
|
};
|
|
934
|
-
|
|
1056
|
+
// A malformed item (a string, a number) has no kind to bucket under.
|
|
1057
|
+
const kindKey = ref !== null && typeof ref === 'object' && typeof ref.kind === 'string' ? ref.kind : MALFORMED_KIND_BUCKET;
|
|
1058
|
+
tallyOutcome((byReferenceKind[kindKey] ??= { checked: 0, ok: 0, stale: 0, missing: 0, unknown: 0, invalid: 0 }), outcome);
|
|
935
1059
|
if (result.failure)
|
|
936
1060
|
failureCounts[result.failure] += 1;
|
|
937
1061
|
const isStaleOrMissing = outcome === ReferenceCheckOutcome.Stale || outcome === ReferenceCheckOutcome.Missing;
|
|
1062
|
+
// A pack's reference is fixed in the pack (round 15 follow-up): a candidate
|
|
1063
|
+
// from THIS tree is never its rename — `fix --knowledge-stale` would point
|
|
1064
|
+
// a pack's entry at a consumer file. Its hint names `root: pack` instead.
|
|
1065
|
+
const findRename = isStaleOrMissing && origin === undefined;
|
|
938
1066
|
// A bare MEMBER name: the qualified spelling resolves in the same file, so
|
|
939
1067
|
// it is the replacement (`shrk fix --knowledge-stale` applies it).
|
|
940
1068
|
if (isStaleOrMissing && result.suggestedSymbol) {
|
|
@@ -948,7 +1076,7 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
|
|
|
948
1076
|
// only for the single unambiguous candidate. Wide mode also
|
|
949
1077
|
// emits scored candidate lists for the multi-candidate cases that
|
|
950
1078
|
// strict silently drops.
|
|
951
|
-
if (
|
|
1079
|
+
if (findRename && ref.kind === 'symbol' && ref.symbol && !check.replaceWith) {
|
|
952
1080
|
const all = (getSymbolIndex().get(ref.symbol) ?? []).filter((p) => p !== ref.path);
|
|
953
1081
|
if (all.length === 1) {
|
|
954
1082
|
check.replaceWith = {
|
|
@@ -966,7 +1094,7 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
|
|
|
966
1094
|
}
|
|
967
1095
|
}
|
|
968
1096
|
// File rename detection (directory move, basename match).
|
|
969
|
-
if (
|
|
1097
|
+
if (findRename && ref.kind === 'file' && ref.path && !check.replaceWith) {
|
|
970
1098
|
const indexed = getFileBasenameIndex();
|
|
971
1099
|
const uniq = pickUniqueRenameCandidate(ref.path, indexed);
|
|
972
1100
|
if (uniq) {
|
|
@@ -988,7 +1116,7 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
|
|
|
988
1116
|
}
|
|
989
1117
|
}
|
|
990
1118
|
// Directory rename detection.
|
|
991
|
-
if (
|
|
1119
|
+
if (findRename && ref.kind === 'directory' && ref.path && !check.replaceWith) {
|
|
992
1120
|
const indexed = getDirBasenameIndex();
|
|
993
1121
|
const uniq = pickUniqueRenameCandidate(ref.path, indexed);
|
|
994
1122
|
if (uniq) {
|
|
@@ -1012,21 +1140,61 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
|
|
|
1012
1140
|
return check;
|
|
1013
1141
|
};
|
|
1014
1142
|
for (const entry of inspection.knowledgeEntries) {
|
|
1143
|
+
// EVERY declared item is judged (`declaredReferenceItems` /
|
|
1144
|
+
// `declaredAnchorItems`): a non-list `references` or `anchors` is never
|
|
1145
|
+
// iterated (it crashed every inspection-backed verb) — each is reported
|
|
1146
|
+
// below as one INVALID row — and a malformed item is checked into an
|
|
1147
|
+
// INVALID row carrying the validator's words (`displayedReference`).
|
|
1148
|
+
const refs = declaredReferenceItems(entry);
|
|
1149
|
+
const anchorItems = declaredAnchorItems(entry);
|
|
1150
|
+
// The contributing pack (round 15 follow-up) — what a `root: pack` reference resolves against.
|
|
1151
|
+
const entrySource = inspection.entrySources?.get(entry.id);
|
|
1152
|
+
const packOrigin = entrySource?.type === 'pack' ? packOriginByName(inspection, entrySource.packageName) : undefined;
|
|
1015
1153
|
if (options.changedFiles &&
|
|
1016
1154
|
!subjectTouchesChangedFiles({
|
|
1017
1155
|
source: relativeSource(projectRoot, entry.source?.origin),
|
|
1018
|
-
references:
|
|
1019
|
-
anchors: entry
|
|
1156
|
+
references: refs.map((r) => scopedReference(r, packOrigin)),
|
|
1157
|
+
anchors: knowledgeAnchors(entry),
|
|
1020
1158
|
}, options.changedFiles)) {
|
|
1021
1159
|
continue;
|
|
1022
1160
|
}
|
|
1023
|
-
const
|
|
1024
|
-
const anchors = entry.anchors ?? [];
|
|
1161
|
+
const sourceFormat = knowledgeSourceFormat(entry);
|
|
1025
1162
|
let checkable = 0;
|
|
1026
1163
|
let failing = 0;
|
|
1164
|
+
// A non-list `references` / `anchors` value (TypeScript or Markdown), or a
|
|
1165
|
+
// malformed anchor item: declared, never checkable — MALFORMED, the same
|
|
1166
|
+
// problem the validator reports. One INVALID row each.
|
|
1167
|
+
const malformedRow = (declaredValue, message) => {
|
|
1168
|
+
counts.invalid += 1;
|
|
1169
|
+
failureCounts[ReferenceFailure.Malformed] += 1;
|
|
1170
|
+
tallyOutcome((byReferenceKind[MALFORMED_KIND_BUCKET] ??= { checked: 0, ok: 0, stale: 0, missing: 0, unknown: 0, invalid: 0 }), ReferenceCheckOutcome.Invalid);
|
|
1171
|
+
referenceChecks.push({
|
|
1172
|
+
entryId: entry.id,
|
|
1173
|
+
// As declared: a string renders as written, a map as `kind:value`.
|
|
1174
|
+
reference: displayedReference(declaredValue),
|
|
1175
|
+
outcome: ReferenceCheckOutcome.Invalid,
|
|
1176
|
+
failure: ReferenceFailure.Malformed,
|
|
1177
|
+
message,
|
|
1178
|
+
});
|
|
1179
|
+
};
|
|
1180
|
+
const listProblem = referencesListProblem(entry.references, sourceFormat);
|
|
1181
|
+
if (listProblem) {
|
|
1182
|
+
totalReferences += 1;
|
|
1183
|
+
malformedRow(entry.references, `malformed reference: ${listProblem}.`);
|
|
1184
|
+
}
|
|
1185
|
+
// An anchor row names WHICH anchor (`anchors`, `anchor #N` — the doctor's
|
|
1186
|
+
// spelling): rendered through the reference grammar, an anchor object read
|
|
1187
|
+
// `undefined:<id>`.
|
|
1188
|
+
const anchorsProblem = anchorsListProblem(entry.anchors);
|
|
1189
|
+
if (anchorsProblem) {
|
|
1190
|
+
totalAnchors += 1;
|
|
1191
|
+
malformedRow('anchors', `malformed anchor: ${anchorsProblem}.`);
|
|
1192
|
+
}
|
|
1193
|
+
// Who fixes a missing path (A3): a Markdown entry names its `references:` frontmatter.
|
|
1194
|
+
const hintSubject = { sourceFormat, source: relativeSource(projectRoot, entry.source?.origin) };
|
|
1027
1195
|
for (const ref of refs) {
|
|
1028
1196
|
totalReferences += 1;
|
|
1029
|
-
const check = checkOne(entry.id, ref);
|
|
1197
|
+
const check = checkOne(entry.id, ref, undefined, packOrigin, hintSubject);
|
|
1030
1198
|
if (check.outcome === ReferenceCheckOutcome.Ok)
|
|
1031
1199
|
counts.ok += 1;
|
|
1032
1200
|
else if (check.outcome === ReferenceCheckOutcome.Stale)
|
|
@@ -1044,8 +1212,16 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
|
|
|
1044
1212
|
}
|
|
1045
1213
|
referenceChecks.push(check);
|
|
1046
1214
|
}
|
|
1047
|
-
for (const
|
|
1215
|
+
for (const [i, item] of anchorItems.entries()) {
|
|
1048
1216
|
totalAnchors += 1;
|
|
1217
|
+
// THE anchor item-shape predicate the validator applies: a `null` item
|
|
1218
|
+
// crashed `checkAnchor` (`anchor.kind`), a non-string path its path join.
|
|
1219
|
+
const shape = anchorShapeProblem(item);
|
|
1220
|
+
if (shape) {
|
|
1221
|
+
malformedRow(`anchor #${i + 1}`, `malformed anchor: ${shape}.`);
|
|
1222
|
+
continue;
|
|
1223
|
+
}
|
|
1224
|
+
const anchor = item;
|
|
1049
1225
|
const inspected = checkAnchor(inspection, anchor, options.graph);
|
|
1050
1226
|
const failure = inspected.outcome === ReferenceCheckOutcome.Ok
|
|
1051
1227
|
? undefined
|
|
@@ -1066,18 +1242,21 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
|
|
|
1066
1242
|
});
|
|
1067
1243
|
}
|
|
1068
1244
|
const verdict = classifyChecks(checkable, failing);
|
|
1069
|
-
const declared = refs.length +
|
|
1245
|
+
const declared = refs.length + anchorItems.length + (listProblem ? 1 : 0) + (anchorsProblem ? 1 : 0);
|
|
1070
1246
|
const reason = verdict !== KnowledgeEntryVerdict.Unverifiable
|
|
1071
1247
|
? undefined
|
|
1072
1248
|
: declared === 0
|
|
1073
1249
|
? KnowledgeUnverifiableReason.NoReferences
|
|
1074
1250
|
: KnowledgeUnverifiableReason.OnlyUnverifiableReferences;
|
|
1075
1251
|
const type = String(entry.type);
|
|
1252
|
+
const origin = inspection.entrySources?.get(entry.id);
|
|
1076
1253
|
entryVerdicts.push({
|
|
1077
1254
|
entryId: entry.id,
|
|
1078
1255
|
verdict,
|
|
1079
1256
|
...(reason ? { reason } : {}),
|
|
1080
1257
|
source: relativeSource(projectRoot, entry.source?.origin),
|
|
1258
|
+
sourceFormat,
|
|
1259
|
+
...(origin?.type === 'pack' && origin.packageName ? { pack: origin.packageName } : {}),
|
|
1081
1260
|
type,
|
|
1082
1261
|
checkable,
|
|
1083
1262
|
failing,
|
|
@@ -1112,15 +1291,29 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
|
|
|
1112
1291
|
references: p.references ?? [],
|
|
1113
1292
|
})),
|
|
1114
1293
|
];
|
|
1294
|
+
// The contributing pack of a boundary rule / policy check a pack declares
|
|
1295
|
+
// (round 15 follow-up) — the same `root: pack` resolution a knowledge entry gets.
|
|
1296
|
+
const subjectPackOrigin = (subject) => {
|
|
1297
|
+
if (subject.assetKind === ReferenceAssetKind.BoundaryRule) {
|
|
1298
|
+
const src = inspection.boundarySources?.get(subject.id);
|
|
1299
|
+
return src?.type === 'pack' ? packOriginByName(inspection, src.packageName) : undefined;
|
|
1300
|
+
}
|
|
1301
|
+
const decl = policyDecls.find((p) => p.qualifiedId === subject.id);
|
|
1302
|
+
return decl?.source === 'pack' ? packOriginOfFile(inspection, decl.sourceFile) : undefined;
|
|
1303
|
+
};
|
|
1115
1304
|
for (const subject of subjects) {
|
|
1305
|
+
const packOrigin = subjectPackOrigin(subject);
|
|
1116
1306
|
if (options.changedFiles &&
|
|
1117
|
-
!subjectTouchesChangedFiles({
|
|
1307
|
+
!subjectTouchesChangedFiles({
|
|
1308
|
+
source: subject.source ?? '(unknown source)',
|
|
1309
|
+
references: subject.references.map((r) => scopedReference(r, packOrigin)),
|
|
1310
|
+
}, options.changedFiles)) {
|
|
1118
1311
|
continue;
|
|
1119
1312
|
}
|
|
1120
1313
|
let checkable = 0;
|
|
1121
1314
|
let failing = 0;
|
|
1122
1315
|
for (const ref of subject.references) {
|
|
1123
|
-
const check = checkOne(subject.id, ref, subject.assetKind);
|
|
1316
|
+
const check = checkOne(subject.id, ref, subject.assetKind, packOrigin);
|
|
1124
1317
|
if (isCheckableOutcome(check.outcome)) {
|
|
1125
1318
|
checkable += 1;
|
|
1126
1319
|
if (isFailingOutcome(check.outcome))
|
|
@@ -1227,6 +1420,7 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
|
|
|
1227
1420
|
coverage,
|
|
1228
1421
|
entryVerdicts,
|
|
1229
1422
|
unverifiableIds,
|
|
1423
|
+
rejectedEntries: knowledgeRejectedEntries(inspection),
|
|
1230
1424
|
failureCounts,
|
|
1231
1425
|
byAssetKind,
|
|
1232
1426
|
byEntryType,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { IKnowledgeEntryVerdictRecord } from './knowledge-entry-verdict-record.js';
|
|
2
|
+
import { KnowledgeMinReferencedValve } from './knowledge-min-referenced-valve.js';
|
|
3
|
+
import type { IUnverifiableRemedyGroup } from './i-unverifiable-remedy-group.js';
|
|
4
|
+
/** The channel sentence: both formats can declare references. */
|
|
5
|
+
export declare const DECLARE_REFERENCES_REMEDY = "Declare references[] (TypeScript) or a references: frontmatter list (Markdown)";
|
|
6
|
+
/** The valve a surface names (the verb takes the flag; `quality` refuses it). */
|
|
7
|
+
export declare function minReferencedValveText(valve: KnowledgeMinReferencedValve): string;
|
|
8
|
+
/**
|
|
9
|
+
* The fix for ONE unverifiable entry — `undefined` only for a local TypeScript
|
|
10
|
+
* (or other non-Markdown) entry that declares NOTHING (the heading names
|
|
11
|
+
* `references[]`). It branches on the verdict REASON (round 15 closing, A4): an
|
|
12
|
+
* entry that declares references, none checkable (a malformed item — a
|
|
13
|
+
* non-boolean `required`, an unknown kind or `root` — or only `url:`s), is told
|
|
14
|
+
* to fix what it declared, never to "add a references: frontmatter list" /
|
|
15
|
+
* "declare references[]" it already has. A pack's entries are fixed upstream;
|
|
16
|
+
* their `file:` / `directory:` paths resolve against the CONSUMER's root unless
|
|
17
|
+
* the reference declares `root: pack` (round 15 follow-up, F7 — then against
|
|
18
|
+
* the pack's own directory), and `package:` reads the consumer's root
|
|
19
|
+
* package.json plus the pack's own name.
|
|
20
|
+
*/
|
|
21
|
+
export declare function unverifiableFileRemedy(v: Pick<IKnowledgeEntryVerdictRecord, 'sourceFormat' | 'pack' | 'reason'>): string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* {@link unverifiableFileRemedy} for EVERY entry — what a per-entry row (the
|
|
24
|
+
* `--require-references` violation) prints: a local TypeScript entry that
|
|
25
|
+
* declares nothing is told to declare `references[]`, one whose references are
|
|
26
|
+
* all uncheckable to fix them (it read "declare references[]").
|
|
27
|
+
*/
|
|
28
|
+
export declare function unverifiableEntryRemedy(v: Pick<IKnowledgeEntryVerdictRecord, 'sourceFormat' | 'pack' | 'reason'>): string;
|
|
29
|
+
/**
|
|
30
|
+
* The heading of the unverifiable list, after `UNVERIFIABLE (N) — never
|
|
31
|
+
* checked; ` — by reason (round 15 closing, A4): it told every entry to
|
|
32
|
+
* "declare references[] …, a references: frontmatter list (Markdown) or
|
|
33
|
+
* anchors[]", over entries whose references exist and are malformed.
|
|
34
|
+
*/
|
|
35
|
+
export declare function unverifiableListHeading(verdicts: readonly Pick<IKnowledgeEntryVerdictRecord, 'verdict' | 'reason'>[]): string;
|
|
36
|
+
/**
|
|
37
|
+
* The remedy sentence for a run with unverifiable entries: the channel (or,
|
|
38
|
+
* for entries that declare references none of which is checkable, the fix to
|
|
39
|
+
* them — round 15 closing, A4), the valve this surface can name, and — when a
|
|
40
|
+
* pack contributed any of them — the pack that fixes them upstream.
|
|
41
|
+
*/
|
|
42
|
+
export declare function unverifiableRemedy(verdicts: readonly Pick<IKnowledgeEntryVerdictRecord, 'verdict' | 'pack' | 'reason'>[], valve: KnowledgeMinReferencedValve): string;
|
|
43
|
+
/**
|
|
44
|
+
* Unverifiable entries grouped by declaring file AND remedy, in report order —
|
|
45
|
+
* THE grouping the stale-check's per-file lines and `quality`'s notes read. A
|
|
46
|
+
* file whose entries need different fixes gets one group per fix: the first
|
|
47
|
+
* entry's remedy used to speak for its whole file (round 15 closing, A4).
|
|
48
|
+
*/
|
|
49
|
+
export declare function unverifiableRemedyGroups(verdicts: readonly Pick<IKnowledgeEntryVerdictRecord, 'entryId' | 'verdict' | 'source' | 'sourceFormat' | 'pack' | 'reason'>[]): IUnverifiableRemedyGroup[];
|
|
50
|
+
/**
|
|
51
|
+
* `<file>: <remedy>` for each file whose unverifiable entries need more than
|
|
52
|
+
* `references[]`, capped — `<file> (<ids>): <remedy>` when that file's entries
|
|
53
|
+
* need different fixes ({@link unverifiableRemedyGroups}).
|
|
54
|
+
*/
|
|
55
|
+
export declare function unverifiableFileRemedies(verdicts: readonly Pick<IKnowledgeEntryVerdictRecord, 'entryId' | 'verdict' | 'source' | 'sourceFormat' | 'pack' | 'reason'>[]): string[];
|
|
56
|
+
//# sourceMappingURL=knowledge-unverifiable-remedy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-unverifiable-remedy.d.ts","sourceRoot":"","sources":["../src/knowledge-unverifiable-remedy.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qCAAqC,CAAC;AACxF,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAEjF,iEAAiE;AACjE,eAAO,MAAM,yBAAyB,mFAC4C,CAAC;AAKnF,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,GAAG,MAAM,CAIjF;AAWD;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,CAAC,EAAE,IAAI,CAAC,4BAA4B,EAAE,cAAc,GAAG,MAAM,GAAG,QAAQ,CAAC,GACxE,MAAM,GAAG,SAAS,CAyBpB;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,CAAC,EAAE,IAAI,CAAC,4BAA4B,EAAE,cAAc,GAAG,MAAM,GAAG,QAAQ,CAAC,GACxE,MAAM,CAER;AAiBD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,SAAS,IAAI,CAAC,4BAA4B,EAAE,SAAS,GAAG,QAAQ,CAAC,EAAE,GAAG,MAAM,CAK7H;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,SAAS,IAAI,CAAC,4BAA4B,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC,EAAE,EACtF,KAAK,EAAE,2BAA2B,GACjC,MAAM,CAmBR;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,SAAS,IAAI,CAAC,4BAA4B,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,cAAc,GAAG,MAAM,GAAG,QAAQ,CAAC,EAAE,GAC7H,wBAAwB,EAAE,CAc5B;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,SAAS,IAAI,CAAC,4BAA4B,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,cAAc,GAAG,MAAM,GAAG,QAAQ,CAAC,EAAE,GAC7H,MAAM,EAAE,CAUV"}
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pack-contributions-inventory.d.ts","sourceRoot":"","sources":["../src/pack-contributions-inventory.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"pack-contributions-inventory.d.ts","sourceRoot":"","sources":["../src/pack-contributions-inventory.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
import { readFileSync } from 'node:fs';
|
|
26
26
|
import * as nodePath from 'node:path';
|
|
27
27
|
import { CONTRIBUTION_FILE_KEYS } from '@shrkcrft/plugin-api';
|
|
28
|
-
import { collectContributionLoadFailures, collectContributionRejections, collectRegistryOutcomes, formatEntryRejection, } from "./contribution-load-failures.js";
|
|
28
|
+
import { collectContributionLoadFailures, collectContributionRejections, collectRegistryOutcomes, formatEntryRejection, rejectedEntrySlot, } from "./contribution-load-failures.js";
|
|
29
29
|
import { ContributionKind } from "./contribution-kind.js";
|
|
30
30
|
import { describePackAssetFreshness, detectPackAssetFreshness } from "./pack-asset-freshness.js";
|
|
31
31
|
export { ContributionKind } from "./contribution-kind.js";
|
|
@@ -826,7 +826,9 @@ export function renderInventoryMarkdown(inv) {
|
|
|
826
826
|
lines.push('| File | Kind | Pack | Entry | Reasons |');
|
|
827
827
|
lines.push('| --- | --- | --- | --- | --- |');
|
|
828
828
|
for (const r of rejections) {
|
|
829
|
-
|
|
829
|
+
// THE slot label (round 15 closing review, A5): a whole Markdown document
|
|
830
|
+
// printed `[-1]` here; every other surface reads `rejectedEntrySlot`.
|
|
831
|
+
lines.push(`| \`${r.file}\` | ${r.kind} | ${r.packageName ?? ''} | ${r.entryId !== undefined ? `\`${r.entryId}\`` : '(no id)'} (${rejectedEntrySlot(r)}) | ${r.reasons.join('; ')} |`);
|
|
830
832
|
}
|
|
831
833
|
}
|
|
832
834
|
lines.push('');
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
14
14
|
import * as nodePath from 'node:path';
|
|
15
|
+
import { knowledgeAnchors, knowledgeReferences } from '@shrkcrft/knowledge';
|
|
15
16
|
import { getChangedFiles, getCommitSubjects, isGitRepo } from "./git-helpers.js";
|
|
16
17
|
import { inspectSharkcraft } from "./sharkcraft-inspector.js";
|
|
17
18
|
import { buildSymbolIndex, SymbolDeclarationKind, SymbolVisibility, } from "./symbol-index.js";
|
|
@@ -111,7 +112,7 @@ function buildCoverageIndex(entries) {
|
|
|
111
112
|
const files = new Map();
|
|
112
113
|
const symbolByFile = new Map();
|
|
113
114
|
for (const entry of entries) {
|
|
114
|
-
for (const ref of entry
|
|
115
|
+
for (const ref of knowledgeReferences(entry)) {
|
|
115
116
|
if (ref.kind === 'symbol' && ref.symbol) {
|
|
116
117
|
const symbolKey = ref.path
|
|
117
118
|
? `${ref.path}::${ref.symbol}`
|
|
@@ -130,7 +131,7 @@ function buildCoverageIndex(entries) {
|
|
|
130
131
|
files.set(ref.path, entry.id);
|
|
131
132
|
}
|
|
132
133
|
}
|
|
133
|
-
for (const anchor of entry
|
|
134
|
+
for (const anchor of knowledgeAnchors(entry)) {
|
|
134
135
|
if (anchor.kind === 'symbol' && anchor.symbol) {
|
|
135
136
|
const symbolKey = anchor.path
|
|
136
137
|
? `${anchor.path}::${anchor.symbol}`
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IReferencePackOrigin } from './i-reference-pack-origin.js';
|
|
2
|
+
import type { ISharkcraftInspection } from './sharkcraft-inspector.js';
|
|
3
|
+
/**
|
|
4
|
+
* The contributing pack of an asset whose provenance names it (`entrySources`
|
|
5
|
+
* / `boundarySources` → `{ type: 'pack', packageName }`), with its package
|
|
6
|
+
* directory from THE discovered pack list (`inspection.packs.validPacks`) —
|
|
7
|
+
* the directory the loaders read the pack's contribution files from. A name
|
|
8
|
+
* no valid pack carries has no directory: `undefined`.
|
|
9
|
+
*/
|
|
10
|
+
export declare function packOriginByName(inspection: ISharkcraftInspection, packageName: string | undefined): IReferencePackOrigin | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* The contributing pack of an asset known only by its declaring FILE (a
|
|
13
|
+
* pack's policy check): the valid pack whose package directory contains it —
|
|
14
|
+
* the innermost one, so a pack nested in another pack's `node_modules`
|
|
15
|
+
* resolves to itself.
|
|
16
|
+
*/
|
|
17
|
+
export declare function packOriginOfFile(inspection: ISharkcraftInspection, absFile: string | undefined): IReferencePackOrigin | undefined;
|
|
18
|
+
//# sourceMappingURL=reference-pack-origin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-pack-origin.d.ts","sourceRoot":"","sources":["../src/reference-pack-origin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAOvE;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,qBAAqB,EACjC,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,oBAAoB,GAAG,SAAS,CAIlC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,qBAAqB,EACjC,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,oBAAoB,GAAG,SAAS,CAUlC"}
|