container-superposition 0.1.6 → 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 (143) hide show
  1. package/dist/scripts/init.js +7 -4
  2. package/dist/scripts/init.js.map +1 -1
  3. package/dist/tool/commands/adopt.d.ts.map +1 -1
  4. package/dist/tool/commands/adopt.js +1 -27
  5. package/dist/tool/commands/adopt.js.map +1 -1
  6. package/dist/tool/commands/doctor.d.ts +3 -0
  7. package/dist/tool/commands/doctor.d.ts.map +1 -1
  8. package/dist/tool/commands/doctor.js +932 -69
  9. package/dist/tool/commands/doctor.js.map +1 -1
  10. package/dist/tool/commands/explain.d.ts.map +1 -1
  11. package/dist/tool/commands/explain.js +9 -0
  12. package/dist/tool/commands/explain.js.map +1 -1
  13. package/dist/tool/questionnaire/composer.d.ts.map +1 -1
  14. package/dist/tool/questionnaire/composer.js +212 -11
  15. package/dist/tool/questionnaire/composer.js.map +1 -1
  16. package/dist/tool/schema/overlay-loader.d.ts.map +1 -1
  17. package/dist/tool/schema/overlay-loader.js +1 -0
  18. package/dist/tool/schema/overlay-loader.js.map +1 -1
  19. package/dist/tool/schema/project-config.d.ts +1 -1
  20. package/dist/tool/schema/project-config.d.ts.map +1 -1
  21. package/dist/tool/schema/project-config.js +94 -25
  22. package/dist/tool/schema/project-config.js.map +1 -1
  23. package/dist/tool/schema/types.d.ts +85 -11
  24. package/dist/tool/schema/types.d.ts.map +1 -1
  25. package/dist/tool/utils/merge.d.ts.map +1 -1
  26. package/dist/tool/utils/merge.js +9 -0
  27. package/dist/tool/utils/merge.js.map +1 -1
  28. package/docs/creating-overlays.md +151 -2
  29. package/docs/overlay-imports.md +125 -102
  30. package/docs/overlays.md +49 -6
  31. package/docs/quick-reference.md +99 -0
  32. package/docs/specs/003-mkdocs2-overlay/spec.md +114 -0
  33. package/docs/specs/004-doctor-fix/spec.md +70 -0
  34. package/docs/specs/005-cuda-overlay/spec.md +101 -0
  35. package/docs/specs/006-rocm-overlay/spec.md +109 -0
  36. package/overlays/.shared/README.md +80 -21
  37. package/overlays/.shared/compose/common-healthchecks.md +60 -0
  38. package/overlays/.shared/vscode/recommended-extensions.json +15 -11
  39. package/overlays/alertmanager/setup.sh +4 -19
  40. package/overlays/alertmanager/verify.sh +8 -9
  41. package/overlays/all/README.md +43 -0
  42. package/overlays/all/devcontainer.patch.json +6 -0
  43. package/overlays/all/overlay.yml +14 -0
  44. package/overlays/amp/setup.sh +5 -0
  45. package/overlays/bun/setup.sh +10 -1
  46. package/overlays/bun/verify.sh +6 -1
  47. package/overlays/claude-code/setup.sh +5 -0
  48. package/overlays/cloudflared/setup.sh +9 -12
  49. package/overlays/codex/README.md +9 -6
  50. package/overlays/codex/devcontainer.patch.json +7 -1
  51. package/overlays/codex/setup.sh +5 -0
  52. package/overlays/codex/verify.sh +8 -0
  53. package/overlays/commitlint/setup.sh +5 -0
  54. package/overlays/cuda/README.md +179 -0
  55. package/overlays/cuda/devcontainer.patch.json +7 -0
  56. package/overlays/cuda/overlay.yml +17 -0
  57. package/overlays/cuda/setup.sh +32 -0
  58. package/overlays/cuda/verify.sh +38 -0
  59. package/overlays/devcontainer-cli/README.md +50 -0
  60. package/overlays/devcontainer-cli/devcontainer.patch.json +13 -0
  61. package/overlays/devcontainer-cli/overlay.yml +16 -0
  62. package/overlays/devcontainer-cli/setup.sh +14 -0
  63. package/overlays/direnv/devcontainer.patch.json +6 -0
  64. package/overlays/direnv/setup.sh +7 -6
  65. package/overlays/dotnet/setup.sh +14 -7
  66. package/overlays/duckdb/devcontainer.patch.json +1 -2
  67. package/overlays/gcloud/devcontainer.patch.json +0 -6
  68. package/overlays/gcloud/setup.sh +51 -0
  69. package/overlays/gemini-cli/setup.sh +5 -0
  70. package/overlays/git-helpers/devcontainer.patch.json +2 -1
  71. package/overlays/go/setup.sh +15 -14
  72. package/overlays/jaeger/overlay.yml +2 -0
  73. package/overlays/just/setup.sh +5 -17
  74. package/overlays/keycloak/docker-compose.yml +6 -4
  75. package/overlays/keycloak/verify.sh +4 -3
  76. package/overlays/kind/devcontainer.patch.json +1 -2
  77. package/overlays/kind/setup.sh +8 -17
  78. package/overlays/minio/setup.sh +10 -18
  79. package/overlays/mkdocs/overlay.yml +2 -1
  80. package/overlays/mkdocs2/README.md +135 -0
  81. package/overlays/mkdocs2/devcontainer.patch.json +19 -0
  82. package/overlays/mkdocs2/overlay.yml +17 -0
  83. package/overlays/mkdocs2/setup.sh +67 -0
  84. package/overlays/mkdocs2/verify.sh +35 -0
  85. package/overlays/modern-cli-tools/devcontainer.patch.json +7 -1
  86. package/overlays/modern-cli-tools/setup.sh +21 -71
  87. package/overlays/mongodb/devcontainer.patch.json +0 -6
  88. package/overlays/mongodb/setup.sh +59 -0
  89. package/overlays/mysql/verify.sh +4 -3
  90. package/overlays/nats/.env.example +1 -1
  91. package/overlays/nats/README.md +1 -1
  92. package/overlays/nats/docker-compose.yml +1 -1
  93. package/overlays/ngrok/setup.sh +9 -6
  94. package/overlays/nodejs/setup.sh +5 -0
  95. package/overlays/openapi-tools/devcontainer.patch.json +1 -2
  96. package/overlays/openapi-tools/setup.sh +9 -8
  97. package/overlays/opencode/setup.sh +5 -0
  98. package/overlays/otel-collector/overlay.yml +2 -0
  99. package/overlays/otel-collector/setup.sh +3 -16
  100. package/overlays/otel-demo-nodejs/verify.sh +8 -9
  101. package/overlays/otel-demo-python/verify.sh +16 -10
  102. package/overlays/pandoc/README.md +22 -15
  103. package/overlays/pandoc/devcontainer.patch.json +6 -2
  104. package/overlays/pandoc/setup.sh +217 -18
  105. package/overlays/pandoc/verify.sh +16 -4
  106. package/overlays/playwright/devcontainer.patch.json +3 -1
  107. package/overlays/playwright/setup.sh +37 -0
  108. package/overlays/postgres/docker-compose.yml +6 -0
  109. package/overlays/powershell/setup.sh +49 -13
  110. package/overlays/pre-commit/setup.sh +12 -3
  111. package/overlays/prometheus/overlay.yml +2 -0
  112. package/overlays/promtail/verify.sh +16 -10
  113. package/overlays/pulumi/devcontainer.patch.json +1 -1
  114. package/overlays/python/setup.sh +28 -9
  115. package/overlays/python/verify.sh +4 -2
  116. package/overlays/redpanda/docker-compose.yml +3 -5
  117. package/overlays/rocm/README.md +227 -0
  118. package/overlays/rocm/devcontainer.patch.json +4 -0
  119. package/overlays/rocm/overlay.yml +17 -0
  120. package/overlays/rocm/setup.sh +45 -0
  121. package/overlays/rocm/verify.sh +47 -0
  122. package/overlays/rust/setup.sh +11 -18
  123. package/overlays/spec-kit/setup.sh +7 -3
  124. package/overlays/sqlite/setup.sh +14 -14
  125. package/overlays/sqlserver/docker-compose.yml +3 -3
  126. package/overlays/sqlserver/verify.sh +22 -5
  127. package/overlays/tempo/verify.sh +16 -10
  128. package/overlays/tilt/devcontainer.patch.json +1 -2
  129. package/overlays/tilt/setup.sh +14 -4
  130. package/overlays/windsurf-cli/setup.sh +27 -4
  131. package/overlays/windsurf-cli/verify.sh +13 -3
  132. package/package.json +2 -1
  133. package/templates/scripts/setup-utils.sh +228 -0
  134. package/tool/schema/config.schema.json +110 -8
  135. package/tool/schema/overlay-manifest.schema.json +5 -0
  136. package/overlays/.shared/compose/common-healthchecks.yml +0 -38
  137. /package/overlays/otel-demo-nodejs/{Dockerfile-otel-demo-nodejs → Dockerfile} +0 -0
  138. /package/overlays/otel-demo-nodejs/{package-otel-demo-nodejs.json → package.json} +0 -0
  139. /package/overlays/otel-demo-nodejs/{server-otel-demo-nodejs.js → server.js} +0 -0
  140. /package/overlays/otel-demo-nodejs/{tracing-otel-demo-nodejs.js → tracing.js} +0 -0
  141. /package/overlays/otel-demo-python/{Dockerfile-otel-demo-python → Dockerfile} +0 -0
  142. /package/overlays/otel-demo-python/{app-otel-demo-python.py → app.py} +0 -0
  143. /package/overlays/otel-demo-python/{requirements-otel-demo-python.txt → requirements.txt} +0 -0
@@ -4,25 +4,28 @@ Overlays can import shared configuration fragments from `overlays/.shared/` to r
4
4
 
5
5
  ## Overview
6
6
 
7
- Import functionality allows overlays to reference common configuration files instead of duplicating them in every overlay. This promotes DRY (Don't Repeat Yourself) principles and makes it easier to maintain consistent patterns.
7
+ The import mechanism allows overlays to reference common configuration files instead of duplicating them. This promotes DRY principles and makes it easier to maintain consistent patterns.
8
+
9
+ Imports are declared in the overlay's `overlay.yml` manifest and applied **before** the overlay's own `devcontainer.patch.json`, so each overlay can specialize on top of a shared baseline.
8
10
 
9
11
  ## Shared Directory Structure
10
12
 
11
13
  ```
12
14
  overlays/
13
15
  ├── .shared/
14
- │ ├── otel/ # OpenTelemetry configurations
15
- ├── otel-base-config.yaml # Base OTEL collector config
16
- │ │ └── instrumentation.env # Common env vars for instrumentation
17
- ├── compose/ # Docker Compose patterns
18
- │ └── common-healthchecks.yml # Standard healthcheck configurations
19
- │ └── vscode/ # VS Code extension sets
20
- └── recommended-extensions.json # Commonly recommended extensions
16
+ │ ├── README.md
17
+ │ ├── otel/
18
+ │ │ ├── instrumentation.env # OTEL SDK env vars imported by otel-collector, prometheus, jaeger
19
+ │ └── otel-base-config.yaml # Base OTEL collector pipeline config
20
+ ├── compose/
21
+ └── common-healthchecks.yml # Standard Docker Compose healthcheck patterns
22
+ └── vscode/
23
+ │ └── recommended-extensions.json # Commonly recommended VS Code extensions (devcontainer patch format)
21
24
  ├── prometheus/
22
- │ ├── overlay.yml # Can import from .shared/
25
+ │ ├── overlay.yml # imports: [.shared/otel/instrumentation.env]
23
26
  │ └── devcontainer.patch.json
24
27
  └── jaeger/
25
- ├── overlay.yml # Can import from .shared/
28
+ ├── overlay.yml # imports: [.shared/otel/instrumentation.env]
26
29
  └── devcontainer.patch.json
27
30
  ```
28
31
 
@@ -48,101 +51,128 @@ ports:
48
51
  - 9090
49
52
  imports:
50
53
  - .shared/otel/instrumentation.env
51
- - .shared/compose/common-healthchecks.yml
52
54
  ```
53
55
 
54
- ## Supported File Types
56
+ **Rules:**
57
+
58
+ - All paths **must** begin with `.shared/` — references outside `.shared/` are rejected (path traversal prevention)
59
+ - Paths are relative to `overlays/`
60
+ - Order is significant — fragments are applied in declaration order, then the overlay's own `devcontainer.patch.json`
61
+ - Missing files, unsupported types, or path traversal attempts cause generation to fail with a message identifying the overlay and the broken reference
55
62
 
56
- ### JSON Files (`.json`)
63
+ ## Supported File Types and Merge Behavior
57
64
 
58
- Merged as devcontainer patches, just like `devcontainer.patch.json`.
65
+ | Extension | How it is merged |
66
+ | ---------------- | ------------------------------------------------------------------------------ |
67
+ | `.json` | Deep-merged into `devcontainer.json` patch (same as `devcontainer.patch.json`) |
68
+ | `.yaml` / `.yml` | Loaded and deep-merged into `devcontainer.json` patch |
69
+ | `.env` | Concatenated into `.env.example` with a `# from .shared/…` comment header |
70
+ | Anything else | Rejected with a clear unsupported-type error |
59
71
 
60
- **Example: `.shared/vscode/recommended-extensions.json`**
72
+ ### JSON import example
61
73
 
62
- ```json
74
+ ```jsonc
75
+ // overlays/.shared/vscode/recommended-extensions.json
63
76
  {
77
+ "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
64
78
  "customizations": {
65
79
  "vscode": {
66
80
  "extensions": [
67
81
  "streetsidesoftware.code-spell-checker",
68
82
  "usernamehw.errorlens",
69
- "editorconfig.editorconfig"
70
- ]
71
- }
72
- }
83
+ "eamodio.gitlens",
84
+ ],
85
+ },
86
+ },
73
87
  }
74
88
  ```
75
89
 
76
- ### YAML Files (`.yaml`, `.yml`)
77
-
78
- Loaded and merged as devcontainer patches. Useful for complex configurations.
79
-
80
- **Example: `.shared/otel/otel-base-config.yaml`**
90
+ ### YAML import example
81
91
 
82
92
  ```yaml
83
- receivers:
84
- otlp:
85
- protocols:
86
- grpc:
87
- endpoint: 0.0.0.0:4317
88
- http:
89
- endpoint: 0.0.0.0:4318
93
+ # overlays/.shared/otel/otel-base-config.yaml
94
+ remoteEnv:
95
+ OTEL_SERVICE_NAME: my-service
96
+ OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4317
90
97
  ```
91
98
 
92
- ### Environment Files (`.env`)
99
+ ### ENV import example
93
100
 
94
- Merged into `.env.example` with a comment indicating the import source.
101
+ ```bash
102
+ # overlays/.shared/otel/instrumentation.env
103
+ # OpenTelemetry SDK Configuration
104
+ OTEL_SERVICE_NAME=my-service
105
+ OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
106
+ OTEL_EXPORTER_OTLP_PROTOCOL=grpc
107
+ OTEL_TRACES_SAMPLER=always_on
108
+ OTEL_TRACES_EXPORTER=otlp
109
+ OTEL_METRICS_EXPORTER=otlp
110
+ OTEL_LOGS_EXPORTER=otlp
111
+ ```
95
112
 
96
- **Example: `.shared/otel/instrumentation.env`**
113
+ When this `.env` fragment is imported, the generated `.env.example` will contain:
97
114
 
98
115
  ```bash
99
- # OpenTelemetry Configuration
116
+ # from .shared/otel/instrumentation.env
100
117
  OTEL_SERVICE_NAME=my-service
101
118
  OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
102
- OTEL_TRACES_SAMPLER=always_on
119
+ ...
103
120
  ```
104
121
 
105
- ## How Imports Work
122
+ ## Import Ordering and Conflict Resolution
106
123
 
107
- 1. **Resolution**: Imports are resolved relative to the `overlays/` directory
108
- 2. **Order**: Imports are applied in the order listed, then the overlay's own files
109
- 3. **Merging**:
110
- - JSON/YAML: Deep merged into devcontainer configuration
111
- - ENV: Concatenated into `.env.example` with source comments
112
- 4. **Validation**: Doctor command validates that all imports exist and are valid
124
+ Imports are applied in declaration order, then the overlay's own `devcontainer.patch.json` is applied last:
113
125
 
114
- ## Benefits
126
+ ```
127
+ [import 1] → [import 2] → … → [import N] → [overlay own patch]
128
+ ```
115
129
 
116
- ### Reduced Duplication
130
+ - The **second** import wins over the first on key conflict
131
+ - The **overlay's own patch always wins** over any shared fragment
117
132
 
118
- Before imports:
133
+ This means overlays can intentionally override shared defaults by setting the same key in their `devcontainer.patch.json`.
119
134
 
120
- ```
121
- prometheus/devcontainer.patch.json (200 lines with OTEL config)
122
- jaeger/devcontainer.patch.json (200 lines with OTEL config)
123
- grafana/devcontainer.patch.json (200 lines with OTEL config)
135
+ ## Worked Example: OTEL Instrumentation
136
+
137
+ Many observability overlays need OTEL environment variables. With imports, these are defined once:
138
+
139
+ **`overlays/.shared/otel/instrumentation.env`** — shared once
140
+
141
+ **`overlays/otel-collector/overlay.yml`:**
142
+
143
+ ```yaml
144
+ imports:
145
+ - .shared/otel/instrumentation.env
124
146
  ```
125
147
 
126
- After imports:
148
+ **`overlays/prometheus/overlay.yml`:**
127
149
 
150
+ ```yaml
151
+ imports:
152
+ - .shared/otel/instrumentation.env
128
153
  ```
129
- .shared/otel/otel-base-config.yaml (50 lines, shared)
130
- prometheus/overlay.yml (imports: [.shared/otel/otel-base-config.yaml])
131
- jaeger/overlay.yml (imports: [.shared/otel/otel-base-config.yaml])
132
- grafana/overlay.yml (imports: [.shared/otel/otel-base-config.yaml])
154
+
155
+ **`overlays/jaeger/overlay.yml`:**
156
+
157
+ ```yaml
158
+ imports:
159
+ - .shared/otel/instrumentation.env
133
160
  ```
134
161
 
135
- ### Consistency
162
+ When any of these overlays is used, the generated `.env.example` will contain the OTEL environment variables with a comment indicating they came from the shared fragment.
163
+
164
+ ## Security: Path Traversal Prevention
136
165
 
137
- All overlays using the same shared config stay in sync automatically.
166
+ Import paths are validated before any file is read:
138
167
 
139
- ### Maintainability
168
+ 1. The path **must** begin with `.shared/`
169
+ 2. The resolved absolute path **must** remain inside `overlays/.shared/`
140
170
 
141
- Update shared configuration once, all importing overlays benefit.
171
+ Any import that fails either check causes generation to abort with an error identifying the overlay and the rejected path. References like `../secret.json`, `/etc/passwd`, or `other-overlay/file.json` are all rejected.
142
172
 
143
- ## Validation
173
+ ## Validation via Doctor
144
174
 
145
- The `doctor` command validates imports:
175
+ The `doctor` command validates all imports for every overlay:
146
176
 
147
177
  ```bash
148
178
  container-superposition doctor
@@ -150,60 +180,53 @@ container-superposition doctor
150
180
 
151
181
  Checks performed:
152
182
 
153
- - Import files exist
154
- - File types are supported (`.json`, `.yaml`, `.yml`, `.env`)
155
- - No broken import references
156
-
157
- ## Creating Shared Configurations
158
-
159
- 1. **Identify common patterns** across overlays
160
- 2. **Extract to `.shared/` subdirectory** with descriptive path
161
- 3. **Update overlays** to import the shared file
162
- 4. **Test** that composition works correctly
163
- 5. **Document** the shared file's purpose in `.shared/README.md`
183
+ - Import path starts with `.shared/` (path traversal check)
184
+ - Import path resolves within `overlays/.shared/` (traversal check)
185
+ - Import file exists on disk
186
+ - File type is one of `.json`, `.yaml`, `.yml`, `.env`
164
187
 
165
- ## Example: OTEL Instrumentation
188
+ Broken references are reported with the overlay ID and the bad path so maintainers can fix them quickly.
166
189
 
167
- Many observability overlays need OTEL instrumentation. Instead of duplicating these environment variables:
190
+ ## Viewing Imports in `explain`
168
191
 
169
- **Create:** `overlays/.shared/otel/instrumentation.env`
192
+ When an overlay has imports, they are shown in the `explain` output:
170
193
 
171
194
  ```bash
172
- # OpenTelemetry SDK Configuration
173
- OTEL_SERVICE_NAME=my-service
174
- OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
175
- OTEL_EXPORTER_OTLP_PROTOCOL=grpc
176
- OTEL_RESOURCE_ATTRIBUTES=deployment.environment=development
177
- OTEL_TRACES_SAMPLER=always_on
178
- OTEL_TRACES_EXPORTER=otlp
179
- OTEL_METRICS_EXPORTER=otlp
180
- OTEL_LOGS_EXPORTER=otlp
195
+ container-superposition explain prometheus
181
196
  ```
182
197
 
183
- **Import in overlays:**
198
+ ```
199
+ Shared Imports:
200
+ (Fragments from overlays/.shared/ applied before this overlay)
201
+ 📎 .shared/otel/instrumentation.env
202
+ ```
184
203
 
185
- ```yaml
186
- # overlays/prometheus/overlay.yml
187
- imports:
188
- - .shared/otel/instrumentation.env
204
+ ## Creating Shared Configurations
189
205
 
190
- # overlays/jaeger/overlay.yml
191
- imports:
192
- - .shared/otel/instrumentation.env
193
- ```
206
+ 1. **Identify common patterns** across multiple overlays
207
+ 2. **Create `overlays/.shared/<category>/<name>.<ext>`** — use descriptive paths, one concern per file
208
+ 3. **Update overlays** to reference the fragment via `imports:` in their `overlay.yml`
209
+ 4. **Update `.shared/README.md`** to document the fragment's purpose and which overlays use it
210
+ 5. **Test** with `npm test` and `container-superposition doctor` to verify
211
+
212
+ ## Downstream Impact Awareness
213
+
214
+ A single change to a shared fragment affects every overlay that imports it. Before editing a shared fragment:
194
215
 
195
- Now all OTEL-compatible overlays share the same instrumentation configuration!
216
+ - Check `.shared/README.md` to see which overlays import it
217
+ - Use `grep -r "fragment-name" overlays/*/overlay.yml` to find all importers
218
+ - Run the full test suite after any shared fragment change
196
219
 
197
220
  ## Best Practices
198
221
 
199
- 1. **Keep shared files focused** - One concern per file
200
- 2. **Use descriptive paths** - `.shared/otel/instrumentation.env` not `.shared/env1.env`
201
- 3. **Document shared files** - Add comments explaining purpose and usage
202
- 4. **Version carefully** - Changes to shared files affect all importing overlays
203
- 5. **Test imports** - Verify overlay composition works after adding imports
222
+ 1. **One concern per file** `instrumentation.env` not `all-the-things.env`
223
+ 2. **Descriptive category paths** `.shared/otel/` not `.shared/misc/`
224
+ 3. **Comment your fragments** explain purpose and usage at the top of each file
225
+ 4. **Keep fragments small** big shared files create tight coupling
226
+ 5. **Overlay-specific overrides are fine** an overlay's own patch always wins; diverging from a shared baseline is expected and supported
204
227
 
205
228
  ## See Also
206
229
 
207
230
  - [Creating Overlays](creating-overlays.md)
208
- - [Overlay Metadata](overlay-metadata-archive.md)
209
- - [Doctor Command](../README.md#doctor-command)
231
+ - `overlays/.shared/README.md` — shared fragment catalogue with usage details
232
+ - CONTRIBUTING.md — overlay authoring guide
package/docs/overlays.md CHANGED
@@ -69,12 +69,13 @@ Jupyter notebook server for interactive computing and data science
69
69
 
70
70
  Material for MkDocs - professional documentation generator
71
71
 
72
- | Property | Value |
73
- | ------------ | ----------------------------------- |
74
- | **Category** | language |
75
- | **Requires** | `python` |
76
- | **Tags** | `documentation`, `mkdocs`, `python` |
77
- | **Ports** | 8000 |
72
+ | Property | Value |
73
+ | ------------- | ----------------------------------- |
74
+ | **Category** | language |
75
+ | **Requires** | `python` |
76
+ | **Conflicts** | `mkdocs2` |
77
+ | **Tags** | `documentation`, `mkdocs`, `python` |
78
+ | **Ports** | 8000 |
78
79
 
79
80
  ### Node.js (`nodejs`)
80
81
 
@@ -513,6 +514,26 @@ Conventional commits validation for automated releases
513
514
  | **Suggests** | `pre-commit` |
514
515
  | **Tags** | `dev`, `git`, `commits`, `semantic-release` |
515
516
 
517
+ ### CUDA (NVIDIA GPU) (`cuda`)
518
+
519
+ NVIDIA CUDA libraries and GPU passthrough for containerized ML/inference workloads
520
+
521
+ | Property | Value |
522
+ | ------------- | ------------------------------------------------- |
523
+ | **Category** | dev |
524
+ | **Conflicts** | `rocm` |
525
+ | **Tags** | `dev`, `gpu`, `cuda`, `nvidia`, `ml`, `inference` |
526
+
527
+ ### Dev Container CLI (`devcontainer-cli`)
528
+
529
+ Official devcontainer CLI for building and testing devcontainer configurations
530
+
531
+ | Property | Value |
532
+ | ------------ | --------------------------------------- |
533
+ | **Category** | dev |
534
+ | **Suggests** | `docker-sock`, `docker-in-docker` |
535
+ | **Tags** | `dev`, `devcontainer`, `cli`, `testing` |
536
+
516
537
  ### direnv (`direnv`)
517
538
 
518
539
  Per-directory environment variable management
@@ -602,6 +623,18 @@ Email testing tool with web UI and SMTP server
602
623
  | **Tags** | `dev`, `email`, `smtp`, `testing` |
603
624
  | **Ports** | [object Object], [object Object] |
604
625
 
626
+ ### MkDocs 2 (`mkdocs2`)
627
+
628
+ MkDocs 2.0 pre-release (encode/mkdocs) — smart, simple website design tool
629
+
630
+ | Property | Value |
631
+ | ------------- | ------------------------------------------ |
632
+ | **Category** | dev |
633
+ | **Requires** | `python` |
634
+ | **Conflicts** | `mkdocs` |
635
+ | **Tags** | `dev`, `documentation`, `mkdocs`, `python` |
636
+ | **Ports** | 8000 |
637
+
605
638
  ### Modern CLI Tools (`modern-cli-tools`)
606
639
 
607
640
  jq, yq, ripgrep, fd, bat - Essential modern command-line tools
@@ -662,6 +695,16 @@ Automated code quality gates with pre-commit hooks
662
695
  | **Suggests** | `commitlint` |
663
696
  | **Tags** | `dev`, `git`, `quality`, `hooks` |
664
697
 
698
+ ### ROCm (AMD GPU) (`rocm`)
699
+
700
+ AMD ROCm libraries and GPU passthrough for containerized ML/inference workloads
701
+
702
+ | Property | Value |
703
+ | ------------- | ---------------------------------------------- |
704
+ | **Category** | dev |
705
+ | **Conflicts** | `cuda` |
706
+ | **Tags** | `dev`, `gpu`, `rocm`, `amd`, `ml`, `inference` |
707
+
665
708
  ### Tilt (`tilt`)
666
709
 
667
710
  Live update and orchestration for Kubernetes development
@@ -162,6 +162,105 @@ npm run init -- \
162
162
  --cloud-tools aws-cli,azure-cli,kubectl-helm
163
163
  ```
164
164
 
165
+ ## Doctor Command
166
+
167
+ The `doctor` command validates the current environment and devcontainer configuration.
168
+
169
+ ### Basic Diagnostics
170
+
171
+ ```bash
172
+ # Run diagnostics against the default .devcontainer/
173
+ container-superposition doctor
174
+
175
+ # Specify a custom path
176
+ container-superposition doctor --output ./my-project/.devcontainer
177
+
178
+ # Point to a manifest file directly (outputPath is derived from the manifest)
179
+ container-superposition doctor --from-manifest ./superposition.json
180
+
181
+ # Load the output path from the repository project file (superposition.yml)
182
+ container-superposition doctor --from-project
183
+
184
+ # Run discovery relative to a different repository root
185
+ container-superposition doctor --project-root /path/to/repo
186
+
187
+ # Machine-readable JSON output
188
+ container-superposition doctor --json
189
+ ```
190
+
191
+ ### Auto-Repair with `--fix`
192
+
193
+ The `--fix` flag runs the full diagnosis and then attempts to automatically repair
194
+ any fixable issues:
195
+
196
+ ```bash
197
+ # Interactive auto-repair (text output)
198
+ container-superposition doctor --fix
199
+
200
+ # Machine-readable repair output (for CI/scripting)
201
+ container-superposition doctor --fix --json
202
+ ```
203
+
204
+ **Fix run output vocabulary:**
205
+
206
+ | Outcome | Meaning |
207
+ | ------------------------ | ---------------------------------------------------- |
208
+ | `fixed` | Tool changed the environment; re-check now passes |
209
+ | `already compliant` | No change needed — check already passed |
210
+ | `skipped` | Not attempted (prerequisite step failed) |
211
+ | `requires manual action` | Automation unsafe/unavailable; manual steps provided |
212
+
213
+ **Fixable issue classes:**
214
+
215
+ | Issue | Auto-fix condition |
216
+ | -------------------------------------------- | ---------------------------------------------------------- |
217
+ | Stale / legacy `superposition.json` manifest | Always — migrate to current schema |
218
+ | Missing or corrupt `devcontainer.json` | When a valid manifest is present — regenerate |
219
+ | Unsupported Node.js runtime | Only when `nvm`, `fnm`, or `volta` is installed |
220
+ | Docker daemon not accessible | Manual only — platform-specific restart instructions shown |
221
+
222
+ **Remediation ordering:** Manifest migration always runs before devcontainer regeneration.
223
+ If migration fails, regeneration is skipped and marked as `skipped`.
224
+
225
+ **Safety:** All file mutations use atomic write (write to `.tmp`, then rename).
226
+ A timestamped backup is created before any manifest is modified.
227
+
228
+ **Exit codes:**
229
+
230
+ - `0` — all findings resolved (success or already-compliant)
231
+ - `0` — some findings require manual action (`repaired-with-warnings`)
232
+ - `1` — unresolved failures remain after fix run
233
+
234
+ ### JSON Fix Run Structure
235
+
236
+ ```json
237
+ {
238
+ "outputPath": "./.devcontainer",
239
+ "requestedJson": true,
240
+ "initialFindings": [...],
241
+ "executions": [
242
+ {
243
+ "findingId": "manifest-version",
244
+ "remediationKey": "manifest-migration",
245
+ "attempted": true,
246
+ "outcome": "fixed",
247
+ "reason": "Manifest migrated to current schema version",
248
+ "changedFiles": [".devcontainer/superposition.json"],
249
+ "backupPath": ".devcontainer/superposition.json.backup-2026-03-19-..."
250
+ }
251
+ ],
252
+ "finalFindings": [...],
253
+ "summary": {
254
+ "fixed": 1,
255
+ "alreadyCompliant": 3,
256
+ "skipped": 0,
257
+ "requiresManualAction": 0,
258
+ "total": 4
259
+ },
260
+ "exitDisposition": "success"
261
+ }
262
+ ```
263
+
165
264
  ## Output Structure
166
265
 
167
266
  ### Minimal (plain + language)
@@ -0,0 +1,114 @@
1
+ # Feature Specification: MkDocs 2.x Overlay
2
+
3
+ **Feature Branch**: `copilot/add-mkdocs2-overlay`
4
+ **Created**: 2026-03-16
5
+ **Status**: Final
6
+ **Input**: Add a new `mkdocs2` overlay that installs MkDocs 2.x with the Material theme via direct `pip` install, keeping the existing `mkdocs` (MkDocs 1.x) overlay untouched for backward compatibility.
7
+
8
+ ## Review & Approval _(mandatory before implementation)_
9
+
10
+ - **Spec Path**: `docs/specs/003-mkdocs2-overlay/spec.md`
11
+ - **Commit Status**: Committed
12
+ - **Review Status**: Approved
13
+ - **Implementation Gate**: No implementation code may begin until this spec is committed and reviewed.
14
+
15
+ ## User Scenarios & Testing _(mandatory)_
16
+
17
+ ### User Story 1 - Use MkDocs 2.x in a devcontainer (Priority: P1)
18
+
19
+ A developer wants to write documentation using MkDocs 2.x with the Material theme inside a devcontainer without manually managing Python packages.
20
+
21
+ **Why this priority**: MkDocs 2.x is the currently maintained release. Users starting new documentation projects need a working overlay that installs the supported version.
22
+
23
+ **Independent Test**: Select the `mkdocs2` overlay (with `python` as a required dependency), rebuild the container, and confirm that `mkdocs --version` reports a 2.x release, `mkdocs new .` succeeds, and `mkdocs serve` starts the dev server on port 8000.
24
+
25
+ **Acceptance Scenarios**:
26
+
27
+ 1. **Given** a user selects the `mkdocs2` overlay, **When** the devcontainer is built, **Then** `mkdocs --version` reports a version matching `2.x`.
28
+ 2. **Given** the container is running, **When** the user runs `mkdocs serve`, **Then** the development server starts on port 8000 and VS Code forwards the port automatically.
29
+ 3. **Given** a `mkdocs.yml` with `theme: {name: material}`, **When** the user runs `mkdocs build`, **Then** the site is generated without errors into the `site/` directory.
30
+
31
+ ---
32
+
33
+ ### User Story 2 - Conflict enforcement between mkdocs and mkdocs2 (Priority: P1)
34
+
35
+ A user selects both `mkdocs` (1.x) and `mkdocs2` (2.x) and expects the tool to report a conflict.
36
+
37
+ **Why this priority**: Both overlays install incompatible versions of the `mkdocs` command into the same environment. Allowing both would produce unpredictable results.
38
+
39
+ **Independent Test**: Attempt to generate a devcontainer with both `mkdocs` and `mkdocs2` selected and confirm the tool surfaces a conflict and blocks generation.
40
+
41
+ **Acceptance Scenarios**:
42
+
43
+ 1. **Given** a user selects `mkdocs` and `mkdocs2` simultaneously, **When** the questionnaire processes the selection, **Then** a conflict is reported and the user is prompted to choose one.
44
+ 2. **Given** `mkdocs` conflicts with `mkdocs2` in `overlays/mkdocs/overlay.yml`, **When** the overlay loader reads both manifests, **Then** the conflict is recognised bidirectionally.
45
+
46
+ ---
47
+
48
+ ### User Story 3 - Backward compatibility for existing mkdocs users (Priority: P2)
49
+
50
+ An existing user who already has the `mkdocs` overlay selected is unaffected by the addition of the new overlay.
51
+
52
+ **Why this priority**: Introducing a new overlay must not break users who rely on the existing one.
53
+
54
+ **Independent Test**: Generate a devcontainer using only the `mkdocs` overlay and confirm the output is identical to what it was before `mkdocs2` was added.
55
+
56
+ **Acceptance Scenarios**:
57
+
58
+ 1. **Given** a user's `superposition.json` references only `mkdocs`, **When** they run `regen`, **Then** the output is identical to before and contains no `mkdocs2`-related changes.
59
+
60
+ ---
61
+
62
+ ## Design
63
+
64
+ ### Installation Method
65
+
66
+ The `mkdocs2` overlay installs packages via `pip` directly into the workspace
67
+ `.venv` virtual environment (created by the `python` overlay, which is a hard
68
+ dependency). The overlay's `setup.sh` creates the `.venv` if it does not exist
69
+ yet, so it is self-contained even when run before the `python` overlay's setup
70
+ script completes.
71
+
72
+ ```bash
73
+ pip install --no-cache-dir \
74
+ "mkdocs>=2.0,<3.0" \
75
+ "mkdocs-material>=9.0" \
76
+ "mkdocs-minify-plugin" \
77
+ "mkdocs-redirects" \
78
+ "pymdown-extensions"
79
+ ```
80
+
81
+ This approach is preferred over the `ghcr.io/devcontainers-extra/features/mkdocs:2`
82
+ devcontainer feature because it gives precise version control and installs into
83
+ the same virtual environment used by the rest of the project.
84
+
85
+ ### Category
86
+
87
+ `dev` — MkDocs is a documentation tool, not a language runtime. This differs
88
+ from the legacy `mkdocs` overlay which uses `language` for historical reasons.
89
+
90
+ ### Conflict Model
91
+
92
+ `mkdocs` ↔ `mkdocs2` conflict is bidirectional:
93
+
94
+ - `overlays/mkdocs/overlay.yml`: `conflicts: [mkdocs2]`
95
+ - `overlays/mkdocs2/overlay.yml`: `conflicts: [mkdocs]`
96
+
97
+ ### TypeScript Type
98
+
99
+ `mkdocs2` is added to the `DevTool` union in `tool/schema/types.ts`, making it
100
+ part of the `OverlayId` union used throughout the type system.
101
+
102
+ ---
103
+
104
+ ## Files
105
+
106
+ | File | Description |
107
+ | ------------------------------------------ | -------------------------------------------------- |
108
+ | `overlays/mkdocs2/overlay.yml` | Overlay manifest |
109
+ | `overlays/mkdocs2/devcontainer.patch.json` | Port 8000 forwarding + VS Code Markdown extensions |
110
+ | `overlays/mkdocs2/setup.sh` | Pip install into `.venv` |
111
+ | `overlays/mkdocs2/verify.sh` | Confirms MkDocs 2.x is installed |
112
+ | `overlays/mkdocs2/README.md` | User documentation |
113
+ | `overlays/mkdocs/overlay.yml` | Updated to add bidirectional conflict |
114
+ | `tool/schema/types.ts` | Adds `mkdocs2` to `DevTool` |