@nbardy/oompa 0.1.0 → 0.2.0
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 +52 -16
- package/agentnet/src/agentnet/cli.clj +5 -3
- package/agentnet/src/agentnet/worker.clj +62 -31
- package/bin/oompa.js +1 -1
- package/config/prompts/_task_header.md +46 -0
- package/config/prompts/executor.md +6 -31
- package/config/prompts/planner.md +10 -35
- package/config/prompts/worker.md +5 -30
- package/oompa.example.json +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -79,25 +79,50 @@ This repo has a fleshed out version of the idea. The oompa loompas are organized
|
|
|
79
79
|
|
|
80
80
|
### Configuration
|
|
81
81
|
|
|
82
|
-
**oompa.json
|
|
82
|
+
**oompa.json** — the only file you need:
|
|
83
83
|
```json
|
|
84
84
|
{
|
|
85
85
|
"review_model": "codex:codex-5.2",
|
|
86
86
|
"workers": [
|
|
87
|
-
{"model": "claude:opus-4.5", "
|
|
88
|
-
{"model": "codex:codex-5.2-mini", "
|
|
87
|
+
{"model": "claude:opus-4.5", "prompt": ["config/prompts/planner.md"], "iterations": 5, "count": 1},
|
|
88
|
+
{"model": "codex:codex-5.2-mini", "prompt": ["config/prompts/executor.md"], "iterations": 10, "count": 3}
|
|
89
89
|
]
|
|
90
90
|
}
|
|
91
91
|
```
|
|
92
92
|
|
|
93
93
|
This spawns:
|
|
94
|
-
- **1 planner** (opus) —
|
|
94
|
+
- **1 planner** (opus) — reads spec, explores codebase, creates/refines tasks
|
|
95
95
|
- **3 executors** (mini) — claims and executes tasks fast
|
|
96
96
|
- **Reviews** done by codex-5.2 before any merge
|
|
97
97
|
|
|
98
|
+
#### Worker fields
|
|
99
|
+
|
|
100
|
+
| Field | Required | Description |
|
|
101
|
+
|-------|----------|-------------|
|
|
102
|
+
| `model` | yes | `harness:model` (e.g. `claude:opus-4.5`, `codex:codex-5.2-mini`) |
|
|
103
|
+
| `prompt` | no | String or array of paths — concatenated into one prompt |
|
|
104
|
+
| `iterations` | no | Max iterations per worker (default: 10) |
|
|
105
|
+
| `count` | no | Number of workers with this config (default: 1) |
|
|
106
|
+
|
|
107
|
+
#### Composable prompts
|
|
108
|
+
|
|
109
|
+
`prompt` accepts a string or an array. Arrays get concatenated, so you can reuse a shared base across workers:
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"workers": [
|
|
114
|
+
{"model": "claude:opus-4.5", "prompt": ["prompts/base.md", "prompts/architect.md"], "count": 1},
|
|
115
|
+
{"model": "codex:codex-5.2-mini", "prompt": ["prompts/base.md", "prompts/frontend.md"], "count": 2},
|
|
116
|
+
{"model": "codex:codex-5.2-mini", "prompt": ["prompts/base.md", "prompts/backend.md"], "count": 2}
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Every worker automatically gets task management instructions injected above your prompts. Your prompts just say *what* the worker should do — the framework handles *how* tasks work.
|
|
122
|
+
|
|
98
123
|
### Task System
|
|
99
124
|
|
|
100
|
-
Workers self-organize via filesystem:
|
|
125
|
+
Workers self-organize via the filesystem. Tasks live at the project root and are shared across all worktrees:
|
|
101
126
|
|
|
102
127
|
```
|
|
103
128
|
tasks/
|
|
@@ -106,20 +131,31 @@ tasks/
|
|
|
106
131
|
└── complete/*.edn # done
|
|
107
132
|
```
|
|
108
133
|
|
|
109
|
-
|
|
110
|
-
- **
|
|
111
|
-
- **
|
|
112
|
-
- **
|
|
134
|
+
From inside a worktree, workers reach tasks via `../tasks/`:
|
|
135
|
+
- **See tasks**: `ls ../tasks/pending/`
|
|
136
|
+
- **Claim**: `mv ../tasks/pending/task.edn ../tasks/current/`
|
|
137
|
+
- **Complete**: `mv ../tasks/current/task.edn ../tasks/complete/`
|
|
138
|
+
- **Create**: write new `.edn` to `../tasks/pending/`
|
|
139
|
+
|
|
140
|
+
Task file format:
|
|
141
|
+
```edn
|
|
142
|
+
{:id "task-001"
|
|
143
|
+
:summary "Add user authentication"
|
|
144
|
+
:description "Implement JWT-based auth for the API"
|
|
145
|
+
:difficulty :medium
|
|
146
|
+
:files ["src/auth.py" "tests/test_auth.py"]
|
|
147
|
+
:acceptance ["Login endpoint returns token" "Tests pass"]}
|
|
148
|
+
```
|
|
113
149
|
|
|
114
|
-
### Prompts
|
|
150
|
+
### Bundled Prompts
|
|
115
151
|
|
|
116
|
-
Three
|
|
152
|
+
Three prompt files ship with oompa that you can use in your `prompt` arrays:
|
|
117
153
|
|
|
118
|
-
| Prompt |
|
|
119
|
-
|
|
120
|
-
| `worker.md` |
|
|
121
|
-
| `planner.md` |
|
|
122
|
-
| `executor.md` |
|
|
154
|
+
| Prompt | Creates Tasks? | Executes Tasks? | Best For |
|
|
155
|
+
|--------|----------------|-----------------|----------|
|
|
156
|
+
| `config/prompts/worker.md` (default) | yes | yes | General purpose |
|
|
157
|
+
| `config/prompts/planner.md` | yes | sometimes | Big models — task design |
|
|
158
|
+
| `config/prompts/executor.md` | no | yes | Small/fast models — heads-down work |
|
|
123
159
|
|
|
124
160
|
---
|
|
125
161
|
|
|
@@ -300,10 +300,12 @@
|
|
|
300
300
|
(println "{")
|
|
301
301
|
(println " \"review_model\": \"codex:codex-5.2\",")
|
|
302
302
|
(println " \"workers\": [")
|
|
303
|
-
(println " {\"model\": \"codex:codex-5.2-mini\", \"iterations\": 10, \"count\": 3},")
|
|
304
|
-
(println " {\"model\": \"
|
|
303
|
+
(println " {\"model\": \"codex:codex-5.2-mini\", \"prompt\": \"prompts/executor.md\", \"iterations\": 10, \"count\": 3},")
|
|
304
|
+
(println " {\"model\": \"claude:opus-4.5\", \"prompt\": [\"prompts/base.md\", \"prompts/planner.md\"], \"count\": 1}")
|
|
305
305
|
(println " ]")
|
|
306
306
|
(println "}")
|
|
307
|
+
(println)
|
|
308
|
+
(println "prompt: string or array of paths — concatenated into one prompt.")
|
|
307
309
|
(System/exit 1))
|
|
308
310
|
(let [config (json/parse-string (slurp f) true)
|
|
309
311
|
review-model (some-> (:review_model config) parse-model-string)
|
|
@@ -325,7 +327,7 @@
|
|
|
325
327
|
:harness harness
|
|
326
328
|
:model model
|
|
327
329
|
:iterations (or (:iterations wc) 10)
|
|
328
|
-
:
|
|
330
|
+
:prompts (:prompt wc)
|
|
329
331
|
:review-harness (:harness review-model)
|
|
330
332
|
:review-model (:model review-model)})))
|
|
331
333
|
expanded-workers)]
|
|
@@ -93,15 +93,29 @@
|
|
|
93
93
|
;; Worker State
|
|
94
94
|
;; =============================================================================
|
|
95
95
|
|
|
96
|
+
(def ^:private package-root
|
|
97
|
+
"Root of the oompa package — set by bin/oompa.js, falls back to cwd."
|
|
98
|
+
(or (System/getenv "OOMPA_PACKAGE_ROOT") "."))
|
|
99
|
+
|
|
100
|
+
(defn- load-prompt
|
|
101
|
+
"Load a prompt file. Tries path as-is first, then from package root."
|
|
102
|
+
[path]
|
|
103
|
+
(or (agent/load-custom-prompt path)
|
|
104
|
+
(agent/load-custom-prompt (str package-root "/" path))))
|
|
105
|
+
|
|
96
106
|
(defn create-worker
|
|
97
|
-
"Create a worker config
|
|
98
|
-
|
|
107
|
+
"Create a worker config.
|
|
108
|
+
:prompts is a string or vector of strings — paths to prompt files."
|
|
109
|
+
[{:keys [id swarm-id harness model iterations prompts review-harness review-model]}]
|
|
99
110
|
{:id id
|
|
100
111
|
:swarm-id swarm-id
|
|
101
112
|
:harness (or harness :codex)
|
|
102
113
|
:model model
|
|
103
114
|
:iterations (or iterations 10)
|
|
104
|
-
:
|
|
115
|
+
:prompts (cond
|
|
116
|
+
(vector? prompts) prompts
|
|
117
|
+
(string? prompts) [prompts]
|
|
118
|
+
:else [])
|
|
105
119
|
:review-harness review-harness
|
|
106
120
|
:review-model review-model
|
|
107
121
|
:completed 0
|
|
@@ -128,25 +142,36 @@
|
|
|
128
142
|
|
|
129
143
|
(defn- run-agent!
|
|
130
144
|
"Run agent with prompt, return {:output string, :done? bool, :exit int}"
|
|
131
|
-
[{:keys [id swarm-id harness model
|
|
132
|
-
(let [;;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
145
|
+
[{:keys [id swarm-id harness model prompts]} worktree-path context]
|
|
146
|
+
(let [;; 1. Task header (always, from package)
|
|
147
|
+
task-header (or (load-prompt "config/prompts/_task_header.md") "")
|
|
148
|
+
|
|
149
|
+
;; 2. Load and concatenate all user prompts (string or list)
|
|
150
|
+
user-prompts (if (seq prompts)
|
|
151
|
+
(->> prompts
|
|
152
|
+
(map load-prompt)
|
|
153
|
+
(remove nil?)
|
|
154
|
+
(str/join "\n\n"))
|
|
155
|
+
(or (load-prompt "config/prompts/worker.md")
|
|
156
|
+
"You are a worker. Claim tasks, execute them, complete them."))
|
|
157
|
+
|
|
158
|
+
;; Assemble: task header + status + user prompts
|
|
159
|
+
full-prompt (str task-header "\n"
|
|
160
|
+
"Task Status: " (:task_status context) "\n"
|
|
161
|
+
"Pending: " (:pending_tasks context) "\n\n"
|
|
162
|
+
user-prompts)
|
|
141
163
|
session-id (str/lower-case (str (java.util.UUID/randomUUID)))
|
|
142
164
|
swarm-id* (or swarm-id "unknown")
|
|
143
165
|
tagged-prompt (str "[oompa:" swarm-id* ":" id "] " full-prompt)
|
|
144
166
|
abs-worktree (.getAbsolutePath (io/file worktree-path))
|
|
145
167
|
|
|
146
|
-
;; Build command
|
|
168
|
+
;; Build command — both harnesses run with cwd=worktree, no sandbox
|
|
169
|
+
;; so agents can `..` to reach project root for task management
|
|
147
170
|
cmd (case harness
|
|
148
|
-
:codex (cond-> ["codex" "exec"
|
|
149
|
-
"-
|
|
171
|
+
:codex (cond-> ["codex" "exec"
|
|
172
|
+
"--dangerously-bypass-approvals-and-sandbox"
|
|
173
|
+
"--skip-git-repo-check"
|
|
174
|
+
"-C" abs-worktree]
|
|
150
175
|
model (into ["--model" model])
|
|
151
176
|
true (conj "--" full-prompt))
|
|
152
177
|
:claude (cond-> ["claude" "-p" "--dangerously-skip-permissions"
|
|
@@ -156,13 +181,11 @@
|
|
|
156
181
|
_ (when (= harness :codex)
|
|
157
182
|
(persist-message! id session-id abs-worktree "user" tagged-prompt))
|
|
158
183
|
|
|
159
|
-
;; Run agent
|
|
184
|
+
;; Run agent — both run with cwd=worktree
|
|
160
185
|
result (try
|
|
161
186
|
(if (= harness :claude)
|
|
162
|
-
|
|
163
|
-
(process/sh cmd {:
|
|
164
|
-
;; Codex takes prompt as arg
|
|
165
|
-
(process/sh cmd {:out :string :err :string}))
|
|
187
|
+
(process/sh cmd {:dir abs-worktree :in tagged-prompt :out :string :err :string})
|
|
188
|
+
(process/sh cmd {:dir abs-worktree :out :string :err :string}))
|
|
166
189
|
(catch Exception e
|
|
167
190
|
{:exit -1 :out "" :err (.getMessage e)}))]
|
|
168
191
|
|
|
@@ -194,20 +217,24 @@
|
|
|
194
217
|
"- NEEDS_CHANGES with bullet points of issues\n"
|
|
195
218
|
"- REJECTED if fundamentally wrong")
|
|
196
219
|
|
|
197
|
-
|
|
220
|
+
abs-wt (.getAbsolutePath (io/file worktree-path))
|
|
221
|
+
|
|
222
|
+
;; Build command — cwd=worktree, no sandbox
|
|
198
223
|
cmd (case review-harness
|
|
199
|
-
:codex (cond-> ["codex" "exec"
|
|
200
|
-
"-
|
|
224
|
+
:codex (cond-> ["codex" "exec"
|
|
225
|
+
"--dangerously-bypass-approvals-and-sandbox"
|
|
226
|
+
"--skip-git-repo-check"
|
|
227
|
+
"-C" abs-wt]
|
|
201
228
|
review-model (into ["--model" review-model])
|
|
202
229
|
true (conj "--" review-prompt))
|
|
203
230
|
:claude (cond-> ["claude" "-p" "--dangerously-skip-permissions"]
|
|
204
231
|
review-model (into ["--model" review-model])))
|
|
205
232
|
|
|
206
|
-
;; Run reviewer
|
|
233
|
+
;; Run reviewer — cwd=worktree
|
|
207
234
|
result (try
|
|
208
235
|
(if (= review-harness :claude)
|
|
209
|
-
(process/sh cmd {:in review-prompt :out :string :err :string})
|
|
210
|
-
(process/sh cmd {:out :string :err :string}))
|
|
236
|
+
(process/sh cmd {:dir abs-wt :in review-prompt :out :string :err :string})
|
|
237
|
+
(process/sh cmd {:dir abs-wt :out :string :err :string}))
|
|
211
238
|
(catch Exception e
|
|
212
239
|
{:exit -1 :out "" :err (.getMessage e)}))
|
|
213
240
|
|
|
@@ -229,9 +256,13 @@
|
|
|
229
256
|
feedback "\n\n"
|
|
230
257
|
"Please fix these issues in the worktree.")
|
|
231
258
|
|
|
259
|
+
abs-wt (.getAbsolutePath (io/file worktree-path))
|
|
260
|
+
|
|
232
261
|
cmd (case harness
|
|
233
|
-
:codex (cond-> ["codex" "exec"
|
|
234
|
-
"-
|
|
262
|
+
:codex (cond-> ["codex" "exec"
|
|
263
|
+
"--dangerously-bypass-approvals-and-sandbox"
|
|
264
|
+
"--skip-git-repo-check"
|
|
265
|
+
"-C" abs-wt]
|
|
235
266
|
model (into ["--model" model])
|
|
236
267
|
true (conj "--" fix-prompt))
|
|
237
268
|
:claude (cond-> ["claude" "-p" "--dangerously-skip-permissions"]
|
|
@@ -239,8 +270,8 @@
|
|
|
239
270
|
|
|
240
271
|
result (try
|
|
241
272
|
(if (= harness :claude)
|
|
242
|
-
(process/sh cmd {:in fix-prompt :out :string :err :string})
|
|
243
|
-
(process/sh cmd {:out :string :err :string}))
|
|
273
|
+
(process/sh cmd {:dir abs-wt :in fix-prompt :out :string :err :string})
|
|
274
|
+
(process/sh cmd {:dir abs-wt :out :string :err :string}))
|
|
244
275
|
(catch Exception e
|
|
245
276
|
{:exit -1 :out "" :err (.getMessage e)}))]
|
|
246
277
|
|
package/bin/oompa.js
CHANGED
|
@@ -18,7 +18,7 @@ if (!fs.existsSync(swarmScript) || !fs.existsSync(classpath)) {
|
|
|
18
18
|
const result = spawnSync("bb", ["--classpath", classpath, swarmScript, ...argv], {
|
|
19
19
|
stdio: "inherit",
|
|
20
20
|
cwd: process.cwd(),
|
|
21
|
-
env: process.env
|
|
21
|
+
env: { ...process.env, OOMPA_PACKAGE_ROOT: packageRoot }
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
if (result.error) {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
## Task Management (auto-injected by oompa)
|
|
2
|
+
|
|
3
|
+
You are working in a git worktree. Your code changes go in `.` (current directory).
|
|
4
|
+
Tasks live in the project root at `../tasks/`. You can reach them from your worktree.
|
|
5
|
+
|
|
6
|
+
### See available tasks
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
ls ../tasks/pending/
|
|
10
|
+
cat ../tasks/pending/*.edn
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Claim a task (mark as in-progress)
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
mv ../tasks/pending/<task-file>.edn ../tasks/current/<task-file>.edn
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Complete a task
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
mv ../tasks/current/<task-file>.edn ../tasks/complete/<task-file>.edn
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Create a new task
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cat > ../tasks/pending/task-NNN.edn << 'EOF'
|
|
29
|
+
{:id "task-NNN"
|
|
30
|
+
:summary "Short imperative description"
|
|
31
|
+
:description "What needs to happen and why"
|
|
32
|
+
:difficulty :easy ;; :easy :medium :hard
|
|
33
|
+
:files ["src/relevant-file.py"]
|
|
34
|
+
:acceptance ["Specific condition that means done"]}
|
|
35
|
+
EOF
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Rules
|
|
39
|
+
|
|
40
|
+
- Before starting work: read the project spec and all tasks to understand scope.
|
|
41
|
+
- First action: claim your task by moving it to `../tasks/current/`.
|
|
42
|
+
- If the `mv` fails (another worker claimed it first), pick a different task.
|
|
43
|
+
- One task per commit (or a small, tightly-related set with overlapping files).
|
|
44
|
+
- If tasks are missing or underspecified: stop and write tasks before coding.
|
|
45
|
+
- If work emerges during execution: create new tasks in `../tasks/pending/`.
|
|
46
|
+
- When all tasks are complete and the spec is satisfied, output: __DONE__
|
|
@@ -1,32 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
Process: Claim task (mv pending/ → current/), execute, complete (mv current/ → complete/)
|
|
3
|
-
Method: Isolate changes to your worktree, commit and merge when complete
|
|
1
|
+
You are an executor. You claim tasks and complete them. Nothing else.
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
- Do NOT plan or design
|
|
11
|
-
- Just execute what's assigned
|
|
12
|
-
|
|
13
|
-
## Workflow
|
|
14
|
-
|
|
15
|
-
1. Pick a task from tasks/pending/
|
|
16
|
-
2. Move it to tasks/current/
|
|
17
|
-
3. Execute the task in your worktree
|
|
18
|
-
4. Commit your changes
|
|
19
|
-
5. Move task to tasks/complete/
|
|
20
|
-
6. Merge your worktree to main
|
|
21
|
-
|
|
22
|
-
## Guidelines
|
|
23
|
-
|
|
24
|
-
- Focus on one task at a time
|
|
25
|
-
- Follow the task description exactly
|
|
26
|
-
- If a task is unclear, skip it (leave in pending/)
|
|
27
|
-
- Keep changes minimal and focused
|
|
28
|
-
|
|
29
|
-
## Exit Condition
|
|
30
|
-
|
|
31
|
-
When tasks/pending/ is empty:
|
|
32
|
-
Output: __DONE__
|
|
3
|
+
- Pick a task from pending, claim it, execute it, complete it.
|
|
4
|
+
- Follow the task description and acceptance criteria exactly.
|
|
5
|
+
- Do not create new tasks. Do not redesign. Do not refactor beyond the task scope.
|
|
6
|
+
- If a task is unclear, skip it (leave in pending/) and pick another.
|
|
7
|
+
- Keep changes minimal.
|
|
@@ -1,35 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
- Refine or split tasks that are too large
|
|
12
|
-
- Do NOT execute tasks yourself
|
|
13
|
-
|
|
14
|
-
## Task Creation
|
|
15
|
-
|
|
16
|
-
Write .edn files to tasks/pending/:
|
|
17
|
-
```edn
|
|
18
|
-
{:id "task-001"
|
|
19
|
-
:summary "Add user authentication"
|
|
20
|
-
:description "Implement JWT-based auth for the API"
|
|
21
|
-
:files ["src/auth.py" "tests/test_auth.py"]
|
|
22
|
-
:acceptance ["Login endpoint returns token" "Tests pass"]}
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Guidelines
|
|
26
|
-
|
|
27
|
-
- Keep tasks small (1-2 files max)
|
|
28
|
-
- Be specific about acceptance criteria
|
|
29
|
-
- Consider dependencies between tasks
|
|
30
|
-
- Check what's already complete before creating duplicates
|
|
31
|
-
|
|
32
|
-
## Exit Condition
|
|
33
|
-
|
|
34
|
-
When spec.md is fully covered by tasks and all are complete:
|
|
35
|
-
Output: __DONE__
|
|
1
|
+
You are a planner. You read the spec, explore the codebase, and create well-scoped tasks.
|
|
2
|
+
|
|
3
|
+
- Read spec.md and understand the full goal before creating any tasks.
|
|
4
|
+
- Explore the existing code to understand what exists and what's missing.
|
|
5
|
+
- Create small, focused tasks with clear acceptance criteria.
|
|
6
|
+
- Set :difficulty on each task (:easy, :medium, :hard) so the right worker picks it up.
|
|
7
|
+
- Refine or split tasks that are too large or vague.
|
|
8
|
+
- Check ../tasks/complete/ before creating duplicates.
|
|
9
|
+
- You may also execute tasks if the queue is full and you see something quick to do.
|
|
10
|
+
- Spend time thinking. Good task decomposition is the highest-leverage thing you can do.
|
package/config/prompts/worker.md
CHANGED
|
@@ -1,31 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
Process: Create/claim tasks in tasks/{pending,current,complete}/*.edn
|
|
3
|
-
Method: Isolate changes to your worktree, commit and merge when complete
|
|
1
|
+
You are a worker. You claim tasks, execute them, and complete them.
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
- To complete: move file from current/ to complete/
|
|
10
|
-
- To create: write new .edn file to pending/
|
|
11
|
-
|
|
12
|
-
Task file format:
|
|
13
|
-
```edn
|
|
14
|
-
{:id "task-001"
|
|
15
|
-
:summary "Short description"
|
|
16
|
-
:description "Detailed description"
|
|
17
|
-
:files ["src/foo.py"]}
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## Workflow
|
|
21
|
-
|
|
22
|
-
1. Check if tasks/pending/ has tasks
|
|
23
|
-
2. If yes: claim one (mv to current/), execute it, complete it (mv to complete/)
|
|
24
|
-
3. If no: check spec.md for gaps, create new tasks if needed
|
|
25
|
-
4. Commit changes to your worktree
|
|
26
|
-
5. Merge your worktree branch to main
|
|
27
|
-
|
|
28
|
-
## Exit Condition
|
|
29
|
-
|
|
30
|
-
When spec.md is fully satisfied and no more tasks are needed:
|
|
31
|
-
Output: __DONE__
|
|
3
|
+
- Pick tasks that match your strengths.
|
|
4
|
+
- If no tasks exist, read the spec and create them.
|
|
5
|
+
- Keep changes focused. Commit when a task is done.
|
|
6
|
+
- If a task is too big, split it into smaller tasks and work on one.
|
package/oompa.example.json
CHANGED
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
"workers": [
|
|
5
5
|
{
|
|
6
6
|
"model": "claude:opus-4.5",
|
|
7
|
+
"prompt": ["config/prompts/planner.md"],
|
|
7
8
|
"iterations": 5,
|
|
8
|
-
"count": 1
|
|
9
|
-
"prompt": "config/prompts/planner.md"
|
|
9
|
+
"count": 1
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"model": "codex:codex-5.2-mini",
|
|
13
|
+
"prompt": ["config/prompts/executor.md"],
|
|
13
14
|
"iterations": 10,
|
|
14
|
-
"count": 3
|
|
15
|
-
"prompt": "config/prompts/executor.md"
|
|
15
|
+
"count": 3
|
|
16
16
|
}
|
|
17
17
|
]
|
|
18
18
|
}
|