jekyll-theme-zer0 1.21.0 → 1.23.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +57 -0
- data/_data/ai.yml +10 -0
- data/_data/backlog.yml +173 -23
- data/_data/navigation/docs.yml +4 -0
- data/_data/theme_backgrounds.yml +24 -0
- data/_includes/components/component-showcase.html +83 -14
- data/_includes/components/js-cdn.html +10 -2
- data/_includes/components/post-card.html +18 -4
- data/_includes/components/search-modal.html +28 -4
- data/_includes/content/backlinks.html +47 -18
- data/_includes/content/giscus.html +30 -44
- data/_includes/core/color-mode-init.html +35 -0
- data/_includes/core/footer-fabs.html +5 -2
- data/_includes/core/head.html +9 -0
- data/_includes/core/tokens-inline.html +5 -0
- data/_includes/navigation/local-graph-fab.html +1 -1
- data/_includes/navigation/local-graph.html +4 -3
- data/_includes/navigation/section-sidebar.html +10 -3
- data/_includes/obsidian/full-graph.html +7 -5
- data/_layouts/article.html +23 -6
- data/_layouts/author.html +22 -1
- data/_layouts/root.html +15 -1
- data/_plugins/obsidian_links.rb +84 -15
- data/_sass/core/_obsidian.scss +59 -8
- data/assets/data/wiki-index.json +50 -3
- data/assets/js/obsidian-graph.js +66 -21
- data/assets/js/obsidian-local-graph.js +125 -32
- data/assets/js/obsidian-wiki-links.js +118 -21
- data/assets/js/search-modal.js +45 -9
- data/scripts/bin/giscus-discussions +509 -0
- data/scripts/bin/validate +1 -0
- data/scripts/ci/classify_changes.py +129 -0
- data/scripts/issues/dispatch.py +478 -0
- data/scripts/issues/test_verify_close.py +118 -0
- data/scripts/issues/triage.py +1046 -0
- data/scripts/issues/verify_close.py +179 -0
- metadata +10 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 73435219bd711a7e8485d895f8e07156804569313c0213be215495e994a72c6b
|
|
4
|
+
data.tar.gz: ff65b97cd663f7cacd18757aad849725c18c9e036563e72bff8185e894dd8c47
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 94a2e3468724372bbf8478f3615b3195a6182a0775dd4ab45be19d9b0a57cdb0af7e85d7d990faa2456cbdc66b23e58b71af7a3fa487fd9e021ffb6175f4edd3
|
|
7
|
+
data.tar.gz: 1bbacd96a15484f01b193394addcc354afb9b35364d9eedf388b0dfce1dd24dafefdc9b7fee46fb1862e5212a50bddb325e3fbe0c8c0808bc254527b2a2e86b7
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,63 @@ 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.23.0](https://github.com/bamr87/zer0-mistakes/compare/v1.22.0...v1.23.0) (2026-06-30)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **automation:** issue-triage→PR autopilot (off by default) ([#243](https://github.com/bamr87/zer0-mistakes/issues/243)) ([229e076](https://github.com/bamr87/zer0-mistakes/commit/229e07654915a9a0e401b30796c4f6c078eda926))
|
|
14
|
+
* **automation:** verify-and-close lane — autopilot closes human issues fixed on main when CI is green ([#247](https://github.com/bamr87/zer0-mistakes/issues/247)) ([7cc7cb0](https://github.com/bamr87/zer0-mistakes/commit/7cc7cb0cdada7f64d59f46c2f4c3a7e88afbde6b))
|
|
15
|
+
* **layouts:** add color_mode_default config knob with FOUC prevention ([#253](https://github.com/bamr87/zer0-mistakes/issues/253)) ([55bee97](https://github.com/bamr87/zer0-mistakes/commit/55bee970686c10a08aeed15bff43c3b66b5293e7))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* **ci:** make claude-run truly OAuth-first — drop API key whenever an OAuth token is set ([#248](https://github.com/bamr87/zer0-mistakes/issues/248)) ([d2b44d2](https://github.com/bamr87/zer0-mistakes/commit/d2b44d2766f5c8543f4c5d8ddb79015e726f88fd))
|
|
21
|
+
* **ci:** pass -R to gh pr view in the self-repair opt-in gate ([#260](https://github.com/bamr87/zer0-mistakes/issues/260)) ([67d67d7](https://github.com/bamr87/zer0-mistakes/commit/67d67d74146366afe6d495f529ba2c86a4513e18))
|
|
22
|
+
* **includes:** existence-guard component-showcase demo links ([#219](https://github.com/bamr87/zer0-mistakes/issues/219)) ([#256](https://github.com/bamr87/zer0-mistakes/issues/256)) ([ef15e79](https://github.com/bamr87/zer0-mistakes/commit/ef15e79dc64db0dc7e721ca10bb7c1e826612473))
|
|
23
|
+
* **layouts:** existence-gate /authors/ breadcrumb in author.html for remote-theme consumers ([#252](https://github.com/bamr87/zer0-mistakes/issues/252)) ([cae21a7](https://github.com/bamr87/zer0-mistakes/commit/cae21a7107b1875ac876f9e30cf71590ac7b0cc5))
|
|
24
|
+
* **search:** existence-gate search modal form action for remote-theme consumers ([#257](https://github.com/bamr87/zer0-mistakes/issues/257)) ([b915c4d](https://github.com/bamr87/zer0-mistakes/commit/b915c4dead5eff3d6a2986720ebacdcf2bed5e33))
|
|
25
|
+
* **skins:** map dark + contrast skins to their background assets ([#245](https://github.com/bamr87/zer0-mistakes/issues/245)) ([fb8808e](https://github.com/bamr87/zer0-mistakes/commit/fb8808e5ec754785b8239b01bccfab99569b70fa)), closes [#240](https://github.com/bamr87/zer0-mistakes/issues/240)
|
|
26
|
+
|
|
27
|
+
## [Unreleased]
|
|
28
|
+
|
|
29
|
+
### Bug Fixes
|
|
30
|
+
|
|
31
|
+
* **includes:** existence-guard component-showcase demo links — breadcrumb and list-group items now render as real links when the target page exists in the build (`/docs/`, `/docs/customization/`, `/categories/`, `/tags/`) and as plain text when absent; removes inert `href="#"` / `onclick="return false;"` workaround ([#219](https://github.com/bamr87/zer0-mistakes/issues/219)) (evidence: [`test/visual/evidence/component-showcase/`](test/visual/evidence/component-showcase/README.md))
|
|
32
|
+
|
|
33
|
+
### Tests
|
|
34
|
+
|
|
35
|
+
* **navigation:** regression spec for section-sidebar /tags/ existence gate — asserts "Browse All Tags" and "View All Tags" links only render when /tags/ page is present in the build (issue #218, `test/visual/section-sidebar-tags-gate.spec.js`)
|
|
36
|
+
### Features
|
|
37
|
+
|
|
38
|
+
- **color_mode_default config knob** — new `color_mode_default` setting (`dark` | `light` | `auto`, default `auto`) in `_config.yml` controls Bootstrap's `data-bs-theme` both server-side (in `_layouts/root.html`) and client-side. An early inline script (`_includes/core/color-mode-init.html`, loaded before Bootstrap CSS) applies the correct theme before any `[data-bs-theme]` selector is evaluated, preventing FOUC. `localStorage["theme"]` (the Appearance panel override) always wins over the config default. `auto` follows `prefers-color-scheme` — backward-compatible with the previous behaviour. (evidence: [`test/visual/evidence/color-mode-default/`](test/visual/evidence/color-mode-default/README.md))
|
|
39
|
+
### Bug Fixes
|
|
40
|
+
|
|
41
|
+
* **search:** existence-gate search modal form action to `/sitemap/` only when that page is present in the build; falls back to `#` (safe no-op) for remote-theme Pages consumers without a `/sitemap/` stub (closes [#202](https://github.com/bamr87/zer0-mistakes/issues/202))
|
|
42
|
+
* **layouts:** existence-gate `/authors/` breadcrumb link in author.html for remote-theme consumers ([#204](https://github.com/bamr87/zer0-mistakes/issues/204))
|
|
43
|
+
### Tests
|
|
44
|
+
|
|
45
|
+
* **tests:** add negative-path smoke tests for AI chat render guard — asserts FAB/panel are absent when `proxy_ready: false` and no `api_key` is set (closes #168)
|
|
46
|
+
|
|
47
|
+
## [1.22.0](https://github.com/bamr87/zer0-mistakes/compare/v1.21.0...v1.22.0) (2026-06-26)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### Features
|
|
51
|
+
|
|
52
|
+
* **ci:** autonomous CI self-repair loop (pipeline Phase 6) ([#237](https://github.com/bamr87/zer0-mistakes/issues/237)) ([a43db45](https://github.com/bamr87/zer0-mistakes/commit/a43db45eae2da2fcf141ac959d0268dd7e6a52bd))
|
|
53
|
+
* **comments:** enable Giscus + wire Claude Code conversation building ([#214](https://github.com/bamr87/zer0-mistakes/issues/214)) ([fef60a5](https://github.com/bamr87/zer0-mistakes/commit/fef60a5cf78697e94c40f098c336112fe5cdd845))
|
|
54
|
+
* **obsidian:** interactive callouts, parity fixes, a11y + vendored graph ([#200](https://github.com/bamr87/zer0-mistakes/issues/200)) ([affbcd6](https://github.com/bamr87/zer0-mistakes/commit/affbcd62b3f7023457195d5137d5ace2a3751367))
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
### Bug Fixes
|
|
58
|
+
|
|
59
|
+
* **ci:** enable auto-merge via GraphQL (no git checkout) + graceful no-op ([#232](https://github.com/bamr87/zer0-mistakes/issues/232)) ([4c8c74c](https://github.com/bamr87/zer0-mistakes/commit/4c8c74cfb0775feda9103b379ebcecc4874d517f))
|
|
60
|
+
* **includes:** existence-gate category badge links for remote-theme consumers ([#235](https://github.com/bamr87/zer0-mistakes/issues/235)) ([16ed0a8](https://github.com/bamr87/zer0-mistakes/commit/16ed0a8c77f4cd66b98918a66d00133fa90f4457))
|
|
61
|
+
* **includes:** make component-showcase demo links inert to avoid consumer 404s ([#236](https://github.com/bamr87/zer0-mistakes/issues/236)) ([e96646b](https://github.com/bamr87/zer0-mistakes/commit/e96646b196c2931fc240411ded23184a1e01c8f5))
|
|
62
|
+
* **navigation:** existence-gate the section-sidebar /tags/ links ([#231](https://github.com/bamr87/zer0-mistakes/issues/231)) ([a02b062](https://github.com/bamr87/zer0-mistakes/commit/a02b0622a4f16dfea375629ad347891861283fe3))
|
|
63
|
+
* **search:** degrade search UI gracefully when /search.json is absent ([#234](https://github.com/bamr87/zer0-mistakes/issues/234)) ([f3a718d](https://github.com/bamr87/zer0-mistakes/commit/f3a718d1a9219bee92e2d1a46d2e32c870efb624))
|
|
64
|
+
|
|
8
65
|
## [1.21.0](https://github.com/bamr87/zer0-mistakes/compare/v1.20.2...v1.21.0) (2026-06-26)
|
|
9
66
|
|
|
10
67
|
|
data/_data/ai.yml
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# _data/ai.yml — one place the AI model is configured for zer0-mistakes agents
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Read by .github/actions/claude-run (the issue-autopilot's AI step). Change the
|
|
5
|
+
# model here and every autopilot agent call uses it. Auth is NOT here — it comes
|
|
6
|
+
# from the CLAUDE_CODE_OAUTH_TOKEN (preferred) or ANTHROPIC_API_KEY secret.
|
|
7
|
+
# =============================================================================
|
|
8
|
+
provider: anthropic
|
|
9
|
+
model: claude-opus-4-8
|
|
10
|
+
max_tokens: 8000
|
data/_data/backlog.yml
CHANGED
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
|
|
63
63
|
meta:
|
|
64
64
|
title: "zer0-mistakes Backlog"
|
|
65
|
-
updated: 2026-06-
|
|
66
|
-
next_id:
|
|
65
|
+
updated: 2026-06-29
|
|
66
|
+
next_id: 33
|
|
67
67
|
|
|
68
68
|
tasks:
|
|
69
69
|
# --- Housekeeping (seeded so the loop has work on day one) ------------------
|
|
@@ -270,7 +270,7 @@ tasks:
|
|
|
270
270
|
|
|
271
271
|
- id: T-010
|
|
272
272
|
title: "Complete v1.9 quickstart docs rewrite with getting-started guide and screenshots"
|
|
273
|
-
status:
|
|
273
|
+
status: done
|
|
274
274
|
priority: P2
|
|
275
275
|
area: docs
|
|
276
276
|
risk: low
|
|
@@ -286,9 +286,9 @@ tasks:
|
|
|
286
286
|
- "At least one guide beyond `bare-minimum.md` covers the standard fork/remote-theme workflow."
|
|
287
287
|
- "Each guide includes at least one screenshot stored under `assets/images/docs/quickstart/`."
|
|
288
288
|
- "All new pages pass `docs-validate.yml` front-matter and link checks."
|
|
289
|
-
links: { issue:
|
|
289
|
+
links: { issue: 126, pr: null, roadmap: "1.9" }
|
|
290
290
|
created: 2026-06-01
|
|
291
|
-
updated: 2026-06-
|
|
291
|
+
updated: 2026-06-29
|
|
292
292
|
|
|
293
293
|
- id: T-011
|
|
294
294
|
title: "Add Ruby unit tests for uncovered _plugins/ generators"
|
|
@@ -358,7 +358,7 @@ tasks:
|
|
|
358
358
|
|
|
359
359
|
- id: T-013
|
|
360
360
|
title: "Refresh Playwright snapshot baselines and re-arm the pixel gate"
|
|
361
|
-
status:
|
|
361
|
+
status: done
|
|
362
362
|
priority: P2
|
|
363
363
|
area: tests
|
|
364
364
|
risk: standard
|
|
@@ -373,9 +373,9 @@ tasks:
|
|
|
373
373
|
- "Baselines under `test/visual/snapshots/` regenerated and committed."
|
|
374
374
|
- "`continue-on-error: true` removed from the snapshot step in `ci.yml`."
|
|
375
375
|
- "Snapshot tier passes in CI on an unchanged follow-up commit."
|
|
376
|
-
links: { issue:
|
|
376
|
+
links: { issue: 135, pr: null, roadmap: "1.13" }
|
|
377
377
|
created: 2026-06-10
|
|
378
|
-
updated: 2026-06-
|
|
378
|
+
updated: 2026-06-29
|
|
379
379
|
|
|
380
380
|
- id: T-014
|
|
381
381
|
title: "Re-arm the docs link-check gate (remove warn-only || true)"
|
|
@@ -538,7 +538,7 @@ tasks:
|
|
|
538
538
|
|
|
539
539
|
- id: T-020
|
|
540
540
|
title: "CI coverage for installer interactive wizard and upgrade path (coverage rank #2)"
|
|
541
|
-
status:
|
|
541
|
+
status: done
|
|
542
542
|
priority: P2
|
|
543
543
|
area: tests
|
|
544
544
|
risk: standard
|
|
@@ -554,13 +554,13 @@ tasks:
|
|
|
554
554
|
- "Wizard prompt helpers exercised non-interactively (piped answers) in a test_install_* suite."
|
|
555
555
|
- "An upgrade fixture covers detect→migrate→verify for at least one version gap."
|
|
556
556
|
- "Suites run in CI via the standard installer e2e discovery (test_install_*.sh)."
|
|
557
|
-
links: { issue:
|
|
557
|
+
links: { issue: 147, pr: null, roadmap: "1.14" }
|
|
558
558
|
created: 2026-06-12
|
|
559
|
-
updated: 2026-06-
|
|
559
|
+
updated: 2026-06-29
|
|
560
560
|
|
|
561
561
|
- id: T-021
|
|
562
562
|
title: "Vendor cytoscape.js so the Obsidian graph works without a CDN"
|
|
563
|
-
status:
|
|
563
|
+
status: done
|
|
564
564
|
priority: P3
|
|
565
565
|
area: feat
|
|
566
566
|
risk: standard
|
|
@@ -577,9 +577,9 @@ tasks:
|
|
|
577
577
|
- "cytoscape.min.js committed under assets/vendor/ and referenced via a local path."
|
|
578
578
|
- "full-graph.html no longer references cdn.jsdelivr.net."
|
|
579
579
|
- "The graph page renders nodes/edges with the vendored file (no network)."
|
|
580
|
-
links: { issue:
|
|
580
|
+
links: { issue: 152, pr: null, roadmap: null }
|
|
581
581
|
created: 2026-06-13
|
|
582
|
-
updated: 2026-06-
|
|
582
|
+
updated: 2026-06-29
|
|
583
583
|
|
|
584
584
|
# --- 2026-06-15 audit -------------------------------------------------------
|
|
585
585
|
|
|
@@ -637,7 +637,7 @@ tasks:
|
|
|
637
637
|
|
|
638
638
|
- id: T-024
|
|
639
639
|
title: "Unit tests for scripts/content-review.rb scoring engine"
|
|
640
|
-
status:
|
|
640
|
+
status: done
|
|
641
641
|
priority: P2
|
|
642
642
|
area: tests
|
|
643
643
|
risk: standard
|
|
@@ -657,13 +657,13 @@ tasks:
|
|
|
657
657
|
- "At least one test verifies the `--strict` flag exits non-zero when the fail threshold is crossed."
|
|
658
658
|
- "Tests run under `LC_ALL=C` (locale-independence parity with T-015 guard)."
|
|
659
659
|
- "`./scripts/bin/test` stays green with the new tests included."
|
|
660
|
-
links: { issue:
|
|
660
|
+
links: { issue: 166, pr: null, roadmap: null }
|
|
661
661
|
created: 2026-06-15
|
|
662
|
-
updated: 2026-06-
|
|
662
|
+
updated: 2026-06-29
|
|
663
663
|
|
|
664
664
|
- id: T-025
|
|
665
665
|
title: "Playwright smoke tests for the site-wide search modal"
|
|
666
|
-
status:
|
|
666
|
+
status: done
|
|
667
667
|
priority: P2
|
|
668
668
|
area: tests
|
|
669
669
|
risk: standard
|
|
@@ -683,13 +683,13 @@ tasks:
|
|
|
683
683
|
- "A result-population check: query matching a known post title (e.g. 'Hello World') yields at least one result `<a>` element."
|
|
684
684
|
- "Mutual-exclusion guard: opening search while Settings offcanvas is open closes the offcanvas first (no stacked backdrops)."
|
|
685
685
|
- "Spec runs in the smoke project (`npx playwright test --project=smoke`) without a network request to an external index."
|
|
686
|
-
links: { issue:
|
|
686
|
+
links: { issue: 167, pr: 208, roadmap: null }
|
|
687
687
|
created: 2026-06-15
|
|
688
|
-
updated: 2026-06-
|
|
688
|
+
updated: 2026-06-29
|
|
689
689
|
|
|
690
690
|
- id: T-026
|
|
691
691
|
title: "Playwright smoke test for AI chat widget render guard and FAB visibility"
|
|
692
|
-
status:
|
|
692
|
+
status: done
|
|
693
693
|
priority: P3
|
|
694
694
|
area: tests
|
|
695
695
|
risk: standard
|
|
@@ -710,6 +710,156 @@ tasks:
|
|
|
710
710
|
- "A mock-config test (inject `data-ai-chat-enabled` attribute or use a fixture page with the widget force-enabled) verifies the FAB renders and the chat panel toggles open/closed on click."
|
|
711
711
|
- "The test passes in the smoke project without a live AI backend."
|
|
712
712
|
- "`./scripts/bin/test` (including the Playwright smoke tier) stays green."
|
|
713
|
-
links: { issue:
|
|
713
|
+
links: { issue: 168, pr: 250, roadmap: null }
|
|
714
714
|
created: 2026-06-15
|
|
715
|
-
updated: 2026-06-
|
|
715
|
+
updated: 2026-06-29
|
|
716
|
+
|
|
717
|
+
# --- Issue intake 2026-06-26: remote-theme 404 cluster + docs ----------------
|
|
718
|
+
# Cap: 5 of 7 open issues triaged this run. Deferred (next run): #203 (consumer
|
|
719
|
+
# checklist docs — companion to T-031); #201 (giscus typo — already in-flight in
|
|
720
|
+
# PR #214, so no task, to avoid duplicating live work).
|
|
721
|
+
|
|
722
|
+
- id: T-027
|
|
723
|
+
title: "Theme chrome injects unconditional links (/authors/, /news/, /tags/, /posts/, graph) that 404 for remote-theme consumers"
|
|
724
|
+
status: done
|
|
725
|
+
priority: P2
|
|
726
|
+
area: a11y
|
|
727
|
+
risk: standard
|
|
728
|
+
effort: M
|
|
729
|
+
source: issue
|
|
730
|
+
route: a11y
|
|
731
|
+
summary: >-
|
|
732
|
+
Umbrella for the remote-theme 404 class (#204): the theme chrome itself
|
|
733
|
+
injects internal links to pages whose generators live in `_plugins` (skipped
|
|
734
|
+
by GitHub Pages safe mode), so a built consumer site has broken links on
|
|
735
|
+
every page. Guard each link by existence the way the footer "Quick Links"
|
|
736
|
+
block already does. Specific instances are T-029 (#218 sidebar) and T-030
|
|
737
|
+
(#219 showcase); T-028 (#202) is the search/sitemap variant. Any fix that
|
|
738
|
+
edits `_plugins/` is CODEOWNERS-gated -> human review.
|
|
739
|
+
acceptance:
|
|
740
|
+
- "Theme-injected chrome links render only when their target exists (mirror the footer Quick-Links existence guard)."
|
|
741
|
+
- "A link check over a built remote-theme `_site` reports no theme-injected 404s."
|
|
742
|
+
- "No edit to `lib/jekyll-theme-zer0/version.rb` or release files."
|
|
743
|
+
links: { issue: 204, pr: 252, roadmap: null }
|
|
744
|
+
created: 2026-06-26
|
|
745
|
+
updated: 2026-06-29
|
|
746
|
+
|
|
747
|
+
- id: T-028
|
|
748
|
+
title: "remote_theme Pages consumers 404 on /search.json and /sitemap/ (generator is plugin-only)"
|
|
749
|
+
status: done
|
|
750
|
+
priority: P2
|
|
751
|
+
area: feat
|
|
752
|
+
risk: standard
|
|
753
|
+
effort: M
|
|
754
|
+
source: issue
|
|
755
|
+
route: code-fixer
|
|
756
|
+
summary: >-
|
|
757
|
+
On a pure remote-theme Pages consumer, `/search.json` and `/sitemap/` 404
|
|
758
|
+
because `_plugins/search_and_sitemap_generator.rb` never runs under Pages
|
|
759
|
+
safe mode (#202). Provide a Pages-safe fallback (committed stubs the navbar
|
|
760
|
+
search + sitemap link can resolve, or graceful degradation in
|
|
761
|
+
`assets/js/search-modal.js`). NOTE: editing `_plugins/` is CODEOWNERS-gated
|
|
762
|
+
-> human review; prefer the non-plugin path.
|
|
763
|
+
acceptance:
|
|
764
|
+
- "On a remote-theme Pages build, the navbar search resolves (no /search.json 404) or degrades gracefully."
|
|
765
|
+
- "The /sitemap/ link resolves (no 404) for a remote-theme consumer."
|
|
766
|
+
- "No new runtime dependency; no edit to version/release files."
|
|
767
|
+
links: { issue: 202, pr: 257, roadmap: null }
|
|
768
|
+
created: 2026-06-26
|
|
769
|
+
updated: 2026-06-29
|
|
770
|
+
|
|
771
|
+
- id: T-029
|
|
772
|
+
title: "Guard the unconditional /tags/ link in section-sidebar.html for remote-theme consumers"
|
|
773
|
+
status: done
|
|
774
|
+
priority: P2
|
|
775
|
+
area: feat
|
|
776
|
+
risk: low
|
|
777
|
+
effort: S
|
|
778
|
+
source: issue
|
|
779
|
+
route: theme-ui
|
|
780
|
+
summary: >-
|
|
781
|
+
`_includes/navigation/section-sidebar.html:69` hardcodes a `/tags/` link;
|
|
782
|
+
remote-theme consumers have no `/tags/` index (plugin-only), so it 404s
|
|
783
|
+
(#218). Guard it the way `_includes/core/footer.html` (~138-147) guards its
|
|
784
|
+
links, or gate on a `site.tags_page` flag. Instance of the T-027 class.
|
|
785
|
+
acceptance:
|
|
786
|
+
- "The sidebar 'View All Tags' link renders only when the tags index exists (or a documented site flag is set)."
|
|
787
|
+
- "Remote-theme consumers no longer 404 from the sidebar link; the Jekyll build stays green."
|
|
788
|
+
- "A `test/visual/*.spec.js` regression asserts the conditional render (theme-ui / visual-evidence)."
|
|
789
|
+
links: { issue: 218, pr: 254, roadmap: null }
|
|
790
|
+
created: 2026-06-26
|
|
791
|
+
updated: 2026-06-29
|
|
792
|
+
|
|
793
|
+
- id: T-030
|
|
794
|
+
title: "component-showcase.html hardcodes demo links (/docs/, /pages/, /docs/customization/) that 404 for consumers"
|
|
795
|
+
status: done
|
|
796
|
+
priority: P3
|
|
797
|
+
area: feat
|
|
798
|
+
risk: low
|
|
799
|
+
effort: S
|
|
800
|
+
source: issue
|
|
801
|
+
route: theme-ui
|
|
802
|
+
summary: >-
|
|
803
|
+
`_includes/components/component-showcase.html` hardcodes absolute demo links
|
|
804
|
+
(~323-325, 417/421) that 404 for any consumer without those exact routes
|
|
805
|
+
(#219). Parameterize them (the component already accepts `sections`) or guard
|
|
806
|
+
each by existence. Low priority — demo component — but it makes the showcase
|
|
807
|
+
un-includable as-is. Instance of the T-027 class.
|
|
808
|
+
acceptance:
|
|
809
|
+
- "The showcase's demo links are parameterized or existence-guarded (no hardcoded absolute paths that can 404)."
|
|
810
|
+
- "Including the showcase on a consumer site produces no theme-injected 404s; the Jekyll build stays green."
|
|
811
|
+
- "A `test/visual/*.spec.js` regression covers the parameterized/guarded links (theme-ui / visual-evidence)."
|
|
812
|
+
links: { issue: 219, pr: 256, roadmap: null }
|
|
813
|
+
created: 2026-06-26
|
|
814
|
+
updated: 2026-06-29
|
|
815
|
+
|
|
816
|
+
- id: T-031
|
|
817
|
+
title: "Document the safe-mode build-overlay recipe for consumers building outside GitHub Pages"
|
|
818
|
+
status: done
|
|
819
|
+
priority: P3
|
|
820
|
+
area: docs
|
|
821
|
+
risk: low
|
|
822
|
+
effort: S
|
|
823
|
+
source: issue
|
|
824
|
+
route: content
|
|
825
|
+
summary: >-
|
|
826
|
+
Consumers who build the theme outside GitHub Pages (own CI/Actions) must
|
|
827
|
+
reinvent the safe-mode overlay: clone the remote theme, overlay content,
|
|
828
|
+
strip `_plugins`, then `jekyll build --strict_front_matter` (#220). Document
|
|
829
|
+
the recipe in the docs (companion to the #203 consumer checklist). A proven
|
|
830
|
+
reference exists in lifehacker.dev's `scripts/ci/build.sh`.
|
|
831
|
+
acceptance:
|
|
832
|
+
- "A docs page/section under `pages/_docs/` documents the build-overlay recipe (clone -> overlay -> strip _plugins -> strict build)."
|
|
833
|
+
- "It is cross-linked from the remote-theme/deploy docs and passes markdownlint + the content-review deterministic tier."
|
|
834
|
+
- "No code change; docs only."
|
|
835
|
+
links: { issue: 220, pr: 251, roadmap: null }
|
|
836
|
+
created: 2026-06-26
|
|
837
|
+
updated: 2026-06-26
|
|
838
|
+
|
|
839
|
+
- id: T-032
|
|
840
|
+
title: "Add color_mode_default config knob (dark|light|auto) with FOUC prevention"
|
|
841
|
+
status: done
|
|
842
|
+
priority: P2
|
|
843
|
+
area: feat
|
|
844
|
+
risk: low
|
|
845
|
+
effort: S
|
|
846
|
+
source: issue
|
|
847
|
+
route: theme-ui
|
|
848
|
+
summary: >-
|
|
849
|
+
Implement a color_mode_default config key (values dark|light|auto, default auto).
|
|
850
|
+
Server-side: root.html reads site.color_mode_default and sets data-bs-theme
|
|
851
|
+
accordingly (auto resolves to dark as SSR fallback). Client-side: an early inline
|
|
852
|
+
script (_includes/core/color-mode-init.html, before Bootstrap CSS) applies the
|
|
853
|
+
correct theme respecting both the config default and a localStorage["theme"] override,
|
|
854
|
+
preventing FOUC. auto follows prefers-color-scheme — backward-compatible.
|
|
855
|
+
acceptance:
|
|
856
|
+
- "site.color_mode_default: dark|light|auto is documented in _config.yml."
|
|
857
|
+
- "root.html server-renders data-bs-theme from the config (not hardcoded 'dark')."
|
|
858
|
+
- "An early inline script before Bootstrap CSS prevents FOUC for all three modes."
|
|
859
|
+
- "localStorage['theme'] override wins over the config default."
|
|
860
|
+
- "auto follows prefers-color-scheme; backward-compatible with the previous behaviour."
|
|
861
|
+
- "Regression spec test/visual/color-mode-default.spec.js passes (smoke tier)."
|
|
862
|
+
- "Before/after evidence committed under test/visual/evidence/color-mode-default/."
|
|
863
|
+
links: { issue: 241, pr: 253, roadmap: null }
|
|
864
|
+
created: 2026-06-29
|
|
865
|
+
updated: 2026-06-29
|
data/_data/navigation/docs.yml
CHANGED
|
@@ -70,6 +70,10 @@
|
|
|
70
70
|
url: /docs/deployment/
|
|
71
71
|
- title: GitHub Pages
|
|
72
72
|
url: /docs/deployment/github-pages/
|
|
73
|
+
- title: Remote-Theme Consumer Checklist
|
|
74
|
+
url: /docs/deployment/remote-theme-checklist/
|
|
75
|
+
- title: Safe-Mode Build Overlay
|
|
76
|
+
url: /docs/deployment/build-overlay/
|
|
73
77
|
- title: Netlify
|
|
74
78
|
url: /docs/deployment/netlify/
|
|
75
79
|
- title: Custom Domain
|
data/_data/theme_backgrounds.yml
CHANGED
|
@@ -99,3 +99,27 @@ skins:
|
|
|
99
99
|
gradient: "assets/backgrounds/gradients/sunrise.svg"
|
|
100
100
|
pattern: "assets/backgrounds/patterns/sunrise.svg"
|
|
101
101
|
noise: "assets/backgrounds/noise/sunrise.svg"
|
|
102
|
+
|
|
103
|
+
# `dark` is the DEFAULT theme_skin, and `contrast` is advertised as valid, but
|
|
104
|
+
# neither was mapped here — so the SVG-background feature had no entry for them
|
|
105
|
+
# (issue #240). The gradient/pattern/noise assets already ship; these entries
|
|
106
|
+
# wire them up. Colors are taken from each skin's gradient stops.
|
|
107
|
+
dark:
|
|
108
|
+
label: "Dark"
|
|
109
|
+
colors:
|
|
110
|
+
primary: "#1a1a2e"
|
|
111
|
+
secondary: "#16213e"
|
|
112
|
+
accent: "#0f3460"
|
|
113
|
+
gradient: "assets/backgrounds/gradients/dark.svg"
|
|
114
|
+
pattern: "assets/backgrounds/patterns/dark.svg"
|
|
115
|
+
noise: "assets/backgrounds/noise/dark.svg"
|
|
116
|
+
|
|
117
|
+
contrast:
|
|
118
|
+
label: "Contrast"
|
|
119
|
+
colors:
|
|
120
|
+
primary: "#111111"
|
|
121
|
+
secondary: "#333333"
|
|
122
|
+
accent: "#ffcc00"
|
|
123
|
+
gradient: "assets/backgrounds/gradients/contrast.svg"
|
|
124
|
+
pattern: "assets/backgrounds/patterns/contrast.svg"
|
|
125
|
+
noise: "assets/backgrounds/noise/contrast.svg"
|
|
@@ -15,13 +15,22 @@
|
|
|
15
15
|
tabs,progress,breadcrumbs,table,tooltips,list-group
|
|
16
16
|
Default: all sections
|
|
17
17
|
|
|
18
|
-
Usage
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
Usage (wrapped in raw so these examples are shown literally and NOT executed —
|
|
19
|
+
un-wrapped, Liquid runs them even inside this HTML comment and the include
|
|
20
|
+
recursively includes itself → "stack level too deep"):
|
|
21
|
+
{% raw %}{% include components/component-showcase.html %}
|
|
22
|
+
{% include components/component-showcase.html sections="alerts,buttons,cards" %}{% endraw %}
|
|
21
23
|
|
|
22
24
|
Dependencies:
|
|
23
25
|
- Bootstrap 5.3 CSS & JS (loaded by theme)
|
|
24
26
|
- Bootstrap Icons (loaded by theme)
|
|
27
|
+
|
|
28
|
+
Note: The breadcrumb and list-group demo links are existence-guarded (issue #219).
|
|
29
|
+
Each target URL is resolved against site.html_pages (and collection docs
|
|
30
|
+
for collection-backed routes). When the page exists in the build the link
|
|
31
|
+
is real; when it does not the label renders as plain text. This keeps the
|
|
32
|
+
showcase safe for remote-theme consumers who may lack /docs/, /posts/,
|
|
33
|
+
/categories/, /tags/, or /docs/customization/.
|
|
25
34
|
===================================================================
|
|
26
35
|
-->
|
|
27
36
|
{% assign sections = include.sections | default: "alerts,buttons,badges,cards,accordion,tabs,progress,breadcrumbs,table,tooltips,list-group" %}
|
|
@@ -318,11 +327,29 @@ theme: jekyll-theme-zer0</code></pre>
|
|
|
318
327
|
<!-- ===== BREADCRUMBS ===== -->
|
|
319
328
|
<h3 id="showcase-breadcrumbs">Breadcrumbs</h3>
|
|
320
329
|
<p>Hierarchical navigation trail showing current page position:</p>
|
|
330
|
+
{% comment %} Existence-guard the demo breadcrumb links so they never 404 on
|
|
331
|
+
remote-theme consumers that lack /docs/ or /docs/customization/. When the
|
|
332
|
+
target page is in the build the crumb is a real link; otherwise plain text.
|
|
333
|
+
Home (/) is always present. Pattern mirrors _includes/navigation/breadcrumbs.html. {% endcomment %}
|
|
334
|
+
{% assign _demo_docs_page = site.html_pages | where: "url", "/docs/" | first %}
|
|
335
|
+
{% unless _demo_docs_page %}
|
|
336
|
+
{% for _col in site.collections %}
|
|
337
|
+
{% assign _demo_docs_page = _col.docs | where: "url", "/docs/" | first %}
|
|
338
|
+
{% if _demo_docs_page %}{% break %}{% endif %}
|
|
339
|
+
{% endfor %}
|
|
340
|
+
{% endunless %}
|
|
341
|
+
{% assign _demo_custom_page = site.html_pages | where: "url", "/docs/customization/" | first %}
|
|
342
|
+
{% unless _demo_custom_page %}
|
|
343
|
+
{% for _col in site.collections %}
|
|
344
|
+
{% assign _demo_custom_page = _col.docs | where: "url", "/docs/customization/" | first %}
|
|
345
|
+
{% if _demo_custom_page %}{% break %}{% endif %}
|
|
346
|
+
{% endfor %}
|
|
347
|
+
{% endunless %}
|
|
321
348
|
<nav aria-label="breadcrumb example" class="mb-4">
|
|
322
349
|
<ol class="breadcrumb">
|
|
323
|
-
<li class="breadcrumb-item"><a href="/" class="text-decoration-none"><i class="bi bi-house me-1"></i>Home</a></li>
|
|
324
|
-
<li class="breadcrumb-item"
|
|
325
|
-
<li class="breadcrumb-item"
|
|
350
|
+
<li class="breadcrumb-item"><a href="{{ '/' | relative_url }}" class="text-decoration-none"><i class="bi bi-house me-1"></i>Home</a></li>
|
|
351
|
+
<li class="breadcrumb-item">{% if _demo_docs_page %}<a href="{{ '/docs/' | relative_url }}" class="text-decoration-none">Documentation</a>{% else %}Documentation{% endif %}</li>
|
|
352
|
+
<li class="breadcrumb-item">{% if _demo_custom_page %}<a href="{{ '/docs/customization/' | relative_url }}" class="text-decoration-none">Customization</a>{% else %}Customization{% endif %}</li>
|
|
326
353
|
<li class="breadcrumb-item active" aria-current="page">Theme Colors</li>
|
|
327
354
|
</ol>
|
|
328
355
|
</nav>
|
|
@@ -411,25 +438,67 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
411
438
|
<!-- ===== LIST GROUP ===== -->
|
|
412
439
|
<h3 id="showcase-list-group">List Group</h3>
|
|
413
440
|
<p>Organized content lists with icons, badges, and action states:</p>
|
|
441
|
+
{% comment %} Existence-guard the demo list-group links (issue #219). Each target
|
|
442
|
+
URL is resolved against site.html_pages + collection docs. When present the
|
|
443
|
+
item is a real <a>; when absent it renders as a non-linking <div> so no 404
|
|
444
|
+
is injected on remote-theme consumers that lack /posts/, /docs/, /categories/,
|
|
445
|
+
or /tags/. Pattern mirrors section-sidebar.html and author-bio.html. {% endcomment %}
|
|
446
|
+
{% assign _demo_posts_page = site.html_pages | where: "url", "/posts/" | first %}
|
|
447
|
+
{% unless _demo_posts_page %}
|
|
448
|
+
{% for _col in site.collections %}
|
|
449
|
+
{% assign _demo_posts_page = _col.docs | where: "url", "/posts/" | first %}
|
|
450
|
+
{% if _demo_posts_page %}{% break %}{% endif %}
|
|
451
|
+
{% endfor %}
|
|
452
|
+
{% endunless %}
|
|
453
|
+
{% assign _demo_cats_page = site.html_pages | where: "url", "/categories/" | first %}
|
|
454
|
+
{% unless _demo_cats_page %}
|
|
455
|
+
{% for _col in site.collections %}
|
|
456
|
+
{% assign _demo_cats_page = _col.docs | where: "url", "/categories/" | first %}
|
|
457
|
+
{% if _demo_cats_page %}{% break %}{% endif %}
|
|
458
|
+
{% endfor %}
|
|
459
|
+
{% endunless %}
|
|
460
|
+
{% assign _demo_tags_page = site.html_pages | where: "url", "/tags/" | first %}
|
|
461
|
+
{% unless _demo_tags_page %}
|
|
462
|
+
{% for _col in site.collections %}
|
|
463
|
+
{% assign _demo_tags_page = _col.docs | where: "url", "/tags/" | first %}
|
|
464
|
+
{% if _demo_tags_page %}{% break %}{% endif %}
|
|
465
|
+
{% endfor %}
|
|
466
|
+
{% endunless %}
|
|
414
467
|
<div class="row g-4 mb-4">
|
|
415
468
|
<div class="col-md-6">
|
|
416
469
|
<div class="list-group">
|
|
417
|
-
|
|
470
|
+
{% if _demo_posts_page %}
|
|
471
|
+
<a href="{{ '/posts/' | relative_url }}" class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
|
|
472
|
+
{% else %}
|
|
473
|
+
<div class="list-group-item d-flex justify-content-between align-items-center">
|
|
474
|
+
{% endif %}
|
|
418
475
|
<span><i class="bi bi-journal-richtext text-primary me-2"></i>Blog Posts</span>
|
|
419
476
|
<span class="badge bg-primary rounded-pill">{{ site.posts.size | default: "12" }}</span>
|
|
420
|
-
</a>
|
|
421
|
-
|
|
477
|
+
{% if _demo_posts_page %}</a>{% else %}</div>{% endif %}
|
|
478
|
+
{% if _demo_docs_page %}
|
|
479
|
+
<a href="{{ '/docs/' | relative_url }}" class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
|
|
480
|
+
{% else %}
|
|
481
|
+
<div class="list-group-item d-flex justify-content-between align-items-center">
|
|
482
|
+
{% endif %}
|
|
422
483
|
<span><i class="bi bi-book text-success me-2"></i>Documentation</span>
|
|
423
484
|
<span class="badge bg-success rounded-pill">{{ site.documents.size | default: "8" }}</span>
|
|
424
|
-
</a>
|
|
425
|
-
|
|
485
|
+
{% if _demo_docs_page %}</a>{% else %}</div>{% endif %}
|
|
486
|
+
{% if _demo_cats_page %}
|
|
487
|
+
<a href="{{ '/categories/' | relative_url }}" class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
|
|
488
|
+
{% else %}
|
|
489
|
+
<div class="list-group-item d-flex justify-content-between align-items-center">
|
|
490
|
+
{% endif %}
|
|
426
491
|
<span><i class="bi bi-collection text-info me-2"></i>Categories</span>
|
|
427
492
|
<span class="badge bg-info rounded-pill">{{ site.categories.size | default: "6" }}</span>
|
|
428
|
-
</a>
|
|
429
|
-
|
|
493
|
+
{% if _demo_cats_page %}</a>{% else %}</div>{% endif %}
|
|
494
|
+
{% if _demo_tags_page %}
|
|
495
|
+
<a href="{{ '/tags/' | relative_url }}" class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
|
|
496
|
+
{% else %}
|
|
497
|
+
<div class="list-group-item d-flex justify-content-between align-items-center">
|
|
498
|
+
{% endif %}
|
|
430
499
|
<span><i class="bi bi-tags text-warning me-2"></i>Tags</span>
|
|
431
500
|
<span class="badge bg-warning text-dark rounded-pill">{{ site.tags.size | default: "24" }}</span>
|
|
432
|
-
</a>
|
|
501
|
+
{% if _demo_tags_page %}</a>{% else %}</div>{% endif %}
|
|
433
502
|
</div>
|
|
434
503
|
</div>
|
|
435
504
|
<div class="col-md-6">
|
|
@@ -44,15 +44,23 @@
|
|
|
44
44
|
{% endif %}
|
|
45
45
|
|
|
46
46
|
<!-- Obsidian wiki-link / embed / tag client-side resolver (fallback for the
|
|
47
|
-
remote_theme GH Pages build, where _plugins/obsidian_links.rb cannot run).
|
|
47
|
+
remote_theme GH Pages build, where _plugins/obsidian_links.rb cannot run).
|
|
48
|
+
Honours `obsidian: { enabled: false }` in _config.yml — when disabled the
|
|
49
|
+
resolver script is not loaded and the flag self-disables any fork that
|
|
50
|
+
loads it another way. Note: `| default: true` would flip `false` back to
|
|
51
|
+
true (Liquid treats false as falsy), so test enabled == false explicitly. -->
|
|
48
52
|
{%- assign obsidian_attachments_path = site.obsidian.attachments_path | default: '/assets/images/notes' -%}
|
|
49
53
|
<script>
|
|
50
54
|
window.OBSIDIAN_CONFIG = window.OBSIDIAN_CONFIG || {};
|
|
55
|
+
window.OBSIDIAN_CONFIG.enabled = {% if site.obsidian.enabled == false %}false{% else %}true{% endif %};
|
|
51
56
|
window.OBSIDIAN_CONFIG.wikiIndexUrl = {{ '/assets/data/wiki-index.json' | relative_url | jsonify }};
|
|
52
57
|
window.OBSIDIAN_CONFIG.attachmentsPath = {{ obsidian_attachments_path | relative_url | jsonify }};
|
|
53
58
|
window.OBSIDIAN_CONFIG.tagBase = {{ '/tags/' | relative_url | jsonify }};
|
|
59
|
+
window.OBSIDIAN_CONFIG.cytoscapeUrl = {{ '/assets/vendor/cytoscape/cytoscape.min.js' | relative_url | jsonify }};
|
|
54
60
|
</script>
|
|
55
|
-
|
|
61
|
+
{%- if site.obsidian.enabled != false -%}
|
|
62
|
+
<script defer src="{{ '/assets/js/obsidian-wiki-links.js' | relative_url }}?v={{ site.time | date: '%s' }}"></script>
|
|
63
|
+
{%- endif -%}
|
|
56
64
|
|
|
57
65
|
<!-- Optional fork overrides: opt-in via `site.user_overrides: true` in _config.yml. -->
|
|
58
66
|
{% if site.user_overrides %}
|
|
@@ -108,16 +108,30 @@
|
|
|
108
108
|
<div class="card-body d-flex flex-column">
|
|
109
109
|
|
|
110
110
|
<!-- Category Badge -->
|
|
111
|
-
{% comment %} Category base is configurable (`category_base`, default `/news`)
|
|
112
|
-
|
|
111
|
+
{% comment %} Category base is configurable (`category_base`, default `/news`).
|
|
112
|
+
Only link the badge when that category index page exists in the build;
|
|
113
|
+
otherwise render a plain badge so remote-theme consumers (whose category
|
|
114
|
+
section is plugin/page-generated and absent) don't get a 404. Mirrors
|
|
115
|
+
the tag-badge / footer Quick-Links existence guard. See issue #204. {% endcomment %}
|
|
113
116
|
{% if show_category and include.post.categories.size > 0 %}
|
|
114
117
|
{% assign _category_base = site.category_base | default: '/news' %}
|
|
118
|
+
{% assign primary_category = include.post.categories | first %}
|
|
119
|
+
{% capture _category_url %}{{ _category_base }}/{{ primary_category | slugify }}/{% endcapture %}
|
|
120
|
+
{% comment %} Category index pages can live in site.pages (a regular page) or
|
|
121
|
+
site.posts (a dated section index), so check both. {% endcomment %}
|
|
122
|
+
{% assign _category_page = site.html_pages | where: "url", _category_url | first %}
|
|
123
|
+
{% unless _category_page %}
|
|
124
|
+
{% assign _category_page = site.posts | where: "url", _category_url | first %}
|
|
125
|
+
{% endunless %}
|
|
115
126
|
<div class="mb-2">
|
|
116
|
-
{%
|
|
117
|
-
<a href="{{ site.baseurl }}{{
|
|
127
|
+
{% if _category_page %}
|
|
128
|
+
<a href="{{ site.baseurl }}{{ _category_url }}"
|
|
118
129
|
class="badge bg-primary text-decoration-none">
|
|
119
130
|
{{ primary_category }}
|
|
120
131
|
</a>
|
|
132
|
+
{% else %}
|
|
133
|
+
<span class="badge bg-primary">{{ primary_category }}</span>
|
|
134
|
+
{% endif %}
|
|
121
135
|
</div>
|
|
122
136
|
{% endif %}
|
|
123
137
|
|