container-superposition 0.1.4 → 0.1.6

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 (98) hide show
  1. package/README.md +74 -1370
  2. package/dist/scripts/init.js +350 -185
  3. package/dist/scripts/init.js.map +1 -1
  4. package/dist/tool/commands/adopt.d.ts +63 -0
  5. package/dist/tool/commands/adopt.d.ts.map +1 -0
  6. package/dist/tool/commands/adopt.js +1104 -0
  7. package/dist/tool/commands/adopt.js.map +1 -0
  8. package/dist/tool/commands/hash.d.ts +36 -0
  9. package/dist/tool/commands/hash.d.ts.map +1 -0
  10. package/dist/tool/commands/hash.js +242 -0
  11. package/dist/tool/commands/hash.js.map +1 -0
  12. package/dist/tool/commands/plan.d.ts +2 -0
  13. package/dist/tool/commands/plan.d.ts.map +1 -1
  14. package/dist/tool/commands/plan.js +262 -42
  15. package/dist/tool/commands/plan.js.map +1 -1
  16. package/dist/tool/schema/project-config.d.ts +17 -0
  17. package/dist/tool/schema/project-config.d.ts.map +1 -0
  18. package/dist/tool/schema/project-config.js +441 -0
  19. package/dist/tool/schema/project-config.js.map +1 -0
  20. package/dist/tool/schema/types.d.ts +39 -1
  21. package/dist/tool/schema/types.d.ts.map +1 -1
  22. package/dist/tool/utils/backup.d.ts +23 -0
  23. package/dist/tool/utils/backup.d.ts.map +1 -0
  24. package/dist/tool/utils/backup.js +123 -0
  25. package/dist/tool/utils/backup.js.map +1 -0
  26. package/docs/README.md +12 -2
  27. package/docs/adopt.md +202 -0
  28. package/docs/custom-patches.md +1 -1
  29. package/docs/discovery-commands.md +55 -3
  30. package/docs/examples.md +40 -6
  31. package/docs/filesystem-contract.md +58 -0
  32. package/docs/hash.md +183 -0
  33. package/docs/minimal-and-editor.md +1 -1
  34. package/docs/overlays.md +70 -0
  35. package/docs/presets-architecture.md +1 -1
  36. package/docs/presets.md +1 -1
  37. package/docs/publishing.md +36 -23
  38. package/docs/security.md +43 -0
  39. package/docs/specs/001-verbose-plan-graph/checklists/requirements.md +36 -0
  40. package/docs/specs/001-verbose-plan-graph/contracts/plan-verbose-output.md +96 -0
  41. package/docs/specs/001-verbose-plan-graph/data-model.md +111 -0
  42. package/docs/specs/001-verbose-plan-graph/plan.md +127 -0
  43. package/docs/specs/001-verbose-plan-graph/quickstart.md +106 -0
  44. package/docs/specs/001-verbose-plan-graph/research.md +100 -0
  45. package/docs/specs/001-verbose-plan-graph/spec.md +128 -0
  46. package/docs/specs/001-verbose-plan-graph/tasks.md +223 -0
  47. package/docs/specs/002-superposition-config-file/checklists/requirements.md +36 -0
  48. package/docs/specs/002-superposition-config-file/contracts/init-project-config.md +98 -0
  49. package/docs/specs/002-superposition-config-file/data-model.md +126 -0
  50. package/docs/specs/002-superposition-config-file/plan.md +213 -0
  51. package/docs/specs/002-superposition-config-file/quickstart.md +140 -0
  52. package/docs/specs/002-superposition-config-file/research.md +144 -0
  53. package/docs/specs/002-superposition-config-file/spec.md +136 -0
  54. package/docs/specs/002-superposition-config-file/tasks.md +215 -0
  55. package/docs/team-workflow.md +33 -1
  56. package/docs/workflows.md +139 -0
  57. package/features/cross-distro-packages/README.md +18 -0
  58. package/features/cross-distro-packages/devcontainer-feature.json +3 -3
  59. package/features/cross-distro-packages/install.sh +49 -7
  60. package/overlays/.presets/sdd.yml +84 -0
  61. package/overlays/README.md +7 -1
  62. package/overlays/amp/README.md +70 -0
  63. package/overlays/amp/devcontainer.patch.json +3 -0
  64. package/overlays/amp/overlay.yml +15 -0
  65. package/overlays/amp/setup.sh +21 -0
  66. package/overlays/amp/verify.sh +21 -0
  67. package/overlays/claude-code/README.md +83 -0
  68. package/overlays/claude-code/devcontainer.patch.json +3 -0
  69. package/overlays/claude-code/overlay.yml +15 -0
  70. package/overlays/claude-code/setup.sh +21 -0
  71. package/overlays/claude-code/verify.sh +21 -0
  72. package/overlays/gemini-cli/README.md +77 -0
  73. package/overlays/gemini-cli/devcontainer.patch.json +3 -0
  74. package/overlays/gemini-cli/overlay.yml +15 -0
  75. package/overlays/gemini-cli/setup.sh +21 -0
  76. package/overlays/gemini-cli/verify.sh +21 -0
  77. package/overlays/opencode/README.md +76 -0
  78. package/overlays/opencode/devcontainer.patch.json +3 -0
  79. package/overlays/opencode/overlay.yml +14 -0
  80. package/overlays/opencode/setup.sh +21 -0
  81. package/overlays/opencode/verify.sh +21 -0
  82. package/overlays/pandoc/README.md +279 -0
  83. package/overlays/pandoc/devcontainer.patch.json +14 -0
  84. package/overlays/pandoc/overlay.yml +19 -0
  85. package/overlays/pandoc/setup.sh +94 -0
  86. package/overlays/pandoc/verify.sh +13 -0
  87. package/overlays/spec-kit/README.md +181 -0
  88. package/overlays/spec-kit/devcontainer.patch.json +6 -0
  89. package/overlays/spec-kit/overlay.yml +19 -0
  90. package/overlays/spec-kit/setup.sh +45 -0
  91. package/overlays/spec-kit/verify.sh +33 -0
  92. package/overlays/windsurf-cli/README.md +69 -0
  93. package/overlays/windsurf-cli/devcontainer.patch.json +3 -0
  94. package/overlays/windsurf-cli/overlay.yml +15 -0
  95. package/overlays/windsurf-cli/setup.sh +21 -0
  96. package/overlays/windsurf-cli/verify.sh +21 -0
  97. package/package.json +1 -1
  98. package/tool/schema/config.schema.json +138 -9
@@ -0,0 +1,215 @@
1
+ # Tasks: Project Configuration File
2
+
3
+ **Input**: Design documents from `docs/specs/002-superposition-config-file/`
4
+ **Prerequisites**: [plan.md](plan.md), [spec.md](spec.md), [research.md](research.md), [data-model.md](data-model.md), [init-project-config.md](contracts/init-project-config.md), [quickstart.md](quickstart.md)
5
+
6
+ **Tests**: Add automated coverage for config discovery, precedence, no-config fallback, explicit `--from-project`, implicit project-file regen, manifest isolation, source-conflict validation, validation failures, and customization parity in `tool/__tests__/commands.test.ts`, `tool/__tests__/composition.test.ts`, `tool/__tests__/manifest-only.test.ts`, and `tool/__tests__/minimal-and-editor.test.ts`, then run `npm test`, `npm run lint`, and `npm run test:smoke`.
7
+
8
+ **Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story.
9
+
10
+ ## Format: `[ID] [P?] [Story] Description`
11
+
12
+ - **[P]**: Can run in parallel (different files, no dependencies)
13
+ - **[Story]**: Which user story this task belongs to (e.g. `US1`, `US2`, `US3`)
14
+ - Include exact repo-relative file paths in descriptions
15
+
16
+ ## Phase 1: Setup (Shared Infrastructure)
17
+
18
+ **Purpose**: Record the approved spec gate and align the feature docs with the implementation baseline before code changes.
19
+
20
+ - [x] T001 Confirm approved spec status and implementation gate in `docs/specs/002-superposition-config-file/spec.md`
21
+ - [x] T002 Align implementation sequencing and verification scope in `docs/specs/002-superposition-config-file/plan.md`
22
+ - [x] T003 Align parity examples and validation steps in `docs/specs/002-superposition-config-file/quickstart.md`
23
+ - [x] T004 [P] Record supported project-config surface and customization parity expectations in `docs/specs/002-superposition-config-file/contracts/init-project-config.md`
24
+
25
+ ---
26
+
27
+ ## Phase 2: Foundational (Blocking Prerequisites)
28
+
29
+ **Purpose**: Add the shared project-config schema and merge-path support that every story depends on.
30
+
31
+ **⚠️ CRITICAL**: No user story work can begin until this phase is complete
32
+
33
+ - [x] T005 Define project-config file discovery, parsed shape, and validation helpers in `tool/schema/project-config.ts`
34
+ - [x] T006 Extend shared config types and `QuestionnaireAnswers` parity fields in `tool/schema/types.ts`
35
+ - [x] T007 Update supported config schema entries for project-config parity in `tool/schema/config.schema.json`
36
+ - [x] T008 Refactor answer-source merging to accept project-config defaults alongside manifest and CLI inputs in `scripts/init.ts`
37
+ - [x] T009 Add foundational regression coverage for project-config discovery, merge precedence, and dual-file ambiguity in `tool/__tests__/commands.test.ts`
38
+ - [x] T010 Add fixture coverage for supported customization parity inputs in `tool/__tests__/composition.test.ts`
39
+
40
+ **Checkpoint**: Foundation ready - user story implementation can now begin in priority order
41
+
42
+ ---
43
+
44
+ ## Phase 3: User Story 1 - Generate from committed project config (Priority: P1) 🎯 MVP
45
+
46
+ **Goal**: Let maintainers define the full supported generation intent, including supported customizations, in one repository-root config file and generate the same output as clean generation.
47
+
48
+ **Independent Test**: Put a valid `.superposition.yml` in the repository root with stack, overlays, output path, and supported customization inputs such as custom container definitions, environment-related settings, and additional generated features, run `npm run init`, and confirm the generated output matches equivalent clean-generation input without re-entering declared values.
49
+
50
+ ### Verification for User Story 1
51
+
52
+ - [x] T011 [US1] Add command regression coverage for valid project-config driven generation in `tool/__tests__/commands.test.ts`
53
+ - [x] T012 [US1] Add composition parity coverage for project-config custom image and container definition inputs in `tool/__tests__/composition.test.ts`
54
+ - [x] T013 [US1] Add parity coverage for environment-related settings and additional generated features in `tool/__tests__/minimal-and-editor.test.ts`
55
+
56
+ ### Implementation for User Story 1
57
+
58
+ - [x] T014 [US1] Load repository-root `.superposition.yml` and `superposition.yml` defaults into the standard init flow in `scripts/init.ts`
59
+ - [x] T015 [US1] Map project-config selections into the clean-generation answer model in `tool/schema/project-config.ts`
60
+ - [x] T016 [US1] Preserve supported customization inputs through generation and summary rendering in `scripts/init.ts`
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
+ - [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`
65
+
66
+ **Checkpoint**: User Story 1 should now be fully functional and testable on its own
67
+
68
+ ---
69
+
70
+ ## Phase 4: User Story 2 - Use config-driven setup in automation (Priority: P2)
71
+
72
+ **Goal**: Let teams run unattended generation from a committed project config while preserving per-run overrides and explicit manifest isolation.
73
+
74
+ **Independent Test**: Run `npm run init` in a non-interactive repository with a valid project config and confirm declared values are not prompted again, direct CLI flags override only that run, and `--from-manifest` remains isolated from project-config defaults.
75
+
76
+ ### Verification for User Story 2
77
+
78
+ - [x] T019 [US2] Add non-interactive command regression coverage for project-config defaults and CLI override precedence in `tool/__tests__/commands.test.ts`
79
+ - [x] T020 [US2] Add manifest-isolation regression coverage for project-config and `--from-manifest` interactions in `tool/__tests__/manifest-only.test.ts`
80
+ - [x] T021 [US2] Add regression coverage for no-config fallback to current interactive and flag-driven behavior in `tool/__tests__/commands.test.ts`
81
+ - [x] T022 [US2] Add regression coverage for partial project-config defaults that still require remaining answers in `tool/__tests__/commands.test.ts`
82
+
83
+ ### Implementation for User Story 2
84
+
85
+ - [x] T023 [US2] Apply project-config values as default persisted input for standard init without prompting for already-declared values in `scripts/init.ts`
86
+ - [x] T024 [US2] Preserve partial project-config values as shared defaults while collecting only unresolved required answers in `scripts/init.ts`
87
+ - [x] T025 [US2] Preserve run-scoped CLI override precedence over project-config defaults in `scripts/init.ts`
88
+ - [x] T026 [US2] Keep explicit manifest mode isolated from repository project-config defaults in `scripts/init.ts`
89
+
90
+ **Checkpoint**: User Stories 1 and 2 should both work independently
91
+
92
+ ---
93
+
94
+ ## Phase 5: User Story 3 - Correct invalid or ambiguous config quickly (Priority: P3)
95
+
96
+ **Goal**: Stop invalid, unsupported, conflicting, or ambiguous project-config input before generation and point users to the corrective action.
97
+
98
+ **Independent Test**: Introduce invalid YAML, unsupported keys, unsupported customization values, conflicting selections, missing non-interactive requirements, and both supported filenames, then confirm generation stops before output with actionable guidance tied to the repository state or config entry.
99
+
100
+ ### Verification for User Story 3
101
+
102
+ - [x] T027 [US3] Add command regression coverage for invalid YAML, unsupported keys, and unsupported values in `tool/__tests__/commands.test.ts`
103
+ - [x] T028 [US3] Add regression coverage for conflicting selections, missing required non-interactive values, and dual-file ambiguity in `tool/__tests__/commands.test.ts`
104
+ - [x] T029 [US3] Add regression coverage for unsupported customization declarations outside the clean-generation surface in `tool/__tests__/commands.test.ts`
105
+
106
+ ### Implementation for User Story 3
107
+
108
+ - [x] T030 [US3] Validate project-config syntax, supported keys, supported values, and conflicting selections before generation in `tool/schema/project-config.ts`
109
+ - [x] T031 [US3] Report repository-root ambiguity and non-interactive missing-value failures with actionable guidance in `scripts/init.ts`
110
+ - [x] T032 [US3] Reject unsupported customization declarations that fall outside the supported clean-generation surface in `tool/schema/project-config.ts`
111
+
112
+ **Checkpoint**: All user stories should now be independently functional
113
+
114
+ ---
115
+
116
+ ## Phase 6: Polish & Cross-Cutting Concerns
117
+
118
+ **Purpose**: Finish documentation, changelog, and end-to-end verification for the declarative workflow.
119
+
120
+ - [x] T033 [P] Document project-config usage, parity scope, and supported customization examples in `README.md`
121
+ - [x] T034 [P] Document local and CI workflow examples for project config in `docs/workflows.md`
122
+ - [x] T035 [P] Document project-config parity examples and customization cases in `docs/examples.md`
123
+ - [x] T036 Update the user-visible project-config change summary in `CHANGELOG.md`
124
+ - [x] T037 Run the maintainer workflow review for SC-003 and record the outcome in `docs/specs/002-superposition-config-file/quickstart.md`
125
+ - [x] T038 Record final verification steps and observed outcomes in `docs/specs/002-superposition-config-file/quickstart.md`
126
+ - [x] T039 Run `npm test`, `npm run lint`, and `npm run test:smoke`, then record the results in `docs/specs/002-superposition-config-file/quickstart.md`
127
+ - [x] T040 Add explicit `--from-project` and implicit `regen` project-file regression coverage in `tool/__tests__/commands.test.ts`
128
+ - [x] T041 Implement `--from-project`, implicit project-file `regen`, and source-conflict validation in `scripts/init.ts`
129
+ - [x] T042 Update project-file regeneration and conflict-resolution documentation in `README.md`, `docs/workflows.md`, and `docs/examples.md`
130
+ - [x] T043 Update the user-visible changelog entry to include `regen --from-project`, implicit project-file `regen`, and source-conflict validation in `CHANGELOG.md`
131
+
132
+ ---
133
+
134
+ ## Dependencies & Execution Order
135
+
136
+ ### Phase Dependencies
137
+
138
+ - **Setup (Phase 1)**: Starts immediately
139
+ - **Foundational (Phase 2)**: Depends on Setup completion and blocks all user story work
140
+ - **User Story 1 (Phase 3)**: Depends on Foundational completion
141
+ - **User Story 2 (Phase 4)**: Depends on Foundational completion and should follow US1 because it extends the same answer-resolution path into unattended and manifest-sensitive flows
142
+ - **User Story 3 (Phase 5)**: Depends on Foundational completion and should follow US1 and US2 because validation rules depend on the final supported project-config surface and precedence behavior
143
+ - **Polish (Phase 6)**: Depends on the desired user stories being complete and now also covers explicit source-selection and regeneration workflow updates
144
+
145
+ ### User Story Dependencies
146
+
147
+ - **User Story 1 (P1)**: No dependency on other stories after Phase 2
148
+ - **User Story 2 (P2)**: Depends on the project-config merge path from US1 and extends it to automation, overrides, and manifest isolation
149
+ - **User Story 3 (P3)**: Depends on the supported config surface from US1 and the precedence rules from US2 so failure behavior matches the completed feature
150
+
151
+ ### Within Each User Story
152
+
153
+ - Add or update verification tasks before implementation for that story
154
+ - Land project-config loading and normalization before parity-sensitive generation changes
155
+ - Complete precedence and failure-handling behavior before final docs and smoke validation
156
+
157
+ ### Parallel Opportunities
158
+
159
+ - `T003` and `T004` can run in parallel during Setup
160
+ - `T009` and `T010` can run in parallel after the foundational schema shape is settled
161
+ - `T012` and `T013` can run in parallel once project-config mapping is defined
162
+ - `T033`, `T034`, and `T035` can run in parallel after behavior is stable
163
+ - `T040`, `T042`, and `T043` can run in parallel after the source-selection behavior is stable
164
+
165
+ ---
166
+
167
+ ## Parallel Example: User Story 1
168
+
169
+ ```bash
170
+ Task: "Add composition parity coverage for project-config custom image and container definition inputs in tool/__tests__/composition.test.ts"
171
+ Task: "Add parity coverage for environment-related settings and additional generated features in tool/__tests__/minimal-and-editor.test.ts"
172
+ ```
173
+
174
+ ## Parallel Example: Polish
175
+
176
+ ```bash
177
+ Task: "Document project-config usage, parity scope, and supported customization examples in README.md"
178
+ Task: "Document local and CI workflow examples for project config in docs/workflows.md"
179
+ Task: "Document project-config parity examples and customization cases in docs/examples.md"
180
+ ```
181
+
182
+ ---
183
+
184
+ ## Implementation Strategy
185
+
186
+ ### MVP First (User Story 1 Only)
187
+
188
+ 1. Complete Phase 1: Setup
189
+ 2. Complete Phase 2: Foundational
190
+ 3. Complete Phase 3: User Story 1
191
+ 4. Validate project-config driven generation against equivalent clean-generation output
192
+ 5. Stop for review before extending into unattended and failure-handling behavior
193
+
194
+ ### Incremental Delivery
195
+
196
+ 1. Land project-config discovery, typing, and merge foundations
197
+ 2. Deliver User Story 1 for repository-root config driven generation with customization parity
198
+ 3. Add User Story 2 for automation, CLI overrides, no-config fallback, and manifest isolation
199
+ 4. Add User Story 3 for validation, ambiguity handling, and corrective guidance
200
+ 5. Finish docs, changelog, and full verification
201
+ 6. Add explicit source-selection and project-file regeneration follow-through so spec, plan, tasks, and CLI behavior stay aligned
202
+
203
+ ### Parallel Team Strategy
204
+
205
+ 1. One developer completes Setup and Foundational work
206
+ 2. After the project-config schema and merge path are stable, one developer can drive US1 implementation while another prepares the parity-focused verification cases
207
+ 3. After US1 is stable, the same command owner should complete US2 and US3 because they concentrate in `scripts/init.ts` and shared validation helpers
208
+
209
+ ---
210
+
211
+ ## Notes
212
+
213
+ - All tasks use the required checklist format with IDs, optional `[P]` markers, story labels for story phases, and exact repo-relative file paths
214
+ - The approved spec gate is already satisfied; execution readiness now depends on completing implementation, verification, and documentation tasks cleanly
215
+ - Favor command-level and composition-level regression tests because the risk is user-visible generation behavior and customization parity drift
@@ -33,6 +33,37 @@ my-project/
33
33
 
34
34
  ## Step-by-Step Setup
35
35
 
36
+ ### 0. Migrating an Existing Devcontainer (Optional)
37
+
38
+ If you already have a hand-crafted `.devcontainer/`, use `adopt` to create the
39
+ initial manifest automatically instead of writing it by hand:
40
+
41
+ ```bash
42
+ # See what would be detected and generated (nothing is written)
43
+ npx container-superposition adopt --dry-run
44
+
45
+ # Run the adoption (writes superposition.json and custom/ patches)
46
+ npx container-superposition adopt
47
+
48
+ # Or also emit a repository-root project file for project-config workflows
49
+ npx container-superposition adopt --project-file
50
+ ```
51
+
52
+ `adopt` reads every feature URI, VS Code extension, and Docker Compose service
53
+ image in your existing configuration and maps them to overlays. Anything with
54
+ no overlay equivalent (custom features, project-specific services, custom
55
+ mounts, unmatched environment variables, …) is written to
56
+ `.devcontainer/custom/` so it survives every subsequent `regen`.
57
+
58
+ `superposition.json` is written to the **project root** (not inside
59
+ `.devcontainer/`), so it can be committed alongside your application code and
60
+ shared with the rest of the team — matching the standard team workflow. If you
61
+ pass `--project-file`, `adopt` also writes a repository-root `.superposition.yml`
62
+ using the same inferred stack, overlays, output path, and supported
63
+ customizations.
64
+
65
+ See the [Adopt Command guide](adopt.md) for full details.
66
+
36
67
  ### 1. Create the Team Manifest
37
68
 
38
69
  The team lead or maintainer creates the initial manifest:
@@ -51,7 +82,7 @@ This creates `superposition.json` in the current directory:
51
82
  ```json
52
83
  {
53
84
  "manifestVersion": "1",
54
- "generatedBy": "0.1.2",
85
+ "generatedBy": "X.Y.Z",
55
86
  "generated": "2026-02-17T14:00:00.000Z",
56
87
  "baseTemplate": "compose",
57
88
  "baseImage": "bookworm",
@@ -535,6 +566,7 @@ code .
535
566
 
536
567
  ## See Also
537
568
 
569
+ - [Adopt Command](adopt.md) - Migrate an existing devcontainer to the overlay-based workflow
538
570
  - [Quick Reference](quick-reference.md) - Common commands and flags
539
571
  - [Overlay Documentation](overlays.md) - Available overlays
540
572
  - [Custom Patches](../tool/README.md#custom-patches) - Custom patch format
@@ -0,0 +1,139 @@
1
+ # Workflows and Regeneration
2
+
3
+ This guide covers project-config driven generation, manifest-based regeneration,
4
+ and common workflows.
5
+
6
+ ## Project Config Workflow
7
+
8
+ Commit exactly one project config file at the repository root:
9
+
10
+ - `.superposition.yml`
11
+ - `superposition.yml`
12
+
13
+ Use it when you want standard `init` runs to start from committed defaults
14
+ instead of a copied command line.
15
+
16
+ ```bash
17
+ npx container-superposition init
18
+ ```
19
+
20
+ Use `--no-interactive` when the config fully describes the intended setup and
21
+ you want unattended generation:
22
+
23
+ ```bash
24
+ npx container-superposition init --no-interactive
25
+ ```
26
+
27
+ Direct CLI flags still win for that run only:
28
+
29
+ ```bash
30
+ npx container-superposition init --no-interactive --output ./tmp-devcontainer
31
+ ```
32
+
33
+ ## Manifest Basics
34
+
35
+ Every generation writes a `superposition.json` manifest that records your choices. It enables:
36
+
37
+ - Reproducible environments
38
+ - Safe upgrades
39
+ - Team sharing
40
+ - Regeneration with backups
41
+
42
+ ## When to Regenerate
43
+
44
+ Use `regen` when you:
45
+
46
+ - Add or remove overlays
47
+ - Update to newer overlay versions
48
+ - Change port offsets
49
+ - Switch base templates
50
+
51
+ Use `init --from-project` or `init --from-manifest` when you:
52
+
53
+ - Want to start from a persisted source and then adjust choices interactively
54
+ - Want a persisted source to provide defaults before making a targeted change
55
+
56
+ Use manual edits when you:
57
+
58
+ - Adjust VS Code settings
59
+ - Add small scripts or config files
60
+ - Tweak a single setting in custom patches
61
+
62
+ ## Quick Regeneration
63
+
64
+ ```bash
65
+ # Uses the repository project file when one exists
66
+ npx container-superposition regen
67
+
68
+ # Or select the project file explicitly
69
+ npx container-superposition regen --from-project
70
+
71
+ # Or run from another directory while targeting a repository root
72
+ npx container-superposition regen --from-project --project-root ../my-project
73
+
74
+ # Falls back to manifest discovery when no project file exists
75
+ npx container-superposition regen
76
+ ```
77
+
78
+ ## Regeneration With Changes
79
+
80
+ ```bash
81
+ # Uses manifest as defaults, then prompts for changes
82
+ npx container-superposition init --from-manifest ./.devcontainer/superposition.json
83
+
84
+ # Uses the repository project file as defaults, then prompts for changes
85
+ npx container-superposition init --from-project
86
+ ```
87
+
88
+ ## Source-Selection Conflicts
89
+
90
+ Persisted-input source flags are mutually exclusive and do not mix with
91
+ clean-generation selection flags:
92
+
93
+ ```bash
94
+ # Invalid: two persisted sources
95
+ npx container-superposition regen --from-project --from-manifest ./.devcontainer/superposition.json
96
+
97
+ # Invalid: persisted source plus structural selection flags
98
+ npx container-superposition init --from-project --stack compose
99
+ ```
100
+
101
+ ## Non-Interactive (CI/CD)
102
+
103
+ ```bash
104
+ npx container-superposition init --no-interactive
105
+
106
+ # Or keep using an explicit manifest when you want that mode
107
+ npx container-superposition init \
108
+ --from-manifest ./.devcontainer/superposition.json \
109
+ --no-interactive \
110
+ --no-backup
111
+ ```
112
+
113
+ ## Backup Behavior
114
+
115
+ - Default: creates `.devcontainer.backup-<timestamp>/`
116
+ - `--no-backup`: skips backup
117
+ - `--backup-dir <path>`: writes backups to a custom location
118
+
119
+ ## Example Workflow
120
+
121
+ ```bash
122
+ # 1. Initial setup
123
+ npx container-superposition init --stack compose --language nodejs --database postgres
124
+
125
+ # 2. Later: reapply the committed project file
126
+ npx container-superposition regen
127
+
128
+ # 3. Or regenerate explicitly from a manifest when that is the intended source
129
+ npx container-superposition init --from-manifest ./.devcontainer/superposition.json
130
+
131
+ # 4. Update to latest overlays
132
+ npx container-superposition@latest regen
133
+ ```
134
+
135
+ ## Team Workflow
136
+
137
+ For a manifest-first approach (commit only `superposition.json`), see:
138
+
139
+ - [team-workflow.md](team-workflow.md)
@@ -6,6 +6,7 @@ A devcontainer feature that installs system packages with automatic distribution
6
6
 
7
7
  - 🔍 **Auto-detection**: Automatically detects whether the container uses apt or apk
8
8
  - 📦 **Distro-specific packages**: Specify different package names for each distribution
9
+ - 🔁 **Fallback package names**: Use `pkgA|pkgB` when Debian/Ubuntu variants expose different names
9
10
  - 🧹 **Clean installation**: Cleans up package manager caches to minimize image size
10
11
  - ⚡ **Fast**: No unnecessary updates or cache rebuilds
11
12
 
@@ -26,6 +27,19 @@ A devcontainer feature that installs system packages with automatic distribution
26
27
 
27
28
  ### Real-World Examples
28
29
 
30
+ **Fallback package names within apt-based distros:**
31
+
32
+ ```json
33
+ {
34
+ "features": {
35
+ "./features/cross-distro-packages": {
36
+ "apt": "fonts-carlito|fonts-crosextra-carlito",
37
+ "apk": ""
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
29
43
  **Node.js Build Tools:**
30
44
 
31
45
  ```json
@@ -85,6 +99,10 @@ A devcontainer feature that installs system packages with automatic distribution
85
99
  | `apt` | string | `""` | Space-separated list of packages for apt-based distributions (Debian, Ubuntu) |
86
100
  | `apk` | string | `""` | Space-separated list of packages for apk-based distributions (Alpine Linux) |
87
101
 
102
+ Package entries may include fallback candidates separated by `|`, for example
103
+ `fonts-carlito|fonts-crosextra-carlito`. The feature selects the first package
104
+ name that exists for the detected package manager.
105
+
88
106
  ## Package Name Differences
89
107
 
90
108
  Common packages that have different names across distributions:
@@ -2,18 +2,18 @@
2
2
  "id": "cross-distro-packages",
3
3
  "version": "1.0.0",
4
4
  "name": "Cross-Distribution Package Manager",
5
- "description": "Install system packages with automatic distribution detection (supports apt and apk)",
5
+ "description": "Install system packages with automatic distribution detection and fallback package-name support (supports apt and apk)",
6
6
  "documentationURL": "https://github.com/veggerby/container-superposition/tree/main/features/cross-distro-packages",
7
7
  "options": {
8
8
  "apt": {
9
9
  "type": "string",
10
10
  "default": "",
11
- "description": "Space-separated list of packages for apt-based distros (Debian, Ubuntu)"
11
+ "description": "Space-separated list of packages for apt-based distros (Debian, Ubuntu). Use pkgA|pkgB to try fallback names."
12
12
  },
13
13
  "apk": {
14
14
  "type": "string",
15
15
  "default": "",
16
- "description": "Space-separated list of packages for apk-based distros (Alpine)"
16
+ "description": "Space-separated list of packages for apk-based distros (Alpine). Use pkgA|pkgB to try fallback names."
17
17
  }
18
18
  },
19
19
  "installsAfter": ["ghcr.io/devcontainers/features/common-utils"]
@@ -14,6 +14,50 @@ deduplicate_packages() {
14
14
  echo "$packages" | tr ' ' '\n' | sort -u | tr '\n' ' ' | sed 's/ $//'
15
15
  }
16
16
 
17
+ resolve_package_token() {
18
+ local manager="$1"
19
+ local token="$2"
20
+ local IFS='|'
21
+ read -r -a candidates <<< "$token"
22
+
23
+ for candidate in "${candidates[@]}"; do
24
+ if [ -z "$candidate" ]; then
25
+ continue
26
+ fi
27
+
28
+ if [ "$manager" = "apt" ]; then
29
+ if apt-cache show "$candidate" >/dev/null 2>&1; then
30
+ echo "$candidate"
31
+ return 0
32
+ fi
33
+ elif [ "$manager" = "apk" ]; then
34
+ if apk search -x "$candidate" >/dev/null 2>&1; then
35
+ echo "$candidate"
36
+ return 0
37
+ fi
38
+ fi
39
+ done
40
+
41
+ return 1
42
+ }
43
+
44
+ resolve_package_list() {
45
+ local manager="$1"
46
+ local packages="$2"
47
+ local resolved=()
48
+
49
+ for token in $packages; do
50
+ local selected=""
51
+ if ! selected=$(resolve_package_token "$manager" "$token"); then
52
+ echo "❌ No package candidate found for \"$token\" using $manager" >&2
53
+ exit 1
54
+ fi
55
+ resolved+=("$selected")
56
+ done
57
+
58
+ deduplicate_packages "${resolved[*]}"
59
+ }
60
+
17
61
  # Exit early if no packages specified
18
62
  if [ -z "$APT_PACKAGES" ] && [ -z "$APK_PACKAGES" ]; then
19
63
  echo "⚠️ No packages specified for installation"
@@ -26,9 +70,8 @@ echo "📦 Installing cross-distro packages..."
26
70
  if command -v apk > /dev/null 2>&1; then
27
71
  # Alpine Linux (apk)
28
72
  if [ -n "$APK_PACKAGES" ]; then
29
- # Deduplicate package list
30
- APK_PACKAGES=$(deduplicate_packages "$APK_PACKAGES")
31
-
73
+ APK_PACKAGES=$(resolve_package_list "apk" "$APK_PACKAGES")
74
+
32
75
  echo " Detected: Alpine Linux (apk)"
33
76
  echo " Installing: $APK_PACKAGES"
34
77
  apk add --no-cache $APK_PACKAGES
@@ -39,12 +82,11 @@ if command -v apk > /dev/null 2>&1; then
39
82
  elif command -v apt-get > /dev/null 2>&1; then
40
83
  # Debian/Ubuntu (apt)
41
84
  if [ -n "$APT_PACKAGES" ]; then
42
- # Deduplicate package list
43
- APT_PACKAGES=$(deduplicate_packages "$APT_PACKAGES")
44
-
85
+ apt-get update
86
+ APT_PACKAGES=$(resolve_package_list "apt" "$APT_PACKAGES")
87
+
45
88
  echo " Detected: Debian/Ubuntu (apt)"
46
89
  echo " Installing: $APT_PACKAGES"
47
- apt-get update
48
90
  DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends $APT_PACKAGES
49
91
  apt-get clean
50
92
  rm -rf /var/lib/apt/lists/*
@@ -0,0 +1,84 @@
1
+ # Spec-Driven Development Preset
2
+ # Complete environment for SDD with specify-cli and your choice of AI coding agent
3
+
4
+ id: sdd
5
+ name: Spec-Driven Development
6
+ description: Complete Spec-Driven Development environment with specify-cli and your choice of AI coding agent
7
+ type: meta
8
+ category: preset
9
+ supports: []
10
+ tags: [preset, sdd, spec-driven, ai, specify, spec-kit]
11
+
12
+ # Overlays to always include
13
+ selects:
14
+ required:
15
+ - spec-kit
16
+
17
+ # Parameterized agent selection
18
+ # Option 'id' is the value passed to `specify init --ai <id>`.
19
+ # 'overlays' is the list of container-superposition overlay IDs to include.
20
+ parameters:
21
+ agent:
22
+ description: AI coding agent to use with Spec Kit
23
+ default: codex
24
+ options:
25
+ - id: codex
26
+ overlays: [codex]
27
+ description: OpenAI Codex CLI (--ai codex)
28
+ - id: claude
29
+ overlays: [claude-code]
30
+ description: Anthropic Claude Code (--ai claude)
31
+ - id: gemini
32
+ overlays: [gemini-cli]
33
+ description: Google Gemini CLI (--ai gemini)
34
+ - id: amp
35
+ overlays: [amp]
36
+ description: Sourcegraph Amp (--ai amp)
37
+ - id: windsurf
38
+ overlays: [windsurf-cli]
39
+ description: Codeium Windsurf (--ai windsurf)
40
+ - id: opencode
41
+ overlays: [opencode]
42
+ description: opencode (--ai opencode)
43
+ - id: copilot
44
+ overlays: []
45
+ description: GitHub Copilot (IDE-integrated, no extra CLI needed) (--ai copilot)
46
+
47
+ # Glue configuration
48
+ glueConfig:
49
+ # environment values support {{parameters.<key>.id}} template substitution —
50
+ # the preset expander replaces it with the selected option's id at generation time.
51
+ environment:
52
+ SPECIFY_AI_AGENT: '{{parameters.agent.id}}'
53
+
54
+ readme: |
55
+ ## Spec-Driven Development (SDD)
56
+
57
+ This devcontainer is configured for Spec-Driven Development using [Spec Kit](https://github.com/github/spec-kit).
58
+
59
+ ### Getting Started
60
+
61
+ Initialize SDD in your project:
62
+
63
+ ```bash
64
+ specify init . --here --ai ${SPECIFY_AI_AGENT:-codex}
65
+ ```
66
+
67
+ ### SDD Workflow
68
+
69
+ Use these slash commands in your AI agent:
70
+
71
+ | Step | Command | Description |
72
+ |------|---------|-------------|
73
+ | 1 | `/speckit.constitution` | Create project governing principles |
74
+ | 2 | `/speckit.specify` | Define requirements |
75
+ | 3 | `/speckit.clarify` | Clarify ambiguities |
76
+ | 4 | `/speckit.plan` | Create implementation plan |
77
+ | 5 | `/speckit.analyze` | Cross-artifact consistency check |
78
+ | 6 | `/speckit.tasks` | Break plan into tasks |
79
+ | 7 | `/speckit.implement` | Execute tasks with AI |
80
+
81
+ ### References
82
+
83
+ - [Spec Kit GitHub](https://github.com/github/spec-kit)
84
+ - [SDD Methodology](https://github.com/github/spec-kit/blob/main/spec-driven.md)
@@ -55,7 +55,13 @@ Each overlay directory contains:
55
55
  - **docker-in-docker** - Docker daemon inside container (conflicts with docker-sock)
56
56
  - **docker-sock** - Docker socket mounting (conflicts with docker-in-docker)
57
57
  - **playwright** - Browser automation with Chromium installed
58
- - **codex** - AI-powered code assistant
58
+ - **codex** - OpenAI Codex CLI for AI-powered code generation and assistance
59
+ - **spec-kit** - Specify CLI for Spec-Driven Development with any AI coding agent
60
+ - **claude-code** - Anthropic Claude Code CLI for AI-powered development assistance
61
+ - **gemini-cli** - Google Gemini CLI for AI-powered development assistance
62
+ - **amp** - Sourcegraph Amp CLI for AI-powered code generation and assistance
63
+ - **windsurf-cli** - Codeium Windsurf CLI for AI-powered development assistance
64
+ - **opencode** - opencode AI coding agent for terminal-based development assistance
59
65
 
60
66
  ## Environment Variables
61
67