Skip to content

feat(ide): generate devcontainer + workspace + launch configs (spec 17) - #98

Merged
gustavobertoi merged 1 commit into
mainfrom
feat/ide-integration
Jul 1, 2026
Merged

feat(ide): generate devcontainer + workspace + launch configs (spec 17)#98
gustavobertoi merged 1 commit into
mainfrom
feat/ide-integration

Conversation

@gustavobertoi

Copy link
Copy Markdown
Contributor

What

Adds devstack ide, the spec-17 editor/IDE generation sink. It rides the existing deterministic pipeline (typed struct → stable encoding/json → atomic writeIfChanged) and the two-file config + name index to author, byte-deterministically, the artifacts that point editors at devstack's already-generated compose stacks. New package internal/ide; the ide stub is removed from internal/cli/stubs.go.

Artifacts emitted

  • <repo>/.devcontainer/devcontainer.json — the dockerComposeFile + service + workspaceFolder attach form (not image/build), referencing the generated project compose (../.devstack/docker-compose.yaml), forwardPorts from declared host ports, runServices scoped to the repo, overrideCommand:false + shutdownAction:"none" so the IDE never hijacks the entrypoint or tears down the shared stack, plus an opt-in postCreateCommand reconcile. Because the referenced compose carries name: devstack-<name> + the external devstack_shared network, the IDE lands in the same tool-owned project — no forked network/containers.
  • <workspace-root>/<name>.code-workspace — VS Code multi-root file listing each repo in declared order + the generated .devstack/ tree, with yaml.schemas mappings and the Dev Containers extension recommendation.
  • <repo>/.vscode/launch.json + settings.json — schema-map + debugger-attach stubs (full per-language attach configs need flock-guarded port allocation, out of this pure-authorship sink's scope).

CLI contract

ide [--devcontainer|--vscode|--all] (default --all); --check reports drift without writing (CI); --json emits a written-paths manifest. Mirrors the generate command. Pure file authorship: no Docker, no ledger, no flock.

Why

Spec 17 — meet developers in their editor by emitting, from the same resolved config, artifacts that attach to the exact stacks devstack runs. Exports generate.ProjectStackName so the name index stays the single source of truth for the compose project name (a rename re-flows into every artifact).

How tested

internal/ide table-driven tests: golden devcontainer.json + .code-workspace + launch/settings.json, byte-determinism across independent builds, idempotent re-write (second run changes nothing), the --devcontainer/--vscode/--all target-flag paths, devcontainer wiring (project name/compose/network/forwardPorts), service-rename reflow, and a no-secret-leak assertion (no secret:///containerEnv/remoteEnv in any artifact). Full gate green: CGO_ENABLED=0 go build ./..., CGO_ENABLED=1 go test ./internal/..., go vet ./..., gofmt -l clean, and make determinism. .gitignore gains a scoped negation so the .vscode/.devcontainer golden fixtures stay tracked.

🤖 Generated with Claude Code

Add `devstack ide`, the spec-17 editor/IDE generation sink. It rides the
existing deterministic pipeline (typed struct -> stable encoding/json ->
atomic writeIfChanged) and the two-file config + name index to author,
byte-deterministically, the artifacts that point editors at devstack's
already-generated compose stacks:

- <repo>/.devcontainer/devcontainer.json in the dockerComposeFile+service+
  workspaceFolder ATTACH form, referencing the generated project compose
  (../.devstack/docker-compose.yaml), forwardPorts from declared host ports,
  runServices scoped to the repo, overrideCommand:false + shutdownAction:none
  so the IDE never hijacks the entrypoint or tears down the shared stack, and
  an opt-in postCreateCommand reconcile. The referenced compose carries
  `name: devstack-<name>` + the external devstack_shared network, so the IDE
  lands in the SAME tool-owned project (no forked network/containers).
- <workspace-root>/<name>.code-workspace multi-root file listing each repo in
  declared order + the generated .devstack/ tree, with yaml.schemas mappings
  and the Dev Containers extension recommendation.
- <repo>/.vscode/launch.json + settings.json stubs (schema-map authoring aid;
  debug-attach configs are a follow-up gated on flock port allocation).

Selection via --devcontainer / --vscode / --all (default all); --check reports
drift without writing; --json emits a written-paths manifest. Pure file
authorship: no Docker, no ledger, no flock. Exports generate.ProjectStackName
so the name index is the single source of truth for the compose project name.

Removes the ide stub from stubs.go. Tests: golden devcontainer.json +
.code-workspace + launch/settings, byte-determinism across builds, idempotent
re-write (nothing changes second run), target-flag paths, devcontainer wiring,
service-rename reflow, and a no-secret-leak assertion. `make determinism`
stays green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gustavobertoi
gustavobertoi force-pushed the feat/ide-integration branch from 447ba3e to e16b255 Compare July 1, 2026 12:47
@gustavobertoi
gustavobertoi merged commit ea1e675 into main Jul 1, 2026
4 checks passed
@gustavobertoi
gustavobertoi deleted the feat/ide-integration branch July 1, 2026 13:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant