container-superposition 0.1.7 → 0.1.8

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 (122) hide show
  1. package/README.md +24 -15
  2. package/dist/scripts/init.js +1 -1537
  3. package/dist/scripts/init.js.map +1 -1
  4. package/dist/tool/cli/args.d.ts +20 -0
  5. package/dist/tool/cli/args.d.ts.map +1 -0
  6. package/dist/tool/cli/args.js +325 -0
  7. package/dist/tool/cli/args.js.map +1 -0
  8. package/dist/tool/cli/run.d.ts +2 -0
  9. package/dist/tool/cli/run.d.ts.map +1 -0
  10. package/dist/tool/cli/run.js +318 -0
  11. package/dist/tool/cli/run.js.map +1 -0
  12. package/dist/tool/commands/doctor.d.ts.map +1 -1
  13. package/dist/tool/commands/doctor.js +141 -6
  14. package/dist/tool/commands/doctor.js.map +1 -1
  15. package/dist/tool/commands/explain.d.ts.map +1 -1
  16. package/dist/tool/commands/explain.js +9 -0
  17. package/dist/tool/commands/explain.js.map +1 -1
  18. package/dist/tool/commands/migrate.d.ts +7 -0
  19. package/dist/tool/commands/migrate.d.ts.map +1 -0
  20. package/dist/tool/commands/migrate.js +52 -0
  21. package/dist/tool/commands/migrate.js.map +1 -0
  22. package/dist/tool/questionnaire/answers.d.ts +16 -0
  23. package/dist/tool/questionnaire/answers.d.ts.map +1 -0
  24. package/dist/tool/questionnaire/answers.js +102 -0
  25. package/dist/tool/questionnaire/answers.js.map +1 -0
  26. package/dist/tool/questionnaire/composer.d.ts +3 -3
  27. package/dist/tool/questionnaire/composer.d.ts.map +1 -1
  28. package/dist/tool/questionnaire/composer.js +691 -27
  29. package/dist/tool/questionnaire/composer.js.map +1 -1
  30. package/dist/tool/questionnaire/presets.d.ts +60 -0
  31. package/dist/tool/questionnaire/presets.d.ts.map +1 -0
  32. package/dist/tool/questionnaire/presets.js +164 -0
  33. package/dist/tool/questionnaire/presets.js.map +1 -0
  34. package/dist/tool/questionnaire/questionnaire.d.ts +10 -0
  35. package/dist/tool/questionnaire/questionnaire.d.ts.map +1 -0
  36. package/dist/tool/questionnaire/questionnaire.js +580 -0
  37. package/dist/tool/questionnaire/questionnaire.js.map +1 -0
  38. package/dist/tool/schema/manifest-migrations.d.ts +5 -0
  39. package/dist/tool/schema/manifest-migrations.d.ts.map +1 -1
  40. package/dist/tool/schema/manifest-migrations.js +45 -0
  41. package/dist/tool/schema/manifest-migrations.js.map +1 -1
  42. package/dist/tool/schema/overlay-loader.d.ts.map +1 -1
  43. package/dist/tool/schema/overlay-loader.js +24 -0
  44. package/dist/tool/schema/overlay-loader.js.map +1 -1
  45. package/dist/tool/schema/project-config.d.ts +13 -1
  46. package/dist/tool/schema/project-config.d.ts.map +1 -1
  47. package/dist/tool/schema/project-config.js +183 -9
  48. package/dist/tool/schema/project-config.js.map +1 -1
  49. package/dist/tool/schema/target-rules.d.ts +78 -0
  50. package/dist/tool/schema/target-rules.d.ts.map +1 -0
  51. package/dist/tool/schema/target-rules.js +367 -0
  52. package/dist/tool/schema/target-rules.js.map +1 -0
  53. package/dist/tool/schema/types.d.ts +38 -1
  54. package/dist/tool/schema/types.d.ts.map +1 -1
  55. package/dist/tool/utils/parameters.d.ts +76 -0
  56. package/dist/tool/utils/parameters.d.ts.map +1 -0
  57. package/dist/tool/utils/parameters.js +125 -0
  58. package/dist/tool/utils/parameters.js.map +1 -0
  59. package/dist/tool/utils/paths.d.ts +2 -0
  60. package/dist/tool/utils/paths.d.ts.map +1 -0
  61. package/dist/tool/utils/paths.js +31 -0
  62. package/dist/tool/utils/paths.js.map +1 -0
  63. package/docs/deployment-targets.md +88 -56
  64. package/docs/examples.md +20 -17
  65. package/docs/filesystem-contract.md +5 -0
  66. package/docs/minimal-and-editor.md +65 -5
  67. package/docs/overlay-imports.md +92 -14
  68. package/docs/overlays.md +113 -28
  69. package/docs/specs/007-init-project-file/spec.md +66 -0
  70. package/docs/specs/007-target-aware-generation/spec.md +126 -0
  71. package/docs/specs/008-project-file-canonical/spec.md +83 -0
  72. package/docs/specs/009-project-env/spec.md +147 -0
  73. package/docs/specs/010-compose-env-materialization/spec.md +130 -0
  74. package/docs/specs/011-overlay-parameters/spec.md +235 -0
  75. package/overlays/.shared/README.md +27 -2
  76. package/overlays/.shared/compose/nvidia-gpu-devcontainer.yml +22 -0
  77. package/overlays/comfyui/.env.example +34 -0
  78. package/overlays/comfyui/README.md +342 -0
  79. package/overlays/comfyui/devcontainer.patch.json +15 -0
  80. package/overlays/comfyui/docker-compose.yml +39 -0
  81. package/overlays/comfyui/overlay.yml +20 -0
  82. package/overlays/comfyui/setup.sh +36 -0
  83. package/overlays/comfyui/verify.sh +103 -0
  84. package/overlays/k3d/README.md +201 -0
  85. package/overlays/k3d/devcontainer.patch.json +9 -0
  86. package/overlays/k3d/overlay.yml +19 -0
  87. package/overlays/k3d/setup.sh +34 -0
  88. package/overlays/k3d/verify.sh +38 -0
  89. package/overlays/ollama/.env.example +14 -0
  90. package/overlays/ollama/README.md +325 -0
  91. package/overlays/ollama/devcontainer.patch.json +14 -0
  92. package/overlays/ollama/docker-compose.yml +24 -0
  93. package/overlays/ollama/overlay.yml +22 -0
  94. package/overlays/ollama/setup.sh +106 -0
  95. package/overlays/ollama/verify.sh +99 -0
  96. package/overlays/open-webui/.env.example +5 -0
  97. package/overlays/open-webui/README.md +162 -0
  98. package/overlays/open-webui/devcontainer.patch.json +14 -0
  99. package/overlays/open-webui/docker-compose.yml +23 -0
  100. package/overlays/open-webui/overlay.yml +38 -0
  101. package/overlays/pgvector/.env.example +6 -0
  102. package/overlays/pgvector/README.md +215 -0
  103. package/overlays/pgvector/devcontainer.patch.json +23 -0
  104. package/overlays/pgvector/docker-compose.yml +32 -0
  105. package/overlays/pgvector/overlay.yml +44 -0
  106. package/overlays/postgres/.env.example +5 -5
  107. package/overlays/postgres/devcontainer.patch.json +4 -4
  108. package/overlays/postgres/docker-compose.yml +10 -6
  109. package/overlays/postgres/overlay.yml +19 -1
  110. package/overlays/qdrant/.env.example +4 -0
  111. package/overlays/qdrant/README.md +216 -0
  112. package/overlays/qdrant/devcontainer.patch.json +20 -0
  113. package/overlays/qdrant/docker-compose.yml +25 -0
  114. package/overlays/qdrant/overlay.yml +40 -0
  115. package/overlays/skaffold/README.md +256 -0
  116. package/overlays/skaffold/devcontainer.patch.json +9 -0
  117. package/overlays/skaffold/overlay.yml +20 -0
  118. package/overlays/skaffold/setup.sh +33 -0
  119. package/overlays/skaffold/verify.sh +24 -0
  120. package/package.json +3 -2
  121. package/tool/schema/config.schema.json +31 -1
  122. package/tool/schema/overlay-manifest.schema.json +33 -0
@@ -6,7 +6,10 @@ Overlays can import shared configuration fragments from `overlays/.shared/` to r
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
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.
9
+ Two import fields are supported in `overlay.yml`:
10
+
11
+ - **`imports:`** — shared devcontainer patch fragments (`.json`, `.yaml`, `.env`) applied before the overlay's own `devcontainer.patch.json`
12
+ - **`compose_imports:`** — shared docker-compose YAML fragments (`.yml`, `.yaml`) deep-merged into `docker-compose.yml` before the overlay's own `docker-compose.yml`
10
13
 
11
14
  ## Shared Directory Structure
12
15
 
@@ -15,21 +18,25 @@ overlays/
15
18
  ├── .shared/
16
19
  │ ├── README.md
17
20
  │ ├── otel/
18
- │ │ ├── instrumentation.env # OTEL SDK env vars — imported by otel-collector, prometheus, jaeger
19
- │ │ └── otel-base-config.yaml # Base OTEL collector pipeline config
21
+ │ │ ├── instrumentation.env # OTEL SDK env vars — imported by otel-collector, prometheus, jaeger
22
+ │ │ └── otel-base-config.yaml # Base OTEL collector pipeline config
20
23
  │ ├── compose/
21
- │ │ └── common-healthchecks.yml # Standard Docker Compose healthcheck patterns
24
+ │ │ ├── nvidia-gpu-devcontainer.yml # NVIDIA GPU passthrough for the devcontainer service
25
+ │ │ └── common-healthchecks.md # Standard Docker Compose healthcheck patterns (reference only)
22
26
  │ └── vscode/
23
- │ └── recommended-extensions.json # Commonly recommended VS Code extensions (devcontainer patch format)
27
+ │ └── recommended-extensions.json # Commonly recommended VS Code extensions (devcontainer patch format)
24
28
  ├── prometheus/
25
- │ ├── overlay.yml # imports: [.shared/otel/instrumentation.env]
29
+ │ ├── overlay.yml # imports: [.shared/otel/instrumentation.env]
30
+ │ └── devcontainer.patch.json
31
+ ├── jaeger/
32
+ │ ├── overlay.yml # imports: [.shared/otel/instrumentation.env]
26
33
  │ └── devcontainer.patch.json
27
- └── jaeger/
28
- ├── overlay.yml # imports: [.shared/otel/instrumentation.env]
29
- └── devcontainer.patch.json
34
+ └── ollama/
35
+ ├── overlay.yml # compose_imports: [.shared/compose/nvidia-gpu-devcontainer.yml]
36
+ └── docker-compose.yml
30
37
  ```
31
38
 
32
- ## Using Imports
39
+ ## Using `imports` (devcontainer patch fragments)
33
40
 
34
41
  Add the `imports` field to your `overlay.yml` manifest:
35
42
 
@@ -60,7 +67,28 @@ imports:
60
67
  - Order is significant — fragments are applied in declaration order, then the overlay's own `devcontainer.patch.json`
61
68
  - Missing files, unsupported types, or path traversal attempts cause generation to fail with a message identifying the overlay and the broken reference
62
69
 
63
- ## Supported File Types and Merge Behavior
70
+ ## Using `compose_imports` (docker-compose fragments)
71
+
72
+ Add the `compose_imports` field to your `overlay.yml` manifest to merge shared docker-compose YAML fragments into the generated `docker-compose.yml`:
73
+
74
+ ```yaml
75
+ id: ollama
76
+ name: Ollama
77
+ # ... other fields ...
78
+ compose_imports:
79
+ - .shared/compose/nvidia-gpu-devcontainer.yml
80
+ ```
81
+
82
+ **Rules:**
83
+
84
+ - All paths **must** begin with `.shared/` (same path traversal rules as `imports`)
85
+ - Files must be `.yml` or `.yaml`
86
+ - Fragments are deep-merged in declaration order, then the overlay's own `docker-compose.yml` is merged last (overlay wins on conflict)
87
+ - Missing files, wrong types, or traversal attempts cause generation to fail
88
+
89
+ ## Supported File Types
90
+
91
+ ### `imports:` — devcontainer patch fragments
64
92
 
65
93
  | Extension | How it is merged |
66
94
  | ---------------- | ------------------------------------------------------------------------------ |
@@ -69,6 +97,13 @@ imports:
69
97
  | `.env` | Concatenated into `.env.example` with a `# from .shared/…` comment header |
70
98
  | Anything else | Rejected with a clear unsupported-type error |
71
99
 
100
+ ### `compose_imports:` — docker-compose fragments
101
+
102
+ | Extension | How it is merged |
103
+ | ---------------- | --------------------------------------------------------------------------- |
104
+ | `.yaml` / `.yml` | Deep-merged into `docker-compose.yml` before the overlay's own compose file |
105
+ | Anything else | Rejected with a clear unsupported-type error |
106
+
72
107
  ### JSON import example
73
108
 
74
109
  ```jsonc
@@ -87,7 +122,7 @@ imports:
87
122
  }
88
123
  ```
89
124
 
90
- ### YAML import example
125
+ ### YAML devcontainer import example
91
126
 
92
127
  ```yaml
93
128
  # overlays/.shared/otel/otel-base-config.yaml
@@ -119,8 +154,27 @@ OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
119
154
  ...
120
155
  ```
121
156
 
157
+ ### YAML compose_import example
158
+
159
+ ```yaml
160
+ # overlays/.shared/compose/nvidia-gpu-devcontainer.yml
161
+ services:
162
+ devcontainer:
163
+ deploy:
164
+ resources:
165
+ reservations:
166
+ devices:
167
+ - driver: nvidia
168
+ count: all
169
+ capabilities: [gpu]
170
+ ```
171
+
172
+ When this fragment is imported via `compose_imports`, the generated `docker-compose.yml` will include the `deploy` block on the `devcontainer` service merged with contributions from all other overlays.
173
+
122
174
  ## Import Ordering and Conflict Resolution
123
175
 
176
+ ### `imports` ordering
177
+
124
178
  Imports are applied in declaration order, then the overlay's own `devcontainer.patch.json` is applied last:
125
179
 
126
180
  ```
@@ -132,6 +186,17 @@ Imports are applied in declaration order, then the overlay's own `devcontainer.p
132
186
 
133
187
  This means overlays can intentionally override shared defaults by setting the same key in their `devcontainer.patch.json`.
134
188
 
189
+ ### `compose_imports` ordering
190
+
191
+ For each overlay, compose fragments are merged before the overlay's own `docker-compose.yml`, in this order:
192
+
193
+ ```
194
+ [base template compose] → [overlay 1 compose_imports] → [overlay 1 docker-compose.yml] → [overlay 2 compose_imports] → [overlay 2 docker-compose.yml] → …
195
+ ```
196
+
197
+ - Each overlay's `docker-compose.yml` wins over its own `compose_imports`
198
+ - Later overlays win over earlier overlays on key conflict
199
+
135
200
  ## Worked Example: OTEL Instrumentation
136
201
 
137
202
  Many observability overlays need OTEL environment variables. With imports, these are defined once:
@@ -183,7 +248,8 @@ Checks performed:
183
248
  - Import path starts with `.shared/` (path traversal check)
184
249
  - Import path resolves within `overlays/.shared/` (traversal check)
185
250
  - Import file exists on disk
186
- - File type is one of `.json`, `.yaml`, `.yml`, `.env`
251
+ - File type is one of `.json`, `.yaml`, `.yml`, `.env` (for `imports:`)
252
+ - File type is one of `.yaml`, `.yml` (for `compose_imports:`)
187
253
 
188
254
  Broken references are reported with the overlay ID and the bad path so maintainers can fix them quickly.
189
255
 
@@ -201,11 +267,23 @@ Shared Imports:
201
267
  📎 .shared/otel/instrumentation.env
202
268
  ```
203
269
 
270
+ When an overlay has compose_imports, they are also shown:
271
+
272
+ ```bash
273
+ container-superposition explain ollama
274
+ ```
275
+
276
+ ```
277
+ Shared Compose Imports:
278
+ (docker-compose fragments from overlays/.shared/ merged before this overlay)
279
+ 🐳 .shared/compose/nvidia-gpu-devcontainer.yml
280
+ ```
281
+
204
282
  ## Creating Shared Configurations
205
283
 
206
284
  1. **Identify common patterns** across multiple overlays
207
285
  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`
286
+ 3. **Update overlays** to reference the fragment via `imports:` or `compose_imports:` in their `overlay.yml`
209
287
  4. **Update `.shared/README.md`** to document the fragment's purpose and which overlays use it
210
288
  5. **Test** with `npm test` and `container-superposition doctor` to verify
211
289
 
package/docs/overlays.md CHANGED
@@ -146,18 +146,18 @@ MongoDB 8 with Mongo Express web UI
146
146
  | **Category** | database |
147
147
  | **Supports** | compose |
148
148
  | **Tags** | `database`, `nosql`, `mongodb`, `document` |
149
- | **Ports** | [object Object], [object Object] |
149
+ | **Ports** | 27017/tcp, 8081/http |
150
150
 
151
151
  ### MySQL (`mysql`)
152
152
 
153
153
  MySQL 8 with phpMyAdmin web UI
154
154
 
155
- | Property | Value |
156
- | ------------ | -------------------------------- |
157
- | **Category** | database |
158
- | **Supports** | compose |
159
- | **Tags** | `database`, `sql`, `mysql` |
160
- | **Ports** | [object Object], [object Object] |
155
+ | Property | Value |
156
+ | ------------ | -------------------------- |
157
+ | **Category** | database |
158
+ | **Supports** | compose |
159
+ | **Tags** | `database`, `sql`, `mysql` |
160
+ | **Ports** | 3306/tcp, 8080/http |
161
161
 
162
162
  ### NATS (`nats`)
163
163
 
@@ -168,18 +168,44 @@ Lightweight pub/sub messaging with JetStream
168
168
  | **Category** | database |
169
169
  | **Supports** | compose |
170
170
  | **Tags** | `database`, `messaging`, `pubsub`, `nats`, `jetstream` |
171
- | **Ports** | [object Object], [object Object] |
171
+ | **Ports** | 4222/tcp, 8222/http |
172
+
173
+ ### pgvector (PostgreSQL + vector) (`pgvector`)
174
+
175
+ PostgreSQL 16 with the pgvector extension for vector similarity search
176
+
177
+ | Property | Value |
178
+ | ------------- | ----------------------------------------------------------------- |
179
+ | **Category** | database |
180
+ | **Supports** | compose |
181
+ | **Suggests** | `ollama`, `python`, `nodejs` |
182
+ | **Conflicts** | `postgres` |
183
+ | **Tags** | `database`, `sql`, `vector`, `embeddings`, `postgres`, `pgvector` |
184
+ | **Ports** | 5432/tcp |
172
185
 
173
186
  ### PostgreSQL (`postgres`)
174
187
 
175
188
  PostgreSQL 16 database
176
189
 
177
- | Property | Value |
178
- | ------------ | ----------------------------- |
179
- | **Category** | database |
180
- | **Supports** | compose |
181
- | **Tags** | `database`, `sql`, `postgres` |
182
- | **Ports** | [object Object] |
190
+ | Property | Value |
191
+ | ------------- | ----------------------------- |
192
+ | **Category** | database |
193
+ | **Supports** | compose |
194
+ | **Conflicts** | `pgvector` |
195
+ | **Tags** | `database`, `sql`, `postgres` |
196
+ | **Ports** | 5432/tcp |
197
+
198
+ ### Qdrant (`qdrant`)
199
+
200
+ High-performance vector database for similarity search and embeddings
201
+
202
+ | Property | Value |
203
+ | ------------ | ------------------------------------------------------ |
204
+ | **Category** | database |
205
+ | **Supports** | compose |
206
+ | **Suggests** | `ollama`, `python`, `nodejs` |
207
+ | **Tags** | `database`, `vector`, `embeddings`, `search`, `qdrant` |
208
+ | **Ports** | 6333/http, 6334/grpc |
183
209
 
184
210
  ### RabbitMQ (`rabbitmq`)
185
211
 
@@ -190,7 +216,7 @@ Message broker with AMQP protocol and management UI
190
216
  | **Category** | database |
191
217
  | **Supports** | compose |
192
218
  | **Tags** | `database`, `messaging`, `queue`, `rabbitmq`, `amqp` |
193
- | **Ports** | [object Object], [object Object] |
219
+ | **Ports** | 5672/tcp, 15672/http |
194
220
 
195
221
  ### Redis (`redis`)
196
222
 
@@ -201,7 +227,7 @@ Redis 7 cache
201
227
  | **Category** | database |
202
228
  | **Supports** | compose |
203
229
  | **Tags** | `database`, `cache`, `redis` |
204
- | **Ports** | [object Object] |
230
+ | **Ports** | 6379/tcp |
205
231
 
206
232
  ### Redpanda (`redpanda`)
207
233
 
@@ -242,13 +268,13 @@ SQLite with litecli and VS Code extensions
242
268
 
243
269
  Distributed tracing backend
244
270
 
245
- | Property | Value |
246
- | ------------- | ------------------------------------------------- |
247
- | **Category** | observability |
248
- | **Supports** | compose |
249
- | **Conflicts** | `tempo` |
250
- | **Tags** | `observability`, `tracing`, `jaeger` |
251
- | **Ports** | [object Object], [object Object], [object Object] |
271
+ | Property | Value |
272
+ | ------------- | ------------------------------------ |
273
+ | **Category** | observability |
274
+ | **Supports** | compose |
275
+ | **Conflicts** | `tempo` |
276
+ | **Tags** | `observability`, `tracing`, `jaeger` |
277
+ | **Ports** | 16686/http, 14250/grpc, 14268/http |
252
278
 
253
279
  ### Loki (`loki`)
254
280
 
@@ -260,7 +286,7 @@ Log aggregation system
260
286
  | **Supports** | compose |
261
287
  | **Suggests** | `promtail` |
262
288
  | **Tags** | `observability`, `logs`, `loki` |
263
- | **Ports** | [object Object] |
289
+ | **Ports** | 3100/http |
264
290
 
265
291
  ### Prometheus (`prometheus`)
266
292
 
@@ -272,7 +298,7 @@ Metrics collection and monitoring
272
298
  | **Supports** | compose |
273
299
  | **Suggests** | `alertmanager` |
274
300
  | **Tags** | `observability`, `metrics`, `prometheus` |
275
- | **Ports** | [object Object] |
301
+ | **Ports** | 9090/http |
276
302
 
277
303
  ### Tempo (`tempo`)
278
304
 
@@ -333,7 +359,7 @@ Observability visualization dashboard with auto-provisioning
333
359
  | **Requires** | `prometheus` |
334
360
  | **Suggests** | `loki`, `jaeger`, `tempo`, `promtail` |
335
361
  | **Tags** | `observability`, `ui`, `visualization` |
336
- | **Ports** | [object Object] |
362
+ | **Ports** | 3000/http |
337
363
 
338
364
  ### OTel Demo (Node.js) (`otel-demo-nodejs`)
339
365
 
@@ -390,6 +416,18 @@ Google Cloud Platform command-line tools (gcloud, gsutil, bq)
390
416
  | **Category** | cloud |
391
417
  | **Tags** | `cloud`, `gcp`, `google`, `cli` |
392
418
 
419
+ ### k3d (`k3d`)
420
+
421
+ Lightweight local Kubernetes clusters using k3s in Docker
422
+
423
+ | Property | Value |
424
+ | ------------- | ----------------------------------------------------- |
425
+ | **Category** | cloud |
426
+ | **Requires** | `docker-in-docker` |
427
+ | **Suggests** | `kubectl-helm` |
428
+ | **Conflicts** | `kind` |
429
+ | **Tags** | `cloud`, `kubernetes`, `k8s`, `k3d`, `k3s`, `testing` |
430
+
393
431
  ### kind (Kubernetes in Docker) (`kind`)
394
432
 
395
433
  Local Kubernetes cluster for development and testing
@@ -503,6 +541,18 @@ OpenAI Codex CLI for AI-powered code generation and assistance
503
541
  | **Requires** | `nodejs` |
504
542
  | **Tags** | `dev`, `ai`, `code-generation` |
505
543
 
544
+ ### ComfyUI (`comfyui`)
545
+
546
+ Node-based image/video generation UI for Stable Diffusion and generative AI workflows
547
+
548
+ | Property | Value |
549
+ | ------------ | -------------------------------------------------------------- |
550
+ | **Category** | dev |
551
+ | **Supports** | compose |
552
+ | **Suggests** | `cuda`, `python`, `ollama` |
553
+ | **Tags** | `dev`, `ai`, `image-generation`, `stable-diffusion`, `comfyui` |
554
+ | **Ports** | 8188 |
555
+
506
556
  ### Commitlint (`commitlint`)
507
557
 
508
558
  Conventional commits validation for automated releases
@@ -610,7 +660,7 @@ Open-source identity and access management (OIDC/OAuth2)
610
660
  | **Supports** | compose |
611
661
  | **Requires** | `postgres` |
612
662
  | **Tags** | `dev`, `auth`, `oidc`, `oauth2`, `identity` |
613
- | **Ports** | [object Object] |
663
+ | **Ports** | 8180/http |
614
664
 
615
665
  ### Mailpit (`mailpit`)
616
666
 
@@ -621,7 +671,7 @@ Email testing tool with web UI and SMTP server
621
671
  | **Category** | dev |
622
672
  | **Supports** | compose |
623
673
  | **Tags** | `dev`, `email`, `smtp`, `testing` |
624
- | **Ports** | [object Object], [object Object] |
674
+ | **Ports** | 8025/http, 1025/tcp |
625
675
 
626
676
  ### MkDocs 2 (`mkdocs2`)
627
677
 
@@ -655,6 +705,30 @@ Secure tunneling for webhook testing and external access
655
705
  | **Tags** | `dev`, `tunneling`, `webhooks` |
656
706
  | **Ports** | 4040 |
657
707
 
708
+ ### Ollama (`ollama`)
709
+
710
+ Local LLM inference server with OpenAI-compatible API
711
+
712
+ | Property | Value |
713
+ | ------------ | ----------------------------------------- |
714
+ | **Category** | dev |
715
+ | **Supports** | compose |
716
+ | **Suggests** | `codex`, `claude-code`, `amp` |
717
+ | **Tags** | `dev`, `ai`, `llm`, `inference`, `ollama` |
718
+ | **Ports** | 11434 |
719
+
720
+ ### Open WebUI (`open-webui`)
721
+
722
+ Browser-based chat UI for Ollama and OpenAI-compatible LLM backends
723
+
724
+ | Property | Value |
725
+ | ------------ | --------------------------------------------- |
726
+ | **Category** | dev |
727
+ | **Supports** | compose |
728
+ | **Suggests** | `ollama` |
729
+ | **Tags** | `dev`, `ai`, `llm`, `ui`, `chat`, `openwebui` |
730
+ | **Ports** | 3000/http |
731
+
658
732
  ### OpenAPI Tools (`openapi-tools`)
659
733
 
660
734
  OpenAPI/Swagger tooling for API development and documentation
@@ -705,6 +779,17 @@ AMD ROCm libraries and GPU passthrough for containerized ML/inference workloads
705
779
  | **Conflicts** | `cuda` |
706
780
  | **Tags** | `dev`, `gpu`, `rocm`, `amd`, `ml`, `inference` |
707
781
 
782
+ ### Skaffold (`skaffold`)
783
+
784
+ Continuous development and deployment pipeline for Kubernetes applications
785
+
786
+ | Property | Value |
787
+ | ------------- | ------------------------------------------------------------ |
788
+ | **Category** | dev |
789
+ | **Suggests** | `kubectl-helm`, `kind`, `k3d` |
790
+ | **Conflicts** | `tilt` |
791
+ | **Tags** | `dev`, `kubernetes`, `k8s`, `cicd`, `deployment`, `skaffold` |
792
+
708
793
  ### Tilt (`tilt`)
709
794
 
710
795
  Live update and orchestration for Kubernetes development
@@ -0,0 +1,66 @@
1
+ # Feature Specification: `init --project-file`
2
+
3
+ **Feature Branch**: `copilot/sub-pr-121`
4
+ **Created**: 2026-03-23
5
+ **Status**: Final
6
+ **Input**: Extend the `init` command with a `--project-file` flag that persists the chosen init configuration into a repository-root project config file (creating `.superposition.yml` by default or updating an existing supported project config), aligning init runs with the project-config workflow.
7
+
8
+ ## Review & Approval _(mandatory before implementation)_
9
+
10
+ - **Spec Path**: `docs/specs/007-init-project-file/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
+ ## Summary
16
+
17
+ Allow `container-superposition init` to optionally write a repository-root
18
+ project config file (`.superposition.yml` by default, or the existing supported
19
+ project config path when one already exists) alongside the normal init output.
20
+
21
+ ## Requirements
22
+
23
+ - `init` MUST accept a `--project-file` flag.
24
+ - When `--project-file` is set, `init` MUST write a repository-root project
25
+ config that reflects the final selected configuration for that run.
26
+ - If the repository already contains exactly one supported project config file,
27
+ `init --project-file` MUST update that file instead of creating a second one.
28
+ - If no project config file exists, `init --project-file` MUST write
29
+ `.superposition.yml` at the repository root.
30
+ - The written project config MUST include supported fields represented by the
31
+ final init answers, including stack, base image, overlays, output path,
32
+ target, minimal mode, editor profile, preset, and preset choices.
33
+ - `init --project-file` MUST continue to write `superposition.json` the same way
34
+ current `init` runs do.
35
+ - Project config write errors MUST NOT suppress devcontainer generation success; they MUST be reported separately.
36
+
37
+ ## User Scenarios & Testing _(mandatory)_
38
+
39
+ ### User Story 1 - Write project config alongside devcontainer generation (Priority: P1)
40
+
41
+ A developer wants to run `init` once and have both a `.devcontainer/` folder and a root-level project config file created, so they can commit the project config and regenerate consistently later.
42
+
43
+ **Why this priority**: The `--project-file` flag is the primary new capability. Without it working correctly for a fresh project, the feature has no value.
44
+
45
+ **Independent Test**: Run `init --project-file` in a directory with no existing project config, then confirm that `.superposition.yml` is created at the repo root and reflects the chosen stack and overlays.
46
+
47
+ **Acceptance Scenarios**:
48
+
49
+ 1. **Given** a repository with no project config file, **When** the user runs `init --project-file`, **Then** `.superposition.yml` is created at the repository root with the selected stack, base image, overlays, and other init options.
50
+ 2. **Given** a repository with an existing `.superposition.yml`, **When** the user runs `init --project-file`, **Then** the existing file is updated (not a new file created) to reflect the newly selected configuration.
51
+ 3. **Given** the project config write fails (e.g., permission error), **When** `init --project-file` is run, **Then** the devcontainer generation still completes successfully and a clear error message is shown for the project-file failure only.
52
+
53
+ ---
54
+
55
+ ### User Story 2 - Update existing project config (Priority: P2)
56
+
57
+ A developer has an existing `superposition.yml` and wants to update it to reflect a changed overlay selection after re-running `init`.
58
+
59
+ **Why this priority**: Round-trip consistency (init → project config → regen) is the main value of the project-config workflow.
60
+
61
+ **Independent Test**: Create a `superposition.yml`, run `init --project-file` with different overlays, and confirm that the file is updated rather than a second file being created.
62
+
63
+ **Acceptance Scenarios**:
64
+
65
+ 1. **Given** a repository with exactly one supported project config file, **When** the user runs `init --project-file` with new overlay selections, **Then** only that existing file is updated and no second project config is created.
66
+ 2. **Given** two supported project config files exist simultaneously, **When** the user runs `init --project-file`, **Then** the command prints an error explaining that only one project config file should exist and does not proceed with the write.
@@ -0,0 +1,126 @@
1
+ # Feature Specification: Target-Aware Generation
2
+
3
+ **Feature Branch**: `copilot/feat-target-aware-generation`
4
+ **Created**: 2026-03-23
5
+ **Status**: Final
6
+ **Input**: Issue [feat] Target-aware generation — produce workspace artifacts and guidance for codespaces, gitpod, and devpod
7
+
8
+ ## Review & Approval _(mandatory before implementation)_
9
+
10
+ - **Spec Path**: `docs/specs/007-target-aware-generation/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 — Generate codespaces artifacts (Priority: P1)
18
+
19
+ A user generates with `--target codespaces` and expects to receive Codespaces-specific files and
20
+ guidance alongside the normal devcontainer output.
21
+
22
+ **Acceptance:**
23
+
24
+ 1. `--target codespaces` → `devcontainer.json` extended with `hostRequirements`, `CODESPACES.md` written to `.devcontainer/`.
25
+ 2. `--target local` or no `--target` → no `CODESPACES.md`, no `hostRequirements` in devcontainer.
26
+
27
+ ### User Story 2 — Generate gitpod artifacts (Priority: P1)
28
+
29
+ A user generates with `--target gitpod` and expects a `.gitpod.yml` in the project root and
30
+ setup guidance inside `.devcontainer/`.
31
+
32
+ **Acceptance:**
33
+
34
+ 1. `--target gitpod` → `.gitpod.yml` at project root with tasks and port exposures from selected overlays; `GITPOD.md` written to `.devcontainer/`.
35
+ 2. `--target local` → no `.gitpod.yml`, no `GITPOD.md`.
36
+
37
+ ### User Story 3 — Generate devpod artifacts (Priority: P1)
38
+
39
+ A user generates with `--target devpod` and expects a `devpod.yaml` at the project root and
40
+ setup guidance inside `.devcontainer/`.
41
+
42
+ **Acceptance:**
43
+
44
+ 1. `--target devpod` → `devpod.yaml` at project root; `DEVPOD.md` written to `.devcontainer/`.
45
+ 2. `--target local` → no `devpod.yaml`, no `DEVPOD.md`.
46
+
47
+ ### User Story 4 — Local generation unchanged (Priority: P1)
48
+
49
+ When a user generates without specifying a target, or with `--target local`, the output must
50
+ not contain any non-local artifacts.
51
+
52
+ **Acceptance:**
53
+
54
+ 1. No `--target` flag → output identical to current behavior; no new files written.
55
+ 2. `--target local` (explicit) → same output as omitting `--target`.
56
+
57
+ ### User Story 5 — Regeneration from manifest with target (Priority: P2)
58
+
59
+ A user regenerates from an existing `superposition.json` that includes `"target": "gitpod"` and
60
+ expects the same Gitpod-specific artifacts without being prompted again.
61
+
62
+ **Acceptance:**
63
+
64
+ 1. Manifest with `target: gitpod` → regen produces `.gitpod.yml` and `GITPOD.md`.
65
+ 2. Manifest with no `target` or `target: local` → regen produces no target-specific artifacts.
66
+
67
+ ### User Story 6 — Target switching cleans up stale artifacts (Priority: P2)
68
+
69
+ A user regenerates with a different `--target` value and expects the previous target's
70
+ project-root artifacts to be removed.
71
+
72
+ **Acceptance:**
73
+
74
+ 1. Previous run was `--target gitpod` (`.gitpod.yml` exists); regeneration with `--target codespaces` → `.gitpod.yml` removed, `CODESPACES.md` written.
75
+ 2. Previous run was `--target devpod`; regeneration with `--target local` → `devpod.yaml` removed.
76
+
77
+ ## Technical Design
78
+
79
+ ### `TargetRule` interface
80
+
81
+ A `TargetRule` encapsulates everything about generating artifacts for one deployment target:
82
+
83
+ ```typescript
84
+ interface TargetRule {
85
+ target: DeploymentTarget;
86
+ /** Extra fields merged into devcontainer.json */
87
+ devcontainerPatch(context: TargetRuleContext): Partial<DevContainer>;
88
+ /** Files to write; keys are relative to outputPath, '../<name>' writes to project root */
89
+ generateFiles(context: TargetRuleContext): Map<string, string>;
90
+ /** All relative paths owned by this rule (for stale-cleanup on target switch) */
91
+ ownedFiles(): string[];
92
+ }
93
+ ```
94
+
95
+ ### Per-target rules
96
+
97
+ | Target | devcontainer.json change | Files in `.devcontainer/` | Files at project root |
98
+ | ------------ | ------------------------ | ------------------------- | --------------------- |
99
+ | `local` | none | none | none |
100
+ | `codespaces` | `hostRequirements` | `CODESPACES.md` | none |
101
+ | `gitpod` | none | `GITPOD.md` | `.gitpod.yml` |
102
+ | `devpod` | none | `DEVPOD.md` | `devpod.yaml` |
103
+
104
+ ### `SuperpositionManifest` update
105
+
106
+ Add `target?: DeploymentTarget` so regeneration reproduces the correct artifacts without
107
+ re-prompting.
108
+
109
+ ### Stale-artifact cleanup
110
+
111
+ On each generation, before writing new target artifacts:
112
+
113
+ 1. Read existing `superposition.json` from `outputPath` (if it exists).
114
+ 2. If `manifest.target !== answers.target`, identify previous target's owned project-root
115
+ files (e.g., `.gitpod.yml`) and remove them from the project root.
116
+
117
+ The `.devcontainer/`-local files are already handled by `cleanupStaleFiles` via `FileRegistry`.
118
+
119
+ ## Functional Requirements (from issue)
120
+
121
+ - **FR-001**: Target is a real generation input that changes produced artifacts.
122
+ - **FR-002**: `codespaces`, `gitpod`, `devpod` produce target-specific workspace artifacts.
123
+ - **FR-003**: `local` (explicit or default) produces no additional artifacts.
124
+ - **FR-009**: Regeneration from manifest reproduces target-aware output automatically.
125
+ - **FR-010**: Target switch between runs removes stale artifacts from the previous target.
126
+ - **FR-011**: Backward compatible — manifests without `target` or with `target: local` unchanged.