Skip to content

shaug/atelier

Repository files navigation

Atelier

Atelier is an installable CLI for workspace-based, agent-assisted development inside local Git repos. It turns each unit of work into its own workspace with a dedicated git worktree, explicit intent, and a predictable launch path for agents and humans. Atelier is Git-first by design; provider integrations are optional and best-effort.

Atelier can manage multiple projects on one machine; each project is identified by its local enlistment path and stored under the Atelier data directory.

The goal is to simulate web-based agent development on a local machine: you can hand off and resume workspaces easily, take the wheel at any time, and coordinate multiple agents across parallel tasks without losing context.

Atelier is:

  • a per-repo tool, not a global project manager
  • a workspace-first workflow, not a branch-switching helper
  • a convention with sharp edges, not a flexible framework

Provider integrations are intentionally minimal: GitHub gets the best support, and other providers are best-effort when project.provider metadata is set.

Inspiration

Atelier is inspired by the ideas explored in Shipping at Inference Speed, which argues that many traditional Git workflows introduce unnecessary cognitive overhead when working with fast, capable coding agents.

In particular, the essay highlights the value of:

  • minimizing mental context switches
  • evolving codebases linearly when coordination cost is low
  • treating LLMs as collaborators, not batch tools

Atelier adopts these ideas where they help, while still supporting branch- and review-based workflows when coordination and safety matter. It's an adaptation of the essay's philosophy, not a clone.

Read more in docs/inspiration.md.

Why “atelier”?

Atelier (pronounced ah-tuh-lee-AY) is the French word for a workshop.

The name reflects how this tool is intended to be used: as a place where work is shaped iteratively, with humans and tools collaborating closely.

Atelier is not a factory pipeline or a fully automated system. It favors explicit intent, interruption, and hands-on control over invisible automation.

Agents are collaborators, not background jobs—and the human is always allowed to step back in and take the reins.

The name is meant to signal craft and collaboration, not art, magic, or opacity.

Read more in docs/atelier-name.md.

Core Ideas

  • One workspace = one unit of work = one branch
  • Intent is captured before code (epic planning)
  • Workspaces are isolated worktrees with their own git checkout
  • Projects are identified by their local enlistment path (each repo you initialize is a separate project), not Git origin
  • The filesystem is the source of truth

Behavior and Design Notes

See docs/behavior.md for the compact behavioral overview. Command-specific details live in module docstrings under src/atelier/commands.

Requirements

  • Git (for worktrees and branch operations)
  • bd >= 0.56.1 on your PATH (Atelier's local planning store)

The reusable Beads client published under atelier.lib.beads supports a bounded v1 bd surface. See docs/beads-client-contract.md for the supported command inventory, version/capability policy, and downstream adoption rules. See docs/beads-adoption-guide.md for the current decision boundary between direct low-level Beads usage, in-memory test usage, and work that should wait for the future at-njpt4 store layer.

Repo-Local Commit Hooks

This repository uses a repo-local hook path (.githooks/) for fast local quality gates:

  • pre-commit: staged Python lint/format checks plus pyright via scripts/lint-gate.sh --staged-python.
  • pre-push: full repository test gate via just test.
  • commit-msg: Conventional Commit validation via commitlint.config.cjs.

Canonical lint gate for local/CI workflows:

bash scripts/lint-gate.sh

CI Required Checks

GitHub Actions CI publishes these check names:

  • ci / lint: lint gate (bash scripts/lint-gate.sh).
  • ci / test: Python + shell test suite.
  • ci / lint-test: temporary compatibility check that mirrors lint + test.

Branch protection should require ci / lint and ci / test. Keep ci / lint-test only during migration from the legacy single check, then remove it once rulesets are updated.

Troubleshooting:

  • ci / lint failed: lint or type checks failed.
  • ci / test failed: tests failed.
  • ci / lint-test failed while either check above failed: expected legacy mirror behavior.

Bootstrap or repair hooks for an existing clone:

bash .githooks/worktree-bootstrap.sh

The bootstrap step is idempotent and does the following:

  • sets core.hooksPath=.githooks in the repository's common Git config
  • ensures tracked hook scripts (pre-commit, pre-push, commit-msg, post-checkout) are executable
  • keeps linked worktrees aligned through .githooks/post-checkout

If your environment does not expose commitlint, the commit hook falls back to npx. If you use a custom binary path, set ATELIER_COMMITLINT_BIN.

If your environment does not expose uv or ruff, set ATELIER_RUFF_BIN to an executable Ruff binary path. If your environment does not expose uv or pyright, set ATELIER_PYRIGHT_BIN to a pyright executable path. If your environment does not expose just, set ATELIER_JUST_BIN to a compatible executable path.

Agent Setup

Atelier launches the agent CLI configured in agent.default. Install and authenticate the agent CLI you want to use and set agent.default accordingly. Atelier validates that the configured agent is available on your PATH (using --version when possible) and exits early if no agent CLI is available.

Supported agents

Supported agent features

  • Launch agents from the workspace directory
  • Best-effort session resumption when the agent CLI supports it
  • Opening prompt containing the workspace ID (Codex only)

Role-scoped launch options

Agent options support both legacy global settings and role-scoped overrides:

  • agent.options.<agent> applies to both atelier plan and atelier work.
  • agent.launch_options.planner.<agent> applies only to planner sessions.
  • agent.launch_options.worker.<agent> applies only to worker sessions.

Precedence is deterministic: worker/planner scoped options override legacy global options for the same flag.

Example:

{
  "agent": {
    "default": "claude",
    "options": {
      "claude": ["--model", "sonnet"]
    },
    "launch_options": {
      "planner": {
        "claude": ["--model", "opus"]
      },
      "worker": {
        "claude": ["--print", "--output-format=stream-json", "--verbose"]
      }
    }
  }
}

Claude worker sessions default to print-mode with --output-format=stream-json --verbose unless explicitly overridden, while planner Claude sessions remain interactive by default.

Workspace identity environment variables

Atelier sets these environment variables when launching editors, shells, and agents:

  • ATELIER_WORKSPACE: workspace branch name
  • ATELIER_PROJECT: project enlistment path (repo root)
  • ATELIER_WORKSPACE_DIR: workspace root directory

Example shell prompt (bash/zsh):

PS1='${ATELIER_WORKSPACE:+[${ATELIER_WORKSPACE}] }\\w$ '

Example editor title (VS Code settings):

{
  "terminal.integrated.title": "${env:ATELIER_WORKSPACE} - ${env:ATELIER_PROJECT}"
}

What the CLI Manages

Atelier is intentionally small. The CLI:

  • registers a local enlistment as a project in the Atelier data directory
  • creates per-epic worktrees under the data directory
  • maintains minimal config.sys.json/config.user.json state for projects
  • stores optional project-wide policy for agents
  • bootstraps policy/context files (AGENTS.md) and installs workspace skills
  • tracks changeset branch mappings for each workspace
  • launches your editor and shells in a predictable way

Project Layout

<atelier-data-dir>/
└─ projects/
   └─ <project-key>/
      ├─ config.sys.json
      ├─ config.user.json
      ├─ templates/
      │  ├─ AGENTS.md
      └─ worktrees/
         ├─ .meta/
         │  └─ <epic-id>.json
         └─ <epic-id>/
            └─ <git worktree checkout>

Notes:

  • <project-key> is the enlistment basename plus a short SHA-256 of the full enlistment path.
  • Worktrees are keyed by epic id; mappings live in worktrees/.meta/.

Quick Start

Create a brand-new local project:

atelier new [path]

If path is omitted, the current directory must be empty.

Initialize a project:

atelier init

Run this inside an existing Git repo; Atelier stores state in the data directory and does not write files into the repo.

You can run atelier init in multiple repos; each enlistment becomes its own project entry.

Start a worker session (one changeset per session):

atelier work
atelier work at-epic123
atelier work --mode auto
atelier work --select first-eligible
atelier work --run-mode once
atelier work --run-mode watch
atelier work --run-mode watch --no-restart-on-update
atelier work --run-mode default --restart-on-update
atelier work --run-mode watch --watch-interval 30
atelier work --reconcile

atelier work will:

  • claim or select the epic to work on
  • pick the next ready changeset
  • ensure the worktree and changeset branch mapping exist
  • repeat or watch depending on --run-mode (--watch-interval for watch cadence)

Supported ATELIER_* -> CLI-default translations for atelier work:

| CLI default                | Env var                  | Built-in default | Accepted env values            |
| -------------------------- | ------------------------ | ---------------- | ------------------------------ |
| --mode                     | ATELIER_MODE             | prompt           | prompt, auto                   |
| --run-mode                 | ATELIER_RUN_MODE         | default          | once, default, watch           |
| --watch-interval-seconds   | ATELIER_WATCH_INTERVAL   | 60               | positive integer               |
| --yes                      | ATELIER_WORK_YES         | false            | 1/true/yes/on, 0/false/no/off |

Example:

ATELIER_WORK_YES=1 atelier work

Unsupported keys for this CLI-default translation layer: ATELIER_PLAN_TRACE, ATELIER_WORK_TRACE, ATELIER_LOG_LEVEL, ATELIER_NO_COLOR. Use global CLI flags instead: --log-level and --color/--no-color.

Plan epics and changesets:

atelier plan

Open a workspace worktree in your editor:

atelier edit <workspace-branch>
atelier edit <workspace-branch> --workspace

Open a shell in a workspace worktree (or run a command there):

atelier open <workspace-branch>
atelier open <workspace-branch> -- python -m http.server
atelier open <workspace-branch> --workspace

Show project status:

atelier status
atelier status --format=json

Detect prefix-migration drift (read-only):

atelier doctor
atelier doctor --format=json

Apply explicit prefix normalization repairs (operator-invoked):

atelier doctor --fix
atelier doctor --fix --force
atelier doctor --fix --format=json

Operator triage + rollback runbook and convergence harness:

List workspaces:

atelier list

Clean up stale hooks/claims and orphaned worktrees:

atelier gc

Notes

  • The epic record is the execution contract for each workspace.
  • AGENTS.md is a managed prologue used to configure agents.
  • atelier policy shows the project-wide policy shared by planning and work agents.
  • The publish skill records integration guidance derived from project config and applies it to changeset branches.
  • Configuration lives in config.sys.json/config.user.json under the Atelier data directory.
  • Worktrees live under the data directory and are keyed by epic id.

CLI Reference

atelier --help and atelier --version

Use atelier --help to view all commands and options. Use atelier --version to print the installed version and exit.

atelier new [path]

Create a new local Git repo, register it as an Atelier project, and start planning.

Usage:

atelier new [path]

Options:

  • --branch-prefix: Prefix for workspace branches (e.g., scott/).
  • --branch-pr-mode: Pull request mode for workspace branches (none, draft, ready).
  • --branch-history: History policy (manual, squash, merge, rebase).
  • --agent: Agent name.
  • --editor-edit: Editor command for blocking edits (e.g., subl -w).
  • --editor-work: Editor command for opening the repo (e.g., code).

Example:

atelier new ~/code/greenfield

atelier init

Register the current Git repo as an Atelier project. This command writes configuration into the Atelier data directory and never modifies the repo.

Usage:

atelier init

Options:

  • --branch-prefix: Prefix for workspace branches (e.g., scott/).
  • --branch-pr-mode: Pull request mode for workspace branches (none, draft, ready).
  • --branch-history: History policy (manual, squash, merge, rebase).
  • --agent: Agent name.
  • --editor-edit: Editor command for blocking edits (e.g., subl -w).
  • --editor-work: Editor command for opening the repo (e.g., code).

Example:

atelier init --branch-prefix scott/ --branch-pr-mode none --branch-history rebase

atelier config [workspace-branch]

Inspect or update configuration. Without arguments, prints the merged project config. With a workspace branch, prints that workspace config.

Usage:

atelier config
atelier config scott/feat/new-search

Options:

  • --installed: Operate on installed defaults instead of the current project.
  • --prompt: Prompt for user-editable settings (branch/agent/editor roles).
  • --reset: Reset user-editable settings to installed defaults.
  • --edit: Edit user config in editor.edit.

Examples:

atelier config --prompt
atelier config --reset
atelier config --installed --prompt

atelier policy

Show or edit project-wide agent policy.

Usage:

atelier policy
atelier policy --edit

Options:

  • --role: Select policy role (planner, worker, or both).
  • --edit: Edit policy in editor.edit; without this flag policy is printed.

atelier edit <workspace-branch>

Open the workspace repo in the configured work editor.

Usage:

atelier edit feat/new-search

Options:

  • --raw: Treat the argument as the full branch name (no prefix lookup).
  • --workspace: Open the worktree root instead of the default repo path.
  • --set-title: Emit a terminal title escape (best-effort).

atelier work [epic-id]

Start a worker session for the next ready changeset. If no epic id is provided, Atelier selects one based on --mode (prompt or auto).

Usage:

atelier work
atelier work at-epic123
atelier work --mode auto

Options:

  • --mode: Worker selection mode (prompt or auto).
  • --select: Startup selector policy (first-eligible or oldest-feedback). Defaults to worker.select in config, then oldest-feedback.
  • --run-mode: Worker loop mode (once, default, or watch).
  • --restart-on-update: Self-reexec at idle boundaries after runtime changes. Defaults to on in watch mode and off in other run modes.
  • --no-restart-on-update: Disable idle-boundary self-reexec even in watch mode.
  • --yes: Accept defaults for interactive choices (ATELIER_WORK_YES).
  • --reconcile: Run a fail-closed reconcile sweep before startup selection. This auto-finalizes orphaned in_progress changesets only when PR lifecycle is terminal (merged/closed) and no live worker hook owns the epic.
  • Watch polling defaults to ATELIER_WATCH_INTERVAL (seconds) in watch mode.

Auto-restart controls:

  • atelier work --run-mode watch enables restart-on-update by default.
  • atelier work --run-mode watch --no-restart-on-update keeps watch polling but disables self-reexec.
  • atelier work --run-mode default --restart-on-update opts long-lived non-watch workers into the same idle-boundary restart behavior.
  • Restart checks happen only between worker sessions, never during an active changeset execution.
  • If restart attempts fail or retrigger too quickly, Atelier logs bounded cooldown diagnostics and keeps running the current process instead of looping indefinitely.

Debugging restart behavior:

  • Confirm the effective mode/flags in the launch command you used.
  • Watch for Runtime update detected, auto-restart is cooling down, and restart failed log lines in the worker output.
  • Use --no-restart-on-update to keep a long-lived worker stable while you investigate repeated runtime changes or install failures.

atelier plan

Start a planner session for epics. Planner sessions run in a dedicated worktree and use the agent runtime for interactive planning.

By default, Atelier resumes an existing planner session when possible:

  • If planner_session.id is saved on the planner agent bead and still exists for this planner workspace, Atelier resumes that exact session id.
  • If no saved pointer exists, Atelier resumes the most recent matching planner session.
  • If a saved pointer is stale or missing, Atelier starts a fresh session and clears the stale pointer.

Use --new-session to bypass resume lookup and always start fresh.

Planner sessions automatically sync their planner worktree to the configured default branch at startup, then continue periodic freshness checks while the session is active. Sync metadata is recorded on the planner agent bead under planner_sync.* fields (last synced sha/time, last attempt/result).

Usage:

atelier plan

Options:

  • --epic-id: Plan against an existing epic id.
  • --new-session: Always start a fresh planner session (skip resume lookup).
  • In an active planner session, run python3 skills/planner-startup-check/scripts/refresh_overview.py to refresh the same read-only startup overview on demand. This command now hardens the previously uncovered mode where projected planner scripts were launched by an ambient interpreter that did not match the repo dependency runtime.

atelier open [workspace-branch] [--] [command ...]

Open a shell in a workspace worktree, or run a command there. If <workspace-branch> is omitted, you will be prompted to choose one. Use --shell to override the interactive shell selection. Use --workspace to run in the worktree root instead of the default repo path.

Options:

  • --shell: Shell path or name for interactive mode.
  • --workspace: Run in the worktree root instead of the default repo path.
  • --set-title: Emit a terminal title escape.
  • --raw: Treat the workspace name as the full branch name (no prefix lookup).

atelier open runs a command when arguments are provided; otherwise it opens an interactive shell.

atelier status

Show project status for epics, hooks, and changesets.

Usage:

atelier status
atelier status --format=json

Options:

  • --format=json: Emit deterministic JSON output.

atelier doctor

Detect prefix-migration branch/worktree drift and report multi-check health. Read-only by default. Use atelier doctor --fix for explicit normalization/repair.

Usage:

atelier doctor
atelier doctor --format=json
atelier doctor --fix
atelier doctor --fix --force

Options:

  • --format=json: Emit deterministic JSON output.
  • --fix: Apply drift repairs instead of read-only detection.
  • --force: Override active-hook deferrals when used with --fix.

atelier list

List workspaces for the current project (names only).

Usage:

atelier list

atelier gc

Clean up stale hooks and orphaned worktrees.

Usage:

atelier gc

Options:

  • --stale-hours: Treat heartbeats older than this many hours as stale.
  • --stale-if-missing-heartbeat: Treat missing heartbeats as stale.
  • --dry-run: Show planned actions without applying them.
  • --yes: Apply without confirmation.

Development

Atelier is a Python 3.11+ CLI packaged with uv.

Global install (recommended for day-to-day use):

uv tool install --editable .
uv tool update-shell

Then open a new shell so the tool bin directory is on your PATH.

Common tasks (requires just):

just install
just install-dev
just test
just test-integration
just lint
just format

Install just with brew install just or cargo install just.

just test-integration runs publish-skill evals and requires the codex CLI to be installed and authenticated.

Local quality gates intentionally pin uv to Python 3.11 to match the current CI baseline. Ambient Python 3.14 interpreters and pre-existing 3.14 .venv directories are not part of the supported publish/test matrix yet.

bash scripts/supported-python.sh venv
uv pip install -e .[dev]

Run the CLI locally:

uv run atelier --help

Run tests:

bash scripts/supported-python.sh run python -m atelier.skill_frontmatter_validation
bash scripts/supported-python.sh run pytest
bash tests/shell/run.sh

atelier.skill_frontmatter_validation enforces required AgentSkills frontmatter rules (name, description, format/length, and name-directory match).

Planner and worker unit-service suites should use the in-memory Beads backend from atelier.testing.beads by default. Keep real-bd coverage explicit in shell tests and command-integration tests that verify subprocess wiring or publish flows. See docs/beads-adoption-guide.md for contributor guidance about where direct atelier.lib.beads usage is still in bounds, and see docs/in-memory-beads-testing-guide.md for the backend-selection rule, an example harness, and current migrated coverage.

License

MIT. See LICENSE.

About

A local, filesystem-based workflow for parallel, agent-assisted software development.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages