Skip to main content

Bootstrap Claude Code web environments

Project description

ccweb

Bootstrap Claude Code web environments with one command.

uvx ccweb init

Generates setup.sh, session-start.sh, diagnose.sh, and wires .claude/settings.json for your project. When you start a Claude Code web session, the VM is automatically provisioned with your selected toolchains.

Quick start

# In your project root
uvx ccweb init

# Commit and push
git add scripts/ .claude/settings.json
git commit -m "Add Claude Code web environment setup"
git push

# Start a Claude Code web session — it auto-provisions
# Then verify:
uvx ccweb doctor

Local Docker validation

Before pushing, validate the generated scripts against a clean Ubuntu 24.04 container:

uvx ccweb test                    # runs setup.sh + diagnose.sh in ubuntu:24.04
uvx ccweb test --image ubuntu:22.04
uvx ccweb test --shell            # interactive shell for ad-hoc debugging

Requires a local Docker daemon. The repo is mounted read-only at /workspace, so the test can never modify your working copy.

Options

uvx ccweb init --toolchains auto --extras auto    # Detect from repo files
uvx ccweb init --toolchains node,python           # Just Node + Python
uvx ccweb init --toolchains go --extras postgres  # Go + psql
uvx ccweb init --versions go=1.23.0,zig=0.14.0    # Pin tool versions
uvx ccweb init --env-file .env.example            # Declare required env vars
uvx ccweb init --env-file ""                      # Disable env-file auto-detect
uvx ccweb init --force                            # Overwrite existing files
uvx ccweb init --scripts-dir ci/scripts           # Custom scripts directory
uvx ccweb init --skills ai/skills                 # Custom skills directory
uvx ccweb init --skills ""                        # Disable skills wiring

Toolchains

node, python, go, rust, ruby, java, deno, elixir, zig, dotnet, php — default: all

Extras

uv, pnpm, yarn, bun, browser, postgres, redis, docker — default: all

gh, duckdb, yq, sqlite3, jq, pandoc, shellcheck, and friends are always installed — no flag needed.

Auto-detection

Pass auto to either flag to install only what the repo actually needs. Detection inspects the project root for marker files:

Toolchain Markers
node package.json, package-lock.json, pnpm-lock.yaml, yarn.lock, bun.lock
python pyproject.toml, requirements.txt, setup.py, Pipfile, uv.lock
go go.mod
rust Cargo.toml
ruby Gemfile, *.gemspec
java pom.xml, build.gradle, build.gradle.kts
deno deno.json, deno.jsonc
elixir mix.exs
zig build.zig, build.zig.zon
dotnet *.csproj, *.fsproj, *.sln
php composer.json

Extras are detected from lockfiles, Dockerfile / docker-compose.yml, playwright/puppeteer in package.json, [tool.uv] in pyproject.toml, and postgres/redis images referenced in compose files.

The cloud extra (aws, gcloud, terraform, kubectl, helm) is detected from any of: *.tf / *.tfvars at the root, a terraform/ / infra/ / iac/ / k8s/ / kubernetes/ / manifests/ directory, or a Chart.yaml, helmfile.yaml, kubeconfig, or kustomization.yaml file at the root.

Version pinning

Override any of the baked-in versions with --versions KEY=VALUE (comma-separated for multiple). Unspecified tools use the defaults in DEFAULT_VERSIONS.

Valid keys: go, zig, gh, duckdb, yq, dotnet_channel, terraform, kubectl.

uvx ccweb init --versions go=1.23.0
uvx ccweb init --versions go=1.23.0,gh=2.74.1,dotnet_channel=LTS

Pins are also auto-detected from common version files at the project root — no flag required:

File Source of pin
.tool-versions asdf/mise entries for golang/go, zig, terraform, kubectl
.go-version Go (takes precedence over .tool-versions)
.terraform-version Terraform (takes precedence over .tool-versions)
.nvmrc, .python-version Read but ignored — node and python are pre-installed and not pinnable

Explicit --versions entries always win over auto-detected pins, per key.

Environment variables

If the repo contains .env.example or .env.template (or you point --env-file somewhere else), session-start.sh reads the variable names from it and warns when any are unset in the session. diagnose.sh gets a matching section that shows each declared variable as set or missing.

The file is treated as a schema — ccweb never reads, copies, or transmits the values. Store actual secrets in the claude.ai/code Environment Variables UI at the project level.

# .env.example (checked into the repo; values are placeholders)
DATABASE_URL=
OPENAI_API_KEY=
STRIPE_SECRET=

Pass --env-file "" to disable auto-detection.

Skills

By default, ccweb looks for Claude Code skills in .claude/skills/ in your repo (each subdirectory holds a SKILL.md). On session start, every skill found there is symlinked into ~/.claude/skills/<name> so Claude Code discovers them at the user level across every session on the VM. Pass --skills ai/skills for a custom path, or --skills "" to disable.

<repo>/<DIR>/my-skill/SKILL.md
<repo>/<DIR>/my-skill/reference.md

Auto-formatting on Edit/Write

ccweb init also generates scripts/post-tool-use.sh and wires it as a PostToolUse hook in .claude/settings.json (matcher: Edit|Write|MultiEdit). After every file edit, the hook reads the file path from Claude's hook payload and runs the matching formatter:

Formatter Extensions
ruff format + ruff check --fix .py
gofmt .go
rustfmt .rs
zig fmt .zig
mix format .ex, .exs
shfmt .sh, .bash
clang-format .c, .h, .cc, .cpp, .cxx, .hpp, .hh, .hxx, .m, .mm
rubocop -A .rb
google-java-format .java
php-cs-fixer .php
terraform fmt .tf, .tfvars
prettier (falls back to deno fmt) .js, .jsx, .ts, .tsx, .mjs, .cjs, .json, .jsonc, .md, .mdx, .css, .scss, .html, .yaml, .yml

Each formatter is guarded by command -v, and the hook always exits 0 so a missing or failing formatter never blocks the agent.

How it works

  1. setup.sh runs once when a new VM is created. Installs system packages, toolchains, and persists environment variables to /etc/environment.

  2. session-start.sh runs on every session start (new + resumed). Sources env vars, detects project lockfiles, and installs dependencies. Auto-runs setup.sh if the VM hasn't been provisioned yet.

  3. diagnose.sh checks what's installed, what's missing, and what's misconfigured.

  4. post-tool-use.sh runs after every Edit/Write/MultiEdit and formats the changed file.

  5. .claude/settings.json wires both hooks so they run automatically.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ccweb-0.5.0.tar.gz (45.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ccweb-0.5.0-py3-none-any.whl (29.1 kB view details)

Uploaded Python 3

File details

Details for the file ccweb-0.5.0.tar.gz.

File metadata

  • Download URL: ccweb-0.5.0.tar.gz
  • Upload date:
  • Size: 45.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ccweb-0.5.0.tar.gz
Algorithm Hash digest
SHA256 e5e16a99137aa800678f6eaadfeb6b168873c65bd8dafaa5c153e628f964237e
MD5 9859aeaf61a17cdeff69af0f2a369982
BLAKE2b-256 6caffcaec89c2d6017e59a9e452553400b87520835c0c4b33601bd39bcbd4527

See more details on using hashes here.

Provenance

The following attestation bundles were made for ccweb-0.5.0.tar.gz:

Publisher: publish.yml on nclandrei/ccweb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ccweb-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: ccweb-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 29.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ccweb-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 311c3135faede6c9ec095b3f65f2f6df8ee0698899e0d71da0b3a7f375992300
MD5 20a216c9d933d9ef3922f4f0ffaf65b2
BLAKE2b-256 a86e7ff96c9d64937d31dc2216ad5282008a210929f19c1ec0e21de99d677973

See more details on using hashes here.

Provenance

The following attestation bundles were made for ccweb-0.5.0-py3-none-any.whl:

Publisher: publish.yml on nclandrei/ccweb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page