@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.
Files changed (134) hide show
  1. package/dist/agent-task-prep.d.ts.map +1 -1
  2. package/dist/agent-task-prep.js +9 -1
  3. package/dist/codemod-assist.d.ts.map +1 -1
  4. package/dist/codemod-assist.js +3 -1
  5. package/dist/comment-syntax.d.ts +15 -0
  6. package/dist/comment-syntax.d.ts.map +1 -0
  7. package/dist/comment-syntax.js +15 -0
  8. package/dist/contribution-load-failures.d.ts +18 -2
  9. package/dist/contribution-load-failures.d.ts.map +1 -1
  10. package/dist/contribution-load-failures.js +20 -3
  11. package/dist/contributions-report.js +2 -2
  12. package/dist/convention-applicability.d.ts +46 -0
  13. package/dist/convention-applicability.d.ts.map +1 -0
  14. package/dist/convention-applicability.js +247 -0
  15. package/dist/convention-filter-level.d.ts +13 -0
  16. package/dist/convention-filter-level.d.ts.map +1 -0
  17. package/dist/convention-filter-level.js +13 -0
  18. package/dist/convention-registry.d.ts +29 -4
  19. package/dist/convention-registry.d.ts.map +1 -1
  20. package/dist/convention-registry.js +58 -23
  21. package/dist/custom-checks.d.ts.map +1 -1
  22. package/dist/custom-checks.js +6 -4
  23. package/dist/decision-records.d.ts +4 -0
  24. package/dist/decision-records.d.ts.map +1 -1
  25. package/dist/decision-records.js +165 -66
  26. package/dist/declared-reference-coverage.d.ts +1 -1
  27. package/dist/declared-reference-coverage.d.ts.map +1 -1
  28. package/dist/declared-reference-coverage.js +6 -1
  29. package/dist/feedback-ingestion.d.ts.map +1 -1
  30. package/dist/feedback-ingestion.js +7 -1
  31. package/dist/file-languages.d.ts +9 -0
  32. package/dist/file-languages.d.ts.map +1 -0
  33. package/dist/file-languages.js +91 -0
  34. package/dist/fix-preview.d.ts.map +1 -1
  35. package/dist/fix-preview.js +78 -17
  36. package/dist/fuzzy-impact.d.ts.map +1 -1
  37. package/dist/fuzzy-impact.js +2 -1
  38. package/dist/git-helpers.d.ts +29 -4
  39. package/dist/git-helpers.d.ts.map +1 -1
  40. package/dist/git-helpers.js +69 -10
  41. package/dist/i-contribution-file-validation.d.ts +8 -0
  42. package/dist/i-contribution-file-validation.d.ts.map +1 -1
  43. package/dist/i-convention-applicability-reason.d.ts +29 -0
  44. package/dist/i-convention-applicability-reason.d.ts.map +1 -0
  45. package/dist/i-convention-applicability-reason.js +1 -0
  46. package/dist/i-convention-applicability.d.ts +9 -0
  47. package/dist/i-convention-applicability.d.ts.map +1 -0
  48. package/dist/i-convention-applicability.js +1 -0
  49. package/dist/i-convention-scope.d.ts +19 -0
  50. package/dist/i-convention-scope.d.ts.map +1 -0
  51. package/dist/i-convention-scope.js +1 -0
  52. package/dist/i-file-language.d.ts +11 -0
  53. package/dist/i-file-language.d.ts.map +1 -0
  54. package/dist/i-file-language.js +1 -0
  55. package/dist/i-not-applicable-convention.d.ts +17 -0
  56. package/dist/i-not-applicable-convention.d.ts.map +1 -0
  57. package/dist/i-not-applicable-convention.js +1 -0
  58. package/dist/i-reference-pack-origin.d.ts +13 -0
  59. package/dist/i-reference-pack-origin.d.ts.map +1 -0
  60. package/dist/i-reference-pack-origin.js +1 -0
  61. package/dist/i-stale-path-hint-input.d.ts +18 -0
  62. package/dist/i-stale-path-hint-input.d.ts.map +1 -0
  63. package/dist/i-stale-path-hint-input.js +1 -0
  64. package/dist/i-unverifiable-remedy-group.d.ts +10 -0
  65. package/dist/i-unverifiable-remedy-group.d.ts.map +1 -0
  66. package/dist/i-unverifiable-remedy-group.js +1 -0
  67. package/dist/index.d.ts +17 -0
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +25 -0
  70. package/dist/knowledge-authoring.d.ts +1 -1
  71. package/dist/knowledge-authoring.d.ts.map +1 -1
  72. package/dist/knowledge-authoring.js +7 -6
  73. package/dist/knowledge-contribution-slots.d.ts +18 -0
  74. package/dist/knowledge-contribution-slots.d.ts.map +1 -0
  75. package/dist/knowledge-contribution-slots.js +25 -0
  76. package/dist/knowledge-entry-rejections.d.ts +17 -0
  77. package/dist/knowledge-entry-rejections.d.ts.map +1 -0
  78. package/dist/knowledge-entry-rejections.js +79 -0
  79. package/dist/knowledge-entry-verdict-record.d.ts +12 -0
  80. package/dist/knowledge-entry-verdict-record.d.ts.map +1 -1
  81. package/dist/knowledge-min-referenced-valve.d.ts +12 -0
  82. package/dist/knowledge-min-referenced-valve.d.ts.map +1 -0
  83. package/dist/knowledge-min-referenced-valve.js +12 -0
  84. package/dist/knowledge-rejected-entry.d.ts +28 -0
  85. package/dist/knowledge-rejected-entry.d.ts.map +1 -0
  86. package/dist/knowledge-rejected-entry.js +1 -0
  87. package/dist/knowledge-rename-command.d.ts +20 -0
  88. package/dist/knowledge-rename-command.d.ts.map +1 -0
  89. package/dist/knowledge-rename-command.js +34 -0
  90. package/dist/knowledge-rename-verb.d.ts +11 -0
  91. package/dist/knowledge-rename-verb.d.ts.map +1 -0
  92. package/dist/knowledge-rename-verb.js +11 -0
  93. package/dist/knowledge-rename.d.ts +1 -1
  94. package/dist/knowledge-rename.d.ts.map +1 -1
  95. package/dist/knowledge-rename.js +6 -5
  96. package/dist/knowledge-stale-gate.d.ts +2 -0
  97. package/dist/knowledge-stale-gate.d.ts.map +1 -1
  98. package/dist/knowledge-stale-gate.js +75 -3
  99. package/dist/knowledge-stale-quality-gate.d.ts.map +1 -1
  100. package/dist/knowledge-stale-quality-gate.js +34 -4
  101. package/dist/knowledge-stale.d.ts +10 -0
  102. package/dist/knowledge-stale.d.ts.map +1 -1
  103. package/dist/knowledge-stale.js +227 -33
  104. package/dist/knowledge-unverifiable-remedy.d.ts +56 -0
  105. package/dist/knowledge-unverifiable-remedy.d.ts.map +1 -0
  106. package/dist/knowledge-unverifiable-remedy.js +0 -0
  107. package/dist/pack-contributions-inventory.d.ts.map +1 -1
  108. package/dist/pack-contributions-inventory.js +4 -2
  109. package/dist/propose-knowledge.js +3 -2
  110. package/dist/reference-pack-origin.d.ts +18 -0
  111. package/dist/reference-pack-origin.d.ts.map +1 -0
  112. package/dist/reference-pack-origin.js +38 -0
  113. package/dist/repository-stats.d.ts.map +1 -1
  114. package/dist/repository-stats.js +3 -77
  115. package/dist/resolve-project-config.d.ts.map +1 -1
  116. package/dist/resolve-project-config.js +10 -1
  117. package/dist/self-config-doctor-v2.d.ts +1 -1
  118. package/dist/self-config-doctor-v2.d.ts.map +1 -1
  119. package/dist/self-config-doctor-v2.js +76 -12
  120. package/dist/self-config-doctor.d.ts.map +1 -1
  121. package/dist/self-config-doctor.js +2 -1
  122. package/dist/sharkcraft-inspector.d.ts.map +1 -1
  123. package/dist/sharkcraft-inspector.js +52 -12
  124. package/dist/stale-path-hint.d.ts +3 -0
  125. package/dist/stale-path-hint.d.ts.map +1 -0
  126. package/dist/stale-path-hint.js +47 -0
  127. package/dist/template-authoring.d.ts +1 -1
  128. package/dist/template-authoring.d.ts.map +1 -1
  129. package/dist/template-authoring.js +2 -1
  130. package/dist/validate-contribution-file.d.ts.map +1 -1
  131. package/dist/validate-contribution-file.js +15 -10
  132. package/dist/why-file.d.ts.map +1 -1
  133. package/dist/why-file.js +5 -4
  134. 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":"AAyBA,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;AAoCD,wBAAgB,eAAe,CAC7B,UAAU,EAAE,qBAAqB,EACjC,OAAO,GAAE,kBAAuB,GAC/B,iBAAiB,CAoFnB;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"}
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"}
@@ -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
- const target = c.reference.id ?? c.reference.path ?? c.reference.symbol ?? '<unknown>';
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
- `shrk fix preview --template-drift ${e.templateId} --write-preview`,
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":"AA2BA,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"}
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"}
@@ -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.references ?? []) {
133
+ for (const ref of knowledgeReferences(k)) {
133
134
  if (ref.kind === 'file' && ref.path)
134
135
  out.push(ref.path);
135
136
  }
@@ -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:src/x.ts`), or `null`
34
- * when the path did not exist at that ref (a newly-added file) or git failed.
35
- * `relPath` is repo-root-relative. Used to diff a file's PAST state against the
36
- * working tree without a checkout — e.g. to see what a now-edited file used to
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":"AAIA,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;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,MAAM,EAAE,CAwBpF;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAI3D;AAED;;;;;;GAMG;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"}
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"}
@@ -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 args = ['diff', '--name-only'];
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(cwd, args);
50
- const set = new Set(parseLines(a.stdout));
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(cwd, ['status', '--porcelain', '-uall']);
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
- set.add(path);
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:src/x.ts`), or `null`
85
- * when the path did not exist at that ref (a newly-added file) or git failed.
86
- * `relPath` is repo-root-relative. Used to diff a file's PAST state against the
87
- * working tree without a checkout — e.g. to see what a now-edited file used to
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}:${relPath}`]);
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 {};