From efaaed9f7381f7d9d1d027193b870cf0596adb4e Mon Sep 17 00:00:00 2001 From: MuriloFP Date: Thu, 3 Jul 2025 15:26:24 -0300 Subject: [PATCH 1/4] feat: add Issue Fixer Orchestrator mode --- .../1_Workflow.xml | 402 +++++++++++++----- .../2_best_practices.xml | 31 +- .roomodes | 3 +- 3 files changed, 315 insertions(+), 121 deletions(-) diff --git a/.roo/rules-issue-fixer-orchestrator/1_Workflow.xml b/.roo/rules-issue-fixer-orchestrator/1_Workflow.xml index 2ad4bf65fc7..3e6619993ec 100644 --- a/.roo/rules-issue-fixer-orchestrator/1_Workflow.xml +++ b/.roo/rules-issue-fixer-orchestrator/1_Workflow.xml @@ -27,7 +27,7 @@ Delegate: Analyze Requirements & Explore Codebase - Launch a subtask in `code` mode to perform a detailed analysis of the issue and the codebase. The subtask will be responsible for identifying affected files and creating an implementation plan. + Launch a subtask in `architect` mode to perform a detailed analysis of the issue and the codebase. The subtask will be responsible for identifying affected files and creating an implementation plan. The context file `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json` will be the input for this subtask. The subtask should write its findings (the implementation plan) to a new file: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md`. @@ -36,19 +36,50 @@ **Task: Analyze Issue and Create Implementation Plan** - You are an expert software architect. Your task is to analyze the provided GitHub issue and the current codebase to create a detailed implementation plan. + You are an expert software architect. Your task is to analyze the provided GitHub issue and the current codebase to create a detailed implementation plan with a focus on understanding component interactions and dependencies. 1. **Read Issue Context**: The full issue details and comments are in `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json`. Read this file to understand all requirements, acceptance criteria, and technical discussions. - 2. **Explore Codebase**: Use `codebase_search`, `read_file`, and other tools to explore the codebase. Identify all files that will need to be modified or created to address the issue. Analyze existing patterns and conventions. - - 3. **Create Implementation Plan**: Based on your analysis, create a comprehensive implementation plan. The plan should be detailed enough for another developer to execute. It must include: - - A summary of the issue and the proposed solution. - - A list of all files to be created or modified. - - A step-by-step guide for the code changes required in each file. - - A plan for writing or updating tests. - - 4. **Save the Plan**: Write the complete implementation plan to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md`. + 2. **Perform Architectural Analysis**: + - **Map Component Interactions**: Trace the complete data flow from entry points to outputs + - **Identify Paired Operations**: For any operation (e.g., export), find its counterpart (e.g., import) + - **Find Similar Patterns**: Search for existing implementations of similar features + - **Analyze Dependencies**: Identify all consumers of the functionality being modified + - **Assess Impact**: Determine how changes will affect other parts of the system + + 3. **Explore Codebase Systematically**: + - Use `codebase_search` FIRST to find all related functionality + - Search for paired operations (if modifying export, search for import) + - Find all files that consume or depend on the affected functionality + - Identify configuration files, tests, and documentation that need updates + - Study similar features to understand established patterns + + 4. **Create Comprehensive Implementation Plan**: The plan must include: + - **Issue Summary**: Clear description of the problem and proposed solution + - **Architectural Context**: + - Data flow diagram showing component interactions + - List of paired operations that must be updated together + - Dependencies and consumers of the affected functionality + - **Impact Analysis**: + - All files that will be affected (directly and indirectly) + - Potential breaking changes + - Performance implications + - **Implementation Steps**: + - Detailed, ordered steps for each file modification + - Specific code changes with context + - Validation and error handling requirements + - **Testing Strategy**: + - Unit tests for individual components + - Integration tests for component interactions + - Edge cases and error scenarios + + 5. **Save the Plan**: Write the complete implementation plan to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md`. + + **Critical Requirements:** + - Always search for and analyze paired operations (import/export, save/load, etc.) + - Map the complete data flow before proposing changes + - Identify all integration points and dependencies + - Consider backward compatibility and migration needs **Completion Protocol:** - This is your only task. Do not deviate from these instructions. @@ -110,19 +141,43 @@ **Task: Implement Code Changes Based on Plan** - You are an expert software developer. Your task is to implement the code changes exactly as described in the provided implementation plan. + You are an expert software developer. Your task is to implement the code changes with full awareness of system interactions and dependencies. - 1. **Read the Plan**: The implementation plan is located at `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md`. Follow its instructions carefully. + 1. **Read the Plan**: The implementation plan is located at `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md`. Pay special attention to: + - The architectural context section + - Component interaction diagrams + - Identified dependencies and related operations + - Impact analysis - 2. **Implement Changes**: Use `apply_diff` and `write_to_file` to make the specified code changes. Adhere to all coding standards and patterns mentioned in the plan. + 2. **Validate Understanding**: Before coding, ensure you understand: + - How data flows through the system + - All related operations that must be updated together + - Dependencies that could be affected + - Integration points with other components - 3. **Implement Tests**: Write new unit and integration tests as specified in the plan to ensure quality and prevent regressions. + 3. **Implement Holistically**: + - **Update Related Operations Together**: If modifying one operation, update all related operations + - **Maintain Consistency**: Ensure data structures, validation, and error handling are consistent + - **Consider Side Effects**: Account for how changes propagate through the system + - **Follow Existing Patterns**: Use established patterns from similar features - 4. **Track Modified Files**: As you modify or create files, keep a running list. + 4. **Implement Tests**: + - Write tests that verify component interactions + - Test related operations together + - Include edge cases and error scenarios + - Verify data consistency across operations - 5. **Save Modified Files List**: After all changes are implemented and tested, save the list of all file paths you created or modified to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json`. The format should be a JSON array of strings. + 5. **Track Modified Files**: As you modify or create files, keep a running list. + + 6. **Save Modified Files List**: After all changes are implemented and tested, save the list of all file paths you created or modified to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json`. The format should be a JSON array of strings. Example: `["src/components/NewFeature.tsx", "src/__tests__/NewFeature.spec.ts"]` + **Critical Reminders:** + - Never implement changes in isolation - consider the full system impact + - Always update related operations together to maintain consistency + - Test component interactions, not just individual functions + - Follow the architectural analysis from the planning phase + Once the `modified_files.json` file is saved, your task is complete. @@ -325,122 +380,233 @@ - Create Pull Request + Delegate: Review Changes Before PR - This is the final step where the orchestrator takes all the prepared materials and creates the pull request. + Before creating the pull request, delegate to the PR reviewer mode to get feedback on the implementation and proposed changes. - 1. **Read PR Summary**: - - - - .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json - - - - - 2. **Get Final Approval**: Present the PR title and body to the user for final approval, providing an option to request changes. + + pr-reviewer + + **Task: Review Implementation Before PR Creation** - - - I have prepared the pull request. Please review and confirm. + You are an expert code reviewer. Your task is to review the implementation for issue #[issue-number] and provide feedback before a pull request is created. - **Title**: [Insert title from pr_summary.json] + **Context Files:** + - **Issue Details**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json` + - **Implementation Plan**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md` + - **Modified Files**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json` + - **Verification Results**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/verification_results.md` + - **Translation Summary** (if exists): `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/translation_summary.md` + - **Draft PR Summary**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json` + + **Your Review Focus:** + 1. **Code Quality**: Review the actual code changes for: + - Adherence to project coding standards + - Proper error handling and edge cases + - Performance considerations + - Security implications + - Maintainability and readability + + 2. **Implementation Completeness**: Verify that: + - All requirements from the issue are addressed + - The solution follows the implementation plan + - No critical functionality is missing + - Proper test coverage exists + + 3. **Integration Concerns**: Check for: + - Potential breaking changes + - Impact on other parts of the system + - Backward compatibility issues + - API consistency + + 4. **Documentation and Communication**: Assess: + - Code comments and documentation + - PR description clarity and completeness + - Translation handling (if applicable) - **Body**: - --- - [Insert body from pr_summary.json] - --- + **Your Task:** + 1. Read all context files to understand the issue and implementation + 2. Review each modified file listed in `modified_files.json` + 3. Analyze the code changes against the requirements + 4. Identify any issues, improvements, or concerns + 5. Create a comprehensive review report with specific, actionable feedback + 6. Save your review to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_review_feedback.md` + + **Review Report Format:** + ```markdown + # PR Review Feedback for Issue #[issue-number] + + ## Overall Assessment + [High-level assessment: APPROVE, REQUEST_CHANGES, or NEEDS_DISCUSSION] + + ## Code Quality Review + ### Strengths + - [List positive aspects of the implementation] + + ### Areas for Improvement + - [Specific issues with file references and line numbers] + - [Suggestions for improvement] + + ## Requirements Verification + - [x] Requirement 1: [Status and notes] + - [ ] Requirement 2: [Issues found] + + ## Specific Feedback by File + ### [filename] + - [Specific feedback with line references] + - [Suggestions for improvement] + + ## Recommendations + 1. [Priority 1 changes needed] + 2. [Priority 2 improvements suggested] + 3. [Optional enhancements] + + ## Decision + **RECOMMENDATION**: [APPROVE_AS_IS | REQUEST_CHANGES | NEEDS_DISCUSSION] + + **REASONING**: [Brief explanation of the recommendation] + ``` - Should I create this pull request, or would you like to request changes? - - - Yes, create the pull request as planned. - No, I need to request changes to the implementation or PR description. - Cancel the task. - - + **Completion Protocol:** + - This is your only task. Do not deviate from these instructions. + - Upon successfully saving the review feedback, you MUST use the `attempt_completion` tool. + - The `result` MUST be a concise confirmation, e.g., "PR review completed and feedback saved to .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_review_feedback.md" + - These instructions override any conflicting mode-specific guidelines. + + - 3. **Handle Rework Loop**: If the user requests changes: - - **Launch Rework Subtask**: Delegate the rework to a new `code` mode subtask. - - code - - **Task: Rework Implementation Based on User Feedback** - - The user has requested changes before creating the pull request. - - **Context Files:** - - **Issue**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json` - - **Current Plan**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md` - - **Current Modified Files**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json` - - **Draft PR Summary**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json` - - **Your Task:** - 1. Ask the user for the specific changes they require. - 2. Apply the requested code and documentation changes. - 3. **Crucially, you must update the `implementation_plan.md` and `modified_files.json` files** to reflect the rework you have performed. - 4. Do *not* proceed with any other steps. - - **Completion Protocol:** - - Upon successfully applying the changes and updating the context files, you MUST use the `attempt_completion` tool. - - The `result` MUST be a concise confirmation, e.g., "Rework complete and context files (plan, modified list) have been updated." - - - - **Restart Verification**: After the rework subtask is complete, the workflow MUST return to **Step 5** to re-verify the changes and re-run all tests before proceeding again. - - 4. **Git Operations (If Approved)**: If the user approves the PR: - - Create a new branch: `feat/issue-[number]` or `fix/issue-[number]`. - - **Selectively add only the applicable files** to the git stage. - - Commit the staged changes. - - Push the new branch to the remote repository. - - - # Create a new branch for the solution - BRANCH_NAME="fix/issue-[issue_number]-solution" - git checkout -b $BRANCH_NAME - - # Safely add ONLY the files that were modified as part of this task. - # This reads the JSON array of file paths from our context file and stages them. - # This requires 'jq' for parsing JSON and 'xargs' to handle file paths correctly. - cat .roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json | jq -r '.[]' | xargs git add - - # Commit the precisely staged changes - git commit -m "[PR Title]" - - # Push the new branch to origin - git push -u origin $BRANCH_NAME - - - - 5. **Create PR**: Use the `gh` CLI to create the pull request. - - gh pr create --repo [owner]/[repo] --base main --title "[PR Title from JSON]" --body "[PR Body from JSON]" - - - 6. **Link to Issue**: Comment on the original issue with the PR link. - - gh issue comment [issue_number] --repo [owner]/[repo] --body "PR #[new PR number] has been created." - + After the review subtask completes, read and process the feedback. - Monitor PR Checks and Cleanup + Process Review Feedback and Decide Next Steps - After creating the PR, monitor the CI checks and then clean up the temporary files. + After the PR review is complete, read the feedback and decide whether to make changes or proceed with PR creation. + + 1. **Read Review Feedback**: + + + + .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_review_feedback.md + + + + + 2. **Present Feedback to User**: Show the review feedback and ask for direction. + + + The PR review has been completed. Here is the feedback: + + --- + [Insert content of pr_review_feedback.md here] + --- + + Based on this review, how would you like to proceed? + + + Implement the suggested changes before creating the PR + Create the PR as-is, ignoring the review feedback + Discuss specific feedback points before deciding + Cancel the task + + + + 3. **Handle User Decision**: + + **If user chooses to implement changes:** + - Launch a rework subtask to address the review feedback + + code + + **Task: Address PR Review Feedback** + + The PR review has identified areas for improvement. Your task is to address the feedback before creating the pull request. + + **Context Files:** + - **Issue**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json` + - **Current Plan**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md` + - **Current Modified Files**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json` + - **Review Feedback**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_review_feedback.md` + - **Draft PR Summary**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json` + + **Your Task:** + 1. Read the review feedback carefully + 2. Address each point raised by the reviewer + 3. Make the necessary code changes + 4. Update tests if needed + 5. **Update the `modified_files.json` file** to reflect any new or changed files + 6. **Update the `implementation_plan.md`** if the approach has changed significantly + + **Important Notes:** + - Focus on the specific issues identified in the review + - Maintain the overall solution approach unless the review suggests otherwise + - Ensure all changes are properly tested + - Do not proceed with any other workflow steps + + **Completion Protocol:** + - Upon successfully addressing the feedback and updating context files, you MUST use the `attempt_completion` tool. + - The `result` MUST be a concise confirmation, e.g., "Review feedback addressed and context files updated." + + + - **After rework completion**: Return to **Step 5** (Verify and Test) to re-verify the changes + + **If user chooses to proceed as-is:** + - Continue to the next step (Create Pull Request) + + **If user wants to discuss or cancel:** + - Handle accordingly based on user input + + - 1. **Monitor Checks**: Use `--watch` to monitor CI status in real-time. - - gh pr checks [PR URL or number] --repo [owner]/[repo] --watch - + + Prepare Branch and Present PR Template + + This step prepares the branch and commits, then presents the PR template to the user for confirmation before creating the actual pull request. + + 1. Read Issue Context for Issue Number: + Use read_file to get the issue context from .roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json + + 2. Git Operations - Create branch and commit changes: + - Create a new branch: feat/issue-[number] or fix/issue-[number] + - Selectively add only the applicable files to the git stage + - Commit the staged changes + - Push the new branch to the remote repository + + Use execute_command with: + BRANCH_NAME="fix/issue-[issue_number]-solution" + git checkout -b $BRANCH_NAME + cat .roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json | jq -r '.[]' | xargs git add + git commit -m "[PR Title]" + git push -u origin $BRANCH_NAME + + 3. Present PR Template - Instead of creating the PR automatically, present the standardized PR template to the user: + Use ask_followup_question to ask: "The branch has been created and changes have been committed. I have prepared a standardized PR template for this issue. Would you like me to create the pull request using the standard Roo Code PR template, or would you prefer to make changes first?" + + Provide these options: + - Yes, create the pull request with the standard template + - No, I want to make changes to the implementation first + - No, I want to customize the PR template before creating it + - Cancel the task + + 4. Handle User Decision: + If user chooses to create the PR: Use gh CLI to create the pull request with the standard template + If user chooses to make changes: Launch a rework subtask using new_task with code mode + If user wants to customize the template: Ask for their preferred PR title and body + + 5. Link to Issue - After PR creation, comment on the original issue with the PR link using gh issue comment + + - 2. **Report Status**: Inform the user of the final status of the checks. + + Monitor PR Checks and Cleanup + + After creating the PR (if created), monitor the CI checks and then clean up the temporary files. - 3. **Cleanup**: Remove the temporary task directory. - - rm -rf .roo/temp/issue-fixer-orchestrator/[TASK_ID] - - + 1. Monitor Checks - Use gh pr checks with --watch to monitor CI status in real-time + 2. Report Status - Inform the user of the final status of the checks + 3. Cleanup - Remove the temporary task directory using rm -rf .roo/temp/issue-fixer-orchestrator/[TASK_ID] + This concludes the orchestration workflow. diff --git a/.roo/rules-issue-fixer-orchestrator/2_best_practices.xml b/.roo/rules-issue-fixer-orchestrator/2_best_practices.xml index e6251d67b23..b9a9b52db78 100644 --- a/.roo/rules-issue-fixer-orchestrator/2_best_practices.xml +++ b/.roo/rules-issue-fixer-orchestrator/2_best_practices.xml @@ -27,6 +27,17 @@ Always use `codebase_search` FIRST to understand the codebase structure and find all related files before using other tools like `read_file`. + + Critical: Understand Component Interactions + + Map the complete data flow from input to output + Identify ALL paired operations (import/export, save/load, encode/decode) + Find all consumers and dependencies of the affected code + Trace how data transformations occur throughout the system + Understand error propagation and handling patterns + + + Investigation Checklist for Bug Fixes Search for the specific error message or broken functionality. @@ -34,6 +45,8 @@ Locate related test files to understand expected behavior. Identify all dependencies and import/export patterns for the affected code. Find similar, working patterns in the codebase to use as a reference. + **CRITICAL**: For any operation being fixed, find and analyze its paired operations + Trace the complete data flow to understand all affected components @@ -42,10 +55,26 @@ Find potential integration points (e.g., API routes, UI component registries). Locate relevant configuration files that may need to be updated. Identify common patterns, components, and utilities that should be reused. + **CRITICAL**: Design paired operations together (e.g., both import AND export) + Map all data transformations and state changes + Identify all downstream consumers of the new functionality + + Always Implement Paired Operations Together + + When fixing export, ALWAYS check and update import + When modifying save, ALWAYS verify load handles the changes + When changing serialization, ALWAYS update deserialization + When updating create, consider read/update/delete operations + + + Paired operations must maintain consistency. Changes to one without the other leads to data corruption, import failures, or broken functionality. + + + - Always read multiple related files together to understand the full context, including coding conventions, testing patterns, and error handling approaches. + Always read multiple related files together to understand the full context. Never assume a change is isolated - trace its impact through the entire system. \ No newline at end of file diff --git a/.roomodes b/.roomodes index 3b178f234fa..213d7b8314a 100644 --- a/.roomodes +++ b/.roomodes @@ -9,7 +9,7 @@ customModes: - Ensuring modes have appropriate tool group permissions - Crafting clear whenToUse descriptions for the Orchestrator - Following XML structuring best practices for clarity and parseability - + You help users create new modes by: - Gathering requirements about the mode's purpose and workflow - Defining appropriate roleDefinition and whenToUse descriptions @@ -182,4 +182,3 @@ customModes: - edit - command source: project - description: Issue Fixer mode ported into an orchestrator From c4b1eca04d04816c7803b8b82798897e2b9fc003 Mon Sep 17 00:00:00 2001 From: MuriloFP Date: Thu, 17 Jul 2025 19:34:58 -0300 Subject: [PATCH 2/4] fix: allow export task history while API is active (#5324) - Add exportAlwaysEnabled prop to TaskActions component - Export button remains enabled when exportAlwaysEnabled is true - Other action buttons still respect buttonsDisabled state - Add tests to verify the new behavior This fixes the regression where users couldn't export task history during API operations, which is a common debugging workflow. --- .../src/components/chat/TaskActions.tsx | 5 +++-- webview-ui/src/components/chat/TaskHeader.tsx | 14 +++++++++++-- .../chat/__tests__/TaskActions.spec.tsx | 21 +++++++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/webview-ui/src/components/chat/TaskActions.tsx b/webview-ui/src/components/chat/TaskActions.tsx index 01340de475d..0ed88a02544 100644 --- a/webview-ui/src/components/chat/TaskActions.tsx +++ b/webview-ui/src/components/chat/TaskActions.tsx @@ -14,9 +14,10 @@ import { ShareButton } from "./ShareButton" interface TaskActionsProps { item?: HistoryItem buttonsDisabled: boolean + exportAlwaysEnabled?: boolean } -export const TaskActions = ({ item, buttonsDisabled }: TaskActionsProps) => { +export const TaskActions = ({ item, buttonsDisabled, exportAlwaysEnabled = false }: TaskActionsProps) => { const [deleteTaskId, setDeleteTaskId] = useState(null) const { t } = useTranslation() const { copyWithFeedback, showCopyFeedback } = useCopyToClipboard() @@ -27,7 +28,7 @@ export const TaskActions = ({ item, buttonsDisabled }: TaskActionsProps) => { vscode.postMessage({ type: "exportCurrentTask" })} /> {item?.task && ( diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index 1896df486b3..567ece26587 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -185,7 +185,13 @@ const TaskHeader = ({ )} - {!totalCost && } + {!totalCost && ( + + )} {((typeof cacheReads === "number" && cacheReads > 0) || @@ -213,7 +219,11 @@ const TaskHeader = ({ {t("chat:task.apiCost")} ${totalCost?.toFixed(2)} - + )} diff --git a/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx b/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx index 5db62877479..b00d68b66e2 100644 --- a/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx @@ -382,5 +382,26 @@ describe("TaskActions", () => { expect(shareButton).toBeDisabled() expect(exportButton).toBeDisabled() }) + + it("keeps export button enabled when exportAlwaysEnabled is true", () => { + render() + + // Find button by its icon class + const buttons = screen.getAllByRole("button") + const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) + const exportButton = screen.getByLabelText("Export task history") + + // Share button should still be disabled + expect(shareButton).toBeDisabled() + // Export button should be enabled despite buttonsDisabled being true + expect(exportButton).not.toBeDisabled() + }) + + it("export button works normally when exportAlwaysEnabled is false", () => { + render() + + const exportButton = screen.getByLabelText("Export task history") + expect(exportButton).toBeDisabled() + }) }) }) From a28e66afd92311aef8166d066cd7392498fdfbbb Mon Sep 17 00:00:00 2001 From: Daniel Riccio Date: Sat, 19 Jul 2025 15:42:32 -0500 Subject: [PATCH 3/4] fix: simplify export button to always be enabled The export functionality is not impacted by the model streaming state, so the button should always be enabled. Removed the unnecessary exportAlwaysEnabled prop and simplified the implementation. - Remove exportAlwaysEnabled prop from TaskActions - Remove disabled attribute from export button entirely - Update TaskHeader to remove exportAlwaysEnabled prop usage - Update tests to reflect that export is always enabled --- .../src/components/chat/TaskActions.tsx | 4 +-- webview-ui/src/components/chat/TaskHeader.tsx | 14 ++------- .../chat/__tests__/TaskActions.spec.tsx | 30 +++++++------------ 3 files changed, 14 insertions(+), 34 deletions(-) diff --git a/webview-ui/src/components/chat/TaskActions.tsx b/webview-ui/src/components/chat/TaskActions.tsx index 0ed88a02544..5a6c19aa01d 100644 --- a/webview-ui/src/components/chat/TaskActions.tsx +++ b/webview-ui/src/components/chat/TaskActions.tsx @@ -14,10 +14,9 @@ import { ShareButton } from "./ShareButton" interface TaskActionsProps { item?: HistoryItem buttonsDisabled: boolean - exportAlwaysEnabled?: boolean } -export const TaskActions = ({ item, buttonsDisabled, exportAlwaysEnabled = false }: TaskActionsProps) => { +export const TaskActions = ({ item, buttonsDisabled }: TaskActionsProps) => { const [deleteTaskId, setDeleteTaskId] = useState(null) const { t } = useTranslation() const { copyWithFeedback, showCopyFeedback } = useCopyToClipboard() @@ -28,7 +27,6 @@ export const TaskActions = ({ item, buttonsDisabled, exportAlwaysEnabled = false vscode.postMessage({ type: "exportCurrentTask" })} /> {item?.task && ( diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index 567ece26587..1896df486b3 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -185,13 +185,7 @@ const TaskHeader = ({ )} - {!totalCost && ( - - )} + {!totalCost && } {((typeof cacheReads === "number" && cacheReads > 0) || @@ -219,11 +213,7 @@ const TaskHeader = ({ {t("chat:task.apiCost")} ${totalCost?.toFixed(2)} - + )} diff --git a/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx b/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx index b00d68b66e2..2389a9c420a 100644 --- a/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx @@ -371,7 +371,7 @@ describe("TaskActions", () => { }) describe("Button States", () => { - it("disables buttons when buttonsDisabled is true", () => { + it("disables share button but keeps export button enabled when buttonsDisabled is true", () => { render() // Find button by its icon class @@ -380,28 +380,20 @@ describe("TaskActions", () => { const exportButton = screen.getByLabelText("Export task history") expect(shareButton).toBeDisabled() - expect(exportButton).toBeDisabled() - }) - - it("keeps export button enabled when exportAlwaysEnabled is true", () => { - render() - - // Find button by its icon class - const buttons = screen.getAllByRole("button") - const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) - const exportButton = screen.getByLabelText("Export task history") - - // Share button should still be disabled - expect(shareButton).toBeDisabled() - // Export button should be enabled despite buttonsDisabled being true + // Export button should always be enabled regardless of buttonsDisabled expect(exportButton).not.toBeDisabled() }) - it("export button works normally when exportAlwaysEnabled is false", () => { - render() + it("export button is always enabled regardless of buttonsDisabled state", () => { + // Test with buttonsDisabled = false + const { rerender } = render() + let exportButton = screen.getByLabelText("Export task history") + expect(exportButton).not.toBeDisabled() - const exportButton = screen.getByLabelText("Export task history") - expect(exportButton).toBeDisabled() + // Test with buttonsDisabled = true + rerender() + exportButton = screen.getByLabelText("Export task history") + expect(exportButton).not.toBeDisabled() }) }) }) From 38e3553097d40547de4065d45e5f157481942bfa Mon Sep 17 00:00:00 2001 From: Daniel Riccio Date: Sat, 19 Jul 2025 16:41:09 -0500 Subject: [PATCH 4/4] fix: enable export, share, and copy buttons during API operations - Export, share, and copy buttons now remain enabled when API is active - Delete button still respects buttonsDisabled state for safety - Removed unnecessary exportAlwaysEnabled prop - Updated tests to reflect new behavior --- .../src/components/chat/TaskActions.tsx | 3 +- .../chat/__tests__/TaskActions.spec.tsx | 35 ++++++++++++++++--- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/webview-ui/src/components/chat/TaskActions.tsx b/webview-ui/src/components/chat/TaskActions.tsx index 5a6c19aa01d..603b6be3e0c 100644 --- a/webview-ui/src/components/chat/TaskActions.tsx +++ b/webview-ui/src/components/chat/TaskActions.tsx @@ -23,7 +23,7 @@ export const TaskActions = ({ item, buttonsDisabled }: TaskActionsProps) => { return (
- + { copyWithFeedback(item.task, e)} /> )} diff --git a/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx b/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx index 2389a9c420a..68c564f8239 100644 --- a/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx @@ -371,29 +371,54 @@ describe("TaskActions", () => { }) describe("Button States", () => { - it("disables share button but keeps export button enabled when buttonsDisabled is true", () => { + it("keeps share, export, and copy buttons enabled but disables delete button when buttonsDisabled is true", () => { render() - // Find button by its icon class + // Find buttons by their labels/icons const buttons = screen.getAllByRole("button") const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) const exportButton = screen.getByLabelText("Export task history") + const copyButton = buttons.find((btn) => btn.querySelector(".codicon-copy")) + const deleteButton = screen.getByLabelText("Delete Task (Shift + Click to skip confirmation)") - expect(shareButton).toBeDisabled() - // Export button should always be enabled regardless of buttonsDisabled + // Share, export, and copy buttons should be enabled regardless of buttonsDisabled + expect(shareButton).not.toBeDisabled() expect(exportButton).not.toBeDisabled() + expect(copyButton).not.toBeDisabled() + // Delete button should respect buttonsDisabled + expect(deleteButton).toBeDisabled() }) - it("export button is always enabled regardless of buttonsDisabled state", () => { + it("share, export, and copy buttons are always enabled while delete button respects buttonsDisabled state", () => { // Test with buttonsDisabled = false const { rerender } = render() + + let buttons = screen.getAllByRole("button") + let shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) let exportButton = screen.getByLabelText("Export task history") + let copyButton = buttons.find((btn) => btn.querySelector(".codicon-copy")) + let deleteButton = screen.getByLabelText("Delete Task (Shift + Click to skip confirmation)") + + expect(shareButton).not.toBeDisabled() expect(exportButton).not.toBeDisabled() + expect(copyButton).not.toBeDisabled() + expect(deleteButton).not.toBeDisabled() // Test with buttonsDisabled = true rerender() + + buttons = screen.getAllByRole("button") + shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) exportButton = screen.getByLabelText("Export task history") + copyButton = buttons.find((btn) => btn.querySelector(".codicon-copy")) + deleteButton = screen.getByLabelText("Delete Task (Shift + Click to skip confirmation)") + + // Share, export, and copy remain enabled + expect(shareButton).not.toBeDisabled() expect(exportButton).not.toBeDisabled() + expect(copyButton).not.toBeDisabled() + // Delete button is disabled + expect(deleteButton).toBeDisabled() }) }) })