claude-task-master 0.1.1__py3-none-any.whl → 0.1.3__py3-none-any.whl

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 (42) hide show
  1. claude_task_master/__init__.py +1 -1
  2. claude_task_master/api/__init__.py +98 -0
  3. claude_task_master/api/models.py +553 -0
  4. claude_task_master/api/routes.py +1135 -0
  5. claude_task_master/api/routes_config.py +160 -0
  6. claude_task_master/api/routes_control.py +278 -0
  7. claude_task_master/api/routes_webhooks.py +980 -0
  8. claude_task_master/api/server.py +551 -0
  9. claude_task_master/auth/__init__.py +89 -0
  10. claude_task_master/auth/middleware.py +448 -0
  11. claude_task_master/auth/password.py +332 -0
  12. claude_task_master/bin/claudetm +1 -1
  13. claude_task_master/cli.py +4 -0
  14. claude_task_master/cli_commands/__init__.py +2 -0
  15. claude_task_master/cli_commands/ci_helpers.py +114 -0
  16. claude_task_master/cli_commands/control.py +191 -0
  17. claude_task_master/cli_commands/fix_pr.py +260 -0
  18. claude_task_master/cli_commands/fix_session.py +174 -0
  19. claude_task_master/cli_commands/workflow.py +51 -3
  20. claude_task_master/core/__init__.py +13 -0
  21. claude_task_master/core/agent_message.py +27 -5
  22. claude_task_master/core/control.py +466 -0
  23. claude_task_master/core/orchestrator.py +316 -4
  24. claude_task_master/core/pr_context.py +7 -2
  25. claude_task_master/core/prompts_working.py +32 -12
  26. claude_task_master/core/state.py +84 -2
  27. claude_task_master/core/state_exceptions.py +9 -6
  28. claude_task_master/core/workflow_stages.py +160 -21
  29. claude_task_master/github/client_pr.py +43 -1
  30. claude_task_master/mcp/auth.py +153 -0
  31. claude_task_master/mcp/server.py +268 -10
  32. claude_task_master/mcp/tools.py +281 -0
  33. claude_task_master/server.py +489 -0
  34. claude_task_master/webhooks/__init__.py +73 -0
  35. claude_task_master/webhooks/client.py +703 -0
  36. claude_task_master/webhooks/config.py +565 -0
  37. claude_task_master/webhooks/events.py +639 -0
  38. {claude_task_master-0.1.1.dist-info → claude_task_master-0.1.3.dist-info}/METADATA +144 -6
  39. {claude_task_master-0.1.1.dist-info → claude_task_master-0.1.3.dist-info}/RECORD +42 -21
  40. {claude_task_master-0.1.1.dist-info → claude_task_master-0.1.3.dist-info}/entry_points.txt +2 -0
  41. {claude_task_master-0.1.1.dist-info → claude_task_master-0.1.3.dist-info}/WHEEL +0 -0
  42. {claude_task_master-0.1.1.dist-info → claude_task_master-0.1.3.dist-info}/top_level.txt +0 -0
@@ -3,5 +3,5 @@
3
3
  Uses Claude Agent SDK to keep Claude working until a goal is achieved.
4
4
  """
5
5
 
6
- __version__ = "0.1.1"
6
+ __version__ = "0.1.3"
7
7
  __all__ = ["__version__"]
@@ -0,0 +1,98 @@
1
+ """REST API layer for Claude Task Master.
2
+
3
+ This module provides a FastAPI-based REST API that exposes claudetm functionality
4
+ as HTTP endpoints for remote task monitoring.
5
+
6
+ Currently Implemented Endpoints:
7
+ - GET /status: Get current task status
8
+ - GET /plan: Get task plan content
9
+ - GET /logs: Get log content
10
+ - GET /progress: Get progress summary
11
+ - GET /context: Get accumulated context/learnings
12
+ - GET /health: Health check endpoint
13
+
14
+ Usage:
15
+ # Import and create the app
16
+ from claude_task_master.api import create_app
17
+
18
+ app = create_app()
19
+
20
+ # Or run directly
21
+ from claude_task_master.api import run_server
22
+
23
+ run_server(host="0.0.0.0", port=8000)
24
+ """
25
+
26
+ # API components - imported as they are implemented
27
+ from claude_task_master.api.models import (
28
+ # Response models
29
+ APIInfo,
30
+ # Request models
31
+ ConfigUpdateRequest,
32
+ ContextResponse,
33
+ ControlResponse,
34
+ ErrorResponse,
35
+ HealthResponse,
36
+ # Enums
37
+ LogFormat,
38
+ LogLevel,
39
+ LogsResponse,
40
+ PauseRequest,
41
+ PlanResponse,
42
+ ProgressResponse,
43
+ ResumeRequest,
44
+ StopRequest,
45
+ TaskDeleteResponse,
46
+ TaskInitRequest,
47
+ TaskInitResponse,
48
+ TaskListItem,
49
+ TaskListResponse,
50
+ TaskOptionsResponse,
51
+ TaskProgressInfo,
52
+ TaskStatus,
53
+ TaskStatusResponse,
54
+ WorkflowStage,
55
+ )
56
+
57
+ # Routes
58
+ from claude_task_master.api.routes import create_info_router, register_routes
59
+
60
+ # Server components
61
+ from claude_task_master.api.server import create_app, get_app, run_server
62
+
63
+ __all__: list[str] = [
64
+ # Server
65
+ "create_app",
66
+ "run_server",
67
+ "get_app",
68
+ # Enums
69
+ "TaskStatus",
70
+ "WorkflowStage",
71
+ "LogLevel",
72
+ "LogFormat",
73
+ # Request models
74
+ "PauseRequest",
75
+ "StopRequest",
76
+ "ResumeRequest",
77
+ "ConfigUpdateRequest",
78
+ "TaskInitRequest",
79
+ # Response models
80
+ "TaskStatusResponse",
81
+ "TaskOptionsResponse",
82
+ "TaskProgressInfo",
83
+ "ControlResponse",
84
+ "PlanResponse",
85
+ "LogsResponse",
86
+ "ProgressResponse",
87
+ "ContextResponse",
88
+ "TaskListItem",
89
+ "TaskListResponse",
90
+ "HealthResponse",
91
+ "TaskInitResponse",
92
+ "TaskDeleteResponse",
93
+ "ErrorResponse",
94
+ "APIInfo",
95
+ # Routes
96
+ "create_info_router",
97
+ "register_routes",
98
+ ]
@@ -0,0 +1,553 @@
1
+ """Pydantic request/response models for the REST API.
2
+
3
+ This module defines all request and response models used by the FastAPI
4
+ REST API endpoints. Models are organized by operation type:
5
+
6
+ Request Models:
7
+ - PauseRequest: Pause a running task
8
+ - StopRequest: Stop a task with optional cleanup
9
+ - ResumeRequest: Resume a paused/blocked task
10
+ - ConfigUpdateRequest: Update task configuration
11
+ - TaskInitRequest: Initialize a new task
12
+
13
+ Response Models:
14
+ - TaskStatusResponse: Full task status information
15
+ - ControlResponse: Generic control operation response
16
+ - PlanResponse: Task plan content
17
+ - LogsResponse: Log content
18
+ - ProgressResponse: Progress summary
19
+ - ContextResponse: Accumulated context/learnings
20
+ - HealthResponse: Server health status
21
+ - ErrorResponse: Standard error response
22
+
23
+ Usage:
24
+ from claude_task_master.api.models import (
25
+ PauseRequest,
26
+ TaskStatusResponse,
27
+ ErrorResponse,
28
+ )
29
+
30
+ @app.post("/control/pause", response_model=ControlResponse)
31
+ async def pause_task(request: PauseRequest):
32
+ ...
33
+ """
34
+
35
+ from __future__ import annotations
36
+
37
+ from datetime import datetime
38
+ from enum import Enum
39
+ from typing import Any
40
+
41
+ from pydantic import BaseModel, Field
42
+
43
+ # =============================================================================
44
+ # Enums
45
+ # =============================================================================
46
+
47
+
48
+ class TaskStatus(str, Enum):
49
+ """Valid task status values."""
50
+
51
+ PLANNING = "planning"
52
+ WORKING = "working"
53
+ BLOCKED = "blocked"
54
+ PAUSED = "paused"
55
+ STOPPED = "stopped"
56
+ SUCCESS = "success"
57
+ FAILED = "failed"
58
+
59
+
60
+ class WorkflowStage(str, Enum):
61
+ """Valid workflow stage values for PR lifecycle."""
62
+
63
+ WORKING = "working"
64
+ PR_CREATED = "pr_created"
65
+ WAITING_CI = "waiting_ci"
66
+ CI_FAILED = "ci_failed"
67
+ WAITING_REVIEWS = "waiting_reviews"
68
+ ADDRESSING_REVIEWS = "addressing_reviews"
69
+ READY_TO_MERGE = "ready_to_merge"
70
+ MERGED = "merged"
71
+
72
+
73
+ class LogLevel(str, Enum):
74
+ """Valid log level values."""
75
+
76
+ QUIET = "quiet"
77
+ NORMAL = "normal"
78
+ VERBOSE = "verbose"
79
+
80
+
81
+ class LogFormat(str, Enum):
82
+ """Valid log format values."""
83
+
84
+ TEXT = "text"
85
+ JSON = "json"
86
+
87
+
88
+ # =============================================================================
89
+ # Request Models
90
+ # =============================================================================
91
+
92
+
93
+ class PauseRequest(BaseModel):
94
+ """Request model for pausing a task.
95
+
96
+ Attributes:
97
+ reason: Optional reason for pausing the task.
98
+ This will be recorded in the progress file.
99
+ """
100
+
101
+ reason: str | None = Field(
102
+ default=None,
103
+ description="Optional reason for pausing the task",
104
+ examples=["Manual pause for code review", "Waiting for dependency update"],
105
+ )
106
+
107
+
108
+ class StopRequest(BaseModel):
109
+ """Request model for stopping a task.
110
+
111
+ Attributes:
112
+ reason: Optional reason for stopping the task.
113
+ cleanup: If True, cleanup state files after stopping.
114
+ """
115
+
116
+ reason: str | None = Field(
117
+ default=None,
118
+ description="Optional reason for stopping the task",
119
+ examples=["Task cancelled by user", "Obsolete task - requirements changed"],
120
+ )
121
+ cleanup: bool = Field(
122
+ default=False,
123
+ description="If True, cleanup state files after stopping",
124
+ )
125
+
126
+
127
+ class ResumeRequest(BaseModel):
128
+ """Request model for resuming a paused or blocked task.
129
+
130
+ Attributes:
131
+ reason: Optional reason for resuming the task.
132
+ """
133
+
134
+ reason: str | None = Field(
135
+ default=None,
136
+ description="Optional reason for resuming the task",
137
+ )
138
+
139
+
140
+ class ConfigUpdateRequest(BaseModel):
141
+ """Request model for updating task configuration.
142
+
143
+ Only specified fields are updated; others retain their current values.
144
+ At least one field must be provided.
145
+
146
+ Attributes:
147
+ auto_merge: Whether to auto-merge PRs when approved.
148
+ max_sessions: Maximum number of work sessions before pausing.
149
+ pause_on_pr: Whether to pause after creating PR for manual review.
150
+ enable_checkpointing: Whether to enable state checkpointing.
151
+ log_level: Log level (quiet, normal, verbose).
152
+ log_format: Log format (text, json).
153
+ pr_per_task: Whether to create PR per task vs per group.
154
+ """
155
+
156
+ auto_merge: bool | None = Field(
157
+ default=None,
158
+ description="Whether to auto-merge PRs when approved",
159
+ )
160
+ max_sessions: int | None = Field(
161
+ default=None,
162
+ ge=1,
163
+ le=1000,
164
+ description="Maximum number of work sessions before pausing",
165
+ )
166
+ pause_on_pr: bool | None = Field(
167
+ default=None,
168
+ description="Whether to pause after creating PR for manual review",
169
+ )
170
+ enable_checkpointing: bool | None = Field(
171
+ default=None,
172
+ description="Whether to enable state checkpointing",
173
+ )
174
+ log_level: LogLevel | None = Field(
175
+ default=None,
176
+ description="Log level (quiet, normal, verbose)",
177
+ )
178
+ log_format: LogFormat | None = Field(
179
+ default=None,
180
+ description="Log format (text, json)",
181
+ )
182
+ pr_per_task: bool | None = Field(
183
+ default=None,
184
+ description="Whether to create PR per task vs per group",
185
+ )
186
+
187
+ def has_updates(self) -> bool:
188
+ """Check if any configuration updates were provided."""
189
+ return any(getattr(self, field) is not None for field in self.model_fields.keys())
190
+
191
+ def to_update_dict(self) -> dict[str, bool | int | str]:
192
+ """Convert to dictionary of non-None updates.
193
+
194
+ Returns:
195
+ Dictionary containing only the fields with non-None values,
196
+ with enum values converted to strings.
197
+ """
198
+ updates: dict[str, bool | int | str] = {}
199
+ for field_name in self.model_fields.keys():
200
+ value = getattr(self, field_name)
201
+ if value is not None:
202
+ # Convert enums to their string values
203
+ if isinstance(value, Enum):
204
+ updates[field_name] = value.value
205
+ else:
206
+ updates[field_name] = value
207
+ return updates
208
+
209
+
210
+ class TaskInitRequest(BaseModel):
211
+ """Request model for initializing a new task.
212
+
213
+ Attributes:
214
+ goal: The goal to achieve.
215
+ model: Model to use (opus, sonnet, haiku).
216
+ auto_merge: Whether to auto-merge PRs when approved.
217
+ max_sessions: Max work sessions before pausing.
218
+ pause_on_pr: Pause after creating PR for manual review.
219
+ """
220
+
221
+ goal: str = Field(
222
+ ...,
223
+ min_length=1,
224
+ max_length=10000,
225
+ description="The goal to achieve",
226
+ examples=["Fix the login form validation bug", "Add dark mode support"],
227
+ )
228
+ model: str = Field(
229
+ default="opus",
230
+ pattern="^(opus|sonnet|haiku)$",
231
+ description="Model to use (opus, sonnet, haiku)",
232
+ )
233
+ auto_merge: bool = Field(
234
+ default=True,
235
+ description="Whether to auto-merge PRs when approved",
236
+ )
237
+ max_sessions: int | None = Field(
238
+ default=None,
239
+ ge=1,
240
+ le=1000,
241
+ description="Maximum number of work sessions before pausing",
242
+ )
243
+ pause_on_pr: bool = Field(
244
+ default=False,
245
+ description="Pause after creating PR for manual review",
246
+ )
247
+
248
+
249
+ # =============================================================================
250
+ # Response Models - Nested Components
251
+ # =============================================================================
252
+
253
+
254
+ class TaskOptionsResponse(BaseModel):
255
+ """Task options in response models.
256
+
257
+ Attributes:
258
+ auto_merge: Whether to auto-merge PRs when approved.
259
+ max_sessions: Maximum number of work sessions before pausing.
260
+ pause_on_pr: Whether to pause after creating PR for manual review.
261
+ enable_checkpointing: Whether state checkpointing is enabled.
262
+ log_level: Current log level.
263
+ log_format: Current log format.
264
+ pr_per_task: Whether to create PR per task vs per group.
265
+ """
266
+
267
+ auto_merge: bool
268
+ max_sessions: int | None
269
+ pause_on_pr: bool
270
+ enable_checkpointing: bool
271
+ log_level: str
272
+ log_format: str
273
+ pr_per_task: bool
274
+
275
+
276
+ class TaskProgressInfo(BaseModel):
277
+ """Task progress information.
278
+
279
+ Attributes:
280
+ completed: Number of completed tasks.
281
+ total: Total number of tasks.
282
+ progress: Human-readable progress string (e.g., "3/10").
283
+ """
284
+
285
+ completed: int
286
+ total: int
287
+ progress: str = Field(examples=["3/10", "0/5", "No tasks"])
288
+
289
+
290
+ class WebhookStatusInfo(BaseModel):
291
+ """Webhook status summary information.
292
+
293
+ Attributes:
294
+ total: Total number of configured webhooks.
295
+ enabled: Number of enabled webhooks.
296
+ disabled: Number of disabled webhooks.
297
+ """
298
+
299
+ total: int = Field(description="Total number of configured webhooks")
300
+ enabled: int = Field(description="Number of enabled webhooks")
301
+ disabled: int = Field(description="Number of disabled webhooks")
302
+
303
+
304
+ # =============================================================================
305
+ # Response Models - Main Responses
306
+ # =============================================================================
307
+
308
+
309
+ class TaskStatusResponse(BaseModel):
310
+ """Response model for task status.
311
+
312
+ Provides comprehensive information about the current task state.
313
+
314
+ Attributes:
315
+ success: Whether the request succeeded.
316
+ goal: The task goal.
317
+ status: Current task status.
318
+ model: Model being used.
319
+ current_task_index: Index of the current task.
320
+ session_count: Number of work sessions completed.
321
+ run_id: Unique run identifier.
322
+ current_pr: Current PR number (if any).
323
+ workflow_stage: Current workflow stage (if any).
324
+ options: Current task options.
325
+ created_at: When the task was created.
326
+ updated_at: When the task was last updated.
327
+ tasks: Task progress information.
328
+ webhooks: Webhook configuration status summary.
329
+ """
330
+
331
+ success: bool = True
332
+ goal: str
333
+ status: TaskStatus
334
+ model: str
335
+ current_task_index: int
336
+ session_count: int
337
+ run_id: str
338
+ current_pr: int | None = None
339
+ workflow_stage: WorkflowStage | None = None
340
+ options: TaskOptionsResponse
341
+ created_at: datetime | str
342
+ updated_at: datetime | str
343
+ tasks: TaskProgressInfo | None = None
344
+ webhooks: WebhookStatusInfo | None = None
345
+
346
+
347
+ class ControlResponse(BaseModel):
348
+ """Generic response model for control operations (pause, stop, resume).
349
+
350
+ Attributes:
351
+ success: Whether the operation succeeded.
352
+ message: Human-readable description of the result.
353
+ operation: The operation that was performed.
354
+ previous_status: The status before the operation.
355
+ new_status: The status after the operation.
356
+ details: Additional operation-specific details.
357
+ """
358
+
359
+ success: bool
360
+ message: str
361
+ operation: str = Field(
362
+ examples=["pause", "stop", "resume", "update_config"],
363
+ )
364
+ previous_status: str | None = None
365
+ new_status: str | None = None
366
+ details: dict[str, Any] | None = None
367
+
368
+
369
+ class PlanResponse(BaseModel):
370
+ """Response model for task plan.
371
+
372
+ Attributes:
373
+ success: Whether the request succeeded.
374
+ plan: The plan content (markdown with checkboxes).
375
+ error: Error message if request failed.
376
+ """
377
+
378
+ success: bool
379
+ plan: str | None = None
380
+ error: str | None = None
381
+
382
+
383
+ class LogsResponse(BaseModel):
384
+ """Response model for log content.
385
+
386
+ Attributes:
387
+ success: Whether the request succeeded.
388
+ log_content: The log content (last N lines).
389
+ log_file: Path to the log file.
390
+ error: Error message if request failed.
391
+ """
392
+
393
+ success: bool
394
+ log_content: str | None = None
395
+ log_file: str | None = None
396
+ error: str | None = None
397
+
398
+
399
+ class ProgressResponse(BaseModel):
400
+ """Response model for progress summary.
401
+
402
+ Attributes:
403
+ success: Whether the request succeeded.
404
+ progress: The progress content (markdown).
405
+ message: Additional message (e.g., "No progress recorded").
406
+ error: Error message if request failed.
407
+ """
408
+
409
+ success: bool
410
+ progress: str | None = None
411
+ message: str | None = None
412
+ error: str | None = None
413
+
414
+
415
+ class ContextResponse(BaseModel):
416
+ """Response model for context/learnings.
417
+
418
+ Attributes:
419
+ success: Whether the request succeeded.
420
+ context: The context content.
421
+ error: Error message if request failed.
422
+ """
423
+
424
+ success: bool
425
+ context: str | None = None
426
+ error: str | None = None
427
+
428
+
429
+ class TaskListItem(BaseModel):
430
+ """Individual task item in task list.
431
+
432
+ Attributes:
433
+ task: Task description.
434
+ completed: Whether the task is completed.
435
+ """
436
+
437
+ task: str
438
+ completed: bool
439
+
440
+
441
+ class TaskListResponse(BaseModel):
442
+ """Response model for task list.
443
+
444
+ Attributes:
445
+ success: Whether the request succeeded.
446
+ tasks: List of tasks with completion status.
447
+ total: Total number of tasks.
448
+ completed: Number of completed tasks.
449
+ current_index: Index of the current task.
450
+ error: Error message if request failed.
451
+ """
452
+
453
+ success: bool
454
+ tasks: list[TaskListItem] | None = None
455
+ total: int = 0
456
+ completed: int = 0
457
+ current_index: int = 0
458
+ error: str | None = None
459
+
460
+
461
+ class HealthResponse(BaseModel):
462
+ """Response model for health check.
463
+
464
+ Attributes:
465
+ status: Health status ("healthy", "degraded", "unhealthy").
466
+ version: Server version string.
467
+ server_name: Name of the server.
468
+ uptime_seconds: Server uptime in seconds (if available).
469
+ active_tasks: Number of active tasks.
470
+ timestamp: Current server timestamp.
471
+ """
472
+
473
+ status: str = Field(examples=["healthy", "degraded", "unhealthy"])
474
+ version: str
475
+ server_name: str = "claude-task-master-api"
476
+ uptime_seconds: float | None = None
477
+ active_tasks: int = 0
478
+ timestamp: datetime = Field(default_factory=datetime.now)
479
+
480
+
481
+ class TaskInitResponse(BaseModel):
482
+ """Response model for task initialization.
483
+
484
+ Attributes:
485
+ success: Whether initialization succeeded.
486
+ message: Human-readable result message.
487
+ run_id: The run ID of the new task.
488
+ status: Initial task status.
489
+ error: Error message if initialization failed.
490
+ """
491
+
492
+ success: bool
493
+ message: str
494
+ run_id: str | None = None
495
+ status: str | None = None
496
+ error: str | None = None
497
+
498
+
499
+ class TaskDeleteResponse(BaseModel):
500
+ """Response model for task deletion/cleanup.
501
+
502
+ Attributes:
503
+ success: Whether cleanup succeeded.
504
+ message: Human-readable result message.
505
+ files_removed: Whether files were actually removed.
506
+ error: Error message if cleanup failed.
507
+ """
508
+
509
+ success: bool
510
+ message: str
511
+ files_removed: bool = False
512
+ error: str | None = None
513
+
514
+
515
+ class ErrorResponse(BaseModel):
516
+ """Standard error response model.
517
+
518
+ Used for all error responses across the API.
519
+
520
+ Attributes:
521
+ success: Always False for error responses.
522
+ error: Error type/code.
523
+ message: Human-readable error message.
524
+ detail: Additional error details (optional).
525
+ suggestion: Suggested action to resolve the error.
526
+ """
527
+
528
+ success: bool = False
529
+ error: str
530
+ message: str
531
+ detail: str | None = None
532
+ suggestion: str | None = None
533
+
534
+
535
+ # =============================================================================
536
+ # API Metadata Models
537
+ # =============================================================================
538
+
539
+
540
+ class APIInfo(BaseModel):
541
+ """API information for documentation.
542
+
543
+ Attributes:
544
+ name: API name.
545
+ version: API version.
546
+ description: API description.
547
+ docs_url: URL to API documentation (None if docs disabled).
548
+ """
549
+
550
+ name: str = "Claude Task Master API"
551
+ version: str
552
+ description: str = "REST API for Claude Task Master task orchestration"
553
+ docs_url: str | None = "/docs"