cralph 1.0.0-beta.7 → 1.0.0-beta.8

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 CHANGED
@@ -4,13 +4,13 @@
4
4
  <img src="https://raw.githubusercontent.com/mguleryuz/cralph/main/assets/ralph.png" alt="Ralph cooking" width="500">
5
5
  </p>
6
6
 
7
- Claude in a loop. Give it a rule, let it cook.
7
+ Claude in a loop. Give it a TODO, let it cook.
8
8
 
9
9
  ```
10
10
  .ralph/
11
- ├── rule.md ──loop──> ./
12
- ├── refs/ (output)
13
- └── TODO.md
11
+ ├── refs/ (read-only reference material)
12
+ ├── TODO.md ──loop──> ./
13
+ └── paths.json (output)
14
14
  ```
15
15
 
16
16
  ## What is Ralph?
@@ -39,7 +39,7 @@ bun add -g cralph
39
39
  # In any directory without .ralph/ - creates starter structure
40
40
  cralph
41
41
 
42
- # Edit rule.md with your instructions, then run again
42
+ # Run again - prepare your TODO, then run
43
43
  cralph
44
44
  ```
45
45
 
@@ -50,7 +50,7 @@ cralph
50
50
  cralph
51
51
 
52
52
  # Override with flags
53
- cralph --refs ./source --rule ./rule.md --output .
53
+ cralph --refs ./source --output .
54
54
 
55
55
  # Auto-confirm prompts (CI/automation)
56
56
  cralph --yes
@@ -59,19 +59,63 @@ cralph --yes
59
59
  ## How It Works
60
60
 
61
61
  1. Checks Claude CLI auth (cached for 6 hours)
62
- 2. Looks for `.ralph/` in current directory only (not subdirectories)
63
- 3. Loads config from `.ralph/paths.json` or creates starter structure
62
+ 2. Looks for `.ralph/` in current directory
63
+ 3. Shows main menu: **Run** / **Prepare TODO** / **Edit config**
64
64
  4. Runs `claude -p --dangerously-skip-permissions` in a loop
65
65
  5. Claude completes **ONE task per iteration**, marks it done, then stops
66
66
  6. Auto-commits progress after each iteration (fails gracefully if no git)
67
67
  7. Stops when Claude outputs `<promise>COMPLETE</promise>`
68
68
 
69
+ ## Main Menu
70
+
71
+ When `.ralph/paths.json` exists, you get:
72
+
73
+ ```
74
+ ❯ Found .ralph/paths.json. What would you like to do?
75
+ ● 🚀 Run with this config
76
+ ○ 📝 Prepare TODO
77
+ ○ ✏️ Edit configuration
78
+ ```
79
+
80
+ - **Run** — validates config and starts the loop
81
+ - **Prepare TODO** — describe your tasks, Claude generates TODO.md, returns to menu
82
+ - **Edit** — re-select refs/output, save config, returns to menu
83
+
84
+ ## Prepare TODO
85
+
86
+ Selecting **Prepare TODO** prompts you to describe what Claude should work on:
87
+
88
+ ```
89
+ ? Describe your tasks (what should Claude work on?):
90
+ > Build a REST API with user auth, add unit tests, setup error handling
91
+ ```
92
+
93
+ Claude generates a structured TODO.md with ordered, actionable tasks:
94
+
95
+ ```markdown
96
+ # Tasks
97
+
98
+ - [ ] Set up Express server with basic routing
99
+ - [ ] Add user authentication with JWT
100
+ - [ ] Create user CRUD endpoints
101
+ - [ ] Add error handling middleware
102
+ - [ ] Write unit tests for auth module
103
+ - [ ] Write unit tests for user endpoints
104
+
105
+ ---
106
+
107
+ # Notes
108
+
109
+ _Append progress and learnings here after each iteration_
110
+ ```
111
+
112
+ You can prepare TODO multiple times — each run overwrites the previous.
113
+
69
114
  ## Config
70
115
 
71
116
  ```json
72
117
  {
73
118
  "refs": ["./.ralph/refs"],
74
- "rule": "./.ralph/rule.md",
75
119
  "output": "."
76
120
  }
77
121
  ```
@@ -82,10 +126,9 @@ Save as `.ralph/paths.json`. Refs are optional reference material (read-only).
82
126
 
83
127
  | File | Description |
84
128
  |------|-------------|
85
- | `.ralph/paths.json` | Configuration |
86
- | `.ralph/rule.md` | Your instructions for Claude |
129
+ | `.ralph/paths.json` | Configuration (refs, output) |
87
130
  | `.ralph/refs/` | Optional reference material (read-only) |
88
- | `.ralph/TODO.md` | Task tracking (updated by Claude) |
131
+ | `.ralph/TODO.md` | Task tracking (generated or manual, updated by Claude) |
89
132
  | `.ralph/ralph.log` | Session log |
90
133
  | `~/.cralph/auth-cache.json` | Auth cache (6h TTL) |
91
134
 
@@ -107,9 +150,6 @@ Claude maintains this structure (one task per iteration):
107
150
  - What was implemented
108
151
  - Files changed
109
152
  - Learnings: patterns discovered, gotchas encountered
110
-
111
- ## Task 2 - Done
112
- - ...
113
153
  ```
114
154
 
115
155
  ## First Run (No .ralph/ in cwd)
@@ -124,39 +164,29 @@ Select **Create starter structure** to generate the default config:
124
164
 
125
165
  ```
126
166
  ℹ Created .ralph/refs/ directory
127
- ℹ Created .ralph/rule.md with starter template
128
167
  ℹ Created .ralph/paths.json
129
168
 
130
- ╭─────────────────────────────────────────────────╮
131
- │ 1. Add source files to .ralph/refs/
132
- │ 2. Edit .ralph/rule.md with your instructions
133
- │ 3. Run cralph again │
134
- ╰─────────────────────────────────────────────────╯
169
+ ╭──────────────────────────────────────────────╮
170
+ │ 1. Add source files to .ralph/refs/
171
+ │ 2. Run cralph again to prepare your TODO
172
+ ╰──────────────────────────────────────────────╯
135
173
  ```
136
174
 
137
- Select **Configure manually** to skip starter creation and pick your own refs/rule/output.
175
+ ## TODO Reset
138
176
 
139
- Use `--yes` to auto-create starter structure (for CI/automation).
177
+ When running, if TODO.md has existing progress:
140
178
 
141
- ## Prompts
142
-
143
- **Config detected:**
144
179
  ```
145
- Found .ralph/paths.json. What would you like to do?
146
- ● 🚀 Run with this config
147
- ○ ✏️ Edit configuration
180
+ ? Found existing TODO with progress. Reset to start fresh? (y/N)
148
181
  ```
149
182
 
150
- **TODO has progress:**
151
- ```
152
- ? Found existing TODO with progress. Reset to start fresh? (Y/n)
153
- ```
183
+ Default is **No** continues with existing progress.
154
184
 
155
185
  ## Path Selection
156
186
 
157
- - **Space** - Toggle selection
158
- - **Enter** - Confirm
159
- - **Ctrl+C** - Exit
187
+ - **Space** Toggle selection
188
+ - **Enter** Confirm
189
+ - **Ctrl+C** Exit
160
190
 
161
191
  ## Platform Support
162
192
 
@@ -168,7 +198,7 @@ cralph works on **macOS**, **Linux**, and **Windows** with platform-specific han
168
198
  | Linux | lost+found, proc, sys |
169
199
  | Windows | System Volume Information, $Recycle.Bin, Windows |
170
200
 
171
- Permission errors (`EPERM`, `EACCES`) are handled gracefully on all platforms, allowing the CLI to run from any directory.
201
+ Permission errors (`EPERM`, `EACCES`) are handled gracefully on all platforms.
172
202
 
173
203
  ## Testing
174
204
 
@@ -176,8 +206,8 @@ Permission errors (`EPERM`, `EACCES`) are handled gracefully on all platforms, a
176
206
  bun test
177
207
  ```
178
208
 
179
- - **Unit tests** - Config, prompt building, CLI, access error handling, platform detection, shutdown state
180
- - **E2E tests** - Full loop with Claude (requires auth)
209
+ - **Unit tests** Config, prompt building, CLI, access error handling, platform detection, shutdown state
210
+ - **E2E tests** Full loop with Claude (requires auth)
181
211
 
182
212
  ## Requirements
183
213
 
package/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // Re-export for programmatic usage
2
2
  export * from "./src/types";
3
- export { loadPathsFile, validateConfig, resolvePathsConfig, toRelativePath } from "./src/paths";
3
+ export { loadPathsFile, validateConfig, resolvePathsConfig, toRelativePath, prepareTodo } from "./src/paths";
4
4
  export { createPrompt, buildPrompt } from "./src/prompt";
5
5
  export { run, checkClaudeAuth } from "./src/runner";
6
6
  export { cleanupSubprocess, setShuttingDown, isShuttingDown } from "./src/state";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cralph",
3
- "version": "1.0.0-beta.7",
3
+ "version": "1.0.0-beta.8",
4
4
  "description": "Claude in a loop. Point at refs, give it a rule, let it cook.",
5
5
  "author": "mguleryuz",
6
6
  "license": "MIT",
package/src/cli.ts CHANGED
@@ -8,11 +8,11 @@ import {
8
8
  loadPathsFile,
9
9
  validateConfig,
10
10
  selectRefs,
11
- selectRule,
12
11
  selectOutput,
13
12
  checkForPathsFile,
14
13
  resolvePathsConfig,
15
14
  toRelativePath,
15
+ prepareTodo,
16
16
  } from "./paths";
17
17
  import { run, checkClaudeAuth } from "./runner";
18
18
  import type { RalphConfig } from "./types";
@@ -47,7 +47,7 @@ const main = defineCommand({
47
47
  meta: {
48
48
  name: "cralph",
49
49
  version: "1.0.0",
50
- description: "Claude in a loop. Point at refs, give it a rule, let it cook.",
50
+ description: "Claude in a loop. Give it a TODO, let it cook.",
51
51
  },
52
52
  args: {
53
53
  refs: {
@@ -57,13 +57,6 @@ const main = defineCommand({
57
57
  alias: "r",
58
58
  required: false,
59
59
  },
60
- rule: {
61
- type: "string",
62
- description: "Path to rule file (.mdc or .md)",
63
- valueHint: "rule.md",
64
- alias: "u",
65
- required: false,
66
- },
67
60
  output: {
68
61
  type: "string",
69
62
  description: "Output directory where results will be written",
@@ -113,18 +106,28 @@ const main = defineCommand({
113
106
 
114
107
  consola.success("Claude authenticated");
115
108
 
116
- // Check for existing paths file in cwd
117
- const pathsFileResult = args.yes
118
- ? await checkForPathsFile(cwd, true) // Auto-run if --yes
119
- : await checkForPathsFile(cwd);
120
-
121
- if (pathsFileResult?.action === "run") {
122
- // Use existing config file
123
- consola.info(`Loading config from ${pathsFileResult.path}`);
124
- const loaded = await loadPathsFile(pathsFileResult.path);
125
- config = resolvePathsConfig(loaded, cwd);
126
- } else {
127
- // Load existing config for edit mode defaults
109
+ // Main selection loop - prepare/edit return here, run breaks out
110
+ while (true) {
111
+ const pathsFileResult = args.yes
112
+ ? await checkForPathsFile(cwd, true)
113
+ : await checkForPathsFile(cwd);
114
+
115
+ if (pathsFileResult?.action === "prepare") {
116
+ const loaded = await loadPathsFile(pathsFileResult.path);
117
+ const resolved = resolvePathsConfig(loaded, cwd);
118
+ const outputBase = resolved.output === cwd ? cwd : resolved.output;
119
+ await prepareTodo(outputBase);
120
+ continue;
121
+ }
122
+
123
+ if (pathsFileResult?.action === "run") {
124
+ consola.info(`Loading config from ${pathsFileResult.path}`);
125
+ const loaded = await loadPathsFile(pathsFileResult.path);
126
+ config = resolvePathsConfig(loaded, cwd);
127
+ break;
128
+ }
129
+
130
+ // Edit mode or no config found
128
131
  let existingConfig: RalphConfig | null = null;
129
132
  if (pathsFileResult?.action === "edit") {
130
133
  consola.info("Edit configuration");
@@ -139,19 +142,15 @@ const main = defineCommand({
139
142
  }
140
143
 
141
144
  // Interactive selection
142
- const refs = args.refs
145
+ const refs = args.refs
143
146
  ? args.refs.split(",").map((r) => resolve(cwd, r.trim()))
144
147
  : await selectRefs(cwd, existingConfig?.refs, args.yes);
145
-
146
- const rule = args.rule
147
- ? resolve(cwd, args.rule)
148
- : await selectRule(cwd, existingConfig?.rule);
149
-
150
- const output = args.output
148
+
149
+ const output = args.output
151
150
  ? resolve(cwd, args.output)
152
151
  : await selectOutput(cwd, existingConfig?.output);
153
152
 
154
- config = { refs, rule, output };
153
+ config = { refs, output };
155
154
 
156
155
  // Offer to save config
157
156
  const saveConfig = await consola.prompt("Save configuration to .ralph/paths.json?", {
@@ -159,16 +158,15 @@ const main = defineCommand({
159
158
  cancel: "symbol",
160
159
  initial: true,
161
160
  });
162
-
161
+
163
162
  throwIfCancelled(saveConfig);
164
163
 
165
164
  if (saveConfig === true) {
166
165
  const ralphDir = join(cwd, ".ralph");
167
166
  await mkdir(ralphDir, { recursive: true });
168
-
167
+
169
168
  const pathsConfig = {
170
169
  refs: config.refs.map((r) => toRelativePath(r, cwd)),
171
- rule: toRelativePath(config.rule, cwd),
172
170
  output: toRelativePath(config.output, cwd),
173
171
  };
174
172
  await Bun.write(
@@ -177,8 +175,12 @@ const main = defineCommand({
177
175
  );
178
176
  consola.success("Saved .ralph/paths.json");
179
177
  }
178
+
179
+ // After edit, loop back to main selection
180
+ continue;
180
181
  }
181
182
 
183
+
182
184
  // Validate configuration
183
185
  consola.info("Validating configuration...");
184
186
  await validateConfig(config);
@@ -186,7 +188,6 @@ const main = defineCommand({
186
188
  // Show config summary
187
189
  consola.info("Configuration:");
188
190
  consola.info(` Refs: ${config.refs.join(", ")}`);
189
- consola.info(` Rule: ${config.rule}`);
190
191
  consola.info(` Output: ${config.output}`);
191
192
  console.log();
192
193
 
package/src/paths.ts CHANGED
@@ -6,10 +6,6 @@ import type { PathsFileConfig, RalphConfig } from "./types";
6
6
  import { isAccessError, shouldExcludeDir } from "./platform";
7
7
  import { throwIfCancelled } from "./state";
8
8
 
9
- // Starter rule template for new projects
10
- const STARTER_RULE = `I want a file named hello.txt
11
- `;
12
-
13
9
  // Dim text helper
14
10
  const dim = (s: string) => `\x1b[2m${s}\x1b[0m`;
15
11
  const CONTROLS = dim("↑↓ Navigate • Space Toggle • Enter • Ctrl+C Exit");
@@ -20,7 +16,6 @@ const CONTROLS = dim("↑↓ Navigate • Space Toggle • Enter • Ctrl+C Exit
20
16
  export function resolvePathsConfig(loaded: PathsFileConfig, cwd: string): RalphConfig {
21
17
  return {
22
18
  refs: loaded.refs.map((r) => resolve(cwd, r)),
23
- rule: resolve(cwd, loaded.rule),
24
19
  output: resolve(cwd, loaded.output),
25
20
  };
26
21
  }
@@ -38,6 +33,7 @@ export function toRelativePath(absolutePath: string, cwd: string): string {
38
33
  */
39
34
  function shouldSkipDirectory(entry: Dirent): boolean {
40
35
  if (!entry.isDirectory()) return true;
36
+ if (entry.name === ".ralph") return false; // Always show .ralph
41
37
  if (entry.name.startsWith(".")) return true;
42
38
  if (shouldExcludeDir(entry.name)) return true;
43
39
  return false;
@@ -50,7 +46,7 @@ async function listDirectories(basePath: string): Promise<string[]> {
50
46
  try {
51
47
  const entries = await readdir(basePath, { withFileTypes: true });
52
48
  return entries
53
- .filter((e) => e.isDirectory() && !e.name.startsWith("."))
49
+ .filter((e) => e.isDirectory() && (e.name === ".ralph" || !e.name.startsWith(".")))
54
50
  .map((e) => e.name);
55
51
  } catch (error) {
56
52
  // Silently skip directories we can't access
@@ -154,27 +150,21 @@ export async function createStarterStructure(cwd: string): Promise<void> {
154
150
  // Create .ralph/
155
151
  const ralphDir = join(cwd, ".ralph");
156
152
  await mkdir(ralphDir, { recursive: true });
157
-
153
+
158
154
  // Create .ralph/refs/
159
155
  const refsDir = join(ralphDir, "refs");
160
156
  await mkdir(refsDir, { recursive: true });
161
157
  consola.info("Created .ralph/refs/ directory");
162
-
163
- // Create .ralph/rule.md
164
- const rulePath = join(ralphDir, "rule.md");
165
- await Bun.write(rulePath, STARTER_RULE);
166
- consola.info("Created .ralph/rule.md with starter template");
167
-
158
+
168
159
  // Create .ralph/paths.json with default config
169
160
  const pathsConfig = {
170
161
  refs: ["./.ralph/refs"],
171
- rule: "./.ralph/rule.md",
172
162
  output: ".",
173
163
  };
174
164
  await Bun.write(join(ralphDir, "paths.json"), JSON.stringify(pathsConfig, null, 2));
175
165
  consola.info("Created .ralph/paths.json");
176
-
177
- consola.box("1. Add source files to .ralph/refs/\n2. Edit .ralph/rule.md with your instructions\n3. Run cralph again");
166
+
167
+ consola.box("1. Add source files to .ralph/refs/\n2. Run cralph again to prepare your TODO");
178
168
  }
179
169
 
180
170
  /**
@@ -263,39 +253,80 @@ export async function selectRefs(cwd: string, defaults?: string[], autoConfirm?:
263
253
  }
264
254
 
265
255
  /**
266
- * Prompt user to select a rule file
256
+ * Prompt user to prepare TODO.md by describing their tasks
257
+ * Uses Claude to generate a properly formatted TODO.md
267
258
  */
268
- export async function selectRule(cwd: string, defaultRule?: string): Promise<string> {
269
- let files = await listFilesRecursive(cwd, [".mdc", ".md"]);
270
- if (files.length === 0) {
271
- // This shouldn't happen if selectRefs ran first, but handle it just in case
272
- const rulePath = join(cwd, "rule.md");
273
- await Bun.write(rulePath, STARTER_RULE);
274
- consola.info("Created rule.md with starter template");
275
- consola.box("Edit rule.md with your instructions then run cralph again");
276
- process.exit(0);
259
+ export async function prepareTodo(cwd: string): Promise<void> {
260
+ const ralphDir = join(cwd, ".ralph");
261
+ const todoPath = join(ralphDir, "TODO.md");
262
+
263
+ const description = await consola.prompt(
264
+ "Describe your tasks (what should Claude work on?):",
265
+ {
266
+ type: "text",
267
+ cancel: "symbol",
268
+ placeholder: "e.g. Build a REST API with user auth, add tests, setup CI...",
269
+ }
270
+ );
271
+
272
+ throwIfCancelled(description);
273
+
274
+ if (!description || (description as string).trim() === "") {
275
+ consola.warn("No description provided, skipping TODO preparation");
276
+ return;
277
277
  }
278
278
 
279
- // Show relative paths for readability
280
- const options = files.map((f) => ({
281
- label: `📄 ${f.replace(cwd + "/", "")}`,
282
- value: f,
283
- hint: f === defaultRule ? "current" : (f.endsWith(".mdc") ? "cursor rule" : "markdown"),
284
- }));
279
+ consola.start("Generating TODO.md from your description...");
285
280
 
286
- // Find initial value for default selection
287
- const initialValue = defaultRule && files.includes(defaultRule) ? defaultRule : files[0];
281
+ const todoPrompt = `You are generating a TODO.md file for an autonomous coding agent. Based on the user's description, create a well-structured TODO.md with clear, actionable tasks.
288
282
 
289
- console.log(CONTROLS);
290
- const selected = await consola.prompt("Select rule file:", {
291
- type: "select",
292
- cancel: "symbol",
293
- options,
294
- initial: initialValue,
295
- });
283
+ Rules:
284
+ - Each task should be a single, focused unit of work
285
+ - Tasks should be ordered logically (dependencies first)
286
+ - Use the checkbox format: "- [ ] Task description"
287
+ - Keep task descriptions concise but specific
288
+ - Include a Notes section placeholder at the bottom
296
289
 
297
- throwIfCancelled(selected);
298
- return selected as string;
290
+ User's description:
291
+ ${(description as string).trim()}
292
+
293
+ Output ONLY the TODO.md content, nothing else. Use this exact format:
294
+
295
+ # Tasks
296
+
297
+ - [ ] First task
298
+ - [ ] Second task
299
+ ...
300
+
301
+ ---
302
+
303
+ # Notes
304
+
305
+ _Append progress and learnings here after each iteration_`;
306
+
307
+ try {
308
+ const proc = Bun.spawn(["claude", "-p"], {
309
+ stdin: new Blob([todoPrompt]),
310
+ stdout: "pipe",
311
+ stderr: "pipe",
312
+ });
313
+
314
+ const stdout = await new Response(proc.stdout).text();
315
+ const exitCode = await proc.exited;
316
+
317
+ if (exitCode !== 0) {
318
+ consola.error("Failed to generate TODO.md");
319
+ return;
320
+ }
321
+
322
+ // Write the generated TODO
323
+ await mkdir(ralphDir, { recursive: true });
324
+ await Bun.write(todoPath, stdout.trim() + "\n");
325
+ consola.success("Generated .ralph/TODO.md");
326
+ } catch (error) {
327
+ const msg = error instanceof Error ? error.message : String(error);
328
+ consola.error(`Failed to generate TODO: ${msg}`);
329
+ }
299
330
  }
300
331
 
301
332
  /**
@@ -340,19 +371,18 @@ export async function selectOutput(cwd: string, defaultOutput?: string): Promise
340
371
 
341
372
  /**
342
373
  * Check if a paths file exists and offer to use it
343
- * Returns: { action: "run", path: string } | { action: "edit" } | null
344
374
  * @param autoRun - If true, skip prompt and auto-select "run" when config exists
345
375
  */
346
- export async function checkForPathsFile(cwd: string, autoRun?: boolean): Promise<{ action: "run"; path: string } | { action: "edit" } | null> {
376
+ export async function checkForPathsFile(cwd: string, autoRun?: boolean): Promise<{ action: "run" | "edit" | "prepare"; path: string } | null> {
347
377
  const filePath = join(cwd, ".ralph", "paths.json");
348
378
  const file = Bun.file(filePath);
349
-
379
+
350
380
  if (await file.exists()) {
351
381
  // Auto-run if flag is set
352
382
  if (autoRun) {
353
383
  return { action: "run", path: filePath };
354
384
  }
355
-
385
+
356
386
  console.log(CONTROLS);
357
387
  const action = await consola.prompt(
358
388
  `Found .ralph/paths.json. What would you like to do?`,
@@ -361,17 +391,15 @@ export async function checkForPathsFile(cwd: string, autoRun?: boolean): Promise
361
391
  cancel: "symbol",
362
392
  options: [
363
393
  { label: "🚀 Run with this config", value: "run" },
394
+ { label: "📝 Prepare TODO", value: "prepare" },
364
395
  { label: "✏️ Edit configuration", value: "edit" },
365
396
  ],
366
397
  }
367
398
  );
368
-
399
+
369
400
  throwIfCancelled(action);
370
-
371
- if (action === "run") {
372
- return { action: "run", path: filePath };
373
- }
374
- return { action: "edit" };
401
+
402
+ return { action: action as "run" | "edit" | "prepare", path: filePath };
375
403
  }
376
404
 
377
405
  return null;
@@ -390,11 +418,5 @@ export async function validateConfig(config: RalphConfig): Promise<void> {
390
418
  }
391
419
  }
392
420
 
393
- // Check rule file
394
- const ruleFile = Bun.file(config.rule);
395
- if (!(await ruleFile.exists())) {
396
- throw new Error(`Rule file does not exist: ${config.rule}`);
397
- }
398
-
399
421
  // Output directory will be created if needed
400
422
  }
package/src/prompt.ts CHANGED
@@ -6,8 +6,6 @@ import type { RalphConfig } from "./types";
6
6
  */
7
7
  const BASE_PROMPT = `You are an autonomous coding agent running in a loop.
8
8
 
9
- FIRST: Read and internalize the rules provided below.
10
-
11
9
  ## Your Task This Iteration
12
10
 
13
11
  1. Read the TODO file
@@ -55,10 +53,10 @@ After completing ONE task, check the TODO file:
55
53
  **IMPORTANT:** Do NOT continue to the next task. Complete ONE task, then STOP.`;
56
54
 
57
55
  /**
58
- * Build the complete prompt with config and rules injected
56
+ * Build the complete prompt with config injected
59
57
  */
60
- export function buildPrompt(config: RalphConfig, rulesContent: string, todoFile: string): string {
61
- const refsList = config.refs.length > 0
58
+ export function buildPrompt(config: RalphConfig, todoFile: string): string {
59
+ const refsList = config.refs.length > 0
62
60
  ? config.refs.map((r) => `- ${r}`).join("\n")
63
61
  : "_None_";
64
62
 
@@ -76,21 +74,12 @@ ${refsList}
76
74
 
77
75
  **Output directory (write your work here):**
78
76
  ${config.output}
79
-
80
- ---
81
-
82
- ## Rules (Your Instructions)
83
-
84
- ${rulesContent}
85
77
  `;
86
78
  }
87
79
 
88
80
  /**
89
- * Read rule file and build complete prompt
81
+ * Build the complete prompt from config
90
82
  */
91
83
  export async function createPrompt(config: RalphConfig, todoFile: string): Promise<string> {
92
- const ruleFile = Bun.file(config.rule);
93
- const ruleContent = await ruleFile.text();
94
-
95
- return buildPrompt(config, ruleContent, todoFile);
84
+ return buildPrompt(config, todoFile);
96
85
  }
package/src/runner.ts CHANGED
@@ -152,7 +152,7 @@ Ralph Session: ${state.startTime.toISOString()}
152
152
  {
153
153
  type: "confirm",
154
154
  cancel: "symbol",
155
- initial: true,
155
+ initial: false,
156
156
  }
157
157
  );
158
158
 
package/src/types.ts CHANGED
@@ -3,7 +3,6 @@
3
3
  */
4
4
  export interface PathsFileConfig {
5
5
  refs: string[];
6
- rule: string;
7
6
  output: string;
8
7
  }
9
8
 
@@ -13,8 +12,6 @@ export interface PathsFileConfig {
13
12
  export interface RalphConfig {
14
13
  /** Paths to reference material directories/files */
15
14
  refs: string[];
16
- /** Path to the rule file (.mdc or .md) */
17
- rule: string;
18
15
  /** Output directory for generated docs */
19
16
  output: string;
20
17
  }