container-superposition 0.1.5 → 0.1.7

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 (155) hide show
  1. package/README.md +3 -1
  2. package/dist/scripts/init.js +24 -4
  3. package/dist/scripts/init.js.map +1 -1
  4. package/dist/tool/commands/adopt.d.ts +3 -2
  5. package/dist/tool/commands/adopt.d.ts.map +1 -1
  6. package/dist/tool/commands/adopt.js +378 -67
  7. package/dist/tool/commands/adopt.js.map +1 -1
  8. package/dist/tool/commands/doctor.d.ts +3 -0
  9. package/dist/tool/commands/doctor.d.ts.map +1 -1
  10. package/dist/tool/commands/doctor.js +932 -69
  11. package/dist/tool/commands/doctor.js.map +1 -1
  12. package/dist/tool/commands/explain.d.ts.map +1 -1
  13. package/dist/tool/commands/explain.js +9 -0
  14. package/dist/tool/commands/explain.js.map +1 -1
  15. package/dist/tool/questionnaire/composer.d.ts.map +1 -1
  16. package/dist/tool/questionnaire/composer.js +212 -11
  17. package/dist/tool/questionnaire/composer.js.map +1 -1
  18. package/dist/tool/schema/overlay-loader.d.ts.map +1 -1
  19. package/dist/tool/schema/overlay-loader.js +1 -0
  20. package/dist/tool/schema/overlay-loader.js.map +1 -1
  21. package/dist/tool/schema/project-config.d.ts +3 -1
  22. package/dist/tool/schema/project-config.d.ts.map +1 -1
  23. package/dist/tool/schema/project-config.js +164 -13
  24. package/dist/tool/schema/project-config.js.map +1 -1
  25. package/dist/tool/schema/types.d.ts +85 -11
  26. package/dist/tool/schema/types.d.ts.map +1 -1
  27. package/dist/tool/utils/merge.d.ts.map +1 -1
  28. package/dist/tool/utils/merge.js +9 -0
  29. package/dist/tool/utils/merge.js.map +1 -1
  30. package/docs/adopt.md +20 -14
  31. package/docs/creating-overlays.md +151 -2
  32. package/docs/overlay-imports.md +125 -102
  33. package/docs/overlays.md +59 -6
  34. package/docs/quick-reference.md +99 -0
  35. package/docs/specs/002-superposition-config-file/plan.md +6 -1
  36. package/docs/specs/002-superposition-config-file/spec.md +6 -0
  37. package/docs/specs/002-superposition-config-file/tasks.md +2 -0
  38. package/docs/specs/003-mkdocs2-overlay/spec.md +114 -0
  39. package/docs/specs/004-doctor-fix/spec.md +70 -0
  40. package/docs/specs/005-cuda-overlay/spec.md +101 -0
  41. package/docs/specs/006-rocm-overlay/spec.md +109 -0
  42. package/docs/team-workflow.md +7 -1
  43. package/docs/workflows.md +3 -0
  44. package/features/cross-distro-packages/README.md +18 -0
  45. package/features/cross-distro-packages/devcontainer-feature.json +3 -3
  46. package/features/cross-distro-packages/install.sh +49 -7
  47. package/overlays/.shared/README.md +80 -21
  48. package/overlays/.shared/compose/common-healthchecks.md +60 -0
  49. package/overlays/.shared/vscode/recommended-extensions.json +15 -11
  50. package/overlays/alertmanager/setup.sh +4 -19
  51. package/overlays/alertmanager/verify.sh +8 -9
  52. package/overlays/all/README.md +43 -0
  53. package/overlays/all/devcontainer.patch.json +6 -0
  54. package/overlays/all/overlay.yml +14 -0
  55. package/overlays/amp/setup.sh +5 -0
  56. package/overlays/bun/setup.sh +10 -1
  57. package/overlays/bun/verify.sh +6 -1
  58. package/overlays/claude-code/setup.sh +5 -0
  59. package/overlays/cloudflared/setup.sh +9 -12
  60. package/overlays/codex/README.md +9 -6
  61. package/overlays/codex/devcontainer.patch.json +7 -1
  62. package/overlays/codex/setup.sh +5 -0
  63. package/overlays/codex/verify.sh +8 -0
  64. package/overlays/commitlint/setup.sh +5 -0
  65. package/overlays/cuda/README.md +179 -0
  66. package/overlays/cuda/devcontainer.patch.json +7 -0
  67. package/overlays/cuda/overlay.yml +17 -0
  68. package/overlays/cuda/setup.sh +32 -0
  69. package/overlays/cuda/verify.sh +38 -0
  70. package/overlays/devcontainer-cli/README.md +50 -0
  71. package/overlays/devcontainer-cli/devcontainer.patch.json +13 -0
  72. package/overlays/devcontainer-cli/overlay.yml +16 -0
  73. package/overlays/devcontainer-cli/setup.sh +14 -0
  74. package/overlays/direnv/devcontainer.patch.json +6 -0
  75. package/overlays/direnv/setup.sh +7 -6
  76. package/overlays/dotnet/setup.sh +14 -7
  77. package/overlays/duckdb/devcontainer.patch.json +1 -2
  78. package/overlays/gcloud/devcontainer.patch.json +0 -6
  79. package/overlays/gcloud/setup.sh +51 -0
  80. package/overlays/gemini-cli/setup.sh +5 -0
  81. package/overlays/git-helpers/devcontainer.patch.json +2 -1
  82. package/overlays/go/setup.sh +15 -14
  83. package/overlays/jaeger/overlay.yml +2 -0
  84. package/overlays/just/setup.sh +5 -17
  85. package/overlays/keycloak/docker-compose.yml +6 -4
  86. package/overlays/keycloak/verify.sh +4 -3
  87. package/overlays/kind/devcontainer.patch.json +1 -2
  88. package/overlays/kind/setup.sh +8 -17
  89. package/overlays/minio/setup.sh +10 -18
  90. package/overlays/mkdocs/overlay.yml +2 -1
  91. package/overlays/mkdocs2/README.md +135 -0
  92. package/overlays/mkdocs2/devcontainer.patch.json +19 -0
  93. package/overlays/mkdocs2/overlay.yml +17 -0
  94. package/overlays/mkdocs2/setup.sh +67 -0
  95. package/overlays/mkdocs2/verify.sh +35 -0
  96. package/overlays/modern-cli-tools/devcontainer.patch.json +7 -1
  97. package/overlays/modern-cli-tools/setup.sh +21 -71
  98. package/overlays/mongodb/devcontainer.patch.json +0 -6
  99. package/overlays/mongodb/setup.sh +59 -0
  100. package/overlays/mysql/verify.sh +4 -3
  101. package/overlays/nats/.env.example +1 -1
  102. package/overlays/nats/README.md +1 -1
  103. package/overlays/nats/docker-compose.yml +1 -1
  104. package/overlays/ngrok/setup.sh +9 -6
  105. package/overlays/nodejs/setup.sh +5 -0
  106. package/overlays/openapi-tools/devcontainer.patch.json +1 -2
  107. package/overlays/openapi-tools/setup.sh +9 -8
  108. package/overlays/opencode/setup.sh +5 -0
  109. package/overlays/otel-collector/overlay.yml +2 -0
  110. package/overlays/otel-collector/setup.sh +3 -16
  111. package/overlays/otel-demo-nodejs/verify.sh +8 -9
  112. package/overlays/otel-demo-python/verify.sh +16 -10
  113. package/overlays/pandoc/README.md +286 -0
  114. package/overlays/pandoc/devcontainer.patch.json +18 -0
  115. package/overlays/pandoc/overlay.yml +19 -0
  116. package/overlays/pandoc/setup.sh +293 -0
  117. package/overlays/pandoc/verify.sh +25 -0
  118. package/overlays/playwright/devcontainer.patch.json +3 -1
  119. package/overlays/playwright/setup.sh +37 -0
  120. package/overlays/postgres/docker-compose.yml +6 -0
  121. package/overlays/powershell/setup.sh +49 -13
  122. package/overlays/pre-commit/setup.sh +12 -3
  123. package/overlays/prometheus/overlay.yml +2 -0
  124. package/overlays/promtail/verify.sh +16 -10
  125. package/overlays/pulumi/devcontainer.patch.json +1 -1
  126. package/overlays/python/setup.sh +28 -9
  127. package/overlays/python/verify.sh +4 -2
  128. package/overlays/redpanda/docker-compose.yml +3 -5
  129. package/overlays/rocm/README.md +227 -0
  130. package/overlays/rocm/devcontainer.patch.json +4 -0
  131. package/overlays/rocm/overlay.yml +17 -0
  132. package/overlays/rocm/setup.sh +45 -0
  133. package/overlays/rocm/verify.sh +47 -0
  134. package/overlays/rust/setup.sh +11 -18
  135. package/overlays/spec-kit/setup.sh +7 -3
  136. package/overlays/sqlite/setup.sh +14 -14
  137. package/overlays/sqlserver/docker-compose.yml +3 -3
  138. package/overlays/sqlserver/verify.sh +22 -5
  139. package/overlays/tempo/verify.sh +16 -10
  140. package/overlays/tilt/devcontainer.patch.json +1 -2
  141. package/overlays/tilt/setup.sh +14 -4
  142. package/overlays/windsurf-cli/setup.sh +27 -4
  143. package/overlays/windsurf-cli/verify.sh +13 -3
  144. package/package.json +2 -1
  145. package/templates/scripts/setup-utils.sh +228 -0
  146. package/tool/schema/config.schema.json +110 -8
  147. package/tool/schema/overlay-manifest.schema.json +5 -0
  148. package/overlays/.shared/compose/common-healthchecks.yml +0 -38
  149. /package/overlays/otel-demo-nodejs/{Dockerfile-otel-demo-nodejs → Dockerfile} +0 -0
  150. /package/overlays/otel-demo-nodejs/{package-otel-demo-nodejs.json → package.json} +0 -0
  151. /package/overlays/otel-demo-nodejs/{server-otel-demo-nodejs.js → server.js} +0 -0
  152. /package/overlays/otel-demo-nodejs/{tracing-otel-demo-nodejs.js → tracing.js} +0 -0
  153. /package/overlays/otel-demo-python/{Dockerfile-otel-demo-python → Dockerfile} +0 -0
  154. /package/overlays/otel-demo-python/{app-otel-demo-python.py → app.py} +0 -0
  155. /package/overlays/otel-demo-python/{requirements-otel-demo-python.txt → requirements.txt} +0 -0
@@ -8,16 +8,19 @@ echo "🌐 Setting up ngrok..."
8
8
  # Install ngrok using official apt repository (provides signed packages)
9
9
  echo "📦 Installing ngrok from official repository..."
10
10
 
11
- # Add ngrok's GPG key and repository
12
- curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
13
- | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null
11
+ # Source shared setup utilities
12
+ # shellcheck source=setup-utils.sh
13
+ source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
14
14
 
15
+ # Add ngrok GPG key and repository
16
+ # Note: ngrok uses .asc (armored) format, piped directly to trusted.gpg.d (no --dearmor needed)
17
+ curl -fsSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
18
+ | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null
15
19
  echo "deb https://ngrok-agent.s3.amazonaws.com buster main" \
16
- | sudo tee /etc/apt/sources.list.d/ngrok.list
20
+ | sudo tee /etc/apt/sources.list.d/ngrok.list >/dev/null
17
21
 
18
22
  # Update and install
19
- sudo apt-get update -qq
20
- sudo apt-get install -y ngrok
23
+ apt_install ngrok
21
24
 
22
25
  # Verify installation
23
26
  if command -v ngrok &> /dev/null; then
@@ -3,6 +3,11 @@
3
3
 
4
4
  set -e
5
5
 
6
+ # Source shared setup utilities (provides load_nvm)
7
+ # shellcheck source=setup-utils.sh
8
+ source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
9
+ load_nvm
10
+
6
11
  # Extract overlay name from script filename (setup-<overlay>.sh -> <overlay>)
7
12
  OVERLAY_NAME=$(basename "$0" | sed 's/setup-//;s/\.sh$//')
8
13
 
@@ -5,6 +5,5 @@
5
5
  "apt": "curl",
6
6
  "apk": "curl"
7
7
  }
8
- },
9
- "postCreateCommand": "bash .devcontainer/scripts/setup-openapi-tools.sh"
8
+ }
10
9
  }
@@ -3,19 +3,20 @@
3
3
 
4
4
  set -e
5
5
 
6
+ # Source shared setup utilities (provides load_nvm)
7
+ # shellcheck source=setup-utils.sh
8
+ source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
9
+ load_nvm
10
+
6
11
  echo "🔧 Setting up OpenAPI Tools..."
7
12
 
8
13
  # Install OpenAPI tools globally via npm
9
14
  echo "📦 Installing OpenAPI tools..."
10
15
 
11
- # Install swagger-cli (OpenAPI validation)
12
- npm install -g @apidevtools/swagger-cli || echo "⚠️ swagger-cli already installed or failed"
13
-
14
- # Install spectral (OpenAPI linting)
15
- npm install -g @stoplight/spectral-cli || echo "⚠️ spectral already installed or failed"
16
-
17
- # Install redocly CLI (documentation and bundling)
18
- npm install -g @redocly/cli || echo "⚠️ redocly already installed or failed"
16
+ # Wrap each install in run_spinner to suppress noisy deprecation warnings
17
+ run_spinner "swagger-cli" npm install -g @apidevtools/swagger-cli
18
+ run_spinner "spectral" npm install -g @stoplight/spectral-cli
19
+ run_spinner "redocly" npm install -g @redocly/cli
19
20
 
20
21
  # Verify installations
21
22
  echo ""
@@ -3,6 +3,11 @@
3
3
 
4
4
  set -e
5
5
 
6
+ # Source shared setup utilities (provides load_nvm)
7
+ # shellcheck source=setup-utils.sh
8
+ source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
9
+ load_nvm
10
+
6
11
  echo "📦 Installing opencode AI coding agent..."
7
12
 
8
13
  # Install opencode-ai globally
@@ -19,3 +19,5 @@ ports:
19
19
  - 8888
20
20
  - 8889
21
21
  order: 2
22
+ imports:
23
+ - .shared/otel/instrumentation.env
@@ -5,23 +5,10 @@ set -e
5
5
 
6
6
  echo "🔧 Configuring OpenTelemetry Collector trace backend..."
7
7
 
8
- # Determine workspace root dynamically
9
- WORKSPACE_ROOT="${LOCAL_WORKSPACE_FOLDER:-$PWD}"
10
-
11
- if [ ! -d "$WORKSPACE_ROOT/.devcontainer" ]; then
12
- if [ -d "/workspaces" ]; then
13
- FIRST_WORKSPACE_DIR="$(find /workspaces -maxdepth 1 -mindepth 1 -type d 2>/dev/null | head -n 1)"
14
- if [ -n "$FIRST_WORKSPACE_DIR" ] && [ -d "$FIRST_WORKSPACE_DIR/.devcontainer" ]; then
15
- WORKSPACE_ROOT="$FIRST_WORKSPACE_DIR"
16
- fi
17
- fi
18
- fi
19
-
20
- if [ ! -d "$WORKSPACE_ROOT/.devcontainer" ] && [ -d "/workspace/.devcontainer" ]; then
21
- WORKSPACE_ROOT="/workspace"
22
- fi
8
+ # Resolve the .devcontainer directory relative to this script.
9
+ DEVCONTAINER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. && pwd)"
23
10
 
24
- OTEL_CONFIG="$WORKSPACE_ROOT/.devcontainer/otel-collector-config-otel-collector.yaml"
11
+ OTEL_CONFIG="$DEVCONTAINER_DIR/otel-collector-config-otel-collector.yaml"
25
12
 
26
13
  if [ ! -f "$OTEL_CONFIG" ]; then
27
14
  echo "⚠️ OTel Collector config not found"
@@ -6,19 +6,18 @@ echo "🔍 Verifying OTel Demo (Node.js) installation..."
6
6
  # Track overall success
7
7
  ALL_CHECKS_PASSED=true
8
8
 
9
- # Check if service is running
10
- if docker ps --format '{{.Names}}' | grep -q otel-demo-nodejs; then
11
- echo " OTel Demo (Node.js) service is running"
9
+ # Check if HTTP health endpoint is accessible (primary health signal).
10
+ # docker ps is informational only not reliably accessible in all devcontainers.
11
+ if curl -s -o /dev/null -w "%{http_code}" http://otel-demo-nodejs:8080/health 2>/dev/null | grep -q "200"; then
12
+ echo "✓ Demo app HTTP endpoint is accessible"
12
13
  else
13
- echo "✗ OTel Demo (Node.js) service is not running"
14
+ echo "✗ Demo app HTTP endpoint not responding (http://otel-demo-nodejs:8080/health)"
14
15
  ALL_CHECKS_PASSED=false
15
16
  fi
16
17
 
17
- # Check if HTTP endpoint is accessible
18
- if curl -s -o /dev/null -w "%{http_code}" http://otel-demo-nodejs:8080/health 2>/dev/null | grep -q "200"; then
19
- echo "✓ Demo app HTTP endpoint is accessible"
20
- else
21
- echo "⚠️ Demo app HTTP endpoint not responding yet (may still be starting)"
18
+ # Informational: check via docker ps if available.
19
+ if docker ps --format '{{.Names}}' 2>/dev/null | grep -q otel-demo-nodejs; then
20
+ echo "✓ OTel Demo (Node.js) container visible in docker ps"
22
21
  fi
23
22
 
24
23
  # Final result
@@ -6,19 +6,25 @@ echo "🔍 Verifying OTel Demo (Python) installation..."
6
6
  # Track overall success
7
7
  ALL_CHECKS_PASSED=true
8
8
 
9
- # Check if service is running
10
- if docker ps --format '{{.Names}}' | grep -q otel-demo-python; then
11
- echo "✓ OTel Demo (Python) service is running"
12
- else
13
- echo " OTel Demo (Python) service is not running"
9
+ # Wait for demo app HTTP health endpoint (primary health signal).
10
+ # docker ps is informational only not reliably accessible in all devcontainers.
11
+ APP_READY=false
12
+ for i in {1..40}; do
13
+ if curl -s -o /dev/null -w "%{http_code}" http://otel-demo-python:8081/health 2>/dev/null | grep -q "200"; then
14
+ echo "✓ Demo app HTTP endpoint is accessible"
15
+ APP_READY=true
16
+ break
17
+ fi
18
+ sleep 3
19
+ done
20
+ if [ "$APP_READY" = false ]; then
21
+ echo "✗ Demo app HTTP endpoint not responding after 120 s (http://otel-demo-python:8081/health)"
14
22
  ALL_CHECKS_PASSED=false
15
23
  fi
16
24
 
17
- # Check if HTTP endpoint is accessible
18
- if curl -s -o /dev/null -w "%{http_code}" http://otel-demo-python:8081/health 2>/dev/null | grep -q "200"; then
19
- echo "✓ Demo app HTTP endpoint is accessible"
20
- else
21
- echo "⚠️ Demo app HTTP endpoint not responding yet (may still be starting)"
25
+ # Informational: check via docker ps if available.
26
+ if docker ps --format '{{.Names}}' 2>/dev/null | grep -q otel-demo-python; then
27
+ echo "✓ OTel Demo (Python) container visible in docker ps"
22
28
  fi
23
29
 
24
30
  # Final result
@@ -0,0 +1,286 @@
1
+ # Pandoc PDF Overlay
2
+
3
+ Adds a complete Markdown → PDF pipeline to your devcontainer, powered by Pandoc, XeLaTeX, and optional Mermaid diagram rendering.
4
+
5
+ ## Features
6
+
7
+ - **Pandoc 3.x** — Latest release binary from GitHub (not the outdated apt version)
8
+ - **TeX Live / XeLaTeX** — Full Unicode-capable PDF engine (`texlive-xetex`, `texlive-fonts-extra`, `texlive-latex-extra`)
9
+ - **Quality fonts** — Carlito (body), JetBrains Mono (code), Noto Sans Symbols 2 (Unicode fallback), and Noto Color Emoji via system packages
10
+ - Uses the `cross-distro-packages` feature with fallback package names for Carlito (`fonts-carlito|fonts-crosextra-carlito`)
11
+ - **`diagram.lua`** — Lua filter from [pandoc-ext/diagram](https://github.com/pandoc-ext/diagram) for rendering code-block diagrams
12
+ - **`emoji-fallback.lua`** — Built-in Lua filter that rewrites unsupported emoji and flag glyphs to plain-text placeholders for reliable XeLaTeX PDF builds
13
+ - **Mermaid CLI (`mmdc`)** — Installed when the `nodejs` overlay is present; skipped gracefully otherwise
14
+ - **`~/.pandoc/pandoc.yaml`** — Ready-to-use defaults file (XeLaTeX engine, font settings, table tweaks)
15
+ - **VS Code Extensions:** Markdown All in One (`yzhang.markdown-all-in-one`), markdownlint (`DavidAnson.vscode-markdownlint`)
16
+
17
+ ## How It Works
18
+
19
+ System packages are installed through the `cross-distro-packages` feature, which handles package-manager detection and now supports fallback package names for distro variants. The setup script then downloads the official Pandoc `.deb` from GitHub releases (Pandoc 3.x is required for `diagram.lua`'s `Figure` AST element). Chromium is installed system-wide to serve as Puppeteer's browser for Mermaid headless rendering.
20
+
21
+ The pipeline:
22
+
23
+ ```text
24
+ Markdown
25
+ -> pandoc
26
+ -> diagram.lua (Lua filter, optional)
27
+ -> mmdc (Mermaid CLI, headless Chromium)
28
+ -> XeLaTeX
29
+ -> PDF
30
+ ```
31
+
32
+ Font discovery is updated with `fc-cache -fv` after installation so XeLaTeX can locate the apt-installed fonts.
33
+
34
+ The generated defaults also enable an emoji fallback filter for LaTeX output. The overlay now installs Noto Color Emoji as well, which may improve glyph coverage in some contexts, but the fallback filter remains enabled because XeLaTeX still is not reliable for full emoji and flag rendering. The filter converts unsupported glyphs such as `🇵🇹` to `[PT]` and generic emoji such as `😀` to `[emoji]` before XeLaTeX runs, preventing the `Unicode character ... not set up for use with LaTeX` failure.
35
+
36
+ The setup script also installs a `/usr/local/bin/pandoc` wrapper that automatically applies `~/.pandoc/pandoc.yaml` unless you explicitly pass `-d` or `--defaults`. That makes plain commands like `pandoc doc.md -o doc.pdf` use the overlay defaults.
37
+
38
+ ## Common Commands
39
+
40
+ ### Basic PDF export
41
+
42
+ ```bash
43
+ # Uses the installed wrapper, which applies ~/.pandoc/pandoc.yaml automatically
44
+ pandoc document.md -o document.pdf
45
+
46
+ # Override the output font on the fly
47
+ pandoc -d ~/.pandoc/pandoc.yaml -V mainfont="DejaVu Serif" document.md -o document.pdf
48
+ ```
49
+
50
+ ### PDF with Mermaid diagrams (requires nodejs overlay)
51
+
52
+ ```bash
53
+ pandoc --lua-filter ~/.pandoc/filters/diagram.lua \
54
+ document.md -o document.pdf
55
+ ```
56
+
57
+ ### Inspect installed fonts
58
+
59
+ ```bash
60
+ fc-list | grep -i carlito
61
+ fc-list | grep -i jetbrains
62
+ fc-list | grep -i "noto sans symbols"
63
+ ```
64
+
65
+ ### Check Pandoc version
66
+
67
+ ```bash
68
+ pandoc --version
69
+ ```
70
+
71
+ ## Mermaid Diagram Usage
72
+
73
+ Add fenced `mermaid` code blocks to your Markdown:
74
+
75
+ ````markdown
76
+ ```mermaid
77
+ graph TD
78
+ A[Start] --> B{Decision}
79
+ B -->|Yes| C[Action]
80
+ B -->|No| D[End]
81
+ ```
82
+ ````
83
+
84
+ Render with the `diagram.lua` filter:
85
+
86
+ ```bash
87
+ pandoc -d ~/.pandoc/pandoc.yaml \
88
+ --lua-filter ~/.pandoc/filters/diagram.lua \
89
+ document.md -o document.pdf
90
+ ```
91
+
92
+ The filter invokes `mmdc` for each `mermaid` block, producing a PNG that XeLaTeX embeds in the PDF. The Puppeteer configuration at `~/.config/mermaid/puppeteer-config.json` points `mmdc` at the system Chromium with `--no-sandbox`, which is required inside containers.
93
+
94
+ ## Configuration
95
+
96
+ ### Default `~/.pandoc/pandoc.yaml`
97
+
98
+ The setup script writes a defaults file with proven settings:
99
+
100
+ ```yaml
101
+ pdf-engine: xelatex
102
+ filters:
103
+ - /home/your-user/.pandoc/filters/emoji-fallback.lua
104
+
105
+ variables:
106
+ mainfont: 'Carlito'
107
+ monofont: 'JetBrains Mono'
108
+ fallbackfont: 'Noto Sans Symbols 2'
109
+ fontsize: 11pt
110
+ linestretch: 1.15
111
+ geometry:
112
+ - top=16mm
113
+ - bottom=16mm
114
+ - left=14mm
115
+ - right=14mm
116
+ header-includes:
117
+ - |
118
+ \usepackage{etoolbox}
119
+ \setlength{\tabcolsep}{3pt}
120
+ \renewcommand{\arraystretch}{1.05}
121
+ \AtBeginEnvironment{longtable}{\small}
122
+ \AtBeginEnvironment{tabular}{\small}
123
+ ```
124
+
125
+ ### Per-project override
126
+
127
+ Create a `pandoc.yaml` in your project directory to override the defaults:
128
+
129
+ ```yaml
130
+ # project/pandoc.yaml
131
+ pdf-engine: xelatex
132
+ variables:
133
+ mainfont: 'DejaVu Serif'
134
+ fontsize: 12pt
135
+ toc: true
136
+ toc-depth: 3
137
+ number-sections: true
138
+ filters:
139
+ - /home/your-user/.pandoc/filters/emoji-fallback.lua
140
+ - /home/your-user/.pandoc/filters/diagram.lua
141
+ ```
142
+
143
+ Then build with:
144
+
145
+ ```bash
146
+ pandoc -d pandoc.yaml document.md -o document.pdf
147
+ ```
148
+
149
+ ### Enable TOC and section numbering
150
+
151
+ Uncomment the relevant lines in `~/.pandoc/pandoc.yaml`:
152
+
153
+ ```yaml
154
+ toc: true
155
+ toc-depth: 3
156
+ number-sections: true
157
+ ```
158
+
159
+ ### Enable Mermaid rendering by default
160
+
161
+ Uncomment in `~/.pandoc/pandoc.yaml`:
162
+
163
+ ```yaml
164
+ filters:
165
+ - /home/your-user/.pandoc/filters/emoji-fallback.lua
166
+ - /home/your-user/.pandoc/filters/diagram.lua
167
+ ```
168
+
169
+ ## Unicode and Emoji
170
+
171
+ XeLaTeX handles normal Unicode text well with the bundled fonts. The overlay now also installs Noto Color Emoji, which can help with emoji coverage, but the failure mode in PDF builds is still usually emoji or regional-indicator flags, for example `🇵🇹`, which XeLaTeX may reject before font fallback can help.
172
+
173
+ The overlay now enables `~/.pandoc/filters/emoji-fallback.lua` by default for LaTeX output. It keeps normal Unicode text intact and rewrites unsupported emoji to plain-text placeholders:
174
+
175
+ - `🇵🇹 Porto` becomes `[PT] Porto`
176
+ - `😀` becomes `[emoji]`
177
+
178
+ If you want to experiment with more native emoji rendering, keep the installed emoji font and override the default Pandoc/LaTeX settings in a project-local `pandoc.yaml`, but the placeholder filter is still the reliable default for PDF generation.
179
+
180
+ ## Use Cases
181
+
182
+ - **Architecture documentation** — Architecture Decision Records (ADRs), system design docs
183
+ - **API specifications** — OpenAPI-style documentation with code samples
184
+ - **Technical reports** — Multi-section documents with tables and diagrams
185
+ - **README to PDF** — Convert project READMEs to distributable PDF format
186
+
187
+ **Integrates well with:**
188
+
189
+ - `nodejs` overlay — Enables Mermaid CLI for diagram rendering
190
+ - `git-helpers` overlay — Commit generated PDFs alongside source Markdown
191
+ - `modern-cli-tools` overlay — Use `bat` to preview Markdown, `rg` to search documents
192
+
193
+ ## Troubleshooting
194
+
195
+ ### `xelatex: command not found`
196
+
197
+ TeX Live was not installed correctly. Re-run the setup script:
198
+
199
+ ```bash
200
+ bash .devcontainer/scripts/setup-pandoc.sh
201
+ ```
202
+
203
+ ### Missing glyph warnings / blank characters in PDF
204
+
205
+ The font does not include that glyph. For common Unicode symbols, Noto Sans Symbols 2 covers most cases. Verify it is installed:
206
+
207
+ ```bash
208
+ fc-list | grep -i "noto sans symbols 2"
209
+ ```
210
+
211
+ If not found, rebuild the font cache:
212
+
213
+ ```bash
214
+ sudo fc-cache -fv
215
+ ```
216
+
217
+ ### Wide tables overflow page margins
218
+
219
+ The `header-includes` in `pandoc.yaml` applies `\small` inside `longtable` and `tabular` environments. For very wide tables, also add `\tiny` or use column width constraints in your Markdown:
220
+
221
+ ```markdown
222
+ | Col 1 | Col 2 | Col 3 |
223
+ | :---- | :---- | :---- |
224
+ | data | data | data |
225
+ ```
226
+
227
+ ### Mermaid: Chromium crashes or `--no-sandbox` error
228
+
229
+ The Puppeteer config at `~/.config/mermaid/puppeteer-config.json` must set `--no-sandbox`:
230
+
231
+ ```json
232
+ {
233
+ "executablePath": "/usr/bin/chromium",
234
+ "args": ["--no-sandbox", "--disable-setuid-sandbox"]
235
+ }
236
+ ```
237
+
238
+ Verify the file exists and contains the correct content:
239
+
240
+ ```bash
241
+ cat ~/.config/mermaid/puppeteer-config.json
242
+ ```
243
+
244
+ ### `mmdc` not found
245
+
246
+ The `nodejs` overlay must be selected to install Mermaid CLI. Check if Node.js is available:
247
+
248
+ ```bash
249
+ node --version
250
+ npm --version
251
+ mmdc --version
252
+ ```
253
+
254
+ If Node.js is present but `mmdc` is missing, install it manually:
255
+
256
+ ```bash
257
+ npm install -g @mermaid-js/mermaid-cli
258
+ ```
259
+
260
+ ### Upgrading Pandoc
261
+
262
+ To upgrade to a newer Pandoc release, update `PANDOC_VERSION` in `setup.sh` and re-run it:
263
+
264
+ ```bash
265
+ PANDOC_VERSION=3.7.0 # update as needed
266
+ ARCH=$(dpkg --print-architecture)
267
+ PANDOC_DEB="pandoc-${PANDOC_VERSION}-1-${ARCH}.deb"
268
+ curl -fsSL "https://github.com/jgm/pandoc/releases/download/${PANDOC_VERSION}/${PANDOC_DEB}" \
269
+ -o "/tmp/${PANDOC_DEB}"
270
+ sudo dpkg -i "/tmp/${PANDOC_DEB}"
271
+ rm "/tmp/${PANDOC_DEB}"
272
+ ```
273
+
274
+ ## References
275
+
276
+ - [Pandoc releases](https://github.com/jgm/pandoc/releases)
277
+ - [pandoc-ext/diagram Lua filter](https://github.com/pandoc-ext/diagram)
278
+ - [Mermaid CLI](https://github.com/mermaid-js/mermaid-cli)
279
+ - [Puppeteer in containers](https://pptr.dev/troubleshooting#running-puppeteer-in-docker)
280
+ - [TeX Live packages](https://packages.debian.org/search?keywords=texlive)
281
+
282
+ **Related Overlays:**
283
+
284
+ - `nodejs` — Required for Mermaid diagram rendering via `mmdc`
285
+ - `git-helpers` — Secure Git operations for committing generated docs
286
+ - `modern-cli-tools` — Productivity tools for Markdown authoring workflows
@@ -0,0 +1,18 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
3
+ "features": {
4
+ "./features/cross-distro-packages": {
5
+ "apt": "texlive-xetex texlive-fonts-recommended texlive-fonts-extra texlive-latex-extra texlive-lang-european lmodern fonts-carlito|fonts-crosextra-carlito fonts-noto fonts-noto-extra fonts-noto-mono fonts-jetbrains-mono fonts-noto-color-emoji fontconfig librsvg2-bin perl chromium",
6
+ "apk": "fontconfig noto-fonts-emoji|noto-emoji perl chromium"
7
+ }
8
+ },
9
+ "customizations": {
10
+ "vscode": {
11
+ "extensions": ["yzhang.markdown-all-in-one", "DavidAnson.vscode-markdownlint"]
12
+ }
13
+ },
14
+ "remoteEnv": {
15
+ "PUPPETEER_EXECUTABLE_PATH": "/usr/local/bin/chromium-no-sandbox",
16
+ "PUPPETEER_SKIP_DOWNLOAD": "true"
17
+ }
18
+ }
@@ -0,0 +1,19 @@
1
+ id: pandoc
2
+ name: Pandoc PDF
3
+ description: Pandoc with XeLaTeX, Mermaid diagrams, and quality fonts for Markdown-to-PDF export
4
+ category: dev
5
+ supports: []
6
+ requires: []
7
+ suggests:
8
+ - nodejs
9
+ conflicts: []
10
+ tags:
11
+ - dev
12
+ - pandoc
13
+ - pdf
14
+ - latex
15
+ - markdown
16
+ - docs
17
+ - mermaid
18
+ ports: []
19
+ order: 25