mirror of
https://github.com/eyaltoledano/claude-task-master.git
synced 2026-01-30 06:12:05 +00:00
feat: add hamster rules to taskmaster rules command (#1454)
This commit is contained in:
5
.changeset/spotty-peaches-hug.md
Normal file
5
.changeset/spotty-peaches-hug.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"task-master-ai": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Add Hamster rules to task-master rules
|
||||||
329
assets/rules/goham.md
Normal file
329
assets/rules/goham.md
Normal file
@@ -0,0 +1,329 @@
|
|||||||
|
# Start Working with Hamster Brief
|
||||||
|
|
||||||
|
End-to-end workflow for working on tasks from a connected Hamster brief. All tasks from the brief are worked on in a single branch, with one PR created at the end.
|
||||||
|
|
||||||
|
## Step 1: Verify Connection & Authentication
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check current context and authentication status
|
||||||
|
tm context
|
||||||
|
```
|
||||||
|
|
||||||
|
If not connected or authentication fails:
|
||||||
|
- Get brief URL from user if not available
|
||||||
|
- Connect: `tm context <brief url>`
|
||||||
|
- Refresh token if needed: `tm auth refresh`
|
||||||
|
|
||||||
|
## Step 2: List Available Tasks
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# View all tasks from the brief
|
||||||
|
tm list
|
||||||
|
```
|
||||||
|
|
||||||
|
Review the task list to understand what needs to be done. Note the total number of tasks.
|
||||||
|
|
||||||
|
## Step 3: Initialize Git Branch for Brief
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ensure you're on dev branch and pull latest
|
||||||
|
git checkout dev
|
||||||
|
git pull origin dev
|
||||||
|
|
||||||
|
# Create a single branch for the entire brief (e.g., hamster-brief-YYYY-MM-DD or brief-specific name)
|
||||||
|
git checkout -b hamster-brief
|
||||||
|
|
||||||
|
# Verify branch creation
|
||||||
|
git branch
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note**: This branch will be used for ALL tasks in the brief. Do not create separate branches per task.
|
||||||
|
|
||||||
|
## Step 4: Task Loop (Repeat for Each Task)
|
||||||
|
|
||||||
|
Work through all tasks sequentially in the same branch:
|
||||||
|
|
||||||
|
### 4.1: Read Task Details
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Get detailed information about the task
|
||||||
|
tm show 1
|
||||||
|
|
||||||
|
# If task has subtasks, examine them all
|
||||||
|
tm show 1,1.1,1.2,1.3 # Adjust IDs as needed
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2: Log Initial Context
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Document task understanding and initial findings
|
||||||
|
tm update-task -i 1 --append --prompt="Starting task implementation.
|
||||||
|
|
||||||
|
Initial context:
|
||||||
|
- Task requirements: [summarize key requirements]
|
||||||
|
- Dependencies identified: [list any dependencies]
|
||||||
|
- Files that may need modification: [list relevant files]
|
||||||
|
- Approach planned: [brief implementation approach]"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3: Mark Task as In-Progress
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Mark task and first subtask (if exists) as in-progress
|
||||||
|
tm set-status -i 1,1.1 -s in-progress
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.4: Subtask Implementation Loop
|
||||||
|
|
||||||
|
For each subtask (1.1, 1.2, 1.3, etc.):
|
||||||
|
|
||||||
|
#### 4.4.1: Read Subtask Details
|
||||||
|
```bash
|
||||||
|
tm show 1.1 # Replace with current subtask ID
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4.4.2: Log Research & Context Gathering
|
||||||
|
```bash
|
||||||
|
# Document findings during implementation
|
||||||
|
tm update-task -i 1 --append --prompt="Subtask 1.1 - Context gathered:
|
||||||
|
|
||||||
|
- Code exploration findings: [what you discovered]
|
||||||
|
- Implementation approach: [how you plan to implement]
|
||||||
|
- Key decisions made: [important choices]
|
||||||
|
- Challenges encountered: [any blockers or issues]"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4.4.3: Implement Subtask
|
||||||
|
- Write code following the subtask requirements
|
||||||
|
- Make necessary changes to files
|
||||||
|
|
||||||
|
#### 4.4.4: Quality Verification
|
||||||
|
```bash
|
||||||
|
# Run linting
|
||||||
|
pnpm lint
|
||||||
|
|
||||||
|
# Run type checking
|
||||||
|
pnpm typecheck
|
||||||
|
|
||||||
|
# If either fails, fix issues and re-run until both pass
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4.4.5: CodeRabbit Review
|
||||||
|
```bash
|
||||||
|
# Generate code review (wait for plain text results)
|
||||||
|
coderabbit --prompt-only
|
||||||
|
|
||||||
|
# Review the output and address any critical issues if needed
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4.4.6: Log Implementation Completion
|
||||||
|
```bash
|
||||||
|
# Document what was completed
|
||||||
|
tm update-task -i 1 --append --prompt="Subtask 1.1 - Implementation complete:
|
||||||
|
|
||||||
|
- Files modified: [list files changed]
|
||||||
|
- Key changes: [summary of implementation]
|
||||||
|
- CodeRabbit feedback addressed: [if any issues were fixed]
|
||||||
|
- Ready for commit"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4.4.7: Commit Subtask Work
|
||||||
|
```bash
|
||||||
|
# Stage changes
|
||||||
|
git add .
|
||||||
|
|
||||||
|
# Commit with detailed message following git_workflow.mdc format
|
||||||
|
git commit -m "feat(task-1): Complete subtask 1.1 - [Subtask Title]
|
||||||
|
|
||||||
|
- Implementation details
|
||||||
|
- Key changes made
|
||||||
|
- Files modified: [list files]
|
||||||
|
- CodeRabbit review completed
|
||||||
|
|
||||||
|
Subtask 1.1: [Brief description of what was accomplished]
|
||||||
|
Relates to Task 1: [Main task title]"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4.4.8: Mark Subtask as Done
|
||||||
|
```bash
|
||||||
|
tm set-status -i 1.1 -s done
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4.4.9: Move to Next Subtask
|
||||||
|
Repeat steps 4.4.1 through 4.4.8 for the next subtask (1.2, 1.3, etc.)
|
||||||
|
|
||||||
|
### 4.5: Complete Parent Task
|
||||||
|
|
||||||
|
After all subtasks are complete:
|
||||||
|
|
||||||
|
#### 4.5.1: Final Quality Checks
|
||||||
|
```bash
|
||||||
|
# Final linting
|
||||||
|
pnpm lint
|
||||||
|
|
||||||
|
# Final type checking
|
||||||
|
pnpm typecheck
|
||||||
|
|
||||||
|
# Final CodeRabbit review
|
||||||
|
coderabbit --prompt-only
|
||||||
|
|
||||||
|
# Address any remaining issues if critical
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4.5.2: Log Task Completion
|
||||||
|
```bash
|
||||||
|
# Document final task completion
|
||||||
|
tm update-task -i 1 --append --prompt="Task 1 - Complete:
|
||||||
|
|
||||||
|
- All subtasks completed: [list all subtasks]
|
||||||
|
- Final verification passed: lint, typecheck, CodeRabbit review
|
||||||
|
- Files changed: [comprehensive list]
|
||||||
|
- Committed to brief branch"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4.5.3: Mark Parent Task as Done
|
||||||
|
```bash
|
||||||
|
tm set-status -i 1 -s done
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note**: Do NOT push or create PR yet. Continue to next task in the same branch.
|
||||||
|
|
||||||
|
### 4.6: Move to Next Task
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Verify remaining tasks
|
||||||
|
tm list
|
||||||
|
|
||||||
|
# Continue with next task (e.g., Task 2)
|
||||||
|
# Repeat steps 4.1 through 4.5 for Task 2, then Task 3, etc.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 5: Complete All Tasks
|
||||||
|
|
||||||
|
Continue working through all tasks (Steps 4.1-4.6) until all tasks in the brief are complete. All work is committed to the same `hamster-brief` branch.
|
||||||
|
|
||||||
|
## Step 6: Final Verification & PR Creation
|
||||||
|
|
||||||
|
After ALL tasks are complete:
|
||||||
|
|
||||||
|
### 6.1: Verify All Tasks Complete
|
||||||
|
```bash
|
||||||
|
# Verify all tasks are done
|
||||||
|
tm list
|
||||||
|
|
||||||
|
# Should show all tasks with status 'done'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2: Final Quality Checks
|
||||||
|
```bash
|
||||||
|
# Final comprehensive checks
|
||||||
|
pnpm lint
|
||||||
|
pnpm typecheck
|
||||||
|
coderabbit --prompt-only
|
||||||
|
|
||||||
|
# Address any remaining issues if critical
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.3: Push Branch
|
||||||
|
```bash
|
||||||
|
# Push the brief branch to remote
|
||||||
|
git push origin hamster-brief
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.4: Create Pull Request to Dev
|
||||||
|
```bash
|
||||||
|
# Get all task titles (adjust task IDs as needed)
|
||||||
|
# Create comprehensive PR description
|
||||||
|
|
||||||
|
gh pr create \
|
||||||
|
--base dev \
|
||||||
|
--title "Hamster Brief: Complete Implementation" \
|
||||||
|
--body "## Brief Overview
|
||||||
|
Completed all tasks from Hamster brief.
|
||||||
|
|
||||||
|
## Tasks Completed
|
||||||
|
- [x] Task 1: [Task 1 title]
|
||||||
|
- Subtasks: 1.1, 1.2, 1.3
|
||||||
|
- [x] Task 2: [Task 2 title]
|
||||||
|
- Subtasks: 2.1, 2.2
|
||||||
|
- [x] Task 3: [Task 3 title]
|
||||||
|
- [Continue listing all tasks]
|
||||||
|
|
||||||
|
## Implementation Summary
|
||||||
|
- Total tasks: [number]
|
||||||
|
- Total subtasks: [number]
|
||||||
|
- Files modified: [comprehensive list]
|
||||||
|
- All quality checks passed
|
||||||
|
|
||||||
|
## Quality Checks
|
||||||
|
- ✅ Linting passed (pnpm lint)
|
||||||
|
- ✅ Type checking passed (pnpm typecheck)
|
||||||
|
- ✅ CodeRabbit review completed for all changes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
- [ ] Manual testing completed
|
||||||
|
- [ ] All checks passing
|
||||||
|
|
||||||
|
Complete implementation of Hamster brief tasks"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 7: Cleanup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# After PR is merged, switch back to dev
|
||||||
|
git checkout dev
|
||||||
|
git pull origin dev
|
||||||
|
|
||||||
|
# Delete local branch (optional)
|
||||||
|
git branch -d hamster-brief
|
||||||
|
```
|
||||||
|
|
||||||
|
## Important Notes
|
||||||
|
|
||||||
|
- **Use ONLY**: `tm list`, `tm show <id>`, `tm set-status`, `tm update-task`, `tm auth refresh`, `tm context <brief url>`
|
||||||
|
- **DON'T use MCP tools** - not compatible with Hamster integration
|
||||||
|
- **Single branch per brief**: All tasks work in the same branch (`hamster-brief`)
|
||||||
|
- **Single PR per brief**: One PR created after all tasks are complete
|
||||||
|
- **Always target dev branch** - never main branch
|
||||||
|
- **Regular logging**: Use `tm update-task -i <id> --append` frequently to document:
|
||||||
|
- Context gathered during exploration
|
||||||
|
- Implementation decisions made
|
||||||
|
- Challenges encountered
|
||||||
|
- Completion status
|
||||||
|
- **Quality gates**: Never skip lint, typecheck, or CodeRabbit review
|
||||||
|
- **Commit format**: Follow git_workflow.mdc commit message standards
|
||||||
|
- **PR format**: Always use `--base dev` when creating PRs
|
||||||
|
|
||||||
|
## Workflow Summary
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Verify connection → tm context
|
||||||
|
2. List tasks → tm list
|
||||||
|
3. Create single branch → git checkout -b hamster-brief
|
||||||
|
4. For each task (in same branch):
|
||||||
|
a. Read task → tm show X
|
||||||
|
b. Log context → tm update-task -i X --append
|
||||||
|
c. Mark in-progress → tm set-status -i X,X.Y -s in-progress
|
||||||
|
d. For each subtask:
|
||||||
|
- Read → tm show X.Y
|
||||||
|
- Log context → tm update-task -i X --append
|
||||||
|
- Implement code
|
||||||
|
- Verify → pnpm lint && pnpm typecheck
|
||||||
|
- Review → coderabbit --prompt-only
|
||||||
|
- Log completion → tm update-task -i X --append
|
||||||
|
- Commit → git commit (following git_workflow.mdc format)
|
||||||
|
- Mark done → tm set-status -i X.Y -s done
|
||||||
|
e. Final checks → pnpm lint && pnpm typecheck && coderabbit --prompt-only
|
||||||
|
f. Log completion → tm update-task -i X --append
|
||||||
|
g. Mark task done → tm set-status -i X -s done
|
||||||
|
h. Continue to next task (same branch)
|
||||||
|
5. After ALL tasks complete:
|
||||||
|
a. Final verification → pnpm lint && pnpm typecheck && coderabbit --prompt-only
|
||||||
|
b. Push branch → git push origin hamster-brief
|
||||||
|
c. Create PR → gh pr create --base dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- Full guidelines: [hamster.mdc](mdc:.cursor/rules/hamster.mdc)
|
||||||
|
- Git workflow: [git_workflow.mdc](mdc:.cursor/rules/git_workflow.mdc)
|
||||||
173
assets/rules/hamster.mdc
Normal file
173
assets/rules/hamster.mdc
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
---
|
||||||
|
description: Guidelines for implementing tasks imported from Hamster using Task Master CLI
|
||||||
|
globs: "**/*"
|
||||||
|
alwaysApply: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Hamster Integration Workflow
|
||||||
|
|
||||||
|
This guide outlines the process for working with tasks imported from Hamster briefs using Task Master. When connected to a Hamster brief, follow these specific guidelines to ensure proper task management and workflow execution.
|
||||||
|
|
||||||
|
## **Command Restrictions**
|
||||||
|
|
||||||
|
### **Supported Commands**
|
||||||
|
- **✅ DO**: Use only these Task Master CLI commands when working with Hamster briefs:
|
||||||
|
```bash
|
||||||
|
tm list # List all tasks
|
||||||
|
tm show <sub/task id> --json # Show task details
|
||||||
|
tm set-status # Update task status
|
||||||
|
tm auth refresh # Refresh authentication token
|
||||||
|
tm context <brief url> # Reconnect to Hamster brief context
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Unsupported Commands**
|
||||||
|
- **❌ DON'T**: Use MCP tools when connected with Hamster briefs - they are not yet up to date with Hamster integration
|
||||||
|
- **❌ DON'T**: Use other Task Master CLI commands that haven't been verified to work with Hamster integration
|
||||||
|
|
||||||
|
## **Task Workflow Process**
|
||||||
|
|
||||||
|
### **Starting a Task**
|
||||||
|
```bash
|
||||||
|
# ✅ DO: Mark task and subtasks as in-progress when starting
|
||||||
|
tm set-status -i 1,1.1 -s in-progress
|
||||||
|
|
||||||
|
# Multiple tasks/subtasks can be marked at once using comma separation
|
||||||
|
tm set-status -i 1,1.1,1.2,2 -s in-progress
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Task Implementation Flow**
|
||||||
|
1. **Read the Task**: Use `tm show <id> --json` to understand the task requirements (json used to save tokens, gets you same information)
|
||||||
|
2. **Check for Subtasks**: If the task has subtasks, implement them one at a time
|
||||||
|
3. **Implement Subtask**: Complete the subtask implementation
|
||||||
|
4. **Verify Quality**: Run lint and typecheck before marking as done
|
||||||
|
```bash
|
||||||
|
npm lint
|
||||||
|
npm typecheck
|
||||||
|
```
|
||||||
|
5. **Mark Complete**: If verification passes, mark the subtask as done
|
||||||
|
```bash
|
||||||
|
tm set-status -i 1.1 -s done
|
||||||
|
```
|
||||||
|
6. **Commit Changes**: Commit the completed subtask work
|
||||||
|
7. **Repeat**: Continue until all subtasks are complete
|
||||||
|
|
||||||
|
### **Parent Task Completion**
|
||||||
|
- After all subtasks are done, run final verification:
|
||||||
|
```bash
|
||||||
|
npm lint
|
||||||
|
npm typecheck
|
||||||
|
```
|
||||||
|
- Mark the parent task as done:
|
||||||
|
```bash
|
||||||
|
tm set-status -i 1 -s done
|
||||||
|
```
|
||||||
|
- Move to the next task and repeat the process
|
||||||
|
|
||||||
|
## **Multiple Task Context**
|
||||||
|
|
||||||
|
### **Viewing Multiple Tasks**
|
||||||
|
```bash
|
||||||
|
# ✅ DO: Use comma-separated IDs to get context from multiple tasks
|
||||||
|
tm show 1,1.1,2,2.1 --json
|
||||||
|
|
||||||
|
# This is more efficient than calling tm show multiple times
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Parallel Subtask Execution**
|
||||||
|
- **When to Parallelize**: If a task has subtasks that can be completed in parallel
|
||||||
|
- **Requirements**:
|
||||||
|
- Ensure work/files to adjust are **not the same** across subtasks
|
||||||
|
- Spawn sub-agents for each parallel subtask
|
||||||
|
- Verify clear separation of work before parallelizing
|
||||||
|
- **Example**: If subtask 1.1 modifies `src/api.js` and subtask 1.2 modifies `src/utils.js`, these can run in parallel
|
||||||
|
|
||||||
|
## **Pull Request Management**
|
||||||
|
|
||||||
|
### **PR Creation Strategy**
|
||||||
|
- **Preferred Approach**: Keep everything in one PR if scope remains manageable
|
||||||
|
- **When to Split**: Create separate PRs if the work becomes too large
|
||||||
|
- **Multi-PR Strategy**: If splitting is necessary:
|
||||||
|
- Create PRs that build on top of previous ones
|
||||||
|
- **Always confirm with the human** before creating multiple PRs
|
||||||
|
- **PR Creation**: Use GitHub CLI after completing a task:
|
||||||
|
```bash
|
||||||
|
gh pr create --title "Task X: [Task Title]" --body "Description"
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Committing to PRs**
|
||||||
|
- Keep committing to the same PR as long as the scope is maintained
|
||||||
|
- An entire task list (brief) might fit into a single PR
|
||||||
|
- If scope grows too large, discuss with human before creating new PRs
|
||||||
|
|
||||||
|
## **Authentication & Context Management**
|
||||||
|
|
||||||
|
### **Token Refresh**
|
||||||
|
```bash
|
||||||
|
# ✅ DO: Refresh token if JWT seems expired or commands don't work
|
||||||
|
tm auth refresh
|
||||||
|
|
||||||
|
# If refresh doesn't work, reconnect context
|
||||||
|
tm context <brief url>
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Context Reconnection**
|
||||||
|
- **When Needed**: If commands stop working or authentication fails
|
||||||
|
- **Required Information**: Brief URL (ask user if not available)
|
||||||
|
- **Best Practice**: Store brief URL at the beginning of the session
|
||||||
|
- **Command**: `tm context <brief url>`
|
||||||
|
|
||||||
|
## **Integration with Git Workflow**
|
||||||
|
|
||||||
|
When working with Hamster briefs, follow the standard Git workflow patterns outlined in [git_workflow.mdc](mdc:.cursor/rules/git_workflow.mdc):
|
||||||
|
|
||||||
|
- Create task-specific branches: `task-XXX`
|
||||||
|
- Commit subtask work incrementally
|
||||||
|
- Create PRs after task completion
|
||||||
|
- Follow commit message standards
|
||||||
|
|
||||||
|
## **Workflow Summary**
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
A[Start: Connect to Hamster Brief] --> B[Get Brief URL]
|
||||||
|
B --> C[tm list - View Tasks]
|
||||||
|
C --> D[Select Task]
|
||||||
|
D --> E[tm show <id> --json - Read Task]
|
||||||
|
E --> F{Has Subtasks?}
|
||||||
|
F -->|Yes| G[Select First Subtask]
|
||||||
|
F -->|No| M[Implement Task]
|
||||||
|
G --> H[tm set-status -i X.Y -s in-progress]
|
||||||
|
H --> I[Implement Subtask]
|
||||||
|
I --> J[npm lint && npm typecheck]
|
||||||
|
J --> K{Passes?}
|
||||||
|
K -->|Yes| L[tm set-status -i X.Y -s done]
|
||||||
|
K -->|No| I
|
||||||
|
L --> N{More Subtasks?}
|
||||||
|
N -->|Yes| G
|
||||||
|
N -->|No| O[Final lint/typecheck]
|
||||||
|
M --> O
|
||||||
|
O --> P[tm set-status -i X -s done]
|
||||||
|
P --> Q[Commit & Create PR]
|
||||||
|
Q --> R{More Tasks?}
|
||||||
|
R -->|Yes| D
|
||||||
|
R -->|No| S[Complete]
|
||||||
|
|
||||||
|
style A fill:#e1f5fe
|
||||||
|
style H fill:#fff3e0
|
||||||
|
style L fill:#e8f5e8
|
||||||
|
style Q fill:#fce4ec
|
||||||
|
```
|
||||||
|
|
||||||
|
## **Key Principles**
|
||||||
|
|
||||||
|
- **Incremental Progress**: Work through subtasks one at a time
|
||||||
|
- **Quality Gates**: Always run lint and typecheck before marking tasks as done
|
||||||
|
- **Clear Communication**: Confirm with human before splitting work across multiple PRs
|
||||||
|
- **Efficient Context Gathering**: Use comma-separated IDs when viewing multiple tasks
|
||||||
|
- **Authentication Management**: Proactively refresh tokens and reconnect context when needed
|
||||||
|
|
||||||
|
## **Related Rules**
|
||||||
|
|
||||||
|
- [Git Workflow](mdc:.cursor/rules/git_workflow.mdc) - Standard Git branching and PR practices
|
||||||
|
- [Development Workflow](mdc:.cursor/rules/dev_workflow.mdc) - General Task Master development patterns
|
||||||
|
- [Task Management](mdc:.cursor/rules/tasks.mdc) - Task structure and operations
|
||||||
@@ -57,7 +57,9 @@ export function createProfile(editorConfig) {
|
|||||||
'rules/cursor_rules.mdc': `${name.toLowerCase()}_rules${targetExtension}`,
|
'rules/cursor_rules.mdc': `${name.toLowerCase()}_rules${targetExtension}`,
|
||||||
'rules/dev_workflow.mdc': `${taskmasterPrefix}dev_workflow${targetExtension}`,
|
'rules/dev_workflow.mdc': `${taskmasterPrefix}dev_workflow${targetExtension}`,
|
||||||
'rules/self_improve.mdc': `self_improve${targetExtension}`,
|
'rules/self_improve.mdc': `self_improve${targetExtension}`,
|
||||||
'rules/taskmaster.mdc': `${taskmasterPrefix}taskmaster${targetExtension}`
|
'rules/taskmaster.mdc': `${taskmasterPrefix}taskmaster${targetExtension}`,
|
||||||
|
'rules/hamster.mdc': `${taskmasterPrefix}hamster${targetExtension}`,
|
||||||
|
'rules/goham.md': `${taskmasterPrefix}goham${targetExtension}`
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build final fileMap - merge defaults with custom entries when includeDefaultRules is true
|
// Build final fileMap - merge defaults with custom entries when includeDefaultRules is true
|
||||||
|
|||||||
147
tests/integration/profiles/hamster-rules-distribution.test.js
Normal file
147
tests/integration/profiles/hamster-rules-distribution.test.js
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import os from 'os';
|
||||||
|
import { execSync } from 'child_process';
|
||||||
|
import { RULE_PROFILES } from '../../../src/constants/profiles.js';
|
||||||
|
import * as profilesModule from '../../../src/profiles/index.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration tests for hamster rules distribution across all profiles.
|
||||||
|
*
|
||||||
|
* These tests verify that hamster.mdc and goham.md are correctly distributed
|
||||||
|
* to all profiles that include default rules when running `rules add`.
|
||||||
|
*/
|
||||||
|
describe('Hamster Rules Distribution', () => {
|
||||||
|
const CLI_PATH = path.join(process.cwd(), 'dist', 'task-master.js');
|
||||||
|
|
||||||
|
// Profiles that have includeDefaultRules: false and won't get hamster files via defaultFileMap
|
||||||
|
const PROFILES_WITHOUT_DEFAULT_RULES = [
|
||||||
|
'claude',
|
||||||
|
'gemini',
|
||||||
|
'codex',
|
||||||
|
'amp',
|
||||||
|
'opencode',
|
||||||
|
'zed'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Profiles that should receive hamster rules
|
||||||
|
const PROFILES_WITH_DEFAULT_RULES = RULE_PROFILES.filter(
|
||||||
|
(p) => !PROFILES_WITHOUT_DEFAULT_RULES.includes(p)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get expected hamster file paths by reading from the actual profile object
|
||||||
|
const getExpectedHamsterPaths = (profileName, tempDir) => {
|
||||||
|
const profile = profilesModule[`${profileName}Profile`];
|
||||||
|
if (!profile || !profile.fileMap) return null;
|
||||||
|
|
||||||
|
const rulesDir = profile.rulesDir;
|
||||||
|
const hamsterTarget = profile.fileMap['rules/hamster.mdc'];
|
||||||
|
const gohamTarget = profile.fileMap['rules/goham.md'];
|
||||||
|
|
||||||
|
if (!hamsterTarget || !gohamTarget) return null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
hamster: path.join(tempDir, rulesDir, hamsterTarget),
|
||||||
|
goham: path.join(tempDir, rulesDir, gohamTarget)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('Source files exist', () => {
|
||||||
|
test('hamster.mdc exists in assets/rules', () => {
|
||||||
|
const hamsterPath = path.join(
|
||||||
|
process.cwd(),
|
||||||
|
'assets',
|
||||||
|
'rules',
|
||||||
|
'hamster.mdc'
|
||||||
|
);
|
||||||
|
expect(fs.existsSync(hamsterPath)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('goham.md exists in assets/rules', () => {
|
||||||
|
const gohamPath = path.join(process.cwd(), 'assets', 'rules', 'goham.md');
|
||||||
|
expect(fs.existsSync(gohamPath)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('hamster.mdc has correct frontmatter', () => {
|
||||||
|
const hamsterPath = path.join(
|
||||||
|
process.cwd(),
|
||||||
|
'assets',
|
||||||
|
'rules',
|
||||||
|
'hamster.mdc'
|
||||||
|
);
|
||||||
|
const content = fs.readFileSync(hamsterPath, 'utf8');
|
||||||
|
expect(content).toContain('---');
|
||||||
|
expect(content).toContain('description:');
|
||||||
|
expect(content).toContain('globs:');
|
||||||
|
expect(content).toContain('alwaysApply:');
|
||||||
|
expect(content).toContain('Hamster Integration Workflow');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Rules add command distributes hamster files', () => {
|
||||||
|
// Test each profile that should receive hamster rules
|
||||||
|
PROFILES_WITH_DEFAULT_RULES.forEach((profile) => {
|
||||||
|
test(`${profile} profile receives hamster rules via 'rules add'`, () => {
|
||||||
|
// Create a unique temp directory for this test
|
||||||
|
const tempDir = fs.mkdtempSync(
|
||||||
|
path.join(os.tmpdir(), `tm-hamster-test-${profile}-`)
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Run the rules add command
|
||||||
|
execSync(`node ${CLI_PATH} rules add ${profile}`, {
|
||||||
|
cwd: tempDir,
|
||||||
|
stdio: 'pipe',
|
||||||
|
env: { ...process.env, TASKMASTER_LOG_LEVEL: 'error' }
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get expected paths for this profile
|
||||||
|
const expectedPaths = getExpectedHamsterPaths(profile, tempDir);
|
||||||
|
|
||||||
|
if (expectedPaths) {
|
||||||
|
// Verify hamster.* file exists
|
||||||
|
expect(fs.existsSync(expectedPaths.hamster)).toBe(true);
|
||||||
|
|
||||||
|
// Verify goham.* file exists
|
||||||
|
expect(fs.existsSync(expectedPaths.goham)).toBe(true);
|
||||||
|
|
||||||
|
// Verify hamster file contains expected content
|
||||||
|
const hamsterContent = fs.readFileSync(
|
||||||
|
expectedPaths.hamster,
|
||||||
|
'utf8'
|
||||||
|
);
|
||||||
|
expect(hamsterContent).toContain('Hamster Integration Workflow');
|
||||||
|
expect(hamsterContent).toContain('tm list');
|
||||||
|
expect(hamsterContent).toContain('tm set-status');
|
||||||
|
|
||||||
|
// Verify goham file contains expected content
|
||||||
|
const gohamContent = fs.readFileSync(expectedPaths.goham, 'utf8');
|
||||||
|
expect(gohamContent).toContain('Start Working with Hamster Brief');
|
||||||
|
expect(gohamContent).toContain('tm context');
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
// Cleanup temp directory
|
||||||
|
fs.rmSync(tempDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Profiles without default rules', () => {
|
||||||
|
// These profiles use different mechanisms (CLAUDE.md, AGENTS.md, etc.)
|
||||||
|
// and don't include the defaultFileMap rules
|
||||||
|
PROFILES_WITHOUT_DEFAULT_RULES.forEach((profile) => {
|
||||||
|
test(`${profile} profile does not use defaultFileMap (has custom mechanism)`, async () => {
|
||||||
|
// Dynamically import the profile to check its configuration
|
||||||
|
const profileModule = await import(
|
||||||
|
`../../../src/profiles/${profile}.js`
|
||||||
|
);
|
||||||
|
const profileExport = profileModule[`${profile}Profile`];
|
||||||
|
|
||||||
|
// These profiles should have includeDefaultRules: false
|
||||||
|
// which means they won't automatically get hamster files via defaultFileMap
|
||||||
|
expect(profileExport.includeDefaultRules).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -219,7 +219,9 @@ Use the .mdc extension for all rule files.`;
|
|||||||
'rules/dev_workflow.mdc': 'dev_workflow.md',
|
'rules/dev_workflow.mdc': 'dev_workflow.md',
|
||||||
'rules/self_improve.mdc': 'self_improve.md',
|
'rules/self_improve.mdc': 'self_improve.md',
|
||||||
'rules/taskmaster.mdc': 'taskmaster.md',
|
'rules/taskmaster.mdc': 'taskmaster.md',
|
||||||
'rules/taskmaster_hooks_workflow.mdc': 'taskmaster_hooks_workflow.md'
|
'rules/taskmaster_hooks_workflow.mdc': 'taskmaster_hooks_workflow.md',
|
||||||
|
'rules/hamster.mdc': 'hamster.md',
|
||||||
|
'rules/goham.md': 'goham.md'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,9 @@ describe('Selective Rules Removal', () => {
|
|||||||
// Second call - get taskmaster subdirectory contents
|
// Second call - get taskmaster subdirectory contents
|
||||||
.mockReturnValueOnce([
|
.mockReturnValueOnce([
|
||||||
'dev_workflow.mdc', // Task Master file in subdirectory
|
'dev_workflow.mdc', // Task Master file in subdirectory
|
||||||
'taskmaster.mdc' // Task Master file in subdirectory
|
'taskmaster.mdc', // Task Master file in subdirectory
|
||||||
|
'hamster.mdc', // Task Master file in subdirectory
|
||||||
|
'goham.mdc' // Task Master file in subdirectory
|
||||||
])
|
])
|
||||||
// Third call - check remaining files after removal
|
// Third call - check remaining files after removal
|
||||||
.mockReturnValueOnce([
|
.mockReturnValueOnce([
|
||||||
@@ -137,7 +139,9 @@ describe('Selective Rules Removal', () => {
|
|||||||
'cursor_rules.mdc',
|
'cursor_rules.mdc',
|
||||||
'taskmaster/dev_workflow.mdc',
|
'taskmaster/dev_workflow.mdc',
|
||||||
'self_improve.mdc',
|
'self_improve.mdc',
|
||||||
'taskmaster/taskmaster.mdc'
|
'taskmaster/taskmaster.mdc',
|
||||||
|
'taskmaster/hamster.mdc',
|
||||||
|
'taskmaster/goham.mdc'
|
||||||
]);
|
]);
|
||||||
expect(result.notice).toContain('Preserved 2 existing rule files');
|
expect(result.notice).toContain('Preserved 2 existing rule files');
|
||||||
|
|
||||||
@@ -214,7 +218,12 @@ describe('Selective Rules Removal', () => {
|
|||||||
'self_improve.mdc'
|
'self_improve.mdc'
|
||||||
])
|
])
|
||||||
// Second call - get taskmaster subdirectory contents
|
// Second call - get taskmaster subdirectory contents
|
||||||
.mockReturnValueOnce(['dev_workflow.mdc', 'taskmaster.mdc'])
|
.mockReturnValueOnce([
|
||||||
|
'dev_workflow.mdc',
|
||||||
|
'taskmaster.mdc',
|
||||||
|
'hamster.mdc',
|
||||||
|
'goham.mdc'
|
||||||
|
])
|
||||||
// Third call - check remaining files after removal (should be empty)
|
// Third call - check remaining files after removal (should be empty)
|
||||||
.mockReturnValueOnce([]) // Empty after removal
|
.mockReturnValueOnce([]) // Empty after removal
|
||||||
// Fourth call - check profile directory contents
|
// Fourth call - check profile directory contents
|
||||||
@@ -227,7 +236,9 @@ describe('Selective Rules Removal', () => {
|
|||||||
'cursor_rules.mdc',
|
'cursor_rules.mdc',
|
||||||
'taskmaster/dev_workflow.mdc',
|
'taskmaster/dev_workflow.mdc',
|
||||||
'self_improve.mdc',
|
'self_improve.mdc',
|
||||||
'taskmaster/taskmaster.mdc'
|
'taskmaster/taskmaster.mdc',
|
||||||
|
'taskmaster/hamster.mdc',
|
||||||
|
'taskmaster/goham.mdc'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// The function may fail due to directory reading issues in the test environment,
|
// The function may fail due to directory reading issues in the test environment,
|
||||||
|
|||||||
Reference in New Issue
Block a user