Establishes CLAUDE.md, CHANGELOG.md, and README.md as persistent project memory. Adds documentation update triggers and semantic versioning rules to ensure context is maintained across sessions. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6.3 KiB
6.3 KiB
CLAUDE.md
Project Memory
This project uses three documentation files as persistent memory. You must keep these files up to date when making changes:
| File | Purpose | Update When |
|---|---|---|
CLAUDE.md |
Technical context for Claude Code sessions | Adding new patterns, conventions, or implementation details |
CHANGELOG.md |
Version history following Keep a Changelog format | Every commit (add entry, bump version) |
README.md |
User-facing documentation | Changing user-visible behavior, adding features, or modifying usage |
Versioning Rules
- Use semantic versioning (MAJOR.MINOR.PATCH)
- Increment PATCH for bug fixes and minor updates
- Increment MINOR for new features and enhancements
- Increment MAJOR for breaking changes
- Tag every commit with its version:
git tag -a vX.Y.Z -m "Description"
Project Overview
This repository contains a dual-mode setup script for creating OrbStack-based development sandboxes tailored for Claude Code with Elixir/Erlang, browser automation, and PostgreSQL.
Repository Structure
setup_env.sh - Main script (macOS host mode + Linux VM provisioning mode)
config.env.example - Example credentials file
config.env - User credentials (gitignored, created on first run)
.gitignore - Ignores config.env
README.md - User-facing documentation
CHANGELOG.md - Version history (Keep a Changelog format)
CLAUDE.md - This file (context for Claude Code sessions)
How the Script Works
The script has two modes, detected via uname -s:
- Darwin (macOS): Orchestrator mode. Checks for OrbStack, reads/creates
config.env, creates a VM, copies itself in, runs itself inside the VM with--non-interactive. - Linux (VM): Provisioning mode. Installs all tools, configures PostgreSQL, sets up VNC, installs Claude Code plugins.
This means ./setup_env.sh my-vm on macOS does everything end-to-end.
Key Technical Details
- Target environment: OrbStack Ubuntu VM on macOS Apple Silicon (ARM64)
- Version manager: mise (manages Node.js, Erlang, Elixir)
- Versions: All tools use latest by default. Erlang/Elixir versions can be configured at the top of
setup_env.sh(ERLANG_VERSION,ELIXIR_VERSION) - set to "latest" or pin to specific versions - PostgreSQL auth: Peer for local socket, scram-sha-256 for all TCP connections (localhost and network)
- Browser: Chromium (no Chrome ARM64 Linux builds exist), symlinked to
google-chrome - VNC: TigerVNC + XFCE on display :1 (port 5901), controlled via
vnc-start/vnc-stophelpers in~/bin - Shared credentials:
config.envstores git name/email only; VNC password is prompted each time (never stored)
Working on This Project
Editing setup_env.sh
- The macOS host-mode block is at the top (inside the
if [[ "$(uname -s)" == "Darwin" ]]block) - The Linux VM-mode block is everything after that conditional
- Version numbers are defined as variables at the top (
ERLANG_VERSION,ELIXIR_VERSION) - All installation steps must be idempotent (safe to run multiple times)
- Use
log_info,log_warn,log_errorhelpers for output - New apt packages go in the base dependencies section
- New Claude plugins go in the appropriate array (
ANTHROPIC_PLUGINSorSUPERPOWERS_PLUGINS) - Redirect verbose output to
$LOG_FILE, show only meaningful progress to the user - The
LOG_FILEvariable is only set in VM mode (not available in macOS host mode) - Each optional component is wrapped in
prompt_install "Name" "Description"— this handles both interactive prompts and--yes/--non-interactiveauto-accept - Track dependency flags (
INSTALLED_NODE,INSTALLED_CHROMIUM) to skip dependent components gracefully
Script Conventions
set -euo pipefailis enforced - handle potential failures with|| trueor explicit checks- Use
command_existsto check for already-installed tools - Use
apt-get(notapt) for scripting reliability - Quote all variable expansions
- Use
findfor PostgreSQL config paths (version-agnostic) - The
--non-interactiveflag is for VM mode (implies--yes); macOS mode always uses config.env --yes/-yaccepts all components without prompting but still allows interactive credential entryMISE_GLOBAL_CONFIG_FILEandMISE_CONFIG_DIRare set to prevent OrbStack host-mount config pollution
Security Patterns
- Input validation: Use
validate_vm_name(),validate_vnc_password(),validate_safe_input()for all user inputs - Safe config loading: Use
load_config_safely()which parses key=value pairs without shell execution (neversource) - Credential passing: Base64-encode values before passing to VM via
orb runto prevent shell injection - Download helper: Use
download_verified_binary()for binary downloads (supports optional checksum verification) - Temp files: Always use
mktempwith restrictive permissions (chmod 600/700) - Symlinks: Check with
[ ! -e path ](not[ ! -L path ]) to avoid overwriting existing files - Architecture detection: Use
detect_architecture()for portable binary downloads
Testing
There are no automated tests. To test changes:
- Remove an existing test VM:
orb delete test-sandbox - Run:
./setup_env.sh test-sandbox - Verify provisioning completes
- Run again to verify idempotency:
ssh test-sandbox@orb -- bash /tmp/setup_env.sh --non-interactive(will need env vars) - Test VNC:
ssh test-sandbox@orb -- vnc-start, thenopen vnc://test-sandbox.orb.local:5901 - Clean up:
orb delete test-sandbox
Security Considerations
config.envis chmod 600 and gitignored (stores git name/email only, never VNC password)- PostgreSQL uses scram-sha-256 for all TCP connections (peer auth for local socket)
- The script refuses to run as root inside the VM
- VNC password is required (min 6 chars), validated to block shell metacharacters, never stored
- VNC binds to all interfaces (
-localhost no) to allow connections from the macOS host — this is intentional for the OrbStack use case and documented in the vnc-start script - All user inputs are validated before use to prevent command injection
- External scripts (mise, ollama) are downloaded to temp files and validated before execution
- Host filesystem access is disabled inside the VM for isolation