@spacek33z/autoauto 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +197 -0
- package/package.json +51 -0
- package/src/App.tsx +224 -0
- package/src/cli.ts +772 -0
- package/src/components/AgentPanel.tsx +254 -0
- package/src/components/Chat.test.tsx +71 -0
- package/src/components/Chat.tsx +308 -0
- package/src/components/CycleField.tsx +23 -0
- package/src/components/ModelPicker.tsx +97 -0
- package/src/components/PostUpdatePrompt.tsx +46 -0
- package/src/components/ResultsTable.tsx +172 -0
- package/src/components/RunCompletePrompt.tsx +90 -0
- package/src/components/RunSettingsOverlay.tsx +49 -0
- package/src/components/RunsTable.tsx +219 -0
- package/src/components/StatsHeader.tsx +100 -0
- package/src/daemon.ts +264 -0
- package/src/index.tsx +8 -0
- package/src/lib/agent/agent-provider.test.ts +133 -0
- package/src/lib/agent/claude-provider.ts +277 -0
- package/src/lib/agent/codex-provider.ts +413 -0
- package/src/lib/agent/default-providers.ts +10 -0
- package/src/lib/agent/index.ts +32 -0
- package/src/lib/agent/mock-provider.ts +61 -0
- package/src/lib/agent/opencode-provider.ts +424 -0
- package/src/lib/agent/types.ts +73 -0
- package/src/lib/auth.ts +11 -0
- package/src/lib/config.ts +152 -0
- package/src/lib/daemon-callbacks.ts +59 -0
- package/src/lib/daemon-client.ts +16 -0
- package/src/lib/daemon-lifecycle.ts +368 -0
- package/src/lib/daemon-spawn.ts +122 -0
- package/src/lib/daemon-status.ts +189 -0
- package/src/lib/daemon-watcher.ts +192 -0
- package/src/lib/experiment-loop.ts +679 -0
- package/src/lib/experiment.ts +356 -0
- package/src/lib/finalize.test.ts +143 -0
- package/src/lib/finalize.ts +511 -0
- package/src/lib/format.test.ts +32 -0
- package/src/lib/format.ts +44 -0
- package/src/lib/git.ts +176 -0
- package/src/lib/ideas-backlog.test.ts +54 -0
- package/src/lib/ideas-backlog.ts +109 -0
- package/src/lib/measure.ts +472 -0
- package/src/lib/model-options.ts +24 -0
- package/src/lib/programs.ts +247 -0
- package/src/lib/push-stream.ts +48 -0
- package/src/lib/run-context.ts +112 -0
- package/src/lib/run-setup.ts +34 -0
- package/src/lib/run.ts +383 -0
- package/src/lib/syntax-theme.ts +39 -0
- package/src/lib/system-prompts/experiment.ts +77 -0
- package/src/lib/system-prompts/finalize.ts +90 -0
- package/src/lib/system-prompts/index.ts +7 -0
- package/src/lib/system-prompts/setup.ts +516 -0
- package/src/lib/system-prompts/update.ts +188 -0
- package/src/lib/tool-events.ts +99 -0
- package/src/lib/validate-measurement.ts +326 -0
- package/src/lib/worktree.ts +40 -0
- package/src/screens/AuthErrorScreen.tsx +31 -0
- package/src/screens/ExecutionScreen.tsx +851 -0
- package/src/screens/FirstSetupScreen.tsx +168 -0
- package/src/screens/HomeScreen.tsx +406 -0
- package/src/screens/PreRunScreen.tsx +206 -0
- package/src/screens/SettingsScreen.tsx +189 -0
- package/src/screens/SetupScreen.tsx +226 -0
- package/src/tui.tsx +17 -0
- package/tsconfig.json +17 -0
package/README.md
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# AutoAuto
|
|
2
|
+
|
|
3
|
+
A TUI tool that makes the [autoresearch](https://github.com/karpathy/autoresearch) pattern easy to set up and run on any codebase. Define a metric, let an AI agent iteratively optimize your code, keep improvements, discard failures, loop overnight.
|
|
4
|
+
|
|
5
|
+
While autoresearch originated in ML training, AutoAuto applies it to everything: software performance, test stability, prompt optimization, search ranking, marketing copy — anything where you have code and a measurable metric. No training loops, datasets, or GPUs required.
|
|
6
|
+
|
|
7
|
+
Don't understand autoresearch or don't know what to apply it on? No problem! This tool will scan your codebase, guide you step by step to create it.
|
|
8
|
+
|
|
9
|
+
This tool takes care of everything:
|
|
10
|
+
|
|
11
|
+
* Finding autoresearch opportunities in your codebase
|
|
12
|
+
* Defining metrics, creating a scripts
|
|
13
|
+
* Defining the best settings
|
|
14
|
+
* Running the experiments (supports Claude, Codex and OpenCode)
|
|
15
|
+
* Using best practices
|
|
16
|
+
|
|
17
|
+
## What it does
|
|
18
|
+
|
|
19
|
+
AutoAuto wraps the full autoresearch workflow — from defining what to optimize, to running hundreds of autonomous experiments, to packaging the results — into a terminal UI that handles all the tricky parts for you.
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
┌─ Setup ────────────────────────────────────────────────────────────┐
|
|
23
|
+
│ An AI agent inspects your repo, helps you define what to optimize, │
|
|
24
|
+
│ generates a measurement script, and validates it's stable. │
|
|
25
|
+
└────────────────────────────────────────────────────────────────────┘
|
|
26
|
+
↓
|
|
27
|
+
┌─ Execute ──────────────────────────────────────────────────────────┐
|
|
28
|
+
│ Autonomous loop in a background daemon: │
|
|
29
|
+
│ 1. Spawn a fresh agent with context from previous experiments │
|
|
30
|
+
│ 2. Agent makes one change and commits │
|
|
31
|
+
│ 3. Measure (median of N runs) │
|
|
32
|
+
│ 4. Keep if improved beyond noise threshold, discard otherwise │
|
|
33
|
+
│ 5. Repeat │
|
|
34
|
+
│ Runs in a git worktree — your main checkout stays clean. │
|
|
35
|
+
│ Survives terminal close. │
|
|
36
|
+
└────────────────────────────────────────────────────────────────────┘
|
|
37
|
+
↓
|
|
38
|
+
┌─ Finalize ─────────────────────────────────────────────────────────┐
|
|
39
|
+
│ Review the accumulated diff, group changes into independent │
|
|
40
|
+
│ branches, and produce a summary. │
|
|
41
|
+
└────────────────────────────────────────────────────────────────────┘
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Why use this instead of a script
|
|
45
|
+
|
|
46
|
+
Autoresearch looks simple — "just loop an agent and measure" — but real implementations fail in predictable ways. AutoAuto encodes lessons from 30+ real-world implementations so you don't have to learn the hard way:
|
|
47
|
+
|
|
48
|
+
- **Metric gaming** — Agents optimize the measurement instead of the real goal (random seed manipulation, stripping untested features, benchmark-specific hacks). AutoAuto locks measurement files, enforces scope constraints, and supports quality gates.
|
|
49
|
+
- **Variance** — A "3% improvement" means nothing if your measurement has 5% noise. AutoAuto validates measurement stability during setup, runs median-of-N measurements, and uses a noise threshold to filter false improvements.
|
|
50
|
+
- **Agent drift** — Without constraints, agents rewrite your architecture or add dependencies you never wanted. AutoAuto's `program.md` defines exactly what's in scope and off-limits.
|
|
51
|
+
- **Narrative momentum** — Long-running agents convince themselves their approach is working and resist changing direction. AutoAuto spawns a fresh agent per experiment with no memory except a structured context packet.
|
|
52
|
+
- **Recovery** — One bad experiment shouldn't corrupt the run. AutoAuto uses `git reset --hard` for clean rollback after every failure, re-baselines to detect environment drift, and auto-stops after prolonged stagnation.
|
|
53
|
+
|
|
54
|
+
## Quick start
|
|
55
|
+
|
|
56
|
+
### Prerequisites
|
|
57
|
+
|
|
58
|
+
- [Bun](https://bun.sh) runtime
|
|
59
|
+
- One of the supported AI providers:
|
|
60
|
+
- **Claude** — [Claude CLI](https://docs.anthropic.com/en/docs/claude-code) installed and authenticated, or `ANTHROPIC_API_KEY` set
|
|
61
|
+
- **Codex** — [Codex CLI](https://github.com/openai/codex) installed
|
|
62
|
+
- **OpenCode** — [OpenCode](https://opencode.ai) installed
|
|
63
|
+
|
|
64
|
+
### Install and run
|
|
65
|
+
|
|
66
|
+
TODO: add easier way to install
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
git clone https://github.com/SpaceK33z/autoauto.git
|
|
70
|
+
cd autoauto
|
|
71
|
+
bun install
|
|
72
|
+
bun dev
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Or install globally:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
bun link
|
|
79
|
+
autoauto
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Headless CLI
|
|
83
|
+
|
|
84
|
+
AutoAuto also has a headless CLI for coding agents, CI or just generally scripting:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
autoauto list # List programs
|
|
88
|
+
autoauto runs <program> # List runs for a program
|
|
89
|
+
autoauto run <program> # Start a run
|
|
90
|
+
autoauto run <program> --max 50 # Run with max experiments
|
|
91
|
+
autoauto stop <program> # Stop after current experiment
|
|
92
|
+
autoauto attach <program> # Attach TUI to a running daemon
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## How it works
|
|
96
|
+
|
|
97
|
+
### 1. Setup — define what to optimize
|
|
98
|
+
|
|
99
|
+
The Setup Agent inspects your repo and walks you through an interactive chat to configure an optimization **program**:
|
|
100
|
+
|
|
101
|
+
- **Goal** — What are you optimizing? (e.g., "reduce homepage LCP", "fix flaky test suite", "improve prompt pass rate")
|
|
102
|
+
- **Measurement script** — A `measure.sh` that outputs a JSON object with your metric. AutoAuto validates it runs cleanly and measures variance across multiple runs.
|
|
103
|
+
- **Scope constraints** — Which files the agent can touch, what's off-limits, and rules it must follow.
|
|
104
|
+
- **Quality gates** — Secondary metrics that must stay within bounds (e.g., "CLS must remain below 0.1" while optimizing LCP).
|
|
105
|
+
|
|
106
|
+
The result is a reusable program stored in `.autoauto/programs/<name>/` — you can run it repeatedly.
|
|
107
|
+
|
|
108
|
+
### 2. Execute — the autonomous loop
|
|
109
|
+
|
|
110
|
+
Hit run and AutoAuto:
|
|
111
|
+
|
|
112
|
+
1. Creates a git worktree (your main checkout stays untouched)
|
|
113
|
+
2. Spawns a background daemon that survives terminal close
|
|
114
|
+
3. Establishes a baseline measurement
|
|
115
|
+
4. Loops: spawn agent → one change → commit → measure → keep or discard → repeat
|
|
116
|
+
|
|
117
|
+
Each experiment agent gets a **context packet** — not the full chat history, but a structured summary: current baseline, recent results, git log of kept changes, diffs from recently discarded attempts, and an ideas backlog of what's been tried. This prevents repeating failed approaches while keeping context small.
|
|
118
|
+
|
|
119
|
+
The live TUI dashboard shows:
|
|
120
|
+
|
|
121
|
+
- **Stats header** — experiment count, keeps/discards, baseline vs best with improvement %, cost, and a sparkline
|
|
122
|
+
- **Results table** — color-coded experiment outcomes (green = kept, red = discarded)
|
|
123
|
+
- **Agent panel** — live streaming output from the current experiment
|
|
124
|
+
|
|
125
|
+
### 3. Finalize — package the results
|
|
126
|
+
|
|
127
|
+
After the loop completes (or you stop it), a Finalize Agent reviews the accumulated diff and groups changes into independent branches for clean review and merge. Falls back to a single squash commit if changes are too intertwined.
|
|
128
|
+
|
|
129
|
+
## Key safeguards
|
|
130
|
+
|
|
131
|
+
| Safeguard | What it prevents |
|
|
132
|
+
|-----------|-----------------|
|
|
133
|
+
| **Locked evaluator** — `measure.sh` + `config.json` are `chmod 444` during runs | Agent modifying the measurement to fake improvements |
|
|
134
|
+
| **Scope constraints** — `program.md` defines allowed files and off-limits areas | Agent drifting into unrelated code or risky changes |
|
|
135
|
+
| **Quality gates** — secondary metrics with hard thresholds | Agent improving one metric by degrading another |
|
|
136
|
+
| **Noise threshold** — improvements must exceed measured variance | False positives from measurement noise |
|
|
137
|
+
| **Median-of-N** — repeated measurements with median aggregation | Outlier measurements causing bad decisions |
|
|
138
|
+
| **One agent per experiment** — fresh context each iteration | Narrative momentum and compounding errors |
|
|
139
|
+
| **Git worktree isolation** — experiments run in a separate checkout | Corrupting your working directory |
|
|
140
|
+
| **Lock violation detection** — discards any experiment that touches `.autoauto/` | Agent tampering with its own config |
|
|
141
|
+
| **Re-baselining** — fresh baseline after keeps and after consecutive discards | Environment drift causing phantom improvements |
|
|
142
|
+
| **Stagnation detection** — auto-stops after 10 consecutive non-improving experiments | Burning money when the agent is stuck |
|
|
143
|
+
| **Simplicity criterion** — auto-keeps within-noise changes that reduce LOC | Rewarding code simplification even without metric gain |
|
|
144
|
+
|
|
145
|
+
## Data model
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
.autoauto/ # All state, gitignored automatically
|
|
149
|
+
config.json # Project config (models, provider)
|
|
150
|
+
programs/
|
|
151
|
+
homepage-lcp/
|
|
152
|
+
program.md # Agent instructions + scope constraints
|
|
153
|
+
measure.sh # Measurement script
|
|
154
|
+
config.json # Metric, direction, noise, quality gates
|
|
155
|
+
build.sh # Optional build step before measurement
|
|
156
|
+
runs/
|
|
157
|
+
20260407-143022/
|
|
158
|
+
state.json # Run state checkpoint
|
|
159
|
+
results.tsv # Append-only experiment outcomes
|
|
160
|
+
ideas.md # Ideas backlog (optional)
|
|
161
|
+
stream-001.log # Per-experiment agent output
|
|
162
|
+
...
|
|
163
|
+
worktrees/
|
|
164
|
+
20260407-143022/ # Git worktree for active run
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Configuration
|
|
168
|
+
|
|
169
|
+
AutoAuto supports two model slots:
|
|
170
|
+
|
|
171
|
+
- **Execution model** — powers the experiment agents (default: Sonnet)
|
|
172
|
+
- **Support model** — powers setup, update, and finalize agents (default: Sonnet)
|
|
173
|
+
|
|
174
|
+
Both are configurable per-provider with effort level (low/medium/high). Override per-run from the pre-run config screen.
|
|
175
|
+
|
|
176
|
+
Supported providers: **Claude** (Agent SDK), **Codex** (CLI), **OpenCode**.
|
|
177
|
+
|
|
178
|
+
## Stack
|
|
179
|
+
|
|
180
|
+
- **Runtime:** [Bun](https://bun.sh)
|
|
181
|
+
- **Language:** TypeScript (strict mode)
|
|
182
|
+
- **TUI:** [OpenTUI](https://opentui.com) (React reconciler for the terminal)
|
|
183
|
+
- **Agent:** [Claude Agent SDK](https://github.com/anthropics/claude-agent-sdk-typescript), with pluggable provider support
|
|
184
|
+
|
|
185
|
+
## Documentation
|
|
186
|
+
|
|
187
|
+
| Doc | Contents |
|
|
188
|
+
|-----|----------|
|
|
189
|
+
| [Architecture](docs/architecture.md) | System architecture, data model, daemon design |
|
|
190
|
+
| [Orchestration Patterns](docs/orchestration-patterns.md) | Loop design, context packets, stopping criteria |
|
|
191
|
+
| [Measurement Patterns](docs/measurement-patterns.md) | Metric design, scoring approaches, variance handling |
|
|
192
|
+
| [Failure Patterns](docs/failure-patterns.md) | Documented failure modes and safeguards from real implementations |
|
|
193
|
+
| [Autoresearch Ideas](docs/autoresearch-ideas.md) | Non-ML use cases across performance, prompts, marketing, and more |
|
|
194
|
+
|
|
195
|
+
## License
|
|
196
|
+
|
|
197
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@spacek33z/autoauto",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "TUI tool for autoresearch — autonomous experiment loops on any codebase",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/SpaceK33z/autoauto.git"
|
|
10
|
+
},
|
|
11
|
+
"author": "Kees Kluskens",
|
|
12
|
+
"homepage": "https://github.com/SpaceK33z/autoauto",
|
|
13
|
+
"engines": {
|
|
14
|
+
"bun": ">=1.0.0"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"autoresearch",
|
|
18
|
+
"tui",
|
|
19
|
+
"ai",
|
|
20
|
+
"automation",
|
|
21
|
+
"experiments",
|
|
22
|
+
"claude",
|
|
23
|
+
"codex"
|
|
24
|
+
],
|
|
25
|
+
"files": [
|
|
26
|
+
"src/",
|
|
27
|
+
"tsconfig.json"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"dev": "bun run src/index.tsx",
|
|
31
|
+
"build": "bun build --compile src/index.tsx --outfile dist/autoauto",
|
|
32
|
+
"lint": "oxlint",
|
|
33
|
+
"typecheck": "bun tsc --noEmit"
|
|
34
|
+
},
|
|
35
|
+
"bin": {
|
|
36
|
+
"autoauto": "./src/index.tsx"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.92",
|
|
40
|
+
"@openai/codex-sdk": "^0.118.0",
|
|
41
|
+
"@opencode-ai/sdk": "^1.3.17",
|
|
42
|
+
"@opentui/core": "^0.1.97",
|
|
43
|
+
"@opentui/react": "^0.1.97"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/bun": "^1.3.11",
|
|
47
|
+
"@types/react": "^19.2.14",
|
|
48
|
+
"oxlint": "^1.58.0",
|
|
49
|
+
"typescript": "^5.7.0"
|
|
50
|
+
}
|
|
51
|
+
}
|
package/src/App.tsx
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { useState, useEffect } from "react"
|
|
2
|
+
import {
|
|
3
|
+
useKeyboard,
|
|
4
|
+
useRenderer,
|
|
5
|
+
useTerminalDimensions,
|
|
6
|
+
} from "@opentui/react"
|
|
7
|
+
import { HomeScreen } from "./screens/HomeScreen.tsx"
|
|
8
|
+
import { SetupScreen } from "./screens/SetupScreen.tsx"
|
|
9
|
+
import { SettingsScreen } from "./screens/SettingsScreen.tsx"
|
|
10
|
+
import { ExecutionScreen } from "./screens/ExecutionScreen.tsx"
|
|
11
|
+
import { PreRunScreen, type PreRunOverrides } from "./screens/PreRunScreen.tsx"
|
|
12
|
+
import { FirstSetupScreen } from "./screens/FirstSetupScreen.tsx"
|
|
13
|
+
import { PostUpdatePrompt } from "./components/PostUpdatePrompt.tsx"
|
|
14
|
+
import { ensureAutoAutoDir, getProjectRoot, type Screen } from "./lib/programs.ts"
|
|
15
|
+
import { loadProjectConfig, configExists, DEFAULT_CONFIG, type ProjectConfig } from "./lib/config.ts"
|
|
16
|
+
import { isRunActive } from "./lib/run.ts"
|
|
17
|
+
|
|
18
|
+
const cwd = process.cwd()
|
|
19
|
+
|
|
20
|
+
export function App() {
|
|
21
|
+
const renderer = useRenderer()
|
|
22
|
+
const { width, height } = useTerminalDimensions()
|
|
23
|
+
const [screen, setScreen] = useState<Screen | null>(null)
|
|
24
|
+
const [selectedProgram, setSelectedProgram] = useState<string | null>(null)
|
|
25
|
+
const [projectRoot, setProjectRoot] = useState(cwd)
|
|
26
|
+
const [projectConfig, setProjectConfig] = useState<ProjectConfig>(DEFAULT_CONFIG)
|
|
27
|
+
const [preRunOverrides, setPreRunOverrides] = useState<PreRunOverrides | null>(null)
|
|
28
|
+
const [attachRunId, setAttachRunId] = useState<string | null>(null)
|
|
29
|
+
const [attachReadOnly, setAttachReadOnly] = useState(false)
|
|
30
|
+
const [autoFinalize, setAutoFinalize] = useState(false)
|
|
31
|
+
const [updateProgramSlug, setUpdateProgramSlug] = useState<string | null>(null)
|
|
32
|
+
const [showPostUpdatePrompt, setShowPostUpdatePrompt] = useState(false)
|
|
33
|
+
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
getProjectRoot(cwd).then(setProjectRoot).catch(() => {})
|
|
36
|
+
ensureAutoAutoDir(cwd).catch(() => {})
|
|
37
|
+
configExists(cwd).then((exists) => {
|
|
38
|
+
setScreen(exists ? "home" : "first-setup")
|
|
39
|
+
})
|
|
40
|
+
}, [])
|
|
41
|
+
|
|
42
|
+
// Load project config + reload when returning to home
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (screen === "home") {
|
|
45
|
+
loadProjectConfig(cwd).then(setProjectConfig)
|
|
46
|
+
}
|
|
47
|
+
}, [screen])
|
|
48
|
+
|
|
49
|
+
useKeyboard((key) => {
|
|
50
|
+
if (key.name === "escape") {
|
|
51
|
+
if (screen === "home") {
|
|
52
|
+
renderer.destroy()
|
|
53
|
+
}
|
|
54
|
+
// execution screen handles its own Escape
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
if (!screen) {
|
|
59
|
+
return (
|
|
60
|
+
<box flexDirection="column" width={width} height={height}>
|
|
61
|
+
<box flexGrow={1} justifyContent="center" alignItems="center">
|
|
62
|
+
<text fg="#888888">Loading...</text>
|
|
63
|
+
</box>
|
|
64
|
+
</box>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const footerText =
|
|
69
|
+
screen === "home"
|
|
70
|
+
? " n: new | e: edit | d: delete | f: finalize | s: settings | Tab: switch | Enter: run | Esc: quit"
|
|
71
|
+
: screen === "execution"
|
|
72
|
+
? " Escape: detach (daemon continues) | Tab: switch panel | s: settings | q: stop | Ctrl+C: abort"
|
|
73
|
+
: screen === "settings"
|
|
74
|
+
? " ↑↓: navigate | ←→: change/open | Enter: open model picker | Escape: back"
|
|
75
|
+
: screen === "first-setup"
|
|
76
|
+
? " ↑↓: navigate | ←→: cycle | Enter: select/continue"
|
|
77
|
+
: " Escape: back"
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<box flexDirection="column" width={width} height={height}>
|
|
81
|
+
{screen !== "execution" && screen !== "pre-run" && (
|
|
82
|
+
<box
|
|
83
|
+
height={3}
|
|
84
|
+
border
|
|
85
|
+
borderStyle="rounded"
|
|
86
|
+
justifyContent="center"
|
|
87
|
+
alignItems="center"
|
|
88
|
+
>
|
|
89
|
+
<text>
|
|
90
|
+
<strong>AutoAuto</strong>
|
|
91
|
+
</text>
|
|
92
|
+
</box>
|
|
93
|
+
)}
|
|
94
|
+
|
|
95
|
+
<box flexDirection="column" flexGrow={1} flexShrink={1}>
|
|
96
|
+
{screen === "first-setup" && (
|
|
97
|
+
<FirstSetupScreen
|
|
98
|
+
cwd={cwd}
|
|
99
|
+
navigate={setScreen}
|
|
100
|
+
onConfigChange={setProjectConfig}
|
|
101
|
+
/>
|
|
102
|
+
)}
|
|
103
|
+
{screen === "home" && (
|
|
104
|
+
<HomeScreen
|
|
105
|
+
cwd={cwd}
|
|
106
|
+
navigate={setScreen}
|
|
107
|
+
onSelectProgram={(slug) => {
|
|
108
|
+
setSelectedProgram(slug)
|
|
109
|
+
setAttachRunId(null)
|
|
110
|
+
setAttachReadOnly(false)
|
|
111
|
+
setScreen("pre-run")
|
|
112
|
+
}}
|
|
113
|
+
onSelectRun={(run) => {
|
|
114
|
+
if (!run.state) return
|
|
115
|
+
setSelectedProgram(run.state.program_slug)
|
|
116
|
+
setPreRunOverrides(null)
|
|
117
|
+
setAttachRunId(run.run_id)
|
|
118
|
+
setAutoFinalize(false)
|
|
119
|
+
setAttachReadOnly(!isRunActive(run))
|
|
120
|
+
setScreen("execution")
|
|
121
|
+
}}
|
|
122
|
+
onFinalizeRun={(run) => {
|
|
123
|
+
if (!run.state) return
|
|
124
|
+
setSelectedProgram(run.state.program_slug)
|
|
125
|
+
setPreRunOverrides(null)
|
|
126
|
+
setAttachRunId(run.run_id)
|
|
127
|
+
setAutoFinalize(true)
|
|
128
|
+
setAttachReadOnly(false)
|
|
129
|
+
setScreen("execution")
|
|
130
|
+
}}
|
|
131
|
+
onUpdateProgram={(slug) => {
|
|
132
|
+
setUpdateProgramSlug(slug)
|
|
133
|
+
setSelectedProgram(slug)
|
|
134
|
+
setScreen("setup")
|
|
135
|
+
}}
|
|
136
|
+
/>
|
|
137
|
+
)}
|
|
138
|
+
{screen === "setup" && !showPostUpdatePrompt && (
|
|
139
|
+
<SetupScreen
|
|
140
|
+
cwd={projectRoot}
|
|
141
|
+
navigate={(s) => {
|
|
142
|
+
if (updateProgramSlug && s === "home") {
|
|
143
|
+
// Leaving update mode — show post-update prompt
|
|
144
|
+
setShowPostUpdatePrompt(true)
|
|
145
|
+
} else {
|
|
146
|
+
setUpdateProgramSlug(null)
|
|
147
|
+
setScreen(s)
|
|
148
|
+
}
|
|
149
|
+
}}
|
|
150
|
+
modelConfig={projectConfig.supportModel}
|
|
151
|
+
programSlug={updateProgramSlug ?? undefined}
|
|
152
|
+
/>
|
|
153
|
+
)}
|
|
154
|
+
{screen === "setup" && showPostUpdatePrompt && selectedProgram && (
|
|
155
|
+
<PostUpdatePrompt
|
|
156
|
+
programSlug={selectedProgram}
|
|
157
|
+
onStartRun={() => {
|
|
158
|
+
setShowPostUpdatePrompt(false)
|
|
159
|
+
setUpdateProgramSlug(null)
|
|
160
|
+
setScreen("pre-run")
|
|
161
|
+
}}
|
|
162
|
+
onGoHome={() => {
|
|
163
|
+
setShowPostUpdatePrompt(false)
|
|
164
|
+
setUpdateProgramSlug(null)
|
|
165
|
+
setScreen("home")
|
|
166
|
+
}}
|
|
167
|
+
/>
|
|
168
|
+
)}
|
|
169
|
+
{screen === "settings" && (
|
|
170
|
+
<SettingsScreen
|
|
171
|
+
cwd={cwd}
|
|
172
|
+
navigate={setScreen}
|
|
173
|
+
config={projectConfig}
|
|
174
|
+
onConfigChange={setProjectConfig}
|
|
175
|
+
/>
|
|
176
|
+
)}
|
|
177
|
+
{screen === "pre-run" && selectedProgram && (
|
|
178
|
+
<PreRunScreen
|
|
179
|
+
cwd={projectRoot}
|
|
180
|
+
programSlug={selectedProgram}
|
|
181
|
+
defaultModelConfig={projectConfig.executionModel}
|
|
182
|
+
navigate={setScreen}
|
|
183
|
+
onStart={(overrides) => {
|
|
184
|
+
setPreRunOverrides(overrides)
|
|
185
|
+
setAttachRunId(null)
|
|
186
|
+
setAttachReadOnly(false)
|
|
187
|
+
setScreen("execution")
|
|
188
|
+
}}
|
|
189
|
+
/>
|
|
190
|
+
)}
|
|
191
|
+
{screen === "execution" && selectedProgram && (preRunOverrides || attachRunId) && (
|
|
192
|
+
<ExecutionScreen
|
|
193
|
+
cwd={projectRoot}
|
|
194
|
+
programSlug={selectedProgram}
|
|
195
|
+
modelConfig={preRunOverrides?.modelConfig ?? projectConfig.executionModel}
|
|
196
|
+
supportModelConfig={projectConfig.supportModel}
|
|
197
|
+
ideasBacklogEnabled={projectConfig.ideasBacklogEnabled}
|
|
198
|
+
navigate={(s) => { setPreRunOverrides(null); setAttachRunId(null); setAttachReadOnly(false); setAutoFinalize(false); setScreen(s) }}
|
|
199
|
+
maxExperiments={preRunOverrides?.maxExperiments ?? 0}
|
|
200
|
+
useWorktree={preRunOverrides?.useWorktree ?? true}
|
|
201
|
+
attachRunId={attachRunId ?? undefined}
|
|
202
|
+
readOnly={attachReadOnly}
|
|
203
|
+
autoFinalize={autoFinalize}
|
|
204
|
+
onUpdateProgram={(slug) => {
|
|
205
|
+
setPreRunOverrides(null)
|
|
206
|
+
setAttachRunId(null)
|
|
207
|
+
setAttachReadOnly(false)
|
|
208
|
+
setAutoFinalize(false)
|
|
209
|
+
setUpdateProgramSlug(slug)
|
|
210
|
+
setSelectedProgram(slug)
|
|
211
|
+
setScreen("setup")
|
|
212
|
+
}}
|
|
213
|
+
/>
|
|
214
|
+
)}
|
|
215
|
+
</box>
|
|
216
|
+
|
|
217
|
+
{screen !== "pre-run" && (
|
|
218
|
+
<box height={1} flexShrink={0} paddingX={1}>
|
|
219
|
+
<text fg="#888888">{footerText}</text>
|
|
220
|
+
</box>
|
|
221
|
+
)}
|
|
222
|
+
</box>
|
|
223
|
+
)
|
|
224
|
+
}
|