@herbcaudill/ralph 0.4.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -14
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +33 -1
- package/dist/cli.js.map +1 -1
- package/dist/components/App.d.ts.map +1 -1
- package/dist/components/App.js +2 -8
- package/dist/components/App.js.map +1 -1
- package/dist/components/EventDisplay.d.ts +8 -1
- package/dist/components/EventDisplay.d.ts.map +1 -1
- package/dist/components/EventDisplay.js +175 -57
- package/dist/components/EventDisplay.js.map +1 -1
- package/dist/components/EventDisplay.replay.test.js +53 -43
- package/dist/components/EventDisplay.replay.test.js.map +1 -1
- package/dist/components/EventDisplay.test.js +107 -11
- package/dist/components/EventDisplay.test.js.map +1 -1
- package/dist/components/FullScreenLayout.d.ts +14 -0
- package/dist/components/FullScreenLayout.d.ts.map +1 -0
- package/dist/components/FullScreenLayout.js +30 -0
- package/dist/components/FullScreenLayout.js.map +1 -0
- package/dist/components/Header.d.ts +2 -1
- package/dist/components/Header.d.ts.map +1 -1
- package/dist/components/Header.js +2 -2
- package/dist/components/Header.js.map +1 -1
- package/dist/components/InitRalph.js +1 -1
- package/dist/components/InitRalph.js.map +1 -1
- package/dist/components/IterationRunner.d.ts +3 -1
- package/dist/components/IterationRunner.d.ts.map +1 -1
- package/dist/components/IterationRunner.js +268 -186
- package/dist/components/IterationRunner.js.map +1 -1
- package/dist/components/IterationRunner.test.js +6 -6
- package/dist/components/IterationRunner.test.js.map +1 -1
- package/dist/components/ReplayLog.d.ts.map +1 -1
- package/dist/components/ReplayLog.js +7 -8
- package/dist/components/ReplayLog.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/addTodo.d.ts +10 -0
- package/dist/lib/addTodo.d.ts.map +1 -0
- package/dist/lib/addTodo.js +55 -0
- package/dist/lib/addTodo.js.map +1 -0
- package/dist/lib/formatContentBlock.d.ts +10 -0
- package/dist/lib/formatContentBlock.d.ts.map +1 -0
- package/dist/lib/formatContentBlock.js +60 -0
- package/dist/lib/formatContentBlock.js.map +1 -0
- package/dist/lib/useTerminalSize.d.ts +5 -0
- package/dist/lib/useTerminalSize.d.ts.map +1 -0
- package/dist/lib/useTerminalSize.js +21 -0
- package/dist/lib/useTerminalSize.js.map +1 -0
- package/package.json +8 -5
- package/templates/prompt.md +1 -12
- package/templates/progress.md +0 -11
|
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from "react";
|
|
|
2
2
|
import { Box, Text, useApp } from "ink";
|
|
3
3
|
import { readFileSync } from "fs";
|
|
4
4
|
import { EventDisplay } from "./EventDisplay.js";
|
|
5
|
+
import { FullScreenLayout, useContentHeight } from "./FullScreenLayout.js";
|
|
5
6
|
export const ReplayLog = ({ filePath }) => {
|
|
6
7
|
const { exit } = useApp();
|
|
7
8
|
const [events, setEvents] = useState([]);
|
|
@@ -39,13 +40,11 @@ export const ReplayLog = ({ filePath }) => {
|
|
|
39
40
|
return (React.createElement(Box, { flexDirection: "column" },
|
|
40
41
|
React.createElement(Text, { color: "red" }, error)));
|
|
41
42
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
React.createElement(
|
|
48
|
-
React.createElement(Text, { dimColor: true }, "─".repeat(40))),
|
|
49
|
-
React.createElement(EventDisplay, { events: events })));
|
|
43
|
+
const footer = React.createElement(Text, { dimColor: true },
|
|
44
|
+
"Replaying: ",
|
|
45
|
+
filePath);
|
|
46
|
+
const contentHeight = useContentHeight(true);
|
|
47
|
+
return (React.createElement(FullScreenLayout, { title: "Ralph", footer: footer },
|
|
48
|
+
React.createElement(EventDisplay, { events: events, iteration: 1, completedIterations: [], height: contentHeight })));
|
|
50
49
|
};
|
|
51
50
|
//# sourceMappingURL=ReplayLog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReplayLog.js","sourceRoot":"","sources":["../../src/components/ReplayLog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAClD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"ReplayLog.js","sourceRoot":"","sources":["../../src/components/ReplayLog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAClD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAE1E,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EAAE,QAAQ,EAAS,EAAE,EAAE;IAC/C,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAA;IACzB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAiC,EAAE,CAAC,CAAA;IACxE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,EAAU,CAAA;IAE5C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YAC/C,yEAAyE;YACzE,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;YAEjE,MAAM,YAAY,GAAmC,EAAE,CAAA;YACvD,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;gBACpC,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;oBAClC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBAC1B,CAAC;gBAAC,MAAM,CAAC;oBACP,yBAAyB;gBAC3B,CAAC;YACH,CAAC;YAED,SAAS,CAAC,YAAY,CAAC,CAAA;YACvB,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,EAAE,CAAA;gBACN,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC,EAAE,GAAG,CAAC,CAAA;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,+BAA+B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YAC3F,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,EAAE,CAAA;gBACN,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC,EAAE,GAAG,CAAC,CAAA;QACT,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAA;IAEpB,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ;YACzB,oBAAC,IAAI,IAAC,KAAK,EAAC,KAAK,IAAE,KAAK,CAAQ,CAC5B,CACP,CAAA;IACH,CAAC;IAED,MAAM,MAAM,GAAG,oBAAC,IAAI,IAAC,QAAQ;;QAAa,QAAQ,CAAQ,CAAA;IAC1D,MAAM,aAAa,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAE5C,OAAO,CACL,oBAAC,gBAAgB,IAAC,KAAK,EAAC,OAAO,EAAC,MAAM,EAAE,MAAM;QAC5C,oBAAC,YAAY,IAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,mBAAmB,EAAE,EAAE,EAAE,MAAM,EAAE,aAAa,GAAI,CAC7E,CACpB,CAAA;AACH,CAAC,CAAA"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,GAAG,YAEf,CAAA"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAElC,MAAM,CAAC,MAAM,GAAG,GAAG,GAAG,EAAE;IACtB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AAC7B,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,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adds a todo item to the todo.md file and commits just that line.
|
|
3
|
+
* Inserts the todo into the working directory, stages only that line, and commits.
|
|
4
|
+
*/
|
|
5
|
+
export declare const addTodo: (description: string, cwd?: string) => void;
|
|
6
|
+
/**
|
|
7
|
+
* Inserts a todo item into the content, right after the "To do" header.
|
|
8
|
+
*/
|
|
9
|
+
export declare const insertTodo: (content: string, description: string) => string;
|
|
10
|
+
//# sourceMappingURL=addTodo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addTodo.d.ts","sourceRoot":"","sources":["../../src/lib/addTodo.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,eAAO,MAAM,OAAO,GAAI,aAAa,MAAM,EAAE,MAAK,MAAsB,KAAG,IAqC1E,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,EAAE,aAAa,MAAM,KAAG,MAmBjE,CAAA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import { readFileSync, writeFileSync } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
/**
|
|
5
|
+
* Adds a todo item to the todo.md file and commits just that line.
|
|
6
|
+
* Inserts the todo into the working directory, stages only that line, and commits.
|
|
7
|
+
*/
|
|
8
|
+
export const addTodo = (description, cwd = process.cwd()) => {
|
|
9
|
+
const todoPath = join(cwd, ".ralph", "todo.md");
|
|
10
|
+
// Read current working directory file and insert the new todo
|
|
11
|
+
const content = readFileSync(todoPath, "utf-8");
|
|
12
|
+
const newContent = insertTodo(content, description);
|
|
13
|
+
// Write updated content to working directory
|
|
14
|
+
writeFileSync(todoPath, newContent);
|
|
15
|
+
// Get what's currently in the index for this file (or HEAD if not staged)
|
|
16
|
+
const indexContent = execSync("git show :0:.ralph/todo.md 2>/dev/null || git show HEAD:.ralph/todo.md", {
|
|
17
|
+
cwd,
|
|
18
|
+
encoding: "utf-8",
|
|
19
|
+
});
|
|
20
|
+
// Create a blob with just the todo added to the index version
|
|
21
|
+
const indexWithTodo = insertTodo(indexContent, description);
|
|
22
|
+
const blobHash = execSync("git hash-object -w --stdin", {
|
|
23
|
+
cwd,
|
|
24
|
+
encoding: "utf-8",
|
|
25
|
+
input: indexWithTodo,
|
|
26
|
+
}).trim();
|
|
27
|
+
// Stage just our change by updating the index to this blob
|
|
28
|
+
execSync(`git update-index --cacheinfo 100644,${blobHash},.ralph/todo.md`, {
|
|
29
|
+
cwd,
|
|
30
|
+
stdio: "pipe",
|
|
31
|
+
});
|
|
32
|
+
// Commit just the staged change
|
|
33
|
+
execSync(`git commit -m "todo: ${description}"`, { cwd, stdio: "pipe" });
|
|
34
|
+
console.log(`✅ added`);
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Inserts a todo item into the content, right after the "To do" header.
|
|
38
|
+
*/
|
|
39
|
+
export const insertTodo = (content, description) => {
|
|
40
|
+
const lines = content.split("\n");
|
|
41
|
+
const todoHeaderIndex = lines.findIndex(line => /^###?\s*To\s*do/i.test(line));
|
|
42
|
+
if (todoHeaderIndex === -1) {
|
|
43
|
+
// No "To do" section found, add one at the beginning
|
|
44
|
+
return `### To do\n\n- [ ] ${description}\n\n${content}`;
|
|
45
|
+
}
|
|
46
|
+
// Find the first line after the header (skip empty lines)
|
|
47
|
+
let insertIndex = todoHeaderIndex + 1;
|
|
48
|
+
while (insertIndex < lines.length && lines[insertIndex].trim() === "") {
|
|
49
|
+
insertIndex++;
|
|
50
|
+
}
|
|
51
|
+
// Insert the new todo item
|
|
52
|
+
lines.splice(insertIndex, 0, `- [ ] ${description}`);
|
|
53
|
+
return lines.join("\n");
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=addTodo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addTodo.js","sourceRoot":"","sources":["../../src/lib/addTodo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,WAAmB,EAAE,MAAc,OAAO,CAAC,GAAG,EAAE,EAAQ,EAAE;IAChF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAA;IAE/C,8DAA8D;IAC9D,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IAC/C,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;IAEnD,6CAA6C;IAC7C,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IAEnC,0EAA0E;IAC1E,MAAM,YAAY,GAAG,QAAQ,CAC3B,wEAAwE,EACxE;QACE,GAAG;QACH,QAAQ,EAAE,OAAO;KAClB,CACF,CAAA;IAED,8DAA8D;IAC9D,MAAM,aAAa,GAAG,UAAU,CAAC,YAAY,EAAE,WAAW,CAAC,CAAA;IAC3D,MAAM,QAAQ,GAAG,QAAQ,CAAC,4BAA4B,EAAE;QACtD,GAAG;QACH,QAAQ,EAAE,OAAO;QACjB,KAAK,EAAE,aAAa;KACrB,CAAC,CAAC,IAAI,EAAE,CAAA;IAET,2DAA2D;IAC3D,QAAQ,CAAC,uCAAuC,QAAQ,iBAAiB,EAAE;QACzE,GAAG;QACH,KAAK,EAAE,MAAM;KACd,CAAC,CAAA;IAEF,gCAAgC;IAChC,QAAQ,CAAC,wBAAwB,WAAW,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IAExE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;AACxB,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAe,EAAE,WAAmB,EAAU,EAAE;IACzE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACjC,MAAM,eAAe,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAE9E,IAAI,eAAe,KAAK,CAAC,CAAC,EAAE,CAAC;QAC3B,qDAAqD;QACrD,OAAO,sBAAsB,WAAW,OAAO,OAAO,EAAE,CAAA;IAC1D,CAAC;IAED,0DAA0D;IAC1D,IAAI,WAAW,GAAG,eAAe,GAAG,CAAC,CAAA;IACrC,OAAO,WAAW,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACtE,WAAW,EAAE,CAAA;IACf,CAAC;IAED,2BAA2B;IAC3B,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC,CAAA;IAEpD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ContentBlock } from "../components/eventToBlocks.js";
|
|
2
|
+
/**
|
|
3
|
+
* Convert a content block to formatted string lines
|
|
4
|
+
*/
|
|
5
|
+
export declare const formatContentBlock: (block: ContentBlock) => string[];
|
|
6
|
+
/**
|
|
7
|
+
* Format an iteration header
|
|
8
|
+
*/
|
|
9
|
+
export declare const formatIterationHeader: (iteration: number) => string;
|
|
10
|
+
//# sourceMappingURL=formatContentBlock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatContentBlock.d.ts","sourceRoot":"","sources":["../../src/lib/formatContentBlock.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AA8ClE;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,YAAY,KAAG,MAAM,EAQ9D,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAAI,WAAW,MAAM,KAAG,MAEzD,CAAA"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
/**
|
|
3
|
+
* Format a text string with markdown-style formatting (bold and inline code)
|
|
4
|
+
*/
|
|
5
|
+
const formatText = (content) => {
|
|
6
|
+
let result = "";
|
|
7
|
+
let i = 0;
|
|
8
|
+
let inBold = false;
|
|
9
|
+
let inCode = false;
|
|
10
|
+
while (i < content.length) {
|
|
11
|
+
if (content[i] === "*" && content[i + 1] === "*") {
|
|
12
|
+
inBold = !inBold;
|
|
13
|
+
i += 2;
|
|
14
|
+
}
|
|
15
|
+
else if (content[i] === "`") {
|
|
16
|
+
inCode = !inCode;
|
|
17
|
+
i++;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
let char = content[i];
|
|
21
|
+
if (inCode) {
|
|
22
|
+
char = chalk.yellow(char);
|
|
23
|
+
}
|
|
24
|
+
else if (inBold) {
|
|
25
|
+
char = chalk.bold(char);
|
|
26
|
+
}
|
|
27
|
+
result += char;
|
|
28
|
+
i++;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Format a tool use block as a string
|
|
35
|
+
*/
|
|
36
|
+
const formatToolUse = (name, arg) => {
|
|
37
|
+
const formattedName = chalk.blue(name);
|
|
38
|
+
if (arg) {
|
|
39
|
+
return ` ${formattedName} ${chalk.dim(arg)}`;
|
|
40
|
+
}
|
|
41
|
+
return ` ${formattedName}`;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Convert a content block to formatted string lines
|
|
45
|
+
*/
|
|
46
|
+
export const formatContentBlock = (block) => {
|
|
47
|
+
if (block.type === "text") {
|
|
48
|
+
const formatted = formatText(block.content);
|
|
49
|
+
// Split into lines, preserving empty lines for paragraph breaks
|
|
50
|
+
return formatted.split("\n");
|
|
51
|
+
}
|
|
52
|
+
return [formatToolUse(block.name, block.arg)];
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Format an iteration header
|
|
56
|
+
*/
|
|
57
|
+
export const formatIterationHeader = (iteration) => {
|
|
58
|
+
return chalk.cyan.bold(`─── Iteration ${iteration} ───`);
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=formatContentBlock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatContentBlock.js","sourceRoot":"","sources":["../../src/lib/formatContentBlock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB;;GAEG;AACH,MAAM,UAAU,GAAG,CAAC,OAAe,EAAU,EAAE;IAC7C,IAAI,MAAM,GAAG,EAAE,CAAA;IACf,IAAI,CAAC,GAAG,CAAC,CAAA;IACT,IAAI,MAAM,GAAG,KAAK,CAAA;IAClB,IAAI,MAAM,GAAG,KAAK,CAAA;IAElB,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QAC1B,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACjD,MAAM,GAAG,CAAC,MAAM,CAAA;YAChB,CAAC,IAAI,CAAC,CAAA;QACR,CAAC;aAAM,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YAC9B,MAAM,GAAG,CAAC,MAAM,CAAA;YAChB,CAAC,EAAE,CAAA;QACL,CAAC;aAAM,CAAC;YACN,IAAI,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;YAErB,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;YAC3B,CAAC;iBAAM,IAAI,MAAM,EAAE,CAAC;gBAClB,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACzB,CAAC;YAED,MAAM,IAAI,IAAI,CAAA;YACd,CAAC,EAAE,CAAA;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,GAAY,EAAU,EAAE;IAC3D,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACtC,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,KAAK,aAAa,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAA;IAC/C,CAAC;IACD,OAAO,KAAK,aAAa,EAAE,CAAA;AAC7B,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAmB,EAAY,EAAE;IAClE,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAC3C,gEAAgE;QAChE,OAAO,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC9B,CAAC;IAED,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;AAC/C,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,SAAiB,EAAU,EAAE;IACjE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,SAAS,MAAM,CAAC,CAAA;AAC1D,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTerminalSize.d.ts","sourceRoot":"","sources":["../../src/lib/useTerminalSize.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe;;;CAuB3B,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
import { useStdout } from "ink";
|
|
3
|
+
export const useTerminalSize = () => {
|
|
4
|
+
const { stdout } = useStdout();
|
|
5
|
+
const getSize = () => ({
|
|
6
|
+
columns: stdout?.columns ?? 80,
|
|
7
|
+
rows: stdout?.rows ?? 24,
|
|
8
|
+
});
|
|
9
|
+
const [size, setSize] = useState(getSize);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const handleResize = () => {
|
|
12
|
+
setSize(getSize());
|
|
13
|
+
};
|
|
14
|
+
stdout?.on("resize", handleResize);
|
|
15
|
+
return () => {
|
|
16
|
+
stdout?.off("resize", handleResize);
|
|
17
|
+
};
|
|
18
|
+
}, [stdout]);
|
|
19
|
+
return size;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=useTerminalSize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTerminalSize.js","sourceRoot":"","sources":["../../src/lib/useTerminalSize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AAE/B,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE;IAClC,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAA;IAE9B,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,CAAC;QACrB,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,EAAE;QAC9B,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI,EAAE;KACzB,CAAC,CAAA;IAEF,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;IAEzC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,YAAY,GAAG,GAAG,EAAE;YACxB,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;QACpB,CAAC,CAAA;QAED,MAAM,EAAE,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;QAElC,OAAO,GAAG,EAAE;YACV,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;QACrC,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IAEZ,OAAO,IAAI,CAAA;AACb,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@herbcaudill/ralph",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Autonomous AI iteration engine for Claude CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -28,20 +28,22 @@
|
|
|
28
28
|
"url": "https://github.com/HerbCaudill/ralph.git"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.7",
|
|
31
32
|
"chalk": "^5.6.2",
|
|
32
33
|
"commander": "^14.0.2",
|
|
33
|
-
"execa": "^9.6.1",
|
|
34
34
|
"ink": "^6.6.0",
|
|
35
35
|
"ink-big-text": "^2.0.0",
|
|
36
36
|
"ink-gradient": "^3.0.0",
|
|
37
37
|
"ink-select-input": "^6.2.0",
|
|
38
38
|
"ink-spinner": "^5.0.0",
|
|
39
|
+
"ink-text-input": "^6.0.0",
|
|
39
40
|
"react": "^19.2.3"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"@types/node": "^24.10.1",
|
|
43
44
|
"@types/react": "^19.2.8",
|
|
44
45
|
"@vitest/ui": "^4.0.17",
|
|
46
|
+
"execa": "^9.6.1",
|
|
45
47
|
"ink-testing-library": "^4.0.0",
|
|
46
48
|
"prettier": "^3.5.3",
|
|
47
49
|
"tsx": "^4.21.0",
|
|
@@ -54,10 +56,11 @@
|
|
|
54
56
|
"scripts": {
|
|
55
57
|
"build": "tsc",
|
|
56
58
|
"dev": "tsc --watch",
|
|
59
|
+
"typecheck": "tsc --noEmit",
|
|
57
60
|
"ralph": "tsx src/index.ts",
|
|
58
|
-
"test": "
|
|
59
|
-
"test
|
|
60
|
-
"test:e2e": "
|
|
61
|
+
"test:all": "pnpm typecheck && pnpm test",
|
|
62
|
+
"test": "vitest --exclude test/e2e/** run",
|
|
63
|
+
"test:e2e": "vitest --config vitest.e2e.config.ts",
|
|
61
64
|
"test:watch": "vitest --watch",
|
|
62
65
|
"test:ui": "vitest --ui",
|
|
63
66
|
"format": "prettier --write ."
|
package/templates/prompt.md
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
## Context
|
|
2
|
-
|
|
3
|
-
You are working in a git worktree. Each iteration runs in an isolated worktree branch, and your changes will be automatically merged back to the main branch when this iteration completes.
|
|
4
|
-
|
|
5
|
-
## Workflow
|
|
6
|
-
|
|
7
1
|
Before doing anything, check that the project builds successfully. Run your project's build/typecheck commands and tests.
|
|
8
2
|
|
|
9
3
|
If there are build errors or test failures: YOUR ONLY TASK IS TO FIX THEM.
|
|
@@ -19,10 +13,5 @@ When you complete a task, before committing:
|
|
|
19
13
|
- Check that the project builds successfully and tests pass
|
|
20
14
|
- Where applicable, add tests to validate your changes and confirm that they pass
|
|
21
15
|
- Update the todo list by checking off the completed task and moving it to the "Done" section
|
|
22
|
-
- Append your progress to the @.ralph/progress.md file. Use this to leave a note for the next person working in the codebase
|
|
23
|
-
|
|
24
|
-
Make one git commit for this task.
|
|
25
|
-
|
|
26
|
-
If merge conflicts occur when your changes are merged back to main, resolve them in the next iteration. The merge process happens automatically after each iteration completes.
|
|
27
16
|
|
|
28
|
-
If, while implementing the task, you notice the todo list is complete, output <promise>COMPLETE</promise> and exit.
|
|
17
|
+
Make one git commit for this task. If, while implementing the task, you notice the todo list is complete, output <promise>COMPLETE</promise> and exit.
|
package/templates/progress.md
DELETED