rlph-cli 0.1.0 → 1.1.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.
Files changed (71) hide show
  1. package/README.md +79 -40
  2. package/dist/agents/claude-events.d.ts +45 -0
  3. package/dist/agents/claude-events.d.ts.map +1 -0
  4. package/dist/agents/claude-events.js +2 -0
  5. package/dist/agents/claude-events.js.map +1 -0
  6. package/dist/agents/claude-formatter.d.ts +3 -0
  7. package/dist/agents/claude-formatter.d.ts.map +1 -0
  8. package/dist/agents/claude-formatter.js +45 -0
  9. package/dist/agents/claude-formatter.js.map +1 -0
  10. package/dist/agents/claude.d.ts.map +1 -1
  11. package/dist/agents/claude.js +27 -40
  12. package/dist/agents/claude.js.map +1 -1
  13. package/dist/commands/prd-add.d.ts +5 -0
  14. package/dist/commands/prd-add.d.ts.map +1 -0
  15. package/dist/commands/prd-add.js +72 -0
  16. package/dist/commands/prd-add.js.map +1 -0
  17. package/dist/commands/prd-list.d.ts +2 -0
  18. package/dist/commands/prd-list.d.ts.map +1 -0
  19. package/dist/commands/prd-list.js +47 -0
  20. package/dist/commands/prd-list.js.map +1 -0
  21. package/dist/commands/run.d.ts +1 -2
  22. package/dist/commands/run.d.ts.map +1 -1
  23. package/dist/commands/run.js +45 -23
  24. package/dist/commands/run.js.map +1 -1
  25. package/dist/index.js +13 -2
  26. package/dist/index.js.map +1 -1
  27. package/dist/prd/index.d.ts +3 -0
  28. package/dist/prd/index.d.ts.map +1 -0
  29. package/dist/prd/index.js +3 -0
  30. package/dist/prd/index.js.map +1 -0
  31. package/dist/prd/manager.d.ts +9 -0
  32. package/dist/prd/manager.d.ts.map +1 -0
  33. package/dist/prd/manager.js +68 -0
  34. package/dist/prd/manager.js.map +1 -0
  35. package/dist/prd/types.d.ts +25 -0
  36. package/dist/prd/types.d.ts.map +1 -0
  37. package/dist/prd/types.js +2 -0
  38. package/dist/prd/types.js.map +1 -0
  39. package/dist/templates/index.d.ts +2 -0
  40. package/dist/templates/index.d.ts.map +1 -0
  41. package/dist/templates/index.js +2 -0
  42. package/dist/templates/index.js.map +1 -0
  43. package/dist/templates/templates.d.ts +6 -0
  44. package/dist/templates/templates.d.ts.map +1 -0
  45. package/dist/templates/templates.js +47 -0
  46. package/dist/templates/templates.js.map +1 -0
  47. package/dist/utils/index.d.ts +1 -1
  48. package/dist/utils/index.d.ts.map +1 -1
  49. package/dist/utils/index.js +1 -1
  50. package/dist/utils/index.js.map +1 -1
  51. package/dist/utils/ndjson.d.ts +12 -0
  52. package/dist/utils/ndjson.d.ts.map +1 -0
  53. package/dist/utils/ndjson.js +43 -0
  54. package/dist/utils/ndjson.js.map +1 -0
  55. package/package.json +11 -2
  56. package/dist/session/index.d.ts +0 -3
  57. package/dist/session/index.d.ts.map +0 -1
  58. package/dist/session/index.js +0 -3
  59. package/dist/session/index.js.map +0 -1
  60. package/dist/session/logger.d.ts +0 -10
  61. package/dist/session/logger.d.ts.map +0 -1
  62. package/dist/session/logger.js +0 -17
  63. package/dist/session/logger.js.map +0 -1
  64. package/dist/session/manager.d.ts +0 -18
  65. package/dist/session/manager.d.ts.map +0 -1
  66. package/dist/session/manager.js +0 -29
  67. package/dist/session/manager.js.map +0 -1
  68. package/dist/utils/files.d.ts +0 -4
  69. package/dist/utils/files.d.ts.map +0 -1
  70. package/dist/utils/files.js +0 -39
  71. package/dist/utils/files.js.map +0 -1
package/README.md CHANGED
@@ -1,15 +1,9 @@
1
1
  # Ralph
2
2
 
3
- Loop coding agent CLI - run AI coding agents headlessly in a loop.
3
+ PRD-based task tracking CLI for AI coding agents. Run agents headlessly with structured task tracking and progress visibility.
4
4
 
5
5
  Inspired by [Geoff Huntley's ralph technique](https://ghuntley.com/ralph/) - putting a coding agent in a while loop and letting it work autonomously.
6
6
 
7
- ```bash
8
- while :; do cat prompt.md | claude -p; done
9
- ```
10
-
11
- Ralph wraps this pattern into a proper CLI with session logging, iteration limits, and automatic task completion detection.
12
-
13
7
  ## Installation
14
8
 
15
9
  ```bash
@@ -17,7 +11,7 @@ Ralph wraps this pattern into a proper CLI with session logging, iteration limit
17
11
  npm install -g rlph-cli
18
12
 
19
13
  # or run directly
20
- npx rlph-cli run -p "your task"
14
+ npx rlph-cli prd add my-feature.md my-feature
21
15
  ```
22
16
 
23
17
  ### From source
@@ -32,60 +26,73 @@ bun link
32
26
 
33
27
  ## Usage
34
28
 
29
+ ### Add a PRD
30
+
31
+ Convert markdown PRD to trackable JSON tasks:
32
+
33
+ ```bash
34
+ ralph prd add <path> <name> [--agent claude]
35
+ ```
36
+
37
+ Example:
35
38
  ```bash
36
- ralph run -p <prompt> [-a agent] [-i iterations]
39
+ ralph prd add feature.md my-feature
37
40
  ```
38
41
 
39
- ### Options
42
+ Creates `~/.ralph/prd/my-feature/` with:
43
+ - `prd.md` - original markdown
44
+ - `prd.json` - converted tasks with pass/fail tracking
45
+ - `progress.txt` - cross-iteration memory
40
46
 
41
- | Flag | Description | Default |
42
- |------|-------------|---------|
43
- | `-p, --prompt <files...>` | Prompt text or files to pass to agent | required |
44
- | `-a, --agent <agent>` | Agent type (currently: claude) | `claude` |
45
- | `-i, --iterations <n>` | Max loop iterations | `4` |
47
+ ### List PRDs
46
48
 
47
- ### Examples
49
+ View all PRDs with status:
48
50
 
49
- **Simple task**
50
51
  ```bash
51
- ralph run -p "fix the login bug" -i 3
52
+ ralph prd list
52
53
  ```
53
54
 
54
- **Using a prompt file**
55
- ```bash
56
- ralph run -p prompt.md -i 10
55
+ Output:
56
+ ```
57
+ 1. my-feature - Add login flow - in_progress (3/7)
58
+ 2. refactor-api - API cleanup - pending (0/4)
57
59
  ```
58
60
 
59
- **Multiple prompts/files**
61
+ ### Run PRD
62
+
63
+ Execute agent loop against a PRD:
64
+
60
65
  ```bash
61
- ralph run -p task.md context.md "also add tests"
66
+ ralph run <prd-name> [--agent claude] [--iterations 4]
62
67
  ```
63
68
 
64
- **Long running task**
69
+ Example:
65
70
  ```bash
66
- ralph run -p "port this codebase from React to Vue" -i 50
71
+ ralph run my-feature -i 10
67
72
  ```
68
73
 
69
- ## How it works
74
+ Agent picks up next incomplete task, implements it, runs feedback loops (tests/lint/types), marks task passed, repeats until done.
70
75
 
71
- 1. Ralph reads your prompt (text or files)
72
- 2. Appends completion instructions asking agent to output `<ralph>RALPH_COMPLETED</ralph>` when done
73
- 3. Runs the agent in a loop up to N iterations
74
- 4. Streams output in real-time
75
- 5. Stops early if agent signals completion
76
- 6. Logs each iteration to `~/.ralph/sessions/<session-id>/`
76
+ ## How it works
77
77
 
78
- ## Session logs
78
+ 1. Write markdown PRD with tasks and verification steps
79
+ 2. `ralph prd add` converts to JSON with agent
80
+ 3. `ralph run` loops agent against PRD tasks
81
+ 4. Agent updates `prd.json` passes field on completion
82
+ 5. Agent maintains `progress.txt` with learnings across iterations
83
+ 6. Stops when all tasks pass or max iterations reached
84
+ 7. Logs each iteration to `~/.ralph/prd/<name>/iterations/`
79
85
 
80
- All sessions are logged to `~/.ralph/sessions/`:
86
+ ## PRD folder structure
81
87
 
82
88
  ```
83
- ~/.ralph/sessions/
84
- └── <session-id>/
85
- ├── meta.json # session metadata
86
- ├── 0.log # iteration 0 output
87
- ├── 1.log # iteration 1 output
88
- └── ...
89
+ ~/.ralph/prd/<name>/
90
+ ├── prd.md # Original markdown
91
+ ├── prd.json # Tasks with passes field
92
+ ├── progress.txt # Cross-iteration memory
93
+ └── iterations/ # Iteration logs
94
+ ├── 0.json
95
+ └── ...
89
96
  ```
90
97
 
91
98
  ## Supported agents
@@ -97,6 +104,38 @@ All sessions are logged to `~/.ralph/sessions/`:
97
104
  - Node.js >= 18
98
105
  - Claude Code CLI installed and authenticated
99
106
 
107
+ ## Releases
108
+
109
+ This project uses [semantic-release](https://github.com/semantic-release/semantic-release) for automated versioning and npm publishing.
110
+
111
+ ### How it works
112
+
113
+ 1. Push/merge to `main` triggers release workflow
114
+ 2. Commits are analyzed to determine version bump
115
+ 3. CHANGELOG.md is updated automatically
116
+ 4. Package is published to npm
117
+ 5. GitHub release is created
118
+
119
+ ### Conventional Commits
120
+
121
+ Commit messages must follow [Conventional Commits](https://www.conventionalcommits.org/):
122
+
123
+ ```
124
+ <type>(<scope>): <description>
125
+
126
+ [optional body]
127
+
128
+ [optional footer]
129
+ ```
130
+
131
+ | Type | Version Bump | Example |
132
+ |------|--------------|---------|
133
+ | `fix` | Patch (1.0.x) | `fix(cli): handle empty input` |
134
+ | `feat` | Minor (1.x.0) | `feat(prd): add export command` |
135
+ | `feat!` or `BREAKING CHANGE:` | Major (x.0.0) | `feat!: change config format` |
136
+
137
+ Other types (`docs`, `chore`, `refactor`, `test`, `ci`) don't trigger releases.
138
+
100
139
  ## License
101
140
 
102
141
  MIT
@@ -0,0 +1,45 @@
1
+ export interface TextContent {
2
+ type: 'text';
3
+ text: string;
4
+ }
5
+ export interface ToolUseContent {
6
+ type: 'tool_use';
7
+ id: string;
8
+ name: string;
9
+ input: Record<string, unknown>;
10
+ }
11
+ export interface ToolResultContent {
12
+ type: 'tool_result';
13
+ tool_use_id: string;
14
+ content: string;
15
+ }
16
+ export type ContentBlock = TextContent | ToolUseContent | ToolResultContent;
17
+ export interface SystemEvent {
18
+ type: 'system';
19
+ subtype: 'init';
20
+ session_id: string;
21
+ tools: string[];
22
+ model: string;
23
+ }
24
+ export interface AssistantEvent {
25
+ type: 'assistant';
26
+ message: {
27
+ content: ContentBlock[];
28
+ };
29
+ session_id: string;
30
+ }
31
+ export interface UserEvent {
32
+ type: 'user';
33
+ message: {
34
+ content: ToolResultContent[];
35
+ };
36
+ }
37
+ export interface ResultEvent {
38
+ type: 'result';
39
+ subtype: 'success' | 'error_max_turns' | 'error_during_execution';
40
+ is_error: boolean;
41
+ duration_ms: number;
42
+ result?: string;
43
+ }
44
+ export type StreamEvent = SystemEvent | AssistantEvent | UserEvent | ResultEvent;
45
+ //# sourceMappingURL=claude-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-events.d.ts","sourceRoot":"","sources":["../../src/agents/claude-events.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAA;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,aAAa,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,cAAc,GAAG,iBAAiB,CAAA;AAE3E,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,WAAW,CAAA;IACjB,OAAO,EAAE;QACP,OAAO,EAAE,YAAY,EAAE,CAAA;KACxB,CAAA;IACD,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE;QACP,OAAO,EAAE,iBAAiB,EAAE,CAAA;KAC7B,CAAA;CACF;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAA;IACd,OAAO,EAAE,SAAS,GAAG,iBAAiB,GAAG,wBAAwB,CAAA;IACjE,QAAQ,EAAE,OAAO,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,WAAW,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=claude-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-events.js","sourceRoot":"","sources":["../../src/agents/claude-events.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { StreamEvent } from './claude-events.js';
2
+ export declare function formatEvent(event: StreamEvent): string | null;
3
+ //# sourceMappingURL=claude-formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-formatter.d.ts","sourceRoot":"","sources":["../../src/agents/claude-formatter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAgD,MAAM,oBAAoB,CAAA;AAEnG,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAiB7D"}
@@ -0,0 +1,45 @@
1
+ import chalk from 'chalk';
2
+ export function formatEvent(event) {
3
+ switch (event.type) {
4
+ case 'system':
5
+ return chalk.gray(`[session] ${event.session_id} model=${event.model}`);
6
+ case 'assistant':
7
+ return formatAssistantContent(event.message.content);
8
+ case 'user':
9
+ return formatToolResults(event.message.content);
10
+ case 'result':
11
+ return formatResult(event);
12
+ default:
13
+ return null;
14
+ }
15
+ }
16
+ function formatAssistantContent(content) {
17
+ const lines = [];
18
+ for (const block of content) {
19
+ if (block.type === 'text') {
20
+ lines.push(block.text);
21
+ }
22
+ else if (block.type === 'tool_use') {
23
+ lines.push(chalk.cyan(`[tool] ${block.name}`));
24
+ lines.push(chalk.gray(JSON.stringify(block.input, null, 2)));
25
+ }
26
+ }
27
+ return lines.join('\n');
28
+ }
29
+ function formatToolResults(content) {
30
+ const lines = [];
31
+ for (const block of content) {
32
+ const preview = block.content.length > 200
33
+ ? block.content.slice(0, 200) + '...'
34
+ : block.content;
35
+ lines.push(chalk.green(`[result] ${preview}`));
36
+ }
37
+ return lines.join('\n');
38
+ }
39
+ function formatResult(event) {
40
+ if (event.is_error) {
41
+ return chalk.red(`[done] ${event.subtype} (${event.duration_ms}ms)`);
42
+ }
43
+ return chalk.green(`[done] ${event.subtype} (${event.duration_ms}ms)`);
44
+ }
45
+ //# sourceMappingURL=claude-formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-formatter.js","sourceRoot":"","sources":["../../src/agents/claude-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,MAAM,UAAU,WAAW,CAAC,KAAkB;IAC5C,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,UAAU,UAAU,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;QAEzE,KAAK,WAAW;YACd,OAAO,sBAAsB,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAEtD,KAAK,MAAM;YACT,OAAO,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAEjD,KAAK,QAAQ;YACX,OAAO,YAAY,CAAC,KAAK,CAAC,CAAA;QAE5B;YACE,OAAO,IAAI,CAAA;IACf,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB,CAAC,OAAuB;IACrD,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACxB,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;YAC9C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QAC9D,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,SAAS,iBAAiB,CAAC,OAA4B;IACrD,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG;YACxC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK;YACrC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAA;QACjB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC,CAAA;IAChD,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,SAAS,YAAY,CAAC,KAAkB;IACtC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,WAAW,KAAK,CAAC,CAAA;IACtE,CAAC;IACD,OAAO,KAAK,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,WAAW,KAAK,CAAC,CAAA;AACxE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/agents/claude.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAA+B,MAAM,WAAW,CAAA;AAmBnE,eAAO,MAAM,MAAM,EAAE,KAqEpB,CAAA"}
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/agents/claude.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAA+B,MAAM,WAAW,CAAA;AAKnE,eAAO,MAAM,MAAM,EAAE,KA0EpB,CAAA"}
@@ -1,21 +1,7 @@
1
1
  import { spawn } from 'node:child_process';
2
- function parseStreamJson(line) {
3
- try {
4
- const data = JSON.parse(line);
5
- // Only parse assistant messages, skip result (already streamed)
6
- if (data.type === 'assistant' && data.message?.content) {
7
- for (const block of data.message.content) {
8
- if (block.type === 'text') {
9
- return block.text;
10
- }
11
- }
12
- }
13
- }
14
- catch {
15
- // Not valid JSON, ignore
16
- }
17
- return null;
18
- }
2
+ import chalk from 'chalk';
3
+ import { NDJSONParser } from '../utils/ndjson.js';
4
+ import { formatEvent } from './claude-formatter.js';
19
5
  export const claude = {
20
6
  name: 'claude',
21
7
  async execute(prompt, cwd, options) {
@@ -24,50 +10,51 @@ export const claude = {
24
10
  return new Promise((resolve, reject) => {
25
11
  const proc = spawn('claude', [
26
12
  '-p',
13
+ '--verbose',
27
14
  '--dangerously-skip-permissions',
28
15
  '--output-format', 'stream-json',
29
- '--verbose',
30
16
  ], {
31
17
  cwd,
32
18
  stdio: ['pipe', 'pipe', 'pipe'],
33
19
  shell: true,
34
20
  });
35
- let output = '';
21
+ let rawOutput = '';
22
+ let textOutput = '';
36
23
  let stderr = '';
37
- let buffer = '';
38
- proc.stdout.on('data', (data) => {
39
- buffer += data.toString();
40
- const lines = buffer.split('\n');
41
- buffer = lines.pop() || ''; // Keep incomplete line in buffer
42
- for (const line of lines) {
43
- if (!line.trim())
44
- continue;
45
- const text = parseStreamJson(line);
46
- if (text) {
47
- output += text;
48
- onOutput?.(text);
24
+ const parser = new NDJSONParser((event) => {
25
+ const formatted = formatEvent(event);
26
+ if (formatted) {
27
+ onOutput?.(formatted + '\n');
28
+ }
29
+ // Accumulate text content for completion marker detection
30
+ if (event.type === 'assistant') {
31
+ for (const block of event.message.content) {
32
+ if (block.type === 'text') {
33
+ textOutput += block.text;
34
+ }
49
35
  }
50
36
  }
37
+ }, (_error, line) => {
38
+ onOutput?.(chalk.yellow(`[warn] malformed JSON: ${line.slice(0, 100)}\n`));
39
+ });
40
+ proc.stdout.on('data', (data) => {
41
+ const chunk = data.toString();
42
+ rawOutput += chunk;
43
+ parser.push(chunk);
51
44
  });
52
45
  proc.stderr.on('data', (data) => {
53
46
  const chunk = data.toString();
54
47
  stderr += chunk;
48
+ onOutput?.(chalk.red(chunk));
55
49
  });
56
50
  proc.on('error', (err) => {
57
51
  reject(new Error(`Failed to spawn claude: ${err.message}`));
58
52
  });
59
53
  proc.on('close', (code) => {
60
- // Process any remaining buffer
61
- if (buffer.trim()) {
62
- const text = parseStreamJson(buffer);
63
- if (text) {
64
- output += text;
65
- onOutput?.(text);
66
- }
67
- }
54
+ parser.flush();
68
55
  const duration = Date.now() - startTime;
69
56
  resolve({
70
- output: output + (stderr ? `\n[stderr]\n${stderr}` : ''),
57
+ output: textOutput + (stderr ? `\n[stderr]\n${stderr}` : ''),
71
58
  exitCode: code ?? 1,
72
59
  duration,
73
60
  });
@@ -1 +1 @@
1
- {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/agents/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAG1C,SAAS,eAAe,CAAC,IAAY;IACnC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC7B,gEAAgE;QAChE,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;YACvD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBACzC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBAC1B,OAAO,KAAK,CAAC,IAAI,CAAA;gBACnB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,yBAAyB;IAC3B,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAU;IAC3B,IAAI,EAAE,QAAQ;IAEd,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,GAAW,EAAE,OAAwB;QACjE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC5B,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,CAAA;QAElC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE;gBAC3B,IAAI;gBACJ,gCAAgC;gBAChC,iBAAiB,EAAE,aAAa;gBAChC,WAAW;aACZ,EAAE;gBACD,GAAG;gBACH,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;gBAC/B,KAAK,EAAE,IAAI;aACZ,CAAC,CAAA;YAEF,IAAI,MAAM,GAAG,EAAE,CAAA;YACf,IAAI,MAAM,GAAG,EAAE,CAAA;YACf,IAAI,MAAM,GAAG,EAAE,CAAA;YAEf,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBACtC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAA;gBACzB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;gBAChC,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAA,CAAC,iCAAiC;gBAE5D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;wBAAE,SAAQ;oBAC1B,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,CAAA;oBAClC,IAAI,IAAI,EAAE,CAAC;wBACT,MAAM,IAAI,IAAI,CAAA;wBACd,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAA;oBAClB,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAA;YAEF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBACtC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAA;gBAC7B,MAAM,IAAI,KAAK,CAAA;YACjB,CAAC,CAAC,CAAA;YAEF,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACvB,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;YAC7D,CAAC,CAAC,CAAA;YAEF,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBACxB,+BAA+B;gBAC/B,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;oBAClB,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,CAAA;oBACpC,IAAI,IAAI,EAAE,CAAC;wBACT,MAAM,IAAI,IAAI,CAAA;wBACd,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAA;oBAClB,CAAC;gBACH,CAAC;gBAED,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;gBACvC,OAAO,CAAC;oBACN,MAAM,EAAE,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACxD,QAAQ,EAAE,IAAI,IAAI,CAAC;oBACnB,QAAQ;iBACT,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;YAEF,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YACxB,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAA;QAClB,CAAC,CAAC,CAAA;IACJ,CAAC;CACF,CAAA"}
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/agents/claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export interface PrdAddOptions {
2
+ agent: string;
3
+ }
4
+ export declare function prdAdd(path: string, name: string, opts: PrdAddOptions): Promise<void>;
5
+ //# sourceMappingURL=prd-add.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prd-add.d.ts","sourceRoot":"","sources":["../../src/commands/prd-add.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;CACd;AAED,wBAAsB,MAAM,CAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,IAAI,CAAC,CA2Ef"}
@@ -0,0 +1,72 @@
1
+ import chalk from 'chalk';
2
+ import { access, writeFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { getAgent, isValidAgent } from '../agents/index.js';
5
+ import { createPrdFolder, copyMarkdown, getPrdDir, prdExists } from '../prd/index.js';
6
+ import { ensureTemplates, loadTemplate, substituteVars } from '../templates/index.js';
7
+ export async function prdAdd(path, name, opts) {
8
+ // Validate agent
9
+ if (!isValidAgent(opts.agent)) {
10
+ console.error(chalk.red(`Unknown agent: ${opts.agent}`));
11
+ console.error(`Supported agents: claude`);
12
+ process.exit(1);
13
+ }
14
+ // Validate markdown file exists
15
+ try {
16
+ await access(path);
17
+ }
18
+ catch {
19
+ console.error(chalk.red(`File not found: ${path}`));
20
+ process.exit(1);
21
+ }
22
+ // Check if PRD already exists
23
+ if (await prdExists(name)) {
24
+ console.error(chalk.red(`PRD already exists: ${name}`));
25
+ process.exit(1);
26
+ }
27
+ const prdDir = getPrdDir(name);
28
+ const prdJsonPath = join(prdDir, 'prd.json');
29
+ const progressPath = join(prdDir, 'progress.txt');
30
+ console.log(chalk.blue(`Creating PRD: ${name}`));
31
+ // Create folder and copy markdown
32
+ await createPrdFolder(name);
33
+ await copyMarkdown(path, name);
34
+ console.log(chalk.gray(` Copied ${path} → prd.md`));
35
+ // Ensure templates and load prd-md-to-json
36
+ await ensureTemplates();
37
+ const template = await loadTemplate('prd-md-to-json');
38
+ const prompt = substituteVars(template, {
39
+ PRD_PATH: join(prdDir, 'prd.md'),
40
+ OUTPUT_PATH: prdJsonPath,
41
+ });
42
+ // Run agent to convert markdown to JSON
43
+ console.log(chalk.yellow(` Running ${opts.agent} to convert PRD...`));
44
+ const agent = getAgent(opts.agent);
45
+ const result = await agent.execute(prompt, process.cwd(), {
46
+ onOutput: (chunk) => process.stdout.write(chunk),
47
+ });
48
+ console.log();
49
+ if (result.exitCode !== 0) {
50
+ console.error(chalk.red(`Agent failed with exit code ${result.exitCode}`));
51
+ process.exit(1);
52
+ }
53
+ // Validate prd.json was created
54
+ try {
55
+ await access(prdJsonPath);
56
+ }
57
+ catch {
58
+ console.error(chalk.red(`Agent did not create prd.json`));
59
+ process.exit(1);
60
+ }
61
+ // Create empty progress.txt
62
+ await writeFile(progressPath, '');
63
+ // Read task count for summary
64
+ const { readFile } = await import('node:fs/promises');
65
+ const prdContent = await readFile(prdJsonPath, 'utf-8');
66
+ const prd = JSON.parse(prdContent);
67
+ const taskCount = prd.tasks?.length ?? 0;
68
+ console.log(chalk.green(`PRD created: ${name}`));
69
+ console.log(chalk.gray(` Tasks: ${taskCount}`));
70
+ console.log(chalk.gray(` Location: ${prdDir}`));
71
+ }
72
+ //# sourceMappingURL=prd-add.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prd-add.js","sourceRoot":"","sources":["../../src/commands/prd-add.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function prdList(): Promise<void>;
2
+ //# sourceMappingURL=prd-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prd-list.d.ts","sourceRoot":"","sources":["../../src/commands/prd-list.ts"],"names":[],"mappings":"AAeA,wBAAsB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CA6C7C"}
@@ -0,0 +1,47 @@
1
+ import chalk from 'chalk';
2
+ import { listPrds } from '../prd/index.js';
3
+ function statusColor(status) {
4
+ switch (status) {
5
+ case 'pending':
6
+ return chalk.gray(status);
7
+ case 'in_progress':
8
+ return chalk.yellow(status);
9
+ case 'completed':
10
+ return chalk.green(status);
11
+ }
12
+ }
13
+ export async function prdList() {
14
+ const prds = await listPrds();
15
+ if (prds.length === 0) {
16
+ console.log(chalk.gray('No PRDs found'));
17
+ return;
18
+ }
19
+ // Calculate column widths
20
+ const nameWidth = Math.max(4, ...prds.map((p) => p.name.length));
21
+ const descWidth = Math.min(40, Math.max(11, ...prds.map((p) => p.description.length)));
22
+ const statusWidth = 11;
23
+ const progressWidth = 8;
24
+ // Header
25
+ console.log(chalk.bold('NAME'.padEnd(nameWidth) +
26
+ ' ' +
27
+ 'DESCRIPTION'.padEnd(descWidth) +
28
+ ' ' +
29
+ 'STATUS'.padEnd(statusWidth) +
30
+ ' ' +
31
+ 'PROGRESS'));
32
+ // Rows
33
+ for (const prd of prds) {
34
+ const desc = prd.description.length > descWidth
35
+ ? prd.description.slice(0, descWidth - 3) + '...'
36
+ : prd.description;
37
+ const progress = `${prd.tasksCompleted}/${prd.tasksTotal}`;
38
+ console.log(prd.name.padEnd(nameWidth) +
39
+ ' ' +
40
+ desc.padEnd(descWidth) +
41
+ ' ' +
42
+ statusColor(prd.status).padEnd(statusWidth + 10) + // extra for ansi codes
43
+ ' ' +
44
+ progress.padStart(progressWidth));
45
+ }
46
+ }
47
+ //# sourceMappingURL=prd-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prd-list.js","sourceRoot":"","sources":["../../src/commands/prd-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAG1C,SAAS,WAAW,CAAC,MAAqB;IACxC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC3B,KAAK,aAAa;YAChB,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAC7B,KAAK,WAAW;YACd,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC9B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAA;IAE7B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAA;QACxC,OAAM;IACR,CAAC;IAED,0BAA0B;IAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;IAChE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IACtF,MAAM,WAAW,GAAG,EAAE,CAAA;IACtB,MAAM,aAAa,GAAG,CAAC,CAAA;IAEvB,SAAS;IACT,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CACR,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;QACtB,IAAI;QACJ,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC;QAC/B,IAAI;QACJ,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC;QAC5B,IAAI;QACJ,UAAU,CACb,CACF,CAAA;IAED,OAAO;IACP,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GACR,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,SAAS;YAChC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,KAAK;YACjD,CAAC,CAAC,GAAG,CAAC,WAAW,CAAA;QACrB,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,cAAc,IAAI,GAAG,CAAC,UAAU,EAAE,CAAA;QAE1D,OAAO,CAAC,GAAG,CACT,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;YACxB,IAAI;YACJ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;YACtB,IAAI;YACJ,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,WAAW,GAAG,EAAE,CAAC,GAAG,uBAAuB;YAC1E,IAAI;YACJ,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CACnC,CAAA;IACH,CAAC;AACH,CAAC"}
@@ -1,7 +1,6 @@
1
1
  export interface RunOptions {
2
- prompt: string[];
3
2
  agent: string;
4
3
  iterations: string;
5
4
  }
6
- export declare function run(opts: RunOptions): Promise<void>;
5
+ export declare function run(prdName: string, opts: RunOptions): Promise<void>;
7
6
  //# sourceMappingURL=run.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,wBAAsB,GAAG,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA4EzD"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,wBAAsB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAsF1E"}