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.
- package/README.md +74 -1370
- package/dist/scripts/init.js +350 -185
- package/dist/scripts/init.js.map +1 -1
- package/dist/tool/commands/adopt.d.ts +63 -0
- package/dist/tool/commands/adopt.d.ts.map +1 -0
- package/dist/tool/commands/adopt.js +1104 -0
- package/dist/tool/commands/adopt.js.map +1 -0
- package/dist/tool/commands/hash.d.ts +36 -0
- package/dist/tool/commands/hash.d.ts.map +1 -0
- package/dist/tool/commands/hash.js +242 -0
- package/dist/tool/commands/hash.js.map +1 -0
- package/dist/tool/commands/plan.d.ts +2 -0
- package/dist/tool/commands/plan.d.ts.map +1 -1
- package/dist/tool/commands/plan.js +262 -42
- package/dist/tool/commands/plan.js.map +1 -1
- package/dist/tool/schema/project-config.d.ts +17 -0
- package/dist/tool/schema/project-config.d.ts.map +1 -0
- package/dist/tool/schema/project-config.js +441 -0
- package/dist/tool/schema/project-config.js.map +1 -0
- package/dist/tool/schema/types.d.ts +39 -1
- package/dist/tool/schema/types.d.ts.map +1 -1
- package/dist/tool/utils/backup.d.ts +23 -0
- package/dist/tool/utils/backup.d.ts.map +1 -0
- package/dist/tool/utils/backup.js +123 -0
- package/dist/tool/utils/backup.js.map +1 -0
- package/docs/README.md +12 -2
- package/docs/adopt.md +202 -0
- package/docs/custom-patches.md +1 -1
- package/docs/discovery-commands.md +55 -3
- package/docs/examples.md +40 -6
- package/docs/filesystem-contract.md +58 -0
- package/docs/hash.md +183 -0
- package/docs/minimal-and-editor.md +1 -1
- package/docs/overlays.md +70 -0
- package/docs/presets-architecture.md +1 -1
- package/docs/presets.md +1 -1
- package/docs/publishing.md +36 -23
- package/docs/security.md +43 -0
- package/docs/specs/001-verbose-plan-graph/checklists/requirements.md +36 -0
- package/docs/specs/001-verbose-plan-graph/contracts/plan-verbose-output.md +96 -0
- package/docs/specs/001-verbose-plan-graph/data-model.md +111 -0
- package/docs/specs/001-verbose-plan-graph/plan.md +127 -0
- package/docs/specs/001-verbose-plan-graph/quickstart.md +106 -0
- package/docs/specs/001-verbose-plan-graph/research.md +100 -0
- package/docs/specs/001-verbose-plan-graph/spec.md +128 -0
- package/docs/specs/001-verbose-plan-graph/tasks.md +223 -0
- package/docs/specs/002-superposition-config-file/checklists/requirements.md +36 -0
- package/docs/specs/002-superposition-config-file/contracts/init-project-config.md +98 -0
- package/docs/specs/002-superposition-config-file/data-model.md +126 -0
- package/docs/specs/002-superposition-config-file/plan.md +213 -0
- package/docs/specs/002-superposition-config-file/quickstart.md +140 -0
- package/docs/specs/002-superposition-config-file/research.md +144 -0
- package/docs/specs/002-superposition-config-file/spec.md +136 -0
- package/docs/specs/002-superposition-config-file/tasks.md +215 -0
- package/docs/team-workflow.md +33 -1
- package/docs/workflows.md +139 -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/.presets/sdd.yml +84 -0
- package/overlays/README.md +7 -1
- package/overlays/amp/README.md +70 -0
- package/overlays/amp/devcontainer.patch.json +3 -0
- package/overlays/amp/overlay.yml +15 -0
- package/overlays/amp/setup.sh +21 -0
- package/overlays/amp/verify.sh +21 -0
- package/overlays/claude-code/README.md +83 -0
- package/overlays/claude-code/devcontainer.patch.json +3 -0
- package/overlays/claude-code/overlay.yml +15 -0
- package/overlays/claude-code/setup.sh +21 -0
- package/overlays/claude-code/verify.sh +21 -0
- package/overlays/gemini-cli/README.md +77 -0
- package/overlays/gemini-cli/devcontainer.patch.json +3 -0
- package/overlays/gemini-cli/overlay.yml +15 -0
- package/overlays/gemini-cli/setup.sh +21 -0
- package/overlays/gemini-cli/verify.sh +21 -0
- package/overlays/opencode/README.md +76 -0
- package/overlays/opencode/devcontainer.patch.json +3 -0
- package/overlays/opencode/overlay.yml +14 -0
- package/overlays/opencode/setup.sh +21 -0
- package/overlays/opencode/verify.sh +21 -0
- package/overlays/pandoc/README.md +279 -0
- package/overlays/pandoc/devcontainer.patch.json +14 -0
- package/overlays/pandoc/overlay.yml +19 -0
- package/overlays/pandoc/setup.sh +94 -0
- package/overlays/pandoc/verify.sh +13 -0
- package/overlays/spec-kit/README.md +181 -0
- package/overlays/spec-kit/devcontainer.patch.json +6 -0
- package/overlays/spec-kit/overlay.yml +19 -0
- package/overlays/spec-kit/setup.sh +45 -0
- package/overlays/spec-kit/verify.sh +33 -0
- package/overlays/windsurf-cli/README.md +69 -0
- package/overlays/windsurf-cli/devcontainer.patch.json +3 -0
- package/overlays/windsurf-cli/overlay.yml +15 -0
- package/overlays/windsurf-cli/setup.sh +21 -0
- package/overlays/windsurf-cli/verify.sh +21 -0
- package/package.json +1 -1
- 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
|
package/docs/team-workflow.md
CHANGED
|
@@ -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": "
|
|
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
|
-
|
|
30
|
-
|
|
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
|
-
|
|
43
|
-
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)
|
package/overlays/README.md
CHANGED
|
@@ -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
|
|
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
|
|