@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
@@ -5,7 +5,8 @@
5
5
  */
6
6
  import { existsSync } from 'node:fs';
7
7
  import * as nodePath from 'node:path';
8
- import { validateConvention, } from '@shrkcrft/plugin-api';
8
+ import { ConventionSeverity, validateConvention, } from '@shrkcrft/plugin-api';
9
+ import { conventionFilePath, conventionScope } from "./convention-applicability.js";
9
10
  import { importModuleViaLoader, readContributionExport, RejectionCause, } from '@shrkcrft/core';
10
11
  export const CONVENTION_REGISTRY_SCHEMA = 'sharkcraft.convention-registry/v1';
11
12
  export var ConventionSource;
@@ -67,7 +68,7 @@ export async function loadConventions(inspection) {
67
68
  if (raw && typeof raw === 'object' && !Array.isArray(raw)) {
68
69
  for (const w of validateConvention(raw).warnings) {
69
70
  issues.push({
70
- severity: 'warning',
71
+ severity: ConventionSeverity.Warning,
71
72
  code: 'convention-shape',
72
73
  message: `${w.field}: ${w.message}`,
73
74
  conventionId: id,
@@ -78,7 +79,7 @@ export async function loadConventions(inspection) {
78
79
  const reasons = conventionRejectionReasons(raw);
79
80
  if (reasons.length > 0) {
80
81
  for (const r of reasons) {
81
- issues.push({ severity: 'error', code: 'invalid-convention', message: r, conventionId: id, source: sourceFile });
82
+ issues.push({ severity: ConventionSeverity.Error, code: 'invalid-convention', message: r, conventionId: id, source: sourceFile });
82
83
  }
83
84
  rejected.push({ ...at, ...(id !== undefined ? { entryId: id } : {}), reasons, cause: RejectionCause.Invalid });
84
85
  return;
@@ -87,7 +88,7 @@ export async function loadConventions(inspection) {
87
88
  const prev = seen.get(conv.id);
88
89
  if (prev !== undefined) {
89
90
  issues.push({
90
- severity: 'error',
91
+ severity: ConventionSeverity.Error,
91
92
  code: 'duplicate-id',
92
93
  message: `Convention "${conv.id}" already loaded; skipping ${sourceFile}.`,
93
94
  conventionId: conv.id,
@@ -124,7 +125,7 @@ export async function loadConventions(inspection) {
124
125
  catch (e) {
125
126
  unread.push(`${rel(file)} — failed to load`);
126
127
  issues.push({
127
- severity: 'warning',
128
+ severity: ConventionSeverity.Warning,
128
129
  code: 'load-failed',
129
130
  message: `Failed to load ${file}: ${e.message}`,
130
131
  source: file,
@@ -139,7 +140,7 @@ export async function loadConventions(inspection) {
139
140
  if (!existsSync(file)) {
140
141
  unread.push(`${rel(file)} — missing (declared by ${pack.packageName})`);
141
142
  issues.push({
142
- severity: 'warning',
143
+ severity: ConventionSeverity.Warning,
143
144
  code: 'missing-file',
144
145
  message: `Pack ${pack.packageName} declares ${packRel} but file is missing.`,
145
146
  source: file,
@@ -152,7 +153,7 @@ export async function loadConventions(inspection) {
152
153
  catch (e) {
153
154
  unread.push(`${rel(file)} — failed to load (${pack.packageName})`);
154
155
  issues.push({
155
- severity: 'warning',
156
+ severity: ConventionSeverity.Warning,
156
157
  code: 'load-failed',
157
158
  message: `Pack ${pack.packageName} (${packRel}): ${e.message}`,
158
159
  source: file,
@@ -174,26 +175,49 @@ export async function listConventionIssues(inspection) {
174
175
  const { issues } = await loadConventions(inspection);
175
176
  return issues;
176
177
  }
177
- function globMatch(file, pattern) {
178
- // very small POSIX-style matcher: ** = any path, * = any segment chars
179
- const re = new RegExp('^' +
180
- pattern
181
- .replace(/[.+^$()|]/g, (m) => '\\' + m)
182
- .replace(/\*\*/g, '__DOUBLE__')
183
- .replace(/\*/g, '[^/]*')
184
- .replace(/__DOUBLE__/g, '.*')
185
- .replace(/\?/g, '.') +
186
- '$');
187
- return re.test(file);
188
- }
189
- export async function checkConventionsAgainstFiles(inspection, files) {
178
+ /**
179
+ * Run the loaded conventions against `files`. Which files a convention covers
180
+ * is `conventionScope` — THE applicability authority (round 15), the same one
181
+ * the rule-graph bridge reads — so every `appliesTo` filter scopes, `**`
182
+ * spans zero or more segments, and a `!` glob subtracts (a private matcher
183
+ * here missed `src/a.ts` under `src/**\/*.ts` and ignored `!`). A convention
184
+ * that does not apply is never evaluated and is reported in `notApplicable`.
185
+ *
186
+ * Per covered file, each rule: `filePattern` and `expectMatch` must match the
187
+ * path (a miss is a hit), `forbidMatch` must not (a match is a hit).
188
+ *
189
+ * Every file is read in ONE spelling — `conventionFilePath` (project-relative,
190
+ * `/`-separated, no `./`), the one the scope test reads — so a rule pattern
191
+ * never tests a spelling the glob did not, and a hit names that path (round 15
192
+ * review: `./src/a.ts` was covered by `src/**` and then failed `^src/`).
193
+ */
194
+ export async function checkConventionsAgainstFiles(inspection, inputFiles) {
195
+ const files = inputFiles.map((f) => conventionFilePath(inspection, f));
190
196
  const entries = await listConventions(inspection);
191
197
  const hits = [];
198
+ const notApplicable = [];
199
+ const filesInScope = {};
200
+ const covered = new Map();
201
+ for (const entry of entries) {
202
+ const c = entry.convention;
203
+ const scope = conventionScope(c, inspection, files);
204
+ if (!scope.applicable) {
205
+ notApplicable.push({
206
+ conventionId: c.id,
207
+ severity: c.severity,
208
+ sourceFile: entry.sourceFile,
209
+ ...(entry.packageName ? { packageName: entry.packageName } : {}),
210
+ reasons: scope.reasons.filter((r) => !r.matched),
211
+ });
212
+ continue;
213
+ }
214
+ filesInScope[c.id] = scope.files.length;
215
+ covered.set(c.id, new Set(scope.files));
216
+ }
192
217
  for (const f of files) {
193
218
  for (const entry of entries) {
194
219
  const c = entry.convention;
195
- const globs = c.appliesTo?.fileGlobs ?? [];
196
- if (globs.length > 0 && !globs.some((g) => globMatch(f, g)))
220
+ if (!covered.get(c.id)?.has(f))
197
221
  continue;
198
222
  for (const r of c.rules) {
199
223
  const sev = r.severity ?? c.severity;
@@ -206,6 +230,15 @@ export async function checkConventionsAgainstFiles(inspection, files) {
206
230
  message: `File "${f}" does not match convention "${c.id}" rule "${r.id}": ${r.description}`,
207
231
  });
208
232
  }
233
+ if (r.expectMatch && !new RegExp(r.expectMatch).test(f)) {
234
+ hits.push({
235
+ conventionId: c.id,
236
+ ruleId: r.id,
237
+ file: f,
238
+ severity: sev,
239
+ message: `File "${f}" does not match the expected pattern /${r.expectMatch}/ of convention "${c.id}" rule "${r.id}": ${r.description}`,
240
+ });
241
+ }
209
242
  if (r.forbidMatch && new RegExp(r.forbidMatch).test(f)) {
210
243
  hits.push({
211
244
  conventionId: c.id,
@@ -222,6 +255,8 @@ export async function checkConventionsAgainstFiles(inspection, files) {
222
255
  schema: 'sharkcraft.convention-check/v1',
223
256
  filesScanned: files.length,
224
257
  hits,
225
- verdict: hits.some((h) => h.severity === 'error') ? 'has-violations' : 'clean',
258
+ verdict: hits.some((h) => h.severity === ConventionSeverity.Error) ? 'has-violations' : 'clean',
259
+ notApplicable,
260
+ filesInScope,
226
261
  };
227
262
  }
@@ -1 +1 @@
1
- {"version":3,"file":"custom-checks.d.ts","sourceRoot":"","sources":["../src/custom-checks.ts"],"names":[],"mappings":"AA8BA,OAAO,EAAE,KAAK,eAAe,EAA8B,MAAM,qBAAqB,CAAC;AAEvF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAEvE,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AACvE,eAAO,MAAM,6BAA6B,yCAAyC,CAAC;AAEpF,oBAAY,gBAAgB;IAC1B,WAAW,iBAAiB;IAC5B,MAAM,WAAW;IACjB,GAAG,QAAQ;CACZ;AAED,oBAAY,eAAe;IACzB,WAAW,iBAAiB;IAC5B,QAAQ,cAAc;IACtB,SAAS,eAAe;IACxB,aAAa,mBAAmB;IAChC,YAAY,kBAAkB;CAC/B;AAED,oBAAY,iBAAiB;IAC3B,QAAQ,cAAc;IACtB,YAAY,kBAAkB;IAC9B,aAAa,mBAAmB;CACjC;AAED,oBAAY,iBAAiB;IAC3B,IAAI,SAAS;IACb,IAAI,SAAS;IACb,QAAQ,cAAc;CACvB;AAED,oBAAY,iBAAiB;IAC3B,IAAI,SAAS;IACb,IAAI,SAAS;IACb,IAAI,SAAS;IACb,OAAO,YAAY;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,0BAA0B;IAC1B,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,0BAA0B,CAAC;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACzC,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,sBAAsB,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED,mGAAmG;AACnG,MAAM,WAAW,8BAA8B;IAC7C,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,kGAAkG;IAClG,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,0FAA0F;IAC1F,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,6BAA6B,CAAC;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAC9C,UAAU,EAAE,SAAS;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAClE,2FAA2F;IAC3F,OAAO,EAAE,SAAS;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1F,qFAAqF;IACrF,OAAO,EAAE,SAAS,8BAA8B,EAAE,CAAC;IACnD,iGAAiG;IACjG,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,uEAAuE;AACvE,MAAM,WAAW,yBAAyB;IACxC,0DAA0D;IAC1D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAKD,oEAAoE;AACpE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,eAAe,GAAG,SAAS,sBAAsB,EAAE,CAKhG;AAwCD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,OAAO,GAAE,yBAA8B,GACtC,oBAAoB,CAmFtB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,CAM/E;AAED,yGAAyG;AACzG,MAAM,WAAW,uBAAuB;IACtC,uHAAuH;IACvH,QAAQ,CAAC,KAAK,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3E,wGAAwG;IACxG,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,sDAAsD;IACtD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,qBAAqB,GAAG,uBAAuB,CA2BjG;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,oCAAoC,CAAC;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,cAAc,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,SAAS;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;QACvC,OAAO,EAAE,MAAM,CAAC;QAChB,sCAAsC;QACtC,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,EAAE,CAAC;CACL;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,oBAAoB,GAC7B,wBAAwB,CAkD1B;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,eAAe,CAAC,EAAE,MAAM,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAM1E;AAED,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,EACX,eAAe,CAAC,EAAE,MAAM,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAgE1E;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,qFAAqF;IACrF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,gCAAgC,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,cAAc,CAC5B,UAAU,EAAE,sBAAsB,EAClC,OAAO,EAAE,sBAAsB,GAC9B,qBAAqB,CAiCvB"}
1
+ {"version":3,"file":"custom-checks.d.ts","sourceRoot":"","sources":["../src/custom-checks.ts"],"names":[],"mappings":"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"}
@@ -28,7 +28,7 @@
28
28
  import { spawnSync } from 'node:child_process';
29
29
  import { existsSync, readFileSync } from 'node:fs';
30
30
  import * as nodePath from 'node:path';
31
- import { unsupportedFrontmatterKeys } from '@shrkcrft/knowledge';
31
+ import { KnowledgeSourceFormat, knowledgeSourceFormat, unsupportedFrontmatterKeys, } from '@shrkcrft/knowledge';
32
32
  import { isRuleEntry } from '@shrkcrft/rules';
33
33
  export const CUSTOM_CHECK_REPORT_SCHEMA = 'sharkcraft.custom-check/v1';
34
34
  export const CUSTOM_CHECKS_REGISTRY_SCHEMA = 'sharkcraft.custom-checks-registry/v1';
@@ -138,8 +138,10 @@ export function buildCustomChecksRegistry(entries, options = {}) {
138
138
  continue;
139
139
  }
140
140
  scannedRules += 1;
141
- if (e.source?.loader === 'markdown') {
142
- if (markdownDroppedChecks(e.source.origin)) {
141
+ // THE source-format authority (round 15) — the one the stale-check remedy
142
+ // and the validator read, so "is this a Markdown entry?" has one answer.
143
+ if (knowledgeSourceFormat(e) === KnowledgeSourceFormat.Markdown) {
144
+ if (markdownDroppedChecks(e.source?.origin)) {
143
145
  ignored.push({
144
146
  entryId: e.id,
145
147
  entryType: String(e.type),
@@ -241,7 +243,7 @@ export function customCheckScanSurface(inspection) {
241
243
  add(nodePath.resolve(pack.packageRoot, rel), `pack ${pack.packageName} ${key}`);
242
244
  }
243
245
  }
244
- const markdownRules = inspection.knowledgeEntries.filter((e) => isRuleEntry(e) && e.source?.loader === 'markdown').length;
246
+ const markdownRules = inspection.knowledgeEntries.filter((e) => isRuleEntry(e) && knowledgeSourceFormat(e) === KnowledgeSourceFormat.Markdown).length;
245
247
  return { files, markdownFiles, markdownRules };
246
248
  }
247
249
  export function doctorCustomChecks(registry) {
@@ -55,6 +55,10 @@ export declare function loadTsDecisions(inspection: ISharkcraftInspection): Prom
55
55
  * {@link loadTsDecisions} with what did not take effect (round 12, 12.1): a
56
56
  * decision file that failed to import (it used to be swallowed to `[]`), and
57
57
  * every declared decision the loader refused — invalid, or a duplicate id.
58
+ * `rejected` also carries every Markdown record (`sharkcraft/decisions/*.md`,
59
+ * `docs/adr/*.md`) whose frontmatter THE parser cannot read as declared (round
60
+ * 15 follow-up, F6) — the same scan {@link listDecisions} reads, so a record is
61
+ * either listed or reported here, never neither.
58
62
  */
59
63
  export declare function loadTsDecisionsWithIssues(inspection: ISharkcraftInspection): Promise<{
60
64
  readonly decisions: readonly IDecisionRecord[];
@@ -1 +1 @@
1
- {"version":3,"file":"decision-records.d.ts","sourceRoot":"","sources":["../src/decision-records.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAyC,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC5F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAE7E,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAE/D,oBAAY,cAAc;IACxB,QAAQ,aAAa;IACrB,QAAQ,aAAa;IACrB,QAAQ,aAAa;IACrB,UAAU,eAAe;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,sBAAsB,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,+FAA+F;IAC/F,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA8CD,wBAAgB,aAAa,CAAC,UAAU,EAAE,qBAAqB,GAAG,SAAS,eAAe,EAAE,CA2D3F;AA0BD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAIxE;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,qBAAqB,GAChC,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,CAErC;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,UAAU,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAC1F,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,SAAS,sBAAsB,EAAE,CAAC;IACnD,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;CAC9C,CAAC,CAuED;AAaD,wBAAgB,WAAW,CAAC,UAAU,EAAE,qBAAqB,EAAE,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAEtG;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CA0CvE;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE/E"}
1
+ {"version":3,"file":"decision-records.d.ts","sourceRoot":"","sources":["../src/decision-records.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EASL,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAE7E,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAE/D,oBAAY,cAAc;IACxB,QAAQ,aAAa;IACrB,QAAQ,aAAa;IACrB,QAAQ,aAAa;IACrB,UAAU,eAAe;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,sBAAsB,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,+FAA+F;IAC/F,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAyKD,wBAAgB,aAAa,CAAC,UAAU,EAAE,qBAAqB,GAAG,SAAS,eAAe,EAAE,CAmB3F;AA0BD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAIxE;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,qBAAqB,GAChC,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,CAErC;AAED;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAAC,UAAU,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAC1F,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,SAAS,sBAAsB,EAAE,CAAC;IACnD,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;CAC9C,CAAC,CAuED;AAaD,wBAAgB,WAAW,CAAC,UAAU,EAAE,qBAAqB,EAAE,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAEtG;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CA8CvE;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE/E"}
@@ -6,11 +6,20 @@
6
6
  * these — `decisions new` produces a dry-run preview unless
7
7
  * `--write-draft` is passed.
8
8
  *
9
+ * The frontmatter is read by THE parser (`splitFrontmatter` +
10
+ * `parseFrontmatter`, @shrkcrft/core — round 15 follow-up, F6) in its `Text`
11
+ * scalar mode: a decision's `id` / `title` / `status` / `date` are strings by
12
+ * contract, read verbatim as the old line splitter read them (`id: 0001`
13
+ * stays `0001`, `title: Fix #12` keeps its `#12`). A record whose frontmatter
14
+ * cannot be read as declared is REJECTED through the round-12 channel
15
+ * ({@link loadTsDecisionsWithIssues} `rejected`) — never listed from a partial
16
+ * reading, never dropped silently.
17
+ *
9
18
  * Read-only operations: list, get, link (preview).
10
19
  */
11
20
  import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
12
21
  import * as nodePath from 'node:path';
13
- import { importModuleViaLoader, RejectionCause } from '@shrkcrft/core';
22
+ import { formatFrontmatterScalar, FrontmatterScalarMode, importModuleViaLoader, parseFrontmatter, RejectionCause, splitFrontmatter, } from '@shrkcrft/core';
14
23
  export const DECISION_RECORD_SCHEMA = 'sharkcraft.decision/v1';
15
24
  export var DecisionStatus;
16
25
  (function (DecisionStatus) {
@@ -20,20 +29,146 @@ export var DecisionStatus;
20
29
  DecisionStatus["Superseded"] = "superseded";
21
30
  })(DecisionStatus || (DecisionStatus = {}));
22
31
  const DECISION_DIRS = ['sharkcraft/decisions', 'docs/adr'];
23
- function frontmatterAndBody(text) {
24
- const m = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/.exec(text);
25
- if (!m)
26
- return { fm: {}, body: text };
27
- const fm = {};
28
- for (const line of (m[1] ?? '').split('\n')) {
29
- const idx = line.indexOf(':');
30
- if (idx <= 0)
32
+ /**
33
+ * A decision's frontmatter values are strings by contract — read verbatim
34
+ * (`Text` scalars), exactly as {@link previewDecisionDraft} writes them. Only
35
+ * the four keys a record reads are parsed (`keys`): any other key — MADR's
36
+ * `decision makers:`, a `summary:` wrapped onto an indented line, a map nested
37
+ * two levels — is skipped unparsed. The old splitter never read those lines
38
+ * either, and YAML the parser does not speak under a key nobody reads must not
39
+ * cost the record (the Markdown knowledge loader skips a key it drops the same
40
+ * way). No key is read as a list (`listKeys: []`, round 15 closing A1): an
41
+ * inline `title: [WIP]` is the title `[WIP]`, verbatim, as the old splitter
42
+ * read it — it used to REJECT the record as "a list".
43
+ */
44
+ const DECISION_FRONTMATTER = Object.freeze({
45
+ scalars: FrontmatterScalarMode.Text,
46
+ keys: Object.freeze(['id', 'title', 'status', 'date']),
47
+ listKeys: Object.freeze([]),
48
+ });
49
+ function shapeOf(value) {
50
+ if (!Array.isArray(value))
51
+ return 'a map';
52
+ return value.some((v) => v !== null && typeof v === 'object') ? 'a list of maps' : 'a list';
53
+ }
54
+ /**
55
+ * Read one Markdown decision record through THE frontmatter parser. Frontmatter
56
+ * the parser refuses in its top-level structure (a stray line naming no key)
57
+ * or under a key the record reads (`title:` wrapped onto an indented line), or
58
+ * an `id` / `title` / `status` / `date` that is not a single value (a block
59
+ * list under `title:`; an inline `title: [WIP]` is text) REJECTS the record, every reason named: the
60
+ * old line splitter skipped such a line silently and let an indented ` id:`
61
+ * under any block overwrite the record's own id. A key the record does not
62
+ * read is never parsed ({@link DECISION_FRONTMATTER}).
63
+ */
64
+ function readMarkdownDecision(full, fileName) {
65
+ const split = splitFrontmatter(readFileSync(full, 'utf8'));
66
+ const problems = [];
67
+ // A decision record opening with `---` and never closing it is broken
68
+ // frontmatter, not a thematic break: its `id:` would silently become the
69
+ // file name (the old splitter did exactly that).
70
+ if (split.unterminated)
71
+ problems.push('frontmatter: an opening --- line has no closing --- line');
72
+ let fields = {};
73
+ if (split.frontmatter !== undefined) {
74
+ const parsed = parseFrontmatter(split.frontmatter, { ...DECISION_FRONTMATTER, lineOffset: split.lineOffset });
75
+ if (parsed.ok)
76
+ fields = parsed.value;
77
+ else
78
+ problems.push(`frontmatter: ${parsed.error.message}`);
79
+ }
80
+ const text = (key) => {
81
+ const v = fields[key];
82
+ if (v === undefined || v === null)
83
+ return undefined;
84
+ if (typeof v === 'string')
85
+ return v;
86
+ if (typeof v === 'number' || typeof v === 'boolean')
87
+ return String(v);
88
+ problems.push(`${key}: must be a single value (got ${shapeOf(v)}) — quote it if it is text`);
89
+ return undefined;
90
+ };
91
+ const declaredId = text('id')?.trim();
92
+ const title = text('title');
93
+ const status = text('status');
94
+ const date = text('date');
95
+ if (problems.length > 0) {
96
+ return {
97
+ rejected: {
98
+ file: full,
99
+ index: -1,
100
+ ...(declaredId ? { entryId: declaredId } : {}),
101
+ reasons: problems,
102
+ cause: RejectionCause.Invalid,
103
+ },
104
+ };
105
+ }
106
+ // A key with no value (`id:`, `title:`, `status:`) is absent and falls back to
107
+ // its default — the old splitter read `id:` as the id "" and `title:` as the
108
+ // title "". An id that is empty after trimming falls back too: "" can never
109
+ // be referenced.
110
+ const id = declaredId || nodePath.basename(fileName, nodePath.extname(fileName)).trim();
111
+ const body = split.body;
112
+ return {
113
+ record: {
114
+ schema: DECISION_RECORD_SCHEMA,
115
+ id,
116
+ title: title ?? id,
117
+ status: status ?? DecisionStatus.Proposed,
118
+ context: sectionFromBody(body, 'Context'),
119
+ decision: sectionFromBody(body, 'Decision'),
120
+ consequences: sectionFromBody(body, 'Consequences'),
121
+ relatedRules: listLinesUnder(body, 'Related rules'),
122
+ relatedPolicies: listLinesUnder(body, 'Related policies'),
123
+ relatedConstructs: listLinesUnder(body, 'Related constructs'),
124
+ relatedFiles: listLinesUnder(body, 'Related files'),
125
+ date: date ?? '',
126
+ sourceFile: full,
127
+ },
128
+ };
129
+ }
130
+ /**
131
+ * Every Markdown decision record under {@link DECISION_DIRS}, in a
132
+ * deterministic order: the records read, and every file refused. THE one pass
133
+ * both {@link listDecisions} (records) and {@link loadTsDecisionsWithIssues}
134
+ * (rejected) read, so what is listed and what is reported cannot disagree.
135
+ */
136
+ function scanMarkdownDecisions(projectRoot) {
137
+ const records = [];
138
+ const rejected = [];
139
+ for (const rel of DECISION_DIRS) {
140
+ const dir = nodePath.join(projectRoot, rel);
141
+ if (!existsSync(dir))
31
142
  continue;
32
- const k = line.slice(0, idx).trim();
33
- const v = line.slice(idx + 1).trim().replace(/^"(.*)"$/, '$1');
34
- fm[k] = v;
143
+ let entries = [];
144
+ try {
145
+ // Sort so the decision-record list (and the doctor findings derived from
146
+ // it) is deterministic, not filesystem-order-dependent.
147
+ entries = readdirSync(dir).sort();
148
+ }
149
+ catch {
150
+ continue;
151
+ }
152
+ for (const f of entries) {
153
+ if (!/\.(md|markdown)$/i.test(f))
154
+ continue;
155
+ const full = nodePath.join(dir, f);
156
+ try {
157
+ const st = statSync(full);
158
+ if (!st.isFile())
159
+ continue;
160
+ }
161
+ catch {
162
+ continue;
163
+ }
164
+ const read = readMarkdownDecision(full, f);
165
+ if ('record' in read)
166
+ records.push(read.record);
167
+ else
168
+ rejected.push(read.rejected);
169
+ }
35
170
  }
36
- return { fm, body: m[2] ?? '' };
171
+ return { records, rejected };
37
172
  }
38
173
  function sectionFromBody(body, header) {
39
174
  const lines = body.split('\n');
@@ -73,54 +208,10 @@ export function listDecisions(inspection) {
73
208
  seenIds.add(rec.id);
74
209
  out.push(rec);
75
210
  };
76
- for (const rel of DECISION_DIRS) {
77
- const dir = nodePath.join(inspection.projectRoot, rel);
78
- if (!existsSync(dir))
79
- continue;
80
- let entries = [];
81
- try {
82
- // Sort so the decision-record list (and the doctor findings derived from
83
- // it) is deterministic, not filesystem-order-dependent.
84
- entries = readdirSync(dir).sort();
85
- }
86
- catch {
87
- continue;
88
- }
89
- for (const f of entries) {
90
- if (!/\.(md|markdown)$/i.test(f))
91
- continue;
92
- const full = nodePath.join(dir, f);
93
- try {
94
- const st = statSync(full);
95
- if (!st.isFile())
96
- continue;
97
- }
98
- catch {
99
- continue;
100
- }
101
- const text = readFileSync(full, 'utf8');
102
- const { fm, body } = frontmatterAndBody(text);
103
- const id = (fm['id'] ?? nodePath.basename(f, nodePath.extname(f))).trim();
104
- const title = fm['title'] ?? id;
105
- const status = fm['status'] ?? DecisionStatus.Proposed;
106
- const date = fm['date'] ?? '';
107
- addMd({
108
- schema: DECISION_RECORD_SCHEMA,
109
- id,
110
- title,
111
- status,
112
- context: sectionFromBody(body, 'Context'),
113
- decision: sectionFromBody(body, 'Decision'),
114
- consequences: sectionFromBody(body, 'Consequences'),
115
- relatedRules: listLinesUnder(body, 'Related rules'),
116
- relatedPolicies: listLinesUnder(body, 'Related policies'),
117
- relatedConstructs: listLinesUnder(body, 'Related constructs'),
118
- relatedFiles: listLinesUnder(body, 'Related files'),
119
- date,
120
- sourceFile: full,
121
- });
122
- }
123
- }
211
+ // A Markdown record whose frontmatter cannot be read as declared is not
212
+ // listed — `loadTsDecisionsWithIssues` reports it rejected (same scan).
213
+ for (const rec of scanMarkdownDecisions(inspection.projectRoot).records)
214
+ addMd(rec);
124
215
  // Also include sync-cached TS decisions if present (loaded by
125
216
  // listDecisionsTsCached on prior async warm-up). Best-effort sync read.
126
217
  for (const r of getTsDecisionsCached(inspection.projectRoot)) {
@@ -158,11 +249,15 @@ export async function loadTsDecisions(inspection) {
158
249
  * {@link loadTsDecisions} with what did not take effect (round 12, 12.1): a
159
250
  * decision file that failed to import (it used to be swallowed to `[]`), and
160
251
  * every declared decision the loader refused — invalid, or a duplicate id.
252
+ * `rejected` also carries every Markdown record (`sharkcraft/decisions/*.md`,
253
+ * `docs/adr/*.md`) whose frontmatter THE parser cannot read as declared (round
254
+ * 15 follow-up, F6) — the same scan {@link listDecisions} reads, so a record is
255
+ * either listed or reported here, never neither.
161
256
  */
162
257
  export async function loadTsDecisionsWithIssues(inspection) {
163
258
  const out = [];
164
259
  const issues = [];
165
- const rejected = [];
260
+ const rejected = [...scanMarkdownDecisions(inspection.projectRoot).rejected];
166
261
  const seen = new Map();
167
262
  const addInput = (raw, source, index) => {
168
263
  const reasons = decisionRejectionReasons(raw);
@@ -248,12 +343,16 @@ export function getDecision(inspection, id) {
248
343
  }
249
344
  export function previewDecisionDraft(input) {
250
345
  const id = input.id.trim();
346
+ // Each value is written so THE parser reads it back as written (round 15
347
+ // follow-up, F6): a raw `title: [WIP]` reads as a list, `title: "Quoted"` as
348
+ // `Quoted`. A value that already reads back stays bare.
349
+ const value = (v) => formatFrontmatterScalar(v, DECISION_FRONTMATTER);
251
350
  const lines = [];
252
351
  lines.push('---');
253
- lines.push(`id: ${id}`);
254
- lines.push(`title: ${input.title}`);
255
- lines.push(`status: ${input.status ?? DecisionStatus.Proposed}`);
256
- lines.push(`date: ${input.date ?? new Date().toISOString().slice(0, 10)}`);
352
+ lines.push(`id: ${value(id)}`);
353
+ lines.push(`title: ${value(input.title)}`);
354
+ lines.push(`status: ${value(input.status ?? DecisionStatus.Proposed)}`);
355
+ lines.push(`date: ${value(input.date ?? new Date().toISOString().slice(0, 10))}`);
257
356
  lines.push('---');
258
357
  lines.push('');
259
358
  lines.push(`# ${input.title}`);
@@ -1,7 +1,7 @@
1
1
  import type { IVerdictCoverage } from '@shrkcrft/core';
2
2
  import { type IKnowledgeAnchorCheck, type IKnowledgeReferenceCheck } from './knowledge-stale.js';
3
3
  /** Why a malformed reference is unexamined — the words every surface prints. */
4
- export declare const MALFORMED_REFERENCE_REASON = "malformed (a kind outside the vocabulary, or a required field missing), so never checked \u2014 `shrk doctor` names each";
4
+ export declare const MALFORMED_REFERENCE_REASON = "malformed (a kind outside the vocabulary, a required field missing, a field of the wrong type, or a root that cannot resolve where it is declared), so never checked \u2014 each INVALID row names its problem, `shrk doctor` each knowledge entry\u2019s";
5
5
  /**
6
6
  * THE fold of declared references into one coverage record.
7
7
  *
@@ -1 +1 @@
1
- {"version":3,"file":"declared-reference-coverage.d.ts","sourceRoot":"","sources":["../src/declared-reference-coverage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC9B,MAAM,sBAAsB,CAAC;AAK9B,gFAAgF;AAChF,eAAO,MAAM,0BAA0B,6HACgF,CAAC;AAExH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,QAAQ,CAAC,UAAU,EAAE,SAAS,wBAAwB,EAAE,CAAC;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACrD,GAAG,gBAAgB,CA0BnB"}
1
+ {"version":3,"file":"declared-reference-coverage.d.ts","sourceRoot":"","sources":["../src/declared-reference-coverage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC9B,MAAM,sBAAsB,CAAC;AAK9B,gFAAgF;AAChF,eAAO,MAAM,0BAA0B,8PAK4M,CAAC;AAEpP;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,QAAQ,CAAC,UAAU,EAAE,SAAS,wBAAwB,EAAE,CAAC;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACrD,GAAG,gBAAgB,CA0BnB"}
@@ -3,7 +3,12 @@ import { isCheckableOutcome, ReferenceCheckOutcome, } from "./knowledge-stale.js
3
3
  /** Unexamined labels carried on the coverage record (the full list is in the JSON). */
4
4
  const LABEL_CAP = 20;
5
5
  /** Why a malformed reference is unexamined — the words every surface prints. */
6
- export const MALFORMED_REFERENCE_REASON = 'malformed (a kind outside the vocabulary, or a required field missing), so never checked — `shrk doctor` names each';
6
+ export const MALFORMED_REFERENCE_REASON =
7
+ // A malformed reference is also one whose `root` cannot resolve where it is
8
+ // declared (`root: pack` on a local asset, an unknown root — round 15
9
+ // follow-up) or a field of the wrong type (`required: "yes"`): the INVALID
10
+ // row names the exact problem.
11
+ 'malformed (a kind outside the vocabulary, a required field missing, a field of the wrong type, or a root that cannot resolve where it is declared), so never checked — each INVALID row names its problem, `shrk doctor` each knowledge entry’s';
7
12
  /**
8
13
  * THE fold of declared references into one coverage record.
9
14
  *
@@ -1 +1 @@
1
- {"version":3,"file":"feedback-ingestion.d.ts","sourceRoot":"","sources":["../src/feedback-ingestion.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"feedback-ingestion.d.ts","sourceRoot":"","sources":["../src/feedback-ingestion.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,8 @@
15
15
  import { existsSync, readFileSync } from 'node:fs';
16
16
  import * as nodePath from 'node:path';
17
17
  import { importModuleViaLoader, RejectionCause } from '@shrkcrft/core';
18
+ import { knowledgeRenameCommand } from "./knowledge-rename-command.js";
19
+ import { KnowledgeRenameVerb } from "./knowledge-rename-verb.js";
18
20
  export const FEEDBACK_INGESTION_SCHEMA = 'sharkcraft.feedback-ingestion/v1';
19
21
  export var FeedbackBucket;
20
22
  (function (FeedbackBucket) {
@@ -129,7 +131,11 @@ const KEYWORD_RULES = [
129
131
  pattern: /\b(rename|move|moved|renamed)\b/i,
130
132
  tags: ['rename'],
131
133
  targetArea: 'knowledge-rename',
132
- suggestedCommands: ['shrk knowledge rename-symbol <old> <new> --dry-run'],
134
+ // THE rename-command helper: the previews are read-only and take no `--dry-run`.
135
+ suggestedCommands: [
136
+ knowledgeRenameCommand(KnowledgeRenameVerb.RenameFile),
137
+ knowledgeRenameCommand(KnowledgeRenameVerb.RenameSymbol),
138
+ ],
133
139
  },
134
140
  {
135
141
  pattern: /\b(trace|impact)\b/i,
@@ -0,0 +1,9 @@
1
+ import type { IFileLanguage } from './i-file-language.js';
2
+ export declare const FILE_LANGUAGES: readonly IFileLanguage[];
3
+ /** The language of `path` (absolute or project-relative): a basename override, else its extension; `null` when unknown. */
4
+ export declare function fileLanguageOf(path: string): IFileLanguage | null;
5
+ /** The language whose table row lists `extension` (`.ts` or `ts`), or `null`. */
6
+ export declare function fileLanguageForExtension(extension: string): IFileLanguage | null;
7
+ /** Every language id of the table, in table order — THE vocabulary `appliesTo.languages` may name. */
8
+ export declare function fileLanguageIds(): readonly string[];
9
+ //# sourceMappingURL=file-languages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-languages.d.ts","sourceRoot":"","sources":["../src/file-languages.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,eAAO,MAAM,cAAc,EAAE,SAAS,aAAa,EAsCvB,CAAC;AAiB7B,2HAA2H;AAC3H,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CASjE;AAED,iFAAiF;AACjF,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAGhF;AAED,sGAAsG;AACtG,wBAAgB,eAAe,IAAI,SAAS,MAAM,EAAE,CAEnD"}