Skip to content

dentarg/ai

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

89 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ai image

Create $HOME/ai/settings with .claude.tmpl.json:

{
  "bypassPermissionsModeAccepted": true,
  "hasCompletedOnboarding": true,
  "primaryApiKey": "op://vault-name/long-id/password",
}

or .claude.json or .claude.<profile>.json (and optionally .credentials.<profile>.json with oauth tokens)

Add AGENTS.md to $HOME/ai/settings if you want. It will populate CLAUDE.md for Claude Code and GEMINI.md for Gemini CLI.

# start podman and share the current working directory
bin/ai
bin/ai --1p # if you want to use claude.tmpl.json with op:// reference

# start services (and run "bundle install" if Gemfile.lock exist)
s

# launch claude
cool_claude

# launch claude with a specific config
cool_claude <profile>

# launch gemini
g

# launch openai codex
oc

Prerequisites

Your Anthropic API key in 1Password.

brew install podman
# memory is in MiB, disk in GiB
podman machine init --disk-size 300 --memory 16384 --now

./build_image

# rebuild all layers and pull latest base image
./build_image --force

OAuth Login

First-time setup to get OAuth credentials:

# inside the container, or via podman run
refresh-tokens --login
refresh-tokens --login <profile>

This generates an OAuth authorization URL. Open it in your browser, sign in, and paste the code back into the terminal. Credentials are saved to ~/.claude/.credentials.json (or .credentials.<profile>.json).

Token Refresh Service

OAuth tokens expire periodically. A systemd service (refresh-tokens.service) runs in every container, keeping ~/.claude/.credentials*.json files fresh automatically.

# check service status
systemctl status refresh-tokens

# view logs
journalctl -u refresh-tokens

# follow logs
journalctl -u refresh-tokens -f

# one-shot refresh (e.g. before launching a session)
refresh-tokens --once

The service can also run as a standalone container to refresh /settings credentials:

podman run -d --name token-refresh \
  --env CREDENTIALS_DIR=/settings \
  --volume ${HOME}/ai/settings:/settings \
  ai:latest /usr/local/bin/refresh-tokens --daemon

Environment variables:

Variable Default Description
CREDENTIALS_DIR ~/.claude Directory containing .credentials*.json files
CHECK_INTERVAL 300 Seconds between checks
REFRESH_BEFORE 3600 Seconds before expiry to trigger refresh

Tricks

zsh things:

# pod       # list all running containers
# pod <id>  # launch bash shell in selected container
# pod last  # launch bash shell in the youngest container
function pod() {
    [ $# -lt 1 ] && podman ps && return 0

    [ "$1" = "last" ] && podman exec -it $(podman ps | tail -1 | cut -d ' ' -f 1) ${2:-bash} && return

    local container
    container=$1
    podman exec -it $container ${2:-bash}
}

mitmproxy

Start it capturing everything:

./mitmdump --mode regular --listen-port 8080 --ssl-insecure --set flow_detail=3 -w claude.flow

mitmproxy generates its CA at ~/.mitmproxy/mitmproxy-ca-cert.pem on first run.

export NODE_EXTRA_CA_CERTS=~/.mitmproxy/mitmproxy-ca-cert.pem
export HTTPS_PROXY=http://127.0.0.1:8080

Start the agent

claude

Output the (partially) binary dump as text (--mode picking another port is important if proxy already running)

./mitmdump --mode regular@8082 --set flow_detail=3 -r claude.flow --set export_format=curl

Commands

tcpdump

podman run --rm -it --cap-add=NET_RAW --cap-add=NET_ADMIN --net=container:<container> nicolaka/netshoot tcpdump -i eth0

podman

# to see current settings
podman machine inspect

# when we can't build because we're out of space
podman system prune--all

# to combat this error related to "Linux Kernel Keyring quota"
# Error: preparing container ... for attach: crun: join keyctl `...`: Disk quota exceeded: OCI runtime error
podman machine ssh sudo sysctl -w kernel.keys.maxkeys=20000
podman machine ssh sudo sysctl -w kernel.keys.maxbytes=200000

Stuff

  • Claude Code
  • GitHub Copilot
  • Google Gemini
  • Node.js
  • Bun TypeScript
  • Ruby
  • Crystal
  • Python
  • Rust
  • Go
  • SSH (ssh-keygen, ...)
  • PostgreSQL
  • LavinMQ
  • amqpcat

About

Easily start the agent in a container

Resources

Stars

Watchers

Forks

Contributors