Compare commits
5 Commits
fix/vscode
...
task-maste
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53903f1e8e | ||
|
|
36c56231cc | ||
|
|
b82d858f81 | ||
|
|
9808967d6b | ||
|
|
3fee7515f3 |
@@ -1,5 +1,5 @@
|
||||
---
|
||||
"task-master-ai": patch
|
||||
"task-master-ai": minor
|
||||
---
|
||||
|
||||
Add new `scope-up` and `scope-down` commands for dynamic task complexity adjustment
|
||||
@@ -9,6 +9,6 @@
|
||||
"eleven-horses-shop",
|
||||
"fix-tag-complexity-detection",
|
||||
"floppy-news-buy",
|
||||
"sour-pans-beam"
|
||||
"sour-pans-beam-1"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,48 @@
|
||||
# Change Log
|
||||
|
||||
## 0.23.0-rc.1
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1064](https://github.com/eyaltoledano/claude-task-master/pull/1064) [`b82d858`](https://github.com/eyaltoledano/claude-task-master/commit/b82d858f81a1e702ad59d84d5ae8a2ca84359a83) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - 🎉 **Introducing TaskMaster Extension!**
|
||||
|
||||
We're thrilled to launch the first version of our Code extension, bringing the power of TaskMaster directly into your favorite code editor. While this is our initial release and we've kept things focused, it already packs powerful features to supercharge your development workflow.
|
||||
|
||||
## ✨ Key Features
|
||||
|
||||
### 📋 Visual Task Management
|
||||
- **Kanban Board View**: Visualize all your tasks in an intuitive board layout directly in VS Code
|
||||
- **Drag & Drop**: Easily change task status by dragging cards between columns
|
||||
- **Real-time Updates**: See changes instantly as you work through your project
|
||||
|
||||
### 🏷️ Multi-Context Support
|
||||
- **Tag Switching**: Seamlessly switch between different project contexts/tags
|
||||
- **Isolated Workflows**: Keep different features or experiments organized separately
|
||||
|
||||
### 🤖 AI-Powered Task Updates
|
||||
- **Smart Updates**: Use TaskMaster's AI capabilities to update tasks and subtasks
|
||||
- **Context-Aware**: Leverages your existing TaskMaster configuration and models
|
||||
|
||||
### 📊 Rich Task Information
|
||||
- **Complexity Scores**: See task complexity ratings at a glance
|
||||
- **Subtask Visualization**: Expand tasks to view and manage subtasks
|
||||
- **Dependency Graphs**: Understand task relationships and dependencies visually
|
||||
|
||||
### ⚙️ Configuration Management
|
||||
- **Visual Config Editor**: View and understand your `.taskmaster/config.json` settings
|
||||
- **Easy Access**: No more manual JSON editing for common configuration tasks
|
||||
|
||||
### 🚀 Quick Actions
|
||||
- **Status Updates**: Change task status with a single click
|
||||
- **Task Details**: Access full task information without leaving VS Code
|
||||
- **Integrated Commands**: All TaskMaster commands available through the command palette
|
||||
|
||||
## 🎯 What's Next?
|
||||
|
||||
This is just the beginning! We wanted to get a solid foundation into your hands quickly. The extension will evolve rapidly with your feedback, adding more advanced features, better visualizations, and deeper integration with your development workflow.
|
||||
|
||||
Thank you for being part of the TaskMaster journey. Your workflow has never looked better! 🚀
|
||||
|
||||
## 0.23.0-rc.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"private": true,
|
||||
"displayName": "TaskMaster",
|
||||
"description": "A visual Kanban board interface for TaskMaster projects in VS Code",
|
||||
"version": "0.23.0-rc.0",
|
||||
"version": "0.23.0-rc.1",
|
||||
"publisher": "Hamster",
|
||||
"icon": "assets/icon.png",
|
||||
"engines": {
|
||||
|
||||
@@ -4,7 +4,13 @@ import { Button } from '@/components/ui/button';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { CollapsibleSection } from '@/components/ui/CollapsibleSection';
|
||||
import { Wand2, Loader2, PlusCircle, TrendingUp, TrendingDown } from 'lucide-react';
|
||||
import {
|
||||
Wand2,
|
||||
Loader2,
|
||||
PlusCircle,
|
||||
TrendingUp,
|
||||
TrendingDown
|
||||
} from 'lucide-react';
|
||||
import {
|
||||
useUpdateTask,
|
||||
useUpdateSubtask,
|
||||
@@ -34,10 +40,12 @@ export const AIActionsSection: React.FC<AIActionsSectionProps> = ({
|
||||
}) => {
|
||||
const [prompt, setPrompt] = useState('');
|
||||
const [scopePrompt, setScopePrompt] = useState('');
|
||||
const [scopeStrength, setScopeStrength] = useState<'light' | 'regular' | 'heavy'>('regular');
|
||||
const [lastAction, setLastAction] = useState<'regenerate' | 'append' | 'scope-up' | 'scope-down' | null>(
|
||||
null
|
||||
);
|
||||
const [scopeStrength, setScopeStrength] = useState<
|
||||
'light' | 'regular' | 'heavy'
|
||||
>('regular');
|
||||
const [lastAction, setLastAction] = useState<
|
||||
'regenerate' | 'append' | 'scope-up' | 'scope-down' | null
|
||||
>(null);
|
||||
const updateTask = useUpdateTask();
|
||||
const updateSubtask = useUpdateSubtask();
|
||||
const scopeUpTask = useScopeUpTask();
|
||||
@@ -117,7 +125,10 @@ export const AIActionsSection: React.FC<AIActionsSectionProps> = ({
|
||||
setLastAction('scope-up');
|
||||
|
||||
try {
|
||||
const taskId = isSubtask && parentTask ? `${parentTask.id}.${currentTask.id}` : currentTask.id;
|
||||
const taskId =
|
||||
isSubtask && parentTask
|
||||
? `${parentTask.id}.${currentTask.id}`
|
||||
: currentTask.id;
|
||||
|
||||
await scopeUpTask.mutateAsync({
|
||||
taskId,
|
||||
@@ -143,7 +154,10 @@ export const AIActionsSection: React.FC<AIActionsSectionProps> = ({
|
||||
setLastAction('scope-down');
|
||||
|
||||
try {
|
||||
const taskId = isSubtask && parentTask ? `${parentTask.id}.${currentTask.id}` : currentTask.id;
|
||||
const taskId =
|
||||
isSubtask && parentTask
|
||||
? `${parentTask.id}.${currentTask.id}`
|
||||
: currentTask.id;
|
||||
|
||||
await scopeDownTask.mutateAsync({
|
||||
taskId,
|
||||
@@ -162,7 +176,11 @@ export const AIActionsSection: React.FC<AIActionsSectionProps> = ({
|
||||
};
|
||||
|
||||
// Track loading states based on the last action
|
||||
const isLoading = updateTask.isPending || updateSubtask.isPending || scopeUpTask.isPending || scopeDownTask.isPending;
|
||||
const isLoading =
|
||||
updateTask.isPending ||
|
||||
updateSubtask.isPending ||
|
||||
scopeUpTask.isPending ||
|
||||
scopeDownTask.isPending;
|
||||
const isRegenerating = isLoading && lastAction === 'regenerate';
|
||||
const isAppending = isLoading && lastAction === 'append';
|
||||
const isScopingUp = isLoading && lastAction === 'scope-up';
|
||||
@@ -348,10 +366,12 @@ export const AIActionsSection: React.FC<AIActionsSectionProps> = ({
|
||||
</>
|
||||
)}
|
||||
<p>
|
||||
<strong>Scope Up:</strong> Increases task complexity with more details, requirements, or implementation steps
|
||||
<strong>Scope Up:</strong> Increases task complexity with more
|
||||
details, requirements, or implementation steps
|
||||
</p>
|
||||
<p>
|
||||
<strong>Scope Down:</strong> Decreases task complexity by simplifying or removing unnecessary details
|
||||
<strong>Scope Down:</strong> Decreases task complexity by
|
||||
simplifying or removing unnecessary details
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -251,7 +251,7 @@ export function useScopeUpTask() {
|
||||
type: 'mcpRequest',
|
||||
tool: 'scope_up_task',
|
||||
params: {
|
||||
id: taskId,
|
||||
id: String(taskId),
|
||||
strength,
|
||||
prompt,
|
||||
research: options.research || false
|
||||
@@ -268,9 +268,7 @@ export function useScopeUpTask() {
|
||||
return response;
|
||||
},
|
||||
onSuccess: async (data, variables) => {
|
||||
console.log(
|
||||
'✅ Task scope up successful, invalidating all task queries'
|
||||
);
|
||||
console.log('✅ Task scope up successful, invalidating all task queries');
|
||||
console.log('Task ID:', variables.taskId);
|
||||
|
||||
// Invalidate ALL task-related queries
|
||||
@@ -309,7 +307,7 @@ export function useScopeDownTask() {
|
||||
type: 'mcpRequest',
|
||||
tool: 'scope_down_task',
|
||||
params: {
|
||||
id: taskId,
|
||||
id: String(taskId),
|
||||
strength,
|
||||
prompt,
|
||||
research: options.research || false
|
||||
|
||||
@@ -9,10 +9,7 @@
|
||||
"task-master-mcp": "mcp-server/server.js",
|
||||
"task-master-ai": "mcp-server/server.js"
|
||||
},
|
||||
"workspaces": [
|
||||
"apps/*",
|
||||
"."
|
||||
],
|
||||
"workspaces": ["apps/*", "."],
|
||||
"scripts": {
|
||||
"test": "node --experimental-vm-modules node_modules/.bin/jest",
|
||||
"test:fails": "node --experimental-vm-modules node_modules/.bin/jest --onlyFailures",
|
||||
|
||||
@@ -279,8 +279,9 @@ async function regenerateSubtasksForComplexity(
|
||||
'debug',
|
||||
`Complexity-aware subtask calculation${complexityInfo}: ${currentPendingCount} pending -> target ${targetSubtaskCount} total`
|
||||
);
|
||||
console.log(
|
||||
`[DEBUG] Complexity-aware calculation${complexityInfo}: ${currentPendingCount} pending -> ${targetSubtaskCount} total subtasks (${strength} ${direction})`
|
||||
log(
|
||||
'debug',
|
||||
`Complexity-aware calculation${complexityInfo}: ${currentPendingCount} pending -> ${targetSubtaskCount} total subtasks (${strength} ${direction})`
|
||||
);
|
||||
|
||||
const newSubtasksNeeded = Math.max(1, targetSubtaskCount - preservedCount);
|
||||
@@ -386,8 +387,9 @@ Ensure the JSON is valid and properly formatted.`;
|
||||
generated: generatedSubtasks.length
|
||||
};
|
||||
} catch (error) {
|
||||
console.log(
|
||||
`[WARN] Failed to regenerate subtasks for task ${task.id}: ${error.message}`
|
||||
log(
|
||||
'warn',
|
||||
`Failed to regenerate subtasks for task ${task.id}: ${error.message}`
|
||||
);
|
||||
// Don't fail the whole operation if subtask regeneration fails
|
||||
return {
|
||||
@@ -583,7 +585,7 @@ export async function scopeUpTask(
|
||||
// Get original complexity score (if available)
|
||||
const originalComplexity = getCurrentComplexityScore(taskId, context);
|
||||
if (originalComplexity && outputFormat === 'text') {
|
||||
console.log(`[INFO] Original complexity: ${originalComplexity}/10`);
|
||||
log('info', `Original complexity: ${originalComplexity}/10`);
|
||||
}
|
||||
|
||||
const adjustResult = await adjustTaskComplexity(
|
||||
@@ -635,8 +637,9 @@ export async function scopeUpTask(
|
||||
const complexityChange = newComplexity - originalComplexity;
|
||||
const arrow =
|
||||
complexityChange > 0 ? '↗️' : complexityChange < 0 ? '↘️' : '➡️';
|
||||
console.log(
|
||||
`[INFO] New complexity: ${originalComplexity}/10 ${arrow} ${newComplexity}/10 (${complexityChange > 0 ? '+' : ''}${complexityChange})`
|
||||
log(
|
||||
'info',
|
||||
`New complexity: ${originalComplexity}/10 ${arrow} ${newComplexity}/10 (${complexityChange > 0 ? '+' : ''}${complexityChange})`
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -733,7 +736,7 @@ export async function scopeDownTask(
|
||||
// Get original complexity score (if available)
|
||||
const originalComplexity = getCurrentComplexityScore(taskId, context);
|
||||
if (originalComplexity && outputFormat === 'text') {
|
||||
console.log(`[INFO] Original complexity: ${originalComplexity}/10`);
|
||||
log('info', `Original complexity: ${originalComplexity}/10`);
|
||||
}
|
||||
|
||||
const adjustResult = await adjustTaskComplexity(
|
||||
@@ -785,8 +788,9 @@ export async function scopeDownTask(
|
||||
const complexityChange = newComplexity - originalComplexity;
|
||||
const arrow =
|
||||
complexityChange > 0 ? '↗️' : complexityChange < 0 ? '↘️' : '➡️';
|
||||
console.log(
|
||||
`[INFO] New complexity: ${originalComplexity}/10 ${arrow} ${newComplexity}/10 (${complexityChange > 0 ? '+' : ''}${complexityChange})`
|
||||
log(
|
||||
'info',
|
||||
`New complexity: ${originalComplexity}/10 ${arrow} ${newComplexity}/10 (${complexityChange > 0 ? '+' : ''}${complexityChange})`
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -8,13 +8,17 @@ jest.unstable_mockModule('../../../../../scripts/modules/utils.js', () => ({
|
||||
log: jest.fn(),
|
||||
readJSON: jest.fn(),
|
||||
writeJSON: jest.fn(),
|
||||
getCurrentTag: jest.fn(() => 'master')
|
||||
getCurrentTag: jest.fn(() => 'master'),
|
||||
readComplexityReport: jest.fn(),
|
||||
findTaskInComplexityReport: jest.fn(),
|
||||
findProjectRoot: jest.fn()
|
||||
}));
|
||||
|
||||
jest.unstable_mockModule(
|
||||
'../../../../../scripts/modules/ai-services-unified.js',
|
||||
() => ({
|
||||
generateObjectService: jest.fn()
|
||||
generateObjectService: jest.fn(),
|
||||
generateTextService: jest.fn()
|
||||
})
|
||||
);
|
||||
|
||||
@@ -26,10 +30,25 @@ jest.unstable_mockModule(
|
||||
})
|
||||
);
|
||||
|
||||
// Import modules after mocking
|
||||
const { log, readJSON, writeJSON } = await import(
|
||||
'../../../../../scripts/modules/utils.js'
|
||||
jest.unstable_mockModule(
|
||||
'../../../../../scripts/modules/task-manager/analyze-task-complexity.js',
|
||||
() => ({
|
||||
default: jest.fn()
|
||||
})
|
||||
);
|
||||
|
||||
jest.unstable_mockModule('../../../../../src/utils/path-utils.js', () => ({
|
||||
findComplexityReportPath: jest.fn()
|
||||
}));
|
||||
|
||||
// Import modules after mocking
|
||||
const {
|
||||
log,
|
||||
readJSON,
|
||||
writeJSON,
|
||||
readComplexityReport,
|
||||
findTaskInComplexityReport
|
||||
} = await import('../../../../../scripts/modules/utils.js');
|
||||
const { generateObjectService } = await import(
|
||||
'../../../../../scripts/modules/ai-services-unified.js'
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user