vibepup 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/PUBLISHING.md ADDED
@@ -0,0 +1,22 @@
1
+ # Vibepup npm Publishing (from any machine)
2
+
3
+ ## 1) Login
4
+ ```bash
5
+ npm adduser
6
+ ```
7
+
8
+ ## 2) Verify package metadata
9
+ ```bash
10
+ node -p "require('./package.json').name"
11
+ node -p "require('./package.json').version"
12
+ ```
13
+
14
+ ## 3) Publish
15
+ ```bash
16
+ npm publish --access public
17
+ ```
18
+
19
+ ## Notes
20
+ - Publish must be run inside `npm-package/`.
21
+ - If you see a `bin` warning, ensure `package.json` has: `"bin": "bin/ralph.js"`.
22
+ - Windows users should have Git Bash or WSL installed to run the CLI.
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # 🐾 Vibepup
2
+
3
+ > **"Fetch Code. Sit. Stay. Good Pup."**
4
+
5
+ Vibepup is a **Split-Brain Autonomous Agent Harness** that lives in your terminal. A loyal helper built for **DX-first, vibe-coding energy**.
6
+
7
+ **Mascot:** Pummy the cyberpunk corgi.
8
+
9
+ ![Pummy Loop](https://raw.githubusercontent.com/shantanusoam/ralph-project/refs/heads/gh-images/assets/corgi_Loop.png)
10
+
11
+ [![npm version](https://badge.fury.io/js/vibepup.svg)](https://badge.fury.io/js/vibepup)
12
+ ![License](https://img.shields.io/npm/l/vibepup)
13
+
14
+ ## ✨ The Vibe
15
+ Most AI agents are black boxes that overwrite your files and get stuck in loops. Vibepup is different: loyal, friendly, meme-y, and built for real dev workflows.
16
+
17
+ **Selling Points:**
18
+ - DX-first onboarding
19
+ - Vibe-coding friendly
20
+ - Safe, loop-resistant agent harness
21
+ - Minimal setup, works everywhere
22
+ - Loyal helper with a cyberpunk-cute mascot
23
+
24
+ * **🧠 Split-Brain**: Keeps your instructions (`prd.md`) separate from internal state (`prd.state.json`). Edit tasks mid-run without breaking the agent.
25
+ * **πŸ›‘οΈ Anti-Wizard**: Refuses to run interactive commands that hang shells. Vibepup forces clarity.
26
+ * **⚑ DX-First**: Optimized for fast iteration, visibility, and zero-friction adoption.
27
+ * **🌈 Cyberpunk Corgi**: Cute, loyal, and ready to ship.
28
+ * **🧩 Friendly + Meme-y**: The tool feels fun without being unserious.
29
+
30
+ ![Pummy Checklist](https://raw.githubusercontent.com/shantanusoam/ralph-project/refs/heads/gh-images/assets/corgi_checklist.png)
31
+
32
+ ## πŸš€ Get Started
33
+
34
+ ### βœ… Works Everywhere
35
+ Linux, macOS, and Windows (via Git Bash or WSL). Vibepup is portable and requires only Bash + `opencode`.
36
+
37
+ ### 1. Install
38
+ ```bash
39
+ npm install -g vibepup
40
+ ```
41
+
42
+ ### 1b. bunx (no global install)
43
+ ```bash
44
+ bunx vibepup --watch
45
+ ```
46
+
47
+ ### 1c. bun global install (optional)
48
+ ```bash
49
+ bun add -g vibepup
50
+ ```
51
+
52
+ ### 2. Fetch!
53
+ Go to any empty folder and tell Vibepup what to build.
54
+
55
+ ```bash
56
+ mkdir my-app
57
+ cd my-app
58
+ vibepup new "A react app for tracking my plant watering schedule"
59
+ ```
60
+
61
+ Using bunx:
62
+ ```bash
63
+ bunx vibepup new "A react app for tracking my plant watering schedule"
64
+ ```
65
+
66
+ Using bun global install:
67
+ ```bash
68
+ vibepup new "A react app for tracking my plant watering schedule"
69
+ ```
70
+
71
+ Vibepup will:
72
+ 1. πŸ—οΈ **Plan**: Map out the architecture in `repo-map.md`.
73
+ 2. πŸ“ **Draft**: Create a `prd.md` checklist.
74
+ 3. πŸ”¨ **Build**: Start checking off items one by one.
75
+
76
+ ### 3. Watch Him Work
77
+ ```bash
78
+ vibepup --watch
79
+ ```
80
+ In watch mode, Vibepup keeps working until the PRD is done. If you edit `prd.md` (e.g., add "- [ ] Add dark mode"), he smells the change and gets back to work immediately.
81
+
82
+ ## βš™οΈ Configuration
83
+ Vibepup works out of the box, but you can tune his brain in `~/.config/ralph/config.json`:
84
+
85
+ ```json
86
+ {
87
+ "build_models": [
88
+ "github-copilot/gpt-5.2-codex",
89
+ "openai/gpt-4o"
90
+ ],
91
+ "plan_models": [
92
+ "github-copilot/claude-opus-4.5"
93
+ ]
94
+ }
95
+ ```
96
+
97
+ ## πŸ—οΈ Architecture
98
+ * **Plan Mode**: When `repo-map.md` is missing, Vibepup explores and plans.
99
+ * **Build Mode**: When `repo-map.md` exists, Vibepup executes tasks from `prd.md`.
100
+
101
+
102
+ ## License
103
+ MIT
package/bin/ralph.js ADDED
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+ const path = require('path');
5
+ const os = require('os');
6
+ const fs = require('fs');
7
+
8
+ const scriptPath = path.join(__dirname, '../lib/ralph.sh');
9
+ const args = process.argv.slice(2);
10
+
11
+ try {
12
+ fs.chmodSync(scriptPath, '755');
13
+ } catch (err) {}
14
+
15
+ console.log('🐾 Vibepup is waking up...');
16
+
17
+ let command = scriptPath;
18
+ let cmdArgs = args;
19
+ let shellOptions = { stdio: 'inherit', shell: false };
20
+
21
+ if (os.platform() === 'win32') {
22
+ command = 'bash';
23
+ cmdArgs = [scriptPath, ...args];
24
+ shellOptions.shell = true;
25
+ } else {
26
+ command = 'bash';
27
+ cmdArgs = [scriptPath, ...args];
28
+ }
29
+
30
+ const vibepup = spawn(command, cmdArgs, shellOptions);
31
+
32
+ vibepup.on('error', (err) => {
33
+ console.error('❌ Failed to start Vibepup.');
34
+ if (err.code === 'ENOENT') {
35
+ console.error(' Error: Bash not found. Please install Git Bash or WSL.');
36
+ } else {
37
+ console.error(String(err));
38
+ }
39
+ process.exit(1);
40
+ });
41
+
42
+ vibepup.on('close', (code) => {
43
+ process.exit(code);
44
+ });
@@ -0,0 +1,32 @@
1
+ # Identity
2
+ You are **The Architect**, a Phase 0 initialization agent for the Ralph system.
3
+ Your goal is to take a raw, abstract project "Idea" and convert it into a concrete, actionable engineering plan.
4
+
5
+ # Output Deliverables
6
+ You must use the `write` tool to generate the following three files in the current directory:
7
+
8
+ 1. **`prd.json`**
9
+ - A JSON file containing a list of atomic tasks.
10
+ - Format: `[ { "id": "1", "description": "...", "status": "pending" } ]`
11
+ - Break the project down into 5-10 high-level implementation steps.
12
+ - **Crucial**: The first step must always be "Initialize project scaffold and install dependencies".
13
+
14
+ 2. **`repo-map.md`**
15
+ - A markdown file describing the intended file structure.
16
+ - Use a tree-like format or a bulleted list.
17
+ - This prevents the "Build" agents from flying blind.
18
+
19
+ 3. **`README.md`**
20
+ - A high-level overview of the project, its purpose, and the chosen tech stack.
21
+
22
+ # Tech Stack defaults (Unless specified otherwise)
23
+ - **Web/Frontend**: React, Next.js (App Router), TailwindCSS, Shadcn/UI.
24
+ - **Backend/API**: Python (FastAPI) or Go (Chi/Gin).
25
+ - **CLI**: Go (Cobra) or Python (Click).
26
+ - **Database**: SQLite (for simple), PostgreSQL (for complex).
27
+
28
+ # Instructions
29
+ 1. Analyze the user's "Idea".
30
+ 2. Determine the best architecture and stack.
31
+ 3. **WRITE** the files (`prd.json`, `repo-map.md`, `README.md`).
32
+ 4. Do not ask for confirmation. Just build the plan.
@@ -0,0 +1,19 @@
1
+ # Ralph - Code Reviewer Agent
2
+
3
+ You are a senior code reviewer. Your goal is to review the changes made by the primary agent *before* they are committed.
4
+
5
+ ## Context
6
+ - `diff.patch`: The changes proposed by the primary agent.
7
+ - `prd.json`: The task requirements.
8
+ - `repo-map.md`: Architecture context.
9
+
10
+ ## Your Job
11
+ 1. **Analyze the Diff**: Look for bugs, security issues, performance problems, and style violations.
12
+ 2. **Verify Against PRD**: Did the code actually implement what was asked?
13
+ 3. **Check for "Context Burn"**: Did the agent delete critical comments or modify unrelated files?
14
+
15
+ ## Output
16
+ - If the code is good: Output `<review>PASS</review>`.
17
+ - If there are issues:
18
+ - Write a concise list of required fixes to `review-feedback.txt`.
19
+ - Output `<review>FAIL</review>`.
package/lib/prompt.md ADDED
@@ -0,0 +1,48 @@
1
+ # Ralph v3.1 - Autonomous Agent Instructions
2
+
3
+ You are "Ralph", an autonomous agent working in a split-state environment. Your goal is to complete tasks defined in `prd.md` while maintaining state in `prd.state.json`.
4
+
5
+ ## Context Files
6
+ 1. **`prd.md`**: The Human Checklist. Read-Only for tasks.
7
+ 2. **`prd.state.json`**: Your State. Write-Only for tracking status.
8
+ 3. **`repo-map.md`**: Architectural Map.
9
+ 4. **`progress.tail.log`**: Recent history (last ~200 lines).
10
+
11
+ ## Core Mandates
12
+
13
+ ### 1. Phase Awareness
14
+ * **PLAN MODE** (Triggered when `repo-map.md` is empty):
15
+ * **Goal**: Explore structure (`ls -R`), read key files, and populate `repo-map.md`.
16
+ * **Prohibited**: Do NOT write code or fix bugs yet. Just map.
17
+ * **BUILD MODE** (Triggered when map exists):
18
+ * **Goal**: Pick the first unchecked item in `prd.md` and implement it.
19
+ * **Guidance**: Prefer local tools first (`read`, `grep`, `glob`). Background agents are allowed **sparingly** when local tools are insufficient, and only one at a time.
20
+
21
+ ### 2. The PRD Contract
22
+ * **Read**: Look at `prd.md`. Find the first task usually marked `- [ ]`.
23
+ * **Check State**: Look at `prd.state.json`.
24
+ * If a task is marked `verified: true`, it is DONE.
25
+ * If `attempts > 3`, consider skipping or asking for help.
26
+ * **Update State**:
27
+ * When you start a task, update `prd.state.json`.
28
+ * When you finish, **YOU MUST VERIFY** (run tests/build).
29
+ * ONLY if verification passes:
30
+ 1. Mark the checkbox in `prd.md` (change `[ ]` to `[x]`).
31
+ 2. Update `prd.state.json` to `verified: true`.
32
+
33
+ ### 3. Surgical Execution
34
+ * **Do not read the whole internet.** Read only what is needed.
35
+ * **Do not pollute logs.** Append ONE concise line to `progress.log` via the `write` tool (using `>>` or reading first then writing). Do not overwrite history.
36
+ * **Background agents (soft)**: If local tools can't find what you need, you may use **one** `background_task` at a time. Prefer `explore` for codebase search and `librarian` for external docs. Avoid webfetch/websearch unless explicitly required by the task.
37
+
38
+ ### 4. Non-Interactive Execution (CRITICAL)
39
+ * **Avoid Wizards**: NEVER run commands that might pause for user input (e.g., `npm init`, `next lint`, `eslint --init`) without ensuring a configuration file exists first.
40
+ * **Use Flags**: ALWAYS use non-interactive flags:
41
+ * `npm init -y`
42
+ * `apt-get install -y`
43
+ * `next lint --no-cache` (ONLY if .eslintrc exists!)
44
+ * **Config First**: If a tool (like ESLint) needs a config, use `write` to create it (e.g., `.eslintrc.json`) BEFORE running the tool.
45
+
46
+ ### 5. Completion
47
+ * If ALL tasks in `prd.md` are checked `[x]`:
48
+ * Output exactly: `<promise>COMPLETE</promise>`
package/lib/ralph.sh ADDED
@@ -0,0 +1,354 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+
5
+ # --- Hardened Environment (Anti-Interactive) ---
6
+ export CI=1
7
+ export GIT_TERMINAL_PROMPT=0
8
+ export npm_config_yes=true
9
+ export npm_config_audit=false
10
+ export npm_config_fund=false
11
+ export FORCE_COLOR=0
12
+ export TERM=dumb
13
+
14
+ # --- Configuration ---
15
+ ITERATIONS=5
16
+ WATCH_MODE="false"
17
+
18
+ # Watchdog Tunables
19
+ RALPH_MAX_TURN_SECONDS=${RALPH_MAX_TURN_SECONDS:-900} # 15 min hard cap
20
+ RALPH_NO_OUTPUT_SECONDS=${RALPH_NO_OUTPUT_SECONDS:-180} # 3m without output => stuck
21
+
22
+ # Model Priority: Build Phase (Implementation)
23
+ # (Defaults - can be overridden by config)
24
+ BUILD_MODELS_PREF=(
25
+ "github-copilot/gpt-5.2-codex"
26
+ "github-copilot/claude-sonnet-4.5"
27
+ "github-copilot/gemini-3-pro-preview"
28
+ "github-copilot-enterprise/gpt-5.2-codex"
29
+ "github-copilot-enterprise/claude-sonnet-4.5"
30
+ "github-copilot-enterprise/gemini-3-pro-preview"
31
+ "openai/gpt-5.2-codex"
32
+ "openai/gpt-5.1-codex-max"
33
+ "google/gemini-3-pro-preview"
34
+ "opencode/grok-code"
35
+ )
36
+
37
+ # Model Priority: Plan Phase (Reasoning/Architecture)
38
+ PLAN_MODELS_PREF=(
39
+ "github-copilot/claude-opus-4.5"
40
+ "github-copilot/gemini-3-pro-preview"
41
+ "github-copilot-enterprise/claude-opus-4.5"
42
+ "github-copilot-enterprise/gemini-3-pro-preview"
43
+ "openai/gpt-5.2"
44
+ "google/antigravity-claude-opus-4-5-thinking"
45
+ "google/gemini-3-pro-preview"
46
+ "opencode/glm-4.7-free"
47
+ )
48
+
49
+ # --- Setup Directories ---
50
+ # Resolve the directory where this script lives (lib/)
51
+ SOURCE=${BASH_SOURCE[0]}
52
+ while [ -L "$SOURCE" ]; do
53
+ DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
54
+ SOURCE=$(readlink "$SOURCE")
55
+ [[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE
56
+ done
57
+ ENGINE_DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
58
+
59
+ # PROJECT_DIR is where the user is running the command from
60
+ PROJECT_DIR="$(pwd)"
61
+ RUNS_DIR="$PROJECT_DIR/.ralph/runs"
62
+
63
+ mkdir -p "$RUNS_DIR"
64
+
65
+ # Cleanup trap
66
+ trap "pkill -P $$; exit" SIGINT SIGTERM
67
+
68
+ # --- Parse Args ---
69
+ MODE="default"
70
+ PROJECT_IDEA=""
71
+
72
+ while [[ "$#" -gt 0 ]]; do
73
+ case $1 in
74
+ new)
75
+ MODE="new"
76
+ PROJECT_IDEA="$2"
77
+ shift 2
78
+ ;;
79
+ --watch) WATCH_MODE="true"; shift ;;
80
+ *) ITERATIONS="$1"; shift ;;
81
+ esac
82
+ done
83
+
84
+ echo "🐾 Vibepup v1.0 (CLI Mode)"
85
+ echo " Engine: $ENGINE_DIR"
86
+ echo " Context: $PROJECT_DIR"
87
+
88
+ # --- Smart Model Discovery ---
89
+ get_available_models() {
90
+ local PREF_MODELS=("$@")
91
+ local AVAILABLE_MODELS=()
92
+
93
+ echo "πŸ” Verifying available models..." >&2
94
+
95
+ local ALL_MODELS=$(opencode models --refresh | grep -E "^[a-z0-9-]+\/[a-z0-9.-]+" || true)
96
+
97
+ for PREF in "${PREF_MODELS[@]}"; do
98
+ if echo "$ALL_MODELS" | grep -q "^$PREF$"; then
99
+ AVAILABLE_MODELS+=("$PREF")
100
+ fi
101
+ done
102
+
103
+ if [ ${#AVAILABLE_MODELS[@]} -eq 0 ]; then
104
+ echo "⚠️ No preferred models found. Falling back to generic discovery." >&2
105
+ AVAILABLE_MODELS+=($(echo "$ALL_MODELS" | grep "gpt-4o" | head -n 1))
106
+ AVAILABLE_MODELS+=($(echo "$ALL_MODELS" | grep "claude-sonnet" | head -n 1))
107
+ fi
108
+
109
+ echo "${AVAILABLE_MODELS[@]}"
110
+ }
111
+
112
+ echo " Configuring Build Models..."
113
+ read -r -a BUILD_MODELS <<< "$(get_available_models "${BUILD_MODELS_PREF[@]}")"
114
+ echo " Build Chain: ${BUILD_MODELS[*]}"
115
+
116
+ echo " Configuring Plan Models..."
117
+ read -r -a PLAN_MODELS <<< "$(get_available_models "${PLAN_MODELS_PREF[@]}")"
118
+ echo " Plan Chain: ${PLAN_MODELS[*]}"
119
+
120
+
121
+ # --- Phase 0: The Architect (Genesis) ---
122
+ if [ "$MODE" == "new" ]; then
123
+ echo ""
124
+ echo "πŸ—οΈ Phase 0: The Architect"
125
+ echo " Idea: $PROJECT_IDEA"
126
+
127
+ ARCHITECT_MODEL="${PLAN_MODELS[0]}"
128
+ echo " Using: $ARCHITECT_MODEL"
129
+
130
+ # NOTE: We assume agents/architect.md is in lib/agents/
131
+ opencode run "PROJECT IDEA: $PROJECT_IDEA" \
132
+ --file "$ENGINE_DIR/agents/architect.md" \
133
+ --agent general \
134
+ --model "$ARCHITECT_MODEL"
135
+
136
+ echo "βœ… Architect initialization complete."
137
+ fi
138
+
139
+
140
+ # --- Initialization & Migration ---
141
+ if [ ! -f "$PROJECT_DIR/prd.md" ]; then
142
+ if [ -f "$PROJECT_DIR/prd.json" ]; then
143
+ echo "πŸ”„ Migrating legacy prd.json to prd.md..."
144
+ jq -r '.[] | "- [ ] " + .description' "$PROJECT_DIR/prd.json" > "$PROJECT_DIR/prd.md"
145
+ mv "$PROJECT_DIR/prd.json" "$PROJECT_DIR/prd.json.bak"
146
+ else
147
+ echo "⚠️ No prd.md found. Initializing..."
148
+ cat > "$PROJECT_DIR/prd.md" <<INNEREOF
149
+ # Product Requirements Document (PRD)
150
+
151
+ - [ ] Initialize repo-map.md with project architecture
152
+ - [ ] Setup initial project structure
153
+ INNEREOF
154
+ fi
155
+ fi
156
+
157
+ if [ ! -f "$PROJECT_DIR/repo-map.md" ]; then
158
+ touch "$PROJECT_DIR/repo-map.md"
159
+ fi
160
+
161
+ if [ ! -f "$PROJECT_DIR/prd.state.json" ]; then
162
+ echo "{}" > "$PROJECT_DIR/prd.state.json"
163
+ fi
164
+
165
+ touch "$PROJECT_DIR/progress.log"
166
+
167
+ # --- Helper Functions ---
168
+
169
+ detect_phase() {
170
+ if [ ! -s "$PROJECT_DIR/repo-map.md" ]; then
171
+ echo "PLAN"
172
+ return
173
+ fi
174
+ echo "BUILD"
175
+ }
176
+
177
+ get_current_prd_hash() {
178
+ md5sum "$PROJECT_DIR/prd.md" | awk '{print $1}'
179
+ }
180
+
181
+ prepare_iteration_context() {
182
+ local ITER_ID="$1"
183
+ local ITER_DIR="$RUNS_DIR/$ITER_ID"
184
+ mkdir -p "$ITER_DIR"
185
+
186
+ tail -n 200 "$PROJECT_DIR/progress.log" > "$ITER_DIR/progress.tail.log"
187
+
188
+ rm -f "$RUNS_DIR/latest"
189
+ ln -s "$ITER_DIR" "$RUNS_DIR/latest"
190
+
191
+ echo "$ITER_DIR"
192
+ }
193
+
194
+ run_with_watchdog () {
195
+ local log="$1"; shift
196
+ : > "$log"
197
+
198
+ # run in background and capture output
199
+ ( "$@" 2>&1 | tee -a "$log" ) &
200
+ local pid=$!
201
+ local start=$(date +%s)
202
+ local last=$start
203
+ local last_size=0
204
+
205
+ while kill -0 "$pid" 2>/dev/null; do
206
+ sleep 5
207
+ local now=$(date +%s)
208
+ local size=$(wc -c < "$log" 2>/dev/null || echo 0)
209
+
210
+ if (( size != last_size )); then
211
+ last="$now"
212
+ last_size="$size"
213
+ fi
214
+
215
+ if (( now - start > RALPH_MAX_TURN_SECONDS )); then
216
+ echo "[RALPH] TIMEOUT: killing opencode turn" >> "$log"
217
+ kill -INT "$pid" 2>/dev/null || true
218
+ sleep 3
219
+ kill -TERM "$pid" 2>/dev/null || true
220
+ sleep 1
221
+ kill -KILL "$pid" 2>/dev/null || true
222
+ return 124
223
+ fi
224
+
225
+ if (( now - last > RALPH_NO_OUTPUT_SECONDS )); then
226
+ echo "[RALPH] NO OUTPUT: likely waiting for input / hung tool" >> "$log"
227
+ kill -INT "$pid" 2>/dev/null || true
228
+ sleep 3
229
+ kill -TERM "$pid" 2>/dev/null || true
230
+ sleep 1
231
+ kill -KILL "$pid" 2>/dev/null || true
232
+ return 125
233
+ fi
234
+ done
235
+
236
+ wait "$pid"
237
+ }
238
+
239
+ run_agent() {
240
+ local MODEL="$1"
241
+ local PHASE="$2"
242
+ local ITER_DIR="$3"
243
+
244
+ local SYSTEM_PROMPT="$ENGINE_DIR/prompt.md"
245
+ local PROMPT_SUFFIX=""
246
+ local EXTRA_ARGS=()
247
+
248
+ if [ "$DESIGN_MODE" == "true" ]; then
249
+ echo " 🎨 Design Mode Active: Injecting frontend-design skill..."
250
+ EXTRA_ARGS+=( "--file" "$HOME/.config/opencode/skills/frontend-design.md" )
251
+ PROMPT_SUFFIX="MODE: DESIGN + BUILD. Apply the frontend-design skill guidelines to all work."
252
+ elif [ "$PHASE" == "PLAN" ]; then
253
+ PROMPT_SUFFIX="MODE: PLAN. Focus on exploring and mapping. Do NOT write implementation code yet."
254
+ else
255
+ PROMPT_SUFFIX="MODE: BUILD. Focus on completing tasks in prd.md."
256
+ fi
257
+
258
+ echo " Thinking..."
259
+
260
+ run_with_watchdog "$ITER_DIR/agent_response.txt" \
261
+ opencode run "Proceed with task. $PROMPT_SUFFIX" \
262
+ --file "$SYSTEM_PROMPT" \
263
+ --file "$PROJECT_DIR/prd.md" \
264
+ --file "$PROJECT_DIR/prd.state.json" \
265
+ --file "$PROJECT_DIR/repo-map.md" \
266
+ --file "$ITER_DIR/progress.tail.log" \
267
+ "${EXTRA_ARGS[@]}" \
268
+ --agent general \
269
+ --model "$MODEL"
270
+ }
271
+
272
+ # --- Main Loop ---
273
+ LAST_HASH=$(get_current_prd_hash)
274
+ i=1
275
+
276
+ while true; do
277
+ # Watch Mode Check
278
+ # Only restart if hash changed EXTERNALLY (since last accepted state)
279
+ CURRENT_HASH=$(get_current_prd_hash)
280
+ if [[ "$CURRENT_HASH" != "$LAST_HASH" ]]; then
281
+ echo "πŸ‘€ PRD Changed! Restarting loop..."
282
+ echo "--- PRD CHANGED: RESTARTING LOOP ---" >> "$PROJECT_DIR/progress.log"
283
+ LAST_HASH="$CURRENT_HASH"
284
+
285
+ # Only reset counter if we are in infinite watch mode
286
+ if [[ "$WATCH_MODE" == "true" ]]; then
287
+ i=1
288
+ fi
289
+ fi
290
+
291
+ if [[ "$WATCH_MODE" != "true" ]] && ((i > ITERATIONS)); then
292
+ echo "⏸️ Max iterations reached."
293
+ break
294
+ fi
295
+
296
+ PHASE=$(detect_phase)
297
+ ITER_ID=$(printf "iter-%04d" $i)
298
+ ITER_DIR=$(prepare_iteration_context "$ITER_ID")
299
+
300
+ echo ""
301
+ echo "πŸ” Loop $i ($PHASE Phase)"
302
+ echo " Logs: $ITER_DIR"
303
+
304
+ if [ "$PHASE" == "PLAN" ]; then
305
+ MODELS=("${PLAN_MODELS[@]}")
306
+ else
307
+ MODELS=("${BUILD_MODELS[@]}")
308
+ fi
309
+
310
+ SUCCESS=false
311
+ for MODEL in "${MODELS[@]}"; do
312
+ echo " Using: $MODEL"
313
+ set +e
314
+ run_agent "$MODEL" "$PHASE" "$ITER_DIR"
315
+ EXIT_CODE=$?
316
+ set -e
317
+
318
+ RESPONSE=$(cat "$ITER_DIR/agent_response.txt")
319
+
320
+ if [ $EXIT_CODE -eq 0 ] && [ -n "$RESPONSE" ]; then
321
+ SUCCESS=true
322
+ echo "$RESPONSE"
323
+
324
+ if echo "$RESPONSE" | grep -q "<promise>COMPLETE</promise>"; then
325
+ echo "βœ… Agent signaled completion."
326
+ if [[ "$WATCH_MODE" != "true" ]]; then
327
+ exit 0
328
+ else
329
+ echo "⏸️ Project Complete. Waiting for changes in prd.md..."
330
+ while [[ "$(get_current_prd_hash)" == "$LAST_HASH" ]]; do
331
+ sleep 2
332
+ done
333
+ echo "πŸ‘€ Change detected! Resuming..."
334
+ i=1
335
+ continue
336
+ fi
337
+ fi
338
+ break
339
+ else
340
+ echo " ⚠️ Model $MODEL failed (Exit: $EXIT_CODE). Falling back..."
341
+ fi
342
+ done
343
+
344
+ if [ "$SUCCESS" = false ]; then
345
+ echo "❌ All models failed this iteration."
346
+ sleep 2
347
+ fi
348
+
349
+ # Sync hash AFTER run so self-edits don't trigger restart
350
+ LAST_HASH=$(get_current_prd_hash)
351
+
352
+ ((i++))
353
+ sleep 1
354
+ done
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "vibepup",
3
+ "version": "1.0.0",
4
+ "description": "A loyal, DX-first split-brain agent harness with cyberpunk vibes.",
5
+ "bin": "bin/ralph.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/shantanusoam/ralph-project.git"
12
+ },
13
+ "keywords": [
14
+ "ai",
15
+ "agent",
16
+ "cli",
17
+ "automation",
18
+ "llm",
19
+ "dev-tool",
20
+ "dx",
21
+ "vibe-coding"
22
+ ],
23
+ "author": "Shantanu Soam",
24
+ "license": "MIT",
25
+ "bugs": {
26
+ "url": "https://github.com/shantanusoam/ralph-project/issues"
27
+ },
28
+ "homepage": "https://github.com/shantanusoam/ralph-project#readme"
29
+ }