@herbcaudill/ralph 0.1.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 +175 -0
- package/bin/ralph.js +2 -0
- package/dist/cli.d.ts +20 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +66 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/outputState.d.ts +5 -0
- package/dist/lib/outputState.d.ts.map +1 -0
- package/dist/lib/outputState.js +6 -0
- package/dist/lib/outputState.js.map +1 -0
- package/dist/lib/processEvent.d.ts +2 -0
- package/dist/lib/processEvent.d.ts.map +1 -0
- package/dist/lib/processEvent.js +100 -0
- package/dist/lib/processEvent.js.map +1 -0
- package/dist/lib/rel.d.ts +2 -0
- package/dist/lib/rel.d.ts.map +1 -0
- package/dist/lib/rel.js +10 -0
- package/dist/lib/rel.js.map +1 -0
- package/dist/lib/replayLog.d.ts +2 -0
- package/dist/lib/replayLog.d.ts.map +1 -0
- package/dist/lib/replayLog.js +21 -0
- package/dist/lib/replayLog.js.map +1 -0
- package/dist/lib/runIteration.d.ts +2 -0
- package/dist/lib/runIteration.d.ts.map +1 -0
- package/dist/lib/runIteration.js +81 -0
- package/dist/lib/runIteration.js.map +1 -0
- package/dist/lib/shortenTempPaths.d.ts +2 -0
- package/dist/lib/shortenTempPaths.d.ts.map +1 -0
- package/dist/lib/shortenTempPaths.js +7 -0
- package/dist/lib/shortenTempPaths.js.map +1 -0
- package/dist/lib/showToolUse.d.ts +2 -0
- package/dist/lib/showToolUse.d.ts.map +1 -0
- package/dist/lib/showToolUse.js +17 -0
- package/dist/lib/showToolUse.js.map +1 -0
- package/dist/lib/textFormatting.d.ts +4 -0
- package/dist/lib/textFormatting.d.ts.map +1 -0
- package/dist/lib/textFormatting.js +94 -0
- package/dist/lib/textFormatting.js.map +1 -0
- package/package.json +46 -0
- package/templates/progress.md +11 -0
- package/templates/prompt.md +18 -0
- package/templates/todo.md +10 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Herb Caudill
|
|
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,175 @@
|
|
|
1
|
+
# Ralph
|
|
2
|
+
|
|
3
|
+
Autonomous AI iteration engine for Claude CLI. Ralph runs Claude in a loop to systematically work through your codebase's task list, enabling Claude to tackle work items iteratively.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Ralph spawns multiple Claude CLI sessions that:
|
|
8
|
+
|
|
9
|
+
1. Check project health (build, tests)
|
|
10
|
+
2. Select and work on the highest-priority task
|
|
11
|
+
3. Validate changes with tests
|
|
12
|
+
4. Document progress
|
|
13
|
+
5. Commit changes
|
|
14
|
+
6. Repeat
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pnpm add -D @herbcaudill/ralph
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or use directly with npx:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx @herbcaudill/ralph
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick start
|
|
29
|
+
|
|
30
|
+
1. **Initialize ralph in your project:**
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx @herbcaudill/ralph init
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
This creates a `.ralph/` directory with template files:
|
|
37
|
+
|
|
38
|
+
- `prompt.md` - Instructions for Claude during each iteration
|
|
39
|
+
- `todo.md` - Your task list
|
|
40
|
+
- `progress.md` - Progress log (auto-updated)
|
|
41
|
+
- `events.log` - Event log (auto-generated)
|
|
42
|
+
|
|
43
|
+
2. **Customize the workflow:**
|
|
44
|
+
|
|
45
|
+
Edit `.ralph/prompt.md` to match your project's workflow (build commands, test commands, etc.).
|
|
46
|
+
|
|
47
|
+
3. **Add tasks:**
|
|
48
|
+
|
|
49
|
+
Edit `.ralph/todo.md` and add tasks for Claude to work on:
|
|
50
|
+
|
|
51
|
+
```markdown
|
|
52
|
+
### To do
|
|
53
|
+
|
|
54
|
+
- [ ] Add user authentication
|
|
55
|
+
- [ ] Fix login form validation
|
|
56
|
+
- [ ] Write tests for auth flow
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
### Done
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
4. **Run ralph:**
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npx ralph # Run 10 iterations (default)
|
|
67
|
+
npx ralph 5 # Run 5 iterations
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Commands
|
|
71
|
+
|
|
72
|
+
| Command | Description |
|
|
73
|
+
| ----------------------- | ------------------------------------------ |
|
|
74
|
+
| `ralph` | Run 10 iterations (default) |
|
|
75
|
+
| `ralph <n>` | Run specified number of iterations |
|
|
76
|
+
| `ralph init` | Initialize .ralph directory with templates |
|
|
77
|
+
| `ralph --replay` | Replay events from `.ralph/events.log` |
|
|
78
|
+
| `ralph --replay <file>` | Replay events from custom log file |
|
|
79
|
+
| `ralph --help` | Show help |
|
|
80
|
+
|
|
81
|
+
## Configuration
|
|
82
|
+
|
|
83
|
+
### Template files
|
|
84
|
+
|
|
85
|
+
**`.ralph/prompt.md`**
|
|
86
|
+
|
|
87
|
+
Instructions for Claude's workflow. Customize this for your project:
|
|
88
|
+
|
|
89
|
+
- Build/typecheck commands
|
|
90
|
+
- Test commands
|
|
91
|
+
- Project-specific conventions
|
|
92
|
+
- Commit message style
|
|
93
|
+
|
|
94
|
+
**`.ralph/todo.md`**
|
|
95
|
+
|
|
96
|
+
Your task list with priority and completion status. Tasks can be:
|
|
97
|
+
|
|
98
|
+
- Simple one-liners: `- [ ] Fix header alignment`
|
|
99
|
+
- Detailed descriptions with acceptance criteria
|
|
100
|
+
- Broken down into subtasks
|
|
101
|
+
|
|
102
|
+
**`.ralph/progress.md`**
|
|
103
|
+
|
|
104
|
+
Auto-updated log of completed work. Each entry includes:
|
|
105
|
+
|
|
106
|
+
- What was changed
|
|
107
|
+
- Why it was changed
|
|
108
|
+
- Commit information
|
|
109
|
+
|
|
110
|
+
**`.ralph/events.log`**
|
|
111
|
+
|
|
112
|
+
Machine-readable log of all Claude interactions (JSON). Use for debugging or replay.
|
|
113
|
+
|
|
114
|
+
### Customizing the prompt
|
|
115
|
+
|
|
116
|
+
The default prompt template checks for build errors and tests, but you should customize it for your project:
|
|
117
|
+
|
|
118
|
+
```markdown
|
|
119
|
+
Before doing anything, run `npm run typecheck` and `npm test`.
|
|
120
|
+
|
|
121
|
+
If there are errors: YOUR ONLY TASK IS TO FIX THEM.
|
|
122
|
+
|
|
123
|
+
If no errors, work on the highest-priority task from @.ralph/todo.md.
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Replace with your actual build/test commands (e.g., `pnpm build`, `cargo test`, `pytest`, etc.).
|
|
127
|
+
|
|
128
|
+
## How it works
|
|
129
|
+
|
|
130
|
+
Ralph is a thin wrapper around the Claude CLI that:
|
|
131
|
+
|
|
132
|
+
1. **Spawns Claude CLI** with your project context (prompt, todo, progress files)
|
|
133
|
+
2. **Captures output** as streaming JSON events
|
|
134
|
+
3. **Processes events** to display tool usage (Read, Edit, Bash, etc.) in a readable format
|
|
135
|
+
4. **Logs everything** to `events.log` for replay and debugging
|
|
136
|
+
5. **Detects completion** when Claude outputs `<result>COMPLETE</result>`
|
|
137
|
+
6. **Recursively runs** next iteration until count reached or todo list complete
|
|
138
|
+
|
|
139
|
+
## Requirements
|
|
140
|
+
|
|
141
|
+
- **Claude CLI** must be installed and configured
|
|
142
|
+
- **Node.js** 18 or higher
|
|
143
|
+
- Git repository (for commits)
|
|
144
|
+
|
|
145
|
+
Install Claude CLI:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# macOS/Linux
|
|
149
|
+
curl https://claude.com/cli | sh
|
|
150
|
+
|
|
151
|
+
# Or with Homebrew
|
|
152
|
+
brew install anthropics/tap/claude
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Configure Claude CLI:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
claude auth
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Tips
|
|
162
|
+
|
|
163
|
+
- **Start with small iteration counts** (3-5) to verify the workflow before running longer sessions
|
|
164
|
+
- **Review progress.md** between runs to understand what changed
|
|
165
|
+
- **Customize prompt.md** for your project's specific needs (build commands, test frameworks, etc.)
|
|
166
|
+
- **Break down complex tasks** into smaller subtasks in todo.md
|
|
167
|
+
- **Let Claude prioritize** by not ordering tasks strictly - Claude will choose what makes sense
|
|
168
|
+
|
|
169
|
+
## License
|
|
170
|
+
|
|
171
|
+
MIT
|
|
172
|
+
|
|
173
|
+
## Author
|
|
174
|
+
|
|
175
|
+
Herb Caudill
|
package/bin/ralph.js
ADDED
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const parseArgs: (args: string[]) => {
|
|
2
|
+
mode: "help";
|
|
3
|
+
replayFile?: undefined;
|
|
4
|
+
iterations?: undefined;
|
|
5
|
+
} | {
|
|
6
|
+
mode: "init";
|
|
7
|
+
replayFile?: undefined;
|
|
8
|
+
iterations?: undefined;
|
|
9
|
+
} | {
|
|
10
|
+
mode: "replay";
|
|
11
|
+
replayFile: string;
|
|
12
|
+
iterations?: undefined;
|
|
13
|
+
} | {
|
|
14
|
+
mode: "run";
|
|
15
|
+
iterations: number;
|
|
16
|
+
replayFile?: undefined;
|
|
17
|
+
};
|
|
18
|
+
export declare const showHelp: () => void;
|
|
19
|
+
export declare const initRalph: () => void;
|
|
20
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE;;;;;;;;;;;;;;;;CAoBvC,CAAA;AAED,eAAO,MAAM,QAAQ,YAapB,CAAA;AAED,eAAO,MAAM,SAAS,YAkCrB,CAAA"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { existsSync, mkdirSync, copyFileSync } from "fs";
|
|
3
|
+
import { join, dirname } from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
export const parseArgs = (args) => {
|
|
7
|
+
const replayIndex = args.indexOf("--replay");
|
|
8
|
+
const initIndex = args.indexOf("init");
|
|
9
|
+
const helpIndex = args.findIndex(a => a === "--help" || a === "-h");
|
|
10
|
+
if (helpIndex !== -1) {
|
|
11
|
+
return { mode: "help" };
|
|
12
|
+
}
|
|
13
|
+
if (initIndex !== -1) {
|
|
14
|
+
return { mode: "init" };
|
|
15
|
+
}
|
|
16
|
+
if (replayIndex !== -1) {
|
|
17
|
+
const replayFile = args[replayIndex + 1] || join(process.cwd(), ".ralph", "events.log");
|
|
18
|
+
return { mode: "replay", replayFile };
|
|
19
|
+
}
|
|
20
|
+
const iterations = parseInt(args.find(a => /^\d+$/.test(a)) ?? "", 10) || 10;
|
|
21
|
+
return { mode: "run", iterations };
|
|
22
|
+
};
|
|
23
|
+
export const showHelp = () => {
|
|
24
|
+
console.log(chalk.bold("ralph") + " - Autonomous AI iteration engine for Claude CLI\n");
|
|
25
|
+
console.log(chalk.bold("Usage:"));
|
|
26
|
+
console.log(" ralph [iterations] Run ralph for specified iterations (default: 10)");
|
|
27
|
+
console.log(" ralph init Initialize .ralph directory with templates");
|
|
28
|
+
console.log(" ralph --replay [file] Replay events from log file");
|
|
29
|
+
console.log(" ralph --help Show this help message\n");
|
|
30
|
+
console.log(chalk.bold("Examples:"));
|
|
31
|
+
console.log(" ralph Run 10 iterations");
|
|
32
|
+
console.log(" ralph 5 Run 5 iterations");
|
|
33
|
+
console.log(" ralph init Create .ralph directory");
|
|
34
|
+
console.log(" ralph --replay Replay default log file");
|
|
35
|
+
console.log(" ralph --replay custom.log Replay custom log file\n");
|
|
36
|
+
};
|
|
37
|
+
export const initRalph = () => {
|
|
38
|
+
const ralphDir = join(process.cwd(), ".ralph");
|
|
39
|
+
if (existsSync(ralphDir)) {
|
|
40
|
+
console.log(chalk.yellow("⚠️ .ralph directory already exists"));
|
|
41
|
+
console.log(chalk.dim("To reinitialize, remove the directory first: rm -rf .ralph"));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
console.log(chalk.cyan("Initializing ralph..."));
|
|
45
|
+
mkdirSync(ralphDir, { recursive: true });
|
|
46
|
+
// Copy templates from package installation
|
|
47
|
+
const templatesDir = join(__dirname, "..", "templates");
|
|
48
|
+
const templates = ["prompt.md", "todo.md", "progress.md"];
|
|
49
|
+
for (const template of templates) {
|
|
50
|
+
const src = join(templatesDir, template);
|
|
51
|
+
const dest = join(ralphDir, template);
|
|
52
|
+
if (existsSync(src)) {
|
|
53
|
+
copyFileSync(src, dest);
|
|
54
|
+
console.log(chalk.green("✓") + ` Created ${chalk.dim(".ralph/" + template)}`);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
console.error(chalk.red("✗") + ` Template not found: ${template}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
console.log(chalk.green("\n✓ Ralph initialized successfully!"));
|
|
61
|
+
console.log(chalk.dim("\nNext steps:"));
|
|
62
|
+
console.log(chalk.dim(" 1. Customize .ralph/prompt.md with your project's workflow"));
|
|
63
|
+
console.log(chalk.dim(" 2. Add tasks to .ralph/todo.md"));
|
|
64
|
+
console.log(chalk.dim(" 3. Run: ralph\n"));
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,GAAG,YAuBf,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { replayLog } from "./lib/replayLog.js";
|
|
2
|
+
import { runIteration } from "./lib/runIteration.js";
|
|
3
|
+
import { parseArgs, showHelp, initRalph } from "./cli.js";
|
|
4
|
+
export const run = () => {
|
|
5
|
+
const args = process.argv.slice(2);
|
|
6
|
+
const parsed = parseArgs(args);
|
|
7
|
+
if (parsed.mode === "help") {
|
|
8
|
+
showHelp();
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (parsed.mode === "init") {
|
|
12
|
+
initRalph();
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (parsed.mode === "replay") {
|
|
16
|
+
replayLog(parsed.replayFile);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (parsed.mode === "run") {
|
|
20
|
+
runIteration(1, parsed.iterations);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
// Run if called directly
|
|
25
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
26
|
+
run();
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzD,MAAM,CAAC,MAAM,GAAG,GAAG,GAAG,EAAE;IACtB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAClC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;IAE9B,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,QAAQ,EAAE,CAAA;QACV,OAAM;IACR,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,SAAS,EAAE,CAAA;QACX,OAAM;IACR,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QAC5B,OAAM;IACR,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC1B,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;QAClC,OAAM;IACR,CAAC;AACH,CAAC,CAAA;AAED,yBAAyB;AACzB,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpD,GAAG,EAAE,CAAA;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outputState.d.ts","sourceRoot":"","sources":["../../src/lib/outputState.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,WAAW;;;CAGvB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outputState.js","sourceRoot":"","sources":["../../src/lib/outputState.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,gBAAgB,EAAE,CAAC;IACnB,wBAAwB,EAAE,KAAK;CAChC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processEvent.d.ts","sourceRoot":"","sources":["../../src/lib/processEvent.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SAuF1D,CAAA"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { rel } from "./rel.js";
|
|
2
|
+
import { shortenTempPaths } from "./shortenTempPaths.js";
|
|
3
|
+
import { writeWrappedText } from "./textFormatting.js";
|
|
4
|
+
import { showToolUse } from "./showToolUse.js";
|
|
5
|
+
import { outputState } from "./outputState.js";
|
|
6
|
+
const toolIndent = " ";
|
|
7
|
+
export const processEvent = (event) => {
|
|
8
|
+
// Stream text deltas as they come in
|
|
9
|
+
if (event.type === "stream_event") {
|
|
10
|
+
const streamEvent = event.event;
|
|
11
|
+
const delta = streamEvent?.delta;
|
|
12
|
+
if (delta?.type === "text_delta" && delta.text) {
|
|
13
|
+
if (outputState.needsBlankLineBeforeText) {
|
|
14
|
+
process.stdout.write("\n");
|
|
15
|
+
outputState.trailingNewlines = 2;
|
|
16
|
+
outputState.needsBlankLineBeforeText = false;
|
|
17
|
+
}
|
|
18
|
+
writeWrappedText(delta.text);
|
|
19
|
+
const match = delta.text.match(/\n+$/);
|
|
20
|
+
if (match) {
|
|
21
|
+
outputState.trailingNewlines = Math.min(match[0].length, 2);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
outputState.trailingNewlines = 0;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Show tool uses
|
|
29
|
+
if (event.type === "assistant") {
|
|
30
|
+
const message = event.message;
|
|
31
|
+
const content = message?.content;
|
|
32
|
+
if (content) {
|
|
33
|
+
for (const block of content) {
|
|
34
|
+
if (block.type === "tool_use") {
|
|
35
|
+
const input = block.input;
|
|
36
|
+
if (block.name === "Read") {
|
|
37
|
+
const filePath = input?.file_path;
|
|
38
|
+
if (filePath) {
|
|
39
|
+
showToolUse("Read", rel(filePath));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (block.name === "Edit" || block.name === "Write") {
|
|
43
|
+
const filePath = input?.file_path;
|
|
44
|
+
if (filePath) {
|
|
45
|
+
showToolUse(block.name, rel(filePath));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (block.name === "Bash") {
|
|
49
|
+
const command = input?.command;
|
|
50
|
+
if (command) {
|
|
51
|
+
showToolUse("$", shortenTempPaths(command));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else if (block.name === "Grep") {
|
|
55
|
+
const pattern = input?.pattern;
|
|
56
|
+
const path = input?.path;
|
|
57
|
+
showToolUse("Grep", `${pattern}${path ? ` in ${rel(path)}` : ""}`);
|
|
58
|
+
}
|
|
59
|
+
else if (block.name === "Glob") {
|
|
60
|
+
const pattern = input?.pattern;
|
|
61
|
+
const path = input?.path;
|
|
62
|
+
showToolUse("Glob", `${pattern}${path ? ` in ${rel(path)}` : ""}`);
|
|
63
|
+
}
|
|
64
|
+
else if (block.name === "TodoWrite") {
|
|
65
|
+
const todos = input?.todos;
|
|
66
|
+
if (todos?.length) {
|
|
67
|
+
const todoIndent = toolIndent + " ";
|
|
68
|
+
const summary = todos
|
|
69
|
+
.map(t => `[${t.status === "completed" ? "x"
|
|
70
|
+
: t.status === "in_progress" ? "~"
|
|
71
|
+
: " "}] ${t.content}`)
|
|
72
|
+
.join("\n" + todoIndent);
|
|
73
|
+
showToolUse("TodoWrite", "\n" + todoIndent + summary);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
showToolUse("TodoWrite");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (block.name === "WebFetch") {
|
|
80
|
+
const url = input?.url;
|
|
81
|
+
showToolUse("WebFetch", url);
|
|
82
|
+
}
|
|
83
|
+
else if (block.name === "WebSearch") {
|
|
84
|
+
const query = input?.query;
|
|
85
|
+
showToolUse("WebSearch", query);
|
|
86
|
+
}
|
|
87
|
+
else if (block.name === "Task") {
|
|
88
|
+
const description = input?.description;
|
|
89
|
+
showToolUse("Task", description);
|
|
90
|
+
}
|
|
91
|
+
else if (block.name === "Skill") {
|
|
92
|
+
const skill = input?.skill;
|
|
93
|
+
showToolUse("Skill", skill);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=processEvent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processEvent.js","sourceRoot":"","sources":["../../src/lib/processEvent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rel.d.ts","sourceRoot":"","sources":["../../src/lib/rel.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,GAAG,GAAI,MAAM,MAAM,WAM/B,CAAA"}
|
package/dist/lib/rel.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { relative } from "path";
|
|
2
|
+
const cwd = process.cwd();
|
|
3
|
+
export const rel = (path) => {
|
|
4
|
+
// For temp files, just show the filename
|
|
5
|
+
if (path.includes("/var/folders/") || path.includes("/tmp/")) {
|
|
6
|
+
return path.split("/").pop() || path;
|
|
7
|
+
}
|
|
8
|
+
return relative(cwd, path) || path;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=rel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rel.js","sourceRoot":"","sources":["../../src/lib/rel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAE/B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;AAEzB,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE;IAClC,yCAAyC;IACzC,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7D,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI,CAAA;IACtC,CAAC;IACD,OAAO,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,IAAI,CAAA;AACpC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replayLog.d.ts","sourceRoot":"","sources":["../../src/lib/replayLog.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS,GAAI,UAAU,MAAM,SAiBzC,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { readFileSync } from "fs";
|
|
3
|
+
import { processEvent } from "./processEvent.js";
|
|
4
|
+
export const replayLog = (filePath) => {
|
|
5
|
+
console.log(chalk.cyan(`Replaying: ${filePath}`));
|
|
6
|
+
console.log(chalk.dim("─".repeat(40)) + "\n");
|
|
7
|
+
const content = readFileSync(filePath, "utf-8");
|
|
8
|
+
// Log file contains pretty-printed JSON objects separated by blank lines
|
|
9
|
+
const eventStrings = content.split(/\n\n+/).filter(s => s.trim());
|
|
10
|
+
for (const eventStr of eventStrings) {
|
|
11
|
+
try {
|
|
12
|
+
const event = JSON.parse(eventStr);
|
|
13
|
+
processEvent(event);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// Skip malformed entries
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
console.log("\n");
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=replayLog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replayLog.js","sourceRoot":"","sources":["../../src/lib/replayLog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAE,EAAE;IAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,QAAQ,EAAE,CAAC,CAAC,CAAA;IACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IAE7C,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IAC/C,yEAAyE;IACzE,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;IAEjE,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;YAClC,YAAY,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,yBAAyB;QAC3B,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AACnB,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runIteration.d.ts","sourceRoot":"","sources":["../../src/lib/runIteration.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,YAAY,GAAI,GAAG,MAAM,EAAE,YAAY,MAAM,SAyFzD,CAAA"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { spawn } from "child_process";
|
|
3
|
+
import { appendFileSync, writeFileSync } from "fs";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import { processEvent } from "./processEvent.js";
|
|
6
|
+
import { flushLine, resetTextState } from "./textFormatting.js";
|
|
7
|
+
const logFile = join(process.cwd(), ".ralph", "events.log");
|
|
8
|
+
export const runIteration = (i, iterations) => {
|
|
9
|
+
if (i > iterations) {
|
|
10
|
+
console.log(chalk.green(`Completed ${iterations} iterations.`));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
console.log(chalk.cyan(`Iteration ${i}`));
|
|
14
|
+
console.log(chalk.dim("─".repeat(40)) + "\n");
|
|
15
|
+
// Clear log file at start of each iteration
|
|
16
|
+
writeFileSync(logFile, "");
|
|
17
|
+
const child = spawn("claude", [
|
|
18
|
+
"--permission-mode",
|
|
19
|
+
"bypassPermissions",
|
|
20
|
+
"-p",
|
|
21
|
+
"@.ralph/prompt.md",
|
|
22
|
+
"@.ralph/todo.md",
|
|
23
|
+
"@.ralph/progress.md",
|
|
24
|
+
"--output-format",
|
|
25
|
+
"stream-json",
|
|
26
|
+
"--include-partial-messages",
|
|
27
|
+
"--verbose",
|
|
28
|
+
], { stdio: ["inherit", "pipe", "inherit"] });
|
|
29
|
+
let output = "";
|
|
30
|
+
let stdoutEnded = false;
|
|
31
|
+
let closeInfo = null;
|
|
32
|
+
const handleIterationComplete = () => {
|
|
33
|
+
if (!stdoutEnded || !closeInfo)
|
|
34
|
+
return;
|
|
35
|
+
const { code, signal } = closeInfo;
|
|
36
|
+
if (code !== 0) {
|
|
37
|
+
console.error(chalk.red(`Claude exited with code ${code}${signal ? ` (signal: ${signal})` : ""}`));
|
|
38
|
+
console.error(chalk.yellow("Last 2000 chars of output:"));
|
|
39
|
+
console.error(chalk.dim(output.slice(-2000)));
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
if (output.includes("<result>COMPLETE</result>")) {
|
|
43
|
+
console.log(chalk.green("Todo list complete, exiting."));
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
// Flush any remaining text in the line buffer and reset state
|
|
47
|
+
flushLine();
|
|
48
|
+
resetTextState();
|
|
49
|
+
console.log("\n"); // Add blank lines before next iteration
|
|
50
|
+
runIteration(i + 1, iterations);
|
|
51
|
+
};
|
|
52
|
+
child.stdout.on("data", data => {
|
|
53
|
+
const chunk = data.toString();
|
|
54
|
+
for (const line of chunk.split("\n")) {
|
|
55
|
+
if (!line.trim())
|
|
56
|
+
continue;
|
|
57
|
+
try {
|
|
58
|
+
const event = JSON.parse(line);
|
|
59
|
+
appendFileSync(logFile, JSON.stringify(event, null, 2) + "\n\n");
|
|
60
|
+
processEvent(event);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Incomplete JSON line, ignore
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
output += chunk;
|
|
67
|
+
});
|
|
68
|
+
child.stdout.on("end", () => {
|
|
69
|
+
stdoutEnded = true;
|
|
70
|
+
handleIterationComplete();
|
|
71
|
+
});
|
|
72
|
+
child.on("close", (code, signal) => {
|
|
73
|
+
closeInfo = { code, signal };
|
|
74
|
+
handleIterationComplete();
|
|
75
|
+
});
|
|
76
|
+
child.on("error", error => {
|
|
77
|
+
console.error(chalk.red("Error running Claude:"), error);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=runIteration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runIteration.js","sourceRoot":"","sources":["../../src/lib/runIteration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortenTempPaths.d.ts","sourceRoot":"","sources":["../../src/lib/shortenTempPaths.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,WAK5C,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const shortenTempPaths = (text) => {
|
|
2
|
+
// Replace temp file paths with just the filename
|
|
3
|
+
return text
|
|
4
|
+
.replace(/\/var\/folders\/[^\s]+/g, match => match.split("/").pop() || match)
|
|
5
|
+
.replace(/\/tmp\/[^\s]+/g, match => match.split("/").pop() || match);
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=shortenTempPaths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortenTempPaths.js","sourceRoot":"","sources":["../../src/lib/shortenTempPaths.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAE,EAAE;IAC/C,iDAAiD;IACjD,OAAO,IAAI;SACR,OAAO,CAAC,yBAAyB,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC;SAC5E,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,CAAA;AACxE,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"showToolUse.d.ts","sourceRoot":"","sources":["../../src/lib/showToolUse.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,EAAE,MAAM,MAAM,SAWrD,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { flushLine, resetTextState } from "./textFormatting.js";
|
|
3
|
+
import { outputState } from "./outputState.js";
|
|
4
|
+
const toolIndent = " ";
|
|
5
|
+
export const showToolUse = (name, arg) => {
|
|
6
|
+
flushLine();
|
|
7
|
+
while (outputState.trailingNewlines < 2) {
|
|
8
|
+
process.stdout.write("\n");
|
|
9
|
+
outputState.trailingNewlines++;
|
|
10
|
+
}
|
|
11
|
+
const formatted = arg ? `${chalk.blue(name)} ${chalk.dim(arg)}` : chalk.blue(name);
|
|
12
|
+
console.log(toolIndent + formatted);
|
|
13
|
+
outputState.trailingNewlines = 1;
|
|
14
|
+
resetTextState();
|
|
15
|
+
outputState.needsBlankLineBeforeText = true;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=showToolUse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"showToolUse.js","sourceRoot":"","sources":["../../src/lib/showToolUse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,MAAM,UAAU,GAAG,IAAI,CAAA;AAEvB,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,GAAY,EAAE,EAAE;IACxD,SAAS,EAAE,CAAA;IACX,OAAO,WAAW,CAAC,gBAAgB,GAAG,CAAC,EAAE,CAAC;QACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC1B,WAAW,CAAC,gBAAgB,EAAE,CAAA;IAChC,CAAC;IACD,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAClF,OAAO,CAAC,GAAG,CAAC,UAAU,GAAG,SAAS,CAAC,CAAA;IACnC,WAAW,CAAC,gBAAgB,GAAG,CAAC,CAAA;IAChC,cAAc,EAAE,CAAA;IAChB,WAAW,CAAC,wBAAwB,GAAG,IAAI,CAAA;AAC7C,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textFormatting.d.ts","sourceRoot":"","sources":["../../src/lib/textFormatting.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,SAAS,YAwCrB,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,SA4B5C,CAAA;AAED,eAAO,MAAM,cAAc,YAK1B,CAAA"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
const termWidth = process.stdout.columns || 80;
|
|
3
|
+
// Word wrap state for streaming text
|
|
4
|
+
let currentLineLength = 0;
|
|
5
|
+
let lineBuffer = "";
|
|
6
|
+
let inBold = false;
|
|
7
|
+
let inCode = false;
|
|
8
|
+
const formatSegment = (text, bold, code) => {
|
|
9
|
+
if (code)
|
|
10
|
+
return chalk.yellow(text);
|
|
11
|
+
if (bold)
|
|
12
|
+
return chalk.bold(text);
|
|
13
|
+
return text;
|
|
14
|
+
};
|
|
15
|
+
export const flushLine = () => {
|
|
16
|
+
if (!lineBuffer)
|
|
17
|
+
return;
|
|
18
|
+
let output = "";
|
|
19
|
+
let segment = "";
|
|
20
|
+
let segmentBold = inBold;
|
|
21
|
+
let segmentCode = inCode;
|
|
22
|
+
let i = 0;
|
|
23
|
+
while (i < lineBuffer.length) {
|
|
24
|
+
if (lineBuffer[i] === "*" && lineBuffer[i + 1] === "*") {
|
|
25
|
+
// Flush current segment
|
|
26
|
+
if (segment) {
|
|
27
|
+
output += formatSegment(segment, segmentBold, segmentCode);
|
|
28
|
+
segment = "";
|
|
29
|
+
}
|
|
30
|
+
inBold = !inBold;
|
|
31
|
+
segmentBold = inBold;
|
|
32
|
+
i += 2;
|
|
33
|
+
}
|
|
34
|
+
else if (lineBuffer[i] === "`") {
|
|
35
|
+
// Flush current segment
|
|
36
|
+
if (segment) {
|
|
37
|
+
output += formatSegment(segment, segmentBold, segmentCode);
|
|
38
|
+
segment = "";
|
|
39
|
+
}
|
|
40
|
+
inCode = !inCode;
|
|
41
|
+
segmentCode = inCode;
|
|
42
|
+
i++;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
segment += lineBuffer[i];
|
|
46
|
+
currentLineLength++;
|
|
47
|
+
i++;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Flush remaining segment
|
|
51
|
+
if (segment) {
|
|
52
|
+
output += formatSegment(segment, segmentBold, segmentCode);
|
|
53
|
+
}
|
|
54
|
+
process.stdout.write(output);
|
|
55
|
+
lineBuffer = "";
|
|
56
|
+
};
|
|
57
|
+
export const writeWrappedText = (text) => {
|
|
58
|
+
// Accumulate text, wrap at word boundaries
|
|
59
|
+
for (const char of text) {
|
|
60
|
+
if (char === "\n") {
|
|
61
|
+
flushLine();
|
|
62
|
+
process.stdout.write("\n");
|
|
63
|
+
currentLineLength = 0;
|
|
64
|
+
}
|
|
65
|
+
else if (char === " " || char === "\t") {
|
|
66
|
+
lineBuffer += char;
|
|
67
|
+
// Check if we need to wrap - look for last space to break at
|
|
68
|
+
const visibleLength = lineBuffer.replace(/\*\*/g, "").replace(/`/g, "").length;
|
|
69
|
+
if (currentLineLength + visibleLength > termWidth) {
|
|
70
|
+
// Find last space to break at
|
|
71
|
+
const lastSpace = lineBuffer.lastIndexOf(" ", lineBuffer.length - 2);
|
|
72
|
+
if (lastSpace > 0) {
|
|
73
|
+
const beforeBreak = lineBuffer.slice(0, lastSpace);
|
|
74
|
+
const afterBreak = lineBuffer.slice(lastSpace + 1);
|
|
75
|
+
lineBuffer = beforeBreak;
|
|
76
|
+
flushLine();
|
|
77
|
+
process.stdout.write("\n");
|
|
78
|
+
currentLineLength = 0;
|
|
79
|
+
lineBuffer = afterBreak;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
lineBuffer += char;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
export const resetTextState = () => {
|
|
89
|
+
currentLineLength = 0;
|
|
90
|
+
lineBuffer = "";
|
|
91
|
+
inBold = false;
|
|
92
|
+
inCode = false;
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=textFormatting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textFormatting.js","sourceRoot":"","sources":["../../src/lib/textFormatting.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@herbcaudill/ralph",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Autonomous AI iteration engine for Claude CLI",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"ralph": "./bin/ralph.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"bin",
|
|
14
|
+
"templates"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc",
|
|
18
|
+
"dev": "tsx src/index.ts",
|
|
19
|
+
"prepublishOnly": "pnpm build"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"claude",
|
|
23
|
+
"ai",
|
|
24
|
+
"automation",
|
|
25
|
+
"cli",
|
|
26
|
+
"iteration",
|
|
27
|
+
"autonomous"
|
|
28
|
+
],
|
|
29
|
+
"author": "Herb Caudill",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/HerbCaudill/ralph.git"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"chalk": "^5.6.2"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^24.10.1",
|
|
40
|
+
"tsx": "^4.21.0",
|
|
41
|
+
"typescript": "~5.9.3"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18.0.0"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Before doing anything, check that the project builds successfully. Run your project's build/typecheck commands and tests.
|
|
2
|
+
|
|
3
|
+
If there are build errors or test failures: YOUR ONLY TASK IS TO FIX THEM.
|
|
4
|
+
|
|
5
|
+
If there are no build errors or test failures:
|
|
6
|
+
|
|
7
|
+
In @.ralph/todo.md, find the highest-priority task to work on and work only on that task. This should be the one YOU decide has the highest priority - not necessarily the first one in the list.
|
|
8
|
+
|
|
9
|
+
ONLY WORK ON A SINGLE TASK. If the task you choose is especially complex, then your task is to break it into subtasks, replace the original task in the todo file, commit the file, and end your turn.
|
|
10
|
+
|
|
11
|
+
When you complete a task, before committing:
|
|
12
|
+
|
|
13
|
+
- Check that the project builds successfully and tests pass
|
|
14
|
+
- Where applicable, add tests to validate your changes and confirm that they pass
|
|
15
|
+
- Update the todo list by checking off the completed task and moving it to the "Done" section
|
|
16
|
+
- Append your progress to the @.ralph/progress.md file. Use this to leave a note for the next person working in the codebase
|
|
17
|
+
|
|
18
|
+
Make one git commit for this task. If, while implementing the task, you notice the todo list is complete, output <result>COMPLETE</result> and exit.
|