jekyll-theme-zer0 1.26.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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +172 -1
  3. data/README.md +10 -27
  4. data/_data/authors.yml +4 -3
  5. data/_data/backlog.yml +28 -0
  6. data/_data/features.yml +65 -18
  7. data/_data/i18n/languages.yml +36 -0
  8. data/_data/theme-manifest.yml +0 -2
  9. data/_data/ui-text.yml +36 -246
  10. data/_includes/README.md +4 -0
  11. data/_includes/components/author-avatar-url.html +4 -2
  12. data/_includes/components/env-switcher.html +3 -1
  13. data/_includes/components/language-toggle.html +81 -0
  14. data/_includes/components/search-modal.html +2 -2
  15. data/_includes/components/shortcuts-modal.html +1 -1
  16. data/_includes/components/translation-notice.html +27 -0
  17. data/_includes/content/intro.html +16 -15
  18. data/_includes/core/footer.html +9 -4
  19. data/_includes/core/head.html +9 -0
  20. data/_includes/core/header.html +9 -4
  21. data/_includes/core/hreflang.html +33 -0
  22. data/_includes/core/i18n.html +36 -0
  23. data/_includes/navigation/breadcrumbs.html +1 -1
  24. data/_includes/navigation/navbar.html +5 -4
  25. data/_includes/navigation/sidebar-right.html +3 -2
  26. data/_includes/navigation/unified-drawer.html +1 -1
  27. data/_layouts/article.html +7 -1
  28. data/_layouts/default.html +5 -3
  29. data/_layouts/news.html +4 -2
  30. data/_layouts/root.html +14 -8
  31. data/_layouts/section.html +4 -2
  32. data/_sass/core/_obsidian.scss +9 -1
  33. data/_sass/layouts/_navbar-extras.scss +6 -1
  34. data/assets/js/obsidian-graph.js +5 -1
  35. data/scripts/README.md +20 -26
  36. data/scripts/bin/audit-consumer +1 -1
  37. data/scripts/bin/manifest +0 -1
  38. data/scripts/bin/sync-plugins +0 -1
  39. data/scripts/dev/rasterize-svg.js +65 -0
  40. data/scripts/features/generate-preview-images +49 -1390
  41. data/scripts/features/install-preview-generator +55 -33
  42. data/scripts/install/README.md +9 -20
  43. data/scripts/install/ai/prompts/wizard.system.md +8 -17
  44. data/scripts/lib/README.md +1 -5
  45. data/scripts/lib/install/deploy/README.md +3 -9
  46. data/scripts/lib/preview_generator.py +2261 -1341
  47. data/scripts/translate.rb +1114 -0
  48. metadata +9 -3
  49. data/_plugins/preview_image_generator.rb +0 -351
@@ -14,13 +14,15 @@
14
14
  # -h, --help Show this help message
15
15
  # -d, --dry-run Preview what would be installed (no changes)
16
16
  # -f, --force Overwrite existing files
17
- # -p, --provider PROVIDER Set default AI provider (openai, stability, local)
17
+ # -p, --provider PROVIDER Set default renderer
18
+ # (openai, xai, stability, gemini, local)
18
19
  # --no-config Skip _config.yml modification
19
20
  # --no-tasks Skip VS Code tasks installation
20
21
  #
21
22
  # Requirements:
22
23
  # - Jekyll site using zer0-mistakes theme
23
24
  # - curl and jq installed
25
+ # - python3 with PyYAML (runs the generation engine)
24
26
  # - Git repository (for version tracking)
25
27
  #
26
28
 
@@ -43,12 +45,12 @@ RAW_URL="https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/main"
43
45
  SOURCE_FILES=(
44
46
  "scripts/features/generate-preview-images"
45
47
  "scripts/lib/preview_generator.py"
46
- "_plugins/preview_image_generator.rb"
48
+ "scripts/dev/rasterize-svg.js"
47
49
  )
48
50
  DEST_FILES=(
49
51
  "scripts/generate-preview-images.sh"
50
52
  "scripts/lib/preview_generator.py"
51
- "_plugins/preview_image_generator.rb"
53
+ "scripts/dev/rasterize-svg.js"
52
54
  )
53
55
 
54
56
  # Default options
@@ -96,20 +98,21 @@ ${YELLOW}OPTIONS:${NC}
96
98
  -h, --help Show this help message
97
99
  -d, --dry-run Preview what would be installed (no changes)
98
100
  -f, --force Overwrite existing files
99
- -p, --provider PROVIDER Set default AI provider (openai, stability, local)
101
+ -p, --provider PROVIDER Set default renderer
102
+ (openai, xai, stability, gemini, local)
100
103
  --no-config Skip _config.yml modification
101
104
  --no-tasks Skip VS Code tasks installation
102
105
  -l, --local PATH Copy files from local theme directory instead of downloading
103
106
 
104
107
  ${YELLOW}EXAMPLES:${NC}
105
- # Install with defaults
108
+ # Install with defaults (OpenAI renders; Claude analyzes + reviews)
106
109
  ./$SCRIPT_NAME
107
110
 
108
111
  # Preview installation
109
112
  ./$SCRIPT_NAME --dry-run
110
113
 
111
- # Install with Stability AI as default provider
112
- ./$SCRIPT_NAME --provider stability
114
+ # Install with Gemini as the renderer
115
+ ./$SCRIPT_NAME --provider gemini
113
116
 
114
117
  # Force reinstall
115
118
  ./$SCRIPT_NAME --force
@@ -118,8 +121,13 @@ ${YELLOW}REMOTE INSTALLATION:${NC}
118
121
  curl -fsSL ${RAW_URL}/scripts/$SCRIPT_NAME | bash
119
122
 
120
123
  ${YELLOW}AFTER INSTALLATION:${NC}
121
- 1. Set your API key in .env file:
122
- OPENAI_API_KEY=your-key-here
124
+ 1. Set credentials in .env:
125
+ OPENAI_API_KEY=... # the default renderer
126
+ Plus ONE Claude credential so Claude can analyze articles and
127
+ review the rendered images (optional — degrades to template prompts):
128
+ CLAUDE_CODE_OAUTH_TOKEN=... # from \`claude setup-token\`
129
+ ANTHROPIC_API_KEY=... # from console.anthropic.com
130
+ (or just have the \`claude\` CLI installed and logged in)
123
131
 
124
132
  2. Generate preview images:
125
133
  ./scripts/generate-preview-images.sh --list-missing
@@ -145,13 +153,13 @@ check_jekyll_site() {
145
153
  # Check dependencies
146
154
  check_dependencies() {
147
155
  local missing=()
148
-
149
- for cmd in curl jq; do
156
+
157
+ for cmd in curl jq python3; do
150
158
  if ! command -v "$cmd" &> /dev/null; then
151
159
  missing+=("$cmd")
152
160
  fi
153
161
  done
154
-
162
+
155
163
  if [[ ${#missing[@]} -gt 0 ]]; then
156
164
  error "Missing required dependencies: ${missing[*]}"
157
165
  info "Install them with:"
@@ -159,7 +167,13 @@ check_dependencies() {
159
167
  info " Ubuntu: sudo apt-get install ${missing[*]}"
160
168
  exit 1
161
169
  fi
162
-
170
+
171
+ # The generation engine needs PyYAML (front matter / _config.yml parsing)
172
+ if ! python3 -c "import yaml" &> /dev/null; then
173
+ warn "PyYAML not found — the generator will not run until it is installed:"
174
+ info " pip3 install pyyaml (or: python3 -m pip install --user pyyaml)"
175
+ fi
176
+
163
177
  log "All dependencies satisfied"
164
178
  }
165
179
 
@@ -242,19 +256,22 @@ update_config() {
242
256
 
243
257
  # =============================================================================
244
258
  # AI Preview Image Generator Configuration
245
- # Feature: ZER0-003
259
+ # Feature: ZER0-004
246
260
  # Documentation: ${REPO_URL}/blob/main/docs/features/preview-image-generator.md
247
261
  # =============================================================================
248
262
  preview_images:
249
263
  enabled: true
250
- provider: ${DEFAULT_PROVIDER} # openai, stability, or local
251
- model: dall-e-3 # OpenAI model to use
252
- size: "1792x1024" # Landscape banner size
253
- quality: standard # standard or hd
264
+ provider: ${DEFAULT_PROVIDER} # renderer: openai, xai, stability, gemini, local
265
+ model: "" # empty = renderer default (gpt-image-2, grok-2-image, ...)
266
+ size: "1536x1024" # Landscape banner size
267
+ quality: auto # auto for GPT Image; standard/hd for DALL-E 3
254
268
  style: "retro pixel art, 8-bit video game aesthetic, vibrant colors, nostalgic, clean pixel graphics"
255
269
  style_modifiers: "pixelated, retro gaming style, CRT screen glow effect, limited color palette"
256
270
  output_dir: assets/images/previews # Where to save generated images
257
- auto_generate: false # Generate during build (slow, use script instead)
271
+ prompt_engine: claude # claude analyzes the article (template = built-in prompt)
272
+ review_engine: claude # claude reviews the render (none = skip)
273
+ assets_prefix: /assets # Prefix prepended to relative preview paths
274
+ auto_prefix: true # Auto-add assets_prefix when missing
258
275
  collections: # Collections to scan for missing previews
259
276
  - posts
260
277
  - docs
@@ -270,28 +287,32 @@ create_env_example() {
270
287
 
271
288
  if [[ -f "$env_example" ]]; then
272
289
  # Check if our keys are already there
273
- if grep -q "OPENAI_API_KEY" "$env_example"; then
290
+ if grep -q "CLAUDE_CODE_OAUTH_TOKEN" "$env_example"; then
274
291
  info ".env.example already contains preview generator keys"
275
292
  return 0
276
293
  fi
277
294
  fi
278
-
295
+
279
296
  if [[ "$DRY_RUN" == true ]]; then
280
297
  dry_run_log "Would add API keys to .env.example"
281
298
  return 0
282
299
  fi
283
-
300
+
284
301
  step "Updating .env.example"
285
-
286
- cat >> "$env_example" << 'EOF'
287
302
 
288
- # AI Preview Image Generator API Keys
289
- # Get your key from: https://platform.openai.com/api-keys
290
- OPENAI_API_KEY=your-openai-api-key-here
303
+ cat >> "$env_example" << 'EOF'
291
304
 
292
- # Stability AI (alternative provider)
293
- # Get your key from: https://platform.stability.ai/
294
- STABILITY_API_KEY=your-stability-api-key-here
305
+ # AI Preview Image Generator credentials
306
+ # Renderer (the default provider is openai):
307
+ # OPENAI_API_KEY=... # https://platform.openai.com/api-keys (also powers --enhance)
308
+ # XAI_API_KEY=... # https://console.x.ai/
309
+ # STABILITY_API_KEY=... # https://platform.stability.ai/
310
+ # GEMINI_API_KEY=... # https://aistudio.google.com/apikey
311
+
312
+ # Claude orchestration (analyzes articles + reviews renders) — any ONE of
313
+ # (or a logged-in `claude` CLI; optional, degrades to template prompts):
314
+ # CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-... # from `claude setup-token`
315
+ # ANTHROPIC_API_KEY=sk-ant-... # from console.anthropic.com
295
316
  EOF
296
317
 
297
318
  log "Updated .env.example"
@@ -431,9 +452,10 @@ print_instructions() {
431
452
  echo ""
432
453
  echo -e "${YELLOW}NEXT STEPS:${NC}"
433
454
  echo ""
434
- echo " 1. ${BLUE}Set up your API key:${NC}"
435
- echo " cp .env.example .env"
436
- echo " # Edit .env and add your OPENAI_API_KEY"
455
+ echo " 1. ${BLUE}Set up credentials:${NC}"
456
+ echo " cp .env.example .env # add OPENAI_API_KEY (the renderer)"
457
+ echo " claude setup-token # optional: lets Claude analyze + review"
458
+ echo " (a logged-in \`claude\` CLI also works for the Claude side)"
437
459
  echo ""
438
460
  echo " 2. ${BLUE}Check for missing preview images:${NC}"
439
461
  echo " ./scripts/generate-preview-images.sh --list-missing"
@@ -50,8 +50,7 @@ scripts/install/
50
50
 
51
51
  ### The Spec
52
52
 
53
- A single JSON document (`.zer0/install.spec.json`) is the universal contract
54
- between all front-ends and the executor:
53
+ A single JSON document (`.zer0/install.spec.json`) is the universal contract between all front-ends and the executor:
55
54
 
56
55
  ```
57
56
  CLI flags → plan.sh → spec.json → apply.sh → tasks → files on disk
@@ -59,21 +58,18 @@ AI wizard → spec.json → apply.sh → tasks → files on disk
59
58
  TUI wizard → spec.json → apply.sh → tasks → files on disk
60
59
  ```
61
60
 
62
- The spec schema is defined in `ai/prompts/spec.schema.json`. The AI is
63
- constrained to emit only valid spec JSON — never raw file content.
61
+ The spec schema is defined in `ai/prompts/spec.schema.json`. The AI is constrained to emit only valid spec JSON — never raw file content.
64
62
 
65
63
  ### Write contract
66
64
 
67
- **ALL filesystem writes go through `fs.sh`**. No raw `>`, `cp`, or `echo >`
68
- outside of `fs.sh` functions. This enforces:
65
+ **ALL filesystem writes go through `fs.sh`**. No raw `>`, `cp`, or `echo >` outside of `fs.sh` functions. This enforces:
69
66
  - `--dry-run`: zero mutations
70
67
  - `--backup`: auto-backup before overwrite
71
68
  - `--force`: overwrite without prompting
72
69
 
73
70
  ### Template contract
74
71
 
75
- **ALL generated file content comes from `templates/`**. No heredocs in shell
76
- code. Templates use `{{VARIABLE}}` substitution via `template.sh::tmpl_apply`.
72
+ **ALL generated file content comes from `templates/`**. No heredocs in shell code. Templates use `{{VARIABLE}}` substitution via `template.sh::tmpl_apply`.
77
73
 
78
74
  ### Bash 3.2 compatibility
79
75
 
@@ -122,16 +118,13 @@ The AI path is a first-class citizen but never mandatory:
122
118
  - `ai_diagnose_run` → post-build error analysis
123
119
  - `ai_suggest_run` → profile + deploy recommendation
124
120
 
125
- All three are guarded by `ZER0_NO_AI=1` kill-switch and degrade gracefully
126
- to defaults or rule-based logic when AI is unavailable.
121
+ All three are guarded by `ZER0_NO_AI=1` kill-switch and degrade gracefully to defaults or rule-based logic when AI is unavailable.
127
122
 
128
123
  To enable: set `OPENAI_API_KEY` (or `OPENAI_BASE_URL` for Azure/Ollama).
129
124
 
130
125
  ## Deploy plugins
131
126
 
132
- Deploy targets listed in the spec (`SPEC_DEPLOY`) are dispatched as
133
- `tasks/deploy_<target>.sh` modules that render reusable templates from
134
- `templates/deploy/<target>/`. Built-in plugins:
127
+ Deploy targets listed in the spec (`SPEC_DEPLOY`) are dispatched as `tasks/deploy_<target>.sh` modules that render reusable templates from `templates/deploy/<target>/`. Built-in plugins:
135
128
 
136
129
  | Target | Writes |
137
130
  |-------------------|---------------------------------------------------------------------|
@@ -139,14 +132,11 @@ Deploy targets listed in the spec (`SPEC_DEPLOY`) are dispatched as
139
132
  | `azure-swa` | `.github/workflows/azure-static-web-apps.yml`, `staticwebapp.config.json` |
140
133
  | `docker-prod` | `Dockerfile.prod`, `docker-compose.prod.yml`, `nginx.conf`, `.dockerignore` |
141
134
 
142
- Add a new plugin by dropping `tasks/deploy_<target>.sh` with a
143
- `task_deploy_<target>_run` function plus a `templates/deploy/<target>/`
144
- template directory. The dispatcher is generic — no registry changes needed.
135
+ Add a new plugin by dropping `tasks/deploy_<target>.sh` with a `task_deploy_<target>_run` function plus a `templates/deploy/<target>/` template directory. The dispatcher is generic — no registry changes needed.
145
136
 
146
137
  ## Testing
147
138
 
148
- A regression harness lives at [`test/test_installer.sh`](../../test/test_installer.sh)
149
- and is wired into the main runner as the `installer` suite:
139
+ A regression harness lives at [`test/test_installer.sh`](../../test/test_installer.sh) and is wired into the main runner as the `installer` suite:
150
140
 
151
141
  ```bash
152
142
  # Standalone (auto-enables AI tier when OPENAI_API_KEY is set)
@@ -158,5 +148,4 @@ and is wired into the main runner as the `installer` suite:
158
148
  ./test/test_runner.sh --suites installer
159
149
  ```
160
150
 
161
- The harness covers: module syntax, all 6 profile inits, all 3 deploy plugins,
162
- all 5 agent flavours, and (when keyed) the full AI wizard → apply pipeline.
151
+ The harness covers: module syntax, all 6 profile inits, all 3 deploy plugins, all 5 agent flavours, and (when keyed) the full AI wizard → apply pipeline.
@@ -1,31 +1,24 @@
1
1
  # zer0-mistakes AI Installation Wizard
2
2
 
3
- You are the **zer0-mistakes installer wizard**. You convert the user's intent
4
- into a single, valid **install spec JSON** that conforms to the schema the
5
- caller will provide in the user prompt.
3
+ You are the **zer0-mistakes installer wizard**. You convert the user's intent into a single, valid **install spec JSON** that conforms to the schema the caller will provide in the user prompt.
6
4
 
7
- You NEVER write files yourself. You ONLY emit a JSON spec. The installer's
8
- `apply.sh` is the sole writer.
5
+ You NEVER write files yourself. You ONLY emit a JSON spec. The installer's `apply.sh` is the sole writer.
9
6
 
10
7
  ---
11
8
 
12
9
  ## Hard constraints (do not violate)
13
10
 
14
11
  1. **Output ONLY one JSON object.** No prose. No explanations. No markdown
15
- fences (no triple-backticks). The first character of your reply MUST be
16
- `{` and the last MUST be `}`.
12
+ fences (no triple-backticks). The first character of your reply MUST be `{` and the last MUST be `}`.
17
13
  2. **Conform exactly to the provided schema.** All `required` keys must be
18
14
  present. All enums must match. `additionalProperties: false` is enforced.
19
15
  3. **Honor every value the user already provided** in the "Key info" block of
20
- the user prompt — copy them through unchanged. Only fill in fields the
21
- user left as `not set`.
16
+ the user prompt — copy them through unchanged. Only fill in fields the user left as `not set`.
22
17
  4. **Always include `schema_version: "1"`**, the supplied `target_dir`, and
23
- a complete `options` object (all 5 required keys: `dry_run`, `force`,
24
- `backup`, `non_interactive`, `output`).
18
+ a complete `options` object (all 5 required keys: `dry_run`, `force`, `backup`, `non_interactive`, `output`).
25
19
  5. **`tasks` MUST be non-empty and end with `"marker"`.**
26
20
  6. **Be decisive.** If information is ambiguous, pick the most reasonable
27
- default and move on. Do not ask follow-up questions in non-interactive
28
- mode.
21
+ default and move on. Do not ask follow-up questions in non-interactive mode.
29
22
 
30
23
  ---
31
24
 
@@ -49,8 +42,7 @@ If a flag in "Key info" already names a profile, USE IT — do not second-guess.
49
42
 
50
43
  ## Task defaults (per profile)
51
44
 
52
- If you are unsure which tasks to enable, use these defaults. `marker` is
53
- always last.
45
+ If you are unsure which tasks to enable, use these defaults. `marker` is always last.
54
46
 
55
47
  - `minimal`: `["config", "gemfile", "gitignore", "marker"]`
56
48
  - `default`: `["config", "gemfile", "docker", "pages", "nav", "data", "gitignore", "readme", "agents", "marker"]`
@@ -102,8 +94,7 @@ Populate `agents` (array, may be empty) based on signals:
102
94
 
103
95
  ## Required output shape (example)
104
96
 
105
- The example below is illustrative. Adapt every value to the user's request.
106
- The exact field set is enforced by the schema in the user prompt.
97
+ The example below is illustrative. Adapt every value to the user's request. The exact field set is enforced by the schema in the user prompt.
107
98
 
108
99
  ```
109
100
  {
@@ -49,11 +49,7 @@ validate_environment false false # skip_publish=false, require_gh=false
49
49
 
50
50
  ### ✅ `scripts/bin/validate` - Preflight Validation
51
51
 
52
- Canonical command for local and CI preflight checks. It composes the release
53
- validation helpers with project-specific checks for version consistency, YAML
54
- configuration/data files, active configuration contracts, config-file
55
- classification, navigation data shape, Jekyll build/doctor, compiled assets,
56
- and optional test suites.
52
+ Canonical command for local and CI preflight checks. It composes the release validation helpers with project-specific checks for version consistency, YAML configuration/data files, active configuration contracts, config-file classification, navigation data shape, Jekyll build/doctor, compiled assets, and optional test suites.
57
53
 
58
54
  **Usage:**
59
55
 
@@ -1,8 +1,6 @@
1
1
  # scripts/lib/install/deploy/
2
2
 
3
- Pluggable deploy-target modules consumed by `scripts/bin/install deploy`
4
- (Phase 4 of the installer refactor). Each module configures one target;
5
- the registry coordinates discovery, dispatch, and verification.
3
+ Pluggable deploy-target modules consumed by `scripts/bin/install deploy` (Phase 4 of the installer refactor). Each module configures one target; the registry coordinates discovery, dispatch, and verification.
6
4
 
7
5
  ## Files
8
6
 
@@ -26,16 +24,12 @@ Every module must define:
26
24
  | `deploy_<slug>_verify <dir>` | Confirm expected files exist + look correct. |
27
25
  | `deploy_<slug>_doc_url` | Print the canonical upstream documentation URL. |
28
26
 
29
- Modules use the lightweight `deploy_render` placeholder set
30
- (`{{RUBY_VERSION}}`, `{{DEFAULT_BRANCH}}`, `{{GITHUB_USER}}`,
31
- `{{SITE_NAME}}`) so they can run without the full install.sh global
32
- environment.
27
+ Modules use the lightweight `deploy_render` placeholder set (`{{RUBY_VERSION}}`, `{{DEFAULT_BRANCH}}`, `{{GITHUB_USER}}`, `{{SITE_NAME}}`) so they can run without the full install.sh global environment.
33
28
 
34
29
  ## Adding a target
35
30
 
36
31
  1. Add `templates/deploy/<slug>/` with the assets (workflow YAML,
37
- Dockerfile, README, etc.). Use `*.template` for files that need
38
- variable substitution.
32
+ Dockerfile, README, etc.). Use `*.template` for files that need variable substitution.
39
33
  2. Create `scripts/lib/install/deploy/<slug>.sh` exporting the four
40
34
  hooks above.
41
35
  3. Add `<slug>` to `DEPLOY_TARGETS_LIST` in `registry.sh` (alphabetical).