Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions .claude/hooks/session-context.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
# SessionStart hook: Inject project context reminder
# Outputs text that Claude will see at session start

set -euo pipefail

INPUT=$(cat)
SESSION_TYPE=$(echo "$INPUT" | jq -r '.matcher_value // "unknown"')

# Only inject on fresh startup, not resume/compact
if [[ "$SESSION_TYPE" == "startup" ]]; then
cat << 'CONTEXT'
moltdown project context:
- VM workflow toolkit for AI agents
- Use 'make lint' before commits
- Shell scripts must pass shellcheck -x
- Key commands: ./agent.sh, ./snapshot_manager.sh, ./clone_manager.sh
CONTEXT
fi

exit 0
31 changes: 31 additions & 0 deletions .claude/hooks/shellcheck-on-write.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
# PostToolUse hook: Run shellcheck on modified .sh files
# Exit 0 = proceed, Exit 2 = block (not used here, just advisory)

set -euo pipefail

# Read input from stdin
INPUT=$(cat)

# Extract file path from tool input
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

# Only check .sh files
if [[ -z "$FILE_PATH" ]] || [[ ! "$FILE_PATH" =~ \.sh$ ]]; then
exit 0
fi

# Check if file exists
if [[ ! -f "$FILE_PATH" ]]; then
exit 0
fi

# Run shellcheck if available
if command -v shellcheck &>/dev/null; then
if ! shellcheck -x "$FILE_PATH" 2>&1; then
# Output goes to Claude as feedback (not blocking)
echo "shellcheck found issues in $FILE_PATH" >&2
fi
fi

exit 0
26 changes: 26 additions & 0 deletions .claude/hooks/validate-bash.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
# PreToolUse hook: Block dangerous bash commands
# Exit 0 = allow, Exit 2 = block with reason

set -euo pipefail

INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

# Patterns to block (destructive VM/disk operations)
DANGEROUS_PATTERNS=(
'virsh.*destroy.*ubuntu2404-agent' # Don't destroy the main golden VM
'virsh.*undefine.*ubuntu2404-agent'
'rm.*\.qcow2' # Don't delete disk images
'rm -rf /var/lib/libvirt'
)

for pattern in "${DANGEROUS_PATTERNS[@]}"; do
if echo "$COMMAND" | grep -qE "$pattern"; then
echo "Blocked: This command could destroy the golden image or disk images." >&2
echo "Use clone_manager.sh for disposable VMs instead." >&2
exit 2
fi
done

exit 0
38 changes: 38 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/shellcheck-on-write.sh",
"timeout": 30
}
]
}
],
"SessionStart": [
{
"matcher": "startup",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-context.sh"
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/validate-bash.sh"
}
]
}
]
}
}
117 changes: 117 additions & 0 deletions .claude/skills/moltdown/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
name: moltdown
description: |
moltdown VM workflow toolkit for AI agents. Use when working with VM creation,
snapshots, clones, bootstrapping, or agent sessions. Triggers on "VM", "snapshot",
"clone", "bootstrap", "golden image", "agent VM", "moltdown", "libvirt".
argument-hint: [command]
allowed-tools: Read, Bash, Grep, Glob
---

# moltdown - Golden Image VM Workflow

<!-- CANONICAL SOURCES:
- CLAUDE.md Quick Reference
- README.md
- RESOURCES.md
-->

## Quick Reference

```bash
# One-command agent VM (start here!)
./agent.sh # Create + connect to agent VM

# Setup (first time only)
./setup_cloud.sh # Default: 16GB RAM, 4 vCPUs
./setup_cloud.sh --memory 8192 --vcpus 4 # Lightweight

# Snapshot workflow
./snapshot_manager.sh list <vm> # List snapshots
./snapshot_manager.sh pre-run <vm> # Before agent work
./snapshot_manager.sh post-run <vm> # Revert to dev-ready
./snapshot_manager.sh golden <vm> # Create golden image

# Clone workflow (parallel agents)
./clone_manager.sh create <vm> --linked # Instant clone
./clone_manager.sh create <vm> --linked --memory 8192 # 8GB clone
./clone_manager.sh list # List all
./clone_manager.sh cleanup <vm> # Delete all

# Inside VM
vm-health-check # Quick health status
vm-health-check --watch # Continuous monitoring
run-claude-limited # Run Claude with 12GB limit
agent-session # Persistent tmux session
```

## Core Concepts

### Golden Image Workflow
1. **os-clean**: Fresh Ubuntu + updates
2. **dev-ready**: Bootstrap complete (tools installed, auth configured)
3. **pre-run**: Before each agent run (timestamped)
4. **post-run**: Revert to dev-ready after work

### Memory Planning
- Claude CLI can leak to 13GB+
- 64GB host: 2-4 clones @ 12-16GB each
- Always use `run-claude-limited` inside VMs

## Script Reference

| Script | Purpose |
|--------|---------|
| `agent.sh` | One-command agent VM creation |
| `setup_cloud.sh` | Full VM setup (cloud images) |
| `snapshot_manager.sh` | Manage libvirt snapshots |
| `clone_manager.sh` | Manage VM clones |
| `sync-ai-auth.sh` | Sync AI CLI auth to VMs |
| `update-golden.sh` | Update golden image |
| `guest/bootstrap_agent_vm.sh` | Run inside VM to configure it |

## Common Workflows

### Start Fresh Agent Session
```bash
./agent.sh
# Inside VM:
agent-session
```

### Run Multiple Agents in Parallel
```bash
./clone_manager.sh create ubuntu2404-agent --linked --memory 8192
./clone_manager.sh create ubuntu2404-agent --linked --memory 8192
./clone_manager.sh start moltdown-clone-*
```

### Update Golden Image
```bash
./update-golden.sh # Full update
./update-golden.sh --quick # CLIs only
./update-golden.sh --auth-only # Re-sync auth
```

## Shell Standards

All scripts follow:
- `set -euo pipefail` strict mode
- `readonly` for constants
- `local` for function variables
- Logging: `log_info()`, `log_warn()`, `log_error()`, `log_phase()`
- All scripts must pass `shellcheck -x`

## Quality Gates

Before committing:
- [ ] `make lint` passes
- [ ] Scripts are executable (`chmod +x`)
- [ ] No hardcoded paths that should be configurable
- [ ] `--help` updated if CLI changed

## Related Files

- [README.md](../../../README.md) - Full documentation
- [RESOURCES.md](../../../RESOURCES.md) - Memory planning
- [CLAUDE.md](../../../CLAUDE.md) - Development guidelines
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ Thumbs.db
*.swp
*.swo

# Claude Code local settings
.claude/
# Claude Code local settings (keep skills and hooks, ignore local settings)
.claude/settings.local.json
.claude/*.bak

# MCP server config (local)
.mcp.json
Expand Down
71 changes: 70 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ systemctl status claude-watchdog # Check watchdog service
make lint # Run shellcheck + yamllint
shellcheck -x *.sh guest/*.sh # Manual shellcheck

# Claude Code Integration
./setup-hooks.sh # Install Claude Code hooks (shellcheck, context)
./setup-hooks.sh --dry-run # Preview hook changes
./setup-hooks.sh --remove # Remove hooks

# GitHub CLI
gh issue create # Create issue
gh issue list # List issues
Expand Down Expand Up @@ -502,6 +507,70 @@ When working with this codebase, ensure:

---

## Claude Code Integration

### Skills

The `/moltdown` skill provides quick reference for VM workflows:

```bash
# In Claude Code, type:
/moltdown # Show quick reference
/moltdown snapshot # Help with snapshot commands
```

Skill location: `.claude/skills/moltdown/SKILL.md`

### Hooks

Configure Claude Code hooks for automatic shell script validation:

```bash
# Install hooks
./setup-hooks.sh

# Preview without changes
./setup-hooks.sh --dry-run

# Remove hooks
./setup-hooks.sh --remove
```

**Installed hooks:**

| Hook | Event | Purpose |
|------|-------|---------|
| `shellcheck-on-write.sh` | PostToolUse[Write\|Edit] | Lint .sh files after modification |
| `session-context.sh` | SessionStart[startup] | Inject project context |
| `validate-bash.sh` | PreToolUse[Bash] | Block dangerous VM commands |

Hook scripts: `.claude/hooks/`
Hook config: `.claude/settings.json`

### Manual Hook Configuration

If you prefer manual setup, add to `.claude/settings.json`:

```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/shellcheck-on-write.sh"
}
]
}
]
}
}
```

---

## Future Improvements / TODOs

- [ ] Support for other distros (Fedora, Debian)
Expand All @@ -512,4 +581,4 @@ When working with this codebase, ensure:

---

_Last updated: 2026-02-02 (ET)_
_Last updated: 2026-02-02 (ET) - Added Claude Code hooks and skills_
Loading