container-superposition 0.1.7 → 0.1.9
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 +24 -15
- package/dist/scripts/init.js +1 -1537
- package/dist/scripts/init.js.map +1 -1
- package/dist/tool/cli/args.d.ts +20 -0
- package/dist/tool/cli/args.d.ts.map +1 -0
- package/dist/tool/cli/args.js +325 -0
- package/dist/tool/cli/args.js.map +1 -0
- package/dist/tool/cli/run.d.ts +2 -0
- package/dist/tool/cli/run.d.ts.map +1 -0
- package/dist/tool/cli/run.js +318 -0
- package/dist/tool/cli/run.js.map +1 -0
- package/dist/tool/commands/adopt.js +1 -1
- package/dist/tool/commands/adopt.js.map +1 -1
- package/dist/tool/commands/doctor.d.ts +1 -0
- package/dist/tool/commands/doctor.d.ts.map +1 -1
- package/dist/tool/commands/doctor.js +1510 -78
- package/dist/tool/commands/doctor.js.map +1 -1
- package/dist/tool/commands/explain.d.ts.map +1 -1
- package/dist/tool/commands/explain.js +9 -0
- package/dist/tool/commands/explain.js.map +1 -1
- package/dist/tool/commands/migrate.d.ts +7 -0
- package/dist/tool/commands/migrate.d.ts.map +1 -0
- package/dist/tool/commands/migrate.js +52 -0
- package/dist/tool/commands/migrate.js.map +1 -0
- package/dist/tool/questionnaire/answers.d.ts +16 -0
- package/dist/tool/questionnaire/answers.d.ts.map +1 -0
- package/dist/tool/questionnaire/answers.js +102 -0
- package/dist/tool/questionnaire/answers.js.map +1 -0
- package/dist/tool/questionnaire/composer.d.ts +6 -4
- package/dist/tool/questionnaire/composer.d.ts.map +1 -1
- package/dist/tool/questionnaire/composer.js +778 -45
- package/dist/tool/questionnaire/composer.js.map +1 -1
- package/dist/tool/questionnaire/presets.d.ts +60 -0
- package/dist/tool/questionnaire/presets.d.ts.map +1 -0
- package/dist/tool/questionnaire/presets.js +165 -0
- package/dist/tool/questionnaire/presets.js.map +1 -0
- package/dist/tool/questionnaire/questionnaire.d.ts +10 -0
- package/dist/tool/questionnaire/questionnaire.d.ts.map +1 -0
- package/dist/tool/questionnaire/questionnaire.js +582 -0
- package/dist/tool/questionnaire/questionnaire.js.map +1 -0
- package/dist/tool/schema/manifest-migrations.d.ts +5 -0
- package/dist/tool/schema/manifest-migrations.d.ts.map +1 -1
- package/dist/tool/schema/manifest-migrations.js +45 -0
- package/dist/tool/schema/manifest-migrations.js.map +1 -1
- package/dist/tool/schema/overlay-loader.d.ts.map +1 -1
- package/dist/tool/schema/overlay-loader.js +24 -0
- package/dist/tool/schema/overlay-loader.js.map +1 -1
- package/dist/tool/schema/project-config.d.ts +13 -1
- package/dist/tool/schema/project-config.d.ts.map +1 -1
- package/dist/tool/schema/project-config.js +188 -10
- package/dist/tool/schema/project-config.js.map +1 -1
- package/dist/tool/schema/target-rules.d.ts +78 -0
- package/dist/tool/schema/target-rules.d.ts.map +1 -0
- package/dist/tool/schema/target-rules.js +367 -0
- package/dist/tool/schema/target-rules.js.map +1 -0
- package/dist/tool/schema/types.d.ts +42 -3
- package/dist/tool/schema/types.d.ts.map +1 -1
- package/dist/tool/utils/parameters.d.ts +76 -0
- package/dist/tool/utils/parameters.d.ts.map +1 -0
- package/dist/tool/utils/parameters.js +125 -0
- package/dist/tool/utils/parameters.js.map +1 -0
- package/dist/tool/utils/paths.d.ts +2 -0
- package/dist/tool/utils/paths.d.ts.map +1 -0
- package/dist/tool/utils/paths.js +31 -0
- package/dist/tool/utils/paths.js.map +1 -0
- package/docs/deployment-targets.md +88 -56
- package/docs/examples.md +20 -17
- package/docs/filesystem-contract.md +5 -0
- package/docs/minimal-and-editor.md +65 -5
- package/docs/overlay-imports.md +92 -14
- package/docs/overlays.md +231 -135
- package/docs/specs/001-verbose-plan-graph/spec.md +5 -12
- package/docs/specs/002-superposition-config-file/spec.md +5 -12
- package/docs/specs/003-mkdocs2-overlay/spec.md +2 -9
- package/docs/specs/004-doctor-fix/spec.md +1 -8
- package/docs/specs/005-cuda-overlay/spec.md +2 -9
- package/docs/specs/006-rocm-overlay/spec.md +3 -10
- package/docs/specs/007-target-aware-generation/spec.md +119 -0
- package/docs/specs/008-project-file-canonical/spec.md +82 -0
- package/docs/specs/009-project-env/spec.md +140 -0
- package/docs/specs/010-compose-env-materialization/spec.md +123 -0
- package/docs/specs/011-overlay-parameters/spec.md +228 -0
- package/docs/specs/012-ollama-cli-overlay/spec.md +47 -0
- package/docs/specs/013-doctor-dependency-check/spec.md +250 -0
- package/docs/specs/014-doctor-compose-port-cross-validation/spec.md +276 -0
- package/docs/specs/015-doctor-env-example-drift/spec.md +248 -0
- package/docs/specs/016-doctor-reproducibility-check/spec.md +276 -0
- package/docs/specs/017-doctor-dry-run/spec.md +276 -0
- package/docs/specs/018-init-project-file/spec.md +59 -0
- package/docs/specs/taxonomy.md +186 -0
- package/overlays/.presets/full-observability.yml +113 -0
- package/overlays/.presets/k8s-dev.yml +174 -0
- package/overlays/.presets/local-llm.yml +105 -0
- package/overlays/.presets/vector-ai.yml +150 -0
- package/overlays/.shared/README.md +27 -2
- package/overlays/.shared/compose/nvidia-gpu-devcontainer.yml +22 -0
- package/overlays/.shared/vscode/js-ts-settings.json +19 -0
- package/overlays/.shared/vscode/markdown-extensions.json +8 -0
- package/overlays/alertmanager/devcontainer.patch.json +0 -1
- package/overlays/alertmanager/docker-compose.yml +8 -0
- package/overlays/alertmanager/overlay.yml +1 -0
- package/overlays/amp/devcontainer.patch.json +4 -1
- package/overlays/bun/devcontainer.patch.json +1 -10
- package/overlays/bun/overlay.yml +8 -1
- package/overlays/claude-code/devcontainer.patch.json +6 -1
- package/overlays/codex/devcontainer.patch.json +5 -0
- package/overlays/comfyui/.env.example +34 -0
- package/overlays/comfyui/README.md +342 -0
- package/overlays/comfyui/devcontainer.patch.json +15 -0
- package/overlays/comfyui/docker-compose.yml +40 -0
- package/overlays/comfyui/overlay.yml +24 -0
- package/overlays/comfyui/setup.sh +36 -0
- package/overlays/comfyui/verify.sh +103 -0
- package/overlays/commitlint/devcontainer.patch.json +1 -6
- package/overlays/docker-sock/overlay.yml +1 -0
- package/overlays/dotnet/overlay.yml +4 -1
- package/overlays/fuseki/.env.example +5 -0
- package/overlays/fuseki/README.md +173 -0
- package/overlays/fuseki/devcontainer.patch.json +18 -0
- package/overlays/fuseki/docker-compose.yml +29 -0
- package/overlays/fuseki/overlay.yml +42 -0
- package/overlays/fuseki/verify.sh +58 -0
- package/overlays/gemini-cli/devcontainer.patch.json +4 -1
- package/overlays/go/overlay.yml +6 -1
- package/overlays/grafana/devcontainer.patch.json +0 -1
- package/overlays/grafana/docker-compose.yml +8 -2
- package/overlays/grafana/overlay.yml +6 -1
- package/overlays/jaeger/.env.example +11 -0
- package/overlays/jaeger/README.md +33 -4
- package/overlays/jaeger/devcontainer.patch.json +9 -1
- package/overlays/jaeger/docker-compose.yml +17 -0
- package/overlays/jaeger/overlay.yml +1 -12
- package/overlays/java/overlay.yml +6 -1
- package/overlays/jupyter/docker-compose.yml +1 -0
- package/overlays/jupyter/overlay.yml +1 -0
- package/overlays/k3d/README.md +201 -0
- package/overlays/k3d/devcontainer.patch.json +9 -0
- package/overlays/k3d/overlay.yml +19 -0
- package/overlays/k3d/setup.sh +34 -0
- package/overlays/k3d/verify.sh +38 -0
- package/overlays/keycloak/devcontainer.patch.json +0 -1
- package/overlays/keycloak/docker-compose.yml +1 -0
- package/overlays/keycloak/overlay.yml +15 -0
- package/overlays/localstack/docker-compose.yml +1 -0
- package/overlays/localstack/overlay.yml +19 -1
- package/overlays/loki/devcontainer.patch.json +0 -1
- package/overlays/loki/docker-compose.yml +8 -0
- package/overlays/loki/overlay.yml +1 -0
- package/overlays/mailpit/docker-compose.yml +1 -0
- package/overlays/mailpit/overlay.yml +1 -0
- package/overlays/minio/devcontainer.patch.json +1 -1
- package/overlays/minio/docker-compose.yml +1 -0
- package/overlays/minio/overlay.yml +23 -2
- package/overlays/mkdocs/devcontainer.patch.json +1 -5
- package/overlays/mkdocs/overlay.yml +3 -1
- package/overlays/mkdocs2/devcontainer.patch.json +1 -5
- package/overlays/mkdocs2/overlay.yml +2 -0
- package/overlays/mongodb/docker-compose.yml +2 -0
- package/overlays/mongodb/overlay.yml +26 -2
- package/overlays/mysql/docker-compose.yml +2 -0
- package/overlays/mysql/overlay.yml +36 -2
- package/overlays/nats/docker-compose.yml +1 -0
- package/overlays/nats/overlay.yml +18 -2
- package/overlays/nodejs/devcontainer.patch.json +1 -12
- package/overlays/nodejs/overlay.yml +8 -1
- package/overlays/ollama/.env.example +14 -0
- package/overlays/ollama/README.md +326 -0
- package/overlays/ollama/devcontainer.patch.json +14 -0
- package/overlays/ollama/docker-compose.yml +25 -0
- package/overlays/ollama/overlay.yml +27 -0
- package/overlays/ollama/verify.sh +76 -0
- package/overlays/ollama-cli/README.md +90 -0
- package/overlays/ollama-cli/devcontainer.patch.json +3 -0
- package/overlays/ollama-cli/overlay.yml +19 -0
- package/overlays/ollama-cli/setup.sh +103 -0
- package/overlays/ollama-cli/verify.sh +49 -0
- package/overlays/open-webui/.env.example +5 -0
- package/overlays/open-webui/README.md +162 -0
- package/overlays/open-webui/devcontainer.patch.json +14 -0
- package/overlays/open-webui/docker-compose.yml +24 -0
- package/overlays/open-webui/overlay.yml +45 -0
- package/overlays/opencode/devcontainer.patch.json +4 -1
- package/overlays/otel-collector/README.md +4 -0
- package/overlays/otel-collector/devcontainer.patch.json +4 -1
- package/overlays/otel-collector/docker-compose.yml +8 -4
- package/overlays/otel-collector/overlay.yml +1 -0
- package/overlays/otel-demo-nodejs/devcontainer.patch.json +0 -1
- package/overlays/otel-demo-nodejs/docker-compose.yml +1 -0
- package/overlays/otel-demo-nodejs/overlay.yml +9 -1
- package/overlays/otel-demo-python/devcontainer.patch.json +0 -1
- package/overlays/otel-demo-python/docker-compose.yml +1 -0
- package/overlays/otel-demo-python/overlay.yml +6 -1
- package/overlays/pandoc/README.md +10 -0
- package/overlays/pandoc/devcontainer.patch.json +0 -5
- package/overlays/pandoc/overlay.yml +2 -0
- package/overlays/pandoc/setup.sh +10 -0
- package/overlays/pgvector/.env.example +6 -0
- package/overlays/pgvector/README.md +215 -0
- package/overlays/pgvector/devcontainer.patch.json +29 -0
- package/overlays/pgvector/docker-compose.yml +33 -0
- package/overlays/pgvector/overlay.yml +47 -0
- package/overlays/playwright/devcontainer.patch.json +0 -5
- package/overlays/playwright/overlay.yml +2 -1
- package/overlays/postgres/.env.example +5 -5
- package/overlays/postgres/devcontainer.patch.json +4 -4
- package/overlays/postgres/docker-compose.yml +11 -6
- package/overlays/postgres/overlay.yml +23 -2
- package/overlays/pre-commit/devcontainer.patch.json +1 -7
- package/overlays/prometheus/devcontainer.patch.json +0 -1
- package/overlays/prometheus/docker-compose.yml +8 -0
- package/overlays/prometheus/overlay.yml +1 -0
- package/overlays/promtail/devcontainer.patch.json +1 -2
- package/overlays/promtail/docker-compose.yml +8 -0
- package/overlays/promtail/overlay.yml +1 -0
- package/overlays/qdrant/.env.example +4 -0
- package/overlays/qdrant/README.md +216 -0
- package/overlays/qdrant/devcontainer.patch.json +20 -0
- package/overlays/qdrant/docker-compose.yml +26 -0
- package/overlays/qdrant/overlay.yml +44 -0
- package/overlays/rabbitmq/docker-compose.yml +1 -0
- package/overlays/rabbitmq/overlay.yml +25 -2
- package/overlays/redis/docker-compose.yml +7 -0
- package/overlays/redis/overlay.yml +15 -1
- package/overlays/redpanda/docker-compose.yml +1 -0
- package/overlays/redpanda/overlay.yml +15 -3
- package/overlays/rocm/overlay.yml +2 -1
- package/overlays/rust/overlay.yml +3 -1
- package/overlays/skaffold/README.md +256 -0
- package/overlays/skaffold/devcontainer.patch.json +9 -0
- package/overlays/skaffold/overlay.yml +20 -0
- package/overlays/skaffold/setup.sh +33 -0
- package/overlays/skaffold/verify.sh +24 -0
- package/overlays/sqlserver/docker-compose.yml +1 -0
- package/overlays/sqlserver/overlay.yml +17 -0
- package/overlays/tempo/devcontainer.patch.json +0 -1
- package/overlays/tempo/docker-compose.yml +8 -0
- package/overlays/tempo/overlay.yml +1 -0
- package/overlays/windsurf-cli/devcontainer.patch.json +4 -1
- package/package.json +3 -2
- package/tool/schema/config.schema.json +31 -1
- package/tool/schema/overlay-manifest.schema.json +33 -0
- package/overlays/.shared/otel/otel-base-config.yaml +0 -30
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Overlay parameter resolution and {{cs.PARAM_NAME}} substitution engine.
|
|
3
|
+
*
|
|
4
|
+
* Syntax: {{cs.PARAM_NAME}} — chosen because it:
|
|
5
|
+
* - does NOT collide with Docker Compose ${VAR} / ${VAR:-default}
|
|
6
|
+
* - does NOT collide with shell $VAR / ${VAR} / ${VAR:-x}
|
|
7
|
+
* - does NOT collide with VS Code ${localWorkspaceFolder} / ${env:VAR}
|
|
8
|
+
* - does NOT collide with GitHub Actions ${{ github.* }}
|
|
9
|
+
* - is consistent with the existing preset {{parameters.<key>.id}} convention
|
|
10
|
+
*
|
|
11
|
+
* This module deliberately has NO parser, NO AST, NO conditionals.
|
|
12
|
+
* If string.replace() can't do it, it doesn't belong here.
|
|
13
|
+
*/
|
|
14
|
+
import type { OverlayMetadata, OverlayParameterDefinition } from '../schema/types.js';
|
|
15
|
+
/**
|
|
16
|
+
* A parameter declaration enriched with the overlay that declared it.
|
|
17
|
+
*/
|
|
18
|
+
export interface DeclaredParameter extends OverlayParameterDefinition {
|
|
19
|
+
overlayId: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Result of parameter resolution.
|
|
23
|
+
*/
|
|
24
|
+
export interface ResolvedParameters {
|
|
25
|
+
/** Key → resolved value map ready for substitution. */
|
|
26
|
+
values: Record<string, string>;
|
|
27
|
+
/** Parameters that are required but have no value — generation must fail. */
|
|
28
|
+
missingRequired: string[];
|
|
29
|
+
/** User-supplied parameter keys not declared by any selected overlay (warnings only). */
|
|
30
|
+
unknownSupplied: string[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Collect all parameter declarations from the selected overlay set.
|
|
34
|
+
* Returns a map of parameter name → declaration enriched with the declaring overlay.
|
|
35
|
+
*
|
|
36
|
+
* When two overlays declare the same parameter name, the first declaration wins
|
|
37
|
+
* (overlays are processed in composition order).
|
|
38
|
+
*/
|
|
39
|
+
export declare function collectOverlayParameters(overlayIds: string[], allOverlayDefs: OverlayMetadata[]): Record<string, DeclaredParameter>;
|
|
40
|
+
/**
|
|
41
|
+
* Resolve parameter values by applying the resolution order:
|
|
42
|
+
* 1. Supplied values (from project file or CLI — highest priority)
|
|
43
|
+
* 2. Overlay defaults (lowest priority)
|
|
44
|
+
*
|
|
45
|
+
* Returns resolved values, any missing-required errors, and unknown-supplied warnings.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveParameters(declared: Record<string, DeclaredParameter>, supplied: Record<string, string>): ResolvedParameters;
|
|
48
|
+
/**
|
|
49
|
+
* Replace all {{cs.KEY}} tokens in `content` with the corresponding resolved value.
|
|
50
|
+
* Tokens for keys not present in `resolved` are left intact (to be caught by validation).
|
|
51
|
+
*
|
|
52
|
+
* Docker Compose ${VAR}, shell $VAR, VS Code ${env:VAR}, and GitHub Actions ${{ }}
|
|
53
|
+
* expressions are NEVER touched — only the {{cs.KEY}} pattern is matched.
|
|
54
|
+
*/
|
|
55
|
+
export declare function substituteParameters(content: string, resolved: Record<string, string>): string;
|
|
56
|
+
/**
|
|
57
|
+
* Recursively substitute {{cs.KEY}} tokens in all string fields of an object.
|
|
58
|
+
* This is preferred over substituting into JSON.stringify() output because it
|
|
59
|
+
* avoids producing invalid JSON when parameter values contain JSON-special
|
|
60
|
+
* characters (quotes, backslashes, newlines, etc.).
|
|
61
|
+
*
|
|
62
|
+
* Non-string values (numbers, booleans, arrays, nested objects) are traversed
|
|
63
|
+
* but their non-string leaves are returned unchanged.
|
|
64
|
+
*/
|
|
65
|
+
export declare function substituteParametersInObject(obj: unknown, resolved: Record<string, string>): unknown;
|
|
66
|
+
/**
|
|
67
|
+
* Validate that no unresolved {{cs.*}} tokens remain in `content`.
|
|
68
|
+
* Returns a list of unresolved token strings (empty = valid).
|
|
69
|
+
*/
|
|
70
|
+
export declare function findUnresolvedTokens(content: string): string[];
|
|
71
|
+
/**
|
|
72
|
+
* Redact sensitive parameter values for display (e.g. in plan output).
|
|
73
|
+
* Non-sensitive values are returned as-is.
|
|
74
|
+
*/
|
|
75
|
+
export declare function redactSensitiveValues(values: Record<string, string>, declared: Record<string, DeclaredParameter>): Record<string, string>;
|
|
76
|
+
//# sourceMappingURL=parameters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parameters.d.ts","sourceRoot":"","sources":["../../../tool/utils/parameters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAKtF;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,0BAA0B;IACjE,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,6EAA6E;IAC7E,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,yFAAyF;IACzF,eAAe,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACpC,UAAU,EAAE,MAAM,EAAE,EACpB,cAAc,EAAE,eAAe,EAAE,GAClC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAgBnC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC3C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,kBAAkB,CAmBpB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAI9F;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CACxC,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,OAAO,CAeT;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ9D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAC5C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMxB"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Overlay parameter resolution and {{cs.PARAM_NAME}} substitution engine.
|
|
3
|
+
*
|
|
4
|
+
* Syntax: {{cs.PARAM_NAME}} — chosen because it:
|
|
5
|
+
* - does NOT collide with Docker Compose ${VAR} / ${VAR:-default}
|
|
6
|
+
* - does NOT collide with shell $VAR / ${VAR} / ${VAR:-x}
|
|
7
|
+
* - does NOT collide with VS Code ${localWorkspaceFolder} / ${env:VAR}
|
|
8
|
+
* - does NOT collide with GitHub Actions ${{ github.* }}
|
|
9
|
+
* - is consistent with the existing preset {{parameters.<key>.id}} convention
|
|
10
|
+
*
|
|
11
|
+
* This module deliberately has NO parser, NO AST, NO conditionals.
|
|
12
|
+
* If string.replace() can't do it, it doesn't belong here.
|
|
13
|
+
*/
|
|
14
|
+
/** Regex matching ALL {{cs.KEY}} tokens (used for substitution and validation). */
|
|
15
|
+
const CS_PARAM_REGEX = /\{\{cs\.([A-Z0-9_]+)\}\}/g;
|
|
16
|
+
/**
|
|
17
|
+
* Collect all parameter declarations from the selected overlay set.
|
|
18
|
+
* Returns a map of parameter name → declaration enriched with the declaring overlay.
|
|
19
|
+
*
|
|
20
|
+
* When two overlays declare the same parameter name, the first declaration wins
|
|
21
|
+
* (overlays are processed in composition order).
|
|
22
|
+
*/
|
|
23
|
+
export function collectOverlayParameters(overlayIds, allOverlayDefs) {
|
|
24
|
+
const declared = {};
|
|
25
|
+
const overlayById = new Map(allOverlayDefs.map((o) => [o.id, o]));
|
|
26
|
+
for (const id of overlayIds) {
|
|
27
|
+
const overlay = overlayById.get(id);
|
|
28
|
+
if (!overlay?.parameters)
|
|
29
|
+
continue;
|
|
30
|
+
for (const [key, def] of Object.entries(overlay.parameters)) {
|
|
31
|
+
if (!(key in declared)) {
|
|
32
|
+
declared[key] = { ...def, overlayId: id };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return declared;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolve parameter values by applying the resolution order:
|
|
40
|
+
* 1. Supplied values (from project file or CLI — highest priority)
|
|
41
|
+
* 2. Overlay defaults (lowest priority)
|
|
42
|
+
*
|
|
43
|
+
* Returns resolved values, any missing-required errors, and unknown-supplied warnings.
|
|
44
|
+
*/
|
|
45
|
+
export function resolveParameters(declared, supplied) {
|
|
46
|
+
const values = {};
|
|
47
|
+
const missingRequired = [];
|
|
48
|
+
// Resolve each declared parameter
|
|
49
|
+
for (const [key, def] of Object.entries(declared)) {
|
|
50
|
+
if (key in supplied) {
|
|
51
|
+
values[key] = supplied[key];
|
|
52
|
+
}
|
|
53
|
+
else if (def.default !== undefined) {
|
|
54
|
+
values[key] = def.default;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
missingRequired.push(key);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Identify unknown supplied parameters (not declared by any overlay)
|
|
61
|
+
const unknownSupplied = Object.keys(supplied).filter((key) => !(key in declared));
|
|
62
|
+
return { values, missingRequired, unknownSupplied };
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Replace all {{cs.KEY}} tokens in `content` with the corresponding resolved value.
|
|
66
|
+
* Tokens for keys not present in `resolved` are left intact (to be caught by validation).
|
|
67
|
+
*
|
|
68
|
+
* Docker Compose ${VAR}, shell $VAR, VS Code ${env:VAR}, and GitHub Actions ${{ }}
|
|
69
|
+
* expressions are NEVER touched — only the {{cs.KEY}} pattern is matched.
|
|
70
|
+
*/
|
|
71
|
+
export function substituteParameters(content, resolved) {
|
|
72
|
+
return content.replace(CS_PARAM_REGEX, (match, key) => {
|
|
73
|
+
return key in resolved ? resolved[key] : match;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Recursively substitute {{cs.KEY}} tokens in all string fields of an object.
|
|
78
|
+
* This is preferred over substituting into JSON.stringify() output because it
|
|
79
|
+
* avoids producing invalid JSON when parameter values contain JSON-special
|
|
80
|
+
* characters (quotes, backslashes, newlines, etc.).
|
|
81
|
+
*
|
|
82
|
+
* Non-string values (numbers, booleans, arrays, nested objects) are traversed
|
|
83
|
+
* but their non-string leaves are returned unchanged.
|
|
84
|
+
*/
|
|
85
|
+
export function substituteParametersInObject(obj, resolved) {
|
|
86
|
+
if (typeof obj === 'string') {
|
|
87
|
+
return substituteParameters(obj, resolved);
|
|
88
|
+
}
|
|
89
|
+
if (Array.isArray(obj)) {
|
|
90
|
+
return obj.map((item) => substituteParametersInObject(item, resolved));
|
|
91
|
+
}
|
|
92
|
+
if (obj !== null && typeof obj === 'object') {
|
|
93
|
+
const result = {};
|
|
94
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
95
|
+
result[k] = substituteParametersInObject(v, resolved);
|
|
96
|
+
}
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
return obj;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Validate that no unresolved {{cs.*}} tokens remain in `content`.
|
|
103
|
+
* Returns a list of unresolved token strings (empty = valid).
|
|
104
|
+
*/
|
|
105
|
+
export function findUnresolvedTokens(content) {
|
|
106
|
+
const found = [];
|
|
107
|
+
let match;
|
|
108
|
+
const regex = new RegExp(CS_PARAM_REGEX.source, 'g');
|
|
109
|
+
while ((match = regex.exec(content)) !== null) {
|
|
110
|
+
found.push(match[0]);
|
|
111
|
+
}
|
|
112
|
+
return found;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Redact sensitive parameter values for display (e.g. in plan output).
|
|
116
|
+
* Non-sensitive values are returned as-is.
|
|
117
|
+
*/
|
|
118
|
+
export function redactSensitiveValues(values, declared) {
|
|
119
|
+
const result = {};
|
|
120
|
+
for (const [key, value] of Object.entries(values)) {
|
|
121
|
+
result[key] = declared[key]?.sensitive ? '***' : value;
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=parameters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parameters.js","sourceRoot":"","sources":["../../../tool/utils/parameters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../tool/utils/paths.ts"],"names":[],"mappings":"AAiBA,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAiB5E"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Resolve a repo-relative path from an anchor directory, handling both
|
|
5
|
+
* source (scripts/) and compiled (dist/scripts/) locations.
|
|
6
|
+
*
|
|
7
|
+
* Walks up from the anchor directory collecting candidate paths:
|
|
8
|
+
* anchor/relative, anchor/../relative, anchor/../../relative, ...
|
|
9
|
+
* Returns the first that exists, or the first candidate as a fallback.
|
|
10
|
+
*/
|
|
11
|
+
// Maximum number of parent directories to walk up when searching for repo-relative paths.
|
|
12
|
+
// 5 levels is sufficient to cover source (<repo>/tool/questionnaire) and compiled
|
|
13
|
+
// (<repo>/dist/tool/questionnaire) layouts without walking too far up the filesystem.
|
|
14
|
+
const MAX_DIRECTORY_WALK_DEPTH = 5;
|
|
15
|
+
export function resolveRepoPath(relativePath, anchor) {
|
|
16
|
+
const candidates = [];
|
|
17
|
+
let currentAnchor = anchor;
|
|
18
|
+
// Walk up from the anchor directory, collecting candidate paths like:
|
|
19
|
+
// anchor/relative, anchor/../relative, anchor/../../relative, ...
|
|
20
|
+
// Stop after MAX_DIRECTORY_WALK_DEPTH levels or when reaching the filesystem root.
|
|
21
|
+
for (let i = 0; i < MAX_DIRECTORY_WALK_DEPTH; i++) {
|
|
22
|
+
candidates.push(path.join(currentAnchor, relativePath));
|
|
23
|
+
const parent = path.dirname(currentAnchor);
|
|
24
|
+
if (parent === currentAnchor) {
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
currentAnchor = parent;
|
|
28
|
+
}
|
|
29
|
+
return candidates.find((c) => fs.existsSync(c)) ?? candidates[0];
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../tool/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;;;;;GAOG;AAEH,0FAA0F;AAC1F,kFAAkF;AAClF,sFAAsF;AACtF,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAEnC,MAAM,UAAU,eAAe,CAAC,YAAoB,EAAE,MAAc;IAChE,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,IAAI,aAAa,GAAG,MAAM,CAAC;IAE3B,sEAAsE;IACtE,kEAAkE;IAClE,mFAAmF;IACnF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,wBAAwB,EAAE,CAAC,EAAE,EAAE,CAAC;QAChD,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAC3C,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;YAC3B,MAAM;QACV,CAAC;QACD,aAAa,GAAG,MAAM,CAAC;IAC3B,CAAC;IAED,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC"}
|
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
# Deployment Target Support
|
|
2
2
|
|
|
3
|
-
Container Superposition
|
|
3
|
+
Container Superposition generates workspace artifacts and setup guidance tailored to the
|
|
4
|
+
selected deployment environment using the `--target` flag.
|
|
4
5
|
|
|
5
6
|
## Quick Start
|
|
6
7
|
|
|
7
8
|
```bash
|
|
8
|
-
#
|
|
9
|
+
# Default — local development (no additional files)
|
|
10
|
+
npx container-superposition init --stack compose --language nodejs
|
|
11
|
+
|
|
12
|
+
# GitHub Codespaces (adds hostRequirements + CODESPACES.md)
|
|
9
13
|
npx container-superposition init --target codespaces
|
|
14
|
+
|
|
15
|
+
# Gitpod (adds .gitpod.yml + GITPOD.md)
|
|
10
16
|
npx container-superposition init --target gitpod
|
|
11
|
-
npx container-superposition init --target local # default
|
|
12
17
|
|
|
13
|
-
#
|
|
18
|
+
# DevPod (adds devpod.yaml + DEVPOD.md)
|
|
19
|
+
npx container-superposition init --target devpod
|
|
20
|
+
|
|
21
|
+
# Full example for Codespaces
|
|
14
22
|
npx container-superposition init \
|
|
15
23
|
--stack compose \
|
|
16
24
|
--language nodejs \
|
|
@@ -21,24 +29,52 @@ npx container-superposition init \
|
|
|
21
29
|
|
|
22
30
|
## Supported Deployment Targets
|
|
23
31
|
|
|
24
|
-
| Target | Description | Docker Support | Auto Port Forward |
|
|
25
|
-
| -------------- | --------------------------------- | -------------- | ----------------- |
|
|
26
|
-
| **local** | Local machine with Docker Desktop | ✅ Host Docker | No |
|
|
27
|
-
| **codespaces** | GitHub Codespaces (cloud IDE) | ⚠️ DinD only | Yes |
|
|
28
|
-
| **gitpod** | Gitpod workspaces | ⚠️ DinD only | Yes |
|
|
29
|
-
| **devpod** | DevPod client-only environments | ✅ Host Docker | No |
|
|
32
|
+
| Target | Description | Docker Support | Auto Port Forward | Extra Artifacts |
|
|
33
|
+
| -------------- | --------------------------------- | -------------- | ----------------- | -------------------------------------------------------- |
|
|
34
|
+
| **local** | Local machine with Docker Desktop | ✅ Host Docker | No | None (current behavior) |
|
|
35
|
+
| **codespaces** | GitHub Codespaces (cloud IDE) | ⚠️ DinD only | Yes | `hostRequirements` in devcontainer.json; `CODESPACES.md` |
|
|
36
|
+
| **gitpod** | Gitpod workspaces | ⚠️ DinD only | Yes | `.gitpod.yml` at project root; `GITPOD.md` |
|
|
37
|
+
| **devpod** | DevPod client-only environments | ✅ Host Docker | No | `devpod.yaml` at project root; `DEVPOD.md` |
|
|
30
38
|
|
|
31
|
-
##
|
|
39
|
+
## Target-Specific Artifact Inventory
|
|
32
40
|
|
|
33
|
-
###
|
|
41
|
+
### `--target codespaces`
|
|
42
|
+
|
|
43
|
+
| File | Location | Purpose |
|
|
44
|
+
| ------------------- | ---------------- | --------------------------------------------------------------------------------- |
|
|
45
|
+
| `devcontainer.json` | `.devcontainer/` | Extended with `hostRequirements` (cpu/memory/storage recommendation) |
|
|
46
|
+
| `CODESPACES.md` | `.devcontainer/` | How to open the repo in a Codespace; machine-type guidance; port forwarding notes |
|
|
47
|
+
|
|
48
|
+
**Machine size recommendation** is determined automatically from the overlays selected:
|
|
49
|
+
|
|
50
|
+
- 0–1 service overlays → 2-core (default)
|
|
51
|
+
- 2–3 service overlays → 4-core recommended
|
|
52
|
+
- 4+ service overlays → 8-core recommended
|
|
53
|
+
|
|
54
|
+
### `--target gitpod`
|
|
55
|
+
|
|
56
|
+
| File | Location | Purpose |
|
|
57
|
+
| ------------- | ---------------- | ----------------------------------------------------------------------------------- |
|
|
58
|
+
| `.gitpod.yml` | **Project root** | Gitpod workspace config; references devcontainer; declares tasks and port exposures |
|
|
59
|
+
| `GITPOD.md` | `.devcontainer/` | One-click open badge; Gitpod-specific usage notes |
|
|
34
60
|
|
|
35
|
-
|
|
61
|
+
### `--target devpod`
|
|
36
62
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
63
|
+
| File | Location | Purpose |
|
|
64
|
+
| ------------- | ---------------- | ---------------------------------------------------- |
|
|
65
|
+
| `devpod.yaml` | **Project root** | DevPod workspace descriptor; references devcontainer |
|
|
66
|
+
| `DEVPOD.md` | `.devcontainer/` | `devpod up` instructions; provider examples |
|
|
40
67
|
|
|
41
|
-
|
|
68
|
+
### `--target local` / no `--target`
|
|
69
|
+
|
|
70
|
+
No additional files are written. Output is identical to the current local-first workflow.
|
|
71
|
+
|
|
72
|
+
## How It Works
|
|
73
|
+
|
|
74
|
+
### Interactive Mode
|
|
75
|
+
|
|
76
|
+
If you select overlays that may not work in a cloud environment (e.g. `docker-sock`), the tool
|
|
77
|
+
prompts you to choose a target so it can warn about incompatibilities:
|
|
42
78
|
|
|
43
79
|
```
|
|
44
80
|
⚠️ Deployment Target Compatibility Check:
|
|
@@ -56,76 +92,70 @@ Which environment are you targeting?
|
|
|
56
92
|
📦 DevPod
|
|
57
93
|
```
|
|
58
94
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
The target validates your selection and generates the configuration:
|
|
62
|
-
|
|
63
|
-
- Incompatibilities are allowed (you know what you're doing)
|
|
64
|
-
- Generated documentation notes any compatibility issues
|
|
95
|
+
After you confirm the target, the generator produces the appropriate workspace artifacts
|
|
96
|
+
alongside the standard `.devcontainer/` output.
|
|
65
97
|
|
|
66
|
-
|
|
98
|
+
### CLI Mode
|
|
67
99
|
|
|
68
|
-
|
|
100
|
+
Pass `--target` directly — the target is applied without interactive prompts:
|
|
69
101
|
|
|
70
102
|
```bash
|
|
71
103
|
npx container-superposition init \
|
|
72
104
|
--stack compose \
|
|
73
105
|
--language nodejs \
|
|
74
|
-
--database postgres \
|
|
75
106
|
--dev-tools docker-in-docker \
|
|
76
|
-
--target
|
|
107
|
+
--target gitpod
|
|
77
108
|
```
|
|
78
109
|
|
|
79
|
-
###
|
|
110
|
+
### Regeneration
|
|
111
|
+
|
|
112
|
+
The selected target is saved in `superposition.json` as the `target` field. Regeneration
|
|
113
|
+
re-produces the correct artifacts automatically without re-prompting:
|
|
80
114
|
|
|
81
115
|
```bash
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
116
|
+
# superposition.json contains "target": "gitpod"
|
|
117
|
+
npx container-superposition regen # → .gitpod.yml and GITPOD.md reproduced
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
To switch target on regeneration, pass `--target` explicitly:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npx container-superposition regen --target codespaces
|
|
88
124
|
```
|
|
89
125
|
|
|
126
|
+
Stale artifacts from the previous target (e.g. `.gitpod.yml`) are **removed automatically**
|
|
127
|
+
before the new target's artifacts are written.
|
|
128
|
+
|
|
90
129
|
## Key Compatibility Rules
|
|
91
130
|
|
|
92
131
|
- ⚠️ **docker-sock** requires host Docker → Use in `local` or `devpod` only
|
|
93
132
|
- ✅ **docker-in-docker** works everywhere → Recommended for `codespaces` and `gitpod`
|
|
94
|
-
- 🔄 Cloud targets auto-forward ports → No manual forwarding needed
|
|
133
|
+
- 🔄 Cloud targets auto-forward ports → No manual port forwarding needed
|
|
95
134
|
|
|
96
135
|
## Environment Differences
|
|
97
136
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
### Codespaces/Gitpod
|
|
137
|
+
### Codespaces / Gitpod
|
|
101
138
|
|
|
102
|
-
- **No access to host Docker daemon**
|
|
103
|
-
- **Auto-forward ports**
|
|
104
|
-
- **Cloud-based**
|
|
139
|
+
- **No access to host Docker daemon** — Must use docker-in-docker
|
|
140
|
+
- **Auto-forward ports** — Ports declared in devcontainer.json are automatically accessible
|
|
141
|
+
- **Cloud-based** — Resources may be constrained; machine size matters
|
|
105
142
|
|
|
106
143
|
### Local
|
|
107
144
|
|
|
108
|
-
- **Full access to host Docker**
|
|
109
|
-
- **Faster builds**
|
|
110
|
-
- **Manual port forwarding**
|
|
145
|
+
- **Full access to host Docker** — Can use docker-sock for better performance
|
|
146
|
+
- **Faster builds** — Shared cache with host
|
|
147
|
+
- **Manual port forwarding** — Expose ports explicitly when needed
|
|
111
148
|
|
|
112
149
|
### DevPod
|
|
113
150
|
|
|
114
|
-
- **Client-managed**
|
|
115
|
-
- **Can access host Docker**
|
|
116
|
-
- **Flexible**
|
|
117
|
-
|
|
118
|
-
## Why Deployment Targets?
|
|
119
|
-
|
|
120
|
-
The target system ensures you get warnings about incompatibilities before deploying. This prevents:
|
|
121
|
-
|
|
122
|
-
- Wasted time debugging environment-specific issues
|
|
123
|
-
- Confusion about why overlays don't work in cloud IDEs
|
|
124
|
-
- Having to manually research compatibility
|
|
151
|
+
- **Client-managed** — Runs on your infrastructure (local Docker, cloud VM, etc.)
|
|
152
|
+
- **Can access host Docker** — Depending on provider configuration
|
|
153
|
+
- **Flexible** — Provider chosen at `devpod up` time, not at generation time
|
|
125
154
|
|
|
126
155
|
## Configuration
|
|
127
156
|
|
|
128
|
-
|
|
157
|
+
Deployment target configurations (compatibility rules, port forwarding defaults) are stored in
|
|
158
|
+
`overlays/.registry/deployment-targets.yml`. To add a new target entry:
|
|
129
159
|
|
|
130
160
|
```yaml
|
|
131
161
|
- id: new-target
|
|
@@ -144,6 +174,8 @@ Target configurations are stored in `overlays/.registry/deployment-targets.yml`.
|
|
|
144
174
|
supportsPrivileged: true
|
|
145
175
|
```
|
|
146
176
|
|
|
177
|
+
Target-specific file generation rules are implemented in `tool/schema/target-rules.ts`.
|
|
178
|
+
|
|
147
179
|
## See Also
|
|
148
180
|
|
|
149
181
|
- [Discovery Commands](discovery-commands.md) - Explore overlays before generating
|
package/docs/examples.md
CHANGED
|
@@ -19,9 +19,11 @@ language:
|
|
|
19
19
|
database:
|
|
20
20
|
- postgres
|
|
21
21
|
outputPath: ./.devcontainer
|
|
22
|
+
env:
|
|
23
|
+
APP_ENV: development
|
|
22
24
|
customizations:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
envTemplate:
|
|
26
|
+
POSTGRES_PASSWORD: postgres
|
|
25
27
|
devcontainerPatch:
|
|
26
28
|
features:
|
|
27
29
|
ghcr.io/devcontainers-extra/features/apt-get-packages:1:
|
|
@@ -171,24 +173,25 @@ All examples produce:
|
|
|
171
173
|
|
|
172
174
|
## Customization After Generation
|
|
173
175
|
|
|
174
|
-
|
|
176
|
+
Prefer editing `superposition.yml` and regenerating:
|
|
175
177
|
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
"MY_VAR": "value", // Add environment variables
|
|
187
|
-
},
|
|
188
|
-
}
|
|
178
|
+
```yaml
|
|
179
|
+
# superposition.yml
|
|
180
|
+
containerName: My Custom Name
|
|
181
|
+
env:
|
|
182
|
+
MY_VAR: value
|
|
183
|
+
customizations:
|
|
184
|
+
devcontainerPatch:
|
|
185
|
+
forwardPorts:
|
|
186
|
+
- 3000
|
|
187
|
+
- 8080
|
|
189
188
|
```
|
|
190
189
|
|
|
191
|
-
|
|
190
|
+
Then regenerate:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
npx container-superposition regen
|
|
194
|
+
```
|
|
192
195
|
|
|
193
196
|
## Help and Documentation
|
|
194
197
|
|
|
@@ -11,6 +11,9 @@ your-project/
|
|
|
11
11
|
│ ├── docker-compose.yml # Services (compose stack only)
|
|
12
12
|
│ ├── .env.example # Environment variable templates
|
|
13
13
|
│ ├── ports.json # Port documentation and connection strings
|
|
14
|
+
│ ├── CODESPACES.md # Codespaces setup guidance (--target codespaces only)
|
|
15
|
+
│ ├── GITPOD.md # Gitpod setup guidance (--target gitpod only)
|
|
16
|
+
│ ├── DEVPOD.md # DevPod setup guidance (--target devpod only)
|
|
14
17
|
│ ├── scripts/ # Setup and verification scripts
|
|
15
18
|
│ │ ├── post-create.sh # Runs once when container is created
|
|
16
19
|
│ │ └── post-start.sh # Runs every time container starts
|
|
@@ -18,6 +21,8 @@ your-project/
|
|
|
18
21
|
│ ├── devcontainer.patch.json
|
|
19
22
|
│ └── docker-compose.patch.yml
|
|
20
23
|
├── superposition.json # Manifest file (enables regeneration)
|
|
24
|
+
├── .gitpod.yml # Gitpod workspace config (--target gitpod only)
|
|
25
|
+
├── devpod.yaml # DevPod workspace descriptor (--target devpod only)
|
|
21
26
|
└── .devcontainer.backup-*/ # Automatic backups (gitignored)
|
|
22
27
|
```
|
|
23
28
|
|
|
@@ -86,7 +86,7 @@ container-superposition init --editor vscode
|
|
|
86
86
|
# None - CLI-only, no editor customizations
|
|
87
87
|
container-superposition init --editor none
|
|
88
88
|
|
|
89
|
-
# JetBrains -
|
|
89
|
+
# JetBrains - Generate .idea/ project settings and run configurations
|
|
90
90
|
container-superposition init --editor jetbrains
|
|
91
91
|
```
|
|
92
92
|
|
|
@@ -126,15 +126,61 @@ Removes all editor customizations. Useful for:
|
|
|
126
126
|
|
|
127
127
|
#### jetbrains
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
Generates JetBrains IDE project artifacts and sets the appropriate IDE backend in
|
|
130
|
+
`devcontainer.json`. VS Code customizations are removed.
|
|
130
131
|
|
|
131
132
|
```json
|
|
132
133
|
{
|
|
133
|
-
|
|
134
|
-
|
|
134
|
+
"customizations": {
|
|
135
|
+
"jetbrains": {
|
|
136
|
+
"backend": "WebStorm"
|
|
137
|
+
}
|
|
138
|
+
}
|
|
135
139
|
}
|
|
136
140
|
```
|
|
137
141
|
|
|
142
|
+
The `backend` value is automatically selected based on the primary language overlay:
|
|
143
|
+
|
|
144
|
+
| Language overlay | JetBrains IDE |
|
|
145
|
+
| ------------------------- | --------------------------------- |
|
|
146
|
+
| `nodejs` / `bun` | `WebStorm` |
|
|
147
|
+
| `python` / `mkdocs` | `PyCharm` |
|
|
148
|
+
| `go` | `GoLand` |
|
|
149
|
+
| `dotnet` | `Rider` |
|
|
150
|
+
| `java` | `IntelliJIdea` |
|
|
151
|
+
| `rust` | `RustRover` |
|
|
152
|
+
| none / multiple / unknown | `IntelliJIdea` (generic fallback) |
|
|
153
|
+
|
|
154
|
+
##### Generated artifacts
|
|
155
|
+
|
|
156
|
+
In addition to the `devcontainer.json` update, enabling JetBrains support generates the
|
|
157
|
+
following files in the **project root** (the parent of `.devcontainer/`):
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
.idea/
|
|
161
|
+
.gitignore # shared workspace entries committed to VCS
|
|
162
|
+
runConfigurations/
|
|
163
|
+
npm_dev.xml # Node.js — npm run dev
|
|
164
|
+
python_main.xml # Python — python main.py
|
|
165
|
+
go_run.xml # Go — go run ./...
|
|
166
|
+
dotnet_run.xml # .NET — dotnet run
|
|
167
|
+
java_run.xml # Java — Application run
|
|
168
|
+
rust_run.xml # Rust — cargo run
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Only run configuration files matching the selected language overlays are created.
|
|
172
|
+
|
|
173
|
+
##### Existing `.idea/` directory
|
|
174
|
+
|
|
175
|
+
If `.idea/` already exists (e.g., from a previous generation or user customisation),
|
|
176
|
+
existing files are **never overwritten**. Only files that are missing are written.
|
|
177
|
+
|
|
178
|
+
##### Regenerating with a different editor profile
|
|
179
|
+
|
|
180
|
+
If you later regenerate with `--editor vscode` after a JetBrains generation, the `.idea/`
|
|
181
|
+
directory is **not removed** — it may contain user-created configurations. Switch back
|
|
182
|
+
to `--editor jetbrains` if you want to add new run configurations.
|
|
183
|
+
|
|
138
184
|
### When to Use Editor Profiles
|
|
139
185
|
|
|
140
186
|
**Terminal Workflows:**
|
|
@@ -187,7 +233,7 @@ container-superposition regen --minimal
|
|
|
187
233
|
|
|
188
234
|
# Step 3: Or regenerate for a different editor
|
|
189
235
|
container-superposition regen --editor jetbrains
|
|
190
|
-
#
|
|
236
|
+
# Adds JetBrains customizations and generates .idea/ artifacts
|
|
191
237
|
|
|
192
238
|
# Step 4: Or both together
|
|
193
239
|
container-superposition regen --minimal --editor none
|
|
@@ -237,6 +283,20 @@ container-superposition init \
|
|
|
237
283
|
|
|
238
284
|
**Result:** Lean Codespaces environment with essential tools and VS Code extensions.
|
|
239
285
|
|
|
286
|
+
### JetBrains IDE Setup
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
container-superposition init \
|
|
290
|
+
--editor jetbrains \
|
|
291
|
+
--stack compose \
|
|
292
|
+
--language nodejs \
|
|
293
|
+
--database postgres
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
**Result:** Node.js + PostgreSQL workspace with `.idea/` project settings, a `WebStorm`
|
|
297
|
+
backend in `devcontainer.json`, and an `npm run dev` run configuration ready to use. No
|
|
298
|
+
VS Code extensions included.
|
|
299
|
+
|
|
240
300
|
## Manifest Support
|
|
241
301
|
|
|
242
302
|
Both settings are stored in `superposition.json`:
|