Skip to content

[Init] sanddune init CLI — Docker + blank template #21

@pyadav

Description

@pyadav

Parent

#1

What to build

First slice of the sanddune init CLI. Scaffolds the config directory (.sanddune/) for Docker + Claude Code + the blank template. Refuses to run if .sanddune/ already exists (so no customizations are overwritten).

Out of scope for this slice: Podman variant, backlog managers (GitHub Issues, Beads), and the four advanced templates (simple-loop, sequential-reviewer, parallel-planner, parallel-planner-with-review) — those land in slice #19.

This slice covers the toolchain decisions that need maintainer judgment: interactive prompt UX, default Dockerfile contents, error messaging, and main.mts vs main.ts selection.

Acceptance criteria

  • sanddune init (run via bunx sanddune init or installed bin) prompts interactively for: agent (Claude Code), template (blank); image name defaults to sanddune:<repo-dir-name>
  • Flags --image-name, --agent, --model, --template skip the corresponding prompts (scriptable for CI/onboarding)
  • Refuses to run if .sanddune/ already exists; exits with an actionable error
  • Scaffolds .sanddune/:
    • Dockerfile — Node 22, git, curl, jq, GitHub CLI, Claude Code CLI, non-root agent user
    • prompt.md — convention scaffold; sanddune does not read this unless promptFile is passed
    • .env.example — placeholder for ANTHROPIC_API_KEY
    • .gitignore — ignores .env, logs/
    • main.mts if package.json lacks \"type\": \"module\", main.ts if it does
  • Template argument substitution runs on the Dockerfile and scaffold .md files (replaces {{KEY}} placeholders with values derived from user choices)
  • Builds the Docker image after scaffolding (one-shot bootstrap)
  • Default Dockerfile guidance: Claude refuses to run as root, so a non-root user is required; git, gh, and the Claude Code CLI must remain on PATH
  • Unit tests against a temp directory: scaffolds expected file tree; refuses on existing .sanddune/; flag-driven non-interactive path
  • Integration test: real sanddune init in a temp repo, then run bun run packages/cli/src/index.ts init and verify the resulting .sanddune/main.mts actually invokes run() against a fake agent
  • bun test and bun run typecheck pass

Blocked by

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestready-for-agentFully specified, ready for an AFK agent

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions