@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
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE per-file extension → language authority (round 15, 15.1).
|
|
3
|
+
*
|
|
4
|
+
* Promoted from `shrk stats` (`repository-stats.ts`, where it was
|
|
5
|
+
* module-private), because a convention's `appliesTo.languages` filter needs a
|
|
6
|
+
* per-file language and the tree had four unrelated maps with four different
|
|
7
|
+
* vocabularies. This is the widest one and the vocabulary `shrk stats` prints
|
|
8
|
+
* (`typescript`, `javascript`, `python`, …), so an author can read the ids
|
|
9
|
+
* they may write off `shrk stats`. `shrk stats`, `conventionApplicability` and
|
|
10
|
+
* the self-config doctor's language-id check read this table and nothing else.
|
|
11
|
+
*
|
|
12
|
+
* (The polyglot `LanguageId` enum, `languages/`, is a different, workspace-level
|
|
13
|
+
* question — which toolchains a repo runs — and keeps its own seven ids.)
|
|
14
|
+
*/
|
|
15
|
+
import * as nodePath from 'node:path';
|
|
16
|
+
import { CommentSyntax } from "./comment-syntax.js";
|
|
17
|
+
export const FILE_LANGUAGES = Object.freeze([
|
|
18
|
+
{ id: 'typescript', extensions: ['.ts', '.tsx', '.mts', '.cts'], comment: CommentSyntax.CFamily },
|
|
19
|
+
{ id: 'javascript', extensions: ['.js', '.jsx', '.mjs', '.cjs'], comment: CommentSyntax.CFamily },
|
|
20
|
+
{ id: 'java', extensions: ['.java'], comment: CommentSyntax.CFamily },
|
|
21
|
+
{ id: 'kotlin', extensions: ['.kt', '.kts'], comment: CommentSyntax.CFamily },
|
|
22
|
+
{ id: 'scala', extensions: ['.scala'], comment: CommentSyntax.CFamily },
|
|
23
|
+
{ id: 'groovy', extensions: ['.groovy'], comment: CommentSyntax.CFamily },
|
|
24
|
+
{ id: 'csharp', extensions: ['.cs'], comment: CommentSyntax.CFamily },
|
|
25
|
+
{ id: 'cpp', extensions: ['.cpp', '.cc', '.cxx', '.hpp', '.hh', '.hxx'], comment: CommentSyntax.CFamily },
|
|
26
|
+
{ id: 'c', extensions: ['.c', '.h'], comment: CommentSyntax.CFamily },
|
|
27
|
+
{ id: 'go', extensions: ['.go'], comment: CommentSyntax.CFamily },
|
|
28
|
+
{ id: 'rust', extensions: ['.rs'], comment: CommentSyntax.CFamily },
|
|
29
|
+
{ id: 'swift', extensions: ['.swift'], comment: CommentSyntax.CFamily },
|
|
30
|
+
{ id: 'php', extensions: ['.php'], comment: CommentSyntax.CFamily },
|
|
31
|
+
{ id: 'dart', extensions: ['.dart'], comment: CommentSyntax.CFamily },
|
|
32
|
+
{ id: 'python', extensions: ['.py', '.pyi'], comment: CommentSyntax.Hash },
|
|
33
|
+
{ id: 'ruby', extensions: ['.rb'], comment: CommentSyntax.Hash },
|
|
34
|
+
{ id: 'shell', extensions: ['.sh', '.bash', '.zsh', '.fish'], comment: CommentSyntax.Hash },
|
|
35
|
+
{ id: 'perl', extensions: ['.pl', '.pm'], comment: CommentSyntax.Hash },
|
|
36
|
+
{ id: 'r', extensions: ['.r', '.R'], comment: CommentSyntax.Hash },
|
|
37
|
+
{ id: 'yaml', extensions: ['.yaml', '.yml'], comment: CommentSyntax.Hash },
|
|
38
|
+
{ id: 'toml', extensions: ['.toml'], comment: CommentSyntax.Hash },
|
|
39
|
+
{ id: 'ini', extensions: ['.ini', '.cfg', '.conf'], comment: CommentSyntax.Hash },
|
|
40
|
+
{ id: 'dockerfile', extensions: ['.dockerfile'], comment: CommentSyntax.Hash },
|
|
41
|
+
{ id: 'makefile', extensions: ['.mk'], comment: CommentSyntax.Hash },
|
|
42
|
+
{ id: 'html', extensions: ['.html', '.htm'], comment: CommentSyntax.Html },
|
|
43
|
+
{ id: 'xml', extensions: ['.xml', '.xsd', '.xsl'], comment: CommentSyntax.Html },
|
|
44
|
+
{ id: 'vue', extensions: ['.vue'], comment: CommentSyntax.Html },
|
|
45
|
+
{ id: 'svelte', extensions: ['.svelte'], comment: CommentSyntax.Html },
|
|
46
|
+
{ id: 'sql', extensions: ['.sql'], comment: CommentSyntax.Sql },
|
|
47
|
+
{ id: 'css', extensions: ['.css', '.scss', '.sass', '.less'], comment: CommentSyntax.CFamily },
|
|
48
|
+
{ id: 'lua', extensions: ['.lua'], comment: CommentSyntax.Lua },
|
|
49
|
+
{ id: 'elixir', extensions: ['.ex', '.exs'], comment: CommentSyntax.Hash },
|
|
50
|
+
{ id: 'clojure', extensions: ['.clj', '.cljs'], comment: CommentSyntax.Lisp },
|
|
51
|
+
{ id: 'lisp', extensions: ['.lisp', '.lsp', '.el'], comment: CommentSyntax.Lisp },
|
|
52
|
+
{ id: 'json', extensions: ['.json', '.jsonc'], comment: CommentSyntax.None },
|
|
53
|
+
{ id: 'markdown', extensions: ['.md', '.mdx'], comment: CommentSyntax.None },
|
|
54
|
+
{ id: 'text', extensions: ['.txt'], comment: CommentSyntax.None },
|
|
55
|
+
]);
|
|
56
|
+
const EXTENSION_INDEX = (() => {
|
|
57
|
+
const m = new Map();
|
|
58
|
+
for (const def of FILE_LANGUAGES) {
|
|
59
|
+
for (const ext of def.extensions)
|
|
60
|
+
m.set(ext.toLowerCase(), def);
|
|
61
|
+
}
|
|
62
|
+
return m;
|
|
63
|
+
})();
|
|
64
|
+
/** Extension-less files named for their language (case-insensitive basename). */
|
|
65
|
+
const BASENAME_OVERRIDES = new Map([
|
|
66
|
+
['dockerfile', 'dockerfile'],
|
|
67
|
+
['makefile', 'makefile'],
|
|
68
|
+
['gnumakefile', 'makefile'],
|
|
69
|
+
]);
|
|
70
|
+
/** The language of `path` (absolute or project-relative): a basename override, else its extension; `null` when unknown. */
|
|
71
|
+
export function fileLanguageOf(path) {
|
|
72
|
+
const override = BASENAME_OVERRIDES.get(nodePath.basename(path).toLowerCase());
|
|
73
|
+
if (override) {
|
|
74
|
+
const def = FILE_LANGUAGES.find((d) => d.id === override);
|
|
75
|
+
if (def)
|
|
76
|
+
return def;
|
|
77
|
+
}
|
|
78
|
+
const ext = nodePath.extname(path).toLowerCase();
|
|
79
|
+
if (!ext)
|
|
80
|
+
return null;
|
|
81
|
+
return EXTENSION_INDEX.get(ext) ?? null;
|
|
82
|
+
}
|
|
83
|
+
/** The language whose table row lists `extension` (`.ts` or `ts`), or `null`. */
|
|
84
|
+
export function fileLanguageForExtension(extension) {
|
|
85
|
+
const ext = (extension.startsWith('.') ? extension : `.${extension}`).toLowerCase();
|
|
86
|
+
return EXTENSION_INDEX.get(ext) ?? null;
|
|
87
|
+
}
|
|
88
|
+
/** Every language id of the table, in table order — THE vocabulary `appliesTo.languages` may name. */
|
|
89
|
+
export function fileLanguageIds() {
|
|
90
|
+
return FILE_LANGUAGES.map((d) => d.id);
|
|
91
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fix-preview.d.ts","sourceRoot":"","sources":["../src/fix-preview.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fix-preview.d.ts","sourceRoot":"","sources":["../src/fix-preview.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAEvE,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;AAE9D,oBAAY,OAAO;IACjB,WAAW,iBAAiB;IAC5B,cAAc,oBAAoB;IAClC,aAAa,mBAAmB;IAChC,QAAQ,aAAa;IACrB,UAAU,eAAe;IACzB,UAAU,gBAAgB;IAC1B,YAAY,kBAAkB;IAC9B,kBAAkB,yBAAyB;IAC3C,kBAAkB,yBAAyB;IAC3C,0BAA0B,iCAAiC;IAC3D,wBAAwB,+BAA+B;IACvD,uBAAuB,8BAA8B;IACrD,wBAAwB,gCAAgC;IACxD,0BAA0B,kCAAkC;IAC5D,qBAAqB,4BAA4B;CAClD;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACvC,8DAA8D;IAC9D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACvC,kEAAkE;IAClE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,kBAAkB,CAAC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,SAAS,OAAO,EAAE,CAAC;IAC1B,WAAW,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC/C;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,SAAS;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAClF,OAAO,EAAE,SAAS;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC9D;AAED,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,sBAAsB,CAAC,CAuCjC;AA+GD,wBAAgB,eAAe,CAC7B,UAAU,EAAE,qBAAqB,EACjC,OAAO,GAAE,kBAAuB,GAC/B,iBAAiB,CAyEnB;AA4CD;;4CAE4C;AAC5C,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,qBAAqB,EACjC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CAsF5B;AAED,wBAAgB,YAAY,IAAI,SAAS;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,EAAE,CAkBhF;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CA+B1E"}
|
package/dist/fix-preview.js
CHANGED
|
@@ -15,7 +15,11 @@
|
|
|
15
15
|
* Read-only at the inspector level. Schema: sharkcraft.fix-preview/v1
|
|
16
16
|
*/
|
|
17
17
|
import { diagnoseActionHints, } from "./action-hint-diagnostics.js";
|
|
18
|
+
import { KnowledgeSourceFormat } from '@shrkcrft/knowledge';
|
|
18
19
|
import { buildKnowledgeStaleReport, ReferenceCheckOutcome, } from "./knowledge-stale.js";
|
|
20
|
+
import { knowledgeRenameCommand } from "./knowledge-rename-command.js";
|
|
21
|
+
import { KnowledgeRenameVerb } from "./knowledge-rename-verb.js";
|
|
22
|
+
import { ReferenceFailure } from "./reference-failure.js";
|
|
19
23
|
import { buildTemplateDriftReport } from "./template-drift.js";
|
|
20
24
|
export const FIX_PREVIEW_SCHEMA = 'sharkcraft.fix-preview/v1';
|
|
21
25
|
export var FixKind;
|
|
@@ -107,6 +111,73 @@ function buildActionHintFix(issue) {
|
|
|
107
111
|
function slug(s) {
|
|
108
112
|
return s.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
|
|
109
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* One non-ok stale-check row as a fix suggestion (round 15 follow-up, F4).
|
|
116
|
+
*
|
|
117
|
+
* Every command it suggests is one the dispatcher RUNS: `knowledge
|
|
118
|
+
* rename-file` / `rename-symbol` are read-only previews already (they take no
|
|
119
|
+
* `--dry-run` — the suggestion used to name it, and the dispatcher refused it),
|
|
120
|
+
* and `fix preview` takes the entry as `--target <id>` (it takes no positional:
|
|
121
|
+
* `--knowledge-stale <id>` read the id as the flag's value and previewed every
|
|
122
|
+
* kind). An entry `shrk fix --knowledge-stale --apply` cannot edit — declared
|
|
123
|
+
* in Markdown (a `references:` frontmatter list), or contributed by a pack —
|
|
124
|
+
* says so in its description and gets no `--apply` command.
|
|
125
|
+
*/
|
|
126
|
+
function buildKnowledgeStaleFix(c, declaredBy) {
|
|
127
|
+
const ref = c.reference;
|
|
128
|
+
// A `command:` reference names its target in `command` (it read `→ <unknown>`).
|
|
129
|
+
const target = ref.id ?? ref.path ?? ref.symbol ?? ref.command ?? '<unknown>';
|
|
130
|
+
const failing = c.outcome === ReferenceCheckOutcome.Stale || c.outcome === ReferenceCheckOutcome.Missing;
|
|
131
|
+
const notAutoFixable = declaredBy?.pack !== undefined
|
|
132
|
+
? `not auto-fixable here: pack ${declaredBy.pack} contributes ${c.entryId} (${declaredBy.source}) — fix it upstream in the pack`
|
|
133
|
+
: declaredBy?.sourceFormat === KnowledgeSourceFormat.Markdown
|
|
134
|
+
? `not auto-fixable: ${c.entryId} is declared in Markdown (${declaredBy.source}) — \`shrk fix --knowledge-stale --apply\` edits TypeScript entries only; edit its references: frontmatter list by hand`
|
|
135
|
+
: undefined;
|
|
136
|
+
const replaceWith = c.replaceWith;
|
|
137
|
+
const hasRenameTarget = replaceWith !== undefined &&
|
|
138
|
+
(replaceWith.path !== undefined || replaceWith.id !== undefined || replaceWith.symbol !== undefined);
|
|
139
|
+
// A rename answers a MOVED target only — a path that is gone (`rename-file`
|
|
140
|
+
// matches any reference by its `path`) or a symbol no longer declared in its
|
|
141
|
+
// file (`rename-symbol`), never a content / count mismatch on a file that is
|
|
142
|
+
// still there. And only for an entry `--apply` can edit: a rename plan lands
|
|
143
|
+
// through `shrk fix --knowledge-stale --apply`, which refuses a Markdown or a
|
|
144
|
+
// pack entry — a pack's reference is fixed in the pack, never renamed onto
|
|
145
|
+
// this tree (the stale engine offers it no rename candidate either).
|
|
146
|
+
const renameCommand = !failing || notAutoFixable !== undefined
|
|
147
|
+
? undefined
|
|
148
|
+
: c.failure === ReferenceFailure.PathMissing && typeof ref.path === 'string'
|
|
149
|
+
? knowledgeRenameCommand(KnowledgeRenameVerb.RenameFile, ref.path, replaceWith?.path)
|
|
150
|
+
: c.failure === ReferenceFailure.AnchorMissing && ref.kind === 'symbol' && typeof ref.symbol === 'string'
|
|
151
|
+
? knowledgeRenameCommand(KnowledgeRenameVerb.RenameSymbol, ref.symbol, replaceWith?.symbol)
|
|
152
|
+
: undefined;
|
|
153
|
+
const applyCommand = failing && notAutoFixable === undefined
|
|
154
|
+
? hasRenameTarget
|
|
155
|
+
? 'shrk fix --knowledge-stale --apply'
|
|
156
|
+
: `shrk fix --knowledge-stale --apply ${c.outcome === ReferenceCheckOutcome.Missing ? '--drop-missing' : '--drop-stale'}`
|
|
157
|
+
: undefined;
|
|
158
|
+
const what = failing
|
|
159
|
+
? 'Stale reference'
|
|
160
|
+
: c.outcome === ReferenceCheckOutcome.Invalid
|
|
161
|
+
? 'Malformed reference'
|
|
162
|
+
: 'Unverifiable reference';
|
|
163
|
+
return {
|
|
164
|
+
kind: FixKind.KnowledgeStale,
|
|
165
|
+
targetId: c.entryId,
|
|
166
|
+
severity: c.outcome === ReferenceCheckOutcome.Missing ? 'error' : 'warning',
|
|
167
|
+
title: `${what} ${c.entryId} → ${target}`,
|
|
168
|
+
description: notAutoFixable !== undefined ? `${c.message} — ${notAutoFixable}.` : c.message,
|
|
169
|
+
nextCommands: [
|
|
170
|
+
`shrk knowledge references ${c.entryId}`,
|
|
171
|
+
...(renameCommand !== undefined ? [renameCommand] : []),
|
|
172
|
+
`shrk fix preview --knowledge-stale --target ${c.entryId}`,
|
|
173
|
+
...(applyCommand !== undefined ? [applyCommand] : []),
|
|
174
|
+
],
|
|
175
|
+
...(c.suggestion ? { draftBody: `// suggestion: ${c.suggestion}` } : {}),
|
|
176
|
+
...(notAutoFixable !== undefined ? { humanReviewRequired: true, reason: notAutoFixable } : {}),
|
|
177
|
+
previewFileName: `knowledge-stale-${slug(c.entryId)}.preview.md`,
|
|
178
|
+
stubbed: true,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
110
181
|
export function buildFixPreview(inspection, options = {}) {
|
|
111
182
|
const defaultKinds = [
|
|
112
183
|
FixKind.ActionHints,
|
|
@@ -126,25 +197,13 @@ export function buildFixPreview(inspection, options = {}) {
|
|
|
126
197
|
}
|
|
127
198
|
if (kinds.has(FixKind.KnowledgeStale)) {
|
|
128
199
|
const stale = buildKnowledgeStaleReport(inspection);
|
|
200
|
+
// The entry's declaring file, format and pack — what decides whether
|
|
201
|
+
// `--apply` can edit it (round 15 follow-up, F4).
|
|
202
|
+
const declared = new Map(stale.entryVerdicts.map((v) => [v.entryId, v]));
|
|
129
203
|
for (const c of stale.referenceChecks) {
|
|
130
204
|
if (c.outcome === ReferenceCheckOutcome.Ok)
|
|
131
205
|
continue;
|
|
132
|
-
|
|
133
|
-
suggestions.push({
|
|
134
|
-
kind: FixKind.KnowledgeStale,
|
|
135
|
-
targetId: c.entryId,
|
|
136
|
-
severity: c.outcome === ReferenceCheckOutcome.Missing ? 'error' : 'warning',
|
|
137
|
-
title: `Stale reference ${c.entryId} → ${target}`,
|
|
138
|
-
description: c.message,
|
|
139
|
-
nextCommands: [
|
|
140
|
-
`shrk knowledge references ${c.entryId}`,
|
|
141
|
-
`shrk knowledge rename-symbol <old> <new> --dry-run`,
|
|
142
|
-
`shrk fix preview --knowledge-stale ${c.entryId}`,
|
|
143
|
-
],
|
|
144
|
-
...(c.suggestion ? { draftBody: `// suggestion: ${c.suggestion}` } : {}),
|
|
145
|
-
previewFileName: `knowledge-stale-${slug(c.entryId)}.preview.md`,
|
|
146
|
-
stubbed: true,
|
|
147
|
-
});
|
|
206
|
+
suggestions.push(buildKnowledgeStaleFix(c, declared.get(c.entryId)));
|
|
148
207
|
}
|
|
149
208
|
}
|
|
150
209
|
if (kinds.has(FixKind.TemplateDrift)) {
|
|
@@ -162,7 +221,9 @@ export function buildFixPreview(inspection, options = {}) {
|
|
|
162
221
|
nextCommands: [
|
|
163
222
|
`shrk templates get ${e.templateId}`,
|
|
164
223
|
`shrk paths list`,
|
|
165
|
-
`
|
|
224
|
+
// `--target <id>`: `fix` takes no positional, so `--template-drift <id>`
|
|
225
|
+
// read the id as the flag's value and previewed every kind (F4).
|
|
226
|
+
`shrk fix preview --template-drift --target ${e.templateId} --write-preview`,
|
|
166
227
|
],
|
|
167
228
|
...(i.suggestedFix ? { draftBody: `// suggestion: ${i.suggestedFix}` } : {}),
|
|
168
229
|
previewFileName: `template-drift-${slug(e.templateId)}-${i.code}.preview.md`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fuzzy-impact.d.ts","sourceRoot":"","sources":["../src/fuzzy-impact.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fuzzy-impact.d.ts","sourceRoot":"","sources":["../src/fuzzy-impact.ts"],"names":[],"mappings":"AA4BA,OAAO,EACL,cAAc,EAEd,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAKvE,eAAO,MAAM,8BAA8B,0CAA0C,CAAC;AAEtF,oBAAY,qBAAqB;IAC/B,SAAS,eAAe;IACxB,SAAS,cAAc;IACvB,SAAS,eAAe;IACxB,UAAU,gBAAgB;IAC1B,OAAO,aAAa;IACpB,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,SAAS,cAAc;IACvB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,UAAU,eAAe;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,OAAO,8BAA8B,CAAC;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC3C,MAAM,EAAE,qBAAqB,CAAC;IAC9B,sEAAsE;IACtE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+CAA+C;IAC/C,YAAY,EAAE,SAAS,WAAW,EAAE,CAAC;IACrC,2EAA2E;IAC3E,eAAe,EAAE,OAAO,CAAC;IACzB,oEAAoE;IACpE,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,kCAAkC;IAClC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,8EAA8E;IAC9E,SAAS,CAAC,EAAE,cAAc,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IACzC,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAClC,6DAA6D;IAC7D,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAqaD,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,qBAAqB,EACjC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,0BAA+B,GACvC,sBAAsB,CA+BxB"}
|
package/dist/fuzzy-impact.js
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
*/
|
|
26
26
|
import { existsSync } from 'node:fs';
|
|
27
27
|
import * as nodePath from 'node:path';
|
|
28
|
+
import { knowledgeReferences } from '@shrkcrft/knowledge';
|
|
28
29
|
import { QueryMatchKind, resolveQuery, } from "./query-resolver.js";
|
|
29
30
|
import { HELPERS } from "./helper-registry.js";
|
|
30
31
|
import { listConstructs } from "./construct-registry.js";
|
|
@@ -129,7 +130,7 @@ function knowledgeFileReferences(inspection, knowledgeId) {
|
|
|
129
130
|
if (!k)
|
|
130
131
|
return [];
|
|
131
132
|
const out = [];
|
|
132
|
-
for (const ref of k
|
|
133
|
+
for (const ref of knowledgeReferences(k)) {
|
|
133
134
|
if (ref.kind === 'file' && ref.path)
|
|
134
135
|
out.push(ref.path);
|
|
135
136
|
}
|
package/dist/git-helpers.d.ts
CHANGED
|
@@ -20,6 +20,26 @@ export interface IGitStatusSummary {
|
|
|
20
20
|
export declare function isGitRepo(cwd: string): boolean;
|
|
21
21
|
export declare function getGitRoot(cwd: string): string | null;
|
|
22
22
|
export declare function getGitBranch(cwd: string): string | null;
|
|
23
|
+
/**
|
|
24
|
+
* The files a change touched, RELATIVE TO THE PROJECT ROOT `cwd` belongs to
|
|
25
|
+
* (`changedScopeRoot` — the root every caller resolves them against), sorted.
|
|
26
|
+
* git names a path relative to the work-tree TOP LEVEL. That is always true of
|
|
27
|
+
* `status --porcelain`, and of `diff` too once `diff.relative` is forced off,
|
|
28
|
+
* so a user's config cannot change the spelling. For a project nested in a
|
|
29
|
+
* larger repository (prefix `app/`), the top-level spelling `app/src/a.ts`
|
|
30
|
+
* resolved to `<root>/app/src/a.ts`, a file that does not exist. A
|
|
31
|
+
* changed-scope check (`conventions check --staged`, `--since`, and every
|
|
32
|
+
* other changed-scope reader) then checked nothing (round 15 lane B, B4). Every
|
|
33
|
+
* path is now mapped to root-relative. A change outside the project's subtree
|
|
34
|
+
* (a sibling package of the larger repository) is not in scope.
|
|
35
|
+
*
|
|
36
|
+
* Root-relative, never `cwd`-relative (lane B review): a command run from a
|
|
37
|
+
* subdirectory (`--cwd src`, a shell in `src/`) inspects the project root
|
|
38
|
+
* `detectProjectRoot` walks up to, so a `cwd`-relative `a.ts` resolved to
|
|
39
|
+
* `<root>/a.ts` — `validate-change`, `ownership affected`, `brief`, `tests
|
|
40
|
+
* impact` and `finish` read the wrong files where the top-level spelling had
|
|
41
|
+
* read the right ones.
|
|
42
|
+
*/
|
|
23
43
|
export declare function getChangedFiles(cwd: string, opts?: IGitChangedOptions): string[];
|
|
24
44
|
/**
|
|
25
45
|
* True when `ref` resolves to a commit in `cwd`'s repo. Lets a caller tell a
|
|
@@ -30,10 +50,15 @@ export declare function getChangedFiles(cwd: string, opts?: IGitChangedOptions):
|
|
|
30
50
|
*/
|
|
31
51
|
export declare function refExists(cwd: string, ref: string): boolean;
|
|
32
52
|
/**
|
|
33
|
-
* The content of `relPath` at `ref` (e.g. `git show HEAD
|
|
34
|
-
* when the path did not exist at that ref (a newly-added file) or git
|
|
35
|
-
* `relPath` is
|
|
36
|
-
*
|
|
53
|
+
* The content of `relPath` at `ref` (e.g. `git show HEAD:./src/x.ts`), or
|
|
54
|
+
* `null` when the path did not exist at that ref (a newly-added file) or git
|
|
55
|
+
* failed. `relPath` is relative to the project root `cwd` belongs to — the
|
|
56
|
+
* spelling `getChangedFiles` returns: git runs from that root and the `./` form
|
|
57
|
+
* resolves the path against it, so a project nested in a larger repository
|
|
58
|
+
* reads its own file (round 15 lane B, B4; the bare `<ref>:<path>` form is
|
|
59
|
+
* top-level-relative), and so does a caller whose `cwd` is a subdirectory
|
|
60
|
+
* (lane B review). Used to diff a file's PAST state against the working tree
|
|
61
|
+
* without a checkout — e.g. to see what a now-edited file used to
|
|
37
62
|
* provide/register.
|
|
38
63
|
*/
|
|
39
64
|
export declare function gitShowFile(cwd: string, ref: string, relPath: string): string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-helpers.d.ts","sourceRoot":"","sources":["../src/git-helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"git-helpers.d.ts","sourceRoot":"","sources":["../src/git-helpers.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;CAChB;AAqBD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAI9C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKrD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKvD;AA4BD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,MAAM,EAAE,CA+BpF;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAI3D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGpF;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAyC/D;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,EAAE,CA6BrF;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAKjD"}
|
package/dist/git-helpers.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
2
|
import { existsSync } from 'node:fs';
|
|
3
3
|
import * as nodePath from 'node:path';
|
|
4
|
+
import { detectProjectRoot } from '@shrkcrft/workspace';
|
|
4
5
|
// 512 MB — the same generous ceiling @shrkcrft/shared's runGitLines uses. A
|
|
5
6
|
// `diff`/`log --name-only` listing on a large changeset overflows Node's 1 MB
|
|
6
7
|
// default `maxBuffer` and dies with ENOBUFS; a name listing never approaches
|
|
@@ -38,22 +39,75 @@ export function getGitBranch(cwd) {
|
|
|
38
39
|
const out = r.stdout.trim();
|
|
39
40
|
return out.length > 0 ? out : null;
|
|
40
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Where `dir` sits inside its git work tree (`git rev-parse --show-prefix`):
|
|
44
|
+
* `''` at the top level, `app/` for a project nested in a larger repository.
|
|
45
|
+
* `''` too when git cannot tell (the paths are then used as git printed them).
|
|
46
|
+
*/
|
|
47
|
+
function gitPrefix(dir) {
|
|
48
|
+
const r = runGit(dir, ['rev-parse', '--show-prefix']);
|
|
49
|
+
return r.ok ? r.stdout.trim() : '';
|
|
50
|
+
}
|
|
51
|
+
/** A top-level-relative git path as a root-relative one, or `undefined` outside the root's subtree. */
|
|
52
|
+
function underPrefix(prefix, gitPath) {
|
|
53
|
+
if (prefix === '')
|
|
54
|
+
return gitPath;
|
|
55
|
+
return gitPath.startsWith(prefix) && gitPath.length > prefix.length ? gitPath.slice(prefix.length) : undefined;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The project root `cwd` belongs to — THE root `inspectSharkcraft` reads
|
|
59
|
+
* (`detectProjectRoot`: the nearest ancestor holding a root marker, `.git`
|
|
60
|
+
* included, so it never climbs out of the work tree). Every changed-scope path
|
|
61
|
+
* is spelled relative to it, from whichever subdirectory a command runs.
|
|
62
|
+
*/
|
|
63
|
+
function changedScopeRoot(cwd) {
|
|
64
|
+
return detectProjectRoot(cwd).root;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The files a change touched, RELATIVE TO THE PROJECT ROOT `cwd` belongs to
|
|
68
|
+
* (`changedScopeRoot` — the root every caller resolves them against), sorted.
|
|
69
|
+
* git names a path relative to the work-tree TOP LEVEL. That is always true of
|
|
70
|
+
* `status --porcelain`, and of `diff` too once `diff.relative` is forced off,
|
|
71
|
+
* so a user's config cannot change the spelling. For a project nested in a
|
|
72
|
+
* larger repository (prefix `app/`), the top-level spelling `app/src/a.ts`
|
|
73
|
+
* resolved to `<root>/app/src/a.ts`, a file that does not exist. A
|
|
74
|
+
* changed-scope check (`conventions check --staged`, `--since`, and every
|
|
75
|
+
* other changed-scope reader) then checked nothing (round 15 lane B, B4). Every
|
|
76
|
+
* path is now mapped to root-relative. A change outside the project's subtree
|
|
77
|
+
* (a sibling package of the larger repository) is not in scope.
|
|
78
|
+
*
|
|
79
|
+
* Root-relative, never `cwd`-relative (lane B review): a command run from a
|
|
80
|
+
* subdirectory (`--cwd src`, a shell in `src/`) inspects the project root
|
|
81
|
+
* `detectProjectRoot` walks up to, so a `cwd`-relative `a.ts` resolved to
|
|
82
|
+
* `<root>/a.ts` — `validate-change`, `ownership affected`, `brief`, `tests
|
|
83
|
+
* impact` and `finish` read the wrong files where the top-level spelling had
|
|
84
|
+
* read the right ones.
|
|
85
|
+
*/
|
|
41
86
|
export function getChangedFiles(cwd, opts = {}) {
|
|
42
87
|
if (!isGitRepo(cwd))
|
|
43
88
|
return [];
|
|
44
|
-
const
|
|
89
|
+
const root = changedScopeRoot(cwd);
|
|
90
|
+
const prefix = gitPrefix(root);
|
|
91
|
+
const args = ['-c', 'diff.relative=false', 'diff', '--name-only'];
|
|
45
92
|
if (opts.staged)
|
|
46
93
|
args.push('--cached');
|
|
47
94
|
if (opts.since)
|
|
48
95
|
args.push(opts.since);
|
|
49
|
-
const a = runGit(
|
|
50
|
-
const set = new Set(
|
|
96
|
+
const a = runGit(root, args);
|
|
97
|
+
const set = new Set();
|
|
98
|
+
const add = (gitPath) => {
|
|
99
|
+
const rel = underPrefix(prefix, gitPath);
|
|
100
|
+
if (rel !== undefined)
|
|
101
|
+
set.add(rel);
|
|
102
|
+
};
|
|
103
|
+
for (const p of parseLines(a.stdout))
|
|
104
|
+
add(p);
|
|
51
105
|
if (opts.includeWorktree && !opts.staged && !opts.since) {
|
|
52
106
|
// Include untracked + working-tree changes via `git status --porcelain`.
|
|
53
107
|
// `-uall` expands untracked directories to individual files (default
|
|
54
108
|
// `--porcelain` collapses them to a single `dir/` entry, which undercounts);
|
|
55
109
|
// `.gitignore` is still honored.
|
|
56
|
-
const s = runGit(
|
|
110
|
+
const s = runGit(root, ['status', '--porcelain', '-uall']);
|
|
57
111
|
if (s.ok) {
|
|
58
112
|
for (const line of s.stdout.split('\n')) {
|
|
59
113
|
// Strip the two-char XY status + leading space, then take the new path
|
|
@@ -61,7 +115,7 @@ export function getChangedFiles(cwd, opts = {}) {
|
|
|
61
115
|
const raw = line.slice(3).trim();
|
|
62
116
|
const path = raw.includes(' -> ') ? raw.slice(raw.indexOf(' -> ') + 4).trim() : raw;
|
|
63
117
|
if (path)
|
|
64
|
-
|
|
118
|
+
add(path);
|
|
65
119
|
}
|
|
66
120
|
}
|
|
67
121
|
}
|
|
@@ -81,14 +135,19 @@ export function refExists(cwd, ref) {
|
|
|
81
135
|
return r.ok && r.stdout.trim().length > 0;
|
|
82
136
|
}
|
|
83
137
|
/**
|
|
84
|
-
* The content of `relPath` at `ref` (e.g. `git show HEAD
|
|
85
|
-
* when the path did not exist at that ref (a newly-added file) or git
|
|
86
|
-
* `relPath` is
|
|
87
|
-
*
|
|
138
|
+
* The content of `relPath` at `ref` (e.g. `git show HEAD:./src/x.ts`), or
|
|
139
|
+
* `null` when the path did not exist at that ref (a newly-added file) or git
|
|
140
|
+
* failed. `relPath` is relative to the project root `cwd` belongs to — the
|
|
141
|
+
* spelling `getChangedFiles` returns: git runs from that root and the `./` form
|
|
142
|
+
* resolves the path against it, so a project nested in a larger repository
|
|
143
|
+
* reads its own file (round 15 lane B, B4; the bare `<ref>:<path>` form is
|
|
144
|
+
* top-level-relative), and so does a caller whose `cwd` is a subdirectory
|
|
145
|
+
* (lane B review). Used to diff a file's PAST state against the working tree
|
|
146
|
+
* without a checkout — e.g. to see what a now-edited file used to
|
|
88
147
|
* provide/register.
|
|
89
148
|
*/
|
|
90
149
|
export function gitShowFile(cwd, ref, relPath) {
|
|
91
|
-
const r = runGit(cwd, ['show', `${ref}
|
|
150
|
+
const r = runGit(changedScopeRoot(cwd), ['show', `${ref}:./${relPath.replace(/^\.\//, '')}`]);
|
|
92
151
|
return r.ok ? r.stdout : null;
|
|
93
152
|
}
|
|
94
153
|
export function getStatusSummary(cwd) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { IRejectedEntry } from '@shrkcrft/core';
|
|
2
|
+
import type { IKnowledgeValidationIssue } from '@shrkcrft/knowledge';
|
|
2
3
|
import type { ContributionKind } from './contribution-kind.js';
|
|
3
4
|
/**
|
|
4
5
|
* One contribution file validated at BUILD time through the runtime loader (or
|
|
@@ -18,6 +19,13 @@ export interface IContributionFileValidation {
|
|
|
18
19
|
readonly accepted: number;
|
|
19
20
|
readonly acceptedIds: readonly string[];
|
|
20
21
|
readonly rejected: readonly IRejectedEntry[];
|
|
22
|
+
/**
|
|
23
|
+
* Issues THE knowledge validator (`validateKnowledgeEntries`) reports on
|
|
24
|
+
* entries the loader ACCEPTED — the entry is kept, and the consumer's doctor
|
|
25
|
+
* reports the same issue (a non-list `references`, a malformed reference
|
|
26
|
+
* item). Knowledge-bearing slots only; absent when there are none (round 15).
|
|
27
|
+
*/
|
|
28
|
+
readonly entryIssues?: readonly IKnowledgeValidationIssue[];
|
|
21
29
|
/** True when no build-time validator exists for this slot (a reserved slot) — nothing was checked. */
|
|
22
30
|
readonly unvalidated?: boolean;
|
|
23
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i-contribution-file-validation.d.ts","sourceRoot":"","sources":["../src/i-contribution-file-validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,WAAW,2BAA2B;IAC1C,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACjC,qBAAqB;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;IAC7C,sGAAsG;IACtG,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC"}
|
|
1
|
+
{"version":3,"file":"i-contribution-file-validation.d.ts","sourceRoot":"","sources":["../src/i-contribution-file-validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,WAAW,2BAA2B;IAC1C,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACjC,qBAAqB;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;IAC7C;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAC5D,sGAAsG;IACtG,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ConventionAppliesToFilter } from '@shrkcrft/plugin-api';
|
|
2
|
+
import type { ConventionFilterLevel } from './convention-filter-level.js';
|
|
3
|
+
/** One declared `appliesTo` filter, judged — a line of `conventionApplicability(...).reasons`. */
|
|
4
|
+
export interface IConventionApplicabilityReason {
|
|
5
|
+
readonly filter: ConventionAppliesToFilter;
|
|
6
|
+
readonly level: ConventionFilterLevel;
|
|
7
|
+
/** The values the convention declares for this filter. */
|
|
8
|
+
readonly declared: readonly string[];
|
|
9
|
+
/**
|
|
10
|
+
* What the filter was compared with: the detected profiles / frameworks, the
|
|
11
|
+
* file's language, the file path — or, over a file list, the distinct values
|
|
12
|
+
* seen. Empty for a reserved filter and for a per-file filter judged without a file.
|
|
13
|
+
*/
|
|
14
|
+
readonly observed: readonly string[];
|
|
15
|
+
/**
|
|
16
|
+
* Did this filter admit the convention? A reserved filter always does (it is
|
|
17
|
+
* not evaluated); a per-file filter judged without a file does too (it is
|
|
18
|
+
* decided per file). Over a file list where no file passed (`conventionScope`),
|
|
19
|
+
* a per-file filter that admitted at least one file is `true` — it did not
|
|
20
|
+
* exclude the convention, another filter did — unless EVERY per-file filter
|
|
21
|
+
* admitted some file and none passed them all: then each is `false` and says
|
|
22
|
+
* the intersection is empty. So a not-applicable convention's `!matched`
|
|
23
|
+
* reasons are never empty and never name a filter that excluded nothing.
|
|
24
|
+
*/
|
|
25
|
+
readonly matched: boolean;
|
|
26
|
+
/** One printable sentence: `appliesTo.profileIds [has-turborepo]: none detected (detected: has-typescript)`. */
|
|
27
|
+
readonly message: string;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=i-convention-applicability-reason.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-convention-applicability-reason.d.ts","sourceRoot":"","sources":["../src/i-convention-applicability-reason.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAE1E,kGAAkG;AAClG,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IACtC,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,gHAAgH;IAChH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IConventionApplicabilityReason } from './i-convention-applicability-reason.js';
|
|
2
|
+
/** THE answer to "does this convention apply here?" — `conventionApplicability` (round 15, 15.1). */
|
|
3
|
+
export interface IConventionApplicability {
|
|
4
|
+
/** True iff every declared filter matched (an absent or empty filter imposes nothing). */
|
|
5
|
+
readonly applicable: boolean;
|
|
6
|
+
/** One judgement per DECLARED filter, workspace filters first — empty when `appliesTo` declares none. */
|
|
7
|
+
readonly reasons: readonly IConventionApplicabilityReason[];
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=i-convention-applicability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-convention-applicability.d.ts","sourceRoot":"","sources":["../src/i-convention-applicability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,wCAAwC,CAAC;AAE7F,qGAAqG;AACrG,MAAM,WAAW,wBAAwB;IACvC,0FAA0F;IAC1F,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,yGAAyG;IACzG,QAAQ,CAAC,OAAO,EAAE,SAAS,8BAA8B,EAAE,CAAC;CAC7D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { IConventionApplicabilityReason } from './i-convention-applicability-reason.js';
|
|
2
|
+
/**
|
|
3
|
+
* Which of a file list one convention covers — `conventionScope`, the ONE
|
|
4
|
+
* answer `conventions check` and the rule-graph bridge both read (round 15).
|
|
5
|
+
*/
|
|
6
|
+
export interface IConventionScope {
|
|
7
|
+
readonly conventionId: string;
|
|
8
|
+
/**
|
|
9
|
+
* False when a workspace filter excluded the convention, or when the file
|
|
10
|
+
* list was non-empty and no file in it passed the per-file filters: the
|
|
11
|
+
* convention is then never evaluated, and {@link reasons} say why.
|
|
12
|
+
*/
|
|
13
|
+
readonly applicable: boolean;
|
|
14
|
+
/** The files of the list the convention covers, in list order (empty when not applicable). */
|
|
15
|
+
readonly files: readonly string[];
|
|
16
|
+
/** The declared filters, judged — over the whole list for the per-file ones. */
|
|
17
|
+
readonly reasons: readonly IConventionApplicabilityReason[];
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=i-convention-scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-convention-scope.d.ts","sourceRoot":"","sources":["../src/i-convention-scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,wCAAwC,CAAC;AAE7F;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,8FAA8F;IAC9F,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,SAAS,8BAA8B,EAAE,CAAC;CAC7D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CommentSyntax } from './comment-syntax.js';
|
|
2
|
+
/** One row of THE extension → language table (`FILE_LANGUAGES`, `file-languages.ts`). */
|
|
3
|
+
export interface IFileLanguage {
|
|
4
|
+
/** The language id — the vocabulary `shrk stats` prints and `appliesTo.languages` names (`typescript`). */
|
|
5
|
+
readonly id: string;
|
|
6
|
+
/** File extensions, dot included (`.ts`); matched case-insensitively. */
|
|
7
|
+
readonly extensions: readonly string[];
|
|
8
|
+
/** How the language writes comments (`shrk stats` line classification). */
|
|
9
|
+
readonly comment: CommentSyntax;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=i-file-language.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-file-language.d.ts","sourceRoot":"","sources":["../src/i-file-language.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC5B,2GAA2G;IAC3G,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;CACjC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ConventionSeverity } from '@shrkcrft/plugin-api';
|
|
2
|
+
import type { IConventionApplicabilityReason } from './i-convention-applicability-reason.js';
|
|
3
|
+
/**
|
|
4
|
+
* A convention `conventions check` did NOT evaluate because it does not apply
|
|
5
|
+
* here (round 15, 15.1) — printed in text and in `--json` `notApplicable[]`,
|
|
6
|
+
* never a silent skip.
|
|
7
|
+
*/
|
|
8
|
+
export interface INotApplicableConvention {
|
|
9
|
+
readonly conventionId: string;
|
|
10
|
+
/** The convention's declared severity — THE closed set `IConvention.severity` uses (round 15 follow-up, F8). */
|
|
11
|
+
readonly severity: ConventionSeverity;
|
|
12
|
+
readonly sourceFile: string;
|
|
13
|
+
readonly packageName?: string;
|
|
14
|
+
/** The declared filters that excluded it (never empty). */
|
|
15
|
+
readonly reasons: readonly IConventionApplicabilityReason[];
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=i-not-applicable-convention.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-not-applicable-convention.d.ts","sourceRoot":"","sources":["../src/i-not-applicable-convention.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,wCAAwC,CAAC;AAE7F;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,gHAAgH;IAChH,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,EAAE,SAAS,8BAA8B,EAAE,CAAC;CAC7D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pack that contributed an asset — the provenance a `root: pack`
|
|
3
|
+
* reference resolves against (round 15 follow-up, F7).
|
|
4
|
+
*/
|
|
5
|
+
export interface IReferencePackOrigin {
|
|
6
|
+
/** The pack's published package name. */
|
|
7
|
+
readonly packageName: string;
|
|
8
|
+
/** Absolute path of the pack's package directory, as pack discovery resolved it. */
|
|
9
|
+
readonly packageRoot: string;
|
|
10
|
+
/** {@link packageRoot} relative to the project root (`node_modules/@x/y`) — what rows print. */
|
|
11
|
+
readonly displayRoot: string;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=i-reference-pack-origin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-reference-pack-origin.d.ts","sourceRoot":"","sources":["../src/i-reference-pack-origin.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,yCAAyC;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,oFAAoF;IACpF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,gGAAgG;IAChG,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|