@grove-dev/core 0.2.16 → 0.2.19

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 (68) hide show
  1. package/README.md +2 -2
  2. package/dist/build-data.d.ts.map +1 -1
  3. package/dist/build-data.js +19 -12
  4. package/dist/build-data.js.map +1 -1
  5. package/dist/build-data.test.d.ts +2 -0
  6. package/dist/build-data.test.d.ts.map +1 -0
  7. package/dist/build-data.test.js +171 -0
  8. package/dist/build-data.test.js.map +1 -0
  9. package/dist/decisions.test.d.ts +2 -0
  10. package/dist/decisions.test.d.ts.map +1 -0
  11. package/dist/decisions.test.js +205 -0
  12. package/dist/decisions.test.js.map +1 -0
  13. package/dist/enrich.test.d.ts +2 -0
  14. package/dist/enrich.test.d.ts.map +1 -0
  15. package/dist/enrich.test.js +105 -0
  16. package/dist/enrich.test.js.map +1 -0
  17. package/dist/github-client.d.ts.map +1 -1
  18. package/dist/github-client.js +4 -1
  19. package/dist/github-client.js.map +1 -1
  20. package/dist/github-client.test.d.ts +2 -0
  21. package/dist/github-client.test.d.ts.map +1 -0
  22. package/dist/github-client.test.js +176 -0
  23. package/dist/github-client.test.js.map +1 -0
  24. package/dist/github.d.ts.map +1 -1
  25. package/dist/github.js +6 -2
  26. package/dist/github.js.map +1 -1
  27. package/dist/github.test.d.ts +2 -0
  28. package/dist/github.test.d.ts.map +1 -0
  29. package/dist/github.test.js +73 -0
  30. package/dist/github.test.js.map +1 -0
  31. package/dist/health.test.d.ts +2 -0
  32. package/dist/health.test.d.ts.map +1 -0
  33. package/dist/health.test.js +183 -0
  34. package/dist/health.test.js.map +1 -0
  35. package/dist/importer.test.d.ts +2 -0
  36. package/dist/importer.test.d.ts.map +1 -0
  37. package/dist/importer.test.js +173 -0
  38. package/dist/importer.test.js.map +1 -0
  39. package/dist/index.d.ts +36 -16
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +44 -16
  42. package/dist/index.js.map +1 -1
  43. package/dist/llms.d.ts.map +1 -1
  44. package/dist/llms.js +6 -4
  45. package/dist/llms.js.map +1 -1
  46. package/dist/markdown.d.ts.map +1 -1
  47. package/dist/markdown.js +16 -10
  48. package/dist/markdown.js.map +1 -1
  49. package/dist/parseReadme.d.ts.map +1 -1
  50. package/dist/parseReadme.js +5 -1
  51. package/dist/parseReadme.js.map +1 -1
  52. package/dist/schema.d.ts +1 -14
  53. package/dist/schema.d.ts.map +1 -1
  54. package/dist/schema.js +14 -60
  55. package/dist/schema.js.map +1 -1
  56. package/dist/slug.d.ts +10 -0
  57. package/dist/slug.d.ts.map +1 -1
  58. package/dist/slug.js +10 -0
  59. package/dist/slug.js.map +1 -1
  60. package/dist/slug.test.d.ts +2 -0
  61. package/dist/slug.test.d.ts.map +1 -0
  62. package/dist/slug.test.js +101 -0
  63. package/dist/slug.test.js.map +1 -0
  64. package/dist/validate.test.d.ts +2 -0
  65. package/dist/validate.test.d.ts.map +1 -0
  66. package/dist/validate.test.js +249 -0
  67. package/dist/validate.test.js.map +1 -0
  68. package/package.json +2 -2
package/README.md CHANGED
@@ -96,7 +96,6 @@ import {
96
96
  fetchGithubMetadata,
97
97
  enrichFromGithubHtml,
98
98
  classifyHealth,
99
- healthFromSignals,
100
99
  type GithubMetadata,
101
100
  type HealthEntry,
102
101
  type EnrichedFields,
@@ -144,7 +143,8 @@ The V0 published `@grove-dev/core` exposed several names that the V1 release rep
144
143
  | `buildReviewReport` | removed (the cleanup report is a side effect of `pickCleanupCandidates`) |
145
144
  | `parseAppYaml` | removed (V0 `apps` model is gone; use `readYamlFile` + Zod parse) |
146
145
  | `normalizeAppRecord` / `toIndexApp` | internal to `build-data.ts`; not part of the V1 public surface |
147
- | `validateProject` / `validateAppRecord` | removed (replaced by `generate` which surfaces validation errors) |
146
+ | `validateAppRecord` | removed (V0 `apps` model is gone) |
147
+ | `validateProject` | kept (V1 name — used by tests and CLI for the structured `ValidationIssue[]` output that `generate`'s throw path does not produce) |
148
148
 
149
149
  ## Development
150
150
 
@@ -1 +1 @@
1
- {"version":3,"file":"build-data.d.ts","sourceRoot":"","sources":["../src/build-data.ts"],"names":[],"mappings":"AAGA,OAAO,EAML,KAAK,WAAW,EAEjB,MAAM,aAAa,CAAC;AA2DrB;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACzC;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACzC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAsB,QAAQ,CAC5B,GAAG,SAAgB,EACnB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,CAAC,CAkNzB"}
1
+ {"version":3,"file":"build-data.d.ts","sourceRoot":"","sources":["../src/build-data.ts"],"names":[],"mappings":"AAGA,OAAO,EAML,KAAK,WAAW,EAEjB,MAAM,aAAa,CAAC;AAgErB;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACzC;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACzC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAsB,QAAQ,CAC5B,GAAG,SAAgB,EACnB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,CAAC,CAmNzB"}
@@ -2,6 +2,7 @@ import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
2
2
  import { basename, join, resolve } from "node:path";
3
3
  import { parse as parseYaml } from "yaml";
4
4
  import { blueprintKind, recordsFileSchema, toIndexRecord, unwrapDecisions, decisionsFileSchema, } from "./schema.js";
5
+ import { classifyHealth } from "./health.js";
5
6
  import { loadConfig } from "./config.js";
6
7
  /**
7
8
  * Apply a minimal decisions.yml override to a normalized record. The
@@ -15,6 +16,15 @@ import { loadConfig } from "./config.js";
15
16
  *
16
17
  * The full override pipeline (with reasons surfaced in the index
17
18
  * payload) is a V2 feature; V1 keeps the merge intentional and small.
19
+ *
20
+ * When a project record has no existing health block but a decisions
21
+ * override exists, we call `classifyHealth` (the V1 single source of
22
+ * truth) with no GitHub metadata to fabricate an "unknown" health
23
+ * block whose `visibility` we then overwrite with the decision. This
24
+ * fabrication is required by the index payload: `toIndexRecord` reads
25
+ * `record.health?.visibility` to populate the index, so the override
26
+ * cannot flow through without a health block. Without the fabrication
27
+ * the override would silently disappear from the rendered index.
18
28
  */
19
29
  function applyDecision(record, visibilityById) {
20
30
  const override = visibilityById.get(record.slug);
@@ -22,17 +32,12 @@ function applyDecision(record, visibilityById) {
22
32
  return record;
23
33
  if (record.kind === "project") {
24
34
  const existing = record.health;
25
- const fallback = {
26
- status: "unknown",
27
- maturity: "unknown",
28
- tier: "listed",
29
- visibility: "keep",
30
- cleanupCandidate: false,
31
- staleReason: null,
32
- confidence: "medium",
33
- reasons: [],
34
- };
35
- const merged = { ...(existing ?? fallback), visibility: override };
35
+ // Fabricate a default "no signals" health block via the canonical
36
+ // classifier. Keeps the threshold/format in lockstep with the rest
37
+ // of the package — if `classifyHealth` ever changes its unknown
38
+ // shape, this fabrication updates automatically.
39
+ const fabricated = classifyHealth(record.slug).health;
40
+ const merged = { ...(existing ?? fabricated), visibility: override };
36
41
  return { ...record, health: merged };
37
42
  }
38
43
  // Resource-hub / ecosystem-map: no `health` block; the top-level
@@ -123,7 +128,9 @@ export async function generate(cwd = process.cwd(), config) {
123
128
  platforms.add(p);
124
129
  const gh = r.github;
125
130
  if (gh?.fullName && gh.fullName.includes("/")) {
126
- owners.add(gh.fullName.split("/")[0]);
131
+ const [owner] = gh.fullName.split("/");
132
+ if (owner)
133
+ owners.add(owner);
127
134
  }
128
135
  if (typeof gh?.stars === "number")
129
136
  totalStars += gh.stars;
@@ -1 +1 @@
1
- {"version":3,"file":"build-data.js","sourceRoot":"","sources":["../src/build-data.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build-data.js","sourceRoot":"","sources":["../src/build-data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,mBAAmB,GAGpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAS,aAAa,CACpB,MAAgB,EAChB,cAAmC;IAEnC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjD,IAAI,CAAC,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC7B,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;QAC/B,kEAAkE;QAClE,mEAAmE;QACnE,gEAAgE;QAChE,iDAAiD;QACjD,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QACtD,MAAM,MAAM,GAAG,EAAE,GAAG,CAAC,QAAQ,IAAI,UAAU,CAAC,EAAE,UAAU,EAAE,QAAwC,EAAE,CAAC;QACrG,OAAO,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACvC,CAAC;IACD,iEAAiE;IACjE,gEAAgE;IAChE,OAAO,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,QAAoC,EAAE,CAAC;AACzE,CAAC;AAED,KAAK,UAAU,sBAAsB,CACnC,aAAqB,EACrB,GAAW;IAEX,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC;QAChE,MAAM,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/D,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,SAAS;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAChE,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,kDAAkD;QAClD,OAAO,IAAI,GAAG,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AA6CD,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,EACnB,MAAoB;IAEpB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACpD,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzC,MAAM,YAAY,GAAG,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAc,CAAC,CAAC;IACtE,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAE/D,gEAAgE;IAChE,MAAM,cAAc,GAAG,MAAM,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAE9E,MAAM,GAAG,GAAe,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;YAC5D,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAA4B,CAAC;YAC/D,IAAI,CAAC,GAAG,CAAC,IAAI;gBAAE,GAAG,CAAC,IAAI,GAAG,YAAY,CAAC;YACvC,MAAM,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAChD,UAAU,CAAC,IAAI,GAAG,QAAQ,CAAC;YAC3B,gEAAgE;YAChE,gEAAgE;YAChE,kCAAkC;YAClC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,MAAM,kBAAkB,CAAC,CAAC;QACxE,CAAoC,CAAC,OAAO,GAAG,MAAM,CAAC;QACvD,MAAM,CAAC,CAAC;IACV,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEvD,MAAM,YAAY,GAAG,GAAG;SACrB,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;SACtC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACZ,MAAM,GAAG,GAAI,CAA6B,CAAC,UAAU,CAAC;QACtD,OAAO,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,QAAQ,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEL,mEAAmE;IACnE,kEAAkE;IAClE,8DAA8D;IAC9D,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IAEjE,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAI,CAA2B,CAAC,QAAQ,CAAC;QAClD,IAAI,GAAG;YAAE,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,EAAE,GAAI,CAAwB,CAAC,KAAK,CAAC;QAC3C,IAAI,EAAE;YAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvB,MAAM,EAAE,GAAI,CAA2B,CAAC,MAAM,IAAI,EAAE,CAAC;QACrD,KAAK,MAAM,CAAC,IAAI,EAAE;YAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,EAAE,GAAI,CAA8B,CAAC,SAAS,IAAI,EAAE,CAAC;QAC3D,KAAK,MAAM,CAAC,IAAI,EAAE;YAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,EAAE,GAAI,CAAwD,CAAC,MAAM,CAAC;QAC5E,IAAI,EAAE,EAAE,QAAQ,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACvC,IAAI,KAAK;gBAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,IAAI,OAAO,EAAE,EAAE,KAAK,KAAK,QAAQ;YAAE,UAAU,IAAI,EAAE,CAAC,KAAK,CAAC;IAC5D,CAAC;IAED,uEAAuE;IACvE,mEAAmE;IACnE,sEAAsE;IACtE,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACtD,IAAI,SAAS,GAMT,EAAE,CAAC;IACP,IAAI,CAAC;QACH,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,2CAA2C;IAC7C,CAAC;IAED,+DAA+D;IAC/D,2DAA2D;IAC3D,6DAA6D;IAC7D,4DAA4D;IAC5D,0DAA0D;IAC1D,EAAE;IACF,0DAA0D;IAC1D,+DAA+D;IAC/D,4BAA4B;IAC5B,EAAE;IACF,4DAA4D;IAC5D,iEAAiE;IACjE,gEAAgE;IAChE,iEAAiE;IACjE,MAAM,IAAI,GAAG,YAAY,CAAC;IAC1B,MAAM,eAAe,GAAG;QACtB,EAAE,EAAE,GAAG,CAAC,SAAS;QACjB,IAAI;QACJ,gEAAgE;QAChE,8DAA8D;QAC9D,0DAA0D;QAC1D,SAAS,EACN,GAA2C,CAAC,MAAM,EAAE,SAAS;YAC9D,CAAC;gBACC,OAAO,EAAE,UAAU;gBACnB,QAAQ,EAAE,WAAW;gBACrB,MAAM,EAAE,UAAU;aACnB,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC;QACrB,QAAQ,EACL,GAAsC,CAAC,MAAM,EAAE,IAAI;YACpD,CAAC;gBACC,OAAO,EAAE,SAAS;gBAClB,QAAQ,EAAE,UAAU;gBACpB,MAAM,EAAE,QAAQ;aACjB,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC;QACpB,oEAAoE;QACpE,aAAa,EACV,GAA0C,CAAC,MAAM,EAAE,QAAQ;YAC5D,CAAC;gBACC,OAAO,EAAE,SAAS;gBAClB,QAAQ,EAAE,UAAU;gBACpB,MAAM,EAAE,QAAQ;aACjB,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC;QACpB,WAAW,EACR,GAAwC,CAAC,MAAM,EAAE,MAAM;YACxD,CAAC;gBACC,OAAO,EAAE,UAAU;gBACnB,QAAQ,EAAE,WAAW;gBACrB,MAAM,EAAE,UAAU;aACnB,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC;KACtB,CAAC;IAEF,MAAM,iBAAiB,GAAG;QACxB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,eAAe;QACf,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI;QACnB,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO;QACzB,WAAW,EAAE,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO;QACrD,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,qBAAqB;QAC9C,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE;QAC/B,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,KAAK,EAAE;YACL,YAAY,EAAE,YAAY,CAAC,MAAM;YACjC,SAAS,EAAE,QAAQ,CAAC,MAAM;YAC1B,cAAc,EAAE,SAAS,CAAC,MAAM;YAChC,aAAa,EAAE,QAAQ,CAAC,MAAM;YAC9B,eAAe,EAAE,UAAU,CAAC,IAAI;YAChC,WAAW,EAAE,MAAM,CAAC,IAAI;YACxB,cAAc,EAAE,SAAS,CAAC,IAAI;YAC9B,WAAW,EAAE,MAAM,CAAC,IAAI;YACxB,UAAU;YACV,mEAAmE;YACnE,YAAY,EAAE,SAAS,CAAC,YAAY,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE;YAC9D,aAAa,EAAE,SAAS,CAAC,KAAK,IAAI,CAAC;YACnC,aAAa,EAAE,SAAS,CAAC,KAAK,IAAI,CAAC;YACnC,oBAAoB,EAAE,SAAS,CAAC,YAAY,IAAI,CAAC;SAClD;KACF,CAAC;IACF,MAAM,SAAS,CACb,IAAI,CAAC,MAAM,EAAE,kBAAkB,CAAC,EAChC,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC,EAC1C,MAAM,CACP,CAAC;IAEF,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,WAAW,GAAuB;QACtC,aAAa,EAAE,CAAC;QAChB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,WAAW;QACX,YAAY,EAAE,GAAG,CAAC,MAAM;QACxB,cAAc,EAAE,YAAY,CAAC,MAAM;QACnC,OAAO,EAAE,GAAgD;KAC1D,CAAC;IACF,MAAM,YAAY,GAAwB;QACxC,aAAa,EAAE,CAAC;QAChB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,WAAW;QACX,YAAY,EAAE,YAAY,CAAC,MAAM;QACjC,OAAO,EAAE,YAAyD;KACnE,CAAC;IAEF,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IACnD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC/C,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,MAAM,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAC1E,MAAM,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAEzE,OAAO;QACL,YAAY,EAAE,GAAG,CAAC,MAAM;QACxB,cAAc,EAAE,YAAY,CAAC,MAAM;QACnC,QAAQ;QACR,SAAS;QACT,SAAS;QACT,MAAM;KACP,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CAAC,MAAgB;IAC9B,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC;IACpD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=build-data.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-data.test.d.ts","sourceRoot":"","sources":["../src/build-data.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,171 @@
1
+ /**
2
+ * @grove-dev/core — build-data.ts unit tests.
3
+ *
4
+ * The brief calls out `applyDecision` as a load-bearing function:
5
+ * - When a project record has no existing health block but a
6
+ * decisions.yml override exists, the function fabricates an
7
+ * "unknown" health block (via `classifyHealth(slug)`) and
8
+ * writes the decision's visibility into it. This is the
9
+ * preserved (vs. removed) decision from the audit, and the
10
+ * test pins the chosen behavior.
11
+ * - For resource-hub / ecosystem-map records (no `health`
12
+ * block), the decision visibility goes onto the record's
13
+ * top-level `visibility` field.
14
+ *
15
+ * `generate` itself is tested via filesystem round-trip with a
16
+ * real tmpdir.
17
+ */
18
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
19
+ import { mkdtemp, mkdir, writeFile, readFile, rm } from "node:fs/promises";
20
+ import { tmpdir } from "node:os";
21
+ import { join } from "node:path";
22
+ import { generate } from "./build-data.js";
23
+ import { toIndexRecord } from "./schema.js";
24
+ function makeProject(overrides = {}) {
25
+ return {
26
+ kind: "project",
27
+ slug: "demo",
28
+ name: "Demo",
29
+ description: "A demo",
30
+ category: "tools",
31
+ tags: [],
32
+ links: {},
33
+ curation: { reviewed: false, labels: [], lenses: [] },
34
+ scores: {},
35
+ visibility: "keep",
36
+ ...overrides,
37
+ };
38
+ }
39
+ describe("toIndexRecord — fabrication behaviour (applyDecision shape)", () => {
40
+ it("a project record with no health block + a decision.decision.visibility of 'hide' fabricates a health block carrying that visibility", async () => {
41
+ // This test pins the PRESERVED audit decision: when a
42
+ // project record has no health block but a decisions.yml
43
+ // override exists, applyDecision (called inside generate)
44
+ // fabricates a health block via classifyHealth(slug) (the
45
+ // canonical unknown shape) and overwrites visibility.
46
+ // The fabrication must keep the unknown status / maturity /
47
+ // tier, and only visibility changes.
48
+ //
49
+ // We exercise the public `toIndexRecord` path, which is what
50
+ // generate ultimately calls, with a record that has been
51
+ // through the applyDecision path (simulate that here by
52
+ // hand).
53
+ const project = makeProject();
54
+ // The "fabricated" record is what applyDecision produces:
55
+ const fabricated = {
56
+ ...project,
57
+ health: {
58
+ status: "unknown",
59
+ maturity: "unknown",
60
+ tier: "experimental",
61
+ visibility: "hide",
62
+ cleanupCandidate: false,
63
+ staleReason: null,
64
+ confidence: "low",
65
+ reasons: ["No GitHub metadata available"],
66
+ },
67
+ };
68
+ const idx = toIndexRecord(fabricated);
69
+ // The index record's `visibility` (read by the index
70
+ // filter) must reflect the decision override, not the
71
+ // fabricated default of "keep".
72
+ expect(idx.visibility).toBe("hide");
73
+ });
74
+ });
75
+ describe("generate — filesystem round-trip", () => {
76
+ let cwd;
77
+ beforeEach(async () => {
78
+ cwd = await mkdtemp(join(tmpdir(), "grove-build-test-"));
79
+ await mkdir(join(cwd, "data", "records"), { recursive: true });
80
+ await mkdir(join(cwd, "data", "generated"), { recursive: true });
81
+ // grove.config.ts stub so loadConfig() doesn't throw.
82
+ await writeFile(join(cwd, "grove.config.ts"), [
83
+ "export default {",
84
+ " site: { name: 'test', tagline: 'test' },",
85
+ " paths: { recordsDir: 'data/records', generatedDir: 'data/generated', health: 'data/health.yml', decisions: 'data/decisions.yml' },",
86
+ " blueprint: 'project-directory',",
87
+ " nav: [],",
88
+ " theme: {},",
89
+ " integrations: {},",
90
+ "};",
91
+ ].join("\n"));
92
+ });
93
+ afterEach(async () => {
94
+ await rm(cwd, { recursive: true, force: true });
95
+ });
96
+ it("generates records.full.json, records.index.json, and records.json (alias) from a real records dir", async () => {
97
+ await writeFile(join(cwd, "data", "records", "demo.yml"), [
98
+ "kind: project",
99
+ "slug: demo",
100
+ "name: Demo",
101
+ "description: a demo",
102
+ "category: tools",
103
+ "links: {}",
104
+ "curation: { reviewed: false, labels: [], lenses: [] }",
105
+ "scores: {}",
106
+ ].join("\n"));
107
+ const r = await generate(cwd);
108
+ expect(r.totalRecords).toBe(1);
109
+ expect(r.visibleRecords).toBe(1);
110
+ // The three files were all written.
111
+ const full = JSON.parse(await readFile(r.fullPath, "utf8"));
112
+ const idx = JSON.parse(await readFile(r.indexPath, "utf8"));
113
+ const alias = JSON.parse(await readFile(r.aliasPath, "utf8"));
114
+ expect(full.totalRecords).toBe(1);
115
+ expect(idx.totalRecords).toBe(1);
116
+ // Alias == full payload.
117
+ expect(alias).toEqual(full);
118
+ });
119
+ it("applies a decisions.yml override of visibility='hide' to a project record without a health block", async () => {
120
+ // The brief's load-bearing test: a project record that has
121
+ // no health block, plus a decisions.yml that says
122
+ // "hide" for that slug, must produce a hidden record in the
123
+ // full payload AND exclude it from the index payload.
124
+ await writeFile(join(cwd, "data", "records", "hidden.yml"), [
125
+ "kind: project",
126
+ "slug: hidden",
127
+ "name: Hidden",
128
+ "description: should be hidden by decisions.yml",
129
+ "category: tools",
130
+ "links: {}",
131
+ "curation: { reviewed: false, labels: [], lenses: [] }",
132
+ "scores: {}",
133
+ ].join("\n"));
134
+ await writeFile(join(cwd, "data", "decisions.yml"), [
135
+ "decisions:",
136
+ " - id: hidden",
137
+ " decision:",
138
+ " visibility: hide",
139
+ " reason: tested override",
140
+ ].join("\n"));
141
+ const r = await generate(cwd);
142
+ expect(r.totalRecords).toBe(1); // full payload still includes the record
143
+ expect(r.visibleRecords).toBe(0); // but the index payload omits it
144
+ const full = JSON.parse(await readFile(r.fullPath, "utf8"));
145
+ const hidden = full.records.find((rec) => rec.slug === "hidden");
146
+ expect(hidden).toBeDefined();
147
+ // The fabrication: a health block exists, and its visibility
148
+ // is "hide" (the decision override), not "keep" (the
149
+ // fabricated default).
150
+ expect(hidden?.health?.visibility).toBe("hide");
151
+ });
152
+ it("writes site-config.json with stats derived from the records", async () => {
153
+ await writeFile(join(cwd, "data", "records", "coolify.yml"), [
154
+ "kind: project",
155
+ "slug: coolify",
156
+ "name: Coolify",
157
+ "description: self-hosting",
158
+ "category: tools",
159
+ "stacks: [typescript]",
160
+ "links: {}",
161
+ "curation: { reviewed: false, labels: [], lenses: [] }",
162
+ "scores: {}",
163
+ ].join("\n"));
164
+ const r = await generate(cwd);
165
+ const sitePath = join(cwd, "data", "generated", "site-config.json");
166
+ const site = JSON.parse(await readFile(sitePath, "utf8"));
167
+ expect(site.stats.totalRecords).toBe(1);
168
+ expect(site.stats.totalApps).toBe(1);
169
+ });
170
+ });
171
+ //# sourceMappingURL=build-data.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-data.test.js","sourceRoot":"","sources":["../src/build-data.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=decisions.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decisions.test.d.ts","sourceRoot":"","sources":["../src/decisions.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * @grove-dev/core — decisions + cleanup-stale unit tests.
3
+ *
4
+ * `pickCleanupCandidates` is a pure predicate and trivially testable
5
+ * without any I/O. `cleanupStale` reads from the filesystem and
6
+ * writes `data/generated/cleanup-report.json` — the tests below use
7
+ * `tmpdir()` (per the brief — no fs mocks) to spin up a real
8
+ * project tree and exercise both the happy path and the missing-
9
+ * files-dir / invalid-YAML silent-fallback paths.
10
+ */
11
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
12
+ import { mkdir, writeFile, readFile, rm, mkdtemp } from "node:fs/promises";
13
+ import { tmpdir } from "node:os";
14
+ import { join } from "node:path";
15
+ import { pickCleanupCandidates, cleanupStale } from "./decisions.js";
16
+ function makeProjectResource(overrides = {}) {
17
+ return {
18
+ kind: "project",
19
+ slug: "demo",
20
+ name: "Demo",
21
+ description: "A demo project",
22
+ category: "tools",
23
+ tags: [],
24
+ links: { github: "https://github.com/owner/repo" },
25
+ curation: { reviewed: false, labels: [], lenses: [] },
26
+ scores: {},
27
+ visibility: "keep",
28
+ ...overrides,
29
+ };
30
+ }
31
+ describe("pickCleanupCandidates — pure predicate", () => {
32
+ it("returns records whose health.cleanupCandidate is true", () => {
33
+ const r = makeProjectResource({
34
+ health: {
35
+ status: "stale",
36
+ maturity: "useful",
37
+ tier: "listed",
38
+ visibility: "keep",
39
+ cleanupCandidate: true,
40
+ staleReason: "no_commits_365_days",
41
+ confidence: "high",
42
+ reasons: [],
43
+ },
44
+ });
45
+ expect(pickCleanupCandidates([r])).toEqual([r]);
46
+ });
47
+ it("returns records whose health.status is 'unknown' or 'needs_review'", () => {
48
+ const a = makeProjectResource({ slug: "a", health: { status: "unknown", maturity: "unknown", tier: "experimental", visibility: "keep", cleanupCandidate: false, staleReason: null, confidence: "low", reasons: [] } });
49
+ const b = makeProjectResource({ slug: "b", health: { status: "needs_review", maturity: "useful", tier: "listed", visibility: "keep", cleanupCandidate: false, staleReason: null, confidence: "medium", reasons: [] } });
50
+ const c = makeProjectResource({ slug: "c", health: { status: "active", maturity: "mature", tier: "curated", visibility: "keep", cleanupCandidate: false, staleReason: null, confidence: "high", reasons: [] } });
51
+ const out = pickCleanupCandidates([a, b, c]);
52
+ expect(out.map((r) => r.slug).sort()).toEqual(["a", "b"]);
53
+ });
54
+ it("returns an empty array when no records need cleanup", () => {
55
+ const a = makeProjectResource({ health: { status: "active", maturity: "mature", tier: "curated", visibility: "keep", cleanupCandidate: false, staleReason: null, confidence: "high", reasons: [] } });
56
+ const b = makeProjectResource({ slug: "b", health: { status: "mature", maturity: "mature", tier: "curated", visibility: "keep", cleanupCandidate: false, staleReason: null, confidence: "high", reasons: [] } });
57
+ expect(pickCleanupCandidates([a, b])).toEqual([]);
58
+ });
59
+ it("treats a record with no health block as not-a-candidate", () => {
60
+ const r = makeProjectResource(); // no health
61
+ expect(pickCleanupCandidates([r])).toEqual([]);
62
+ });
63
+ });
64
+ describe("cleanupStale — filesystem integration (real tmpdir)", () => {
65
+ let cwd;
66
+ beforeEach(async () => {
67
+ cwd = await mkdtemp(join(tmpdir(), "grove-cleanup-test-"));
68
+ await mkdir(join(cwd, "data", "records"), { recursive: true });
69
+ await mkdir(join(cwd, "data", "generated"), { recursive: true });
70
+ // cleanupStale → loadConfig → jiti-resolves grove.config.ts.
71
+ // Write a minimal valid stub so the config loader doesn't throw.
72
+ await writeFile(join(cwd, "grove.config.ts"), [
73
+ "export default {",
74
+ " site: { name: 'test', tagline: 'test' },",
75
+ " paths: { recordsDir: 'data/records', generatedDir: 'data/generated', health: 'data/health.yml', decisions: 'data/decisions.yml' },",
76
+ " blueprint: 'project-directory',",
77
+ " nav: [],",
78
+ " theme: {},",
79
+ " integrations: {},",
80
+ "};",
81
+ ].join("\n"));
82
+ });
83
+ afterEach(async () => {
84
+ await rm(cwd, { recursive: true, force: true });
85
+ });
86
+ it("reads records, applies pickCleanupCandidates, writes cleanup-report.json", async () => {
87
+ // One record whose health status is 'unknown' (cleanup candidate)
88
+ // and one whose status is 'active' (not a candidate). The slug
89
+ // field is in the YAML (matches the schema), and the file name
90
+ // also carries it (cleanupStale overwrites normalized.slug
91
+ // with the filename at line 88 — pinning that contract).
92
+ await writeFile(join(cwd, "data", "records", "stale-one.yml"), [
93
+ "kind: project",
94
+ "slug: stale-one",
95
+ "name: Stale One",
96
+ "description: an old project",
97
+ "category: tools",
98
+ "links: { github: 'https://github.com/owner/repo' }",
99
+ "curation: { reviewed: false, labels: [], lenses: [] }",
100
+ "scores: {}",
101
+ "health:",
102
+ " status: unknown",
103
+ " maturity: unknown",
104
+ " tier: experimental",
105
+ " visibility: keep",
106
+ " cleanupCandidate: false",
107
+ " staleReason: null",
108
+ " confidence: low",
109
+ " reasons: []",
110
+ ].join("\n"));
111
+ await writeFile(join(cwd, "data", "records", "fresh.yml"), [
112
+ "kind: project",
113
+ "slug: fresh",
114
+ "name: Fresh",
115
+ "description: an active project",
116
+ "category: tools",
117
+ "links: { github: 'https://github.com/owner/fresh' }",
118
+ "curation: { reviewed: false, labels: [], lenses: [] }",
119
+ "scores: {}",
120
+ "health:",
121
+ " status: active",
122
+ " maturity: mature",
123
+ " tier: curated",
124
+ " visibility: keep",
125
+ " cleanupCandidate: false",
126
+ " staleReason: null",
127
+ " confidence: high",
128
+ " reasons: []",
129
+ ].join("\n"));
130
+ const { report, path } = await cleanupStale(cwd);
131
+ expect(report.totalCandidates).toBe(1);
132
+ expect(report.candidates[0]?.slug).toBe("stale-one");
133
+ expect(report.candidates[0]?.status).toBe("unknown");
134
+ expect(report.blueprint).toBe("project-directory");
135
+ // Verify the file was actually written.
136
+ const written = JSON.parse(await readFile(path, "utf8"));
137
+ expect(written.totalCandidates).toBe(1);
138
+ expect(written.candidates[0]?.slug).toBe("stale-one");
139
+ });
140
+ it("skips records whose parsed YAML fails Zod (try/catch on recordsFileSchema.parse)", async () => {
141
+ // The brief calls out the silent try/catch around
142
+ // `recordsFileSchema.parse(raw)` in decisions.ts as audit
143
+ // concern #1. Pin the *current* behaviour (skip, do not
144
+ // throw) so a future change to throw is visible.
145
+ //
146
+ // Note: `parseYaml` itself is NOT in a try/catch — a totally
147
+ // malformed YAML would crash the loop. The silent path the
148
+ // audit flagged is the Zod parse step, not the YAML parse
149
+ // step. So this test uses a YAML file that *parses* but
150
+ // produces a value the Zod schema rejects (e.g. an array
151
+ // where an object is required).
152
+ await writeFile(join(cwd, "data", "records", "broken.yml"),
153
+ // YAML that parses to an array — fails Zod object validation.
154
+ "- this\n- is\n- an\n- array\n");
155
+ // A second, valid record that IS a cleanup candidate.
156
+ await writeFile(join(cwd, "data", "records", "ok.yml"), [
157
+ "kind: project",
158
+ "slug: ok",
159
+ "name: Ok",
160
+ "description: candidate",
161
+ "category: tools",
162
+ "links: {}",
163
+ "curation: { reviewed: false, labels: [], lenses: [] }",
164
+ "scores: {}",
165
+ "health:",
166
+ " status: needs_review",
167
+ " maturity: useful",
168
+ " tier: listed",
169
+ " visibility: keep",
170
+ " cleanupCandidate: false",
171
+ " staleReason: null",
172
+ " confidence: medium",
173
+ " reasons: []",
174
+ ].join("\n"));
175
+ const { report } = await cleanupStale(cwd);
176
+ // The broken record is dropped; only "ok" is reported.
177
+ expect(report.totalCandidates).toBe(1);
178
+ expect(report.candidates[0]?.slug).toBe("ok");
179
+ });
180
+ it("returns an empty report when the records directory does not exist", async () => {
181
+ // The readdir call at decisions.ts:77 uses .catch(() => []),
182
+ // so a missing dir is silently treated as zero records. Pin
183
+ // that behaviour — the function should NOT throw, the report
184
+ // should be empty, and the JSON file should still be written
185
+ // (so downstream tooling can rely on its presence). We test
186
+ // by pointing config.paths.recordsDir at a path that doesn't
187
+ // exist, rather than rm-ing the records dir after beforeEach
188
+ // created the config (which would also remove the config).
189
+ const noRecordsConfig = {
190
+ site: { name: "test", tagline: "test" },
191
+ paths: { recordsDir: "data/does-not-exist", generatedDir: "data/generated", health: "data/health.yml", decisions: "data/decisions.yml" },
192
+ blueprint: "project-directory",
193
+ nav: [],
194
+ theme: {},
195
+ integrations: {},
196
+ };
197
+ const { report, path } = await cleanupStale(cwd, noRecordsConfig);
198
+ expect(report.totalCandidates).toBe(0);
199
+ expect(report.candidates).toEqual([]);
200
+ // The file should still exist for downstream consumers.
201
+ const written = JSON.parse(await readFile(path, "utf8"));
202
+ expect(written.totalCandidates).toBe(0);
203
+ });
204
+ });
205
+ //# sourceMappingURL=decisions.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decisions.test.js","sourceRoot":"","sources":["../src/decisions.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=enrich.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enrich.test.d.ts","sourceRoot":"","sources":["../src/enrich.test.ts"],"names":[],"mappings":""}