@herbcaudill/ralph 0.2.0 → 0.4.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.
Files changed (175) hide show
  1. package/bin/ralph.js +1 -1
  2. package/dist/cli.d.ts +2 -19
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +30 -65
  5. package/dist/cli.js.map +1 -1
  6. package/dist/components/App.d.ts +10 -0
  7. package/dist/components/App.d.ts.map +1 -0
  8. package/dist/components/App.js +16 -0
  9. package/dist/components/App.js.map +1 -0
  10. package/dist/components/EventDisplay.d.ts +7 -0
  11. package/dist/components/EventDisplay.d.ts.map +1 -0
  12. package/dist/components/EventDisplay.js +64 -0
  13. package/dist/components/EventDisplay.js.map +1 -0
  14. package/dist/components/EventDisplay.replay.test.d.ts +2 -0
  15. package/dist/components/EventDisplay.replay.test.d.ts.map +1 -0
  16. package/dist/components/EventDisplay.replay.test.js +403 -0
  17. package/dist/components/EventDisplay.replay.test.js.map +1 -0
  18. package/dist/components/EventDisplay.test.d.ts +2 -0
  19. package/dist/components/EventDisplay.test.d.ts.map +1 -0
  20. package/dist/components/EventDisplay.test.js +223 -0
  21. package/dist/components/EventDisplay.test.js.map +1 -0
  22. package/dist/components/Header.d.ts +8 -0
  23. package/dist/components/Header.d.ts.map +1 -0
  24. package/dist/components/Header.js +15 -0
  25. package/dist/components/Header.js.map +1 -0
  26. package/dist/components/Header.test.d.ts +2 -0
  27. package/dist/components/Header.test.d.ts.map +1 -0
  28. package/dist/components/Header.test.js +27 -0
  29. package/dist/components/Header.test.js.map +1 -0
  30. package/dist/components/InitRalph.d.ts +3 -0
  31. package/dist/components/InitRalph.d.ts.map +1 -0
  32. package/dist/components/InitRalph.js +100 -0
  33. package/dist/components/InitRalph.js.map +1 -0
  34. package/dist/components/IterationRunner.d.ts +7 -0
  35. package/dist/components/IterationRunner.d.ts.map +1 -0
  36. package/dist/components/IterationRunner.js +286 -0
  37. package/dist/components/IterationRunner.js.map +1 -0
  38. package/dist/components/IterationRunner.test.d.ts +2 -0
  39. package/dist/components/IterationRunner.test.d.ts.map +1 -0
  40. package/dist/components/IterationRunner.test.js +109 -0
  41. package/dist/components/IterationRunner.test.js.map +1 -0
  42. package/dist/components/ReplayLog.d.ts +7 -0
  43. package/dist/components/ReplayLog.d.ts.map +1 -0
  44. package/dist/components/ReplayLog.js +51 -0
  45. package/dist/components/ReplayLog.js.map +1 -0
  46. package/dist/components/StreamingText.d.ts +7 -0
  47. package/dist/components/StreamingText.d.ts.map +1 -0
  48. package/dist/components/StreamingText.js +36 -0
  49. package/dist/components/StreamingText.js.map +1 -0
  50. package/dist/components/StreamingText.test.d.ts +2 -0
  51. package/dist/components/StreamingText.test.d.ts.map +1 -0
  52. package/dist/components/StreamingText.test.js +86 -0
  53. package/dist/components/StreamingText.test.js.map +1 -0
  54. package/dist/components/ToolUse.d.ts +8 -0
  55. package/dist/components/ToolUse.d.ts.map +1 -0
  56. package/dist/components/ToolUse.js +10 -0
  57. package/dist/components/ToolUse.js.map +1 -0
  58. package/dist/components/ToolUse.test.d.ts +2 -0
  59. package/dist/components/ToolUse.test.d.ts.map +1 -0
  60. package/dist/components/ToolUse.test.js +43 -0
  61. package/dist/components/ToolUse.test.js.map +1 -0
  62. package/dist/components/eventToBlocks.d.ts +12 -0
  63. package/dist/components/eventToBlocks.d.ts.map +1 -0
  64. package/dist/components/eventToBlocks.js +142 -0
  65. package/dist/components/eventToBlocks.js.map +1 -0
  66. package/dist/components/eventToBlocks.test.d.ts +2 -0
  67. package/dist/components/eventToBlocks.test.d.ts.map +1 -0
  68. package/dist/components/eventToBlocks.test.js +412 -0
  69. package/dist/components/eventToBlocks.test.js.map +1 -0
  70. package/dist/index.d.ts +1 -0
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +3 -21
  73. package/dist/index.js.map +1 -1
  74. package/dist/lib/cleanupAllWorktrees.d.ts +5 -0
  75. package/dist/lib/cleanupAllWorktrees.d.ts.map +1 -0
  76. package/dist/lib/cleanupAllWorktrees.js +25 -0
  77. package/dist/lib/cleanupAllWorktrees.js.map +1 -0
  78. package/dist/lib/cleanupWorktree.d.ts +6 -0
  79. package/dist/lib/cleanupWorktree.d.ts.map +1 -0
  80. package/dist/lib/cleanupWorktree.js +33 -0
  81. package/dist/lib/cleanupWorktree.js.map +1 -0
  82. package/dist/lib/copyRalphFilesFromWorktree.d.ts +5 -0
  83. package/dist/lib/copyRalphFilesFromWorktree.d.ts.map +1 -0
  84. package/dist/lib/copyRalphFilesFromWorktree.js +19 -0
  85. package/dist/lib/copyRalphFilesFromWorktree.js.map +1 -0
  86. package/dist/lib/copyRalphFilesToWorktree.d.ts +5 -0
  87. package/dist/lib/copyRalphFilesToWorktree.d.ts.map +1 -0
  88. package/dist/lib/copyRalphFilesToWorktree.js +21 -0
  89. package/dist/lib/copyRalphFilesToWorktree.js.map +1 -0
  90. package/dist/lib/createWorktree.d.ts +6 -0
  91. package/dist/lib/createWorktree.d.ts.map +1 -0
  92. package/dist/lib/createWorktree.js +34 -0
  93. package/dist/lib/createWorktree.js.map +1 -0
  94. package/dist/lib/getClaudeVersion.d.ts +2 -0
  95. package/dist/lib/getClaudeVersion.d.ts.map +1 -0
  96. package/dist/lib/getClaudeVersion.js +17 -0
  97. package/dist/lib/getClaudeVersion.js.map +1 -0
  98. package/dist/lib/getClaudeVersion.test.d.ts +2 -0
  99. package/dist/lib/getClaudeVersion.test.d.ts.map +1 -0
  100. package/dist/lib/getClaudeVersion.test.js +39 -0
  101. package/dist/lib/getClaudeVersion.test.js.map +1 -0
  102. package/dist/lib/getGitRoot.d.ts +5 -0
  103. package/dist/lib/getGitRoot.d.ts.map +1 -0
  104. package/dist/lib/getGitRoot.js +18 -0
  105. package/dist/lib/getGitRoot.js.map +1 -0
  106. package/dist/lib/installDependencies.d.ts +5 -0
  107. package/dist/lib/installDependencies.d.ts.map +1 -0
  108. package/dist/lib/installDependencies.js +23 -0
  109. package/dist/lib/installDependencies.js.map +1 -0
  110. package/dist/lib/installDependencies.test.d.ts +2 -0
  111. package/dist/lib/installDependencies.test.d.ts.map +1 -0
  112. package/dist/lib/installDependencies.test.js +37 -0
  113. package/dist/lib/installDependencies.test.js.map +1 -0
  114. package/dist/lib/mergeWorktreeToMain.d.ts +6 -0
  115. package/dist/lib/mergeWorktreeToMain.d.ts.map +1 -0
  116. package/dist/lib/mergeWorktreeToMain.js +44 -0
  117. package/dist/lib/mergeWorktreeToMain.js.map +1 -0
  118. package/dist/lib/popStash.d.ts +5 -0
  119. package/dist/lib/popStash.d.ts.map +1 -0
  120. package/dist/lib/popStash.js +17 -0
  121. package/dist/lib/popStash.js.map +1 -0
  122. package/dist/lib/rel.test.d.ts +2 -0
  123. package/dist/lib/rel.test.d.ts.map +1 -0
  124. package/dist/lib/rel.test.js +36 -0
  125. package/dist/lib/rel.test.js.map +1 -0
  126. package/dist/lib/replayLog.d.ts.map +1 -1
  127. package/dist/lib/replayLog.js +20 -6
  128. package/dist/lib/replayLog.js.map +1 -1
  129. package/dist/lib/runIteration.d.ts.map +1 -1
  130. package/dist/lib/runIteration.js +18 -8
  131. package/dist/lib/runIteration.js.map +1 -1
  132. package/dist/lib/shortenTempPaths.test.d.ts +2 -0
  133. package/dist/lib/shortenTempPaths.test.d.ts.map +1 -0
  134. package/dist/lib/shortenTempPaths.test.js +46 -0
  135. package/dist/lib/shortenTempPaths.test.js.map +1 -0
  136. package/dist/lib/signalHandler.d.ts +3 -0
  137. package/dist/lib/signalHandler.d.ts.map +1 -0
  138. package/dist/lib/signalHandler.js +23 -0
  139. package/dist/lib/signalHandler.js.map +1 -0
  140. package/dist/lib/stashChanges.d.ts +6 -0
  141. package/dist/lib/stashChanges.d.ts.map +1 -0
  142. package/dist/lib/stashChanges.js +27 -0
  143. package/dist/lib/stashChanges.js.map +1 -0
  144. package/dist/lib/types.d.ts +8 -0
  145. package/dist/lib/types.d.ts.map +1 -0
  146. package/dist/lib/types.js +5 -0
  147. package/dist/lib/types.js.map +1 -0
  148. package/dist/lib/worktree.d.ts +43 -0
  149. package/dist/lib/worktree.d.ts.map +1 -0
  150. package/dist/lib/worktree.js +210 -0
  151. package/dist/lib/worktree.js.map +1 -0
  152. package/dist/ui/EventProcessor.d.ts +11 -0
  153. package/dist/ui/EventProcessor.d.ts.map +1 -0
  154. package/dist/ui/EventProcessor.js +95 -0
  155. package/dist/ui/EventProcessor.js.map +1 -0
  156. package/dist/ui/IterationApp.d.ts +10 -0
  157. package/dist/ui/IterationApp.d.ts.map +1 -0
  158. package/dist/ui/IterationApp.js +21 -0
  159. package/dist/ui/IterationApp.js.map +1 -0
  160. package/dist/ui/IterationUI.d.ts +13 -0
  161. package/dist/ui/IterationUI.d.ts.map +1 -0
  162. package/dist/ui/IterationUI.js +19 -0
  163. package/dist/ui/IterationUI.js.map +1 -0
  164. package/dist/ui/TextDisplay.d.ts +7 -0
  165. package/dist/ui/TextDisplay.d.ts.map +1 -0
  166. package/dist/ui/TextDisplay.js +41 -0
  167. package/dist/ui/TextDisplay.js.map +1 -0
  168. package/dist/ui/ToolUseDisplay.d.ts +10 -0
  169. package/dist/ui/ToolUseDisplay.d.ts.map +1 -0
  170. package/dist/ui/ToolUseDisplay.js +10 -0
  171. package/dist/ui/ToolUseDisplay.js.map +1 -0
  172. package/package.json +23 -4
  173. package/templates/progress.md +1 -1
  174. package/templates/prompt.md +11 -1
  175. package/templates/todo.md +0 -1
@@ -0,0 +1,23 @@
1
+ // Global cleanup function registry for SIGINT/SIGTERM handling
2
+ let cleanupFn = null;
3
+ let isCleaningUp = false;
4
+ export const registerCleanup = (fn) => {
5
+ cleanupFn = fn;
6
+ };
7
+ export const unregisterCleanup = () => {
8
+ cleanupFn = null;
9
+ };
10
+ const handleSignal = async () => {
11
+ // Prevent double handling
12
+ if (isCleaningUp)
13
+ return;
14
+ isCleaningUp = true;
15
+ if (cleanupFn) {
16
+ await cleanupFn();
17
+ }
18
+ process.exit(0);
19
+ };
20
+ // Register handlers once at module load
21
+ process.on("SIGINT", () => handleSignal());
22
+ process.on("SIGTERM", () => handleSignal());
23
+ //# sourceMappingURL=signalHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signalHandler.js","sourceRoot":"","sources":["../../src/lib/signalHandler.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,IAAI,SAAS,GAAwC,IAAI,CAAA;AACzD,IAAI,YAAY,GAAG,KAAK,CAAA;AAExB,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAA8B,EAAE,EAAE;IAChE,SAAS,GAAG,EAAE,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,EAAE;IACpC,SAAS,GAAG,IAAI,CAAA;AAClB,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,KAAK,IAAI,EAAE;IAC9B,0BAA0B;IAC1B,IAAI,YAAY;QAAE,OAAM;IACxB,YAAY,GAAG,IAAI,CAAA;IAEnB,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,SAAS,EAAE,CAAA;IACnB,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAA;AAED,wCAAwC;AACxC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,YAAY,EAAE,CAAC,CAAA;AAC1C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,YAAY,EAAE,CAAC,CAAA"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Stash any uncommitted changes in the main repository
3
+ * Returns true if changes were stashed, false if working tree was clean
4
+ */
5
+ export declare function stashChanges(repoRoot: string): boolean;
6
+ //# sourceMappingURL=stashChanges.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stashChanges.d.ts","sourceRoot":"","sources":["../../src/lib/stashChanges.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAuBtD"}
@@ -0,0 +1,27 @@
1
+ import { execSync } from "child_process";
2
+ import { execOptions } from "./types.js";
3
+ /**
4
+ * Stash any uncommitted changes in the main repository
5
+ * Returns true if changes were stashed, false if working tree was clean
6
+ */
7
+ export function stashChanges(repoRoot) {
8
+ try {
9
+ // Check if there are any changes to stash
10
+ const status = execSync("git status --porcelain", {
11
+ ...execOptions,
12
+ cwd: repoRoot,
13
+ });
14
+ if (!status.toString().trim()) {
15
+ return false; // Nothing to stash
16
+ }
17
+ execSync("git stash push --include-untracked -m 'Ralph: stashing changes before worktree iterations'", {
18
+ ...execOptions,
19
+ cwd: repoRoot,
20
+ });
21
+ return true;
22
+ }
23
+ catch (error) {
24
+ throw new Error(`Failed to stash changes: ${error}`);
25
+ }
26
+ }
27
+ //# sourceMappingURL=stashChanges.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stashChanges.js","sourceRoot":"","sources":["../../src/lib/stashChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAExC;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,IAAI,CAAC;QACH,0CAA0C;QAC1C,MAAM,MAAM,GAAG,QAAQ,CAAC,wBAAwB,EAAE;YAChD,GAAG,WAAW;YACd,GAAG,EAAE,QAAQ;SACd,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAA,CAAC,mBAAmB;QAClC,CAAC;QAED,QAAQ,CACN,4FAA4F,EAC5F;YACE,GAAG,WAAW;YACd,GAAG,EAAE,QAAQ;SACd,CACF,CAAA;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,EAAE,CAAC,CAAA;IACtD,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { ExecSyncOptions } from "child_process";
2
+ export interface WorktreeInfo {
3
+ path: string;
4
+ branch: string;
5
+ guid: string;
6
+ }
7
+ export declare const execOptions: ExecSyncOptions;
8
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAE/C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb;AAED,eAAO,MAAM,WAAW,EAAE,eAGzB,CAAA"}
@@ -0,0 +1,5 @@
1
+ export const execOptions = {
2
+ stdio: "pipe",
3
+ encoding: "utf-8",
4
+ };
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,WAAW,GAAoB;IAC1C,KAAK,EAAE,MAAM;IACb,QAAQ,EAAE,OAAO;CAClB,CAAA"}
@@ -0,0 +1,43 @@
1
+ export interface WorktreeInfo {
2
+ path: string;
3
+ branch: string;
4
+ guid: string;
5
+ }
6
+ /**
7
+ * Get the root directory of the git repository
8
+ */
9
+ export declare function getGitRoot(cwd: string): string;
10
+ /**
11
+ * Stash any uncommitted changes in the main repository
12
+ * Returns true if changes were stashed, false if working tree was clean
13
+ */
14
+ export declare function stashChanges(repoRoot: string): boolean;
15
+ /**
16
+ * Pop the most recent stash
17
+ */
18
+ export declare function popStash(repoRoot: string): void;
19
+ /**
20
+ * Create a new git worktree for an iteration
21
+ */
22
+ export declare function createWorktree(repoRoot: string): WorktreeInfo;
23
+ /**
24
+ * Copy .ralph files from main repo to worktree
25
+ */
26
+ export declare function copyRalphFilesToWorktree(repoRoot: string, worktreePath: string): void;
27
+ /**
28
+ * Copy updated .ralph files from worktree back to main repo
29
+ */
30
+ export declare function copyRalphFilesFromWorktree(repoRoot: string, worktreePath: string): void;
31
+ /**
32
+ * Merge worktree changes back to main branch and commit
33
+ */
34
+ export declare function mergeWorktreeToMain(repoRoot: string, worktree: WorktreeInfo): void;
35
+ /**
36
+ * Remove a worktree and its branch
37
+ */
38
+ export declare function cleanupWorktree(repoRoot: string, worktree: WorktreeInfo): void;
39
+ /**
40
+ * Clean up all ralph worktrees (useful for recovery)
41
+ */
42
+ export declare function cleanupAllWorktrees(repoRoot: string): void;
43
+ //# sourceMappingURL=worktree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/lib/worktree.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb;AAOD;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAU9C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAoBtD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAS/C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAwB7D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,IAAI,CAgBN;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,IAAI,CAaN;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,YAAY,GACrB,IAAI,CA2CN;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,YAAY,GACrB,IAAI,CAyBN;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAe1D"}
@@ -0,0 +1,210 @@
1
+ import { execSync } from "child_process";
2
+ import { copyFileSync, mkdirSync, rmSync, existsSync } from "fs";
3
+ import { tmpdir } from "os";
4
+ import { join } from "path";
5
+ import { randomUUID } from "crypto";
6
+ const execOptions = {
7
+ stdio: "pipe",
8
+ encoding: "utf-8",
9
+ };
10
+ /**
11
+ * Get the root directory of the git repository
12
+ */
13
+ export function getGitRoot(cwd) {
14
+ try {
15
+ const root = execSync("git rev-parse --show-toplevel", {
16
+ ...execOptions,
17
+ cwd,
18
+ });
19
+ return root.toString().trim();
20
+ }
21
+ catch (error) {
22
+ throw new Error("Not in a git repository");
23
+ }
24
+ }
25
+ /**
26
+ * Stash any uncommitted changes in the main repository
27
+ * Returns true if changes were stashed, false if working tree was clean
28
+ */
29
+ export function stashChanges(repoRoot) {
30
+ try {
31
+ // Check if there are any changes to stash
32
+ const status = execSync("git status --porcelain", {
33
+ ...execOptions,
34
+ cwd: repoRoot,
35
+ });
36
+ if (!status.toString().trim()) {
37
+ return false; // Nothing to stash
38
+ }
39
+ execSync("git stash push --include-untracked -m 'Ralph: stashing changes before worktree iterations'", {
40
+ ...execOptions,
41
+ cwd: repoRoot,
42
+ });
43
+ return true;
44
+ }
45
+ catch (error) {
46
+ throw new Error(`Failed to stash changes: ${error}`);
47
+ }
48
+ }
49
+ /**
50
+ * Pop the most recent stash
51
+ */
52
+ export function popStash(repoRoot) {
53
+ try {
54
+ execSync("git stash pop", {
55
+ ...execOptions,
56
+ cwd: repoRoot,
57
+ });
58
+ }
59
+ catch (error) {
60
+ throw new Error(`Failed to pop stash: ${error}`);
61
+ }
62
+ }
63
+ /**
64
+ * Create a new git worktree for an iteration
65
+ */
66
+ export function createWorktree(repoRoot) {
67
+ const guid = randomUUID();
68
+ const branch = `ralph-${guid}`;
69
+ const worktreesDir = join(tmpdir(), "ralph-worktrees");
70
+ const worktreePath = join(worktreesDir, guid);
71
+ try {
72
+ // Ensure worktrees directory exists
73
+ mkdirSync(worktreesDir, { recursive: true });
74
+ // Create worktree with new branch from current HEAD
75
+ execSync(`git worktree add -b ${branch} "${worktreePath}"`, {
76
+ ...execOptions,
77
+ cwd: repoRoot,
78
+ });
79
+ return {
80
+ path: worktreePath,
81
+ branch,
82
+ guid,
83
+ };
84
+ }
85
+ catch (error) {
86
+ throw new Error(`Failed to create worktree: ${error}`);
87
+ }
88
+ }
89
+ /**
90
+ * Copy .ralph files from main repo to worktree
91
+ */
92
+ export function copyRalphFilesToWorktree(repoRoot, worktreePath) {
93
+ const ralphDir = join(repoRoot, ".ralph");
94
+ const worktreeRalphDir = join(worktreePath, ".ralph");
95
+ // Create .ralph directory in worktree
96
+ mkdirSync(worktreeRalphDir, { recursive: true });
97
+ // Copy required files
98
+ const files = ["prompt.md", "todo.md", "progress.md"];
99
+ for (const file of files) {
100
+ const src = join(ralphDir, file);
101
+ const dest = join(worktreeRalphDir, file);
102
+ if (existsSync(src)) {
103
+ copyFileSync(src, dest);
104
+ }
105
+ }
106
+ }
107
+ /**
108
+ * Copy updated .ralph files from worktree back to main repo
109
+ */
110
+ export function copyRalphFilesFromWorktree(repoRoot, worktreePath) {
111
+ const ralphDir = join(repoRoot, ".ralph");
112
+ const worktreeRalphDir = join(worktreePath, ".ralph");
113
+ // Copy back todo.md and progress.md (prompt.md doesn't change)
114
+ const files = ["todo.md", "progress.md"];
115
+ for (const file of files) {
116
+ const src = join(worktreeRalphDir, file);
117
+ const dest = join(ralphDir, file);
118
+ if (existsSync(src)) {
119
+ copyFileSync(src, dest);
120
+ }
121
+ }
122
+ }
123
+ /**
124
+ * Merge worktree changes back to main branch and commit
125
+ */
126
+ export function mergeWorktreeToMain(repoRoot, worktree) {
127
+ try {
128
+ // First, ensure all changes in worktree are committed
129
+ // (Claude should have done this, but let's be safe)
130
+ const status = execSync("git status --porcelain", {
131
+ ...execOptions,
132
+ cwd: worktree.path,
133
+ });
134
+ if (status.toString().trim()) {
135
+ // There are uncommitted changes - commit them
136
+ execSync("git add -A", {
137
+ ...execOptions,
138
+ cwd: worktree.path,
139
+ });
140
+ execSync(`git commit -m "Ralph iteration ${worktree.guid}: auto-commit remaining changes"`, {
141
+ ...execOptions,
142
+ cwd: worktree.path,
143
+ });
144
+ }
145
+ // Get current branch in main repo
146
+ const currentBranch = execSync("git branch --show-current", {
147
+ ...execOptions,
148
+ cwd: repoRoot,
149
+ }).toString().trim();
150
+ // Merge the worktree branch into current branch
151
+ execSync(`git merge --no-ff ${worktree.branch} -m "Merge iteration ${worktree.guid}"`, {
152
+ ...execOptions,
153
+ cwd: repoRoot,
154
+ });
155
+ }
156
+ catch (error) {
157
+ // If merge fails, it might be due to conflicts
158
+ throw new Error(`Failed to merge worktree to main: ${error}\n\n` +
159
+ `You may need to resolve conflicts manually in the main repository.`);
160
+ }
161
+ }
162
+ /**
163
+ * Remove a worktree and its branch
164
+ */
165
+ export function cleanupWorktree(repoRoot, worktree) {
166
+ try {
167
+ // Remove the worktree
168
+ execSync(`git worktree remove "${worktree.path}" --force`, {
169
+ ...execOptions,
170
+ cwd: repoRoot,
171
+ });
172
+ // Delete the branch
173
+ execSync(`git branch -D ${worktree.branch}`, {
174
+ ...execOptions,
175
+ cwd: repoRoot,
176
+ });
177
+ }
178
+ catch (error) {
179
+ // Try to clean up the directory even if git commands fail
180
+ try {
181
+ if (existsSync(worktree.path)) {
182
+ rmSync(worktree.path, { recursive: true, force: true });
183
+ }
184
+ }
185
+ catch {
186
+ // Ignore cleanup errors
187
+ }
188
+ console.error(`Warning: Failed to fully cleanup worktree: ${error}`);
189
+ }
190
+ }
191
+ /**
192
+ * Clean up all ralph worktrees (useful for recovery)
193
+ */
194
+ export function cleanupAllWorktrees(repoRoot) {
195
+ try {
196
+ const worktreesDir = join(tmpdir(), "ralph-worktrees");
197
+ if (existsSync(worktreesDir)) {
198
+ rmSync(worktreesDir, { recursive: true, force: true });
199
+ }
200
+ // Prune any stale worktree references
201
+ execSync("git worktree prune", {
202
+ ...execOptions,
203
+ cwd: repoRoot,
204
+ });
205
+ }
206
+ catch (error) {
207
+ console.error(`Warning: Failed to cleanup all worktrees: ${error}`);
208
+ }
209
+ }
210
+ //# sourceMappingURL=worktree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree.js","sourceRoot":"","sources":["../../src/lib/worktree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export declare class EventProcessor {
2
+ private onTextDelta;
3
+ private onToolUse;
4
+ constructor(handlers: {
5
+ onTextDelta: (text: string) => void;
6
+ onToolUse: (name: string, arg?: string) => void;
7
+ });
8
+ processEvent(event: Record<string, unknown>): void;
9
+ private processToolUse;
10
+ }
11
+ //# sourceMappingURL=EventProcessor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventProcessor.d.ts","sourceRoot":"","sources":["../../src/ui/EventProcessor.ts"],"names":[],"mappings":"AAGA,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAwB;IAC3C,OAAO,CAAC,SAAS,CAAsC;gBAE3C,QAAQ,EAAE;QACpB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;QACnC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;KAChD;IAKD,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAwB3C,OAAO,CAAC,cAAc;CA0DvB"}
@@ -0,0 +1,95 @@
1
+ import { rel } from "../lib/rel.js";
2
+ import { shortenTempPaths } from "../lib/shortenTempPaths.js";
3
+ export class EventProcessor {
4
+ onTextDelta;
5
+ onToolUse;
6
+ constructor(handlers) {
7
+ this.onTextDelta = handlers.onTextDelta;
8
+ this.onToolUse = handlers.onToolUse;
9
+ }
10
+ processEvent(event) {
11
+ // Stream text deltas as they come in
12
+ if (event.type === "stream_event") {
13
+ const streamEvent = event.event;
14
+ const delta = streamEvent?.delta;
15
+ if (delta?.type === "text_delta" && delta.text) {
16
+ this.onTextDelta(delta.text);
17
+ }
18
+ }
19
+ // Show tool uses
20
+ if (event.type === "assistant") {
21
+ const message = event.message;
22
+ const content = message?.content;
23
+ if (content) {
24
+ for (const block of content) {
25
+ if (block.type === "tool_use") {
26
+ this.processToolUse(block);
27
+ }
28
+ }
29
+ }
30
+ }
31
+ }
32
+ processToolUse(block) {
33
+ const input = block.input;
34
+ const name = block.name;
35
+ if (name === "Read") {
36
+ const filePath = input?.file_path;
37
+ if (filePath) {
38
+ this.onToolUse("Read", rel(filePath));
39
+ }
40
+ }
41
+ else if (name === "Edit" || name === "Write") {
42
+ const filePath = input?.file_path;
43
+ if (filePath) {
44
+ this.onToolUse(name, rel(filePath));
45
+ }
46
+ }
47
+ else if (name === "Bash") {
48
+ const command = input?.command;
49
+ if (command) {
50
+ this.onToolUse("$", shortenTempPaths(command));
51
+ }
52
+ }
53
+ else if (name === "Grep") {
54
+ const pattern = input?.pattern;
55
+ const path = input?.path;
56
+ this.onToolUse("Grep", `${pattern}${path ? ` in ${rel(path)}` : ""}`);
57
+ }
58
+ else if (name === "Glob") {
59
+ const pattern = input?.pattern;
60
+ const path = input?.path;
61
+ this.onToolUse("Glob", `${pattern}${path ? ` in ${rel(path)}` : ""}`);
62
+ }
63
+ else if (name === "TodoWrite") {
64
+ const todos = input?.todos;
65
+ if (todos?.length) {
66
+ const summary = todos
67
+ .map(t => `[${t.status === "completed" ? "x"
68
+ : t.status === "in_progress" ? "~"
69
+ : " "}] ${t.content}`)
70
+ .join("\n ");
71
+ this.onToolUse("TodoWrite", "\n " + summary);
72
+ }
73
+ else {
74
+ this.onToolUse("TodoWrite");
75
+ }
76
+ }
77
+ else if (name === "WebFetch") {
78
+ const url = input?.url;
79
+ this.onToolUse("WebFetch", url);
80
+ }
81
+ else if (name === "WebSearch") {
82
+ const query = input?.query;
83
+ this.onToolUse("WebSearch", query);
84
+ }
85
+ else if (name === "Task") {
86
+ const description = input?.description;
87
+ this.onToolUse("Task", description);
88
+ }
89
+ else if (name === "Skill") {
90
+ const skill = input?.skill;
91
+ this.onToolUse("Skill", skill);
92
+ }
93
+ }
94
+ }
95
+ //# sourceMappingURL=EventProcessor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventProcessor.js","sourceRoot":"","sources":["../../src/ui/EventProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAA;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAE7D,MAAM,OAAO,cAAc;IACjB,WAAW,CAAwB;IACnC,SAAS,CAAsC;IAEvD,YAAY,QAGX;QACC,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAA;QACvC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAA;IACrC,CAAC;IAED,YAAY,CAAC,KAA8B;QACzC,qCAAqC;QACrC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAClC,MAAM,WAAW,GAAG,KAAK,CAAC,KAA4C,CAAA;YACtE,MAAM,KAAK,GAAG,WAAW,EAAE,KAA4C,CAAA;YACvE,IAAI,KAAK,EAAE,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC/C,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAc,CAAC,CAAA;YACxC,CAAC;QACH,CAAC;QAED,iBAAiB;QACjB,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,KAAK,CAAC,OAA8C,CAAA;YACpE,MAAM,OAAO,GAAG,OAAO,EAAE,OAAqD,CAAA;YAC9E,IAAI,OAAO,EAAE,CAAC;gBACZ,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oBAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;wBAC9B,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;oBAC5B,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAEO,cAAc,CAAC,KAA8B;QACnD,MAAM,KAAK,GAAG,KAAK,CAAC,KAA4C,CAAA;QAChE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAc,CAAA;QAEjC,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,MAAM,QAAQ,GAAG,KAAK,EAAE,SAA+B,CAAA;YACvD,IAAI,QAAQ,EAAE,CAAC;gBACb,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;YACvC,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YAC/C,MAAM,QAAQ,GAAG,KAAK,EAAE,SAA+B,CAAA;YACvD,IAAI,QAAQ,EAAE,CAAC;gBACb,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;YACrC,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,KAAK,EAAE,OAA6B,CAAA;YACpD,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAA;YAChD,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,KAAK,EAAE,OAA6B,CAAA;YACpD,MAAM,IAAI,GAAG,KAAK,EAAE,IAA0B,CAAA;YAC9C,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QACvE,CAAC;aAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,KAAK,EAAE,OAA6B,CAAA;YACpD,MAAM,IAAI,GAAG,KAAK,EAAE,IAA0B,CAAA;YAC9C,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QACvE,CAAC;aAAM,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,KAAK,EAAE,KAA+D,CAAA;YACpF,IAAI,KAAK,EAAE,MAAM,EAAE,CAAC;gBAClB,MAAM,OAAO,GAAG,KAAK;qBAClB,GAAG,CACF,CAAC,CAAC,EAAE,CACF,IACE,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG;oBAC9B,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,GAAG;wBAClC,CAAC,CAAC,GACJ,KAAK,CAAC,CAAC,OAAO,EAAE,CACnB;qBACA,IAAI,CAAC,QAAQ,CAAC,CAAA;gBACjB,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAA;YACjD,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAA;YAC7B,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,KAAK,EAAE,GAAyB,CAAA;YAC5C,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;QACjC,CAAC;aAAM,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,KAAK,EAAE,KAA2B,CAAA;YAChD,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;QACpC,CAAC;aAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YAC3B,MAAM,WAAW,GAAG,KAAK,EAAE,WAAiC,CAAA;YAC5D,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;QACrC,CAAC;aAAM,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,KAAK,EAAE,KAA2B,CAAA;YAChD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QAChC,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { EventProcessor } from "./EventProcessor.js";
3
+ export declare const IterationApp: React.FC<Props>;
4
+ type Props = {
5
+ iteration: number;
6
+ totalIterations: number;
7
+ onProcessEvent: (processor: EventProcessor) => void;
8
+ };
9
+ export {};
10
+ //# sourceMappingURL=IterationApp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IterationApp.d.ts","sourceRoot":"","sources":["../../src/ui/IterationApp.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAA;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CA0BxC,CAAA;AAED,KAAK,KAAK,GAAG;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,EAAE,MAAM,CAAA;IACvB,cAAc,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAA;CACpD,CAAA"}
@@ -0,0 +1,21 @@
1
+ import React, { useState, useEffect } from "react";
2
+ import { IterationUI } from "./IterationUI.js";
3
+ import { EventProcessor } from "./EventProcessor.js";
4
+ export const IterationApp = ({ iteration, totalIterations, onProcessEvent }) => {
5
+ const [textContent, setTextContent] = useState("");
6
+ const [tools, setTools] = useState([]);
7
+ useEffect(() => {
8
+ const processor = new EventProcessor({
9
+ onTextDelta: (text) => {
10
+ setTextContent(prev => prev + text);
11
+ },
12
+ onToolUse: (name, arg) => {
13
+ setTools(prev => [...prev, { name, arg }]);
14
+ },
15
+ });
16
+ // Pass processor back to parent
17
+ onProcessEvent(processor);
18
+ }, [onProcessEvent]);
19
+ return (React.createElement(IterationUI, { iteration: iteration, totalIterations: totalIterations, textContent: textContent, tools: tools }));
20
+ };
21
+ //# sourceMappingURL=IterationApp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IterationApp.js","sourceRoot":"","sources":["../../src/ui/IterationApp.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,MAAM,CAAC,MAAM,YAAY,GAAoB,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,cAAc,EAAE,EAAE,EAAE;IAC9F,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAClD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAwC,EAAE,CAAC,CAAA;IAE7E,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,SAAS,GAAG,IAAI,cAAc,CAAC;YACnC,WAAW,EAAE,CAAC,IAAY,EAAE,EAAE;gBAC5B,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;YACrC,CAAC;YACD,SAAS,EAAE,CAAC,IAAY,EAAE,GAAY,EAAE,EAAE;gBACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;YAC5C,CAAC;SACF,CAAC,CAAA;QAEF,gCAAgC;QAChC,cAAc,CAAC,SAAS,CAAC,CAAA;IAC3B,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAA;IAEpB,OAAO,CACL,oBAAC,WAAW,IACV,SAAS,EAAE,SAAS,EACpB,eAAe,EAAE,eAAe,EAChC,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,KAAK,GACZ,CACH,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ export declare const IterationUI: React.FC<Props>;
3
+ type Props = {
4
+ iteration: number;
5
+ totalIterations: number;
6
+ textContent: string;
7
+ tools: Array<{
8
+ name: string;
9
+ arg?: string;
10
+ }>;
11
+ };
12
+ export {};
13
+ //# sourceMappingURL=IterationUI.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IterationUI.d.ts","sourceRoot":"","sources":["../../src/ui/IterationUI.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CA8BvC,CAAA;AAED,KAAK,KAAK,GAAG;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,EAAE,MAAM,CAAA;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC7C,CAAA"}
@@ -0,0 +1,19 @@
1
+ import { Box, Text } from "ink";
2
+ import React from "react";
3
+ import { ToolUseDisplay } from "./ToolUseDisplay.js";
4
+ import { TextDisplay } from "./TextDisplay.js";
5
+ export const IterationUI = ({ iteration, totalIterations, textContent, tools }) => {
6
+ return (React.createElement(Box, { flexDirection: "column" },
7
+ React.createElement(Box, { marginBottom: 1 },
8
+ React.createElement(Text, { color: "cyan", bold: true },
9
+ "Iteration ",
10
+ iteration),
11
+ totalIterations > 0 && (React.createElement(Text, { color: "dim" },
12
+ " of ",
13
+ totalIterations))),
14
+ React.createElement(Box, { marginBottom: 1 },
15
+ React.createElement(Text, { color: "dim" }, "─".repeat(40))),
16
+ tools.length > 0 && (React.createElement(ToolUseDisplay, { tools: tools })),
17
+ textContent && (React.createElement(TextDisplay, { content: textContent }))));
18
+ };
19
+ //# sourceMappingURL=IterationUI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IterationUI.js","sourceRoot":"","sources":["../../src/ui/IterationUI.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,MAAM,CAAC,MAAM,WAAW,GAAoB,CAAC,EAC3C,SAAS,EACT,eAAe,EACf,WAAW,EACX,KAAK,EACN,EAAE,EAAE;IACH,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ;QACzB,oBAAC,GAAG,IAAC,YAAY,EAAE,CAAC;YAClB,oBAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI;;gBACV,SAAS,CACf;YACN,eAAe,GAAG,CAAC,IAAI,CACtB,oBAAC,IAAI,IAAC,KAAK,EAAC,KAAK;;gBAAM,eAAe,CAAQ,CAC/C,CACG;QAEN,oBAAC,GAAG,IAAC,YAAY,EAAE,CAAC;YAClB,oBAAC,IAAI,IAAC,KAAK,EAAC,KAAK,IAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAQ,CACrC;QAEL,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CACnB,oBAAC,cAAc,IAAC,KAAK,EAAE,KAAK,GAAI,CACjC;QAEA,WAAW,IAAI,CACd,oBAAC,WAAW,IAAC,OAAO,EAAE,WAAW,GAAI,CACtC,CACG,CACP,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ export declare const TextDisplay: React.FC<Props>;
3
+ type Props = {
4
+ content: string;
5
+ };
6
+ export {};
7
+ //# sourceMappingURL=TextDisplay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextDisplay.d.ts","sourceRoot":"","sources":["../../src/ui/TextDisplay.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAavC,CAAA;AA2CD,KAAK,KAAK,GAAG;IACX,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA"}
@@ -0,0 +1,41 @@
1
+ import { Box, Text } from "ink";
2
+ import React from "react";
3
+ export const TextDisplay = ({ content }) => {
4
+ // Parse markdown-style formatting
5
+ const parts = parseFormatting(content);
6
+ return (React.createElement(Box, { flexDirection: "column" }, parts.map((part, index) => (React.createElement(Text, { key: index, bold: part.bold, color: part.code ? "yellow" : undefined }, part.text)))));
7
+ };
8
+ function parseFormatting(content) {
9
+ const parts = [];
10
+ let currentText = "";
11
+ let bold = false;
12
+ let code = false;
13
+ let i = 0;
14
+ while (i < content.length) {
15
+ if (content[i] === "*" && content[i + 1] === "*") {
16
+ if (currentText) {
17
+ parts.push({ text: currentText, bold, code });
18
+ currentText = "";
19
+ }
20
+ bold = !bold;
21
+ i += 2;
22
+ }
23
+ else if (content[i] === "`") {
24
+ if (currentText) {
25
+ parts.push({ text: currentText, bold, code });
26
+ currentText = "";
27
+ }
28
+ code = !code;
29
+ i++;
30
+ }
31
+ else {
32
+ currentText += content[i];
33
+ i++;
34
+ }
35
+ }
36
+ if (currentText) {
37
+ parts.push({ text: currentText, bold, code });
38
+ }
39
+ return parts;
40
+ }
41
+ //# sourceMappingURL=TextDisplay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextDisplay.js","sourceRoot":"","sources":["../../src/ui/TextDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,CAAC,MAAM,WAAW,GAAoB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;IAC1D,kCAAkC;IAClC,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAA;IAEtC,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,IACxB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAC1B,oBAAC,IAAI,IAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,IACvE,IAAI,CAAC,IAAI,CACL,CACR,CAAC,CACE,CACP,CAAA;AACH,CAAC,CAAA;AAQD,SAAS,eAAe,CAAC,OAAe;IACtC,MAAM,KAAK,GAAoB,EAAE,CAAA;IACjC,IAAI,WAAW,GAAG,EAAE,CAAA;IACpB,IAAI,IAAI,GAAG,KAAK,CAAA;IAChB,IAAI,IAAI,GAAG,KAAK,CAAA;IAChB,IAAI,CAAC,GAAG,CAAC,CAAA;IAET,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,IAAI,WAAW,EAAE,CAAC;gBAChB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;gBAC7C,WAAW,GAAG,EAAE,CAAA;YAClB,CAAC;YACD,IAAI,GAAG,CAAC,IAAI,CAAA;YACZ,CAAC,IAAI,CAAC,CAAA;QACR,CAAC;aAAM,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YAC9B,IAAI,WAAW,EAAE,CAAC;gBAChB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;gBAC7C,WAAW,GAAG,EAAE,CAAA;YAClB,CAAC;YACD,IAAI,GAAG,CAAC,IAAI,CAAA;YACZ,CAAC,EAAE,CAAA;QACL,CAAC;aAAM,CAAC;YACN,WAAW,IAAI,OAAO,CAAC,CAAC,CAAC,CAAA;YACzB,CAAC,EAAE,CAAA;QACL,CAAC;IACH,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IAC/C,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ export declare const ToolUseDisplay: React.FC<Props>;
3
+ type Props = {
4
+ tools: Array<{
5
+ name: string;
6
+ arg?: string;
7
+ }>;
8
+ };
9
+ export {};
10
+ //# sourceMappingURL=ToolUseDisplay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolUseDisplay.d.ts","sourceRoot":"","sources":["../../src/ui/ToolUseDisplay.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAa1C,CAAA;AAED,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC7C,CAAA"}