mirror of
https://github.com/eyaltoledano/claude-task-master.git
synced 2025-07-31 04:42:27 +00:00
269 lines
9.2 KiB
Plaintext
269 lines
9.2 KiB
Plaintext
![]() |
---
|
||
|
description: Standardized patterns for gathering and processing context from multiple sources in Task Master commands, particularly for AI-powered features.
|
||
|
globs:
|
||
|
alwaysApply: false
|
||
|
---
|
||
|
# Context Gathering Patterns and Utilities
|
||
|
|
||
|
This document outlines the standardized patterns for gathering and processing context from multiple sources in Task Master commands, particularly for AI-powered features.
|
||
|
|
||
|
## Core Context Gathering Utility
|
||
|
|
||
|
The `ContextGatherer` class (`scripts/modules/utils/contextGatherer.js`) provides a centralized, reusable utility for extracting context from multiple sources:
|
||
|
|
||
|
### **Key Features**
|
||
|
- **Multi-source Context**: Tasks, files, custom text, project file tree
|
||
|
- **Token Counting**: Detailed breakdown using `gpt-tokens` library
|
||
|
- **Format Support**: Different output formats (research, chat, system-prompt)
|
||
|
- **Error Handling**: Graceful handling of missing files, invalid task IDs
|
||
|
- **Performance**: File size limits, depth limits for tree generation
|
||
|
|
||
|
### **Usage Pattern**
|
||
|
```javascript
|
||
|
import { ContextGatherer } from '../utils/contextGatherer.js';
|
||
|
|
||
|
// Initialize with project paths
|
||
|
const gatherer = new ContextGatherer(projectRoot, tasksPath);
|
||
|
|
||
|
// Gather context with detailed token breakdown
|
||
|
const result = await gatherer.gather({
|
||
|
tasks: ['15', '16.2'], // Task and subtask IDs
|
||
|
files: ['src/api.js', 'README.md'], // File paths
|
||
|
customContext: 'Additional context text',
|
||
|
includeProjectTree: true, // Include file tree
|
||
|
format: 'research', // Output format
|
||
|
includeTokenCounts: true // Get detailed token breakdown
|
||
|
});
|
||
|
|
||
|
// Access results
|
||
|
const contextString = result.context;
|
||
|
const tokenBreakdown = result.tokenBreakdown;
|
||
|
```
|
||
|
|
||
|
### **Token Breakdown Structure**
|
||
|
```javascript
|
||
|
{
|
||
|
customContext: { tokens: 150, characters: 800 },
|
||
|
tasks: [
|
||
|
{ id: '15', type: 'task', title: 'Task Title', tokens: 245, characters: 1200 },
|
||
|
{ id: '16.2', type: 'subtask', title: 'Subtask Title', tokens: 180, characters: 900 }
|
||
|
],
|
||
|
files: [
|
||
|
{ path: 'src/api.js', tokens: 890, characters: 4500, size: '4.5 KB' }
|
||
|
],
|
||
|
projectTree: { tokens: 320, characters: 1600 },
|
||
|
total: { tokens: 1785, characters: 8000 }
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Fuzzy Search Integration
|
||
|
|
||
|
The `FuzzyTaskSearch` class (`scripts/modules/utils/fuzzyTaskSearch.js`) provides intelligent task discovery:
|
||
|
|
||
|
### **Key Features**
|
||
|
- **Semantic Matching**: Uses Fuse.js for similarity scoring
|
||
|
- **Purpose Categories**: Pattern-based task categorization
|
||
|
- **Relevance Scoring**: High/medium/low relevance thresholds
|
||
|
- **Context-Aware**: Different search configurations for different use cases
|
||
|
|
||
|
### **Usage Pattern**
|
||
|
```javascript
|
||
|
import { FuzzyTaskSearch } from '../utils/fuzzyTaskSearch.js';
|
||
|
|
||
|
// Initialize with tasks data and context
|
||
|
const fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');
|
||
|
|
||
|
// Find relevant tasks
|
||
|
const searchResults = fuzzySearch.findRelevantTasks(query, {
|
||
|
maxResults: 8,
|
||
|
includeRecent: true,
|
||
|
includeCategoryMatches: true
|
||
|
});
|
||
|
|
||
|
// Get task IDs for context gathering
|
||
|
const taskIds = fuzzySearch.getTaskIds(searchResults);
|
||
|
```
|
||
|
|
||
|
## Implementation Patterns for Commands
|
||
|
|
||
|
### **1. Context-Aware Command Structure**
|
||
|
```javascript
|
||
|
// In command action handler
|
||
|
async function commandAction(prompt, options) {
|
||
|
// 1. Parameter validation and parsing
|
||
|
const taskIds = options.id ? parseTaskIds(options.id) : [];
|
||
|
const filePaths = options.files ? parseFilePaths(options.files) : [];
|
||
|
|
||
|
// 2. Initialize context gatherer
|
||
|
const projectRoot = findProjectRoot() || '.';
|
||
|
const tasksPath = path.join(projectRoot, 'tasks', 'tasks.json');
|
||
|
const gatherer = new ContextGatherer(projectRoot, tasksPath);
|
||
|
|
||
|
// 3. Auto-discover relevant tasks if none specified
|
||
|
if (taskIds.length === 0) {
|
||
|
const fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');
|
||
|
const discoveredIds = fuzzySearch.getTaskIds(
|
||
|
fuzzySearch.findRelevantTasks(prompt)
|
||
|
);
|
||
|
taskIds.push(...discoveredIds);
|
||
|
}
|
||
|
|
||
|
// 4. Gather context with token breakdown
|
||
|
const contextResult = await gatherer.gather({
|
||
|
tasks: taskIds,
|
||
|
files: filePaths,
|
||
|
customContext: options.context,
|
||
|
includeProjectTree: options.projectTree,
|
||
|
format: 'research',
|
||
|
includeTokenCounts: true
|
||
|
});
|
||
|
|
||
|
// 5. Display token breakdown (for CLI)
|
||
|
if (outputFormat === 'text') {
|
||
|
displayDetailedTokenBreakdown(contextResult.tokenBreakdown);
|
||
|
}
|
||
|
|
||
|
// 6. Use context in AI call
|
||
|
const aiResult = await generateTextService(role, session, systemPrompt, userPrompt);
|
||
|
|
||
|
// 7. Display results with enhanced formatting
|
||
|
displayResults(aiResult, contextResult.tokenBreakdown);
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### **2. Token Display Pattern**
|
||
|
```javascript
|
||
|
function displayDetailedTokenBreakdown(tokenBreakdown, systemTokens, userTokens) {
|
||
|
const sections = [];
|
||
|
|
||
|
// Build context breakdown
|
||
|
if (tokenBreakdown.tasks?.length > 0) {
|
||
|
const taskDetails = tokenBreakdown.tasks.map(task =>
|
||
|
`${task.type === 'subtask' ? ' ' : ''}${task.id}: ${task.tokens.toLocaleString()}`
|
||
|
).join('\n');
|
||
|
sections.push(`Tasks (${tokenBreakdown.tasks.reduce((sum, t) => sum + t.tokens, 0).toLocaleString()}):\n${taskDetails}`);
|
||
|
}
|
||
|
|
||
|
if (tokenBreakdown.files?.length > 0) {
|
||
|
const fileDetails = tokenBreakdown.files.map(file =>
|
||
|
` ${file.path}: ${file.tokens.toLocaleString()} (${file.size})`
|
||
|
).join('\n');
|
||
|
sections.push(`Files (${tokenBreakdown.files.reduce((sum, f) => sum + f.tokens, 0).toLocaleString()}):\n${fileDetails}`);
|
||
|
}
|
||
|
|
||
|
// Add prompts breakdown
|
||
|
sections.push(`Prompts: system ${systemTokens.toLocaleString()}, user ${userTokens.toLocaleString()}`);
|
||
|
|
||
|
// Display in clean box
|
||
|
const content = sections.join('\n\n');
|
||
|
console.log(boxen(content, {
|
||
|
title: chalk.cyan('Token Usage'),
|
||
|
padding: { top: 1, bottom: 1, left: 2, right: 2 },
|
||
|
borderStyle: 'round',
|
||
|
borderColor: 'cyan'
|
||
|
}));
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### **3. Enhanced Result Display Pattern**
|
||
|
```javascript
|
||
|
function displayResults(result, query, detailLevel, tokenBreakdown) {
|
||
|
// Header with query info
|
||
|
const header = boxen(
|
||
|
chalk.green.bold('Research Results') + '\n\n' +
|
||
|
chalk.gray('Query: ') + chalk.white(query) + '\n' +
|
||
|
chalk.gray('Detail Level: ') + chalk.cyan(detailLevel),
|
||
|
{
|
||
|
padding: { top: 1, bottom: 1, left: 2, right: 2 },
|
||
|
margin: { top: 1, bottom: 0 },
|
||
|
borderStyle: 'round',
|
||
|
borderColor: 'green'
|
||
|
}
|
||
|
);
|
||
|
console.log(header);
|
||
|
|
||
|
// Process and highlight code blocks
|
||
|
const processedResult = processCodeBlocks(result);
|
||
|
|
||
|
// Main content in clean box
|
||
|
const contentBox = boxen(processedResult, {
|
||
|
padding: { top: 1, bottom: 1, left: 2, right: 2 },
|
||
|
margin: { top: 0, bottom: 1 },
|
||
|
borderStyle: 'single',
|
||
|
borderColor: 'gray'
|
||
|
});
|
||
|
console.log(contentBox);
|
||
|
|
||
|
console.log(chalk.green('✓ Research complete'));
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Code Block Enhancement
|
||
|
|
||
|
### **Syntax Highlighting Pattern**
|
||
|
```javascript
|
||
|
import { highlight } from 'cli-highlight';
|
||
|
|
||
|
function processCodeBlocks(text) {
|
||
|
return text.replace(/```(\w+)?\n([\s\S]*?)```/g, (match, language, code) => {
|
||
|
try {
|
||
|
const highlighted = highlight(code.trim(), {
|
||
|
language: language || 'javascript',
|
||
|
theme: 'default'
|
||
|
});
|
||
|
return `\n${highlighted}\n`;
|
||
|
} catch (error) {
|
||
|
return `\n${code.trim()}\n`;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Integration Guidelines
|
||
|
|
||
|
### **When to Use Context Gathering**
|
||
|
- ✅ **DO**: Use for AI-powered commands that benefit from project context
|
||
|
- ✅ **DO**: Use when users might want to reference specific tasks or files
|
||
|
- ✅ **DO**: Use for research, analysis, or generation commands
|
||
|
- ❌ **DON'T**: Use for simple CRUD operations that don't need AI context
|
||
|
|
||
|
### **Performance Considerations**
|
||
|
- ✅ **DO**: Set reasonable file size limits (50KB default)
|
||
|
- ✅ **DO**: Limit project tree depth (3-5 levels)
|
||
|
- ✅ **DO**: Provide token counts to help users understand context size
|
||
|
- ✅ **DO**: Allow users to control what context is included
|
||
|
|
||
|
### **Error Handling**
|
||
|
- ✅ **DO**: Gracefully handle missing files with warnings
|
||
|
- ✅ **DO**: Validate task IDs and provide helpful error messages
|
||
|
- ✅ **DO**: Continue processing even if some context sources fail
|
||
|
- ✅ **DO**: Provide fallback behavior when context gathering fails
|
||
|
|
||
|
### **Future Command Integration**
|
||
|
Commands that should consider adopting this pattern:
|
||
|
- `analyze-complexity` - Could benefit from file context
|
||
|
- `expand-task` - Could use related task context
|
||
|
- `update-task` - Could reference similar tasks for consistency
|
||
|
- `add-task` - Could use project context for better task generation
|
||
|
|
||
|
## Export Patterns
|
||
|
|
||
|
### **Context Gatherer Module**
|
||
|
```javascript
|
||
|
export {
|
||
|
ContextGatherer,
|
||
|
createContextGatherer // Factory function
|
||
|
};
|
||
|
```
|
||
|
|
||
|
### **Fuzzy Search Module**
|
||
|
```javascript
|
||
|
export {
|
||
|
FuzzyTaskSearch,
|
||
|
PURPOSE_CATEGORIES,
|
||
|
RELEVANCE_THRESHOLDS
|
||
|
};
|
||
|
```
|
||
|
|
||
|
This context gathering system provides a foundation for building more intelligent, context-aware commands that can leverage project knowledge to provide better AI-powered assistance.
|