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.
- package/README.md +3 -1
- package/dist/scripts/init.js +24 -4
- package/dist/scripts/init.js.map +1 -1
- package/dist/tool/commands/adopt.d.ts +3 -2
- package/dist/tool/commands/adopt.d.ts.map +1 -1
- package/dist/tool/commands/adopt.js +378 -67
- package/dist/tool/commands/adopt.js.map +1 -1
- package/dist/tool/commands/doctor.d.ts +3 -0
- package/dist/tool/commands/doctor.d.ts.map +1 -1
- package/dist/tool/commands/doctor.js +932 -69
- package/dist/tool/commands/doctor.js.map +1 -1
- package/dist/tool/commands/explain.d.ts.map +1 -1
- package/dist/tool/commands/explain.js +9 -0
- package/dist/tool/commands/explain.js.map +1 -1
- package/dist/tool/questionnaire/composer.d.ts.map +1 -1
- package/dist/tool/questionnaire/composer.js +212 -11
- package/dist/tool/questionnaire/composer.js.map +1 -1
- package/dist/tool/schema/overlay-loader.d.ts.map +1 -1
- package/dist/tool/schema/overlay-loader.js +1 -0
- package/dist/tool/schema/overlay-loader.js.map +1 -1
- package/dist/tool/schema/project-config.d.ts +3 -1
- package/dist/tool/schema/project-config.d.ts.map +1 -1
- package/dist/tool/schema/project-config.js +164 -13
- package/dist/tool/schema/project-config.js.map +1 -1
- package/dist/tool/schema/types.d.ts +85 -11
- package/dist/tool/schema/types.d.ts.map +1 -1
- package/dist/tool/utils/merge.d.ts.map +1 -1
- package/dist/tool/utils/merge.js +9 -0
- package/dist/tool/utils/merge.js.map +1 -1
- package/docs/adopt.md +20 -14
- package/docs/creating-overlays.md +151 -2
- package/docs/overlay-imports.md +125 -102
- package/docs/overlays.md +59 -6
- package/docs/quick-reference.md +99 -0
- package/docs/specs/002-superposition-config-file/plan.md +6 -1
- package/docs/specs/002-superposition-config-file/spec.md +6 -0
- package/docs/specs/002-superposition-config-file/tasks.md +2 -0
- package/docs/specs/003-mkdocs2-overlay/spec.md +114 -0
- package/docs/specs/004-doctor-fix/spec.md +70 -0
- package/docs/specs/005-cuda-overlay/spec.md +101 -0
- package/docs/specs/006-rocm-overlay/spec.md +109 -0
- package/docs/team-workflow.md +7 -1
- package/docs/workflows.md +3 -0
- package/features/cross-distro-packages/README.md +18 -0
- package/features/cross-distro-packages/devcontainer-feature.json +3 -3
- package/features/cross-distro-packages/install.sh +49 -7
- package/overlays/.shared/README.md +80 -21
- package/overlays/.shared/compose/common-healthchecks.md +60 -0
- package/overlays/.shared/vscode/recommended-extensions.json +15 -11
- package/overlays/alertmanager/setup.sh +4 -19
- package/overlays/alertmanager/verify.sh +8 -9
- package/overlays/all/README.md +43 -0
- package/overlays/all/devcontainer.patch.json +6 -0
- package/overlays/all/overlay.yml +14 -0
- package/overlays/amp/setup.sh +5 -0
- package/overlays/bun/setup.sh +10 -1
- package/overlays/bun/verify.sh +6 -1
- package/overlays/claude-code/setup.sh +5 -0
- package/overlays/cloudflared/setup.sh +9 -12
- package/overlays/codex/README.md +9 -6
- package/overlays/codex/devcontainer.patch.json +7 -1
- package/overlays/codex/setup.sh +5 -0
- package/overlays/codex/verify.sh +8 -0
- package/overlays/commitlint/setup.sh +5 -0
- package/overlays/cuda/README.md +179 -0
- package/overlays/cuda/devcontainer.patch.json +7 -0
- package/overlays/cuda/overlay.yml +17 -0
- package/overlays/cuda/setup.sh +32 -0
- package/overlays/cuda/verify.sh +38 -0
- package/overlays/devcontainer-cli/README.md +50 -0
- package/overlays/devcontainer-cli/devcontainer.patch.json +13 -0
- package/overlays/devcontainer-cli/overlay.yml +16 -0
- package/overlays/devcontainer-cli/setup.sh +14 -0
- package/overlays/direnv/devcontainer.patch.json +6 -0
- package/overlays/direnv/setup.sh +7 -6
- package/overlays/dotnet/setup.sh +14 -7
- package/overlays/duckdb/devcontainer.patch.json +1 -2
- package/overlays/gcloud/devcontainer.patch.json +0 -6
- package/overlays/gcloud/setup.sh +51 -0
- package/overlays/gemini-cli/setup.sh +5 -0
- package/overlays/git-helpers/devcontainer.patch.json +2 -1
- package/overlays/go/setup.sh +15 -14
- package/overlays/jaeger/overlay.yml +2 -0
- package/overlays/just/setup.sh +5 -17
- package/overlays/keycloak/docker-compose.yml +6 -4
- package/overlays/keycloak/verify.sh +4 -3
- package/overlays/kind/devcontainer.patch.json +1 -2
- package/overlays/kind/setup.sh +8 -17
- package/overlays/minio/setup.sh +10 -18
- package/overlays/mkdocs/overlay.yml +2 -1
- package/overlays/mkdocs2/README.md +135 -0
- package/overlays/mkdocs2/devcontainer.patch.json +19 -0
- package/overlays/mkdocs2/overlay.yml +17 -0
- package/overlays/mkdocs2/setup.sh +67 -0
- package/overlays/mkdocs2/verify.sh +35 -0
- package/overlays/modern-cli-tools/devcontainer.patch.json +7 -1
- package/overlays/modern-cli-tools/setup.sh +21 -71
- package/overlays/mongodb/devcontainer.patch.json +0 -6
- package/overlays/mongodb/setup.sh +59 -0
- package/overlays/mysql/verify.sh +4 -3
- package/overlays/nats/.env.example +1 -1
- package/overlays/nats/README.md +1 -1
- package/overlays/nats/docker-compose.yml +1 -1
- package/overlays/ngrok/setup.sh +9 -6
- package/overlays/nodejs/setup.sh +5 -0
- package/overlays/openapi-tools/devcontainer.patch.json +1 -2
- package/overlays/openapi-tools/setup.sh +9 -8
- package/overlays/opencode/setup.sh +5 -0
- package/overlays/otel-collector/overlay.yml +2 -0
- package/overlays/otel-collector/setup.sh +3 -16
- package/overlays/otel-demo-nodejs/verify.sh +8 -9
- package/overlays/otel-demo-python/verify.sh +16 -10
- package/overlays/pandoc/README.md +286 -0
- package/overlays/pandoc/devcontainer.patch.json +18 -0
- package/overlays/pandoc/overlay.yml +19 -0
- package/overlays/pandoc/setup.sh +293 -0
- package/overlays/pandoc/verify.sh +25 -0
- package/overlays/playwright/devcontainer.patch.json +3 -1
- package/overlays/playwright/setup.sh +37 -0
- package/overlays/postgres/docker-compose.yml +6 -0
- package/overlays/powershell/setup.sh +49 -13
- package/overlays/pre-commit/setup.sh +12 -3
- package/overlays/prometheus/overlay.yml +2 -0
- package/overlays/promtail/verify.sh +16 -10
- package/overlays/pulumi/devcontainer.patch.json +1 -1
- package/overlays/python/setup.sh +28 -9
- package/overlays/python/verify.sh +4 -2
- package/overlays/redpanda/docker-compose.yml +3 -5
- package/overlays/rocm/README.md +227 -0
- package/overlays/rocm/devcontainer.patch.json +4 -0
- package/overlays/rocm/overlay.yml +17 -0
- package/overlays/rocm/setup.sh +45 -0
- package/overlays/rocm/verify.sh +47 -0
- package/overlays/rust/setup.sh +11 -18
- package/overlays/spec-kit/setup.sh +7 -3
- package/overlays/sqlite/setup.sh +14 -14
- package/overlays/sqlserver/docker-compose.yml +3 -3
- package/overlays/sqlserver/verify.sh +22 -5
- package/overlays/tempo/verify.sh +16 -10
- package/overlays/tilt/devcontainer.patch.json +1 -2
- package/overlays/tilt/setup.sh +14 -4
- package/overlays/windsurf-cli/setup.sh +27 -4
- package/overlays/windsurf-cli/verify.sh +13 -3
- package/package.json +2 -1
- package/templates/scripts/setup-utils.sh +228 -0
- package/tool/schema/config.schema.json +110 -8
- package/tool/schema/overlay-manifest.schema.json +5 -0
- package/overlays/.shared/compose/common-healthchecks.yml +0 -38
- /package/overlays/otel-demo-nodejs/{Dockerfile-otel-demo-nodejs → Dockerfile} +0 -0
- /package/overlays/otel-demo-nodejs/{package-otel-demo-nodejs.json → package.json} +0 -0
- /package/overlays/otel-demo-nodejs/{server-otel-demo-nodejs.js → server.js} +0 -0
- /package/overlays/otel-demo-nodejs/{tracing-otel-demo-nodejs.js → tracing.js} +0 -0
- /package/overlays/otel-demo-python/{Dockerfile-otel-demo-python → Dockerfile} +0 -0
- /package/overlays/otel-demo-python/{app-otel-demo-python.py → app.py} +0 -0
- /package/overlays/otel-demo-python/{requirements-otel-demo-python.txt → requirements.txt} +0 -0
package/docs/overlay-imports.md
CHANGED
|
@@ -4,25 +4,28 @@ Overlays can import shared configuration fragments from `overlays/.shared/` to r
|
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
|
|
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
|
-
│ ├──
|
|
15
|
-
│
|
|
16
|
-
│ │
|
|
17
|
-
│
|
|
18
|
-
│
|
|
19
|
-
│ └──
|
|
20
|
-
│
|
|
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
|
|
25
|
+
│ ├── overlay.yml # imports: [.shared/otel/instrumentation.env]
|
|
23
26
|
│ └── devcontainer.patch.json
|
|
24
27
|
└── jaeger/
|
|
25
|
-
├── overlay.yml
|
|
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
|
-
|
|
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
|
-
|
|
63
|
+
## Supported File Types and Merge Behavior
|
|
57
64
|
|
|
58
|
-
|
|
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
|
-
|
|
72
|
+
### JSON import example
|
|
61
73
|
|
|
62
|
-
```
|
|
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
|
-
"
|
|
70
|
-
]
|
|
71
|
-
}
|
|
72
|
-
}
|
|
83
|
+
"eamodio.gitlens",
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
},
|
|
73
87
|
}
|
|
74
88
|
```
|
|
75
89
|
|
|
76
|
-
### YAML
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
###
|
|
99
|
+
### ENV import example
|
|
93
100
|
|
|
94
|
-
|
|
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
|
-
|
|
113
|
+
When this `.env` fragment is imported, the generated `.env.example` will contain:
|
|
97
114
|
|
|
98
115
|
```bash
|
|
99
|
-
#
|
|
116
|
+
# from .shared/otel/instrumentation.env
|
|
100
117
|
OTEL_SERVICE_NAME=my-service
|
|
101
118
|
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
|
|
102
|
-
|
|
119
|
+
...
|
|
103
120
|
```
|
|
104
121
|
|
|
105
|
-
##
|
|
122
|
+
## Import Ordering and Conflict Resolution
|
|
106
123
|
|
|
107
|
-
|
|
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
|
-
|
|
126
|
+
```
|
|
127
|
+
[import 1] → [import 2] → … → [import N] → [overlay own patch]
|
|
128
|
+
```
|
|
115
129
|
|
|
116
|
-
|
|
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
|
-
|
|
133
|
+
This means overlays can intentionally override shared defaults by setting the same key in their `devcontainer.patch.json`.
|
|
119
134
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
-
|
|
148
|
+
**`overlays/prometheus/overlay.yml`:**
|
|
127
149
|
|
|
150
|
+
```yaml
|
|
151
|
+
imports:
|
|
152
|
+
- .shared/otel/instrumentation.env
|
|
128
153
|
```
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
154
|
+
|
|
155
|
+
**`overlays/jaeger/overlay.yml`:**
|
|
156
|
+
|
|
157
|
+
```yaml
|
|
158
|
+
imports:
|
|
159
|
+
- .shared/otel/instrumentation.env
|
|
133
160
|
```
|
|
134
161
|
|
|
135
|
-
|
|
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
|
-
|
|
166
|
+
Import paths are validated before any file is read:
|
|
138
167
|
|
|
139
|
-
|
|
168
|
+
1. The path **must** begin with `.shared/`
|
|
169
|
+
2. The resolved absolute path **must** remain inside `overlays/.shared/`
|
|
140
170
|
|
|
141
|
-
|
|
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
|
|
154
|
-
-
|
|
155
|
-
-
|
|
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
|
-
|
|
188
|
+
Broken references are reported with the overlay ID and the bad path so maintainers can fix them quickly.
|
|
166
189
|
|
|
167
|
-
|
|
190
|
+
## Viewing Imports in `explain`
|
|
168
191
|
|
|
169
|
-
|
|
192
|
+
When an overlay has imports, they are shown in the `explain` output:
|
|
170
193
|
|
|
171
194
|
```bash
|
|
172
|
-
|
|
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
|
-
|
|
198
|
+
```
|
|
199
|
+
Shared Imports:
|
|
200
|
+
(Fragments from overlays/.shared/ applied before this overlay)
|
|
201
|
+
📎 .shared/otel/instrumentation.env
|
|
202
|
+
```
|
|
184
203
|
|
|
185
|
-
|
|
186
|
-
# overlays/prometheus/overlay.yml
|
|
187
|
-
imports:
|
|
188
|
-
- .shared/otel/instrumentation.env
|
|
204
|
+
## Creating Shared Configurations
|
|
189
205
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
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. **
|
|
200
|
-
2. **
|
|
201
|
-
3. **
|
|
202
|
-
4. **
|
|
203
|
-
5. **
|
|
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
|
-
-
|
|
209
|
-
-
|
|
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
|
|
73
|
-
|
|
|
74
|
-
| **Category**
|
|
75
|
-
| **Requires**
|
|
76
|
-
| **
|
|
77
|
-
| **
|
|
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
|
|
|
@@ -452,6 +453,16 @@ Specify CLI for Spec-Driven Development with any AI coding agent
|
|
|
452
453
|
| **Suggests** | `python`, `codex` |
|
|
453
454
|
| **Tags** | `dev`, `ai`, `sdd`, `spec-driven`, `specify`, `spec-kit` |
|
|
454
455
|
|
|
456
|
+
### Pandoc PDF (`pandoc`)
|
|
457
|
+
|
|
458
|
+
Pandoc with XeLaTeX, Mermaid diagrams, and quality fonts for Markdown-to-PDF export
|
|
459
|
+
|
|
460
|
+
| Property | Value |
|
|
461
|
+
| ------------ | -------------------------------------------------------------- |
|
|
462
|
+
| **Category** | dev |
|
|
463
|
+
| **Suggests** | `nodejs` |
|
|
464
|
+
| **Tags** | `dev`, `pandoc`, `pdf`, `latex`, `markdown`, `docs`, `mermaid` |
|
|
465
|
+
|
|
455
466
|
### Amp (`amp`)
|
|
456
467
|
|
|
457
468
|
Sourcegraph Amp CLI for AI-powered code generation and assistance
|
|
@@ -503,6 +514,26 @@ Conventional commits validation for automated releases
|
|
|
503
514
|
| **Suggests** | `pre-commit` |
|
|
504
515
|
| **Tags** | `dev`, `git`, `commits`, `semantic-release` |
|
|
505
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
|
+
|
|
506
537
|
### direnv (`direnv`)
|
|
507
538
|
|
|
508
539
|
Per-directory environment variable management
|
|
@@ -592,6 +623,18 @@ Email testing tool with web UI and SMTP server
|
|
|
592
623
|
| **Tags** | `dev`, `email`, `smtp`, `testing` |
|
|
593
624
|
| **Ports** | [object Object], [object Object] |
|
|
594
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
|
+
|
|
595
638
|
### Modern CLI Tools (`modern-cli-tools`)
|
|
596
639
|
|
|
597
640
|
jq, yq, ripgrep, fd, bat - Essential modern command-line tools
|
|
@@ -652,6 +695,16 @@ Automated code quality gates with pre-commit hooks
|
|
|
652
695
|
| **Suggests** | `commitlint` |
|
|
653
696
|
| **Tags** | `dev`, `git`, `quality`, `hooks` |
|
|
654
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
|
+
|
|
655
708
|
### Tilt (`tilt`)
|
|
656
709
|
|
|
657
710
|
Live update and orchestration for Kubernetes development
|
package/docs/quick-reference.md
CHANGED
|
@@ -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)
|
|
@@ -17,7 +17,12 @@ The design extends the existing answer-merging flow instead of creating a second
|
|
|
17
17
|
generation pipeline, introduces an explicit `--from-project` mode, allows
|
|
18
18
|
implicit project-file use for `init --no-interactive` and default `regen` when
|
|
19
19
|
no conflicting source or selection flags are supplied, and keeps explicit
|
|
20
|
-
manifest-based regeneration as a separate persisted-input mode.
|
|
20
|
+
manifest-based regeneration as a separate persisted-input mode. The same schema
|
|
21
|
+
must also be writable from `adopt --project-file` so migration from an existing
|
|
22
|
+
`.devcontainer/` can produce a repository-root project config without inventing
|
|
23
|
+
a parallel declaration format. Persisted-input workflows must also support an
|
|
24
|
+
explicit repository-root override so users can run `init` or `regen` against a
|
|
25
|
+
different repository without first changing their shell working directory.
|
|
21
26
|
|
|
22
27
|
## Technical Context
|
|
23
28
|
|
|
@@ -29,6 +29,8 @@ A project maintainer defines the desired development environment in a single rep
|
|
|
29
29
|
|
|
30
30
|
1. **Given** a repository with a valid project config file in its root that defines stack, overlay selections, output location, and supported customization settings, **When** a maintainer runs the generation flow from that repository root, **Then** the tool uses those values as the starting configuration for generation.
|
|
31
31
|
2. **Given** a repository with a committed project config file, **When** a teammate clones the repository and runs the same generation flow from a fresh checkout, **Then** they receive the same effective project setup without needing the original author’s shell history or copied command examples.
|
|
32
|
+
3. **Given** a repository with an existing hand-crafted `.devcontainer/`, **When** a maintainer runs `adopt --project-file`, **Then** the tool writes a repository-root project config that captures the inferred stack, overlay selections, output path, and supported customization inputs from the adopted setup.
|
|
33
|
+
4. **Given** a maintainer is working outside the target repository, **When** they run `init --from-project --project-root <path>` or `regen --project-root <path>`, **Then** the tool resolves the project file and relative output paths from that selected repository root.
|
|
32
34
|
|
|
33
35
|
---
|
|
34
36
|
|
|
@@ -72,6 +74,8 @@ A contributor receives clear guidance when the project config file is invalid, i
|
|
|
72
74
|
- How does the system handle supported customizations such as environment settings, custom container definitions, or additional generated features? Those values are treated as first-class generation inputs and must round-trip through the project config file without being dropped.
|
|
73
75
|
- How does the system handle unsupported overlay IDs, invalid categories, or conflicting selections in the project config file? It fails validation before generation and explains the invalid entries.
|
|
74
76
|
- How does the system handle both `.superposition.yml` and `superposition.yml` in one repository? It treats this as an error to avoid ambiguity.
|
|
77
|
+
- How does the system handle `adopt --project-file` when a repository already contains a supported project config file? It reuses that file path, and it must still stop on dual-file ambiguity so the source of truth stays deterministic.
|
|
78
|
+
- How does the system handle project-file or manifest discovery from outside the target repository? An explicit project-root option may redirect persisted-input discovery and relative output resolution to that repository root.
|
|
75
79
|
|
|
76
80
|
## Requirements _(mandatory)_
|
|
77
81
|
|
|
@@ -96,6 +100,8 @@ A contributor receives clear guidance when the project config file is invalid, i
|
|
|
96
100
|
- **FR-017**: The system MUST allow `init --no-interactive` and `regen` to use the repository project file implicitly when a valid project config file exists and no other persisted-input source flag or clean-generation selection flags are supplied.
|
|
97
101
|
- **FR-018**: The system MUST reject conflicting persisted-input source combinations before generation, including `--from-project` with `--from-manifest` and either source-selection mode combined with clean-generation selection flags such as stack, overlay, or preset selection.
|
|
98
102
|
- **FR-019**: The system MUST document how teams create, commit, validate, and use the project config file in local development, regeneration, and automation workflows, including how parity with clean generation applies to supported customization inputs and how source-selection conflicts are resolved.
|
|
103
|
+
- **FR-020**: The system MUST allow `adopt --project-file` to write a repository-root project config that represents the inferred adopted setup using the same supported declaration surface as other project-config workflows.
|
|
104
|
+
- **FR-021**: The system MUST allow `init` and `regen` to resolve project-file and manifest discovery from an explicitly selected repository root so users can run persisted-input workflows without changing their shell working directory first.
|
|
99
105
|
|
|
100
106
|
### Key Entities _(include if feature involves data)_
|
|
101
107
|
|
|
@@ -60,6 +60,8 @@
|
|
|
60
60
|
- [x] T016 [US1] Preserve supported customization inputs through generation and summary rendering in `scripts/init.ts`
|
|
61
61
|
- [x] T017 [US1] Ensure project-config driven answers produce the same composed output as equivalent clean-generation input in `tool/questionnaire/composer.ts`
|
|
62
62
|
- [x] T018 [US1] Keep generated run summaries accurate for project-config sourced generation in `tool/utils/summary.ts`
|
|
63
|
+
- [x] T018a [US1] Let `adopt --project-file` write a repository-root project config from inferred overlay selections and supported customizations in `tool/commands/adopt.ts` and `tool/schema/project-config.ts`
|
|
64
|
+
- [x] T018b [US1] Let `init` and `regen` target a different repository root for project-file and manifest discovery via `--project-root <path>` in `scripts/init.ts` and `tool/__tests__/commands.test.ts`
|
|
63
65
|
|
|
64
66
|
**Checkpoint**: User Story 1 should now be fully functional and testable on its own
|
|
65
67
|
|