chiefwiggum 1.0.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/LICENSE +21 -0
- package/README.md +144 -0
- package/chiefwiggum +782 -0
- package/package.json +28 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Addison Kowalski
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Chief Wiggum
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
░█▀▀░█░█░▀█▀░█▀▀░█▀▀░░░█░█░▀█▀░█▀▀░█▀▀░█░█░█▄█
|
|
5
|
+
░█░░░█▀█░░█░░█▀▀░█▀▀░░░█▄█░░█░░█░█░█░█░█░█░█░█
|
|
6
|
+
░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀░░░░░▀░▀░▀▀▀░▀▀▀░▀▀▀░▀▀▀░▀░▀
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Autonomous coding agent CLI. Point it at a plan, watch it build.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx chiefwiggum@latest
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
That's it. Now you can use `chiefwiggum` anywhere.
|
|
18
|
+
|
|
19
|
+
**Requires:** [Claude Code](https://claude.ai/code) installed and authenticated.
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
### Interactive Setup
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cd your-project
|
|
27
|
+
chiefwiggum new
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
You'll be prompted with numbered options:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
How would you like to set up this project?
|
|
34
|
+
|
|
35
|
+
1) From a plan file - I have a plan.md ready
|
|
36
|
+
2) Describe it - I'll tell you what to build
|
|
37
|
+
3) Existing TODO - Just start the loop with current TODO.md
|
|
38
|
+
|
|
39
|
+
Enter choice [1-3]:
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### From a Plan File
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
chiefwiggum new plans/myplan.md
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Generates specs and starts building.
|
|
49
|
+
|
|
50
|
+
### Just Run the Loop
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
chiefwiggum loop
|
|
54
|
+
# or just
|
|
55
|
+
chiefwiggum
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Works through existing TODO.md tasks.
|
|
59
|
+
|
|
60
|
+
### Check Status
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
chiefwiggum status
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Shows project status and task progress.
|
|
67
|
+
|
|
68
|
+
## What It Does
|
|
69
|
+
|
|
70
|
+
1. **Setup** (`chiefwiggum new`)
|
|
71
|
+
- Interactive Q&A or use existing plan
|
|
72
|
+
- Generates: `specs/prd.md`, `specs/technical.md`, `CLAUDE.md`, `TODO.md`
|
|
73
|
+
|
|
74
|
+
2. **Build Loop** (`chiefwiggum loop`)
|
|
75
|
+
- Picks first unchecked task from TODO.md
|
|
76
|
+
- Spawns Claude to implement it
|
|
77
|
+
- Commits changes
|
|
78
|
+
- Repeats until done
|
|
79
|
+
|
|
80
|
+
3. **Guardrails**
|
|
81
|
+
- 3 consecutive failures → stops
|
|
82
|
+
- 5 cycles without commits → stops
|
|
83
|
+
- 60 minute timeout per task
|
|
84
|
+
|
|
85
|
+
## Project Structure
|
|
86
|
+
|
|
87
|
+
After setup:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
your-project/
|
|
91
|
+
├── specs/
|
|
92
|
+
│ ├── prd.md # Product requirements
|
|
93
|
+
│ └── technical.md # Technical specification
|
|
94
|
+
├── CLAUDE.md # Project context for AI
|
|
95
|
+
├── TODO.md # Task list (checkbox format)
|
|
96
|
+
└── plans/
|
|
97
|
+
└── plan.md # Your original plan (if provided)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Configuration
|
|
101
|
+
|
|
102
|
+
Environment variables:
|
|
103
|
+
|
|
104
|
+
| Variable | Default | Description |
|
|
105
|
+
|----------|---------|-------------|
|
|
106
|
+
| `TODO_FILE` | `TODO.md` | Task list file |
|
|
107
|
+
| `ITERATION_TIMEOUT_MINUTES` | `60` | Max time per task |
|
|
108
|
+
| `MAX_CONSECUTIVE_FAILURES` | `3` | Failures before stopping |
|
|
109
|
+
| `MAX_NO_COMMIT_CYCLES` | `5` | Cycles without progress |
|
|
110
|
+
| `COOLDOWN_SECONDS` | `5` | Pause between tasks |
|
|
111
|
+
|
|
112
|
+
## Requirements
|
|
113
|
+
|
|
114
|
+
- [Claude Code CLI](https://claude.ai/code) (authenticated)
|
|
115
|
+
- Git
|
|
116
|
+
- jq
|
|
117
|
+
- tmux (recommended for long builds)
|
|
118
|
+
|
|
119
|
+
## Tips
|
|
120
|
+
|
|
121
|
+
- **Run in tmux**: For long builds, use `tmux` so you can detach
|
|
122
|
+
- **Review specs first**: After `chiefwiggum new`, review generated specs before starting loop
|
|
123
|
+
- **Watch the output**: Claude streams progress so you can see what it's doing
|
|
124
|
+
- **Check commits**: Each task should produce a commit - if not, something's wrong
|
|
125
|
+
|
|
126
|
+
## Troubleshooting
|
|
127
|
+
|
|
128
|
+
**Loop stops with "3 consecutive failures"**
|
|
129
|
+
- Check `/tmp/chiefwiggum-iter*.log` for error details
|
|
130
|
+
- Fix the issue, then run `chiefwiggum` again
|
|
131
|
+
|
|
132
|
+
**Loop stops with "No commits for 5 cycles"**
|
|
133
|
+
- Tasks may be too vague or blocked
|
|
134
|
+
- Review TODO.md and make tasks more specific
|
|
135
|
+
|
|
136
|
+
**`jq: command not found`**
|
|
137
|
+
```bash
|
|
138
|
+
brew install jq # macOS
|
|
139
|
+
sudo apt install jq # Ubuntu
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
MIT
|
package/chiefwiggum
ADDED
|
@@ -0,0 +1,782 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
###########################################
|
|
5
|
+
# ░█▀▀░█░█░▀█▀░█▀▀░█▀▀░░░█░█░▀█▀░█▀▀░█▀▀░█░█░█▄█
|
|
6
|
+
# ░█░░░█▀█░░█░░█▀▀░█▀▀░░░█▄█░░█░░█░█░█░█░█░█░█░█
|
|
7
|
+
# ░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀░░░░░▀░▀░▀▀▀░▀▀▀░▀▀▀░▀▀▀░▀░▀
|
|
8
|
+
#
|
|
9
|
+
# Autonomous coding agent CLI
|
|
10
|
+
###########################################
|
|
11
|
+
|
|
12
|
+
VERSION="1.0.0"
|
|
13
|
+
|
|
14
|
+
# =========================================
|
|
15
|
+
# COLORS
|
|
16
|
+
# =========================================
|
|
17
|
+
GREEN='\033[0;32m'
|
|
18
|
+
YELLOW='\033[1;33m'
|
|
19
|
+
RED='\033[0;31m'
|
|
20
|
+
BLUE='\033[0;34m'
|
|
21
|
+
CYAN='\033[0;36m'
|
|
22
|
+
BOLD='\033[1m'
|
|
23
|
+
NC='\033[0m'
|
|
24
|
+
|
|
25
|
+
# =========================================
|
|
26
|
+
# CONFIGURATION
|
|
27
|
+
# =========================================
|
|
28
|
+
TODO_FILE="${TODO_FILE:-TODO.md}"
|
|
29
|
+
COOLDOWN_SECONDS="${COOLDOWN_SECONDS:-5}"
|
|
30
|
+
|
|
31
|
+
# Guardrails
|
|
32
|
+
ITERATION_TIMEOUT_MINUTES="${ITERATION_TIMEOUT_MINUTES:-60}"
|
|
33
|
+
MAX_CONSECUTIVE_FAILURES="${MAX_CONSECUTIVE_FAILURES:-3}"
|
|
34
|
+
MAX_NO_COMMIT_CYCLES="${MAX_NO_COMMIT_CYCLES:-5}"
|
|
35
|
+
MAX_CLAUDE_ATTEMPTS="${MAX_CLAUDE_ATTEMPTS:-3}"
|
|
36
|
+
|
|
37
|
+
# Claude Code reliability hardening
|
|
38
|
+
export CLAUDE_CODE_EXIT_AFTER_STOP_DELAY="${CLAUDE_CODE_EXIT_AFTER_STOP_DELAY:-30000}"
|
|
39
|
+
export NODE_OPTIONS="--unhandled-rejections=strict${NODE_OPTIONS:+ $NODE_OPTIONS}"
|
|
40
|
+
|
|
41
|
+
# =========================================
|
|
42
|
+
# BANNER
|
|
43
|
+
# =========================================
|
|
44
|
+
show_banner() {
|
|
45
|
+
echo ""
|
|
46
|
+
echo -e "${CYAN}░█▀▀░█░█░▀█▀░█▀▀░█▀▀░░░█░█░▀█▀░█▀▀░█▀▀░█░█░█▄█${NC}"
|
|
47
|
+
echo -e "${CYAN}░█░░░█▀█░░█░░█▀▀░█▀▀░░░█▄█░░█░░█░█░█░█░█░█░█░█${NC}"
|
|
48
|
+
echo -e "${CYAN}░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀░░░░░▀░▀░▀▀▀░▀▀▀░▀▀▀░▀▀▀░▀░▀${NC}"
|
|
49
|
+
echo -e "${BLUE} Autonomous Coding Agent v${VERSION}${NC}"
|
|
50
|
+
echo ""
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# =========================================
|
|
54
|
+
# HELP
|
|
55
|
+
# =========================================
|
|
56
|
+
show_help() {
|
|
57
|
+
show_banner
|
|
58
|
+
echo "Usage: chiefwiggum [command] [options]"
|
|
59
|
+
echo ""
|
|
60
|
+
echo "Commands:"
|
|
61
|
+
echo " new [plan.md] Initialize project (interactive or from plan file)"
|
|
62
|
+
echo " loop Run the build loop on existing TODO.md"
|
|
63
|
+
echo " status Show current project status"
|
|
64
|
+
echo " help Show this help message"
|
|
65
|
+
echo ""
|
|
66
|
+
echo "Examples:"
|
|
67
|
+
echo " chiefwiggum new # Interactive setup"
|
|
68
|
+
echo " chiefwiggum new plans/myplan.md # Setup from plan file"
|
|
69
|
+
echo " chiefwiggum loop # Start build loop"
|
|
70
|
+
echo " chiefwiggum # Same as 'loop'"
|
|
71
|
+
echo ""
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# =========================================
|
|
75
|
+
# PROMPT HELPERS
|
|
76
|
+
# =========================================
|
|
77
|
+
ask_choice() {
|
|
78
|
+
local prompt="$1"
|
|
79
|
+
shift
|
|
80
|
+
local options=("$@")
|
|
81
|
+
|
|
82
|
+
echo ""
|
|
83
|
+
echo -e "${BOLD}${prompt}${NC}"
|
|
84
|
+
echo ""
|
|
85
|
+
|
|
86
|
+
local i=1
|
|
87
|
+
for opt in "${options[@]}"; do
|
|
88
|
+
echo -e " ${CYAN}${i})${NC} ${opt}"
|
|
89
|
+
((i++))
|
|
90
|
+
done
|
|
91
|
+
echo ""
|
|
92
|
+
|
|
93
|
+
while true; do
|
|
94
|
+
read -rp "Enter choice [1-${#options[@]}]: " choice
|
|
95
|
+
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "${#options[@]}" ]; then
|
|
96
|
+
return $((choice - 1))
|
|
97
|
+
fi
|
|
98
|
+
echo -e "${RED}Invalid choice. Please enter 1-${#options[@]}${NC}"
|
|
99
|
+
done
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
ask_text() {
|
|
103
|
+
local prompt="$1"
|
|
104
|
+
local default="${2:-}"
|
|
105
|
+
|
|
106
|
+
echo ""
|
|
107
|
+
if [ -n "$default" ]; then
|
|
108
|
+
read -rp "${prompt} [${default}]: " response
|
|
109
|
+
echo "${response:-$default}"
|
|
110
|
+
else
|
|
111
|
+
read -rp "${prompt}: " response
|
|
112
|
+
echo "$response"
|
|
113
|
+
fi
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
ask_confirm() {
|
|
117
|
+
local prompt="$1"
|
|
118
|
+
local default="${2:-y}"
|
|
119
|
+
|
|
120
|
+
if [ "$default" = "y" ]; then
|
|
121
|
+
read -rp "${prompt} [Y/n]: " response
|
|
122
|
+
[[ ! "$response" =~ ^[Nn] ]]
|
|
123
|
+
else
|
|
124
|
+
read -rp "${prompt} [y/N]: " response
|
|
125
|
+
[[ "$response" =~ ^[Yy] ]]
|
|
126
|
+
fi
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
# =========================================
|
|
130
|
+
# STATUS COMMAND
|
|
131
|
+
# =========================================
|
|
132
|
+
cmd_status() {
|
|
133
|
+
show_banner
|
|
134
|
+
|
|
135
|
+
echo -e "${BOLD}Project Status${NC}"
|
|
136
|
+
echo ""
|
|
137
|
+
|
|
138
|
+
# Check for key files
|
|
139
|
+
local has_todo=false
|
|
140
|
+
local has_specs=false
|
|
141
|
+
local has_claude_md=false
|
|
142
|
+
|
|
143
|
+
[ -f "$TODO_FILE" ] && has_todo=true
|
|
144
|
+
[ -d "specs" ] && has_specs=true
|
|
145
|
+
[ -f "CLAUDE.md" ] && has_claude_md=true
|
|
146
|
+
|
|
147
|
+
echo -e " TODO.md: $([ "$has_todo" = true ] && echo -e "${GREEN}✓${NC}" || echo -e "${RED}✗${NC}")"
|
|
148
|
+
echo -e " specs/: $([ "$has_specs" = true ] && echo -e "${GREEN}✓${NC}" || echo -e "${RED}✗${NC}")"
|
|
149
|
+
echo -e " CLAUDE.md: $([ "$has_claude_md" = true ] && echo -e "${GREEN}✓${NC}" || echo -e "${RED}✗${NC}")"
|
|
150
|
+
echo ""
|
|
151
|
+
|
|
152
|
+
if [ "$has_todo" = true ]; then
|
|
153
|
+
local total=$(grep -c "^\s*- \[" "$TODO_FILE" 2>/dev/null || echo "0")
|
|
154
|
+
local done=$(grep -c "^\s*- \[x\]" "$TODO_FILE" 2>/dev/null || echo "0")
|
|
155
|
+
local remaining=$((total - done))
|
|
156
|
+
|
|
157
|
+
echo -e "${BOLD}Tasks${NC}"
|
|
158
|
+
echo -e " Total: ${total}"
|
|
159
|
+
echo -e " Completed: ${GREEN}${done}${NC}"
|
|
160
|
+
echo -e " Remaining: ${YELLOW}${remaining}${NC}"
|
|
161
|
+
echo ""
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
# Git status
|
|
165
|
+
if git rev-parse --git-dir &>/dev/null; then
|
|
166
|
+
local branch=$(git branch --show-current 2>/dev/null || echo "unknown")
|
|
167
|
+
local commits=$(git rev-list --count HEAD 2>/dev/null || echo "0")
|
|
168
|
+
echo -e "${BOLD}Git${NC}"
|
|
169
|
+
echo -e " Branch: ${branch}"
|
|
170
|
+
echo -e " Commits: ${commits}"
|
|
171
|
+
fi
|
|
172
|
+
echo ""
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
# =========================================
|
|
176
|
+
# NEW COMMAND - INTERACTIVE SETUP
|
|
177
|
+
# =========================================
|
|
178
|
+
cmd_new() {
|
|
179
|
+
local plan_file="${1:-}"
|
|
180
|
+
|
|
181
|
+
show_banner
|
|
182
|
+
|
|
183
|
+
echo -e "${BOLD}Project Setup${NC}"
|
|
184
|
+
echo ""
|
|
185
|
+
|
|
186
|
+
# Show current directory
|
|
187
|
+
echo -e "Working directory: ${CYAN}$(pwd)${NC}"
|
|
188
|
+
echo ""
|
|
189
|
+
|
|
190
|
+
if ! ask_confirm "Initialize Chief Wiggum in this directory?"; then
|
|
191
|
+
echo -e "${YELLOW}Aborted.${NC}"
|
|
192
|
+
exit 0
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
# Check for existing files
|
|
196
|
+
local existing_files=()
|
|
197
|
+
[ -f "$TODO_FILE" ] && existing_files+=("TODO.md")
|
|
198
|
+
[ -d "specs" ] && existing_files+=("specs/")
|
|
199
|
+
[ -f "CLAUDE.md" ] && existing_files+=("CLAUDE.md")
|
|
200
|
+
|
|
201
|
+
if [ ${#existing_files[@]} -gt 0 ]; then
|
|
202
|
+
echo ""
|
|
203
|
+
echo -e "${YELLOW}Existing files found:${NC}"
|
|
204
|
+
for f in "${existing_files[@]}"; do
|
|
205
|
+
echo " - $f"
|
|
206
|
+
done
|
|
207
|
+
echo ""
|
|
208
|
+
if ! ask_confirm "Overwrite these files?" "n"; then
|
|
209
|
+
echo -e "${YELLOW}Aborted.${NC}"
|
|
210
|
+
exit 0
|
|
211
|
+
fi
|
|
212
|
+
fi
|
|
213
|
+
|
|
214
|
+
# If plan file provided, use it directly
|
|
215
|
+
if [ -n "$plan_file" ]; then
|
|
216
|
+
if [ ! -f "$plan_file" ]; then
|
|
217
|
+
echo -e "${RED}Plan file not found: ${plan_file}${NC}"
|
|
218
|
+
exit 1
|
|
219
|
+
fi
|
|
220
|
+
generate_from_plan "$plan_file"
|
|
221
|
+
start_loop
|
|
222
|
+
return
|
|
223
|
+
fi
|
|
224
|
+
|
|
225
|
+
# Interactive setup
|
|
226
|
+
ask_choice "How would you like to set up this project?" \
|
|
227
|
+
"From a plan file - I have a plan.md ready" \
|
|
228
|
+
"Describe it - I'll tell you what to build" \
|
|
229
|
+
"Existing TODO - Just start the loop with current TODO.md"
|
|
230
|
+
local setup_choice=$?
|
|
231
|
+
|
|
232
|
+
case $setup_choice in
|
|
233
|
+
0)
|
|
234
|
+
# From plan file
|
|
235
|
+
local plan_path
|
|
236
|
+
plan_path=$(ask_text "Path to plan file" "plans/plan.md")
|
|
237
|
+
if [ ! -f "$plan_path" ]; then
|
|
238
|
+
echo -e "${RED}Plan file not found: ${plan_path}${NC}"
|
|
239
|
+
exit 1
|
|
240
|
+
fi
|
|
241
|
+
generate_from_plan "$plan_path"
|
|
242
|
+
;;
|
|
243
|
+
1)
|
|
244
|
+
# Describe project
|
|
245
|
+
interactive_describe
|
|
246
|
+
;;
|
|
247
|
+
2)
|
|
248
|
+
# Existing TODO
|
|
249
|
+
if [ ! -f "$TODO_FILE" ]; then
|
|
250
|
+
echo -e "${RED}No TODO.md found. Run 'chiefwiggum new' to set up first.${NC}"
|
|
251
|
+
exit 1
|
|
252
|
+
fi
|
|
253
|
+
;;
|
|
254
|
+
esac
|
|
255
|
+
|
|
256
|
+
# Ask about starting the loop
|
|
257
|
+
echo ""
|
|
258
|
+
ask_choice "Ready to start. What would you like to do?" \
|
|
259
|
+
"Start the build loop now" \
|
|
260
|
+
"Review files first, then start manually with 'chiefwiggum loop'" \
|
|
261
|
+
"Exit"
|
|
262
|
+
local start_choice=$?
|
|
263
|
+
|
|
264
|
+
case $start_choice in
|
|
265
|
+
0) start_loop ;;
|
|
266
|
+
1)
|
|
267
|
+
echo ""
|
|
268
|
+
echo -e "${GREEN}Setup complete!${NC} Review your files, then run:"
|
|
269
|
+
echo -e " ${CYAN}chiefwiggum loop${NC}"
|
|
270
|
+
;;
|
|
271
|
+
2)
|
|
272
|
+
echo -e "${YELLOW}Exiting.${NC}"
|
|
273
|
+
;;
|
|
274
|
+
esac
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
# =========================================
|
|
278
|
+
# INTERACTIVE PROJECT DESCRIPTION
|
|
279
|
+
# =========================================
|
|
280
|
+
interactive_describe() {
|
|
281
|
+
echo ""
|
|
282
|
+
echo -e "${BOLD}Tell me about your project${NC}"
|
|
283
|
+
echo ""
|
|
284
|
+
|
|
285
|
+
# Project name
|
|
286
|
+
local project_name
|
|
287
|
+
project_name=$(ask_text "Project name")
|
|
288
|
+
|
|
289
|
+
# Project type
|
|
290
|
+
ask_choice "What type of project is this?" \
|
|
291
|
+
"Web application (Next.js, React, etc.)" \
|
|
292
|
+
"API / Backend service" \
|
|
293
|
+
"CLI tool" \
|
|
294
|
+
"Library / Package" \
|
|
295
|
+
"Mobile app" \
|
|
296
|
+
"Other"
|
|
297
|
+
local project_type=$?
|
|
298
|
+
local project_type_names=("web" "api" "cli" "library" "mobile" "other")
|
|
299
|
+
local project_type_name="${project_type_names[$project_type]}"
|
|
300
|
+
|
|
301
|
+
# Tech stack
|
|
302
|
+
local tech_stack
|
|
303
|
+
tech_stack=$(ask_text "Tech stack (e.g., Next.js, TypeScript, Convex)")
|
|
304
|
+
|
|
305
|
+
# Description
|
|
306
|
+
echo ""
|
|
307
|
+
echo -e "${BOLD}Describe what you're building:${NC}"
|
|
308
|
+
echo "(Enter description, then press Enter twice to finish)"
|
|
309
|
+
echo ""
|
|
310
|
+
local description=""
|
|
311
|
+
local empty_lines=0
|
|
312
|
+
while IFS= read -r line; do
|
|
313
|
+
if [ -z "$line" ]; then
|
|
314
|
+
((empty_lines++))
|
|
315
|
+
[ $empty_lines -ge 1 ] && break
|
|
316
|
+
else
|
|
317
|
+
empty_lines=0
|
|
318
|
+
fi
|
|
319
|
+
description+="$line"$'\n'
|
|
320
|
+
done
|
|
321
|
+
|
|
322
|
+
# Key features
|
|
323
|
+
echo ""
|
|
324
|
+
echo -e "${BOLD}List key features (one per line, empty line to finish):${NC}"
|
|
325
|
+
local features=""
|
|
326
|
+
while IFS= read -r line; do
|
|
327
|
+
[ -z "$line" ] && break
|
|
328
|
+
features+="- $line"$'\n'
|
|
329
|
+
done
|
|
330
|
+
|
|
331
|
+
# Generate plan content
|
|
332
|
+
local plan_content="# ${project_name}
|
|
333
|
+
|
|
334
|
+
## Overview
|
|
335
|
+
${description}
|
|
336
|
+
|
|
337
|
+
## Project Type
|
|
338
|
+
${project_type_name}
|
|
339
|
+
|
|
340
|
+
## Tech Stack
|
|
341
|
+
${tech_stack}
|
|
342
|
+
|
|
343
|
+
## Key Features
|
|
344
|
+
${features}
|
|
345
|
+
"
|
|
346
|
+
|
|
347
|
+
# Save plan
|
|
348
|
+
mkdir -p plans
|
|
349
|
+
local plan_file="plans/plan.md"
|
|
350
|
+
echo "$plan_content" > "$plan_file"
|
|
351
|
+
echo ""
|
|
352
|
+
echo -e "${GREEN}Plan saved to ${plan_file}${NC}"
|
|
353
|
+
|
|
354
|
+
# Generate specs from plan
|
|
355
|
+
generate_from_plan "$plan_file"
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
# =========================================
|
|
359
|
+
# GENERATE SPECS FROM PLAN
|
|
360
|
+
# =========================================
|
|
361
|
+
generate_from_plan() {
|
|
362
|
+
local plan_file="$1"
|
|
363
|
+
local plan_content
|
|
364
|
+
plan_content="$(cat "$plan_file")"
|
|
365
|
+
|
|
366
|
+
echo ""
|
|
367
|
+
echo -e "${GREEN}════════════════════════════════════════${NC}"
|
|
368
|
+
echo -e "${GREEN} Generating specs from: ${plan_file}${NC}"
|
|
369
|
+
echo -e "${GREEN}════════════════════════════════════════${NC}"
|
|
370
|
+
|
|
371
|
+
mkdir -p specs
|
|
372
|
+
|
|
373
|
+
# Step 1: Generate PRD
|
|
374
|
+
echo ""
|
|
375
|
+
echo -e "${YELLOW}[1/4] Generating specs/prd.md...${NC}"
|
|
376
|
+
|
|
377
|
+
local prd_prompt="You are generating a PRD (Product Requirements Document) from a project plan.
|
|
378
|
+
|
|
379
|
+
Here is the plan:
|
|
380
|
+
<plan>
|
|
381
|
+
${plan_content}
|
|
382
|
+
</plan>
|
|
383
|
+
|
|
384
|
+
Generate a complete PRD with these sections:
|
|
385
|
+
- Overview
|
|
386
|
+
- Problem Statement
|
|
387
|
+
- Goals & Success Metrics
|
|
388
|
+
- User Stories
|
|
389
|
+
- Functional Requirements
|
|
390
|
+
- Non-Functional Requirements
|
|
391
|
+
- Out of Scope
|
|
392
|
+
|
|
393
|
+
Write it directly to specs/prd.md.
|
|
394
|
+
Do NOT ask questions — infer everything from the plan.
|
|
395
|
+
Be concise but comprehensive."
|
|
396
|
+
|
|
397
|
+
echo "$prd_prompt" | claude -p --dangerously-skip-permissions 2>/dev/null
|
|
398
|
+
echo -e "${GREEN} ✓ specs/prd.md${NC}"
|
|
399
|
+
|
|
400
|
+
# Step 2: Generate Technical Spec
|
|
401
|
+
echo ""
|
|
402
|
+
echo -e "${YELLOW}[2/4] Generating specs/technical.md...${NC}"
|
|
403
|
+
local prd_generated
|
|
404
|
+
prd_generated="$(cat specs/prd.md 2>/dev/null || echo "")"
|
|
405
|
+
|
|
406
|
+
local tech_prompt="You are generating a Technical Specification from a PRD.
|
|
407
|
+
|
|
408
|
+
Here is the PRD:
|
|
409
|
+
<prd>
|
|
410
|
+
${prd_generated}
|
|
411
|
+
</prd>
|
|
412
|
+
|
|
413
|
+
Generate a complete Technical Specification with:
|
|
414
|
+
- Architecture Overview
|
|
415
|
+
- Tech Stack
|
|
416
|
+
- Data Model
|
|
417
|
+
- API Design (if applicable)
|
|
418
|
+
- Key Components
|
|
419
|
+
- Security Considerations
|
|
420
|
+
- Performance Considerations
|
|
421
|
+
|
|
422
|
+
Write it directly to specs/technical.md.
|
|
423
|
+
Do NOT ask questions — infer everything from the PRD."
|
|
424
|
+
|
|
425
|
+
echo "$tech_prompt" | claude -p --dangerously-skip-permissions 2>/dev/null
|
|
426
|
+
echo -e "${GREEN} ✓ specs/technical.md${NC}"
|
|
427
|
+
|
|
428
|
+
# Step 3: Generate CLAUDE.md
|
|
429
|
+
echo ""
|
|
430
|
+
echo -e "${YELLOW}[3/4] Generating CLAUDE.md...${NC}"
|
|
431
|
+
|
|
432
|
+
local claude_prompt="You are generating a CLAUDE.md file for a project.
|
|
433
|
+
|
|
434
|
+
Here is the PRD:
|
|
435
|
+
<prd>
|
|
436
|
+
${prd_generated}
|
|
437
|
+
</prd>
|
|
438
|
+
|
|
439
|
+
Here is the Technical Spec:
|
|
440
|
+
<technical>
|
|
441
|
+
$(cat specs/technical.md 2>/dev/null || echo "")
|
|
442
|
+
</technical>
|
|
443
|
+
|
|
444
|
+
Generate a CLAUDE.md with:
|
|
445
|
+
- Brief project overview
|
|
446
|
+
- Key commands to run
|
|
447
|
+
- Architecture summary
|
|
448
|
+
- Important conventions
|
|
449
|
+
- Empty '## Learnings' section at the bottom
|
|
450
|
+
|
|
451
|
+
Write it directly to CLAUDE.md.
|
|
452
|
+
Keep it concise - this is a quick reference for AI agents."
|
|
453
|
+
|
|
454
|
+
echo "$claude_prompt" | claude -p --dangerously-skip-permissions 2>/dev/null
|
|
455
|
+
echo -e "${GREEN} ✓ CLAUDE.md${NC}"
|
|
456
|
+
|
|
457
|
+
# Step 4: Generate TODO
|
|
458
|
+
echo ""
|
|
459
|
+
echo -e "${YELLOW}[4/4] Generating TODO.md...${NC}"
|
|
460
|
+
|
|
461
|
+
local todo_prompt="You are generating a TODO task list from a PRD and Technical Specification.
|
|
462
|
+
|
|
463
|
+
Here is the PRD:
|
|
464
|
+
<prd>
|
|
465
|
+
${prd_generated}
|
|
466
|
+
</prd>
|
|
467
|
+
|
|
468
|
+
Here is the Technical Specification:
|
|
469
|
+
<technical>
|
|
470
|
+
$(cat specs/technical.md 2>/dev/null || echo "")
|
|
471
|
+
</technical>
|
|
472
|
+
|
|
473
|
+
Generate a phased TODO.md with:
|
|
474
|
+
- Logical phases (Setup, Core Features, Polish, etc.)
|
|
475
|
+
- Granular tasks using checkbox format: - [ ] Task description
|
|
476
|
+
- Each phase ends with: - [ ] Phase review
|
|
477
|
+
- Tasks should be completable in 1-2 hours max
|
|
478
|
+
|
|
479
|
+
Write it directly to TODO.md.
|
|
480
|
+
Do NOT ask questions — infer everything from the specs."
|
|
481
|
+
|
|
482
|
+
echo "$todo_prompt" | claude -p --dangerously-skip-permissions 2>/dev/null
|
|
483
|
+
echo -e "${GREEN} ✓ TODO.md${NC}"
|
|
484
|
+
|
|
485
|
+
echo ""
|
|
486
|
+
echo -e "${GREEN}Specs generated:${NC}"
|
|
487
|
+
echo " - specs/prd.md"
|
|
488
|
+
echo " - specs/technical.md"
|
|
489
|
+
echo " - CLAUDE.md"
|
|
490
|
+
echo " - TODO.md"
|
|
491
|
+
|
|
492
|
+
# Commit specs
|
|
493
|
+
if git rev-parse --git-dir &>/dev/null; then
|
|
494
|
+
git add specs/ TODO.md CLAUDE.md 2>/dev/null || true
|
|
495
|
+
git commit -m "chore: generate specs from plan" 2>/dev/null || true
|
|
496
|
+
fi
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
# =========================================
|
|
500
|
+
# BUILD LOOP
|
|
501
|
+
# =========================================
|
|
502
|
+
start_loop() {
|
|
503
|
+
[ -f "$TODO_FILE" ] || { echo -e "${RED}Missing $TODO_FILE${NC}"; exit 1; }
|
|
504
|
+
|
|
505
|
+
local max_iterations
|
|
506
|
+
max_iterations=$(grep -c "\[ \]" "$TODO_FILE" 2>/dev/null) || max_iterations=0
|
|
507
|
+
|
|
508
|
+
if [ "$max_iterations" -eq 0 ]; then
|
|
509
|
+
echo -e "${GREEN}No unchecked tasks in $TODO_FILE. All done!${NC}"
|
|
510
|
+
exit 0
|
|
511
|
+
fi
|
|
512
|
+
|
|
513
|
+
echo ""
|
|
514
|
+
echo -e "${GREEN}════════════════════════════════════════${NC}"
|
|
515
|
+
echo -e "${GREEN} Starting Build Loop${NC}"
|
|
516
|
+
echo -e "${GREEN} Tasks remaining: ${max_iterations}${NC}"
|
|
517
|
+
echo -e "${GREEN} Timeout: ${ITERATION_TIMEOUT_MINUTES}m per task${NC}"
|
|
518
|
+
echo -e "${GREEN}════════════════════════════════════════${NC}"
|
|
519
|
+
|
|
520
|
+
local consecutive_failures=0
|
|
521
|
+
local no_commit_cycles=0
|
|
522
|
+
local last_commit
|
|
523
|
+
last_commit="$(git rev-parse HEAD 2>/dev/null || echo "none")"
|
|
524
|
+
|
|
525
|
+
for i in $(seq 1 "$max_iterations"); do
|
|
526
|
+
echo ""
|
|
527
|
+
echo -e "${YELLOW}══════════ Task $i of $max_iterations ══════════${NC}"
|
|
528
|
+
|
|
529
|
+
cleanup_stale_processes
|
|
530
|
+
|
|
531
|
+
local start_time
|
|
532
|
+
start_time="$(date +%s)"
|
|
533
|
+
|
|
534
|
+
set +e
|
|
535
|
+
run_task_iteration "$i"
|
|
536
|
+
local claude_exit=$?
|
|
537
|
+
set -e
|
|
538
|
+
|
|
539
|
+
local duration=$(($(date +%s) - start_time))
|
|
540
|
+
echo ""
|
|
541
|
+
echo -e "Completed in ${duration}s (exit: ${claude_exit})"
|
|
542
|
+
|
|
543
|
+
# Track failures
|
|
544
|
+
if [ "$claude_exit" -ne 0 ]; then
|
|
545
|
+
consecutive_failures=$((consecutive_failures + 1))
|
|
546
|
+
echo -e "${RED}Failure ${consecutive_failures}/${MAX_CONSECUTIVE_FAILURES}${NC}"
|
|
547
|
+
sleep 30
|
|
548
|
+
else
|
|
549
|
+
consecutive_failures=0
|
|
550
|
+
fi
|
|
551
|
+
|
|
552
|
+
# Track commits
|
|
553
|
+
local current_commit
|
|
554
|
+
current_commit="$(git rev-parse HEAD 2>/dev/null || echo "none")"
|
|
555
|
+
if [ "$current_commit" = "$last_commit" ]; then
|
|
556
|
+
if [ "$claude_exit" -eq 0 ]; then
|
|
557
|
+
no_commit_cycles=$((no_commit_cycles + 1))
|
|
558
|
+
echo -e "${YELLOW}No commit (${no_commit_cycles}/${MAX_NO_COMMIT_CYCLES})${NC}"
|
|
559
|
+
fi
|
|
560
|
+
else
|
|
561
|
+
no_commit_cycles=0
|
|
562
|
+
last_commit="$current_commit"
|
|
563
|
+
echo -e "${GREEN}New commit: ${current_commit:0:7}${NC}"
|
|
564
|
+
git push origin HEAD 2>/dev/null && echo "Pushed to origin" || true
|
|
565
|
+
fi
|
|
566
|
+
|
|
567
|
+
# Guardrails
|
|
568
|
+
if [ "$consecutive_failures" -ge "$MAX_CONSECUTIVE_FAILURES" ]; then
|
|
569
|
+
echo -e "${RED}Stopping: ${MAX_CONSECUTIVE_FAILURES} consecutive failures${NC}"
|
|
570
|
+
exit 1
|
|
571
|
+
fi
|
|
572
|
+
|
|
573
|
+
if [ "$no_commit_cycles" -ge "$MAX_NO_COMMIT_CYCLES" ]; then
|
|
574
|
+
echo -e "${RED}Stopping: No commits for ${MAX_NO_COMMIT_CYCLES} cycles${NC}"
|
|
575
|
+
exit 1
|
|
576
|
+
fi
|
|
577
|
+
|
|
578
|
+
# Check if done
|
|
579
|
+
if ! grep -q "\[ \]" "$TODO_FILE"; then
|
|
580
|
+
echo ""
|
|
581
|
+
echo -e "${GREEN}════════════════════════════════════════${NC}"
|
|
582
|
+
echo -e "${GREEN} All tasks completed!${NC}"
|
|
583
|
+
echo -e "${GREEN}════════════════════════════════════════${NC}"
|
|
584
|
+
git push origin HEAD 2>/dev/null || true
|
|
585
|
+
exit 0
|
|
586
|
+
fi
|
|
587
|
+
|
|
588
|
+
sleep "$COOLDOWN_SECONDS"
|
|
589
|
+
done
|
|
590
|
+
|
|
591
|
+
echo -e "${YELLOW}Reached max iterations (${max_iterations})${NC}"
|
|
592
|
+
git push origin HEAD 2>/dev/null || true
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
run_task_iteration() {
|
|
596
|
+
local iteration="$1"
|
|
597
|
+
local log_file="/tmp/chiefwiggum-iter${iteration}.log"
|
|
598
|
+
|
|
599
|
+
local task_prompt='You are an autonomous coding agent. Complete ONE task from TODO.md.
|
|
600
|
+
|
|
601
|
+
## Before Starting
|
|
602
|
+
Read these files to understand the project:
|
|
603
|
+
- CLAUDE.md — Project context and conventions
|
|
604
|
+
- specs/prd.md — What we are building
|
|
605
|
+
- specs/technical.md — How we are building it
|
|
606
|
+
- TODO.md — Task list
|
|
607
|
+
|
|
608
|
+
## Workflow
|
|
609
|
+
1. Find the FIRST unchecked task (- [ ]) in TODO.md
|
|
610
|
+
2. Plan: Understand what needs to be done
|
|
611
|
+
3. Implement: Write the code
|
|
612
|
+
4. Review: Verify it works
|
|
613
|
+
5. Mark complete: Change - [ ] to - [x] in TODO.md
|
|
614
|
+
6. Commit: git add . && git commit -m "type(scope): description"
|
|
615
|
+
|
|
616
|
+
## Rules
|
|
617
|
+
- ONE task per iteration
|
|
618
|
+
- Follow existing code patterns
|
|
619
|
+
- Use conventional commits (feat, fix, docs, refactor, test, chore)
|
|
620
|
+
- If blocked after 3 attempts, output RALPH_BLOCKED: <reason>
|
|
621
|
+
|
|
622
|
+
## When Done
|
|
623
|
+
Output: RALPH_COMPLETE
|
|
624
|
+
If no tasks remain: RALPH_ALL_DONE'
|
|
625
|
+
|
|
626
|
+
local claude_exit=1
|
|
627
|
+
|
|
628
|
+
for attempt in $(seq 1 "$MAX_CLAUDE_ATTEMPTS"); do
|
|
629
|
+
echo -e "${YELLOW}Attempt ${attempt}/${MAX_CLAUDE_ATTEMPTS}${NC}"
|
|
630
|
+
|
|
631
|
+
echo "$task_prompt" \
|
|
632
|
+
| timeout --kill-after=10s "${ITERATION_TIMEOUT_MINUTES}m" \
|
|
633
|
+
claude -p --dangerously-skip-permissions --no-session-persistence \
|
|
634
|
+
--verbose --output-format stream-json \
|
|
635
|
+
2>&1 \
|
|
636
|
+
| tee "$log_file" \
|
|
637
|
+
| jq -r '
|
|
638
|
+
if .type == "assistant" then
|
|
639
|
+
(.message.content[]? | select(.type=="text") | .text? // empty),
|
|
640
|
+
(.message.content[]? | select(.type=="tool_use") | "🔧 " + .name)
|
|
641
|
+
elif .type == "result" then
|
|
642
|
+
"✅ " + (.subtype // "done")
|
|
643
|
+
else empty end
|
|
644
|
+
' 2>/dev/null || true &
|
|
645
|
+
local claude_pid=$!
|
|
646
|
+
|
|
647
|
+
# Monitor for freeze
|
|
648
|
+
while kill -0 $claude_pid 2>/dev/null; do
|
|
649
|
+
if grep -q "No messages returned" "$log_file" 2>/dev/null; then
|
|
650
|
+
echo -e "${RED}Freeze detected, killing...${NC}"
|
|
651
|
+
kill -9 $claude_pid 2>/dev/null || true
|
|
652
|
+
sleep 2
|
|
653
|
+
break
|
|
654
|
+
fi
|
|
655
|
+
sleep 1
|
|
656
|
+
done
|
|
657
|
+
|
|
658
|
+
wait $claude_pid 2>/dev/null
|
|
659
|
+
claude_exit=$?
|
|
660
|
+
|
|
661
|
+
# Check for transient errors
|
|
662
|
+
if [ "$claude_exit" -ne 0 ]; then
|
|
663
|
+
if grep -qE "(No messages returned|ECONNRESET|ETIMEDOUT)" "$log_file" 2>/dev/null; then
|
|
664
|
+
echo -e "${YELLOW}Transient error, retrying...${NC}"
|
|
665
|
+
sleep $((attempt * 5))
|
|
666
|
+
continue
|
|
667
|
+
fi
|
|
668
|
+
fi
|
|
669
|
+
|
|
670
|
+
break
|
|
671
|
+
done
|
|
672
|
+
|
|
673
|
+
rm -f "$log_file"
|
|
674
|
+
return $claude_exit
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
cleanup_stale_processes() {
|
|
678
|
+
pkill -f playwright 2>/dev/null || true
|
|
679
|
+
pkill -f chromium 2>/dev/null || true
|
|
680
|
+
if command -v lsof &>/dev/null; then
|
|
681
|
+
lsof -ti:3000 | xargs kill -9 2>/dev/null || true
|
|
682
|
+
fi
|
|
683
|
+
sleep 1
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
# =========================================
|
|
687
|
+
# INSTALL COMMAND
|
|
688
|
+
# =========================================
|
|
689
|
+
cmd_install() {
|
|
690
|
+
show_banner
|
|
691
|
+
|
|
692
|
+
echo -e "${BOLD}Installing Chief Wiggum...${NC}"
|
|
693
|
+
echo ""
|
|
694
|
+
|
|
695
|
+
# Check if already installed globally
|
|
696
|
+
if command -v chiefwiggum &>/dev/null; then
|
|
697
|
+
local installed_path=$(which chiefwiggum)
|
|
698
|
+
if [[ "$installed_path" != *"npx"* ]] && [[ "$installed_path" != *".npm/_npx"* ]]; then
|
|
699
|
+
echo -e "${GREEN}✓ Already installed at: ${installed_path}${NC}"
|
|
700
|
+
echo ""
|
|
701
|
+
echo "Run 'chiefwiggum new' to get started."
|
|
702
|
+
return 0
|
|
703
|
+
fi
|
|
704
|
+
fi
|
|
705
|
+
|
|
706
|
+
# Install globally
|
|
707
|
+
echo "Running: npm install -g chiefwiggum"
|
|
708
|
+
echo ""
|
|
709
|
+
|
|
710
|
+
if npm install -g chiefwiggum; then
|
|
711
|
+
echo ""
|
|
712
|
+
echo -e "${GREEN}════════════════════════════════════════${NC}"
|
|
713
|
+
echo -e "${GREEN} ✓ Installation complete!${NC}"
|
|
714
|
+
echo -e "${GREEN}════════════════════════════════════════${NC}"
|
|
715
|
+
echo ""
|
|
716
|
+
echo "Get started:"
|
|
717
|
+
echo -e " ${CYAN}chiefwiggum new${NC} # Set up a new project"
|
|
718
|
+
echo -e " ${CYAN}chiefwiggum loop${NC} # Run the build loop"
|
|
719
|
+
echo -e " ${CYAN}chiefwiggum help${NC} # See all commands"
|
|
720
|
+
echo ""
|
|
721
|
+
else
|
|
722
|
+
echo ""
|
|
723
|
+
echo -e "${RED}Installation failed.${NC}"
|
|
724
|
+
echo "Try running with sudo: sudo npm install -g chiefwiggum"
|
|
725
|
+
exit 1
|
|
726
|
+
fi
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
# =========================================
|
|
730
|
+
# MAIN
|
|
731
|
+
# =========================================
|
|
732
|
+
main() {
|
|
733
|
+
local cmd="${1:-}"
|
|
734
|
+
|
|
735
|
+
case "$cmd" in
|
|
736
|
+
install)
|
|
737
|
+
cmd_install
|
|
738
|
+
;;
|
|
739
|
+
new)
|
|
740
|
+
shift
|
|
741
|
+
cmd_new "$@"
|
|
742
|
+
;;
|
|
743
|
+
loop)
|
|
744
|
+
show_banner
|
|
745
|
+
start_loop
|
|
746
|
+
;;
|
|
747
|
+
status)
|
|
748
|
+
cmd_status
|
|
749
|
+
;;
|
|
750
|
+
help|--help|-h)
|
|
751
|
+
show_help
|
|
752
|
+
;;
|
|
753
|
+
"")
|
|
754
|
+
# No command: if running via npx, install. Otherwise run loop.
|
|
755
|
+
if [[ "${0}" == *"npx"* ]] || [[ "${0}" == *".npm/_npx"* ]]; then
|
|
756
|
+
cmd_install
|
|
757
|
+
else
|
|
758
|
+
show_banner
|
|
759
|
+
if [ -f "$TODO_FILE" ]; then
|
|
760
|
+
start_loop
|
|
761
|
+
else
|
|
762
|
+
echo -e "${YELLOW}No TODO.md found. Run 'chiefwiggum new' to get started.${NC}"
|
|
763
|
+
exit 1
|
|
764
|
+
fi
|
|
765
|
+
fi
|
|
766
|
+
;;
|
|
767
|
+
*)
|
|
768
|
+
# Check if it's a file path (for backward compat with ralph.sh)
|
|
769
|
+
if [ -f "$cmd" ]; then
|
|
770
|
+
show_banner
|
|
771
|
+
generate_from_plan "$cmd"
|
|
772
|
+
start_loop
|
|
773
|
+
else
|
|
774
|
+
echo -e "${RED}Unknown command: ${cmd}${NC}"
|
|
775
|
+
echo "Run 'chiefwiggum help' for usage."
|
|
776
|
+
exit 1
|
|
777
|
+
fi
|
|
778
|
+
;;
|
|
779
|
+
esac
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
main "$@"
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "chiefwiggum",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Autonomous coding agent CLI. Point it at a plan, watch it build.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"chiefwiggum": "./chiefwiggum"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/addisonk/chief-wiggum.git"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"cli",
|
|
14
|
+
"autonomous",
|
|
15
|
+
"coding-agent",
|
|
16
|
+
"claude",
|
|
17
|
+
"ai"
|
|
18
|
+
],
|
|
19
|
+
"author": "Addison Kowalski",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/addisonk/chief-wiggum/issues"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://github.com/addisonk/chief-wiggum#readme",
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=18"
|
|
27
|
+
}
|
|
28
|
+
}
|