Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
180d540
Move existing code to legacy/, organize workspace for rewrite
asmacdo Mar 28, 2026
d7ebdcd
Add Containerfile.base: core image without extras
asmacdo Mar 28, 2026
4f35612
Containerfile.base: minimal debian image with native Claude Code
asmacdo Mar 28, 2026
74cca27
Add Containerfile.extras, apt.sh, python.sh, and test scaffolding
asmacdo Mar 28, 2026
02c0562
Add Python CLI skeleton: yo build, yo run
asmacdo Mar 28, 2026
62ef35d
Add config tests: merge semantics, path resolution, layer precedence
asmacdo Mar 28, 2026
0131e74
Add CLAUDE.md, move future ideas to notes/ideas/
asmacdo Mar 28, 2026
357bfc1
Swap pyyaml for ruamel.yaml, add builder, wire up CLI
asmacdo Mar 28, 2026
d41f26a
Add builder tests: parsing, resolution, build context assembly
asmacdo Mar 28, 2026
8a78a01
One format, one contract: env vars for container-extras
asmacdo Mar 28, 2026
577e739
Move issues, PRs, notes, security-reports to .local-notes/ (gitignored)
asmacdo Mar 28, 2026
f1b2b03
Reorganize: legacy under design/, local notes gitignored, TODOs split
asmacdo Mar 28, 2026
1810a95
Add pre-commit (ruff, yamllint, shellcheck), CI, CONTRIBUTING.md
asmacdo Mar 28, 2026
97c696d
CI: add stubs for codespell, shellcheck, unit/integration test jobs
asmacdo Mar 28, 2026
fb0d627
CI: run on redesign-python branch (temporary)
asmacdo Mar 28, 2026
592b457
Add hardcoded launcher: yo run launches Claude in container
asmacdo Mar 28, 2026
557df3f
Pass-through args to claude: yo run --resume, yo run "prompt"
asmacdo Mar 29, 2026
bff257b
Wire volumes: config + CLI -v flag, with launcher tests
asmacdo Mar 29, 2026
3e013e1
Add --entrypoint override to launcher
asmacdo Mar 29, 2026
65e7381
Named images with FROM support, project-derived tags
asmacdo Mar 29, 2026
ce5b8ba
Move REDESIGN_HACKIN.md to SPEC.md at root for rewrite
asmacdo Mar 29, 2026
53fef84
Rewrite SPEC.md to reflect current implementation
asmacdo Mar 29, 2026
b11b56c
Auto-build base image if missing, error on unknown base
asmacdo Mar 29, 2026
315c5da
Add worktree detection and handling (ask/bind/skip/error)
asmacdo Mar 29, 2026
754b26d
Add shorthand volume expansion
asmacdo Mar 29, 2026
5464398
Add --podman-arg escape hatch for raw podman flags
asmacdo Mar 29, 2026
8d33db8
Add --nvidia flag and --container-arg escape hatch
asmacdo Mar 29, 2026
6140874
Add !replace YAML tag for per-key merge override
asmacdo Mar 29, 2026
6296972
Add xfail tests for recursive named-list merge
asmacdo Mar 29, 2026
1634bbc
Config-driven env var passthrough
asmacdo Mar 29, 2026
9b0d7bd
Add --no-config flag to skip all user/project config files
asmacdo Mar 29, 2026
8987ff7
Add yo init: generate config from default template
asmacdo Mar 29, 2026
1f118fc
Expand default config with docs for all config features
asmacdo Mar 29, 2026
2bd34e2
Rename container-extras to image-extras
asmacdo Mar 29, 2026
36eceba
Separate integration tests: marker + directory
asmacdo Mar 29, 2026
a31a20b
Add YOLO_VERIFY mode to extras scripts + integration tests
asmacdo Mar 30, 2026
8ff8a2b
Update features_to_test.md: mark done, add integration TODOs
asmacdo Mar 30, 2026
1ef25d6
Improve build output: summary before build, PS4 tracing
asmacdo Mar 30, 2026
aaf67b7
Split defaults from template: yo init copies commented template
asmacdo Mar 30, 2026
6977e84
Remove accidentally committed .yolo/ and docs/tutorial.md
asmacdo Mar 30, 2026
b574109
Replace yo verify with yo build --verify
asmacdo Mar 30, 2026
0500612
Auto-build image on yo run if it doesn't exist
asmacdo Mar 30, 2026
86a21db
Add context injection via --append-system-prompt
asmacdo Mar 30, 2026
21c0a4f
Add clipboard bridge: yo clip + /tmp/yolo-clip mount
asmacdo Mar 30, 2026
73f94fe
Add git workflow guidelines to CLAUDE.md
asmacdo Mar 30, 2026
828544f
Add yo demo command and move demo script into repo
asmacdo Mar 30, 2026
8e0bd6a
Add yo demo command and move demo script into repo
asmacdo Mar 30, 2026
385dad6
Add datalad, jj, and playwright image extras
asmacdo Mar 30, 2026
8100fbd
Add yo images command to list configured images
asmacdo Mar 30, 2026
c438951
Revamp demo: conversational flow, source mount, context fixes
asmacdo Mar 30, 2026
c28a2f3
Wire CI to actual test suite
asmacdo Mar 30, 2026
227635a
Add pip image extra for baking packages into images
asmacdo Mar 30, 2026
4cec9ac
Add README with install, quick start, security, and extras
asmacdo Mar 30, 2026
49e78b1
Add git worktree section to README
asmacdo Mar 30, 2026
1890120
Skip legacy dir in codespell CI check
asmacdo Mar 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 35 additions & 110 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,129 +1,54 @@
---
name: CI

on:
push:
branches: [ main, enhs ]
# TODO: remove redesign-python after merge
branches: [main, redesign-python]
pull_request:
branches: [ main ]
branches: [main]

jobs:
shellcheck:
name: ShellCheck
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Run shellcheck on setup-yolo.sh
run: shellcheck setup-yolo.sh
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
- run: uv venv && uv pip install -e ".[dev]"
- uses: pre-commit/action@v3.0.1

- name: Run shellcheck on bin/yolo
run: shellcheck bin/yolo

unit-tests:
name: Unit Tests (BATS)
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
codespell:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- uses: actions/checkout@v4
- uses: codespell-project/actions-codespell@v2
with:
submodules: true

- name: Install bats
run: |
if command -v brew &>/dev/null; then
brew install bats-core
else
sudo apt-get update && sudo apt-get install -y bats
fi

- name: Run tests
run: bats tests/
skip: ./design/legacy

test-setup:
name: Test Setup Script
shellcheck:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install podman
run: |
sudo apt-get update
sudo apt-get install -y podman

- name: Test setup-yolo.sh (build only)
run: |
# Run setup with no input to skip installation prompt
# This will build the image and exit when asking about installation
echo "n" | ./setup-yolo.sh || true

# Verify the image was built
podman image exists con-bomination-claude-code

- name: Verify yolo script syntax
run: |
bash -n bin/yolo
echo "✓ Yolo script has valid syntax"

- name: Test yolo script help (dry run)
run: |
# Create a mock podman command that just echoes what would run
mkdir -p ~/test-bin
cat > ~/test-bin/podman << 'EOF'
#!/bin/bash
echo "PODMAN COMMAND:"
echo "podman $@"
exit 0
EOF
chmod +x ~/test-bin/podman

# Add to PATH and test
export PATH="$HOME/test-bin:$PATH"

# Verify our mock is used
which podman

# Test various yolo invocations
echo "Testing: yolo"
./bin/yolo || true

echo "Testing: yolo -- \"help with code\""
./bin/yolo -- "help with code" || true

echo "Testing: yolo -v /data:/data --"
./bin/yolo -v /data:/data -- || true
- uses: actions/checkout@v4
- uses: ludeeus/action-shellcheck@master
with:
scandir: image-extras

integration-test:
name: Integration Test
unit-tests:
runs-on: ubuntu-latest
needs: [shellcheck, test-setup]
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install podman
run: |
sudo apt-get update
sudo apt-get install -y podman

- name: Run full setup (automated)
run: |
# Answer 'no' to installation prompt
echo "n" | ./setup-yolo.sh
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
- run: uv venv && uv pip install -e ".[dev]"
- run: .venv/bin/pytest -m "not integration" -v

- name: Verify container image
run: |
podman images
podman image exists con-bomination-claude-code
echo "✓ Container image successfully built"

- name: Test container can start
run: |
# Test that the container starts and can run a basic command
# We'll use --help which doesn't require authentication
podman run --rm con-bomination-claude-code claude --help
echo "✓ Container runs successfully"
integration-tests:
runs-on: ubuntu-latest
needs: [lint, unit-tests]
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
- run: uv venv && uv pip install -e ".[dev]"
- name: Build base image
run: podman build -f images/Containerfile.base -t yolo-base images/
- name: Run integration tests
run: .venv/bin/pytest -m integration -v
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.venv/
__pycache__/
*.egg-info/
.local-notes/
.yolo/
!src/yolo/demo/.yolo/
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[submodule "tests/test_helper/bats-support"]
path = tests/test_helper/bats-support
path = legacy/tests/test_helper/bats-support
url = https://github.com/bats-core/bats-support.git
[submodule "tests/test_helper/bats-assert"]
path = tests/test_helper/bats-assert
path = legacy/tests/test_helper/bats-assert
url = https://github.com/bats-core/bats-assert.git
Comment on lines 1 to 6
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Submodule paths point to legacy/tests/test_helper/..., but this repo's legacy code lives under design/legacy/... (and there is no top-level legacy/ dir). As written, git submodule update --init will fail. Update the path = entries to the actual directory you want the submodules checked out into (likely design/legacy/tests/test_helper/...) or move the legacy directory to match these paths.

Copilot uses AI. Check for mistakes.
21 changes: 21 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.6
hooks:
- id: ruff
- id: ruff-format

- repo: https://github.com/adrienverge/yamllint
rev: v1.37.1
hooks:
- id: yamllint
args: [--strict]
exclude: ^design/legacy/

- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.10.0.1
hooks:
- id: shellcheck
files: \.sh$
exclude: ^design/legacy/
6 changes: 6 additions & 0 deletions .yamllint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
extends: default
rules:
truthy:
# YAML spec treats bare 'on' as true, which breaks GitHub Actions 'on:' key
check-keys: false
45 changes: 45 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
**Before writing files, check if CLAUDE.md, design docs, or tests need updating to reflect your changes.**

## Git workflow

- Make clean, atomic commits — one feature or fix per commit.
- Run `pre-commit run --files <staged files>` before attempting `git commit` to catch formatting issues early.

## Python

- Always import at the top of the file unless there's a good reason not to.

## Project

yolo runs Claude Code safely in a rootless Podman container with full autonomy.

Currently being rewritten from bash to Python. Legacy code is in `design/legacy/`.

## Key files

- `SPEC.md` — current specification (source of truth for behavior)
- `design/HACK_DECISIONS.md` — locked design decisions, do not revisit
- `design/LEGACY_SPEC.md` — spec of the legacy bash implementation
- `tests/features_to_test.md` — checklist of things that need tests

## Development

```
uv venv .venv && source .venv/bin/activate
uv pip install -e ".[dev]"
pytest
```

Entry point is `yo` (temporary, becomes `yolo` at cutover).

## Architecture

- `src/yolo/config.py` — YAML config loading from 5 locations (defaults + 4 user)
- `src/yolo/builder.py` — resolves extras, assembles build context, invokes podman
- `src/yolo/cli.py` — click CLI (yo build, yo run, yo clip, yo demo)
- `src/yolo/launcher.py` — assembles podman run command
- `src/yolo/defaults/config.yaml` — default image-extras shipped with package
- `images/Containerfile.base` — minimal debian base image
- `images/Containerfile.extras` — layers image-extras on top
- `image-extras/` — composable install scripts (apt.sh, python.sh, etc.)
- `.local-notes/` — gitignored local working notes (issues, PRs, etc.)
54 changes: 54 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Contributing

## Setup

```
git clone https://github.com/con/yolo
cd yolo
uv venv .venv && source .venv/bin/activate
uv pip install -e ".[dev]"
pre-commit install
```

## Running tests

```
pytest
```

## Pre-commit hooks

Hooks run automatically on commit:
- **ruff** — Python lint and format
- **yamllint** — YAML validation
- **shellcheck** — shell script lint

Run manually against all files:

```
pre-commit run --all-files
```

## Writing image-extras scripts

Scripts live in `image-extras/`. Each script is a self-contained
bash installer. Parameters are passed as env vars prefixed with
`YOLO_{SCRIPTNAME}_{KEY}`:

```bash
#!/bin/bash
# Env: YOLO_APT_PACKAGES (required)
set -eu
[ -z "${YOLO_APT_PACKAGES:-}" ] && { echo "apt.sh: YOLO_APT_PACKAGES required"; exit 1; }
sudo apt-get install -y $YOLO_APT_PACKAGES
```

Config references scripts by name:

```yaml
image-extras:
- name: apt
packages: [zsh, fzf]
```

See `design/HACK_DECISIONS.md` for the full contract.
Loading
Loading