@towles/tool 0.0.53 → 0.0.55

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 (43) hide show
  1. package/README.md +82 -72
  2. package/package.json +8 -7
  3. package/src/commands/auto-claude.ts +219 -0
  4. package/src/commands/doctor.ts +1 -34
  5. package/src/config/settings.ts +0 -10
  6. package/src/lib/auto-claude/config.test.ts +53 -0
  7. package/src/lib/auto-claude/config.ts +68 -0
  8. package/src/lib/auto-claude/index.ts +14 -0
  9. package/src/lib/auto-claude/pipeline.test.ts +14 -0
  10. package/src/lib/auto-claude/pipeline.ts +64 -0
  11. package/src/lib/auto-claude/prompt-templates/01-prompt-research.md +28 -0
  12. package/src/lib/auto-claude/prompt-templates/02-prompt-plan.md +28 -0
  13. package/src/lib/auto-claude/prompt-templates/03-prompt-plan-annotations.md +21 -0
  14. package/src/lib/auto-claude/prompt-templates/04-prompt-plan-implementation.md +33 -0
  15. package/src/lib/auto-claude/prompt-templates/05-prompt-implement.md +31 -0
  16. package/src/lib/auto-claude/prompt-templates/06-prompt-review.md +30 -0
  17. package/src/lib/auto-claude/prompt-templates/07-prompt-refresh.md +39 -0
  18. package/src/lib/auto-claude/prompt-templates/index.test.ts +145 -0
  19. package/src/lib/auto-claude/prompt-templates/index.ts +44 -0
  20. package/src/lib/auto-claude/steps/create-pr.ts +93 -0
  21. package/src/lib/auto-claude/steps/fetch-issues.ts +64 -0
  22. package/src/lib/auto-claude/steps/implement.ts +63 -0
  23. package/src/lib/auto-claude/steps/plan-annotations.ts +54 -0
  24. package/src/lib/auto-claude/steps/plan-implementation.ts +14 -0
  25. package/src/lib/auto-claude/steps/plan.ts +14 -0
  26. package/src/lib/auto-claude/steps/refresh.ts +114 -0
  27. package/src/lib/auto-claude/steps/remove-label.ts +22 -0
  28. package/src/lib/auto-claude/steps/research.ts +21 -0
  29. package/src/lib/auto-claude/steps/review.ts +14 -0
  30. package/src/lib/auto-claude/utils.test.ts +136 -0
  31. package/src/lib/auto-claude/utils.ts +334 -0
  32. package/src/commands/ralph/plan/add.ts +0 -69
  33. package/src/commands/ralph/plan/done.ts +0 -82
  34. package/src/commands/ralph/plan/list.test.ts +0 -48
  35. package/src/commands/ralph/plan/list.ts +0 -100
  36. package/src/commands/ralph/plan/remove.ts +0 -71
  37. package/src/commands/ralph/run.test.ts +0 -607
  38. package/src/commands/ralph/run.ts +0 -362
  39. package/src/commands/ralph/show.ts +0 -88
  40. package/src/lib/ralph/execution.ts +0 -292
  41. package/src/lib/ralph/formatter.ts +0 -240
  42. package/src/lib/ralph/index.ts +0 -4
  43. package/src/lib/ralph/state.ts +0 -201
@@ -1,201 +0,0 @@
1
- import * as fs from "node:fs";
2
- import * as path from "node:path";
3
- import pc from "picocolors";
4
- import { z } from "zod";
5
- import type { RalphSettings } from "../../config/settings.js";
6
- import { RalphSettingsSchema } from "../../config/settings.js";
7
-
8
- // ============================================================================
9
- // Constants
10
- // ============================================================================
11
-
12
- export const DEFAULT_MAX_ITERATIONS = 10;
13
- export const DEFAULT_STATE_DIR = "./.claude/.ralph";
14
- export const DEFAULT_COMPLETION_MARKER = "RALPH_DONE";
15
- export const DEFAULT_TASK_DONE_MARKER = "TASK_DONE";
16
-
17
- // File names within stateDir
18
- const STATE_FILE_NAME = "ralph-state.local.json";
19
- const LOG_FILE_NAME = "ralph-log.local.md";
20
- const HISTORY_FILE_NAME = "ralph-history.local.log";
21
-
22
- // ============================================================================
23
- // Path Helpers (use stateDir from settings)
24
- // ============================================================================
25
-
26
- export function getRalphPaths(settings?: RalphSettings) {
27
- const stateDir = settings?.stateDir ?? RalphSettingsSchema.parse({}).stateDir;
28
- return {
29
- stateFile: path.join(stateDir, STATE_FILE_NAME),
30
- logFile: path.join(stateDir, LOG_FILE_NAME),
31
- historyFile: path.join(stateDir, HISTORY_FILE_NAME),
32
- };
33
- }
34
-
35
- // Defaults used in flag descriptions
36
- export const DEFAULT_STATE_FILE = `${DEFAULT_STATE_DIR}/${STATE_FILE_NAME}`;
37
- export const DEFAULT_LOG_FILE = `${DEFAULT_STATE_DIR}/${LOG_FILE_NAME}`;
38
- export const DEFAULT_HISTORY_FILE = `${DEFAULT_STATE_DIR}/${HISTORY_FILE_NAME}`;
39
-
40
- /**
41
- * Resolve ralph file path - uses flag value if provided, otherwise computes from settings
42
- */
43
- export function resolveRalphPath(
44
- flagValue: string | undefined,
45
- pathType: "stateFile" | "logFile" | "historyFile",
46
- settings?: RalphSettings,
47
- ): string {
48
- if (flagValue !== undefined) {
49
- return flagValue;
50
- }
51
- const paths = getRalphPaths(settings);
52
- return paths[pathType];
53
- }
54
- export const CLAUDE_DEFAULT_ARGS = [
55
- "--print",
56
- "--verbose",
57
- "--output-format",
58
- "stream-json",
59
- "--permission-mode",
60
- "bypassPermissions",
61
- ];
62
-
63
- // ============================================================================
64
- // State Validation Schemas
65
- // ============================================================================
66
-
67
- const PlanStatusSchema = z.enum(["ready", "done", "blocked", "cancelled"]);
68
-
69
- const RalphPlanSchema = z.object({
70
- id: z.number(),
71
- planFilePath: z.string(),
72
- status: PlanStatusSchema,
73
- addedAt: z.string(),
74
- completedAt: z.string().optional(),
75
- error: z.string().optional(),
76
- });
77
-
78
- const RalphStateSchema = z.object({
79
- version: z.number(),
80
- plans: z.array(RalphPlanSchema),
81
- startedAt: z.string(),
82
- status: z.enum(["running", "completed", "max_iterations_reached", "error"]),
83
- });
84
-
85
- // ============================================================================
86
- // Types (derived from Zod schemas)
87
- // ============================================================================
88
-
89
- export interface IterationHistory {
90
- iteration: number;
91
- startedAt: string;
92
- completedAt: string;
93
- durationMs: number;
94
- durationHuman: string;
95
- outputSummary: string;
96
- markerFound: boolean;
97
- taskMarkerFound?: boolean;
98
- contextUsedPercent?: number;
99
- }
100
-
101
- export type PlanStatus = z.infer<typeof PlanStatusSchema>;
102
- export type RalphPlan = z.infer<typeof RalphPlanSchema>;
103
- export type RalphState = z.infer<typeof RalphStateSchema>;
104
-
105
- // ============================================================================
106
- // State Management
107
- // ============================================================================
108
-
109
- export function createInitialState(): RalphState {
110
- return {
111
- version: 1,
112
- plans: [],
113
- startedAt: new Date().toISOString(),
114
- status: "running",
115
- };
116
- }
117
-
118
- /**
119
- * Append iteration history as a JSON line to the history log file.
120
- * Each line is a complete JSON object for easy parsing.
121
- */
122
- export function appendHistory(
123
- history: IterationHistory,
124
- historyFile: string = DEFAULT_HISTORY_FILE,
125
- ): void {
126
- fs.mkdirSync(path.dirname(historyFile), { recursive: true });
127
- const line = JSON.stringify(history) + "\n";
128
- fs.appendFileSync(historyFile, line);
129
- }
130
-
131
- export function saveState(state: RalphState, stateFile: string): void {
132
- fs.mkdirSync(path.dirname(stateFile), { recursive: true });
133
- fs.writeFileSync(stateFile, JSON.stringify(state, null, 2));
134
- }
135
-
136
- export function loadState(stateFile: string): RalphState | null {
137
- try {
138
- if (!fs.existsSync(stateFile)) {
139
- return null;
140
- }
141
- const content = fs.readFileSync(stateFile, "utf-8");
142
- const parsed = JSON.parse(content);
143
-
144
- const result = RalphStateSchema.safeParse(parsed);
145
- if (!result.success) {
146
- const errors = result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join(", ");
147
- console.warn(pc.yellow(`Warning: Invalid state file ${stateFile}: ${errors}`));
148
- return null;
149
- }
150
- return result.data;
151
- } catch (err) {
152
- console.warn(pc.yellow(`Warning: Failed to load state file ${stateFile}: ${err}`));
153
- return null;
154
- }
155
- }
156
-
157
- export function addPlanToState(state: RalphState, planFilePath: string): RalphPlan {
158
- const nextId = state.plans.length > 0 ? Math.max(...state.plans.map((p) => p.id)) + 1 : 1;
159
-
160
- const newPlan: RalphPlan = {
161
- id: nextId,
162
- planFilePath,
163
- status: "ready",
164
- addedAt: new Date().toISOString(),
165
- };
166
-
167
- state.plans.push(newPlan);
168
- return newPlan;
169
- }
170
-
171
- /**
172
- * Read plan content from file. Updates plan error field and logs warning if file missing.
173
- * @returns File content on success, null if file missing/error
174
- */
175
- export function readPlanContent(
176
- plan: RalphPlan,
177
- state: RalphState,
178
- stateFile: string,
179
- ): string | null {
180
- try {
181
- if (!fs.existsSync(plan.planFilePath)) {
182
- const errorMsg = `Plan file not found: ${plan.planFilePath}`;
183
- console.warn(pc.yellow(`Warning: ${errorMsg}`));
184
- plan.error = errorMsg;
185
- saveState(state, stateFile);
186
- return null;
187
- }
188
- // Clear any previous error
189
- if (plan.error) {
190
- plan.error = undefined;
191
- saveState(state, stateFile);
192
- }
193
- return fs.readFileSync(plan.planFilePath, "utf-8").trim();
194
- } catch (err) {
195
- const errorMsg = `Failed to read plan file: ${err}`;
196
- console.warn(pc.yellow(`Warning: ${errorMsg}`));
197
- plan.error = errorMsg;
198
- saveState(state, stateFile);
199
- return null;
200
- }
201
- }