prd-parser 0.2.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.
- package/LICENSE +21 -0
- package/README.md +443 -0
- package/bin/prd-parser +14 -0
- package/package.json +46 -0
- package/scripts/install.js +184 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 David Habedank
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
# prd-parser
|
|
2
|
+
|
|
3
|
+
> **🚧 Active Development** - This project is new and actively evolving. Expect breaking changes. Contributions and feedback welcome!
|
|
4
|
+
|
|
5
|
+
**Turn your PRD into a ready-to-work beads project in one command.**
|
|
6
|
+
|
|
7
|
+
prd-parser uses LLM guardrails to transform Product Requirements Documents into a hierarchical issue structure (Epics → Tasks → Subtasks) and creates them directly in [beads](https://github.com/beads-project/beads) - the git-backed issue tracker for AI-driven development.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# One command: PRD → structured beads issues
|
|
11
|
+
prd-parser parse ./docs/prd.md
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## The 0→1 Problem
|
|
15
|
+
|
|
16
|
+
Starting a new project is exciting. You have a vision, maybe a PRD, and you're ready to build. But then:
|
|
17
|
+
|
|
18
|
+
1. **The breakdown problem** - You need to turn that PRD into actionable tasks. This is tedious and error-prone. You lose context as you go.
|
|
19
|
+
|
|
20
|
+
2. **The context problem** - By the time you're implementing subtask #47, you've forgotten why it matters. What was the business goal? Who are the users? What constraints apply?
|
|
21
|
+
|
|
22
|
+
3. **The handoff problem** - If you're using AI to help implement, it needs that context too. Copy-pasting from your PRD for every task doesn't scale.
|
|
23
|
+
|
|
24
|
+
**prd-parser + beads solves all three.** Write your PRD once, run one command, and get a complete project structure with context propagated to every level - ready for you or Claude to start implementing.
|
|
25
|
+
|
|
26
|
+
## Why prd-parser + beads?
|
|
27
|
+
|
|
28
|
+
**For greenfield projects**, this is the fastest path from idea to structured, trackable work:
|
|
29
|
+
|
|
30
|
+
| Without prd-parser | With prd-parser |
|
|
31
|
+
|-------------------|-----------------|
|
|
32
|
+
| Read PRD, manually create issues | One command |
|
|
33
|
+
| Forget context by subtask #10 | Context propagated everywhere |
|
|
34
|
+
| Testing requirements? Maybe later | Testing enforced at every level |
|
|
35
|
+
| Dependencies tracked in your head | Dependencies explicit and tracked |
|
|
36
|
+
| Copy-paste context for AI helpers | AI has full context in every issue |
|
|
37
|
+
|
|
38
|
+
**How it works**: prd-parser uses Go struct guardrails to force the LLM to output valid, hierarchical JSON with:
|
|
39
|
+
- **Context propagation** - Business purpose flows from PRD → Epic → Task → Subtask
|
|
40
|
+
- **Testing at every level** - Unit, integration, type, and E2E requirements enforced
|
|
41
|
+
- **Dependencies tracked** - Issues know what blocks them
|
|
42
|
+
- **Direct beads integration** - Issues created with one command, ready to work
|
|
43
|
+
|
|
44
|
+
## Getting Started: Your First PRD → beads Project
|
|
45
|
+
|
|
46
|
+
### 1. Install prd-parser
|
|
47
|
+
|
|
48
|
+
**Via npm/bun (easiest):**
|
|
49
|
+
```bash
|
|
50
|
+
npm install -g prd-parser
|
|
51
|
+
# or
|
|
52
|
+
bun install -g prd-parser
|
|
53
|
+
# or
|
|
54
|
+
npx prd-parser parse ./docs/prd.md # run without installing
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Via Go:**
|
|
58
|
+
```bash
|
|
59
|
+
go install github.com/dhabedank/prd-parser@latest
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**From source:**
|
|
63
|
+
```bash
|
|
64
|
+
cd /tmp && git clone https://github.com/dhabedank/prd-parser.git && cd prd-parser && make install
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
If you see "Make sure ~/go/bin is in your PATH", run:
|
|
68
|
+
```bash
|
|
69
|
+
echo 'export PATH="$HOME/go/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Now go back to your project.
|
|
73
|
+
|
|
74
|
+
### 2. Create a new project with beads
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
mkdir my-project && cd my-project
|
|
78
|
+
git init
|
|
79
|
+
bd init --prefix my-project
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 3. Write your PRD
|
|
83
|
+
|
|
84
|
+
Create `docs/prd.md` with your product requirements. Include:
|
|
85
|
+
- What you're building and why
|
|
86
|
+
- Who the target users are
|
|
87
|
+
- Technical constraints
|
|
88
|
+
- Key features
|
|
89
|
+
|
|
90
|
+
Example:
|
|
91
|
+
```markdown
|
|
92
|
+
# Task Management CLI
|
|
93
|
+
|
|
94
|
+
## Overview
|
|
95
|
+
A fast, developer-friendly command-line task manager for teams
|
|
96
|
+
who prefer terminal workflows.
|
|
97
|
+
|
|
98
|
+
## Target Users
|
|
99
|
+
Software developers who live in the terminal and want sub-100ms
|
|
100
|
+
task operations without context-switching to a GUI.
|
|
101
|
+
|
|
102
|
+
## Core Features
|
|
103
|
+
1. Create tasks with title, description, priority
|
|
104
|
+
2. List and filter tasks by status/priority
|
|
105
|
+
3. Update task status (todo → in-progress → done)
|
|
106
|
+
4. Local JSON storage for offline-first operation
|
|
107
|
+
|
|
108
|
+
## Technical Constraints
|
|
109
|
+
- Sub-100ms response for all operations
|
|
110
|
+
- Single binary, no runtime dependencies
|
|
111
|
+
- Config stored in ~/.taskman/
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 4. Parse your PRD into beads issues
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
prd-parser parse docs/prd.md
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
That's it. Your PRD is now a structured beads project with **readable hierarchical IDs**:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
$ bd list
|
|
124
|
+
â—‹ my-project-e1 [P1] [epic] - Core Task Management System
|
|
125
|
+
â—‹ my-project-e1t1 [P0] [task] - Implement Task Data Model
|
|
126
|
+
â—‹ my-project-e1t1s1 [P2] [task] - Define Task struct with JSON tags
|
|
127
|
+
â—‹ my-project-e1t1s2 [P2] [task] - Implement JSON file storage
|
|
128
|
+
â—‹ my-project-e1t2 [P1] [task] - Build CLI Interface
|
|
129
|
+
â—‹ my-project-e2 [P1] [epic] - User Authentication
|
|
130
|
+
...
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
IDs follow a logical hierarchy: `e1` (epic 1) → `e1t1` (task 1) → `e1t1s1` (subtask 1). Use `bd show <id>` to see parent/children relationships.
|
|
134
|
+
|
|
135
|
+
### 5. Start working with beads + Claude
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# See what's ready to work on
|
|
139
|
+
bd ready
|
|
140
|
+
|
|
141
|
+
# Pick an issue and let Claude implement it
|
|
142
|
+
bd show my-project-4og # Shows full context, testing requirements
|
|
143
|
+
|
|
144
|
+
# Or let Claude pick and work autonomously
|
|
145
|
+
# (beads integrates with Claude Code via the beads skill)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## What prd-parser Creates
|
|
149
|
+
|
|
150
|
+
### Hierarchical Structure
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
Epic: Core Task Management System
|
|
154
|
+
├── Task: Implement Task Data Model
|
|
155
|
+
│ ├── Subtask: Define Task struct with JSON tags
|
|
156
|
+
│ └── Subtask: Implement JSON file storage
|
|
157
|
+
├── Task: Build CLI Interface
|
|
158
|
+
│ ├── Subtask: Implement create command
|
|
159
|
+
│ └── Subtask: Implement list command
|
|
160
|
+
└── ...
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Context Propagation
|
|
164
|
+
|
|
165
|
+
Every issue includes propagated context so implementers understand WHY:
|
|
166
|
+
|
|
167
|
+
```markdown
|
|
168
|
+
**Context:**
|
|
169
|
+
- **Business Context:** Developers need fast, frictionless task management
|
|
170
|
+
- **Target Users:** Terminal-first developers who want <100ms operations
|
|
171
|
+
- **Success Metrics:** All CRUD operations complete in under 100ms
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Testing Requirements
|
|
175
|
+
|
|
176
|
+
Every issue specifies what testing is needed:
|
|
177
|
+
|
|
178
|
+
```markdown
|
|
179
|
+
**Testing Requirements:**
|
|
180
|
+
- **Unit Tests:** Task struct validation, JSON marshaling/unmarshaling
|
|
181
|
+
- **Integration Tests:** Full storage layer integration, concurrent access
|
|
182
|
+
- **Type Tests:** Go struct tags validation, JSON schema compliance
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Priority Evaluation
|
|
186
|
+
|
|
187
|
+
The LLM evaluates each task and assigns appropriate priority (not just a default):
|
|
188
|
+
|
|
189
|
+
| Priority | When to Use |
|
|
190
|
+
|----------|-------------|
|
|
191
|
+
| **P0 (critical)** | Blocks all work, security issues, launch blockers |
|
|
192
|
+
| **P1 (high)** | Core functionality, enables other tasks |
|
|
193
|
+
| **P2 (medium)** | Important features, standard work |
|
|
194
|
+
| **P3 (low)** | Nice-to-haves, polish |
|
|
195
|
+
| **P4 (very-low)** | Future considerations, can defer indefinitely |
|
|
196
|
+
|
|
197
|
+
Foundation/setup work gets higher priority. Polish/UI tweaks get lower priority.
|
|
198
|
+
|
|
199
|
+
### Labels
|
|
200
|
+
|
|
201
|
+
Issues are automatically labeled based on:
|
|
202
|
+
- **Layer**: frontend, backend, api, database, infra
|
|
203
|
+
- **Domain**: auth, payments, search, notifications
|
|
204
|
+
- **Skill**: react, go, sql, typescript
|
|
205
|
+
- **Type**: setup, feature, refactor, testing
|
|
206
|
+
|
|
207
|
+
Labels are extracted from the PRD's tech stack and feature descriptions.
|
|
208
|
+
|
|
209
|
+
### Design Notes & Acceptance Criteria
|
|
210
|
+
|
|
211
|
+
- **Epics** include acceptance criteria for when the epic is complete
|
|
212
|
+
- **Tasks** include design notes for technical approach
|
|
213
|
+
|
|
214
|
+
### Time Estimates
|
|
215
|
+
|
|
216
|
+
All items include time estimates that flow to beads:
|
|
217
|
+
- Epics: estimated days
|
|
218
|
+
- Tasks: estimated hours
|
|
219
|
+
- Subtasks: estimated minutes
|
|
220
|
+
|
|
221
|
+
### Dependencies
|
|
222
|
+
|
|
223
|
+
Issues are linked with proper blocking relationships:
|
|
224
|
+
- Tasks depend on setup tasks
|
|
225
|
+
- Subtasks depend on parent task completion
|
|
226
|
+
- Cross-epic dependencies are tracked
|
|
227
|
+
|
|
228
|
+
## Configuration
|
|
229
|
+
|
|
230
|
+
### Parse Options
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
# Control structure size
|
|
234
|
+
prd-parser parse ./prd.md --epics 5 --tasks 8 --subtasks 4
|
|
235
|
+
|
|
236
|
+
# Set default priority
|
|
237
|
+
prd-parser parse ./prd.md --priority high
|
|
238
|
+
|
|
239
|
+
# Choose testing level
|
|
240
|
+
prd-parser parse ./prd.md --testing comprehensive # or minimal, standard
|
|
241
|
+
|
|
242
|
+
# Preview without creating (dry run)
|
|
243
|
+
prd-parser parse ./prd.md --dry-run
|
|
244
|
+
|
|
245
|
+
# Include/exclude sections in issue descriptions
|
|
246
|
+
prd-parser parse ./prd.md --include-context --include-testing
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Full Options
|
|
250
|
+
|
|
251
|
+
| Flag | Short | Default | Description |
|
|
252
|
+
|------|-------|---------|-------------|
|
|
253
|
+
| `--epics` | `-e` | 3 | Target number of epics |
|
|
254
|
+
| `--tasks` | `-t` | 5 | Target tasks per epic |
|
|
255
|
+
| `--subtasks` | `-s` | 4 | Target subtasks per task |
|
|
256
|
+
| `--priority` | `-p` | medium | Default priority (critical/high/medium/low) |
|
|
257
|
+
| `--testing` | | comprehensive | Testing level (minimal/standard/comprehensive) |
|
|
258
|
+
| `--llm` | `-l` | auto | LLM provider (auto/claude-cli/codex-cli/anthropic-api) |
|
|
259
|
+
| `--model` | `-m` | | Model to use (provider-specific) |
|
|
260
|
+
| `--multi-stage` | | | Force multi-stage parsing |
|
|
261
|
+
| `--single-shot` | | | Force single-shot parsing |
|
|
262
|
+
| `--smart-threshold` | | 300 | Line count for auto multi-stage (0 to disable) |
|
|
263
|
+
| `--validate` | | false | Run validation pass to check for gaps |
|
|
264
|
+
| `--subtask-model` | | | Model for subtasks in multi-stage (can be faster/cheaper) |
|
|
265
|
+
| `--output` | `-o` | beads | Output adapter (beads/json) |
|
|
266
|
+
| `--output-path` | | | Output path for JSON adapter |
|
|
267
|
+
| `--working-dir` | `-w` | . | Working directory for beads |
|
|
268
|
+
| `--dry-run` | | false | Preview without creating items |
|
|
269
|
+
| `--include-context` | | true | Include context in descriptions |
|
|
270
|
+
| `--include-testing` | | true | Include testing requirements |
|
|
271
|
+
|
|
272
|
+
### Smart Parsing (Default Behavior)
|
|
273
|
+
|
|
274
|
+
prd-parser automatically chooses the best parsing strategy based on PRD size:
|
|
275
|
+
|
|
276
|
+
- **Small PRDs** (< 300 lines): Single-shot parsing (faster)
|
|
277
|
+
- **Large PRDs** (≥ 300 lines): Multi-stage parallel parsing (more reliable)
|
|
278
|
+
|
|
279
|
+
Override with `--single-shot` or `--multi-stage` flags, or adjust threshold with `--smart-threshold`.
|
|
280
|
+
|
|
281
|
+
### Validation Pass
|
|
282
|
+
|
|
283
|
+
Use `--validate` to run a final review that checks for gaps in the generated plan:
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
prd-parser parse ./prd.md --validate
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
This asks the LLM to review the complete plan and identify:
|
|
290
|
+
- Missing setup/initialization tasks
|
|
291
|
+
- Backend without UI to test it
|
|
292
|
+
- Dependencies not installed
|
|
293
|
+
- Acceptance criteria that can't be verified
|
|
294
|
+
- Tasks in wrong order
|
|
295
|
+
|
|
296
|
+
Example output:
|
|
297
|
+
```
|
|
298
|
+
✓ Plan validation passed - no gaps found
|
|
299
|
+
```
|
|
300
|
+
or
|
|
301
|
+
```
|
|
302
|
+
âš Plan validation found gaps:
|
|
303
|
+
• No task to install dependencies after adding @clerk/nextjs
|
|
304
|
+
• Auth API built but no login page to test it
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## LLM Providers
|
|
308
|
+
|
|
309
|
+
### Zero-Config (Recommended)
|
|
310
|
+
|
|
311
|
+
prd-parser auto-detects installed LLM CLIs - no API keys needed:
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
# If you have Claude Code installed, it just works
|
|
315
|
+
prd-parser parse ./prd.md
|
|
316
|
+
|
|
317
|
+
# If you have Codex installed, it just works
|
|
318
|
+
prd-parser parse ./prd.md
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Detection Priority
|
|
322
|
+
|
|
323
|
+
1. **Claude Code CLI** (`claude`) - Preferred, already authenticated
|
|
324
|
+
2. **Codex CLI** (`codex`) - Already authenticated
|
|
325
|
+
3. **Anthropic API** - Fallback if `ANTHROPIC_API_KEY` is set
|
|
326
|
+
|
|
327
|
+
### Explicit Selection
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
# Force specific provider
|
|
331
|
+
prd-parser parse ./prd.md --llm claude-cli
|
|
332
|
+
prd-parser parse ./prd.md --llm codex-cli
|
|
333
|
+
prd-parser parse ./prd.md --llm anthropic-api
|
|
334
|
+
|
|
335
|
+
# Specify model
|
|
336
|
+
prd-parser parse ./prd.md --llm claude-cli --model claude-sonnet-4-20250514
|
|
337
|
+
prd-parser parse ./prd.md --llm codex-cli --model o3
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Output Options
|
|
341
|
+
|
|
342
|
+
### beads (Default)
|
|
343
|
+
|
|
344
|
+
Creates issues directly in the current beads-initialized project:
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
bd init --prefix myproject
|
|
348
|
+
prd-parser parse ./prd.md --output beads
|
|
349
|
+
bd list # See created issues
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### JSON
|
|
353
|
+
|
|
354
|
+
Export to JSON for inspection or custom processing:
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
# Write to file
|
|
358
|
+
prd-parser parse ./prd.md --output json --output-path tasks.json
|
|
359
|
+
|
|
360
|
+
# Write to stdout (pipe to other tools)
|
|
361
|
+
prd-parser parse ./prd.md --output json | jq '.epics[0].tasks'
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## The Guardrails System
|
|
365
|
+
|
|
366
|
+
prd-parser isn't just a prompt wrapper. It uses Go structs as **guardrails** to enforce valid output:
|
|
367
|
+
|
|
368
|
+
```go
|
|
369
|
+
type Epic struct {
|
|
370
|
+
TempID string `json:"temp_id"`
|
|
371
|
+
Title string `json:"title"`
|
|
372
|
+
Description string `json:"description"`
|
|
373
|
+
Context interface{} `json:"context"`
|
|
374
|
+
AcceptanceCriteria []string `json:"acceptance_criteria"`
|
|
375
|
+
Testing TestingRequirements `json:"testing"`
|
|
376
|
+
Tasks []Task `json:"tasks"`
|
|
377
|
+
DependsOn []string `json:"depends_on"`
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
type TestingRequirements struct {
|
|
381
|
+
UnitTests *string `json:"unit_tests,omitempty"`
|
|
382
|
+
IntegrationTests *string `json:"integration_tests,omitempty"`
|
|
383
|
+
TypeTests *string `json:"type_tests,omitempty"`
|
|
384
|
+
E2ETests *string `json:"e2e_tests,omitempty"`
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
The LLM MUST produce output that matches these structs. Missing required fields? Validation fails. Wrong types? Parse fails. This ensures every PRD produces consistent, complete issue structures.
|
|
389
|
+
|
|
390
|
+
## Architecture
|
|
391
|
+
|
|
392
|
+
```
|
|
393
|
+
prd-parser/
|
|
394
|
+
├── cmd/ # CLI commands (Cobra)
|
|
395
|
+
│ └── parse.go # Main parse command
|
|
396
|
+
├── internal/
|
|
397
|
+
│ ├── core/ # Core types and orchestration
|
|
398
|
+
│ │ ├── types.go # Hierarchical structs (guardrails)
|
|
399
|
+
│ │ ├── prompts.go # Embedded system/user prompts
|
|
400
|
+
│ │ └── parser.go # LLM → Output orchestration
|
|
401
|
+
│ ├── llm/ # LLM adapters
|
|
402
|
+
│ │ ├── adapter.go # Interface definition
|
|
403
|
+
│ │ ├── claude_cli.go # Claude Code CLI adapter
|
|
404
|
+
│ │ ├── codex_cli.go # Codex CLI adapter
|
|
405
|
+
│ │ ├── anthropic_api.go # API fallback
|
|
406
|
+
│ │ └── detector.go # Auto-detection logic
|
|
407
|
+
│ └── output/ # Output adapters
|
|
408
|
+
│ ├── adapter.go # Interface definition
|
|
409
|
+
│ ├── beads.go # beads issue tracker
|
|
410
|
+
│ └── json.go # JSON file output
|
|
411
|
+
└── tests/ # Unit tests
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
## Adding Custom Adapters
|
|
415
|
+
|
|
416
|
+
### Custom LLM Adapter
|
|
417
|
+
|
|
418
|
+
```go
|
|
419
|
+
type Adapter interface {
|
|
420
|
+
Name() string
|
|
421
|
+
IsAvailable() bool
|
|
422
|
+
Generate(ctx context.Context, systemPrompt, userPrompt string) (*core.ParseResponse, error)
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### Custom Output Adapter
|
|
427
|
+
|
|
428
|
+
```go
|
|
429
|
+
type Adapter interface {
|
|
430
|
+
Name() string
|
|
431
|
+
IsAvailable() (bool, error)
|
|
432
|
+
CreateItems(response *core.ParseResponse, config Config) (*CreateResult, error)
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
## Related Projects
|
|
437
|
+
|
|
438
|
+
- **[beads](https://github.com/beads-project/beads)** - Git-backed issue tracker for AI-driven development
|
|
439
|
+
- **[Claude Code](https://claude.ai/claude-code)** - Claude's official CLI with beads integration
|
|
440
|
+
|
|
441
|
+
## License
|
|
442
|
+
|
|
443
|
+
MIT
|
package/bin/prd-parser
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// This is a placeholder that gets replaced by the actual binary during install.
|
|
4
|
+
// If you see this message, the installation may have failed.
|
|
5
|
+
|
|
6
|
+
console.error('prd-parser binary not found.');
|
|
7
|
+
console.error('');
|
|
8
|
+
console.error('Try reinstalling:');
|
|
9
|
+
console.error(' npm install -g prd-parser');
|
|
10
|
+
console.error('');
|
|
11
|
+
console.error('Or install manually from:');
|
|
12
|
+
console.error(' https://github.com/dhabedank/prd-parser/releases');
|
|
13
|
+
|
|
14
|
+
process.exit(1);
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "prd-parser",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Turn your PRD into a ready-to-work beads project in one command",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"prd",
|
|
7
|
+
"parser",
|
|
8
|
+
"beads",
|
|
9
|
+
"task",
|
|
10
|
+
"project-management",
|
|
11
|
+
"ai",
|
|
12
|
+
"llm"
|
|
13
|
+
],
|
|
14
|
+
"author": "David Habedank",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/dhabedank/prd-parser.git"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/dhabedank/prd-parser#readme",
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/dhabedank/prd-parser/issues"
|
|
23
|
+
},
|
|
24
|
+
"bin": {
|
|
25
|
+
"prd-parser": "bin/prd-parser"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"postinstall": "node scripts/install.js"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"bin",
|
|
32
|
+
"scripts"
|
|
33
|
+
],
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=16.0.0"
|
|
36
|
+
},
|
|
37
|
+
"os": [
|
|
38
|
+
"darwin",
|
|
39
|
+
"linux",
|
|
40
|
+
"win32"
|
|
41
|
+
],
|
|
42
|
+
"cpu": [
|
|
43
|
+
"x64",
|
|
44
|
+
"arm64"
|
|
45
|
+
]
|
|
46
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execSync } = require('child_process');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const https = require('https');
|
|
7
|
+
const { createWriteStream, chmodSync, existsSync, mkdirSync } = require('fs');
|
|
8
|
+
|
|
9
|
+
const REPO = 'dhabedank/prd-parser';
|
|
10
|
+
const BIN_NAME = 'prd-parser';
|
|
11
|
+
|
|
12
|
+
// Map Node.js platform/arch to Go naming
|
|
13
|
+
function getPlatformInfo() {
|
|
14
|
+
const platform = process.platform;
|
|
15
|
+
const arch = process.arch;
|
|
16
|
+
|
|
17
|
+
const platformMap = {
|
|
18
|
+
darwin: 'darwin',
|
|
19
|
+
linux: 'linux',
|
|
20
|
+
win32: 'windows',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const archMap = {
|
|
24
|
+
x64: 'amd64',
|
|
25
|
+
arm64: 'arm64',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const goPlatform = platformMap[platform];
|
|
29
|
+
const goArch = archMap[arch];
|
|
30
|
+
|
|
31
|
+
if (!goPlatform || !goArch) {
|
|
32
|
+
throw new Error(`Unsupported platform: ${platform}/${arch}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const ext = platform === 'win32' ? '.exe' : '';
|
|
36
|
+
return { goPlatform, goArch, ext };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Get the latest release version from GitHub
|
|
40
|
+
async function getLatestVersion() {
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
const options = {
|
|
43
|
+
hostname: 'api.github.com',
|
|
44
|
+
path: `/repos/${REPO}/releases/latest`,
|
|
45
|
+
headers: { 'User-Agent': 'prd-parser-installer' },
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
https.get(options, (res) => {
|
|
49
|
+
let data = '';
|
|
50
|
+
res.on('data', (chunk) => (data += chunk));
|
|
51
|
+
res.on('end', () => {
|
|
52
|
+
try {
|
|
53
|
+
const release = JSON.parse(data);
|
|
54
|
+
resolve(release.tag_name);
|
|
55
|
+
} catch (e) {
|
|
56
|
+
reject(new Error('Failed to parse GitHub response'));
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}).on('error', reject);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Download file with redirect support
|
|
64
|
+
function downloadFile(url, dest) {
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
const file = createWriteStream(dest);
|
|
67
|
+
|
|
68
|
+
const request = (url) => {
|
|
69
|
+
https.get(url, { headers: { 'User-Agent': 'prd-parser-installer' } }, (res) => {
|
|
70
|
+
// Handle redirects
|
|
71
|
+
if (res.statusCode === 302 || res.statusCode === 301) {
|
|
72
|
+
request(res.headers.location);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (res.statusCode !== 200) {
|
|
77
|
+
reject(new Error(`Download failed with status ${res.statusCode}`));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
res.pipe(file);
|
|
82
|
+
file.on('finish', () => {
|
|
83
|
+
file.close();
|
|
84
|
+
resolve();
|
|
85
|
+
});
|
|
86
|
+
}).on('error', (err) => {
|
|
87
|
+
fs.unlink(dest, () => {});
|
|
88
|
+
reject(err);
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
request(url);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Extract tar.gz archive
|
|
97
|
+
function extractTarGz(archive, dest) {
|
|
98
|
+
execSync(`tar -xzf "${archive}" -C "${dest}"`, { stdio: 'inherit' });
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Extract zip archive
|
|
102
|
+
function extractZip(archive, dest) {
|
|
103
|
+
if (process.platform === 'win32') {
|
|
104
|
+
execSync(`powershell -Command "Expand-Archive -Path '${archive}' -DestinationPath '${dest}'"`, { stdio: 'inherit' });
|
|
105
|
+
} else {
|
|
106
|
+
execSync(`unzip -o "${archive}" -d "${dest}"`, { stdio: 'inherit' });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function main() {
|
|
111
|
+
console.log('Installing prd-parser...');
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
const { goPlatform, goArch, ext } = getPlatformInfo();
|
|
115
|
+
console.log(`Platform: ${goPlatform}/${goArch}`);
|
|
116
|
+
|
|
117
|
+
// Get latest version
|
|
118
|
+
let version;
|
|
119
|
+
try {
|
|
120
|
+
version = await getLatestVersion();
|
|
121
|
+
console.log(`Latest version: ${version}`);
|
|
122
|
+
} catch (e) {
|
|
123
|
+
console.log('Could not fetch latest version, using v0.1.0');
|
|
124
|
+
version = 'v0.1.0';
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Determine archive format
|
|
128
|
+
const archiveExt = goPlatform === 'windows' ? '.zip' : '.tar.gz';
|
|
129
|
+
const archiveName = `prd-parser_${version.replace('v', '')}_${goPlatform}_${goArch}${archiveExt}`;
|
|
130
|
+
const downloadUrl = `https://github.com/${REPO}/releases/download/${version}/${archiveName}`;
|
|
131
|
+
|
|
132
|
+
console.log(`Downloading from: ${downloadUrl}`);
|
|
133
|
+
|
|
134
|
+
// Create temp directory
|
|
135
|
+
const tempDir = path.join(__dirname, '..', '.temp');
|
|
136
|
+
if (!existsSync(tempDir)) {
|
|
137
|
+
mkdirSync(tempDir, { recursive: true });
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const archivePath = path.join(tempDir, archiveName);
|
|
141
|
+
await downloadFile(downloadUrl, archivePath);
|
|
142
|
+
console.log('Download complete');
|
|
143
|
+
|
|
144
|
+
// Extract
|
|
145
|
+
console.log('Extracting...');
|
|
146
|
+
if (archiveExt === '.zip') {
|
|
147
|
+
extractZip(archivePath, tempDir);
|
|
148
|
+
} else {
|
|
149
|
+
extractTarGz(archivePath, tempDir);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Move binary to bin directory
|
|
153
|
+
const binDir = path.join(__dirname, '..', 'bin');
|
|
154
|
+
if (!existsSync(binDir)) {
|
|
155
|
+
mkdirSync(binDir, { recursive: true });
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const srcBinary = path.join(tempDir, `${BIN_NAME}${ext}`);
|
|
159
|
+
const destBinary = path.join(binDir, `${BIN_NAME}${ext}`);
|
|
160
|
+
|
|
161
|
+
fs.copyFileSync(srcBinary, destBinary);
|
|
162
|
+
|
|
163
|
+
// Make executable on Unix
|
|
164
|
+
if (goPlatform !== 'windows') {
|
|
165
|
+
chmodSync(destBinary, 0o755);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Cleanup
|
|
169
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
170
|
+
|
|
171
|
+
console.log(`✓ prd-parser installed successfully to ${destBinary}`);
|
|
172
|
+
console.log('Run "prd-parser --help" to get started');
|
|
173
|
+
|
|
174
|
+
} catch (error) {
|
|
175
|
+
console.error('Installation failed:', error.message);
|
|
176
|
+
console.error('');
|
|
177
|
+
console.error('You can install manually:');
|
|
178
|
+
console.error(' 1. Download from https://github.com/dhabedank/prd-parser/releases');
|
|
179
|
+
console.error(' 2. Extract and move prd-parser to a directory in your PATH');
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
main();
|