molecule-ai-workspace-templ.../runbooks/local-dev-setup.md
Molecule AI Plugin-Dev 335474b71b docs: add known-issues.md and runbooks/local-dev-setup.md
Recovered from prior work. Previously pushed commit 03c6929
was lost during reset-to-origin/main divergence resolution.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 08:36:22 +00:00

5.7 KiB

Runbook: Local Development Setup — claude-code Workspace Template

Use this runbook to set up a local development environment for the claude-code workspace template. It covers cloning, dependency installation, running the adapter outside Docker, overriding config for dev, building the container, and diagnosing common problems.


Prerequisites

Requirement Version Notes
Python 3.11+ 3.12 recommended
pip 23+
Docker 24+
Docker Compose v2 (standalone or compose plugin)
Git 2.40+
gh CLI 2.40+ Required for agent autonomy features (git, gh operations)
Molecule platform access Token with workspace:dev scope

Step 1 — Clone the Repository

git clone https://github.com/Molecule-AI/molecule-ai-workspace-template-claude-code.git
cd molecule-ai-workspace-template-claude-code

Always branch off main for local development:

git checkout -b feat/your-feature-name

Step 2 — Install Dependencies

pip install -r requirements.txt

If you encounter dependency conflicts with an existing virtual environment, create an isolated one:

python -m venv .venv
source .venv/bin/activate        # Linux/macOS
# .\.venv\Scripts\Activate.ps1  # Windows PowerShell
pip install -r requirements.txt

Verify the adapter is importable:

python -c "from adapter import MoleculeClaudeCodeAdapter; print('OK')"

Step 3 — Configure Environment Variables

The adapter requires CLAUDE_CODE_OAUTH_TOKEN to authenticate with the LLM. There is no API-key fallback — this variable must be set.

# Required — OAuth token for the LLM provider
export CLAUDE_CODE_OAUTH_TOKEN="your-oauth-token-here"

# Platform URL (required for agent task polling)
export MOLECULE_PLATFORM_URL="https://platform.molecule.ai"

# Workspace instance ID (assigned by the platform)
export MOLECULE_WORKSPACE_ID="ws-dev-local"

# Optional — override adapter log level
export LOG_LEVEL=DEBUG

# Optional — HEARTBEAT interval in seconds (prevents platform timeout on long tasks)
export HEARTBEAT_INTERVAL_SECONDS=30

Security note: Never commit .env.local to version control. Create a .env.local file and ensure it is listed in .gitignore.


Step 4 — Dev Overrides in config.yaml

The config.yaml shipped in the repo is production-oriented. For local dev, the recommended approach is to pass environment-variable overrides. Alternatively, create config.dev.yaml that the adapter merges on top of config.yaml:

# config.dev.yaml — local development overrides
runtime_config:
  model: sonnet
  timeout: 300           # shorter timeout for faster dev cycles

Apply dev overrides when running locally:

python adapter.py --config config.yaml --config-override config.dev.yaml

If the adapter does not support --config-override, set MOLECULE_CONFIG_OVERLAY to the path of the dev config file.


Step 5 — Run the Adapter Locally

Start the adapter in foreground mode:

python adapter.py

Expected startup output:

[molecule.adapter] INFO  — resolved config template_schema_version=1
[molecule.adapter] INFO  — runtime: claude-code, model: sonnet
[molecule.adapter] INFO  — OAuth token: present
[molecule.adapter] INFO  — workspace ready, polling https://platform.molecule.ai/api/v1/tasks

Press Ctrl+C to stop. For background operation:

nohup python adapter.py > adapter.log 2>&1 &
echo $! > adapter.pid

Stop with:

kill $(cat adapter.pid)

Step 6 — Test the Docker Build

Build the dev image:

docker build \
  --build-arg BUILDKIT_INLINE_CACHE=1 \
  -t molecule-claude-code-workspace:dev \
  .

Run a smoke test (adapter starts and reaches idle state):

docker run --rm \
  --env CLAUDE_CODE_OAUTH_TOKEN \
  --env MOLECULE_PLATFORM_URL \
  --env MOLECULE_WORKSPACE_ID \
  molecule-claude-code-workspace:dev \
  python -c "
from adapter import MoleculeClaudeCodeAdapter
a = MoleculeClaudeCodeAdapter()
a.load_config()
print('smoke test PASSED')
"

Full Docker Compose stack:

docker compose up --build

Logs:

docker compose logs -f workspace

Teardown:

docker compose down -v

Common Issues Table

Symptom Likely Cause Resolution
401 Unauthorized — Bearer token invalid CLAUDE_CODE_OAUTH_TOKEN unset or expired Set a valid token: export CLAUDE_CODE_OAUTH_TOKEN=...
anthropic.AuthenticationError Wrong token or token lacks required scopes Verify token has model:read and agent:invoke scopes
Adapter starts but never receives tasks Wrong MOLECULE_PLATFORM_URL or token expired Check URL; refresh token
Platform shows "silent" after ~60s No HEARTBEAT configured; platform timed out the workspace Set HEARTBEAT_INTERVAL_SECONDS=30; upgrade adapter
docker build fails with Step N/12: RUN pip install... Network / pip index issue Proxy through corporate firewall or mirror: pip install --index-url https://pypi.org/simple/ -r requirements.txt
docker run exits immediately with code 0 CLAUDE_CODE_OAUTH_TOKEN not set Pass -e CLAUDE_CODE_OAUTH_TOKEN or --env-file .env.local
ValidationError: template schema version '1' not supported Platform minimum schema version increased Update template_schema_version in config.yaml to match platform minimum

IDE Setup (VS Code)

// .vscode/settings.json — create in workspace root
{
  "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
  "python.analysis.typeCheckingMode": "basic",
  "files.insertFinalNewline": true,
  "[python]": {
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "charliermarsh.ruff"
  }
}