Autonomous development loop for multiple agentic CLIs - your tireless Aussie dev mate!
npm install jonno> G'day! Jonno here - your tireless Aussie dev mate!
Jonno is an autonomous development loop that works with Claude Code CLI, OpenCode CLI and others to iteratively complete tasks defined in a structured specification format.
Before using Jonno, ensure you have the following installed:
| Requirement | Version | Notes |
| ------------------- | --------- | ------------------------------------------------------ |
| Node.js | >= 18.0.0 | Required |
| bash | Any | Ships with macOS/Linux |
| jq | Any | JSON processor - brew install jq or apt install jq |
| Claude Code CLI | Latest | npm install -g @anthropic-ai/claude-code |
| OpenCode CLI | Latest | Alternative to Claude Code (optional) |
| GitHub Copilot CLI | Latest | npm install -g @github/copilot (optional) |
| fswatch | Any | Optional - for efficient file watching |
Platform Support: Linux and macOS only. Windows is not currently supported.
- Multi-Feature Projects: Organize your project into multiple independent features, each with its own PRD, tasks, and progress tracking
- Autonomous Task Execution: Reads tasks from feature-specific features.json and executes them one by one
- Multi-Agent Support: Works with Claude Code CLI, OpenCode CLI, and GitHub Copilot CLI
- Interactive Permission Handling: Prompts for approval on sensitive operations
- Progress Tracking: Maintains a log of completed iterations per feature
- Model Escalation: Automatically uses stronger models for architectural phases or after failures
- Project-Local State Storage: Logs and state stored in .logs/jonno/ for portability
- Configurable Verification: Optionally run a verification script after each iteration
``bash`
npm install -g jonno
Or use with npx:
`bash`
npx jonno init
1. Initialize a new project:
`bash`
cd your-project
npx jonno init
This creates a main feature by default with the following structure:
``
your-project/
├── .jonnorc # Configuration
├── AGENTS.md # Agent guidelines (shared)
└── specs/
├── TECH_STACK.md # Tech stack (shared)
└── features/
└── main/ # Default feature
├── PRD.md # Product requirements
├── features.json # Task definitions
└── PROGRESS.md # Progress log
2. Configure your feature (choose one approach):
Option A: Interactive builder (recommended)
`bash`
npx jonno define main --mode update
The AI will ask you questions and update the spec files automatically.
Option B: Manual editing
- Edit .jonnorc to set your preferencesspecs/features/main/PRD.md
- Edit with your product requirementsspecs/features/main/features.json
- Edit with your task breakdownAGENTS.md
- Edit with project-specific guidelines
3. Run the loop:
`bash`
npx jonno loop
If you have only one feature, it runs automatically. With multiple features, you'll see an interactive menu to select one:
`
Multiple features found. Select one:
1) auth 3 pending
2) dashboard COMPLETE
3) main 5 pending
Enter number [1-3]:
`
Or specify directly on the command line:
`bash`
npx jonno loop main
4. Monitor progress (in a separate terminal):
`bash`
npx jonno watch
| Command | Description |
| --------------------------------- | ---------------------------------------------- |
| jonno init [--force] | Initialize Jonno in current project |jonno define [feature] [--mode]
| | Interactive feature builder (create or update) |jonno loop [feature] [iters]
| | Run the development loop for a feature |jonno feature new
| | Create a new feature (from template) |jonno feature list
| | List all features with status |jonno feature remove
| | Remove a feature (requires --force) |jonno lima [subcommand]
| | Lima VM management (macOS only) |jonno watch
| | Start file watcher in separate terminal |jonno logs [file]
| | Format JSON log files for readability |jonno status [feature]
| | Show current loop status |jonno clean [--force]
| | Remove state directory for this project |jonno help
| | Show help message |
The define command launches an interactive session where the AI agent asks you questions about your feature and automatically generates all the spec files.
When run without arguments, it shows an interactive menu to select an existing feature or create a new one:
`bash
npx jonno define
You can also specify a feature directly:
`bash
Create a new feature with a specific name
npx jonno define my-featureUpdate an existing feature
npx jonno define auth --mode update
`The agent will ask about:
- Feature name and problem statement
- Primary goals and target users
- Core capabilities and success criteria
- Technical constraints and out-of-scope items
Then it generates
PRD.md, features.json, jonnorc.json, and PROGRESS.md for you.$3
`bash
Create a new feature from template (manual editing required)
npx jonno feature new authOr use the interactive builder (recommended)
npx jonno define authList all features and their progress
npx jonno feature listRun loop for a specific feature
npx jonno loop authRun 50 iterations for a feature
npx jonno loop auth 50Remove a feature (with confirmation)
npx jonno feature remove auth --force
`Configuration
Create a
.jonnorc file in your project root (generated by jonno init):`json
{
"agent": "claude",
"specs": {
"agents": "AGENTS.md",
"techStack": "specs/TECH_STACK.md",
"featuresDir": "specs/features"
},
"models": {
"claude": {
"default": "claude-sonnet-4-5-20250929",
"strong": "claude-opus-4-5-20251101"
},
"opencode": {
"default": "anthropic/claude-sonnet-4-5-20250929",
"strong": "anthropic/claude-opus-4-5-20251101"
},
"copilot": {
"default": "claude-sonnet-4.5",
"strong": "claude-opus-4.5",
"coAuthor": null
}
},
"maxIterations": 100,
"verify": {
"enabled": false,
"script": "scripts/verify.sh",
"runOn": "failure"
}
}
`$3
| Option | Description |
| ------------------- | ------------------------------------------------------ |
|
agent | CLI to use: "claude", "opencode", or "copilot" |
| specs.agents | Path to agent guidelines file (shared across features) |
| specs.techStack | Path to tech stack file (shared across features) |
| specs.featuresDir | Directory containing feature subdirectories |
| models.claude.* | Model names for Claude Code CLI |
| models.opencode.* | Model names for OpenCode CLI (provider/model format) |
| models.copilot.* | Model names for GitHub Copilot CLI |
| maxIterations | Maximum iterations before stopping |
| verify.enabled | Whether to run verification script |
| verify.script | Path to verification script |
| verify.runOn | When to run: "always", "failure", or "never" |Environment Variables
| Variable | Description |
| ----------------- | ------------------------------------------------- |
|
AGENT_CLI | Override CLI selection (claude, opencode, or copilot) |
| JONNO_STATE_DIR | Override state directory (default: .logs/jonno) |
| JONNO_DEBUG | Set to 1 for debug output |
| VERBOSE | Set to 1 for verbose agent output (Claude only) |
| STREAM | Set to 1 for JSON streaming output |
| FORMAT | Set to 1 for formatted real-time output |Project Structure
Jonno organizes your project with multi-feature support. Each feature is self-contained with its own requirements, tasks, and progress tracking.
`
your-project/
├── .jonnorc # Configuration
├── AGENTS.md # Agent guidelines (shared)
└── specs/
├── TECH_STACK.md # Tech stack (shared)
└── features/
├── main/ # Default feature
│ ├── PRD.md
│ ├── features.json
│ └── PROGRESS.md
├── auth/ # Another feature
│ ├── PRD.md
│ ├── features.json
│ └── PROGRESS.md
└── dashboard/ # Yet another feature
├── PRD.md
├── features.json
└── PROGRESS.md
`$3
-
AGENTS.md - Guidelines and conventions for the AI agent (shared across all features)
- specs/TECH_STACK.md - Technical stack and constraints (shared across all features)$3
Each feature directory contains:
-
PRD.md - Product requirements document for this feature
- features.json - Task definitions for this feature
- PROGRESS.md - Auto-generated log of completed iterations
- jonnorc.json - Feature-specific configuration (optional)$3
Each feature can have its own
jonnorc.json file with feature-specific settings:`json
{
"strongModelPhases": ["phase-0", "phase-1", "phase-2", "phase-5"],
"maxIterations": 100
}
`| Option | Description |
| ------------------- | ---------------------------------------------------------- |
|
strongModelPhases | Phases that should use the stronger model for this feature |
| maxIterations | Maximum iterations for this feature |The
strongModelPhases setting controls which phases use the stronger model (e.g., Opus) instead of the default model (e.g., Sonnet). This is useful for complex architectural phases that benefit from more capable reasoning.Default phases using the stronger model:
["phase-0", "phase-1", "phase-2", "phase-5"]$3
Defines the tasks to be completed:
`json
{
"phases": [
{
"id": "phase-0",
"name": "Project Setup",
"sections": [
{
"id": "section-0-1",
"name": "Environment",
"tasks": [
{
"id": "task-0-1-1",
"description": "Initialize project structure",
"passes": false
}
]
}
]
}
]
}
`State Directory
Jonno stores logs and state in a project-local
.logs/jonno/ directory, organized by feature. This makes projects fully portable and Lima/VM-friendly.`
your-project/
├── .logs/ # Auto-added to .gitignore
│ └── jonno/
│ ├── logs/
│ │ ├── main/ # Logs for 'main' feature
│ │ │ ├── combined.log
│ │ │ └── iteration_001.log
│ │ └── auth/ # Logs for 'auth' feature
│ │ ├── combined.log
│ │ └── iteration_001.log
│ └── state/
│ ├── main/ # State for 'main' feature
│ │ ├── status.txt
│ │ └── last_features_hash
│ ├── auth/ # State for 'auth' feature
│ │ ├── status.txt
│ │ └── last_features_hash
│ └── jonno.pid # Process PID file
└── ...
`The
jonno init command automatically adds .logs to your .gitignore file.Verification Script
If you want to run verification after each iteration:
1. Create
scripts/verify.sh:
`bash
#!/bin/bash
npm run lint && npm run typecheck && npm run build
`2. Configure in
.jonnorc:
`json
{
"verify": {
"enabled": true,
"script": "scripts/verify.sh",
"runOn": "always"
}
}
`Options for
runOn:-
"always" - Run at the start of each iteration
- "failure" - Run only after a failed iteration
- "never" - Never run (same as enabled: false)Lima VM Isolation (macOS)
When running autonomous AI agents, there's an inherent risk: the agent executes arbitrary code and shell commands on your machine. A malicious prompt injection, compromised dependency, or unexpected agent behavior could potentially:
- Delete or modify files outside your project
- Access sensitive credentials or environment variables
- Install unwanted software or malware
- Exfiltrate data from your system
Lima VM isolation mitigates these risks by running the agent inside a lightweight Linux virtual machine. The agent can only access your project directory (mounted read-write), while the rest of your system remains protected.
$3
| Command | Description |
| --------------------- | ---------------------------------------- |
|
jonno lima | Interactive menu to select an option |
| jonno lima setup | Full VM setup with agent authentication |
| jonno lima auth | Re-authenticate agent CLI in existing VM |
| jonno lima shell | Open interactive shell inside the VM |
| jonno lima teardown | Remove the VM completely |$3
`bash
Set up Lima VM (installs Lima via Homebrew if needed)
npx jonno lima setupRun your development loop (automatically uses VM)
npx jonno loopWhen done, remove the VM
npx jonno lima teardown
`$3
1. VM Creation: Creates a Lima VM using the default Ubuntu template
2. Project Mount: Mounts your project directory with write access
3. Agent Installation: Installs Node.js and your chosen agent CLI (Claude Code, OpenCode, or GitHub Copilot) inside the VM
4. Authentication: Captures authentication URLs from the VM and opens them on your Mac
5. Transparent Execution: Once configured,
jonno loop automatically runs the agent inside the VM$3
After running
jonno lima setup, your .jonnorc is updated with "lima": true. This tells Jonno to prefix all agent commands with limactl shell , transparently executing them inside the VM.To disable Lima and run agents directly on your host:
`json
{
"lima": false
}
`$3
- macOS only (Lima uses Apple's Virtualization framework)
- Homebrew (for installing Lima if not present)
- Sufficient disk space for the VM (~5GB)
Tips
- Start small: Begin with a few well-defined tasks to test your setup
- One feature at a time: Focus on completing one feature before starting another
- Use
feature list: Run jonno feature list to see progress across all features
- Watch the logs: Use jonno watch` in a separate terminal to see real-time progressMIT
Contributions welcome! Please open an issue or PR on GitHub.
---
_No worries, I've got this!_ 🦘