Skip to content

Commit 1ab889c

Browse files
committed
feat(devshell): add markdownlint-cli2, lychee, vale, cspell; gate Chromium to Linux; add Justfile tasks
- Add `markdownlint-cli2` for fast, configurable Markdown linting. - Add `lychee` for robust external link checking in Markdown. - Add `vale` for prose/style linting; `cspell` for spelling. - Limit `chromium` to Linux in devShell; keep Puppeteer env to use system Chrome/Chromium when present, avoiding issues on aarch64-darwin. - Add `md-lint`, `md-links`, and `md-spell` Justfile tasks alongside existing Mermaid validator. - Keeps existing Mermaid validation script; integrates better ergonomics for vault-wide checks.
1 parent 7fb3610 commit 1ab889c

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed

Justfile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,19 @@ conf-schema-taplo-check:
4444
# Serve schema docs locally with Docson (opens http://localhost:3000)
4545
conf-schema-docs:
4646
docson -d specs/schemas
47+
48+
# Validate Mermaid diagrams in Markdown with mermaid-cli (mmdc)
49+
md-mermaid-check:
50+
bash scripts/md-mermaid-validate.sh specs/**/*.md
51+
52+
# Lint Markdown structure/style in specs with markdownlint-cli2
53+
md-lint:
54+
markdownlint-cli2 "specs/**/*.md"
55+
56+
# Check external links in Markdown with lychee
57+
md-links:
58+
lychee --offline false --no-progress --require-https true --max-concurrency 8 "specs/**/*.md"
59+
60+
# Spell-check Markdown with cspell (uses default dictionaries unless configured)
61+
md-spell:
62+
cspell "specs/**/*.md"

flake.nix

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@
7171
pkgs.fossil
7272
pkgs.mercurial
7373
pkgs.nodejs # for npx-based docson helper
74+
# Mermaid validation (diagram syntax)
75+
(pkgs.nodePackages."@mermaid-js/mermaid-cli")
76+
pkgs.noto-fonts
77+
78+
# Markdown linting & link/prose checking
79+
(pkgs.nodePackages.markdownlint-cli2)
80+
pkgs.lychee
81+
pkgs.vale
82+
(pkgs.nodePackages.cspell)
7483

7584
# AI Coding Assistants (latest versions from nixpkgs-unstable)
7685
pkgs.goose-cli # Goose AI coding assistant
@@ -86,6 +95,8 @@
8695
then pkgs.nodePackages."ajv-cli" else null)
8796
])
8897
++ pkgs.lib.optionals isLinux [
98+
# Use Chromium on Linux for mermaid-cli's Puppeteer
99+
pkgs.chromium
89100
# Linux-only filesystem utilities for snapshot functionality
90101
pkgs.zfs # ZFS utilities for copy-on-write snapshots
91102
pkgs.btrfs-progs # Btrfs utilities for subvolume snapshots
@@ -99,6 +110,15 @@
99110
# Provide a convenience function to launch Docson without global install
100111
docson () { npx -y docson "$@"; }
101112
echo "Tip: run: docson -d ./specs/schemas # then open http://localhost:3000"
113+
# Ensure mermaid-cli (mmdc) uses system Chrome/Chromium when present
114+
if command -v chromium >/dev/null 2>&1; then
115+
export PUPPETEER_EXECUTABLE_PATH="$(command -v chromium)"
116+
elif command -v google-chrome >/dev/null 2>&1; then
117+
export PUPPETEER_EXECUTABLE_PATH="$(command -v google-chrome)"
118+
elif command -v google-chrome-stable >/dev/null 2>&1; then
119+
export PUPPETEER_EXECUTABLE_PATH="$(command -v google-chrome-stable)"
120+
fi
121+
export PUPPETEER_PRODUCT=chrome
102122
'';
103123
};
104124
});

scripts/md-mermaid-validate.sh

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# Resolve Mermaid CLI (mmdc)
5+
if command -v mmdc >/dev/null 2>&1; then
6+
MMDC_CMD="mmdc"
7+
else
8+
# Fallback to npx if available (requires network on first run)
9+
if command -v npx >/dev/null 2>&1; then
10+
MMDC_CMD="npx -y @mermaid-js/mermaid-cli"
11+
# Prefer system Chrome/Chromium if present to avoid downloads
12+
for bin in chromium chromium-browser google-chrome google-chrome-stable; do
13+
if command -v "$bin" >/dev/null 2>&1; then
14+
export PUPPETEER_EXECUTABLE_PATH="$(command -v "$bin")"
15+
export PUPPETEER_PRODUCT=chrome
16+
export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
17+
break
18+
fi
19+
done
20+
if [[ -z "${PUPPETEER_EXECUTABLE_PATH:-}" ]]; then
21+
echo "No system Chrome/Chromium found. Without nix develop this fallback requires network to download a headless browser via npx. If that's not possible here, either install Chrome and re-run, or enter 'nix develop'." >&2
22+
exit 127
23+
fi
24+
else
25+
echo "mmdc (mermaid-cli) not found and no npx fallback. Install via Nix dev shell or Node." >&2
26+
exit 127
27+
fi
28+
fi
29+
30+
TMPDIR_ROOT="${TMPDIR:-/tmp}"
31+
FAILED=0
32+
33+
validate_file() {
34+
local file="$1"
35+
local tmpdir
36+
tmpdir="$(mktemp -d "$TMPDIR_ROOT/mmdc.$$.$(basename "$file").XXXX")"
37+
trap 'rm -rf "'$tmpdir'"' RETURN
38+
39+
local in_block=0
40+
local block_no=0
41+
local line_no=0
42+
while IFS= read -r line; do
43+
line_no=$((line_no+1))
44+
if [[ $in_block -eq 0 && $line =~ ^```mermaid[[:space:]]*$ ]]; then
45+
in_block=1
46+
block_no=$((block_no+1))
47+
: >"$tmpdir/block_${block_no}.mmd"
48+
continue
49+
fi
50+
if [[ $in_block -eq 1 && $line =~ ^```[[:space:]]*$ ]]; then
51+
in_block=0
52+
# validate the block by attempting render
53+
local in_file="$tmpdir/block_${block_no}.mmd"
54+
local out_file="$tmpdir/block_${block_no}.svg"
55+
if ! $MMDC_CMD -i "$in_file" -o "$out_file" --quiet >/dev/null 2>&1; then
56+
echo "Mermaid error: $file: block $block_no (see $in_file)" >&2
57+
FAILED=1
58+
fi
59+
continue
60+
fi
61+
if [[ $in_block -eq 1 ]]; then
62+
printf '%s\n' "$line" >>"$tmpdir/block_${block_no}.mmd"
63+
fi
64+
done <"$file"
65+
}
66+
67+
if [[ $# -eq 0 ]]; then
68+
set -- specs/Public/*.md specs/Public/**/*.md 2>/dev/null || true
69+
fi
70+
71+
shopt -s nullglob
72+
for f in "$@"; do
73+
validate_file "$f"
74+
done
75+
76+
exit $FAILED

0 commit comments

Comments
 (0)