claude-task-master 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.
@@ -0,0 +1,305 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+ require 'timeout'
5
+
6
+ module ClaudeTaskMaster
7
+ # Wrapper around the Claude Code CLI
8
+ # Handles invocation, output capture, and error handling
9
+ class Claude
10
+ DEFAULT_TIMEOUT = 3600 # 1 hour max per invocation
11
+ CLAUDE_BINARY = 'claude'
12
+
13
+ attr_reader :model, :timeout
14
+
15
+ def initialize(model: 'sonnet', timeout: DEFAULT_TIMEOUT)
16
+ @model = model
17
+ @timeout = timeout
18
+ end
19
+
20
+ # Check if Claude CLI is available
21
+ def self.available?
22
+ system('which claude > /dev/null 2>&1')
23
+ end
24
+
25
+ # Get Claude version
26
+ def self.version
27
+ `claude --version 2>&1`.strip
28
+ end
29
+
30
+ # Invoke Claude with a prompt (non-interactive mode)
31
+ # Returns [success, output, exit_code]
32
+ def invoke(prompt, allowed_tools: nil, working_dir: nil)
33
+ args = build_args(allowed_tools)
34
+ cmd = [CLAUDE_BINARY, *args, prompt]
35
+
36
+ output = +''
37
+ success = false
38
+ exit_code = nil
39
+
40
+ Dir.chdir(working_dir || Dir.pwd) do
41
+ Timeout.timeout(timeout) do
42
+ Open3.popen2e(*cmd) do |stdin, stdout_err, wait_thr|
43
+ stdin.close
44
+
45
+ # Stream output in real-time
46
+ stdout_err.each_line do |line|
47
+ output << line
48
+ # Minimal progress indicator
49
+ $stdout.print '.' if line.include?('[Tool:')
50
+ end
51
+
52
+ exit_code = wait_thr.value.exitstatus
53
+ success = exit_code.zero?
54
+ end
55
+ end
56
+ end
57
+
58
+ $stdout.puts if output.include?('[Tool:') # Newline after dots
59
+
60
+ [success, output, exit_code]
61
+ rescue Timeout::Error
62
+ [false, "#{output}\n\n[TIMEOUT after #{timeout}s]", -1]
63
+ rescue StandardError => e
64
+ [false, "#{output}\n\n[ERROR: #{e.message}]", -1]
65
+ end
66
+
67
+ # Build the planning prompt
68
+ def self.planning_prompt(goal, existing_claude_md: nil, no_merge: false)
69
+ claude_md_section = if existing_claude_md
70
+ <<~SECTION
71
+ ## Existing Project Context (CLAUDE.md)
72
+ The project already has a CLAUDE.md file. Read and follow its conventions:
73
+
74
+ ```
75
+ #{existing_claude_md[0..2000]}#{'...' if existing_claude_md.length > 2000}
76
+ ```
77
+ SECTION
78
+ else
79
+ ''
80
+ end
81
+
82
+ <<~PROMPT
83
+ # Claude Task Master - Planning Phase
84
+
85
+ You are an autonomous software engineer starting a new project. Your job is to:
86
+ 1. **Analyze the codebase** - Understand what exists, patterns, tech stack
87
+ 2. **Create a detailed plan** - Break the goal into PRs, each PR into tasks
88
+ 3. **Save the plan** - Write to .claude-task-master/plan.md
89
+
90
+ #{claude_md_section}
91
+
92
+ ## Goal
93
+ #{goal}
94
+
95
+ ## Planning Instructions
96
+
97
+ ### Step 1: Explore the Codebase
98
+ - Read key files: README.md, CLAUDE.md, package.json/Gemfile/Cargo.toml/CMakeLists.txt
99
+ - Understand the project structure and directory layout
100
+ - Identify existing patterns, coding style, and conventions
101
+ - Note the tech stack, dependencies, and build system
102
+ - Check for existing CI/CD configuration (.github/workflows, etc.)
103
+
104
+ ### Step 2: Design the Plan
105
+ Create a plan structured as multiple PRs. Each PR should be:
106
+ - **Atomic**: A logical chunk of work that makes sense on its own
107
+ - **Reviewable**: Small enough for meaningful code review
108
+ - **Testable**: Includes tests or can be verified independently
109
+
110
+ Structure your plan like this:
111
+ ```markdown
112
+ # Plan for: [Goal Summary]
113
+
114
+ ## PR 1: [Title - e.g., "Project Foundation"]
115
+ - [ ] Task 1.1: Description
116
+ - [ ] Task 1.2: Description
117
+ ...
118
+
119
+ ## PR 2: [Title - e.g., "Core Implementation"]
120
+ - [ ] Task 2.1: Description
121
+ ...
122
+ ```
123
+
124
+ Guidelines:
125
+ - 3-10 PRs typically, depending on scope
126
+ - 3-15 tasks per PR
127
+ - First PR often includes: project setup, CI, basic structure
128
+ - Order tasks by dependency (what must be done first)
129
+ - Include test tasks where appropriate
130
+ - Include documentation where appropriate
131
+
132
+ ### Step 3: Write State Files
133
+ 1. Write plan to `.claude-task-master/plan.md`
134
+ 2. Update `.claude-task-master/state.json`:
135
+ - Set `status` to `"ready"`
136
+ - Set `current_task` to first task description
137
+ - Set `current_pr` to `1`
138
+ 3. Write context to `.claude-task-master/context.md`:
139
+ - Key files discovered
140
+ - Patterns to follow
141
+ - Decisions made
142
+
143
+ Be thorough but practical. Each PR should deliver value.
144
+ PROMPT
145
+ end
146
+
147
+ # Build the work prompt
148
+ def self.work_prompt(context, no_merge: false)
149
+ merge_instructions = if no_merge
150
+ <<~MERGE
151
+ **IMPORTANT: DO NOT MERGE PRs**
152
+ - Create PRs but do not merge them
153
+ - Wait for manual review and merge
154
+ - Once PR is ready (CI green, no unresolved comments), move to next PR
155
+ - Set `pr_ready` to `true` in state.json when ready for merge
156
+ MERGE
157
+ else
158
+ <<~MERGE
159
+ **Auto-merge is enabled**
160
+ - Once PR is approved (CI green, no unresolved comments), merge it:
161
+ `gh pr merge --squash --delete-branch`
162
+ - After merge, pull main and start next PR
163
+ MERGE
164
+ end
165
+
166
+ <<~PROMPT
167
+ # Claude Task Master - Work Session
168
+
169
+ You are an autonomous software engineer continuing work on a project.
170
+
171
+ ## Current State
172
+ #{context}
173
+
174
+ ## Work Loop Instructions
175
+
176
+ ### Step 1: Understand Current State
177
+ - Read `.claude-task-master/plan.md` to see all tasks
178
+ - Read `.claude-task-master/state.json` for current task and status
179
+ - Identify what needs to be done next
180
+
181
+ ### Step 2: Execute the Work
182
+
183
+ **If working on a task:**
184
+ 1. Implement the task (write code, create files)
185
+ 2. Run tests/linters if available
186
+ 3. Commit with a clear message
187
+ 4. Check off task in plan.md: `- [x] Task`
188
+ 5. Update state.json with next task
189
+ 6. Continue to next task in same PR
190
+
191
+ **If PR is ready (all tasks for this PR done):**
192
+ 1. Create the PR if not already created:
193
+ ```bash
194
+ gh pr create --title "PR Title" --body "Description
195
+
196
+ ---
197
+ Built with [claude-task-master](https://github.com/sebyx07/claude-task-master) + [Claude Code](https://claude.ai/code)"
198
+ ```
199
+ 2. Store PR number in state.json: `pr_number`
200
+
201
+ **If PR exists, check its status:**
202
+ 1. Check CI status:
203
+ ```bash
204
+ gh pr checks
205
+ ```
206
+ 2. Check for review comments (CodeRabbit, Copilot, human reviewers):
207
+ ```bash
208
+ gh pr view --json comments,reviews
209
+ gh api repos/{owner}/{repo}/pulls/{pr}/comments
210
+ ```
211
+ 3. **CRITICAL: Address ALL review comments before proceeding**
212
+ - Read each comment carefully
213
+ - Make the requested changes
214
+ - Commit and push: `git push`
215
+ - Wait for CI to pass again
216
+
217
+ **If CI fails:**
218
+ 1. Read the error output: `gh pr checks`
219
+ 2. Fix the issues
220
+ 3. Commit and push
221
+ 4. Repeat until green
222
+
223
+ **If review comments exist:**
224
+ 1. Address each comment
225
+ 2. Push fixes
226
+ 3. Comments from bots (CodeRabbit, Copilot) often auto-resolve
227
+ 4. Check again: `gh api repos/{owner}/{repo}/pulls/{pr}/comments`
228
+
229
+ #{merge_instructions}
230
+
231
+ ### Step 3: Track Progress
232
+
233
+ Always update state files after significant progress:
234
+
235
+ **plan.md:**
236
+ - Check off completed tasks: `- [x] Task done`
237
+ - Keep unchecked tasks: `- [ ] Task pending`
238
+
239
+ **state.json:**
240
+ ```json
241
+ {
242
+ "status": "working|ready|blocked|success",
243
+ "current_task": "Current task description",
244
+ "current_pr": 1,
245
+ "pr_number": 123,
246
+ "pr_ready": false,
247
+ "session_count": N,
248
+ "updated_at": "ISO timestamp"
249
+ }
250
+ ```
251
+
252
+ **progress.md:**
253
+ - Append notes about what was done
254
+ - Document any issues encountered
255
+ - Note decisions made
256
+
257
+ **context.md:**
258
+ - Add newly discovered patterns
259
+ - Document learnings about the codebase
260
+
261
+ ### Step 4: Handle Completion
262
+
263
+ **When current PR is complete (merged or ready):**
264
+ 1. Update state.json: increment `current_pr`
265
+ 2. Create new branch from main: `git checkout main && git pull && git checkout -b pr-N-description`
266
+ 3. Reset `pr_number` to null in state.json
267
+ 4. Continue with next PR's tasks
268
+
269
+ **When ALL PRs are done:**
270
+ 1. Set status to `"success"` in state.json
271
+ 2. Write completion summary to progress.md
272
+
273
+ **If stuck or blocked:**
274
+ 1. Set status to `"blocked"` in state.json
275
+ 2. Explain the blocker clearly in progress.md
276
+ 3. Do NOT retry the same failing approach repeatedly
277
+
278
+ ### Guidelines
279
+ - Work autonomously - make decisions
280
+ - Ship working code - don't over-engineer
281
+ - Follow existing patterns in the codebase
282
+ - Write tests where appropriate
283
+ - Keep commits focused and well-described
284
+ - Don't leave commented-out code
285
+ - Fix issues properly, don't hack around them
286
+ PROMPT
287
+ end
288
+
289
+ private
290
+
291
+ def build_args(allowed_tools)
292
+ args = [
293
+ '-p',
294
+ '--dangerously-skip-permissions',
295
+ '--model', model
296
+ ]
297
+
298
+ if allowed_tools
299
+ args += ['--allowedTools', allowed_tools.join(',')]
300
+ end
301
+
302
+ args
303
+ end
304
+ end
305
+ end