ralph-mcp 1.0.11 → 1.0.13
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/dist/tools/update.js +54 -1
- package/dist/utils/agent.js +43 -9
- package/package.json +1 -1
package/dist/tools/update.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import notifier from "node-notifier";
|
|
3
|
-
import { appendFile, mkdir } from "fs/promises";
|
|
3
|
+
import { appendFile, mkdir, readFile, writeFile } from "fs/promises";
|
|
4
4
|
import { existsSync } from "fs";
|
|
5
5
|
import { join, dirname } from "path";
|
|
6
6
|
import { areDependenciesSatisfied, findExecutionByBranch, findExecutionsDependingOn, findMergeQueueItemByExecutionId, findUserStoryById, insertMergeQueueItem, listMergeQueue, listUserStoriesByExecutionId, updateExecution, updateUserStory, } from "../store/state.js";
|
|
@@ -21,6 +21,54 @@ function formatDate(date) {
|
|
|
21
21
|
const mm = pad(date.getMinutes());
|
|
22
22
|
return `${yyyy}-${MM}-${dd} ${HH}:${mm}`;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Extract Codebase Pattern from notes if present.
|
|
26
|
+
* Looks for "**Codebase Pattern:**" section in the notes.
|
|
27
|
+
*/
|
|
28
|
+
function extractCodebasePattern(notes) {
|
|
29
|
+
const match = notes.match(/\*\*Codebase Pattern:\*\*\s*(.+?)(?=\n\*\*|\n##|$)/is);
|
|
30
|
+
if (match && match[1].trim()) {
|
|
31
|
+
return match[1].trim();
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Update the Codebase Patterns section at the top of ralph-progress.md.
|
|
37
|
+
* Creates the section if it doesn't exist.
|
|
38
|
+
*/
|
|
39
|
+
async function updateCodebasePatterns(progressPath, newPattern) {
|
|
40
|
+
let content = "";
|
|
41
|
+
if (existsSync(progressPath)) {
|
|
42
|
+
content = await readFile(progressPath, "utf-8");
|
|
43
|
+
}
|
|
44
|
+
const patternsSectionHeader = "## Codebase Patterns\n";
|
|
45
|
+
const patternLine = `- ${newPattern}\n`;
|
|
46
|
+
if (content.includes(patternsSectionHeader)) {
|
|
47
|
+
// Find the end of the Codebase Patterns section (next ## or end of patterns)
|
|
48
|
+
const sectionStart = content.indexOf(patternsSectionHeader);
|
|
49
|
+
const sectionContentStart = sectionStart + patternsSectionHeader.length;
|
|
50
|
+
// Find next section (## that's not Codebase Patterns)
|
|
51
|
+
const nextSectionMatch = content.slice(sectionContentStart).match(/\n## /);
|
|
52
|
+
const sectionEnd = nextSectionMatch
|
|
53
|
+
? sectionContentStart + nextSectionMatch.index
|
|
54
|
+
: content.length;
|
|
55
|
+
// Check if pattern already exists (avoid duplicates)
|
|
56
|
+
const existingPatterns = content.slice(sectionContentStart, sectionEnd);
|
|
57
|
+
if (!existingPatterns.includes(newPattern)) {
|
|
58
|
+
// Insert new pattern at the end of the patterns section
|
|
59
|
+
const before = content.slice(0, sectionEnd);
|
|
60
|
+
const after = content.slice(sectionEnd);
|
|
61
|
+
content = before + patternLine + after;
|
|
62
|
+
await writeFile(progressPath, content, "utf-8");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// Create new Codebase Patterns section at the top
|
|
67
|
+
const newSection = patternsSectionHeader + patternLine + "\n";
|
|
68
|
+
content = newSection + content;
|
|
69
|
+
await writeFile(progressPath, content, "utf-8");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
24
72
|
export async function update(input) {
|
|
25
73
|
// Find execution by branch
|
|
26
74
|
const exec = await findExecutionByBranch(input.branch);
|
|
@@ -49,6 +97,11 @@ export async function update(input) {
|
|
|
49
97
|
const timestamp = formatDate(new Date());
|
|
50
98
|
const notesContent = input.notes || story.notes || "No notes provided.";
|
|
51
99
|
const entry = `## [${timestamp}] ${story.storyId}: ${story.title}\n${notesContent}\n\n`;
|
|
100
|
+
// Extract and consolidate Codebase Pattern if present
|
|
101
|
+
const pattern = extractCodebasePattern(notesContent);
|
|
102
|
+
if (pattern) {
|
|
103
|
+
await updateCodebasePatterns(progressPath, pattern);
|
|
104
|
+
}
|
|
52
105
|
await appendFile(progressPath, entry, "utf-8");
|
|
53
106
|
}
|
|
54
107
|
catch (e) {
|
package/dist/utils/agent.js
CHANGED
|
@@ -57,21 +57,55 @@ ${progressLog ? `## Progress & Learnings\n${progressLog}\n` : ""}
|
|
|
57
57
|
## Pending User Stories
|
|
58
58
|
${storiesText}
|
|
59
59
|
|
|
60
|
+
## Story Size Check (CRITICAL)
|
|
61
|
+
|
|
62
|
+
Before implementing, verify the story is small enough to complete in ONE context window.
|
|
63
|
+
|
|
64
|
+
**Right-sized stories:**
|
|
65
|
+
- Add a database column and migration
|
|
66
|
+
- Add a UI component to an existing page
|
|
67
|
+
- Update a server action with new logic
|
|
68
|
+
- Add a filter dropdown to a list
|
|
69
|
+
|
|
70
|
+
**Too big (should have been split):**
|
|
71
|
+
- "Build the entire dashboard" → schema, queries, UI components, filters
|
|
72
|
+
- "Add authentication" → schema, middleware, login UI, session handling
|
|
73
|
+
- "Refactor the API" → one story per endpoint
|
|
74
|
+
|
|
75
|
+
**If a story seems too big:** Complete what you can, commit it, then call \`ralph_update\` with \`passes: false\` and notes explaining what remains. Do NOT produce broken code trying to finish everything.
|
|
76
|
+
|
|
60
77
|
## Instructions
|
|
61
78
|
|
|
62
79
|
1. Work on ONE user story at a time, starting with the highest priority.
|
|
63
|
-
2. ${progressLog ? "Review the 'Progress & Learnings' section above
|
|
80
|
+
2. ${progressLog ? "Review the 'Progress & Learnings' section above - especially the 'Codebase Patterns' section at the top." : "Check if 'ralph-progress.md' exists and review it for context."}
|
|
64
81
|
3. Implement the feature to satisfy all acceptance criteria.
|
|
65
|
-
4. Run quality checks: \`pnpm check-types\` and \`pnpm --filter api build\` (adjust
|
|
66
|
-
5.
|
|
67
|
-
6.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
82
|
+
4. Run quality checks: \`pnpm check-types\` and \`pnpm --filter api build\` (adjust for repo structure).
|
|
83
|
+
5. **Browser Testing (UI stories)**: If the story changes UI, verify in browser using Chrome DevTools MCP or similar tools. A frontend story is NOT complete until visually verified.
|
|
84
|
+
6. Commit changes with message: \`feat: [${pendingStories[0].storyId}] - ${pendingStories[0].title}\`
|
|
85
|
+
7. **Update Directory CLAUDE.md**: If you discovered reusable patterns, add them to the CLAUDE.md in the directory you modified (create if needed). Only add genuinely reusable knowledge, not story-specific details.
|
|
86
|
+
8. Call \`ralph_update\` to mark the story as passed. Include detailed notes:
|
|
87
|
+
\`ralph_update({ branch: "${branch}", storyId: "${pendingStories[0].storyId}", passes: true, notes: "..." })\`
|
|
88
|
+
9. Continue to the next story until all are complete.
|
|
89
|
+
|
|
90
|
+
## Notes Format for ralph_update
|
|
91
|
+
|
|
92
|
+
Provide structured learnings in the \`notes\` field:
|
|
93
|
+
\`\`\`
|
|
94
|
+
**Implemented:** Brief summary of what was done
|
|
95
|
+
**Files changed:** List key files
|
|
96
|
+
**Learnings:**
|
|
97
|
+
- Patterns discovered (e.g., "this codebase uses X for Y")
|
|
98
|
+
- Gotchas encountered (e.g., "don't forget to update Z when changing W")
|
|
99
|
+
- Useful context for future iterations
|
|
100
|
+
**Codebase Pattern:** (if discovered a general pattern worth consolidating)
|
|
101
|
+
\`\`\`
|
|
102
|
+
|
|
103
|
+
## Quality Requirements (Feedback Loops)
|
|
104
|
+
- ALL commits must pass typecheck and build - broken code compounds across iterations
|
|
73
105
|
- Keep changes focused and minimal
|
|
74
106
|
- Follow existing code patterns
|
|
107
|
+
- UI changes must be browser-verified
|
|
108
|
+
- Do NOT commit broken code - if checks fail, fix before committing
|
|
75
109
|
|
|
76
110
|
## Stop Condition
|
|
77
111
|
When all stories are complete, report completion.
|
package/package.json
CHANGED