@recallnet/remark-lint-docs-freshness 0.2.2 → 0.2.4

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 (3) hide show
  1. package/README.md +57 -1
  2. package/package.json +3 -3
  3. package/src/index.js +8 -17
package/README.md CHANGED
@@ -2,9 +2,65 @@
2
2
 
3
3
  Checks Markdown frontmatter `reviewed` dates against policy-defined `max_age_days`.
4
4
 
5
- Use with `remark-frontmatter`:
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -D remark remark-frontmatter @recallnet/remark-lint-docs-freshness
9
+ ```
10
+
11
+ ## Use
12
+
13
+ Use with `remark-frontmatter` so YAML frontmatter is available to the rule:
6
14
 
7
15
  ```js
16
+ import { remark } from "remark";
8
17
  import remarkFrontmatter from "remark-frontmatter";
9
18
  import remarkLintDocsFreshness from "@recallnet/remark-lint-docs-freshness";
19
+
20
+ await remark()
21
+ .use(remarkFrontmatter)
22
+ .use(remarkLintDocsFreshness, {
23
+ cwd: process.cwd(),
24
+ policyPath: "./docs/docs-policy.json",
25
+ })
26
+ .process({
27
+ path: "docs/architecture/cache.md",
28
+ value: `---
29
+ review_policy: periodic-7
30
+ reviewed: 2026-03-01
31
+ ---
32
+
33
+ # Cache`,
34
+ });
10
35
  ```
36
+
37
+ ## What It Checks
38
+
39
+ - only files that match `in_scope_paths` in `docs/docs-policy.json`
40
+ - only docs using periodic review policies
41
+ - frontmatter `reviewed` values in `YYYY-MM-DD` format
42
+ - whether `reviewed` is older than the policy's `max_age_days`
43
+
44
+ The rule reports messages such as:
45
+
46
+ ```text
47
+ Document is stale: reviewed=2026-03-01 age_days=18 max_age_days=7.
48
+ ```
49
+
50
+ ## Options
51
+
52
+ - `cwd`
53
+ Repository root used to resolve the docs policy and the current file path.
54
+ - `policyPath`
55
+ Path to the docs policy file relative to `cwd`.
56
+ Defaults to `docs/docs-policy.json`.
57
+ - `today`
58
+ Override the current date as `YYYY-MM-DD`.
59
+ Useful for deterministic tests.
60
+
61
+ ## Notes
62
+
63
+ - Docs with non-periodic policies such as `historical` are ignored.
64
+ - If frontmatter is missing or unreadable for an in-scope file, the rule reports that freshness could not be checked.
65
+ - Frontmatter parsing uses `vfile-matter`, which is the unified-recommended way to expose YAML metadata on `file.data.matter`.
66
+ - This package is intended for docs-governance setups that keep freshness policy in repo config rather than hardcoding date thresholds in lint config.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@recallnet/remark-lint-docs-freshness",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Remark plugin that checks docs reviewed dates against repo policy.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,8 +25,8 @@
25
25
  "src"
26
26
  ],
27
27
  "dependencies": {
28
- "yaml": "^2.8.3",
29
- "@recallnet/docs-governance-policy": "0.2.2"
28
+ "vfile-matter": "^5.0.1",
29
+ "@recallnet/docs-governance-policy": "0.2.3"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "remark-frontmatter": "^5.0.0"
package/src/index.js CHANGED
@@ -9,24 +9,10 @@ import {
9
9
  resolveDocsReviewPolicy,
10
10
  resolveReviewPolicyConfig,
11
11
  } from "@recallnet/docs-governance-policy";
12
- import { parse } from "yaml";
12
+ import { matter } from "vfile-matter";
13
13
 
14
14
  const RULE_ID = "docs-freshness";
15
15
 
16
- function findYamlNode(tree) {
17
- return tree?.children?.find((node) => node.type === "yaml") ?? null;
18
- }
19
-
20
- function parseFrontmatter(tree) {
21
- const yamlNode = findYamlNode(tree);
22
- if (!yamlNode?.value) {
23
- return null;
24
- }
25
-
26
- const data = parse(String(yamlNode.value));
27
- return data && typeof data === "object" && !Array.isArray(data) ? data : null;
28
- }
29
-
30
16
  function dateDiffDays(older, newer) {
31
17
  const olderMs = new Date(`${older}T00:00:00Z`).getTime();
32
18
  const newerMs = new Date(`${newer}T00:00:00Z`).getTime();
@@ -58,8 +44,13 @@ export default function remarkLintDocsFreshness(options = {}) {
58
44
  return;
59
45
  }
60
46
 
61
- const frontmatter = parseFrontmatter(tree);
62
- if (!frontmatter) {
47
+ matter(file);
48
+ const frontmatter =
49
+ file.data.matter && typeof file.data.matter === "object" && !Array.isArray(file.data.matter)
50
+ ? file.data.matter
51
+ : null;
52
+
53
+ if (!frontmatter || Object.keys(frontmatter).length === 0) {
63
54
  file.message("Document freshness could not be checked because frontmatter is unreadable.", {
64
55
  ruleId: RULE_ID,
65
56
  source: "@recallnet/remark-lint-docs-freshness",