jekyll-theme-zer0 1.25.0 → 1.27.0

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +201 -0
  3. data/README.md +11 -28
  4. data/_data/authors.yml +4 -3
  5. data/_data/backlog.yml +54 -1
  6. data/_data/features.yml +101 -61
  7. data/_data/feedback_types.yml +148 -0
  8. data/_data/i18n/languages.yml +36 -0
  9. data/_data/navigation/README.md +1 -1
  10. data/_data/theme-manifest.yml +0 -2
  11. data/_data/ui-text.yml +36 -246
  12. data/_includes/README.md +4 -0
  13. data/_includes/components/README.md +1 -0
  14. data/_includes/components/author-avatar-url.html +4 -2
  15. data/_includes/components/env-switcher.html +3 -1
  16. data/_includes/components/language-toggle.html +81 -0
  17. data/_includes/components/page-feedback.html +252 -0
  18. data/_includes/components/search-modal.html +2 -2
  19. data/_includes/components/shortcuts-modal.html +1 -1
  20. data/_includes/components/translation-notice.html +27 -0
  21. data/_includes/content/intro.html +35 -76
  22. data/_includes/core/console-capture.html +89 -0
  23. data/_includes/core/footer.html +9 -4
  24. data/_includes/core/head.html +13 -0
  25. data/_includes/core/header.html +9 -4
  26. data/_includes/core/hreflang.html +33 -0
  27. data/_includes/core/i18n.html +36 -0
  28. data/_includes/navigation/breadcrumbs.html +1 -1
  29. data/_includes/navigation/navbar.html +5 -4
  30. data/_includes/navigation/sidebar-right.html +3 -2
  31. data/_includes/navigation/unified-drawer.html +1 -1
  32. data/_layouts/article.html +7 -1
  33. data/_layouts/default.html +5 -3
  34. data/_layouts/news.html +4 -2
  35. data/_layouts/root.html +17 -8
  36. data/_layouts/section.html +4 -2
  37. data/_sass/components/_page-feedback.scss +276 -0
  38. data/_sass/core/_docs-layout.scss +2 -78
  39. data/_sass/core/_obsidian.scss +9 -1
  40. data/_sass/layouts/_navbar-extras.scss +6 -1
  41. data/_sass/tokens/_layers.scss +4 -0
  42. data/assets/css/main.scss +1 -0
  43. data/assets/js/obsidian-graph.js +5 -1
  44. data/assets/js/page-feedback.js +660 -0
  45. data/scripts/README.md +20 -26
  46. data/scripts/bin/audit-consumer +1 -1
  47. data/scripts/bin/manifest +0 -1
  48. data/scripts/bin/sync-plugins +0 -1
  49. data/scripts/dev/rasterize-svg.js +65 -0
  50. data/scripts/features/generate-preview-images +49 -1390
  51. data/scripts/features/install-preview-generator +55 -33
  52. data/scripts/install/README.md +9 -20
  53. data/scripts/install/ai/prompts/wizard.system.md +8 -17
  54. data/scripts/lib/README.md +1 -5
  55. data/scripts/lib/install/deploy/README.md +3 -9
  56. data/scripts/lib/preview_generator.py +2261 -1341
  57. data/scripts/translate.rb +1114 -0
  58. metadata +14 -4
  59. data/_data/prompts.yml +0 -302
  60. data/_plugins/preview_image_generator.rb +0 -351
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ffe866835e858107f670f29086f904914d21bf1159d8c6eb3cbd138f79caf64
4
- data.tar.gz: d26f27d6460136cc9f2da67da26523721b52b0e7525e0811498910215e2f29e2
3
+ metadata.gz: 3cb4259aa073fce4885f3d87ae9e4d7227b6580eba6599c270b0a98660ba52a8
4
+ data.tar.gz: 1606cb3f5fe102133fccf84ba7e7f11d3338695b41c1f546f15a4c775b956834
5
5
  SHA512:
6
- metadata.gz: 50038606f12260b1382fceee13299e6f8a9ca0b08b00ba18e285ed88ee762fd425e853d6fde39e8c9f72f8b345f841b04b29a3e4b095a89c36f01dc4d267d036
7
- data.tar.gz: e2e2764ca02d2d10250c768beb66ca7b7ba44c60b22e1852f3993f245080b5b2d3ad532245b33e394a078ae912cc60b28b33ee9fb23403194a1e75183841d925
6
+ metadata.gz: 20b1f33db10f4dde3b0ee980cd481405fc166c765f3ba9c2d740a448aeed77f8aa08f017570d33c8329330009499b4629243e6ea35da3fd635ee87025eae541d
7
+ data.tar.gz: e7a0a830ea658d6a798ac53001535e849853f177be6e295524289d1e8a41ccb734964ee7d9ce7e85c6811e9409c27c6e922a0c631a26ea63c971a83c4769cfd3
data/CHANGELOG.md CHANGED
@@ -5,6 +5,207 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.27.0](https://github.com/bamr87/zer0-mistakes/compare/v1.26.0...v1.27.0) (2026-07-22)
9
+
10
+
11
+ ### Features
12
+
13
+ * **analytics:** wire posthog.html into head.html ([#317](https://github.com/bamr87/zer0-mistakes/issues/317)) ([7977fe1](https://github.com/bamr87/zer0-mistakes/commit/7977fe189dec3b62eb9779feac56ec27e513f2c3))
14
+ * **article:** show_hero front-matter flag opts standard posts into the hero image ([#309](https://github.com/bamr87/zer0-mistakes/issues/309)) ([6344473](https://github.com/bamr87/zer0-mistakes/commit/6344473c14c613825ab7ac9083b87f17a2a1e858))
15
+ * **i18n:** AI-generated multilingual support with language toggle ([#316](https://github.com/bamr87/zer0-mistakes/issues/316)) ([72b2ab6](https://github.com/bamr87/zer0-mistakes/commit/72b2ab6980742e26305a22e3aff535f465ade084))
16
+ * **scripts:** Claude-orchestrated preview images — Claude analyzes & reviews, image models render ([#296](https://github.com/bamr87/zer0-mistakes/issues/296)) ([acac205](https://github.com/bamr87/zer0-mistakes/commit/acac2051ec79a81c04efb1af76fb4031e106a852))
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+ * **a11y:** keep a single <main> landmark per page ([#310](https://github.com/bamr87/zer0-mistakes/issues/310)) ([fae920e](https://github.com/bamr87/zer0-mistakes/commit/fae920eb5c60b5e792e9842c9b112bd5eb60e391)), closes [#299](https://github.com/bamr87/zer0-mistakes/issues/299)
22
+ * **author:** build avatar path with relative_url, never protocol-relative ([#306](https://github.com/bamr87/zer0-mistakes/issues/306)) ([ac597d2](https://github.com/bamr87/zer0-mistakes/commit/ac597d2c029157bb47da5a336812f764a3946da4))
23
+ * **ci:** secret scan matches added lines only, not context/removals/hunk headers ([#301](https://github.com/bamr87/zer0-mistakes/issues/301)) ([1b7175d](https://github.com/bamr87/zer0-mistakes/commit/1b7175ddece3d95aefc406f3b59df682db9fd0f2))
24
+ * **includes:** gate Quick Links Dev row on is_production ([#308](https://github.com/bamr87/zer0-mistakes/issues/308)) ([03b6877](https://github.com/bamr87/zer0-mistakes/commit/03b687713b8552c6ceb6b2ab30ac8caea0d6632d))
25
+ * **obsidian:** graph reads OBSIDIAN_CONFIG.wikiIndexUrl that js-cdn.html emits ([#305](https://github.com/bamr87/zer0-mistakes/issues/305)) ([2875912](https://github.com/bamr87/zer0-mistakes/commit/28759128b7b352a054e642d153e5e38e16aa1e48))
26
+ * **sass:** stack left-side FABs to prevent obsidian/feedback overlap ([#289](https://github.com/bamr87/zer0-mistakes/issues/289)) ([6cc4596](https://github.com/bamr87/zer0-mistakes/commit/6cc4596dff28d164386a16a6637420f84b4571bf))
27
+ * **test:** repoint ZER0-003 to test_install_legacy_flags.sh after retirement ([#292](https://github.com/bamr87/zer0-mistakes/issues/292)) ([fd7a2ce](https://github.com/bamr87/zer0-mistakes/commit/fd7a2ce256e32d2f630bd82732227b54ba13d3dd))
28
+ * **theme:** apply relative_url to preview_path exactly once ([#307](https://github.com/bamr87/zer0-mistakes/issues/307)) ([012e577](https://github.com/bamr87/zer0-mistakes/commit/012e577fe3131e0be42f7d33a6f5161dc666cc81))
29
+
30
+ ## [1.26.0](https://github.com/bamr87/zer0-mistakes/compare/v1.25.0...v1.26.0) (2026-07-07)
31
+
32
+
33
+ ### Features
34
+
35
+ * **feedback:** runtime "Improve this page" capture → GitHub issue (logs + AI triage) ([#286](https://github.com/bamr87/zer0-mistakes/issues/286)) ([f7fb20d](https://github.com/bamr87/zer0-mistakes/commit/f7fb20df74c22df7eb823344121c60617f06c7b6))
36
+
37
+ ## [Unreleased]
38
+
39
+ ### Added
40
+
41
+ - **Multilingual support via AI-generated translations** (ZER0-078) — the
42
+ theme now serves alternate-language versions of the site without storing
43
+ hand-written translations in source. English under `pages/**` +
44
+ `_data/ui-text.yml` `en` is the only human-maintained language; a
45
+ build-time utility ([`scripts/translate.rb`](scripts/translate.rb),
46
+ Claude Code OAuth with API-key fallback, stdlib-only Ruby) generates the
47
+ alternates and the
48
+ [`translate.yml`](.github/workflows/translate.yml) workflow commits them
49
+ via PR — one large `mode=full` dispatch job for the initial conversion,
50
+ plus bounded incremental runs whenever English content changes on `main`:
51
+ - Generated artifacts: `fr/**` page files (plain Jekyll pages with
52
+ explicit `/fr<en-url>` permalinks — GitHub Pages safe-mode friendly, no
53
+ plugin required), `_data/i18n/<lang>.yml` UI strings, and
54
+ `_data/i18n/manifest.yml` (en URL → translations map + SHA-based
55
+ incremental change detection with pruning of deleted sources).
56
+ - Markdown safety by construction: per-line segment translation with
57
+ `⟦N⟧` masking of code, Liquid, wiki-links and URLs, placeholder
58
+ set-equality validation with one retry, code fences never sent.
59
+ - Frontend: navbar **language toggle**
60
+ ([`language-toggle.html`](_includes/components/language-toggle.html))
61
+ with per-page availability states and `localStorage` preference,
62
+ `hreflang` alternates in `<head>`, per-page `<html lang>`, and a
63
+ machine-translation disclosure banner linking back to the original.
64
+ - Refactor: UI-string lookup centralized in
65
+ [`core/i18n.html`](_includes/core/i18n.html) and made per-page-language
66
+ aware (cached chrome includes take a `lang` parameter so each language
67
+ gets its own `include_cached` entry); the hand-maintained es/fr/de/ar
68
+ blocks in `_data/ui-text.yml` were **removed** in favor of the
69
+ generated pipeline.
70
+ - Offline test suite `test/test_i18n.sh` (stub provider, no network),
71
+ registered as the `i18n` suite in `test_runner.sh`, plus the
72
+ `language-toggle` Playwright smoke spec; docs in
73
+ [`docs/systems/multilingual-translation.md`](docs/systems/multilingual-translation.md).
74
+ (evidence:
75
+ [`test/visual/evidence/language-toggle/`](test/visual/evidence/language-toggle/README.md)
76
+ and
77
+ [`test/visual/evidence/language-toggle-fr/`](test/visual/evidence/language-toggle-fr/README.md)
78
+ — toggle at 6 widths + generated French page with 0px overflow, code
79
+ blocks byte-identical)
80
+
81
+ - **`show_hero` front-matter flag** — a post of any `post_type` can now opt
82
+ its `preview:` image into the top-of-article hero with `show_hero: true`,
83
+ without being promoted to `featured`/`breaking` (layout width, sidebar,
84
+ typography, and the post-type badge keep their `post_type` defaults);
85
+ existing posts are unchanged by construction — the flag is falsy everywhere
86
+ it isn't set ([#303](https://github.com/bamr87/zer0-mistakes/issues/303)).
87
+ (evidence:
88
+ [`test/visual/evidence/show-hero/`](test/visual/evidence/show-hero/README.md)
89
+ — hero renders only on the opted-in demo post; whole-build before/after
90
+ diff: exactly 1 page differs)
91
+
92
+ - **Claude-orchestrated preview-image engine** (ZER0-004) — the three
93
+ divergent implementations (1,404-line Bash engine, drifted Python
94
+ duplicate, dead Jekyll plugin) are consolidated into ONE Python engine,
95
+ [`scripts/lib/preview_generator.py`](scripts/lib/preview_generator.py).
96
+ Claude directs; an image model renders:
97
+ - **Analyze** (`prompt_engine: claude`, default) — Claude reads each
98
+ article and writes a subject-specific art-direction brief, replacing the
99
+ generic template prompt that produced unrepresentative banners.
100
+ - **Produce** — the configured renderer executes the brief: `openai`
101
+ (gpt-image-2 / DALL-E, default), `xai` (grok-2-image), `stability`,
102
+ **`gemini` (new)** — or `local`, upgraded from a `.txt` stub to a real
103
+ deterministic SVG/PNG banner (sanitized, rasterized via `rsvg-convert` →
104
+ `inkscape` → `magick` → the new Playwright helper
105
+ [`scripts/dev/rasterize-svg.js`](scripts/dev/rasterize-svg.js)).
106
+ - **Review** (`review_engine: claude`, default) — Claude inspects the
107
+ rendered image with vision against the article and style; when it
108
+ misrepresents the subject or contains text artifacts, Claude writes a
109
+ corrected prompt and the engine regenerates once.
110
+ - Claude credential chain: `CLAUDE_CODE_OAUTH_TOKEN` (`claude setup-token`)
111
+ → `ANTHROPIC_AUTH_TOKEN` → `ANTHROPIC_API_KEY` → a logged-in `claude` CLI
112
+ (zero-setup for Claude Code users); orchestration degrades gracefully to
113
+ template prompts without one.
114
+ - New unit suite [`test/test_preview_generator.py`](test/test_preview_generator.py)
115
+ (83 tests, zero network) wired into `test_core.sh`.
116
+
117
+ ### Fixed
118
+
119
+ - **Obsidian graph loads its wiki index on project sites** — the full-graph
120
+ renderer (`assets/js/obsidian-graph.js`) now reads the baseurl-aware
121
+ `window.OBSIDIAN_CONFIG.wikiIndexUrl` that `js-cdn.html` emits (falling back
122
+ to the legacy `OBSIDIAN_WIKI_INDEX_URL` override, then the `<base>`-relative
123
+ path), instead of only the never-set legacy global — whose fallback dropped
124
+ the baseurl and 404'd the `wiki-index.json` fetch on GitHub Pages project
125
+ sites, leaving `/docs/obsidian/graph/` a "Failed to load graph data" alert
126
+ ([#294](https://github.com/bamr87/zer0-mistakes/issues/294)). (evidence:
127
+ [`test/visual/evidence/obsidian-graph-index/`](test/visual/evidence/obsidian-graph-index/README.md)
128
+ — wiki-index fetch 404 → 200, alert → rendered graph, on a baseurl'd build)
129
+
130
+ - **Quick Links no longer ships a dead `localhost:4000` Dev row to production
131
+ visitors** — the env-switcher's Development URL row (rendered in the
132
+ site-wide Settings offcanvas on every page) is now wrapped in
133
+ {% raw %}`{% unless is_production %}`{% endraw %}, using the same `env-detect.html` flag the card
134
+ already keys its badge on; serving locally with `JEKYLL_ENV=production`
135
+ still counts as dev context, so the row stays available for Docker workflows
136
+ ([#298](https://github.com/bamr87/zer0-mistakes/issues/298)). (evidence:
137
+ [`test/visual/evidence/env-switcher-prod/`](test/visual/evidence/env-switcher-prod/README.md)
138
+ — production Settings-chrome `localhost:4000` occurrences 5 → 0, Dev row
139
+ intact in development)
140
+ - **Author avatars never render as protocol-relative `//assets/…` URLs** —
141
+ `author-avatar-url.html` now builds the relative-path branch in a capture,
142
+ collapses doubled slashes, and applies `relative_url` exactly once, instead
143
+ of the manual `{{ site.baseurl }}/{{ site.public_folder }}{{ avatar }}`
144
+ concatenation that produced `src="//assets/…"` (a URL browsers resolve
145
+ against a host named `assets`) on consumer sites where `public_folder` is
146
+ unset or carries a leading slash
147
+ ([#297](https://github.com/bamr87/zer0-mistakes/issues/297)). (evidence:
148
+ [`test/visual/evidence/author-avatar-url/`](test/visual/evidence/author-avatar-url/README.md)
149
+ — 4 protocol-relative avatars → 0, all avatars loading, on a misconfigured
150
+ consumer build)
151
+
152
+ - **Intro hero banner renders on project sites** — `content/intro.html` now
153
+ applies `relative_url` to the banner image exactly once (in the
154
+ `preview_path` assignment logic), instead of a second time at the point of
155
+ use, which doubled the baseurl segment on any site with a non-empty
156
+ `baseurl` (`url('/reponame/reponame/assets/…')` → 404 → gradient-only hero)
157
+ and mangled absolute preview URLs
158
+ ([#293](https://github.com/bamr87/zer0-mistakes/issues/293)). (evidence:
159
+ [`test/visual/evidence/intro-banner-baseurl/`](test/visual/evidence/intro-banner-baseurl/README.md)
160
+ — background fetch 404 → 200 on both preview branches of a baseurl'd build)
161
+
162
+ - **Preview-image config keys `enabled`, `assets_prefix`, `auto_prefix` and
163
+ `collections` are now honored by the generator** (the Bash engine ignored
164
+ them), and front-matter `preview:` updates are scoped to the front-matter
165
+ block only — the previous file-wide `sed` could corrupt body lines starting
166
+ with `preview:`. External-URL previews are no longer silently regenerated,
167
+ and a configured model from the wrong vendor family falls back to the
168
+ provider default instead of a guaranteed API error.
169
+
170
+ - **Left-side FAB overlap** — the Obsidian local-graph button and the
171
+ page-feedback "Improve this page" button were both positioned at
172
+ `bottom: 1rem; left: 1rem` and completely overlapped each other. The
173
+ Obsidian FAB is now at slot 2 (`bottom: offset + size + gap`), stacking
174
+ above the feedback FAB — the same pattern the TOC FAB uses above
175
+ back-to-top on the right side. The docs-sidebar restore-mode FAB was
176
+ also offset to slot 2 so it cannot overlap the feedback FAB on mobile.
177
+ Closes #288. (evidence:
178
+ [`test/visual/evidence/fab-stack/`](test/visual/evidence/fab-stack/README.md)
179
+ — feedback↔obsidian FAB overlap 3136px² → 0; regression test
180
+ [`test/visual/features/fab-stack.spec.js`](test/visual/features/fab-stack.spec.js)).
181
+
182
+ ### Changed
183
+
184
+ - **Preview-image generation is now Claude-orchestrated by default**
185
+ (`prompt_engine: claude` + `review_engine: claude`; disable with
186
+ `--prompt-engine template --review none`). The renderer default stays
187
+ `openai`. `scripts/features/generate-preview-images` is now a thin wrapper
188
+ delegating to the Python engine (full CLI flag surface preserved;
189
+ `rake preview:*` and the VS Code tasks work unchanged).
190
+ - **CI test tiering** — the PR-blocking Playwright gate is now the new
191
+ `critical` project (118 `@critical`-tagged, user-facing tests: navigation,
192
+ search, mobile survival, theming baseline, security) instead of the full
193
+ 331-test `smoke` tier; the full smoke tier, the complete shell-suite
194
+ matrix, and the 9-skin pixel snapshots moved to a nightly workflow
195
+ (`nightly-extended.yml`) that files a sticky issue on failure instead of
196
+ blocking PRs. Install/deploy/site-generation shell suites run on PRs only
197
+ when install-related paths change (always nightly).
198
+
199
+ ### Added
200
+
201
+ - **Weekly agentic UI/UX audit** (`ui-audit.yml`) — a deterministic
202
+ Playwright sweep (`test/ui-audit/sweep.mjs`: screenshots, axe WCAG 2.1 AA,
203
+ console errors, overflow, broken internal links across critical routes ×
204
+ 3 viewports) interpreted by a read-only Claude Code agent
205
+ (`.claude/agents/ui-auditor.md`) against the component contract in
206
+ `docs/architecture/ui-components.md`; findings are filed as a
207
+ `source:ui-audit` issue feeding the continuous-evolution loop.
208
+
8
209
  ## [1.25.0](https://github.com/bamr87/zer0-mistakes/compare/v1.24.0...v1.25.0) (2026-07-03)
9
210
 
10
211
 
data/README.md CHANGED
@@ -44,14 +44,7 @@ hero_image: /assets/images/wizard-on-journey.png
44
44
  excerpt: "AI-native Jekyll theme for GitHub Pages — multi-agent ready (Copilot, Codex, Cursor, Claude), AI-powered install & preview images, AIEO-optimized, with Docker-first development and 43 documented features"
45
45
  ---
46
46
 
47
- [![pages-build-deployment](https://github.com/bamr87/zer0-mistakes/actions/workflows/pages/pages-build-deployment/badge.svg)](https://github.com/bamr87/zer0-mistakes/actions/workflows/pages/pages-build-deployment)
48
- [![Gem Version](https://badge.fury.io/rb/jekyll-theme-zer0.svg)](https://badge.fury.io/rb/jekyll-theme-zer0)
49
- [![CI](https://github.com/bamr87/zer0-mistakes/actions/workflows/ci.yml/badge.svg)](https://github.com/bamr87/zer0-mistakes/actions/workflows/ci.yml)
50
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
51
- [![Docker](https://img.shields.io/badge/docker-ready-blue.svg)](https://github.com/bamr87/zer0-mistakes/blob/main/docker-compose.yml)
52
- [![Bootstrap](https://img.shields.io/badge/Bootstrap-5.3.3-purple.svg)](https://getbootstrap.com/)
53
- [![AI-Native](https://img.shields.io/badge/AI--Native-Copilot%20%7C%20Codex%20%7C%20Cursor%20%7C%20Claude-8A2BE2)](AGENTS.md)
54
- [![AIEO](https://img.shields.io/badge/AIEO-Optimized-ff69b4)](#-aieo-optimized--built-for-ai-citation)
47
+ [![pages-build-deployment](https://github.com/bamr87/zer0-mistakes/actions/workflows/pages/pages-build-deployment/badge.svg)](https://github.com/bamr87/zer0-mistakes/actions/workflows/pages/pages-build-deployment) [![Gem Version](https://badge.fury.io/rb/jekyll-theme-zer0.svg)](https://badge.fury.io/rb/jekyll-theme-zer0) [![CI](https://github.com/bamr87/zer0-mistakes/actions/workflows/ci.yml/badge.svg)](https://github.com/bamr87/zer0-mistakes/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Docker](https://img.shields.io/badge/docker-ready-blue.svg)](https://github.com/bamr87/zer0-mistakes/blob/main/docker-compose.yml) [![Bootstrap](https://img.shields.io/badge/Bootstrap-5.3.3-purple.svg)](https://getbootstrap.com/) [![AI-Native](https://img.shields.io/badge/AI--Native-Copilot%20%7C%20Codex%20%7C%20Cursor%20%7C%20Claude-8A2BE2)](AGENTS.md) [![AIEO](https://img.shields.io/badge/AIEO-Optimized-ff69b4)](#-aieo-optimized--built-for-ai-citation)
55
48
 
56
49
  # zer0-mistakes
57
50
 
@@ -155,9 +148,7 @@ The installer auto-detects your operating system, sets up Docker, downloads the
155
148
 
156
149
  ## 🎯 Bare-Minimum Starter (3 files, zero install)
157
150
 
158
- Don't want to run the installer? You can publish a working site to GitHub
159
- Pages with **just three files** in your repo. The remote theme provides every
160
- layout, style, and even an in-browser configuration wizard.
151
+ Don't want to run the installer? You can publish a working site to GitHub Pages with **just three files** in your repo. The remote theme provides every layout, style, and even an in-browser configuration wizard.
161
152
 
162
153
  ```text
163
154
  my-site/
@@ -200,11 +191,7 @@ title: Home
200
191
  # Welcome to my site
201
192
  ```
202
193
 
203
- Push to a GitHub Pages–enabled repository and visit your site. Until you set
204
- `site_configured: true`, the home page renders the **welcome layout** — a hero
205
- card and a full in-browser wizard that generates a personalised `_config.yml`
206
- you can download. Flip the flag (or fill in `title`/`founder`/`email`) and your
207
- own content takes over.
194
+ Push to a GitHub Pages–enabled repository and visit your site. Until you set `site_configured: true`, the home page renders the **welcome layout** — a hero card and a full in-browser wizard that generates a personalised `_config.yml` you can download. Flip the flag (or fill in `title`/`founder`/`email`) and your own content takes over.
208
195
 
209
196
  ---
210
197
 
@@ -248,7 +235,7 @@ zer0-mistakes treats AI as core infrastructure across **install → author → b
248
235
  | **File-scoped instructions** | `applyTo:` globs auto-load guidance for `_layouts/`, `_includes/`, `scripts/`, `test/`, `docs/`, version files | [`.github/instructions/`](.github/instructions/) |
249
236
  | **Reusable agent prompts** | `commit-publish`, `frontmatter-maintainer`, `seed` (full-rebuild blueprint) | [`.github/prompts/`](.github/prompts/) |
250
237
  | **Cursor slash-commands** | Mirrors prompts as `/commit-publish`, `/frontend-run-improve` | [`.cursor/commands/`](.cursor/commands/) |
251
- | **AI preview images** | Jekyll plugin + script generate OpenAI/DALL·E images for posts missing previews | [`_plugins/preview_image_generator.rb`](_plugins/preview_image_generator.rb), [`scripts/generate-preview-images.sh`](scripts/generate-preview-images.sh) |
238
+ | **AI preview images** | Python engine + script generate OpenAI/DALL·E images for posts missing previews | [`scripts/lib/preview_generator.py`](scripts/lib/preview_generator.py), [`scripts/generate-preview-images.sh`](scripts/generate-preview-images.sh) |
252
239
  | **AI release pipeline** | Conventional-commit analyzer chooses MAJOR/MINOR/PATCH, writes CHANGELOG, tags & publishes | [`scripts/analyze-commits.sh`](scripts/analyze-commits.sh), [`scripts/bin/release`](scripts/bin/release) |
253
240
  | **AIEO content layer** | `SoftwareApplication`, `WebPage`, `FAQPage`, `Person` JSON-LD; glossary; FAQ; dated roadmap | [See AIEO section](#-aieo-optimized--built-for-ai-citation) |
254
241
 
@@ -303,7 +290,7 @@ zer0-mistakes is a layered system: your content (Markdown + YAML) flows through
303
290
  | **Development** | Docker | Cross-platform consistency |
304
291
  | **Templates** | Liquid | Dynamic content rendering |
305
292
  | **AI Agents** | Copilot · Codex · Cursor · Claude Code · Aider · Jules · Continue | Multi-tool agentic development via [`AGENTS.md`](AGENTS.md) + `.github/instructions/` |
306
- | **AI Content** | OpenAI Images API | AI-generated preview images via [`_plugins/preview_image_generator.rb`](_plugins/preview_image_generator.rb) |
293
+ | **AI Content** | OpenAI Images API | AI-generated preview images via [`scripts/lib/preview_generator.py`](scripts/lib/preview_generator.py) |
307
294
  | **AI Automation** | Conventional-commit analyzer | Auto semantic versioning + changelog ([`scripts/analyze-commits.sh`](scripts/analyze-commits.sh)) |
308
295
  | **AIEO** | JSON-LD + FAQ + Glossary schema | Optimized for AI citation and retrieval |
309
296
  | **Analytics** | PostHog | Privacy-first tracking |
@@ -430,8 +417,7 @@ GDPR/CCPA compliant PostHog integration with granular consent: it respects Do No
430
417
 
431
418
  ### 🧠 Obsidian Vault Integration
432
419
 
433
- Edit your content as an [Obsidian](https://obsidian.md) vault — same files,
434
- same git history, identical rendering on the published site:
420
+ Edit your content as an [Obsidian](https://obsidian.md) vault — same files, same git history, identical rendering on the published site:
435
421
 
436
422
  - **Open repo as a vault**: shared `.obsidian/` config commits with the repo.
437
423
  - **Wiki-links** `[[Page Title]]` and aliases `[[Page|Alias]]` resolve to permalinks.
@@ -440,17 +426,14 @@ same git history, identical rendering on the published site:
440
426
  - **Backlinks panel** auto-renders on every note (and on any page with `backlinks: true`).
441
427
  - **Inline tags** `#topic` link to the tag index, hierarchical tags supported.
442
428
  - **Zero plugin requirements**: works on the default GitHub Pages
443
- `remote_theme` build via a client-side resolver
444
- (`assets/js/obsidian-wiki-links.js`) backed by a Liquid-generated
445
- `assets/data/wiki-index.json`.
429
+ `remote_theme` build via a client-side resolver (`assets/js/obsidian-wiki-links.js`) backed by a Liquid-generated `assets/data/wiki-index.json`.
446
430
 
447
431
  ```bash
448
432
  # Open the repo root as an Obsidian vault, edit, then commit & push
449
433
  git commit -am "note: today's thinking" && git push
450
434
  ```
451
435
 
452
- Read the [Obsidian docs](pages/_docs/obsidian/) for setup, syntax reference,
453
- authoring workflow, and troubleshooting.
436
+ Read the [Obsidian docs](pages/_docs/obsidian/) for setup, syntax reference, authoring workflow, and troubleshooting.
454
437
 
455
438
  ### 📓 Jupyter Notebook Support
456
439
 
@@ -646,8 +629,8 @@ git commit -m "feat: add new component"
646
629
  ### Testing Commands
647
630
 
648
631
  ```bash
649
- # Quick validation
650
- ./test/test_installation.sh
632
+ # Quick validation (preflight)
633
+ ./scripts/validate --quick
651
634
 
652
635
  # Full test suite
653
636
  ./test/test_runner.sh --verbose
@@ -655,7 +638,7 @@ git commit -m "feat: add new component"
655
638
  # Docker-specific tests
656
639
  ./test/test_deployment.sh
657
640
 
658
- # Frontend smoke tests (Playwright; starts Jekyll on :4011 unless BASE_URL is set)
641
+ # Frontend smoke tests (Playwright; starts Jekyll on :4000 unless BASE_URL is set)
659
642
  npm run test:smoke
660
643
  # Pixel regression (skin homepage screenshots; baselines committed for Linux)
661
644
  npm run test:snapshots
data/_data/authors.yml CHANGED
@@ -47,11 +47,12 @@
47
47
  # generator. When a post sets `author: <this key>`, these
48
48
  # values WIN over _config.yml › preview_images for that
49
49
  # post's banner, giving each AI author a distinct look.
50
- # (scripts/features/generate-preview-images and
51
- # scripts/lib/preview_generator.py read this block.)
50
+ # (Read by the consolidated engine
51
+ # scripts/lib/preview_generator.py every provider.)
52
52
  # style: .. Art-style prompt fragment (overrides preview_images.style).
53
53
  # style_modifiers: .. Extra modifiers (overrides preview_images.style_modifiers).
54
- # size/quality/model: Optional generator overrides (bash generator only).
54
+ # size/quality/model: Optional generator overrides (all providers; a model
55
+ # from another vendor family falls back to the default).
55
56
 
56
57
  default:
57
58
  name: "Zer0-Mistakes Team"
data/_data/backlog.yml CHANGED
@@ -63,7 +63,7 @@
63
63
  meta:
64
64
  title: "zer0-mistakes Backlog"
65
65
  updated: 2026-06-29
66
- next_id: 33
66
+ next_id: 34
67
67
 
68
68
  tasks:
69
69
  # --- Housekeeping (seeded so the loop has work on day one) ------------------
@@ -863,3 +863,56 @@ tasks:
863
863
  links: { issue: 241, pr: 253, roadmap: null }
864
864
  created: 2026-06-29
865
865
  updated: 2026-06-29
866
+
867
+ - id: T-033
868
+ title: "Retire legacy test_installation.sh after equivalence audit against the installer harness"
869
+ status: open
870
+ priority: P2
871
+ area: tests
872
+ risk: standard
873
+ effort: M
874
+ source: user
875
+ route: test-author
876
+ summary: >-
877
+ test_installation.sh (~1,000 lines, "legacy install.sh CLI args") predates the
878
+ modern test_installer.sh + test_install_*.sh harness and largely overlaps it.
879
+ Audit each of its scenarios against the harness, port anything genuinely
880
+ uncovered into test_install_*.sh, then delete the legacy suite and remove the
881
+ `installation` routing from test_runner.sh, ci.yml, and nightly-extended.yml.
882
+ Until then it runs nightly and on install-path PRs only (2026-07 CI tiering).
883
+ acceptance:
884
+ - "Every test_installation.sh scenario is mapped to a harness equivalent or ported."
885
+ - "test_installation.sh deleted; test_runner.sh no longer routes an `installation` suite."
886
+ - "ci.yml and nightly-extended.yml suite lists updated; docs (test/README.md) updated."
887
+ - "Nightly extended run green after removal."
888
+ links: { issue: null, pr: null, roadmap: null }
889
+ created: 2026-07-06
890
+ updated: 2026-07-06
891
+ - id: T-034
892
+ title: "Remove the dead preview_image_generator.rb Jekyll plugin and its test surface"
893
+ status: done
894
+ priority: P3
895
+ area: infra
896
+ risk: standard
897
+ effort: M
898
+ source: user
899
+ route: code-fixer
900
+ summary: >-
901
+ _plugins/preview_image_generator.rb never loads anywhere (the github-pages gem
902
+ forces safe mode + a randomized plugins_dir), and the consolidated Python engine
903
+ (scripts/lib/preview_generator.py, ZER0-004) now owns all generation logic while
904
+ _includes/components/preview-image.html + _includes/content/seo.html cover
905
+ rendering in pure Liquid. Remove the plugin, its PreviewImageGeneratorTest half
906
+ of test/test_plugins.rb, the consumer fixture
907
+ test/fixtures/consumer-remote/_plugins/preview_image_generator.rb, and its
908
+ entries in REQUIRED_PLUGIN_FILES (scripts/bin/audit-consumer, sync-plugins,
909
+ manifest) and the installer SOURCE/DEST_FILES. Touches CODEOWNERS-owned
910
+ _plugins/ and scripts/bin/ paths, so this is a human-review PR.
911
+ acceptance:
912
+ - "_plugins/preview_image_generator.rb deleted; docs no longer advertise its Liquid filters."
913
+ - "test_plugins.rb keeps its content-statistics coverage; preview plugin specs removed."
914
+ - "audit-consumer/sync-plugins/manifest lists and the consumer fixture updated; test_audit.sh green."
915
+ - "install-preview-generator no longer ships the plugin; installer tests green."
916
+ links: { issue: 302, pr: null, roadmap: null }
917
+ created: 2026-07-12
918
+ updated: 2026-07-16