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 +22 -0
- package/README.md +103 -0
- package/bin/ralph.js +44 -0
- package/lib/agents/architect.md +32 -0
- package/lib/agents/reviewer.md +19 -0
- package/lib/prompt.md +48 -0
- package/lib/ralph.sh +354 -0
- package/package.json +29 -0
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
|
+

|
|
10
|
+
|
|
11
|
+
[](https://badge.fury.io/js/vibepup)
|
|
12
|
+

|
|
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
|
+

|
|
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
|
+
}
|