openalex-mcp-server 1.0.1
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/.claude/README.md +680 -0
- package/.claude/commands/prd.md +138 -0
- package/.claude/commands/ralph-yolo.md +346 -0
- package/.claude/commands/ralph.md +226 -0
- package/.claude/ralph-config.json +17 -0
- package/.claude/scripts/prompt.md +108 -0
- package/.claude/scripts/ralph.sh +127 -0
- package/.claude/skills/prd.md +270 -0
- package/.claude/skills/ralph-yolo.md +613 -0
- package/.claude/skills/ralph.md +315 -0
- package/.claude/templates/prd.json.example +64 -0
- package/.env.example +8 -0
- package/.github/workflows/npm-publish.yml +48 -0
- package/README.md +525 -0
- package/config/mcp-config.json +77 -0
- package/docs/PRD.md +897 -0
- package/docs/api-document.md +973 -0
- package/docs/document-mcp.txt +1 -0
- package/package.json +49 -0
- package/prd-progress.txt +66 -0
- package/src/cache-manager.js +204 -0
- package/src/cli.js +47 -0
- package/src/fulltext-downloader.js +333 -0
- package/src/index.js +603 -0
- package/src/json-optimizer.js +153 -0
- package/src/openalex-client.js +305 -0
- package/src/types/pdf-parse.d.ts +13 -0
- package/src/utils.js +90 -0
- package/tests/cli.test.js +31 -0
- package/tsconfig.json +22 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ralph
|
|
3
|
+
description: "Convert PRD to Ralph format and run the autonomous agent loop. Use when you have a PRD and want Ralph to implement it automatically."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Ralph - Autonomous Agent Loop
|
|
7
|
+
|
|
8
|
+
Ralph is an autonomous AI agent loop that implements PRDs by repeatedly spawning fresh AI instances to complete user stories one by one.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## What This Skill Does
|
|
13
|
+
|
|
14
|
+
This skill handles two phases:
|
|
15
|
+
|
|
16
|
+
1. **PRD Conversion**: Converts a markdown PRD to `prd.json` format
|
|
17
|
+
2. **Ralph Execution**: Launches the autonomous loop that implements each story
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
/ralph [path-to-prd.md]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
If no path is provided, looks for `prd.json` in the project root and runs directly.
|
|
28
|
+
|
|
29
|
+
Examples:
|
|
30
|
+
- `/ralph tasks/prd-my-feature.md` - Convert PRD and run Ralph
|
|
31
|
+
- `/ralph prd.json` - Run Ralph with existing prd.json
|
|
32
|
+
- `/ralph` - Run Ralph (looks for prd.json)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Phase 1: PRD Conversion (if markdown provided)
|
|
37
|
+
|
|
38
|
+
### Step 1: Read the PRD
|
|
39
|
+
|
|
40
|
+
Read the provided markdown PRD file.
|
|
41
|
+
|
|
42
|
+
### Step 2: Archive Previous Run (if needed)
|
|
43
|
+
|
|
44
|
+
Check if `prd.json` exists with a different `branchName`. If so:
|
|
45
|
+
1. Read current `prd.json` and extract `branchName`
|
|
46
|
+
2. Check if it differs from the new feature's branch
|
|
47
|
+
3. If different AND `prd-progress.txt` has content:
|
|
48
|
+
- Create archive folder: `.claude/archive/YYYY-MM-DD-[feature-name]/`
|
|
49
|
+
- Copy current `prd.json` and `prd-progress.txt` to archive
|
|
50
|
+
- Reset `prd-progress.txt` with fresh header
|
|
51
|
+
|
|
52
|
+
### Step 3: Convert to prd.json
|
|
53
|
+
|
|
54
|
+
Parse the PRD and generate `prd.json` in the project root:
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"project": "[Project Name from PRD or auto-detected]",
|
|
59
|
+
"branchName": "ralph/[feature-name-kebab-case]",
|
|
60
|
+
"description": "[Feature description from PRD]",
|
|
61
|
+
"userStories": [
|
|
62
|
+
{
|
|
63
|
+
"id": "US-001",
|
|
64
|
+
"title": "[Story title]",
|
|
65
|
+
"description": "As a [user], I want [feature] so that [benefit]",
|
|
66
|
+
"acceptanceCriteria": [
|
|
67
|
+
"Criterion 1",
|
|
68
|
+
"Criterion 2",
|
|
69
|
+
"Typecheck passes"
|
|
70
|
+
],
|
|
71
|
+
"priority": 1,
|
|
72
|
+
"passes": false,
|
|
73
|
+
"notes": ""
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Conversion Rules
|
|
80
|
+
|
|
81
|
+
1. **Each user story becomes one JSON entry**
|
|
82
|
+
2. **IDs**: Sequential (US-001, US-002, etc.)
|
|
83
|
+
3. **Priority**: Based on dependency order (schema → backend → UI)
|
|
84
|
+
4. **All stories**: `passes: false` and empty `notes`
|
|
85
|
+
5. **branchName**: Derive from feature name, kebab-case, prefixed with `ralph/`
|
|
86
|
+
6. **Always add**: "Typecheck passes" to every story
|
|
87
|
+
7. **For UI stories**: Add "Verify in browser using dev-browser skill"
|
|
88
|
+
|
|
89
|
+
### Story Sizing is Critical
|
|
90
|
+
|
|
91
|
+
Each story MUST be completable in ONE Ralph iteration.
|
|
92
|
+
|
|
93
|
+
**Right-sized stories:**
|
|
94
|
+
- Add a database column and migration
|
|
95
|
+
- Add a UI component to an existing page
|
|
96
|
+
- Update a server action with new logic
|
|
97
|
+
- Add a filter dropdown to a list
|
|
98
|
+
|
|
99
|
+
**Too big (must split):**
|
|
100
|
+
- "Build the entire dashboard" → Split into: schema, queries, UI components, filters
|
|
101
|
+
- "Add authentication" → Split into: schema, middleware, login UI, session handling
|
|
102
|
+
|
|
103
|
+
**Rule of thumb:** If you cannot describe the change in 2-3 sentences, it is too big.
|
|
104
|
+
|
|
105
|
+
### Story Ordering
|
|
106
|
+
|
|
107
|
+
Stories execute in `priority` order. Earlier stories must NOT depend on later ones.
|
|
108
|
+
|
|
109
|
+
**Correct order:**
|
|
110
|
+
1. Schema/database changes (migrations)
|
|
111
|
+
2. Server actions / backend logic
|
|
112
|
+
3. UI components that use the backend
|
|
113
|
+
4. Dashboard/summary views that aggregate data
|
|
114
|
+
|
|
115
|
+
### Verification Before Proceeding
|
|
116
|
+
|
|
117
|
+
Before running Ralph, verify:
|
|
118
|
+
- [ ] Previous run archived (if applicable)
|
|
119
|
+
- [ ] Each story is completable in one iteration
|
|
120
|
+
- [ ] Stories are ordered by dependencies
|
|
121
|
+
- [ ] Every story has "Typecheck passes"
|
|
122
|
+
- [ ] UI stories have "Verify in browser using dev-browser skill"
|
|
123
|
+
- [ ] Acceptance criteria are verifiable (not vague)
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Phase 2: Ralph Execution
|
|
128
|
+
|
|
129
|
+
### Step 1: Pre-flight Checks
|
|
130
|
+
|
|
131
|
+
Verify the following before starting:
|
|
132
|
+
|
|
133
|
+
1. **Amp CLI installed**
|
|
134
|
+
```bash
|
|
135
|
+
which amp
|
|
136
|
+
```
|
|
137
|
+
If not found, instruct user to install from https://ampcode.com
|
|
138
|
+
|
|
139
|
+
2. **jq installed**
|
|
140
|
+
```bash
|
|
141
|
+
which jq
|
|
142
|
+
```
|
|
143
|
+
If not found, instruct user to install (brew install jq on macOS)
|
|
144
|
+
|
|
145
|
+
3. **Git working directory clean**
|
|
146
|
+
```bash
|
|
147
|
+
git status --porcelain
|
|
148
|
+
```
|
|
149
|
+
If not clean, ask user to commit or stash changes
|
|
150
|
+
|
|
151
|
+
4. **prd.json exists and is valid**
|
|
152
|
+
```bash
|
|
153
|
+
cat prd.json | jq .
|
|
154
|
+
```
|
|
155
|
+
If invalid, show error and exit
|
|
156
|
+
|
|
157
|
+
### Step 2: Create or Checkout Feature Branch
|
|
158
|
+
|
|
159
|
+
Read `branchName` from `prd.json`:
|
|
160
|
+
```bash
|
|
161
|
+
jq -r '.branchName' prd.json
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
If branch doesn't exist, create it from main:
|
|
165
|
+
```bash
|
|
166
|
+
git checkout -b $(jq -r '.branchName' prd.json)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
If branch exists, checkout it:
|
|
170
|
+
```bash
|
|
171
|
+
git checkout $(jq -r '.branchName' prd.json)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Step 3: Run Ralph Loop
|
|
175
|
+
|
|
176
|
+
Execute the Ralph script:
|
|
177
|
+
```bash
|
|
178
|
+
bash .claude/scripts/ralph.sh [max_iterations]
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Default is 10 iterations. The script will:
|
|
182
|
+
|
|
183
|
+
1. Spawn a fresh Amp instance with `.claude/scripts/prompt.md`
|
|
184
|
+
2. Amp picks the highest priority story with `passes: false`
|
|
185
|
+
3. Amp implements that single story
|
|
186
|
+
4. Amp runs quality checks (typecheck, lint, test)
|
|
187
|
+
5. If checks pass, Amp commits with message: `feat: [Story ID] - [Story Title]`
|
|
188
|
+
6. Amp updates `prd.json` to set `passes: true` for the story
|
|
189
|
+
7. Amp appends progress to `prd-progress.txt`
|
|
190
|
+
8. Loop repeats until all stories pass or max iterations reached
|
|
191
|
+
|
|
192
|
+
### Step 4: Monitor Progress
|
|
193
|
+
|
|
194
|
+
Show the user how to monitor:
|
|
195
|
+
```bash
|
|
196
|
+
# See which stories are done
|
|
197
|
+
cat prd.json | jq '.userStories[] | {id, title, passes}'
|
|
198
|
+
|
|
199
|
+
# See learnings from previous iterations
|
|
200
|
+
cat prd-progress.txt
|
|
201
|
+
|
|
202
|
+
# Check git history
|
|
203
|
+
git log --oneline -10
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Step 5: Completion
|
|
207
|
+
|
|
208
|
+
When ALL stories have `passes: true`, Ralph will output:
|
|
209
|
+
```
|
|
210
|
+
<promise>COMPLETE</promise>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
And the loop exits successfully.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Ralph's Inner Loop (What Happens During Execution)
|
|
218
|
+
|
|
219
|
+
Each iteration spawns a fresh Amp instance with instructions from `.claude/scripts/prompt.md`.
|
|
220
|
+
|
|
221
|
+
The Amp instance:
|
|
222
|
+
|
|
223
|
+
1. Reads `prd.json` to pick the next story
|
|
224
|
+
2. Reads `prd-progress.txt` for context
|
|
225
|
+
3. Implements that ONE story
|
|
226
|
+
4. Runs quality checks
|
|
227
|
+
5. Updates `AGENTS.md` files if patterns are discovered
|
|
228
|
+
6. Commits if checks pass
|
|
229
|
+
7. Updates `prd.json` to mark story complete
|
|
230
|
+
8. Appends learnings to `prd-progress.txt`
|
|
231
|
+
|
|
232
|
+
### Memory Between Iterations
|
|
233
|
+
|
|
234
|
+
The only memory between iterations:
|
|
235
|
+
- Git history (commits from previous iterations)
|
|
236
|
+
- `prd-progress.txt` (learnings and context)
|
|
237
|
+
- `prd.json` (which stories are done)
|
|
238
|
+
|
|
239
|
+
Each iteration is a **fresh Amp instance** with clean context.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Key Files
|
|
244
|
+
|
|
245
|
+
| File | Purpose |
|
|
246
|
+
|------|---------|
|
|
247
|
+
| `.claude/scripts/ralph.sh` | The bash loop that spawns Amp instances |
|
|
248
|
+
| `.claude/scripts/prompt.md` | Instructions given to each Amp instance |
|
|
249
|
+
| `prd.json` | User stories with `passes` status |
|
|
250
|
+
| `prd-progress.txt` | Append-only learnings log |
|
|
251
|
+
| `.claude/archive/` | Previous run archives |
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Troubleshooting
|
|
256
|
+
|
|
257
|
+
### Ralph stops mid-execution
|
|
258
|
+
|
|
259
|
+
Check `prd-progress.txt` for the last completed story, then resume:
|
|
260
|
+
```bash
|
|
261
|
+
# Just run ralph again, it will continue from where it left off
|
|
262
|
+
bash .claude/scripts/ralph.sh
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Amp context fills up
|
|
266
|
+
|
|
267
|
+
Enable auto-handoff in `~/.config/amp/settings.json`:
|
|
268
|
+
```json
|
|
269
|
+
{
|
|
270
|
+
"amp.experimental.autoHandoff": { "context": 90 }
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Story fails quality checks
|
|
275
|
+
|
|
276
|
+
Ralph won't commit broken code. Check:
|
|
277
|
+
- `prd-progress.txt` for errors
|
|
278
|
+
- Git working directory for uncommitted changes
|
|
279
|
+
- Fix the issue and run Ralph again
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Tips for Best Results
|
|
284
|
+
|
|
285
|
+
1. **Keep stories small** - Each must complete in one context window
|
|
286
|
+
2. **Order by dependencies** - Schema before backend before UI
|
|
287
|
+
3. **Verifiable criteria** - "Typecheck passes" not "Works correctly"
|
|
288
|
+
4. **Clean git state** - Start with a clean working directory
|
|
289
|
+
5. **Monitor progress** - Check `prd-progress.txt` and git log regularly
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## Example Session
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
User: /ralph tasks/prd-task-priority.md
|
|
297
|
+
|
|
298
|
+
Ralph Skill:
|
|
299
|
+
- Converting PRD to prd.json...
|
|
300
|
+
- Created prd.json with 4 user stories
|
|
301
|
+
- Checking prerequisites...
|
|
302
|
+
- Creating branch ralph/task-priority...
|
|
303
|
+
- Starting Ralph loop...
|
|
304
|
+
|
|
305
|
+
[Ralph executes iterations...]
|
|
306
|
+
|
|
307
|
+
Iteration 1: US-001 - Add priority field to database ✓
|
|
308
|
+
Iteration 2: US-002 - Display priority indicator on task cards ✓
|
|
309
|
+
Iteration 3: US-003 - Add priority selector to task edit ✓
|
|
310
|
+
Iteration 4: US-004 - Filter tasks by priority ✓
|
|
311
|
+
|
|
312
|
+
<promise>COMPLETE</promise>
|
|
313
|
+
|
|
314
|
+
All stories completed! Check prd-progress.txt for details.
|
|
315
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"project": "MyApp",
|
|
3
|
+
"branchName": "ralph/task-priority",
|
|
4
|
+
"description": "Task Priority System - Add priority levels to tasks",
|
|
5
|
+
"userStories": [
|
|
6
|
+
{
|
|
7
|
+
"id": "US-001",
|
|
8
|
+
"title": "Add priority field to database",
|
|
9
|
+
"description": "As a developer, I need to store task priority so it persists across sessions.",
|
|
10
|
+
"acceptanceCriteria": [
|
|
11
|
+
"Add priority column to tasks table: 'high' | 'medium' | 'low' (default 'medium')",
|
|
12
|
+
"Generate and run migration successfully",
|
|
13
|
+
"Typecheck passes"
|
|
14
|
+
],
|
|
15
|
+
"priority": 1,
|
|
16
|
+
"passes": false,
|
|
17
|
+
"notes": ""
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "US-002",
|
|
21
|
+
"title": "Display priority indicator on task cards",
|
|
22
|
+
"description": "As a user, I want to see task priority at a glance.",
|
|
23
|
+
"acceptanceCriteria": [
|
|
24
|
+
"Each task card shows colored priority badge (red=high, yellow=medium, gray=low)",
|
|
25
|
+
"Priority visible without hovering or clicking",
|
|
26
|
+
"Typecheck passes",
|
|
27
|
+
"Verify in browser using dev-browser skill"
|
|
28
|
+
],
|
|
29
|
+
"priority": 2,
|
|
30
|
+
"passes": false,
|
|
31
|
+
"notes": ""
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "US-003",
|
|
35
|
+
"title": "Add priority selector to task edit",
|
|
36
|
+
"description": "As a user, I want to change a task's priority when editing it.",
|
|
37
|
+
"acceptanceCriteria": [
|
|
38
|
+
"Priority dropdown in task edit modal",
|
|
39
|
+
"Shows current priority as selected",
|
|
40
|
+
"Saves immediately on selection change",
|
|
41
|
+
"Typecheck passes",
|
|
42
|
+
"Verify in browser using dev-browser skill"
|
|
43
|
+
],
|
|
44
|
+
"priority": 3,
|
|
45
|
+
"passes": false,
|
|
46
|
+
"notes": ""
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "US-004",
|
|
50
|
+
"title": "Filter tasks by priority",
|
|
51
|
+
"description": "As a user, I want to filter the task list to see only high-priority items.",
|
|
52
|
+
"acceptanceCriteria": [
|
|
53
|
+
"Filter dropdown with options: All | High | Medium | Low",
|
|
54
|
+
"Filter persists in URL params",
|
|
55
|
+
"Empty state message when no tasks match filter",
|
|
56
|
+
"Typecheck passes",
|
|
57
|
+
"Verify in browser using dev-browser skill"
|
|
58
|
+
],
|
|
59
|
+
"priority": 4,
|
|
60
|
+
"passes": false,
|
|
61
|
+
"notes": ""
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
package/.env.example
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: npm publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch: {}
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
id-token: write
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
publish:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- name: Checkout
|
|
18
|
+
uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Setup Node.js
|
|
21
|
+
uses: actions/setup-node@v4
|
|
22
|
+
with:
|
|
23
|
+
node-version: "18"
|
|
24
|
+
registry-url: "https://registry.npmjs.org"
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: npm ci
|
|
28
|
+
|
|
29
|
+
- name: Typecheck
|
|
30
|
+
run: npm run typecheck
|
|
31
|
+
|
|
32
|
+
- name: Test
|
|
33
|
+
run: npm test
|
|
34
|
+
|
|
35
|
+
- name: Verify tag matches package version
|
|
36
|
+
shell: bash
|
|
37
|
+
run: |
|
|
38
|
+
TAG="${GITHUB_REF#refs/tags/}"
|
|
39
|
+
VERSION="v$(node -p "require('./package.json').version")"
|
|
40
|
+
if [ "$TAG" != "$VERSION" ]; then
|
|
41
|
+
echo "Tag ($TAG) does not match package.json version ($VERSION)"
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
- name: Publish
|
|
46
|
+
env:
|
|
47
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
48
|
+
run: npm publish --access public
|