container-superposition 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/README.md +24 -15
  2. package/dist/scripts/init.js +1 -1534
  3. package/dist/scripts/init.js.map +1 -1
  4. package/dist/tool/cli/args.d.ts +20 -0
  5. package/dist/tool/cli/args.d.ts.map +1 -0
  6. package/dist/tool/cli/args.js +325 -0
  7. package/dist/tool/cli/args.js.map +1 -0
  8. package/dist/tool/cli/run.d.ts +2 -0
  9. package/dist/tool/cli/run.d.ts.map +1 -0
  10. package/dist/tool/cli/run.js +318 -0
  11. package/dist/tool/cli/run.js.map +1 -0
  12. package/dist/tool/commands/adopt.d.ts.map +1 -1
  13. package/dist/tool/commands/adopt.js +1 -27
  14. package/dist/tool/commands/adopt.js.map +1 -1
  15. package/dist/tool/commands/doctor.d.ts +3 -0
  16. package/dist/tool/commands/doctor.d.ts.map +1 -1
  17. package/dist/tool/commands/doctor.js +1068 -70
  18. package/dist/tool/commands/doctor.js.map +1 -1
  19. package/dist/tool/commands/explain.d.ts.map +1 -1
  20. package/dist/tool/commands/explain.js +18 -0
  21. package/dist/tool/commands/explain.js.map +1 -1
  22. package/dist/tool/commands/migrate.d.ts +7 -0
  23. package/dist/tool/commands/migrate.d.ts.map +1 -0
  24. package/dist/tool/commands/migrate.js +52 -0
  25. package/dist/tool/commands/migrate.js.map +1 -0
  26. package/dist/tool/questionnaire/answers.d.ts +16 -0
  27. package/dist/tool/questionnaire/answers.d.ts.map +1 -0
  28. package/dist/tool/questionnaire/answers.js +102 -0
  29. package/dist/tool/questionnaire/answers.js.map +1 -0
  30. package/dist/tool/questionnaire/composer.d.ts +3 -3
  31. package/dist/tool/questionnaire/composer.d.ts.map +1 -1
  32. package/dist/tool/questionnaire/composer.js +902 -37
  33. package/dist/tool/questionnaire/composer.js.map +1 -1
  34. package/dist/tool/questionnaire/presets.d.ts +60 -0
  35. package/dist/tool/questionnaire/presets.d.ts.map +1 -0
  36. package/dist/tool/questionnaire/presets.js +164 -0
  37. package/dist/tool/questionnaire/presets.js.map +1 -0
  38. package/dist/tool/questionnaire/questionnaire.d.ts +10 -0
  39. package/dist/tool/questionnaire/questionnaire.d.ts.map +1 -0
  40. package/dist/tool/questionnaire/questionnaire.js +580 -0
  41. package/dist/tool/questionnaire/questionnaire.js.map +1 -0
  42. package/dist/tool/schema/manifest-migrations.d.ts +5 -0
  43. package/dist/tool/schema/manifest-migrations.d.ts.map +1 -1
  44. package/dist/tool/schema/manifest-migrations.js +45 -0
  45. package/dist/tool/schema/manifest-migrations.js.map +1 -1
  46. package/dist/tool/schema/overlay-loader.d.ts.map +1 -1
  47. package/dist/tool/schema/overlay-loader.js +25 -0
  48. package/dist/tool/schema/overlay-loader.js.map +1 -1
  49. package/dist/tool/schema/project-config.d.ts +14 -2
  50. package/dist/tool/schema/project-config.d.ts.map +1 -1
  51. package/dist/tool/schema/project-config.js +277 -34
  52. package/dist/tool/schema/project-config.js.map +1 -1
  53. package/dist/tool/schema/target-rules.d.ts +78 -0
  54. package/dist/tool/schema/target-rules.d.ts.map +1 -0
  55. package/dist/tool/schema/target-rules.js +367 -0
  56. package/dist/tool/schema/target-rules.js.map +1 -0
  57. package/dist/tool/schema/types.d.ts +123 -12
  58. package/dist/tool/schema/types.d.ts.map +1 -1
  59. package/dist/tool/utils/merge.d.ts.map +1 -1
  60. package/dist/tool/utils/merge.js +9 -0
  61. package/dist/tool/utils/merge.js.map +1 -1
  62. package/dist/tool/utils/parameters.d.ts +76 -0
  63. package/dist/tool/utils/parameters.d.ts.map +1 -0
  64. package/dist/tool/utils/parameters.js +125 -0
  65. package/dist/tool/utils/parameters.js.map +1 -0
  66. package/dist/tool/utils/paths.d.ts +2 -0
  67. package/dist/tool/utils/paths.d.ts.map +1 -0
  68. package/dist/tool/utils/paths.js +31 -0
  69. package/dist/tool/utils/paths.js.map +1 -0
  70. package/docs/creating-overlays.md +151 -2
  71. package/docs/deployment-targets.md +88 -56
  72. package/docs/examples.md +20 -17
  73. package/docs/filesystem-contract.md +5 -0
  74. package/docs/minimal-and-editor.md +65 -5
  75. package/docs/overlay-imports.md +202 -101
  76. package/docs/overlays.md +162 -34
  77. package/docs/quick-reference.md +99 -0
  78. package/docs/specs/003-mkdocs2-overlay/spec.md +114 -0
  79. package/docs/specs/004-doctor-fix/spec.md +70 -0
  80. package/docs/specs/005-cuda-overlay/spec.md +101 -0
  81. package/docs/specs/006-rocm-overlay/spec.md +109 -0
  82. package/docs/specs/007-init-project-file/spec.md +66 -0
  83. package/docs/specs/007-target-aware-generation/spec.md +126 -0
  84. package/docs/specs/008-project-file-canonical/spec.md +83 -0
  85. package/docs/specs/009-project-env/spec.md +147 -0
  86. package/docs/specs/010-compose-env-materialization/spec.md +130 -0
  87. package/docs/specs/011-overlay-parameters/spec.md +235 -0
  88. package/overlays/.shared/README.md +105 -21
  89. package/overlays/.shared/compose/common-healthchecks.md +60 -0
  90. package/overlays/.shared/compose/nvidia-gpu-devcontainer.yml +22 -0
  91. package/overlays/.shared/vscode/recommended-extensions.json +15 -11
  92. package/overlays/alertmanager/setup.sh +4 -19
  93. package/overlays/alertmanager/verify.sh +8 -9
  94. package/overlays/all/README.md +43 -0
  95. package/overlays/all/devcontainer.patch.json +6 -0
  96. package/overlays/all/overlay.yml +14 -0
  97. package/overlays/amp/setup.sh +5 -0
  98. package/overlays/bun/setup.sh +10 -1
  99. package/overlays/bun/verify.sh +6 -1
  100. package/overlays/claude-code/setup.sh +5 -0
  101. package/overlays/cloudflared/setup.sh +9 -12
  102. package/overlays/codex/README.md +9 -6
  103. package/overlays/codex/devcontainer.patch.json +7 -1
  104. package/overlays/codex/setup.sh +5 -0
  105. package/overlays/codex/verify.sh +8 -0
  106. package/overlays/comfyui/.env.example +34 -0
  107. package/overlays/comfyui/README.md +342 -0
  108. package/overlays/comfyui/devcontainer.patch.json +15 -0
  109. package/overlays/comfyui/docker-compose.yml +39 -0
  110. package/overlays/comfyui/overlay.yml +20 -0
  111. package/overlays/comfyui/setup.sh +36 -0
  112. package/overlays/comfyui/verify.sh +103 -0
  113. package/overlays/commitlint/setup.sh +5 -0
  114. package/overlays/cuda/README.md +179 -0
  115. package/overlays/cuda/devcontainer.patch.json +7 -0
  116. package/overlays/cuda/overlay.yml +17 -0
  117. package/overlays/cuda/setup.sh +32 -0
  118. package/overlays/cuda/verify.sh +38 -0
  119. package/overlays/devcontainer-cli/README.md +50 -0
  120. package/overlays/devcontainer-cli/devcontainer.patch.json +13 -0
  121. package/overlays/devcontainer-cli/overlay.yml +16 -0
  122. package/overlays/devcontainer-cli/setup.sh +14 -0
  123. package/overlays/direnv/devcontainer.patch.json +6 -0
  124. package/overlays/direnv/setup.sh +7 -6
  125. package/overlays/dotnet/setup.sh +14 -7
  126. package/overlays/duckdb/devcontainer.patch.json +1 -2
  127. package/overlays/gcloud/devcontainer.patch.json +0 -6
  128. package/overlays/gcloud/setup.sh +51 -0
  129. package/overlays/gemini-cli/setup.sh +5 -0
  130. package/overlays/git-helpers/devcontainer.patch.json +2 -1
  131. package/overlays/go/setup.sh +15 -14
  132. package/overlays/jaeger/overlay.yml +2 -0
  133. package/overlays/just/setup.sh +5 -17
  134. package/overlays/k3d/README.md +201 -0
  135. package/overlays/k3d/devcontainer.patch.json +9 -0
  136. package/overlays/k3d/overlay.yml +19 -0
  137. package/overlays/k3d/setup.sh +34 -0
  138. package/overlays/k3d/verify.sh +38 -0
  139. package/overlays/keycloak/docker-compose.yml +6 -4
  140. package/overlays/keycloak/verify.sh +4 -3
  141. package/overlays/kind/devcontainer.patch.json +1 -2
  142. package/overlays/kind/setup.sh +8 -17
  143. package/overlays/minio/setup.sh +10 -18
  144. package/overlays/mkdocs/overlay.yml +2 -1
  145. package/overlays/mkdocs2/README.md +135 -0
  146. package/overlays/mkdocs2/devcontainer.patch.json +19 -0
  147. package/overlays/mkdocs2/overlay.yml +17 -0
  148. package/overlays/mkdocs2/setup.sh +67 -0
  149. package/overlays/mkdocs2/verify.sh +35 -0
  150. package/overlays/modern-cli-tools/devcontainer.patch.json +7 -1
  151. package/overlays/modern-cli-tools/setup.sh +21 -71
  152. package/overlays/mongodb/devcontainer.patch.json +0 -6
  153. package/overlays/mongodb/setup.sh +59 -0
  154. package/overlays/mysql/verify.sh +4 -3
  155. package/overlays/nats/.env.example +1 -1
  156. package/overlays/nats/README.md +1 -1
  157. package/overlays/nats/docker-compose.yml +1 -1
  158. package/overlays/ngrok/setup.sh +9 -6
  159. package/overlays/nodejs/setup.sh +5 -0
  160. package/overlays/ollama/.env.example +14 -0
  161. package/overlays/ollama/README.md +325 -0
  162. package/overlays/ollama/devcontainer.patch.json +14 -0
  163. package/overlays/ollama/docker-compose.yml +24 -0
  164. package/overlays/ollama/overlay.yml +22 -0
  165. package/overlays/ollama/setup.sh +106 -0
  166. package/overlays/ollama/verify.sh +99 -0
  167. package/overlays/open-webui/.env.example +5 -0
  168. package/overlays/open-webui/README.md +162 -0
  169. package/overlays/open-webui/devcontainer.patch.json +14 -0
  170. package/overlays/open-webui/docker-compose.yml +23 -0
  171. package/overlays/open-webui/overlay.yml +38 -0
  172. package/overlays/openapi-tools/devcontainer.patch.json +1 -2
  173. package/overlays/openapi-tools/setup.sh +9 -8
  174. package/overlays/opencode/setup.sh +5 -0
  175. package/overlays/otel-collector/overlay.yml +2 -0
  176. package/overlays/otel-collector/setup.sh +3 -16
  177. package/overlays/otel-demo-nodejs/verify.sh +8 -9
  178. package/overlays/otel-demo-python/verify.sh +16 -10
  179. package/overlays/pandoc/README.md +22 -15
  180. package/overlays/pandoc/devcontainer.patch.json +6 -2
  181. package/overlays/pandoc/setup.sh +217 -18
  182. package/overlays/pandoc/verify.sh +16 -4
  183. package/overlays/pgvector/.env.example +6 -0
  184. package/overlays/pgvector/README.md +215 -0
  185. package/overlays/pgvector/devcontainer.patch.json +23 -0
  186. package/overlays/pgvector/docker-compose.yml +32 -0
  187. package/overlays/pgvector/overlay.yml +44 -0
  188. package/overlays/playwright/devcontainer.patch.json +3 -1
  189. package/overlays/playwright/setup.sh +37 -0
  190. package/overlays/postgres/.env.example +5 -5
  191. package/overlays/postgres/devcontainer.patch.json +4 -4
  192. package/overlays/postgres/docker-compose.yml +15 -5
  193. package/overlays/postgres/overlay.yml +19 -1
  194. package/overlays/powershell/setup.sh +49 -13
  195. package/overlays/pre-commit/setup.sh +12 -3
  196. package/overlays/prometheus/overlay.yml +2 -0
  197. package/overlays/promtail/verify.sh +16 -10
  198. package/overlays/pulumi/devcontainer.patch.json +1 -1
  199. package/overlays/python/setup.sh +28 -9
  200. package/overlays/python/verify.sh +4 -2
  201. package/overlays/qdrant/.env.example +4 -0
  202. package/overlays/qdrant/README.md +216 -0
  203. package/overlays/qdrant/devcontainer.patch.json +20 -0
  204. package/overlays/qdrant/docker-compose.yml +25 -0
  205. package/overlays/qdrant/overlay.yml +40 -0
  206. package/overlays/redpanda/docker-compose.yml +3 -5
  207. package/overlays/rocm/README.md +227 -0
  208. package/overlays/rocm/devcontainer.patch.json +4 -0
  209. package/overlays/rocm/overlay.yml +17 -0
  210. package/overlays/rocm/setup.sh +45 -0
  211. package/overlays/rocm/verify.sh +47 -0
  212. package/overlays/rust/setup.sh +11 -18
  213. package/overlays/skaffold/README.md +256 -0
  214. package/overlays/skaffold/devcontainer.patch.json +9 -0
  215. package/overlays/skaffold/overlay.yml +20 -0
  216. package/overlays/skaffold/setup.sh +33 -0
  217. package/overlays/skaffold/verify.sh +24 -0
  218. package/overlays/spec-kit/setup.sh +7 -3
  219. package/overlays/sqlite/setup.sh +14 -14
  220. package/overlays/sqlserver/docker-compose.yml +3 -3
  221. package/overlays/sqlserver/verify.sh +22 -5
  222. package/overlays/tempo/verify.sh +16 -10
  223. package/overlays/tilt/devcontainer.patch.json +1 -2
  224. package/overlays/tilt/setup.sh +14 -4
  225. package/overlays/windsurf-cli/setup.sh +27 -4
  226. package/overlays/windsurf-cli/verify.sh +13 -3
  227. package/package.json +4 -2
  228. package/templates/scripts/setup-utils.sh +228 -0
  229. package/tool/schema/config.schema.json +141 -9
  230. package/tool/schema/overlay-manifest.schema.json +38 -0
  231. package/overlays/.shared/compose/common-healthchecks.yml +0 -38
  232. /package/overlays/otel-demo-nodejs/{Dockerfile-otel-demo-nodejs → Dockerfile} +0 -0
  233. /package/overlays/otel-demo-nodejs/{package-otel-demo-nodejs.json → package.json} +0 -0
  234. /package/overlays/otel-demo-nodejs/{server-otel-demo-nodejs.js → server.js} +0 -0
  235. /package/overlays/otel-demo-nodejs/{tracing-otel-demo-nodejs.js → tracing.js} +0 -0
  236. /package/overlays/otel-demo-python/{Dockerfile-otel-demo-python → Dockerfile} +0 -0
  237. /package/overlays/otel-demo-python/{app-otel-demo-python.py → app.py} +0 -0
  238. /package/overlays/otel-demo-python/{requirements-otel-demo-python.txt → requirements.txt} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../../tool/utils/merge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../../tool/utils/merge.ts"],"names":[],"mappings":"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"}
@@ -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,2 @@
1
+ export declare function resolveRepoPath(relativePath: string, anchor: string): string;
2
+ //# sourceMappingURL=paths.d.ts.map
@@ -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"}
@@ -46,10 +46,24 @@ Overlays automatically detect the package manager based on the selected base ima
46
46
  - **Alpine**: Uses `apk` for package installation
47
47
  - **Custom**: Defaults to `apt-get` (may need manual adjustment)
48
48
 
49
- When creating overlays with package installations, use devcontainer features that handle this automatically, or detect the package manager in setup scripts:
49
+ When creating overlays with package installations, prefer the `cross-distro-packages` devcontainer feature for packages available in standard distro repos they run at build time and require no shell scripting:
50
+
51
+ ```json
52
+ {
53
+ "features": {
54
+ "./features/cross-distro-packages": {
55
+ "apt": "direnv ripgrep fd-find",
56
+ "apk": "direnv ripgrep fd"
57
+ }
58
+ }
59
+ }
60
+ ```
61
+
62
+ For packages that require a custom apt repository or are not in standard repos, use a `setup.sh` script instead (see [Setup Scripts](#setup-scripts) below).
63
+
64
+ If you do need to detect the package manager in a setup script:
50
65
 
51
66
  ```bash
52
- # Example: Detect package manager
53
67
  if command -v apk > /dev/null; then
54
68
  apk add --no-cache some-package
55
69
  elif command -v apt-get > /dev/null; then
@@ -252,6 +266,139 @@ volumes:
252
266
 
253
267
  These files are automatically copied to the output directory.
254
268
 
269
+ ## Setup Scripts
270
+
271
+ If your overlay needs shell work at container-create time (e.g., adding a custom apt repo, downloading a binary, or configuring shell hooks), add a `setup.sh` to your overlay directory.
272
+
273
+ ```
274
+ overlays/my-overlay/
275
+ ├── devcontainer.patch.json
276
+ └── setup.sh # postCreateCommand script
277
+ ```
278
+
279
+ The composer copies `setup.sh` to `scripts/setup-my-overlay.sh` and wires it into `postCreateCommand` automatically. All setup scripts for all selected overlays **run in parallel**, so you must use the shared locking utilities for any apt/dpkg operations.
280
+
281
+ ### Using setup-utils.sh
282
+
283
+ A shared utility library is automatically emitted to `scripts/setup-utils.sh` whenever any overlay contributes a setup script. Source it at the top of your `setup.sh`:
284
+
285
+ ```bash
286
+ #!/bin/bash
287
+ set -e
288
+ source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
289
+ ```
290
+
291
+ #### APT locking — `apt_install` / `with_apt_lock` / `acquire_apt_lock`
292
+
293
+ Setup scripts run in parallel. Without coordination, two scripts calling `apt-get update` simultaneously will corrupt the apt database.
294
+
295
+ For the common case of installing packages, use `apt_install` — it acquires the lock, runs `apt-get update`, installs, then releases the lock:
296
+
297
+ ```bash
298
+ apt_install my-package another-package
299
+ ```
300
+
301
+ For operations that need the lock but aren't a plain `apt-get install` (e.g. `dpkg -i`), use `with_apt_lock`:
302
+
303
+ ```bash
304
+ with_apt_lock sudo dpkg -i /tmp/package.deb
305
+ ```
306
+
307
+ For multi-step sequences (add repo, then install), use `acquire_apt_lock` / `release_apt_lock` directly:
308
+
309
+ ```bash
310
+ add_apt_repo ...
311
+ acquire_apt_lock
312
+ sudo apt-get update -qq
313
+ sudo apt-get install -y my-package
314
+ sudo apt-get clean && sudo rm -rf /var/lib/apt/lists/*
315
+ release_apt_lock
316
+ ```
317
+
318
+ The lock is `flock`-based and crash-safe: the kernel releases it automatically if the process exits for any reason.
319
+
320
+ #### Adding a custom apt repo — `add_apt_repo`
321
+
322
+ ```bash
323
+ add_apt_repo \
324
+ "https://example.com/repo.gpg" \
325
+ "/usr/share/keyrings/example.gpg" \
326
+ "deb [signed-by=/usr/share/keyrings/example.gpg] https://repo.example.com stable main" \
327
+ "/etc/apt/sources.list.d/example.list"
328
+ ```
329
+
330
+ This handles the `curl → gpg --dearmor → tee sources.list.d` sequence, including `mkdir -p` for the keyring and sources directories. Call it **before** `acquire_apt_lock` — it only writes key/sources files and does not invoke apt.
331
+
332
+ #### Architecture detection — `detect_arch`
333
+
334
+ ```bash
335
+ detect_arch # returns 1 on unknown arch
336
+ detect_arch amd64 # falls back to amd64 on unknown arch
337
+ # $CS_ARCH is now "amd64" or "arm64"
338
+ ```
339
+
340
+ #### Installing a binary — `install_binary` / `install_binary_from_tar`
341
+
342
+ ```bash
343
+ # Single binary
344
+ install_binary "https://example.com/tool-linux-${CS_ARCH}" "tool"
345
+
346
+ # Binary inside a .tar.gz
347
+ install_binary_from_tar \
348
+ "https://example.com/tool-${VERSION}-linux-${CS_ARCH}.tar.gz" \
349
+ "tool" # name inside archive
350
+ ```
351
+
352
+ ### Full example — custom apt repo
353
+
354
+ ```bash
355
+ #!/bin/bash
356
+ # my-tool setup script
357
+ set -e
358
+
359
+ source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
360
+
361
+ echo "📦 Installing my-tool..."
362
+ add_apt_repo \
363
+ "https://my-tool.example.com/gpg.key" \
364
+ "/usr/share/keyrings/my-tool.gpg" \
365
+ "deb [signed-by=/usr/share/keyrings/my-tool.gpg] https://my-tool.example.com/apt stable main" \
366
+ "/etc/apt/sources.list.d/my-tool.list"
367
+
368
+ apt_install my-tool
369
+
370
+ echo "✅ my-tool installed: $(my-tool --version)"
371
+ ```
372
+
373
+ ### Full example — binary download
374
+
375
+ ```bash
376
+ #!/bin/bash
377
+ # my-cli setup script
378
+ set -e
379
+
380
+ source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
381
+
382
+ MY_VERSION="${MY_VERSION:-1.2.3}"
383
+ detect_arch
384
+ echo "📦 Installing my-cli ${MY_VERSION} for ${CS_ARCH}..."
385
+ install_binary \
386
+ "https://github.com/example/my-cli/releases/download/v${MY_VERSION}/my-cli-linux-${CS_ARCH}" \
387
+ "my-cli"
388
+
389
+ echo "✅ my-cli installed: $(my-cli --version)"
390
+ ```
391
+
392
+ ### Checklist for setup scripts
393
+
394
+ - Source `setup-utils.sh` at the top
395
+ - Use `acquire_apt_lock` / `release_apt_lock` around **all** apt/dpkg calls
396
+ - Use `detect_arch` instead of a hand-rolled `uname -m` case statement
397
+ - Use `install_binary` / `install_binary_from_tar` instead of `curl | tar | mv`
398
+ - Use `add_apt_repo` instead of inline `curl | gpg | tee`
399
+ - Never hardcode architecture (`x86_64`, `amd64`) or checksums that will go stale
400
+ - Verify the installed tool with `command -v` after installation
401
+
255
402
  ## .env.example
256
403
 
257
404
  Define environment variables for your overlay.
@@ -537,6 +684,8 @@ CLI tools without services:
537
684
  Before submitting an overlay:
538
685
 
539
686
  - [ ] devcontainer.patch.json validates against schema
687
+ - [ ] Packages available in standard repos use `cross-distro-packages` feature (not `apt-get install` in setup.sh)
688
+ - [ ] `setup.sh` (if present) sources `setup-utils.sh` and uses `apt_install`/`install_binary`/`detect_arch`
540
689
  - [ ] docker-compose.yml uses version "3.8" and devnet network
541
690
  - [ ] .env.example has sensible defaults and comments
542
691
  - [ ] README.md documents ports, environment variables, usage