diff --git a/.roo/rules-issue-fixer-orchestrator/10_pr_template_format.xml b/.roo/rules-issue-fixer-orchestrator/10_pr_template_format.xml
deleted file mode 100644
index d16eb51424..0000000000
--- a/.roo/rules-issue-fixer-orchestrator/10_pr_template_format.xml
+++ /dev/null
@@ -1,213 +0,0 @@
-
-
- This document defines the format for PR messages that are saved to the temp folder
- before creating a pull request. The PR message is saved in two formats:
- 1. JSON format in pr_summary.json (for programmatic use)
- 2. Markdown format in pr_message.md (for manual PR creation)
-
- The PR message must follow the exact Roo Code contribution template.
-
-
-
-
- The pr_summary.json file contains the PR title and body in a structured format
- that can be easily parsed by scripts and the GitHub CLI.
-
-
- {
- "title": "fix: [description] (#[issue-number])",
- "body": "[Full markdown body as described below]",
- "issue_number": 123,
- "repo_owner": "owner",
- "repo_name": "repo",
- "base_branch": "main",
- "head_branch": "fix/issue-123-description"
- }
-
-
-
-
-
- The pr_message.md file contains the complete PR message in a format that can be
- directly copied and pasted when creating a PR manually.
-
-
- PR Title: [title from JSON]
-
- ---
-
- [Full PR body from JSON]
-
-
-
-
-
- The PR body must follow this exact Roo Code PR template with all required sections.
-
-
-
-### Related GitHub Issue
-
-
-
-Closes: #[ISSUE_NUMBER]
-
-### Roo Code Task Context (Optional)
-
-
-
-[TASK_CONTEXT]
-
-### Description
-
-
-
-[DESCRIPTION_CONTENT]
-
-### Test Procedure
-
-
-
-[TEST_PROCEDURE_CONTENT]
-
-### Pre-Submission Checklist
-
-
-
-- [x] **Issue Linked**: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
-- [x] **Scope**: My changes are focused on the linked issue (one major feature/fix per PR).
-- [x] **Self-Review**: I have performed a thorough self-review of my code.
-- [x] **Testing**: New and/or updated tests have been added to cover my changes (if applicable).
-- [x] **Documentation Impact**: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
-- [x] **Contribution Guidelines**: I have read and agree to the [Contributor Guidelines](/CONTRIBUTING.md).
-
-### Screenshots / Videos
-
-
-
-[SCREENSHOTS_CONTENT]
-
-### Documentation Updates
-
-
-
-[DOCUMENTATION_UPDATES_CONTENT]
-
-### Additional Notes
-
-
-
-[ADDITIONAL_NOTES_CONTENT]
-
-### Get in Touch
-
-
-
-[DISCORD_USERNAME]
- ]]>
-
-
-
- The GitHub issue number being fixed
- Optional Roo Code task links (remove section if not applicable)
-
- Summary of changes and implementation details. Should include:
- - Key implementation details
- - Design choices or trade-offs made
- - Specific areas reviewers should focus on
-
-
- Detailed testing steps including:
- - Unit tests added/modified
- - Manual testing steps performed
- - How reviewers can reproduce tests
- - Testing environment details
-
-
- For UI changes: before/after screenshots or video
- For non-UI changes: "N/A - No UI changes"
-
-
- Check appropriate box:
- - "- [x] No documentation updates are required." OR
- - "- [x] Yes, documentation updates are required. [describe updates]"
-
-
- Any additional context, or remove entire section if not needed
-
- User's Discord username for contact
-
-
-
-
- pr_summary.json
- .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json
- Structured data for programmatic PR creation
-
-
- pr_message.md
- .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_message.md
- Human-readable format for manual PR creation
-
-
-
-
-
- Always save both formats when preparing a PR to give users flexibility
- in how they create the pull request.
-
-
- The pr_message.md file should be self-contained and ready to copy/paste
- without any additional formatting needed.
-
-
- Include all sections in the template, maintaining the exact format
- and HTML comments as shown.
-
-
- Pre-check all checklist items that can be verified programmatically.
- Leave documentation checkbox unchecked for user to decide.
-
-
- For sections that don't apply, use appropriate placeholder text
- rather than removing the section entirely.
-
-
-
-
-
- If translations were added during the issue fix, include details in the
- Description section about which languages were updated.
-
-
-
\ No newline at end of file
diff --git a/.roo/rules-issue-fixer-orchestrator/1_Workflow.xml b/.roo/rules-issue-fixer-orchestrator/1_Workflow.xml
deleted file mode 100644
index e41d30bbda..0000000000
--- a/.roo/rules-issue-fixer-orchestrator/1_Workflow.xml
+++ /dev/null
@@ -1,874 +0,0 @@
-
-
- Initialize Task Context
-
- The user will provide a GitHub issue URL.
-
- 1. **Parse URL**: Extract the `owner`, `repo`, and `issue_number`.
- 2. **Create Task Directory**: Create a dedicated directory to store all context for this task. Use a unique identifier for the directory name, like the task ID. For example: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/`.
-
- mkdir -p .roo/temp/issue-fixer-orchestrator/[TASK_ID]
-
- 3. **Retrieve Issue Details**: Fetch the issue details and its comments as a single JSON object.
-
- gh issue view [issue_number] --repo [owner]/[repo] --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author,comments > .roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json
-
- 4. **Handle Auth Errors**: If the `gh` command fails with an authentication error, prompt the user to log in.
-
- GitHub CLI is not authenticated. Please run 'gh auth login' in your terminal, then let me know when you're ready to continue.
-
- I've authenticated, please continue
-
-
- 5. **Confirm Context**: Inform the user that the context has been saved.
-
-
-
-
- Delegate: Analyze Requirements & Explore Codebase
-
- 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`.
-
-
- architect
-
- **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 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. **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.
- - Once you have successfully written the `implementation_plan.md` file, you MUST signal your completion by using the `attempt_completion` tool.
- - The `result` parameter of `attempt_completion` MUST be a concise confirmation message, for example: "Implementation plan created and saved to .roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md."
- - These specific instructions override any conflicting general guidelines from your assigned mode.
-
-
-
- After launching the subtask, wait for it to complete. The orchestrator will then read the `implementation_plan.md` to proceed with the next step.
-
-
-
-
- Review and Approve Plan
-
- After the analysis subtask completes, the orchestrator must present the generated plan to the user for approval.
-
- 1. **Read the Plan**: Read the content of the implementation plan created by the previous subtask.
-
-
-
- .roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md
-
-
-
-
- 2. **Present for Approval**: Show the plan to the user and ask for confirmation before proceeding with implementation.
-
-
- The initial analysis is complete. Here is the proposed implementation plan:
-
- ---
- [Insert content of implementation_plan.md here]
- ---
-
- Shall I proceed with implementing this plan?
-
-
- Yes, proceed with the implementation.
- No, please modify the plan with the following changes...
- No, cancel this task.
-
-
-
- Do not proceed until the user gives explicit approval.
-
-
-
-
- Delegate: Implement Solution
-
- Once the user approves the plan, launch a new subtask in `code` mode to execute the implementation.
-
- This subtask will use the `implementation_plan.md` as its primary guide. It should write the list of modified files to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json`.
-
-
- code
-
- **Task: Implement Code Changes Based on 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`. Pay special attention to:
- - The architectural context section
- - Component interaction diagrams
- - Identified dependencies and related operations
- - Impact analysis
-
- 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 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. **Implement Tests**:
- - Write tests that verify component interactions
- - Test related operations together
- - Include edge cases and error scenarios
- - Verify data consistency across operations
-
- 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.
-
-
-
- After launching the subtask, wait for it to complete. The orchestrator will use the list of modified files for the verification and PR creation steps.
-
-
-
-
- Delegate: Verify and Test
-
- After implementation, delegate the verification and testing to a `test` mode subtask.
-
- This subtask will use the implementation plan for acceptance criteria and the list of modified files to focus its testing efforts. It will output its results to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/verification_results.md`.
-
-
- test
-
- **Task: Verify Implementation and Run Tests**
-
- You are a meticulous QA engineer. Your task is to verify an implementation against its plan and run all necessary tests.
-
- **Context Files:**
- - **Plan**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md`
- - **Modified Files**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json`
-
- **Your Steps:**
- 1. **Read Context**: Read both context files to understand the acceptance criteria and which files were changed.
- 2. **Run Tests**: Execute all relevant tests.
- - Run unit tests related to the modified files.
- - Run any relevant integration tests.
- - Run a full lint and type check.
- 3. **Verify Acceptance Criteria**: Systematically go through each acceptance criterion from the plan and verify that it has been met by the implementation.
- 4. **Write Verification Report**: Create a detailed report of your findings. The report must include:
- - A summary of the tests that were run and their results (pass/fail).
- - A checklist of all acceptance criteria and their verification status (verified/failed).
- - Details on any bugs or regressions found.
-
- 5. **Save Report**: Write the complete report to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/verification_results.md`.
-
- **Completion Protocol:**
- - This is your only task. Do not deviate.
- - Upon successfully saving `verification_results.md`, you MUST use the `attempt_completion` tool.
- - The `result` MUST be a concise confirmation, e.g., "Verification complete and results saved to .roo/temp/issue-fixer-orchestrator/[TASK_ID]/verification_results.md."
- - These instructions override any conflicting mode-specific guidelines.
-
-
-
- Wait for the subtask to complete, then review the verification results.
-
-
-
-
- Review Verification and Handle Translations
-
- After the verification subtask is complete, review the results and handle any necessary translations.
-
- 1. **Read Verification Report**:
-
-
-
- .roo/temp/issue-fixer-orchestrator/[TASK_ID]/verification_results.md
-
-
-
-
- 2. **Check for Failures**: If the report indicates any failed tests or unmet criteria, present the failures to the user and ask how to proceed.
-
-
- The verification step has failed. Here are the details:
-
- ---
- [Insert content of verification_results.md here]
- ---
-
- How should I proceed?
-
-
- Attempt to fix the failing tests and criteria.
- Ignore the failures and proceed anyway.
- Cancel the task.
-
-
-
- 3. **Analyze for Translation Needs**: If verification passed, check if translations are required.
-
- a. **Read Modified Files List**:
-
-
-
- .roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json
-
-
-
-
- b. **Identify Files Requiring Translation**:
- - Check for UI component files: `.tsx`, `.jsx` files in `webview-ui/src/` or `src/` directories
- - Check for user-facing documentation: `.md` files (especially README.md, docs/, or announcement files)
- - Check for i18n resource files: files in `src/i18n/locales/` or `webview-ui/src/i18n/locales/`
- - Check for any files containing user-visible strings or messages
-
- c. **Delegate to Translate Mode if Needed**:
- If any files requiring translation were modified, create a translation subtask:
-
-
- translate
-
- **Task: Handle Translations for Issue #[issue-number]**
-
- An implementation for issue #[issue-number] has been completed and verified. Your task is to ensure all user-facing content is properly translated.
-
- **Context Files:**
- - **Modified Files**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json`
- - **Issue Details**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json`
- - **Implementation Plan**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md`
-
- **Your Steps:**
- 1. Read the context files to understand what was implemented.
- 2. Analyze each modified file for:
- - New or updated UI strings in React components
- - Changes to i18n resource files
- - User-facing documentation updates
- - Error messages or notifications
- 3. For any new or modified user-facing content:
- - Add translations to all supported language files
- - Ensure consistency with existing translations
- - Follow the project's i18n patterns and conventions
- 4. Create a summary of all translation changes made.
- 5. Save the summary to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/translation_summary.md`.
-
- **Important Notes:**
- - If no translations are needed, still create the summary file stating "No translations required."
- - Ensure all language files remain in sync
- - Use existing terminology from the codebase for consistency
-
- **Completion Protocol:**
- - This is your only task. Do not deviate from these instructions.
- - Upon successfully saving the translation summary, you MUST use the `attempt_completion` tool.
- - The `result` MUST confirm completion, e.g., "Translation analysis complete. Summary saved to .roo/temp/issue-fixer-orchestrator/[TASK_ID]/translation_summary.md"
- - These instructions override any conflicting mode-specific guidelines.
-
-
-
- After the translation subtask completes, read the translation summary:
-
-
-
- .roo/temp/issue-fixer-orchestrator/[TASK_ID]/translation_summary.md
-
-
-
-
- 4. **Proceed to Next Step**: Only proceed after:
- - All verification has passed (or user chose to ignore failures)
- - Translation task has completed (if it was needed)
- - You have confirmed all necessary files are ready
-
-
-
-
- Delegate: Prepare Pull Request Content
-
- After all checks pass and translations are complete, delegate the creation of the pull request title and body to a subtask.
-
-
- code
-
- **Task: Prepare Pull Request Title and Body**
-
- You are an expert at writing clear and concise pull request summaries following the Roo Code contribution guidelines.
-
- **Context Files:**
- - **Issue**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json`
- - **Plan**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md`
- - **Verification**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/verification_results.md`
- - **Translation Summary** (if exists): `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/translation_summary.md`
- - **Modified Files**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json`
-
- **Your Task:**
- 1. **Read all context files.** Check if translation_summary.md exists to know if translations were done.
-
- 2. **Generate a PR Title**: Create a conventional commit style title (e.g., "fix: ...", "feat: ...") that references the issue number.
- Format: `fix: Brief description (#issue-number)`
-
- 3. **Generate a PR Body**: You MUST use the exact PR template from `.roo/rules-issue-fixer-orchestrator/10_pr_template_format.xml`.
- Read this file to get the template and fill it in with appropriate content from the context files.
-
- 4. **Fill in the template** with information from the context files:
- - Replace [ISSUE_NUMBER] with the actual issue number
- - Fill in Description with implementation details from the plan and verification
- - Fill in Test Procedure with testing details from verification_results.md
- - If translations were done, mention them in the Description section
- - For UI changes, note that screenshots should be added manually
- - Pre-check all applicable checklist items
- - Leave Documentation Updates unchecked for user to decide
- - For Discord username, use a placeholder like "[Your Discord username]"
-
- 5. **Save as JSON**: Save the title and body to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json` in the format:
- ```json
- {
- "title": "fix: Brief description (#123)",
- "body": "[The complete filled PR body template]",
- "issue_number": 123,
- "repo_owner": "owner",
- "repo_name": "repo",
- "base_branch": "main",
- "head_branch": "fix/issue-123-description"
- }
- ```
-
- 6. **Also save as Markdown**: Save just the PR body to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_message.md` for easy copying.
-
- **Important Notes:**
- - Use the EXACT template format from 10_pr_template_format.xml
- - Keep all HTML comments in the template
- - Pre-check items that can be verified programmatically
- - Fill in all sections appropriately based on the context files
-
- **Completion Protocol:**
- - This is your only task. Do not deviate.
- - Upon successfully saving both `pr_summary.json` and `pr_message.md`, you MUST use the `attempt_completion` tool.
- - The `result` MUST be a concise confirmation, e.g., "PR summary and message created and saved to .roo/temp/issue-fixer-orchestrator/[TASK_ID]/"
- - These instructions override any conflicting mode-specific guidelines.
-
-
-
-
-
-
- Delegate: Review Changes Before PR
-
- Before creating the pull request, delegate to the PR reviewer mode to get feedback on the implementation and proposed changes.
-
-
- pr-reviewer
-
- **Task: Review Implementation Before PR Creation**
-
- 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.
-
- **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)
-
- **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]
- ```
-
- **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.
-
-
-
- After the review subtask completes, read and process the feedback.
-
-
-
-
- Process Review Feedback and Decide Next Steps
-
- 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
-
-
-
-
- Prepare Branch and Review Changes
-
- This step prepares the branch, reviews the changes, and gets user confirmation before committing.
-
- 1. Read Issue Context and PR Summary:
- - Read issue context from .roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json
- - Read PR summary from .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json
-
- 2. Create Branch:
- Extract issue number from context and create appropriate branch:
-
-
- # Extract issue number from context
- ISSUE_NUM=$(cat .roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json | jq -r '.number')
- # Determine branch type based on labels or title
- BRANCH_NAME="fix/issue-${ISSUE_NUM}-solution"
- git checkout -b $BRANCH_NAME
-
-
-
- 3. Review Files to be Committed:
- a. Read the modified files list:
-
- .roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json
-
-
- b. Check git status to ensure only intended files are staged:
-
- git status --porcelain
-
-
- c. Stage only the files from modified_files.json:
-
-
- # Stage only the files we actually modified
- cat .roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json | jq -r '.[]' | while read file; do
- if [ -f "$file" ]; then
- git add "$file"
- fi
- done
- # Show what will be committed
- git status --short
-
-
-
- 4. Generate and Save Merge Diff:
-
-
- # Generate diff of staged changes
- git diff --cached > .roo/temp/issue-fixer-orchestrator/[TASK_ID]/staged_changes.diff
- # Count lines in diff
- LINE_COUNT=$(wc -l < .roo/temp/issue-fixer-orchestrator/[TASK_ID]/staged_changes.diff)
- echo "Diff contains $LINE_COUNT lines"
-
- # If diff is too large, create a summary instead
- if [ $LINE_COUNT -gt 2000 ]; then
- echo "Creating summary due to large diff size..."
- git diff --cached --stat > .roo/temp/issue-fixer-orchestrator/[TASK_ID]/staged_changes_summary.txt
- git diff --cached --name-status >> .roo/temp/issue-fixer-orchestrator/[TASK_ID]/staged_changes_summary.txt
- echo -e "\n\nNote: Full diff exceeds 2000 lines. Showing summary only." >> .roo/temp/issue-fixer-orchestrator/[TASK_ID]/staged_changes_summary.txt
- fi
-
-
-
- 5. Save PR Message to File:
- Read the PR summary and save the formatted PR message:
-
-
- # Extract title and body from pr_summary.json
- PR_TITLE=$(cat .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json | jq -r '.title')
- PR_BODY=$(cat .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json | jq -r '.body')
-
- # Save PR message to file
- echo "PR Title: $PR_TITLE" > .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_message.md
- echo -e "\n---\n" >> .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_message.md
- echo "$PR_BODY" >> .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_message.md
-
- echo "PR message saved to .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_message.md"
-
-
-
- 6. Present Changes for User Confirmation:
- Read the diff (or summary) and PR message, then ask for confirmation:
-
- a. Read the appropriate diff file:
-
- .roo/temp/issue-fixer-orchestrator/[TASK_ID]/staged_changes.diff
-
- OR (if summary exists):
-
- .roo/temp/issue-fixer-orchestrator/[TASK_ID]/staged_changes_summary.txt
-
-
- b. Read the PR message:
-
- .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_message.md
-
-
- c. Ask for user confirmation:
-
-
- I've prepared the changes for commit. Here's what will be included:
-
- **Files to be committed:**
- [List files from modified_files.json]
-
- **Changes summary:**
- [Include diff or summary content]
-
- **Proposed PR message:**
- [Include PR message content]
-
- How would you like to proceed?
-
-
- Looks good, go ahead and commit the changes
- I tested the changes, and something is wrong - let me explain...
- I still need to test the changes manually before committing
- I want to modify the PR message before proceeding
- Cancel this task
-
-
-
- 7. Handle User Decision:
- Based on user response:
-
- **If "Looks good, go ahead and commit":**
- - Proceed to commit and push:
-
-
- # Get PR title for commit message
- PR_TITLE=$(cat .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json | jq -r '.title')
- git commit -m "$PR_TITLE"
- git push -u origin $(git branch --show-current)
-
-
- - Continue to next step
-
- **If "something is wrong":**
- - Ask for details about the issue
- - Launch a fix subtask in code mode to address the problems
- - Return to Step 5 (Verify and Test) after fixes
-
- **If "need to test manually":**
- - Inform user that changes are staged but not committed
- - Provide instructions for testing
- - Wait for user to confirm testing is complete
-
- **If "modify PR message":**
- - Ask for the new PR title and body
- - Update pr_summary.json with new content
- - Return to step 5 of this workflow
-
- **If "cancel":**
- - Clean up staged changes and branch
- - End workflow
-
-
-
-
- Finalize and Create PR
-
- After user confirmation and successful commit, finalize the process.
-
- 1. Verify Push Success:
-
-
- # Verify the branch was pushed
- git branch -r | grep $(git branch --show-current)
- # Get the remote URL for PR creation
- git remote get-url origin
-
-
-
- 2. Present Final PR Creation Options:
-
-
- The changes have been committed and pushed to the branch. The PR message has been saved to:
- `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_message.md`
-
- You can now:
- 1. Create the PR manually using the saved message
- 2. Let me create the PR automatically
- 3. Make additional changes before creating the PR
-
- What would you like to do?
-
-
- Create the PR automatically using the saved message
- I'll create the PR manually - just show me the branch name
- I want to make more changes first
-
-
-
- 3. Handle Final Decision:
-
- **If "Create PR automatically":**
- - Read PR details and create:
-
-
- # Extract PR details
- PR_TITLE=$(cat .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json | jq -r '.title')
- PR_BODY=$(cat .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json | jq -r '.body')
- ISSUE_NUM=$(cat .roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json | jq -r '.number')
-
- # Create PR
- gh pr create --title "$PR_TITLE" --body "$PR_BODY" --base main
-
- # Get PR number and link to issue
- PR_NUM=$(gh pr list --head $(git branch --show-current) --json number -q '.[0].number')
- gh issue comment $ISSUE_NUM --body "PR #$PR_NUM has been created to address this issue."
-
-
-
- **If "Create manually":**
- - Show branch name and location of PR message:
-
-
- echo "Branch name: $(git branch --show-current)"
- echo "PR message saved at: .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_message.md"
- echo "You can copy the PR message from the file above when creating the PR."
-
-
-
- **If "Make more changes":**
- - Inform user they can continue working on the branch
- - Provide the task directory location for reference
-
- 4. Cleanup:
- Ask if user wants to clean up the temporary files:
-
-
- Would you like me to clean up the temporary task files now, or keep them for reference?
-
-
- Yes, clean up the temporary files
- No, keep the files for now
-
-
-
- If yes, clean up:
-
- rm -rf .roo/temp/issue-fixer-orchestrator/[TASK_ID]
-
-
-
-
-
- Monitor PR (Optional)
-
- If a PR was created automatically, offer to monitor its status.
-
- 1. Check if PR exists:
-
-
- # Check if there's a PR for the current branch
- BRANCH=$(git branch --show-current)
- gh pr list --head $BRANCH --json number,state,checks
-
-
-
- 2. If PR exists, offer monitoring:
-
-
- Would you like me to monitor the PR checks and CI status?
-
-
- Yes, monitor the PR checks
- No, I'll check it myself
-
-
-
- 3. If user wants monitoring:
-
-
- PR_NUM=$(gh pr list --head $(git branch --show-current) --json number -q '.[0].number')
- echo "Monitoring PR #$PR_NUM checks..."
- gh pr checks $PR_NUM --watch
-
-
-
- This concludes the orchestration workflow.
-
-
-
\ No newline at end of file
diff --git a/.roo/rules-issue-fixer-orchestrator/2_best_practices.xml b/.roo/rules-issue-fixer-orchestrator/2_best_practices.xml
deleted file mode 100644
index 839d862fb8..0000000000
--- a/.roo/rules-issue-fixer-orchestrator/2_best_practices.xml
+++ /dev/null
@@ -1,120 +0,0 @@
-
- - Always read the entire issue and all comments before starting
- - Follow the project's coding standards and patterns
- - Focus exclusively on addressing the issue's requirements.
- - Make minimal, high-quality changes for bug fixes. The goal is a narrow, targeted fix, not a one-line hack.
- - Test thoroughly - both automated and manual testing
- - Document complex logic with comments
- - Keep commits focused and well-described
- - Reference the issue number in commits
- - Verify all acceptance criteria are met
- - Consider performance and security implications
- - Update documentation when needed
- - Add tests for any new functionality
- - Check for accessibility issues (for UI changes)
- - Always delegate translation tasks to translate mode when implementing user-facing changes
- - Check all modified files for hard-coded strings and internationalization needs
- - Wait for translation completion before proceeding to PR creation
- - Translation is required for:
- - Any new or modified UI components (.tsx, .jsx files)
- - User-facing documentation changes (.md files)
- - Error messages and notifications
- - Any strings visible to end users
- - The translate mode will handle:
- - Adding translations to all supported language files
- - Ensuring consistency with existing terminology
- - Maintaining sync across all language resources
-
-
- Always verify files before committing
-
- - Review git status to ensure only intended files are staged
- - Stage only files listed in modified_files.json
- - Never commit unrelated changes or temporary files
- - Always get user confirmation before committing
-
-
-
- - Save full diff to staged_changes.diff for review
- - If diff exceeds 2000 lines, create a summary instead
- - Summary should include file stats and change types
- - Always inform user when showing summary vs full diff
-
-
-
- - Save PR message in both JSON and Markdown formats
- - pr_summary.json for programmatic use
- - pr_message.md for manual PR creation
- - Include all standard template sections
- - Make PR message self-contained and ready to use
-
-
-
- - Always ask for confirmation with clear options
- - First option should be "Looks good, go ahead"
- - Provide options for testing and issue reporting
- - Allow PR message modification before proceeding
- - Handle each user response appropriately
-
-
-
- - All delegated tasks must save outputs to .roo/temp/issue-fixer-orchestrator/[TASK_ID]/
- - Keep all context files until user confirms cleanup
- - Offer cleanup option after PR creation
- - Never delete files without user permission
-
-
-
- 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.
- Find all relevant error handling and logging statements.
- 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
-
-
-
- Investigation Checklist for New Features
- Search for any similar existing features to use as a blueprint.
- 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. Never assume a change is isolated - trace its impact through the entire system.
-
-
-
\ No newline at end of file
diff --git a/.roo/rules-issue-fixer-orchestrator/3_common_patterns.xml b/.roo/rules-issue-fixer-orchestrator/3_common_patterns.xml
deleted file mode 100644
index 97bba7a9e4..0000000000
--- a/.roo/rules-issue-fixer-orchestrator/3_common_patterns.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
- 1. Reproduce the issue
- 2. Identify root cause
- 3. Implement minimal fix
- 4. Add regression test
- 5. Verify fix works
- 6. Check for side effects
-
-
-
- 1. Understand all requirements
- 2. Design the solution
- 3. Implement incrementally
- 4. Test each component
- 5. Integrate components
- 6. Verify acceptance criteria
- 7. Add comprehensive tests
- 8. Update documentation
-
-
-
- 1. Review git status to identify all changes
- 2. Stage only files from modified_files.json
- 3. Generate diff for review (full or summary based on size)
- 4. Create PR message and save to temp directory
- 5. Present changes to user for confirmation
- 6. Handle user response:
- - If approved: commit and proceed to PR options
- - If issues found: return to implementation
- - If manual testing needed: wait for user
- 7. After commit, offer PR creation options:
- - Create PR automatically
- - Save PR message for manual creation
- - Skip PR creation
- 8. Optionally monitor PR and offer cleanup
-
-
\ No newline at end of file
diff --git a/.roo/rules-issue-fixer-orchestrator/4_github_cli_usage.xml b/.roo/rules-issue-fixer-orchestrator/4_github_cli_usage.xml
deleted file mode 100644
index e12fb06a5b..0000000000
--- a/.roo/rules-issue-fixer-orchestrator/4_github_cli_usage.xml
+++ /dev/null
@@ -1,221 +0,0 @@
-
-
- This mode uses the GitHub CLI (gh) for all GitHub operations.
- The mode assumes the user has gh installed and authenticated. If authentication errors occur,
- the mode will prompt the user to authenticate.
-
- Users must provide full GitHub issue URLs (e.g., https://github.com/owner/repo/issues/123)
- so the mode can extract the repository information dynamically.
-
-
-
- https://github.com/[owner]/[repo]/issues/[number]
-
- - Owner: The organization or username
- - Repo: The repository name
- - Number: The issue number
-
-
-
-
- Assume authenticated, handle errors gracefully
- Only check authentication if a gh command fails with auth error
-
- - "gh: Not authenticated"
- - "HTTP 401"
- - "HTTP 403: Resource not accessible"
-
-
-
-
-
- Retrieve the issue details at the start
- Always use first to get the full issue content
- gh issue view [issue-number] --repo [owner]/[repo] --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author
-
-
- gh issue view 123 --repo octocat/hello-world --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author
-
-
-
-
-
- Get additional context and requirements from issue comments
- Always use after viewing issue to see full discussion
- gh issue view [issue-number] --repo [owner]/[repo] --comments
-
-
- gh issue view 123 --repo octocat/hello-world --comments
-
-
-
-
-
-
- Find recent changes to affected files
- Use during codebase exploration
- gh api repos/[owner]/[repo]/commits?path=[file-path]&per_page=10
-
-
- gh api repos/octocat/hello-world/commits?path=src/api/index.ts&per_page=10 --jq '.[].sha + " " + .[].commit.message'
-
-
-
-
-
- Search for code patterns on GitHub
- Use to supplement local codebase_search
- gh search code "[search-query]" --repo [owner]/[repo]
-
-
- gh search code "function handleError" --repo octocat/hello-world --limit 10
-
-
-
-
-
-
-
- Add progress updates or ask questions on issues
- Use if clarification needed or to show progress
- gh issue comment [issue-number] --repo [owner]/[repo] --body "[comment]"
-
-
- gh issue comment 123 --repo octocat/hello-world --body "Working on this issue. Found the root cause in the theme detection logic."
-
-
-
-
-
- Find related or similar PRs
- Use to understand similar changes
- gh pr list --repo [owner]/[repo] --search "[search-terms]"
-
-
- gh pr list --repo octocat/hello-world --search "dark theme" --limit 10
-
-
-
-
-
- View the diff of a pull request
- Use to understand changes in a PR
- gh pr diff [pr-number] --repo [owner]/[repo]
-
-
- gh pr diff 456 --repo octocat/hello-world
-
-
-
-
-
-
-
- Create a pull request
- Use in step 11 after user approval
-
- - Target the repository from the provided URL
- - Use "main" as the base branch unless specified otherwise
- - Include issue number in PR title
- - Use --maintainer-can-modify flag
-
- gh pr create --repo [owner]/[repo] --base main --title "[title]" --body "[body]" --maintainer-can-modify
-
-
- gh pr create --repo octocat/hello-world --base main --title "fix: Resolve dark theme button visibility (#123)" --body "## Description
-
-Fixes #123
-
-[Full PR description]" --maintainer-can-modify
-
-
-
- If working from a fork, ensure the fork is set as the remote and push the branch there first.
- The gh CLI will automatically handle the fork workflow.
-
-
-
-
- Fork the repository if user doesn't have push access
- Use if user needs to work from a fork
- gh repo fork [owner]/[repo] --clone
-
-
- gh repo fork octocat/hello-world --clone
-
-
-
-
-
- Monitor CI/CD checks on a pull request
- Use after creating PR to ensure checks pass
- gh pr checks [pr-number] --repo [owner]/[repo] --watch
-
-
- gh pr checks 789 --repo octocat/hello-world --watch
-
-
-
-
-
-
-
- Access GitHub API directly for advanced operations
- Use when specific gh commands don't provide needed functionality
-
-
-
- gh api repos/[owner]/[repo] --jq '.default_branch'
-
-
-
-
- gh api repos/[owner]/[repo]/contents/README.md --jq '.content' | base64 -d
-
-
-
-
- gh api repos/[owner]/[repo]/actions/runs --jq '.workflow_runs[0:5] | .[] | .id, .status, .conclusion'
-
-
-
-
-
- Check GitHub Actions workflow status
- Use to monitor CI/CD pipeline
- gh run list --repo [owner]/[repo] --limit 5
-
-
- gh run list --repo octocat/hello-world --limit 5
-
-
-
-
-
-
-
- gh: Not authenticated. Run 'gh auth login' to authenticate.
-
- Ask user to authenticate:
-
- GitHub CLI is not authenticated. Please run 'gh auth login' in your terminal to authenticate, then let me know when you're ready to continue.
-
- I've authenticated, please continue
- I need help with authentication
- Let's use a different approach
-
-
-
-
-
-
- HTTP 403: Resource not accessible by integration
-
- Check if working from a fork is needed:
-
- gh repo fork [owner]/[repo] --clone
-
-
-
-
-
\ No newline at end of file
diff --git a/.roo/rules-issue-fixer-orchestrator/5_pull_request_workflow.xml b/.roo/rules-issue-fixer-orchestrator/5_pull_request_workflow.xml
deleted file mode 100644
index 03da14d8a4..0000000000
--- a/.roo/rules-issue-fixer-orchestrator/5_pull_request_workflow.xml
+++ /dev/null
@@ -1,106 +0,0 @@
-
-
- 1. Ensure all changes are committed with proper message format
- 2. Push to appropriate branch (fork or direct)
- 3. Prepare comprehensive PR description
- 4. Get user approval before creating PR
- 5. Extract owner and repo from the provided GitHub URL
-
-
-
- - Bug fixes: "fix: [description] (#[issue-number])"
- - Features: "feat: [description] (#[issue-number])"
- - Follow conventional commit format
-
-
- A comprehensive PR description is critical. The subtask responsible for preparing the PR content should generate a body that includes the following markdown structure:
-
- ```markdown
- ## Description
-
- Fixes #[issue number]
-
- [Detailed description of what was changed and why]
-
- ## Changes Made
-
- - [Specific change 1 with file references]
- - [Specific change 2 with technical details]
- - [Any refactoring or cleanup done]
-
- ## Testing
-
- - [x] All existing tests pass
- - [x] Added tests for [specific functionality]
- - [x] Manual testing completed:
- - [Specific manual test 1]
- - [Specific manual test 2]
-
- ## Translations
-
- [If translations were added/updated]
- - [x] All user-facing strings have been translated
- - [x] Updated language files: [list of languages]
- - [x] Translations reviewed for consistency
-
- [If no translations needed]
- - No user-facing string changes in this PR
-
- ## Verification of Acceptance Criteria
-
- [For each criterion from the issue, show it's met]
- - [x] Criterion 1: [How it's verified]
- - [x] Criterion 2: [How it's verified]
-
- ## Checklist
-
- - [x] Code follows project style guidelines
- - [x] Self-review completed
- - [x] Comments added for complex logic
- - [x] Documentation updated (if needed)
- - [x] No breaking changes (or documented if any)
- - [x] Accessibility checked (for UI changes)
- - [x] Translations added/updated (for UI changes)
-
- ## Screenshots/Demo (if applicable)
-
- [Add before/after screenshots for UI changes]
- [Add terminal output for CLI changes]
- ```
-
-
-
- Use a consistent format for branch names.
-
- - Bug fixes: `fix/issue-[number]-[brief-description]`
- - Features: `feat/issue-[number]-[brief-description]`
-
-
-
-
- Use GitHub CLI to create the pull request:
-
- gh pr create --repo [owner]/[repo] --base main --title "[title]" --body "[description]" --maintainer-can-modify
-
-
- If working from a fork, ensure you've forked first:
-
- gh repo fork [owner]/[repo] --clone
-
-
- The gh CLI automatically handles fork workflows.
-
-
-
- 1. Comment on original issue with PR link:
-
- gh issue comment [issue-number] --repo [owner]/[repo] --body "PR #[pr-number] has been created to address this issue"
-
- 2. Inform user of successful creation
- 3. Provide next steps and tracking info
- 4. Monitor PR checks:
-
- gh pr checks [pr-number] --repo [owner]/[repo] --watch
-
-
-
\ No newline at end of file
diff --git a/.roo/rules-issue-fixer-orchestrator/6_testing_guidelines.xml b/.roo/rules-issue-fixer-orchestrator/6_testing_guidelines.xml
deleted file mode 100644
index 721a89f2b9..0000000000
--- a/.roo/rules-issue-fixer-orchestrator/6_testing_guidelines.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
- - Always run existing tests before making changes (baseline)
- - Add tests for any new functionality
- - Add regression tests for bug fixes
- - Test edge cases and error conditions
- - Run the full test suite before completing
- - For UI changes, test in multiple themes
- - Verify accessibility (keyboard navigation, screen readers)
- - Test performance impact for large operations
-
\ No newline at end of file
diff --git a/.roo/rules-issue-fixer-orchestrator/7_communication_style.xml b/.roo/rules-issue-fixer-orchestrator/7_communication_style.xml
deleted file mode 100644
index 898269cc0c..0000000000
--- a/.roo/rules-issue-fixer-orchestrator/7_communication_style.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
- - Be clear about what you're doing at each step
- - Explain technical decisions and trade-offs
- - Ask for clarification if requirements are ambiguous
- - Provide regular progress updates for complex issues
- - Summarize changes clearly for non-technical stakeholders
- - Use issue numbers and links for reference
- - Inform the user when delegating to translate mode
- - Include translation status in progress updates
- - Mention in PR description if translations were added
-
-
- - Clearly list all files that will be committed
- - Explain when showing a summary vs full diff (>2000 lines)
- - Provide file statistics for large diffs
- - Mention that PR message has been saved to temp directory
- - Offer clear options for user to proceed or report issues
-
-
-
- - Confirm successful commit with commit hash
- - Explain PR creation options clearly
- - Mention that PR message is saved and ready to use
- - Provide path to PR message file for manual creation
- - Offer cleanup option after PR is created
-
-
\ No newline at end of file
diff --git a/.roo/rules-issue-fixer-orchestrator/8_github_communication_guidelines.xml b/.roo/rules-issue-fixer-orchestrator/8_github_communication_guidelines.xml
deleted file mode 100644
index 627908f1f7..0000000000
--- a/.roo/rules-issue-fixer-orchestrator/8_github_communication_guidelines.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- - Provide brief status updates when working on complex issues
- - Ask specific questions if requirements are unclear
- - Share findings when investigation reveals important context
- - Keep progress updates factual and concise
- - Example: "Found the root cause in the theme detection logic. Working on a fix that preserves backward compatibility."
-
-
-
- - Follow conventional commit format: "type: description (#issue-number)"
- - Keep first line under 72 characters
- - Be specific about what changed
- - Example: "fix: resolve button visibility in dark theme (#123)"
-
-
\ No newline at end of file
diff --git a/.roo/rules-issue-fixer-orchestrator/9_translation_handling.xml b/.roo/rules-issue-fixer-orchestrator/9_translation_handling.xml
deleted file mode 100644
index 15d196263c..0000000000
--- a/.roo/rules-issue-fixer-orchestrator/9_translation_handling.xml
+++ /dev/null
@@ -1,125 +0,0 @@
-
-
- The issue-fixer-orchestrator mode must ensure all user-facing content is properly translated before creating a pull request. This is achieved by delegating translation tasks to the specialized translate mode.
-
-
-
-
- Any changes to React/Vue/Angular components
-
- - webview-ui/src/**/*.tsx
- - webview-ui/src/**/*.jsx
- - src/**/*.tsx (if contains UI elements)
-
-
- - New text strings in JSX
- - Updated button labels, tooltips, or placeholders
- - Error messages displayed to users
- - Any hardcoded strings that should use i18n
-
-
-
-
- User-facing documentation changes
-
- - README.md
- - docs/**/*.md
- - webview-ui/src/components/chat/Announcement.tsx
- - Any markdown files visible to end users
-
-
-
-
- Direct changes to translation files
-
- - src/i18n/locales/**/*.json
- - webview-ui/src/i18n/locales/**/*.json
-
- When English (en) locale is updated, all other locales must be synchronized
-
-
-
- New or modified error messages
-
- - API error responses
- - Validation messages
- - System notifications
- - Status messages
-
-
-
-
-
-
- Detect Translation Needs
-
- - Read the modified_files.json from the implementation step
- - Check each file against the patterns above
- - Determine if any user-facing content was changed
-
-
-
-
- Prepare Translation Context
-
- - Gather all context files (issue details, implementation plan, modified files)
- - Identify specific strings or content that need translation
- - Note any special terminology or context from the issue
-
-
-
-
- Delegate to Translate Mode
-
- - Use new_task to create a translation subtask
- - Provide clear instructions about what needs translation
- - Include paths to all context files
- - Specify expected output (translation_summary.md)
-
-
-
-
- Verify Translation Completion
-
- - Wait for the translate mode subtask to complete
- - Read the translation_summary.md file
- - Confirm all necessary translations were handled
- - Only proceed to PR creation after confirmation
-
-
-
-
-
- Template for creating translation subtasks
-
- - Clear identification of the issue being fixed
- - List of modified files requiring translation review
- - Path to context files for understanding the changes
- - Specific instructions for what to translate
- - Expected output format and location
-
-
-
-
- Always check for translations AFTER verification passes
- Don't skip translation even for "minor" UI changes
- Ensure the translate mode has access to full context
- Wait for translation completion before creating PR
- Include translation changes in the PR description
-
-
-
-
- Assuming no translations needed without checking
- Always analyze modified files for user-facing content
-
-
- Proceeding to PR creation before translations complete
- Wait for translation_summary.md confirmation
-
-
- Not providing enough context to translate mode
- Include issue details and implementation plan
-
-
-
\ No newline at end of file
diff --git a/.roo/rules-issue-fixer/9_pr_template.xml b/.roo/rules-issue-fixer/9_pr_template.xml
new file mode 100644
index 0000000000..4c35819b1f
--- /dev/null
+++ b/.roo/rules-issue-fixer/9_pr_template.xml
@@ -0,0 +1,205 @@
+
+
+ This file contains the official Roo Code PR template that must be used when creating pull requests.
+ All PRs must follow this exact format to ensure consistency and proper documentation.
+
+
+
+
+ The PR body must follow this exact Roo Code PR template with all required sections.
+ Replace placeholder content in square brackets with actual information.
+
+
+
+### Related GitHub Issue
+
+
+
+Closes: #[ISSUE_NUMBER]
+
+### Roo Code Task Context (Optional)
+
+
+
+[TASK_CONTEXT]
+
+### Description
+
+
+
+[DESCRIPTION_CONTENT]
+
+### Test Procedure
+
+
+
+[TEST_PROCEDURE_CONTENT]
+
+### Pre-Submission Checklist
+
+
+
+- [x] **Issue Linked**: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
+- [x] **Scope**: My changes are focused on the linked issue (one major feature/fix per PR).
+- [x] **Self-Review**: I have performed a thorough self-review of my code.
+- [x] **Testing**: New and/or updated tests have been added to cover my changes (if applicable).
+- [x] **Documentation Impact**: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
+- [x] **Contribution Guidelines**: I have read and agree to the [Contributor Guidelines](/CONTRIBUTING.md).
+
+### Screenshots / Videos
+
+
+
+[SCREENSHOTS_CONTENT]
+
+### Documentation Updates
+
+
+
+[DOCUMENTATION_UPDATES_CONTENT]
+
+### Additional Notes
+
+
+
+[ADDITIONAL_NOTES_CONTENT]
+
+### Get in Touch
+
+
+
+[DISCORD_USERNAME]
+ ]]>
+
+
+
+
+ Valid GitHub CLI commands for creating PRs with the proper template
+
+
+
+ Create a PR using the filled template
+
+ The PR body should be saved to a temporary file first, then referenced with --body-file
+
+
+
+ Alternative: Create PR with inline body (for shorter content)
+
+ Use this only if the body content doesn't contain special characters that need escaping
+
+
+
+ Fork repository if user doesn't have push access
+
+ The --clone=false flag prevents cloning since we're already in the repo
+
+
+
+
+ PR titles should follow conventional commit format
+
+ fix: [brief description] (#[issue-number])
+ feat: [brief description] (#[issue-number])
+ docs: [brief description] (#[issue-number])
+ refactor: [brief description] (#[issue-number])
+ test: [brief description] (#[issue-number])
+ chore: [brief description] (#[issue-number])
+
+
+
+
+ How to fill in the template placeholders
+
+
+ The GitHub issue number being addressed
+ 123
+
+
+ Optional Roo Code task links if used during development
+ https://app.roocode.com/share/task-abc123
+ _No Roo Code task context for this PR_
+
+
+ Detailed explanation of implementation approach
+
+ - Focus on HOW you solved the problem
+ - Mention key design decisions
+ - Highlight any trade-offs made
+ - Point out areas needing special review attention
+
+
+
+ Steps to verify the changes work correctly
+
+ - List specific test commands run
+ - Describe manual testing performed
+ - Include steps for reviewers to reproduce tests
+ - Mention test environment details if relevant
+
+
+
+ Visual evidence of changes for UI modifications
+ _No UI changes in this PR_
+
+
+ Documentation impact assessment
+ - [x] No documentation updates are required.
+
+
+ Any extra context for reviewers
+ _No additional notes_
+
+
+ Discord username for communication
+ @username
+
+
+
+
\ No newline at end of file
diff --git a/.roo/rules-issue-writer/1_workflow.xml b/.roo/rules-issue-writer/1_workflow.xml
index a861bcafbb..fe2bfc2e8b 100644
--- a/.roo/rules-issue-writer/1_workflow.xml
+++ b/.roo/rules-issue-writer/1_workflow.xml
@@ -308,23 +308,31 @@
Create GitHub Issue
- Once user confirms, create the issue using the GitHub MCP tool:
+ Once user confirms, create the issue using the GitHub CLI:
-
- github
- create_issue
-
- {
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "title": "[Create a descriptive title based on the issue content]",
- "body": "[The complete formatted issue body from step 6]",
- "labels": [Use ["bug"] for bug reports or ["proposal", "enhancement"] for features]
- }
-
-
+ First, save the issue body to a temporary file:
+
+ cat > /tmp/issue_body.md << 'EOF'
+[The complete formatted issue body from step 6]
+EOF
+
- After creation, inform the user of the issue number and URL.
+ Then create the issue:
+
+ gh issue create --repo RooCodeInc/Roo-Code --title "[Create a descriptive title based on the issue content]" --body-file /tmp/issue_body.md --label "bug"
+
+
+ For feature requests, use labels "proposal,enhancement":
+
+ gh issue create --repo RooCodeInc/Roo-Code --title "[Create a descriptive title based on the issue content]" --body-file /tmp/issue_body.md --label "proposal" --label "enhancement"
+
+
+ The command will return the issue URL. Inform the user of the created issue number and URL.
+
+ Clean up the temporary file:
+
+ rm /tmp/issue_body.md
+
\ No newline at end of file
diff --git a/.roo/rules-issue-writer/5_github_cli_usage.xml b/.roo/rules-issue-writer/5_github_cli_usage.xml
new file mode 100644
index 0000000000..8beb024d15
--- /dev/null
+++ b/.roo/rules-issue-writer/5_github_cli_usage.xml
@@ -0,0 +1,273 @@
+
+
+ The GitHub CLI (gh) provides comprehensive tools for interacting with GitHub.
+ Here's when and how to use each command in the issue creation workflow.
+
+ Note: Issue body formatting should follow the templates defined in
+ 2_github_issue_templates.xml, with different formats for problem reporters
+ vs contributors.
+
+
+
+
+
+ ALWAYS use this FIRST before creating any issue to check for duplicates.
+ Search for keywords from the user's problem description.
+
+
+
+ gh issue list --repo RooCodeInc/Roo-Code --search "dark theme button visibility" --state all --limit 20
+
+
+
+ --search: Search query for issue titles and bodies
+ --state: all, open, or closed
+ --label: Filter by specific labels
+ --limit: Number of results to show
+ --json: Get structured JSON output
+
+
+
+
+
+ Use for more advanced searches across issues and pull requests.
+ Supports GitHub's advanced search syntax.
+
+
+
+ gh search issues --repo RooCodeInc/Roo-Code "dark theme button" --limit 10
+
+
+
+
+
+
+ Use when you find a potentially related issue and need full details.
+ Check if the user's issue is already reported or related.
+
+
+
+ gh issue view 123 --repo RooCodeInc/Roo-Code --comments
+
+
+
+ --comments: Include issue comments
+ --json: Get structured data
+ --web: Open in browser
+
+
+
+
+
+
+ These commands should ONLY be used if the user has indicated they want to
+ contribute the implementation. Skip these for problem reporters.
+
+
+
+
+ Get repository information and recent activity.
+
+
+
+ gh repo view RooCodeInc/Roo-Code --json defaultBranchRef,description,updatedAt
+
+
+
+
+
+
+ Check recent PRs that might be related to the issue.
+ Look for PRs that modified relevant code.
+
+
+
+ gh search prs --repo RooCodeInc/Roo-Code "dark theme" --limit 10 --state all
+
+
+
+
+
+
+ For bug reports from contributors, check recent commits that might have introduced the issue.
+ Use after cloning the repository locally.
+
+
+
+ git log --oneline --grep="theme" -n 20
+
+
+
+
+
+
+
+
+ Only use after:
+ 1. Confirming no duplicates exist
+ 2. Gathering all required information
+ 3. Determining if user is contributing or just reporting
+ 4. Getting user confirmation
+
+
+
+ gh issue create --repo RooCodeInc/Roo-Code --title "[Descriptive title of the bug]" --body-file /tmp/issue_body.md --label "bug"
+
+
+
+
+ gh issue create --repo RooCodeInc/Roo-Code --title "[Problem-focused title]" --body-file /tmp/issue_body.md --label "proposal" --label "enhancement"
+
+
+
+ --title: Issue title (required)
+ --body: Issue body text
+ --body-file: Read body from file
+ --label: Add labels (can use multiple times)
+ --assignee: Assign to user
+ --project: Add to project
+ --web: Open in browser to create
+
+
+
+
+
+
+
+ ONLY use if user wants to add additional information after creation.
+
+
+
+ gh issue comment 456 --repo RooCodeInc/Roo-Code --body "Additional context or comments."
+
+
+
+
+
+
+ Use if user realizes they need to update the issue after creation.
+ Can update title, body, or labels.
+
+
+
+ gh issue edit 456 --repo RooCodeInc/Roo-Code --title "[Updated title]" --body "[Updated body]"
+
+
+
+
+
+
+
+ After user selects issue type, immediately search for related issues:
+ 1. Use `gh issue list --search` with keywords from their description
+ 2. Show any similar issues found
+ 3. Ask if they want to continue or comment on existing issue
+
+
+
+ When searching GitHub Discussions:
+ 1. Note that GitHub CLI doesn't currently have full discussions support
+ 2. Use web search or instruct user to manually search discussions at:
+ https://github.com/RooCodeInc/Roo-Code/discussions/categories/feature-requests
+ 3. Ask user to provide any related discussion numbers they find
+ 4. Include these in the "Related Discussions" section of the issue
+
+
+
+ Decision point for contribution:
+ 1. Ask user if they want to contribute implementation
+ 2. If yes: Use contributor commands for codebase investigation
+ 3. If no: Skip directly to creating a problem-focused issue
+ 4. This saves time for problem reporters
+
+
+
+ During codebase exploration (CONTRIBUTORS ONLY):
+ 1. Clone repo locally if needed: `gh repo clone RooCodeInc/Roo-Code`
+ 2. Use `git log` to find recent changes to affected files
+ 3. Use `gh search prs` for related pull requests
+ 4. Include findings in the technical context section
+
+
+
+ When creating the issue:
+ 1. Format differently based on contributor vs problem reporter
+ 2. Problem reporters: Simple problem description + context
+ 3. Contributors: Full template with technical sections
+ 4. Save formatted body to temporary file
+ 5. Use `gh issue create` with appropriate labels
+ 6. Capture the returned issue URL
+ 7. Show user the created issue URL
+
+
+
+
+
+ When creating issues with long bodies:
+ 1. Save to temporary file: `cat > /tmp/issue_body.md << 'EOF'`
+ 2. Use --body-file flag with gh issue create
+ 3. Clean up after: `rm /tmp/issue_body.md`
+
+
+
+ Use specific search terms:
+ - Include error messages in quotes
+ - Use label filters when appropriate
+ - Limit results to avoid overwhelming output
+
+
+
+ Use --json flag for structured data when needed:
+ - Easier to parse programmatically
+ - Consistent format across commands
+ - Example: `gh issue list --json number,title,state`
+
+
+
+
+
+ If search finds exact duplicate:
+ - Show the existing issue to user using `gh issue view`
+ - Ask if they want to add a comment instead
+ - Use `gh issue comment` if they agree
+
+
+
+ If `gh issue create` fails:
+ - Check error message (auth, permissions, network)
+ - Ensure gh is authenticated: `gh auth status`
+ - Save the drafted issue content for user
+ - Suggest using --web flag to create in browser
+
+
+
+ Ensure GitHub CLI is authenticated:
+ - Check status: `gh auth status`
+ - Login if needed: `gh auth login`
+ - Select appropriate scopes for issue creation
+
+
+
+
+
+ gh issue create - Create new issue
+ gh issue list - List and search issues
+ gh issue view - View issue details
+ gh issue comment - Add comment to issue
+ gh issue edit - Edit existing issue
+ gh issue close - Close an issue
+ gh issue reopen - Reopen closed issue
+
+
+
+ gh search issues - Search issues and PRs
+ gh search prs - Search pull requests
+ gh search repos - Search repositories
+
+
+
+ gh repo view - View repository info
+ gh repo clone - Clone repository
+
+
+
\ No newline at end of file
diff --git a/.roo/rules-issue-writer/5_github_mcp_tool_usage.xml b/.roo/rules-issue-writer/5_github_mcp_tool_usage.xml
deleted file mode 100644
index b5ae5d8aec..0000000000
--- a/.roo/rules-issue-writer/5_github_mcp_tool_usage.xml
+++ /dev/null
@@ -1,352 +0,0 @@
-
-
- The GitHub MCP server provides multiple tools for interacting with GitHub.
- Here's when and how to use each tool in the issue creation workflow.
-
- Note: Issue body formatting should follow the templates defined in
- 2_github_issue_templates.xml, with different formats for problem reporters
- vs contributors.
-
-
-
-
-
- ALWAYS use this FIRST before creating any issue to check for duplicates.
- Search for keywords from the user's problem description.
-
-
-
- github
- search_issues
-
- {
- "q": "repo:RooCodeInc/Roo-Code dark theme button visibility",
- "sort": "updated",
- "order": "desc"
- }
-
-
-
-
-
-
-
- Use to browse recent issues if search doesn't find specific matches.
- Helpful for understanding issue patterns and formatting.
-
-
-
- github
- list_issues
-
- {
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "state": "all",
- "labels": ["bug"],
- "sort": "created",
- "direction": "desc",
- "perPage": 10
- }
-
-
-
-
-
-
-
- Use when you find a potentially related issue and need full details.
- Check if the user's issue is already reported or related.
-
-
-
- github
- get_issue
-
- {
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "issue_number": 123
- }
-
-
-
-
-
-
-
- Use on related issues to understand discussion context.
- Helps avoid creating issues for already-discussed topics.
-
-
-
- github
- get_issue_comments
-
- {
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "issue_number": 123
- }
-
-
-
-
-
-
-
-
- These tools should ONLY be used if the user has indicated they want to
- contribute the implementation. Skip these for problem reporters.
-
-
-
-
- For bug reports from contributors, check recent commits that might have introduced the issue.
- Look for commits touching the affected files.
-
-
-
- github
- list_commits
-
- {
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "perPage": 20
- }
-
-
-
-
-
-
-
- When you identify a potentially problematic commit.
- Get details about what changed.
-
-
-
- github
- get_commit
-
- {
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "sha": "abc123def456"
- }
-
-
-
-
-
-
-
- Use to find code patterns across the repository on GitHub.
- Complements local codebase_search tool for contributors.
-
-
-
- github
- search_code
-
- {
- "q": "repo:RooCodeInc/Roo-Code language:typescript dark theme button"
- }
-
-
-
-
-
-
-
- Check recent PRs that might be related to the issue.
- Look for PRs that modified relevant code.
-
-
-
- github
- list_pull_requests
-
- {
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "state": "all",
- "sort": "updated",
- "direction": "desc",
- "perPage": 10
- }
-
-
-
-
-
-
-
-
-
- Only use after:
- 1. Confirming no duplicates exist
- 2. Gathering all required information
- 3. Determining if user is contributing or just reporting
- 4. Getting user confirmation
-
-
-
- github
- create_issue
-
- {
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "title": "[Descriptive title of the bug]",
- "body": "[Format according to bug report template]",
- "labels": ["bug"]
- }
-
-
-
-
-
- github
- create_issue
-
- {
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "title": "[Problem-focused title]",
- "body": "[Problem description only - no technical details]",
- "labels": ["proposal", "enhancement"]
- }
-
-
-
-
-
- github
- create_issue
-
- {
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "title": "[Problem-focused title with implementation intent]",
- "body": "[Full template including technical analysis sections]",
- "labels": ["proposal", "enhancement"]
- }
-
-
-
-
-
-
-
-
-
- ONLY use if user wants to add additional information after creation.
-
-
-
- github
- add_issue_comment
-
- {
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "issue_number": 456,
- "body": "Additional context or comments."
- }
-
-
-
-
-
-
-
- Use if user realizes they need to update the issue after creation.
- Can update title, body, or state.
-
-
-
- github
- update_issue
-
- {
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "issue_number": 456,
- "title": "[Updated title if needed]",
- "body": "[Updated body if needed]"
- }
-
-
-
-
-
-
-
-
- After user selects issue type, immediately search for related issues:
- 1. Use search_issues with keywords from their description
- 2. Show any similar issues found
- 3. Ask if they want to continue or comment on existing issue
-
-
-
- When searching GitHub Discussions:
- 1. Note that GitHub MCP tools don't currently support discussions API
- 2. Instruct user to manually search discussions at:
- https://github.com/RooCodeInc/Roo-Code/discussions/categories/feature-requests
- 3. Ask user to provide any related discussion numbers they find
- 4. Include these in the "Related Discussions" section of the issue
-
-
-
- Decision point for contribution:
- 1. Ask user if they want to contribute implementation
- 2. If yes: Use contributor tools for codebase investigation
- 3. If no: Skip directly to creating a problem-focused issue
- 4. This saves time for problem reporters
-
-
-
- During codebase exploration (CONTRIBUTORS ONLY):
- 1. Use list_commits to find recent changes to affected files
- 2. Use search_code for additional code references
- 3. Check list_pull_requests for related PRs
- 4. Include findings in the technical context section
-
-
-
- When creating the issue:
- 1. Format differently based on contributor vs problem reporter
- 2. Problem reporters: Simple problem description + context
- 3. Contributors: Full template with technical sections
- 4. Use create_issue with appropriate body format
- 5. Capture the returned issue number
- 6. Show user the created issue URL
-
-
-
-
-
- If search_issues finds exact duplicate:
- - Show the existing issue to user
- - Ask if they want to add a comment instead
- - Use add_issue_comment if they agree
-
-
-
- If create_issue fails:
- - Check error message (permissions, rate limit, etc.)
- - Save the drafted issue content
- - Provide user with the content to create manually
-
-
-
- Be aware of GitHub API rate limits:
- - Authenticated requests: 5000/hour
- - Search API: 30 requests/minute
- - Use searches efficiently
-
-
-
\ No newline at end of file
diff --git a/.roo/rules-pr-fixer-orchestrator/1_Workflow.xml b/.roo/rules-pr-fixer-orchestrator/1_Workflow.xml
deleted file mode 100644
index a376596c1d..0000000000
--- a/.roo/rules-pr-fixer-orchestrator/1_Workflow.xml
+++ /dev/null
@@ -1,771 +0,0 @@
-
-
- Initialize PR Context
-
- The user will provide a GitHub PR URL or number.
-
- 1. **Parse Input**: Extract the `owner`, `repo`, and `pr_number` from the URL or use provided number.
- 2. **Create Task Directory**: Create a dedicated directory to store all context for this PR fix task.
-
- mkdir -p .roo/temp/pr-fixer-orchestrator/[TASK_ID]
-
- 3. **Retrieve PR Details**: Fetch the PR details, comments, and check status as a comprehensive JSON object.
-
- gh pr view [pr_number] --repo [owner]/[repo] --json number,title,body,state,labels,author,headRefName,baseRefName,mergeable,mergeStateStatus,isDraft,isCrossRepository,headRepositoryOwner,reviews,statusCheckRollup,comments > .roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_context.json
-
- 4. **Get Review Comments**: Fetch detailed review comments separately for better analysis.
-
- gh pr view [pr_number] --repo [owner]/[repo] --comments > .roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_comments.txt
-
- 5. **Check CI Status**: Get current check status and any failing workflows.
-
- gh pr checks [pr_number] --repo [owner]/[repo] --json name,state,conclusion,detailsUrl > .roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_checks.json
-
- 6. **Get Associated Issue**: Check if PR is linked to an issue and fetch issue details if available.
-
- gh pr view [pr_number] --repo [owner]/[repo] --json closingIssuesReferences > .roo/temp/pr-fixer-orchestrator/[TASK_ID]/linked_issues.json
-
- If linked issues exist, fetch the first issue's details:
-
- gh issue view [issue_number] --repo [owner]/[repo] --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author,comments > .roo/temp/pr-fixer-orchestrator/[TASK_ID]/issue_context.json
-
- 7. **Handle Auth Errors**: If any `gh` command fails with authentication error, prompt the user to log in.
- 8. **Confirm Context**: Inform the user that the PR context has been gathered.
-
-
-
-
- Checkout PR Branch and Initial Analysis
-
- Before delegating analysis, ensure the PR branch is checked out locally.
-
- 1. **Checkout PR Branch**: Use gh to checkout the PR branch locally.
-
- gh pr checkout [pr_number] --repo [owner]/[repo] --force
-
-
- 2. **Determine Remote Type**: Check if this is a cross-repository PR (from a fork).
-
- gh pr view [pr_number] --repo [owner]/[repo] --json isCrossRepository,headRepositoryOwner,headRefName > .roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_remote_info.json
-
-
- 3. **Setup Fork Remote if Needed**: If it's a cross-repository PR, ensure fork remote is configured.
- Read the pr_remote_info.json file. If isCrossRepository is true:
-
- git remote add fork https://github.com/[headRepositoryOwner]/[repo].git || git remote set-url fork https://github.com/[headRepositoryOwner]/[repo].git
-
-
- 4. **Fetch Latest Main**: Ensure we have the latest main branch for comparison.
-
- git fetch origin main
-
-
- 5. **Check for Conflicts**: Determine if there are merge conflicts with main.
-
- git merge-tree $(git merge-base HEAD origin/main) HEAD origin/main > .roo/temp/pr-fixer-orchestrator/[TASK_ID]/merge_conflicts.txt
-
-
- 6. **Get PR Diff**: Fetch the files changed in this PR for context.
-
- gh pr diff [pr_number] --repo [owner]/[repo] --name-only > .roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_changed_files.txt
-
-
- 7. **Check Merge Diff Size**: Get the full diff and check line count.
-
- git diff origin/main...HEAD > .roo/temp/pr-fixer-orchestrator/[TASK_ID]/full_merge_diff.txt
-
-
- wc -l .roo/temp/pr-fixer-orchestrator/[TASK_ID]/full_merge_diff.txt
-
-
- If the diff has over 2000 lines, create a summary instead:
-
- git diff origin/main...HEAD --stat > .roo/temp/pr-fixer-orchestrator/[TASK_ID]/merge_diff_summary.txt
-
-
- rm .roo/temp/pr-fixer-orchestrator/[TASK_ID]/full_merge_diff.txt
-
-
-
-
-
- Delegate: Comprehensive Requirements and PR Analysis
-
- Launch a subtask in `architect` mode to perform a detailed analysis of the PR, its underlying requirements, and all issues that need to be addressed.
-
- The context files in `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/` will be the input for this subtask.
- The subtask should write its findings to: `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_analysis_report.md`.
-
-
- architect
-
- **Task: Analyze Pull Request Requirements and Create Comprehensive Fix Plan**
-
- You are an expert software architect. Your task is to analyze a pull request, understand its underlying requirements, and create a comprehensive plan to address all issues.
-
- 1. **Read PR Context**: The PR details are in:
- - `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_context.json` - Full PR metadata
- - `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_comments.txt` - Review comments
- - `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_checks.json` - CI/CD check status
- - `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/merge_conflicts.txt` - Conflict analysis
- - `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_changed_files.txt` - Files changed in PR
- - `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/linked_issues.json` - Associated issues (if any)
- - `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/issue_context.json` - Issue details (if linked)
- - `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/full_merge_diff.txt` OR `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/merge_diff_summary.txt` - Diff information
-
- 2. **Understand the PR's Purpose**:
- - Extract the feature or bug being addressed from PR title, body, and linked issues
- - Identify the acceptance criteria (from PR description or linked issue)
- - Understand the intended functionality and expected behavior
- - Note any design decisions or architectural choices made
-
- 3. **Perform Architectural Analysis**:
- - **Map Component Interactions**: Trace the complete data flow for the PR's changes
- - **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 affect other parts of the system
-
- 4. **Explore Codebase Systematically**:
- - Use `codebase_search` FIRST to understand the feature area
- - Search for related functionality that might be affected
- - Find all files that consume or depend on the changed functionality
- - Identify configuration files, tests, and documentation that need updates
- - Study similar features to understand established patterns
-
- 5. **Analyze Review Feedback**:
- - Categorize review comments by type (bug, enhancement, style, etc.)
- - Identify which comments are actionable vs informational
- - Prioritize changes based on reviewer authority and importance
- - Note any conflicting feedback that needs clarification
-
- 6. **Investigate Failing Tests**:
- - For each failing check, determine the root cause
- - Use `gh run view --log-failed` to get detailed error logs
- - Identify if failures are due to code issues, flaky tests, or environment problems
- - Determine which files need modification to fix test failures
-
- 7. **Assess Merge Conflicts**:
- - Analyze the merge_conflicts.txt file
- - Identify which files have conflicts
- - Determine the complexity of conflict resolution
- - Plan the rebase/merge strategy
-
- 8. **Create Comprehensive Fix Plan**: The plan must include:
- - **PR Purpose Summary**: Clear description of what the PR is trying to achieve
- - **Requirements Analysis**:
- - Original requirements from issue or PR description
- - Acceptance criteria that must be met
- - Any missing functionality that needs to be added
- - **Architectural Context**:
- - Data flow diagram showing component interactions
- - List of paired operations that must be updated together
- - Dependencies and consumers of the affected functionality
- - **Issue Summary**: Clear categorization of all issues found
- - **Priority Order**: Which issues to tackle first and why
- - **Review Feedback Analysis**:
- - List of all actionable review comments
- - Specific code changes required for each
- - Any clarifications needed from reviewers
- - **Test Failure Resolution**:
- - Root cause of each failing test
- - Files and changes needed to fix
- - Any test updates required
- - **Conflict Resolution Strategy**:
- - Whether to rebase or merge
- - Order of operations for conflict resolution
- - Risk assessment of conflicts
- - **Implementation Steps**:
- - Detailed, ordered steps for fixing all issues
- - Specific commands and file modifications
- - Validation steps after each change
- - **Risk Assessment**:
- - Potential side effects of changes
- - Areas requiring extra testing
- - Backward compatibility concerns
-
- 9. **Save the Analysis**: Write the complete analysis to `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_analysis_report.md`.
-
- **Critical Requirements:**
- - Always understand the PR's underlying purpose before analyzing issues
- - Be thorough in analyzing all aspects of the PR
- - Consider the interaction between different fixes
- - Provide specific, actionable steps
- - Include exact commands where applicable
- - **IMPORTANT**: Save your analysis to the specified file in .roo/temp/pr-fixer-orchestrator/[TASK_ID]/
-
- **Completion Protocol:**
- - This is your only task. Do not deviate from these instructions.
- - Once you have successfully written the analysis report, you MUST signal completion by using the `attempt_completion` tool.
- - The `result` parameter MUST be: "PR analysis complete and saved to .roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_analysis_report.md"
-
-
-
- After launching the subtask, wait for it to complete. The orchestrator will then read the analysis report to proceed.
-
-
-
-
- Review Analysis and Get User Approval
-
- After the analysis subtask completes, present the findings to the user for approval.
-
- 1. **Read the Analysis Report**:
-
-
-
- .roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_analysis_report.md
-
-
-
-
- 2. **Present for Approval**: Show the analysis to the user and ask how to proceed.
-
-
- I've completed the analysis of PR #[pr_number]. Here's what I found:
-
- ---
- [Insert content of pr_analysis_report.md here]
- ---
-
- How would you like to proceed with fixing these issues?
-
-
- Fix all issues in the recommended priority order
- Only fix the review comments, skip failing tests for now
- Only fix failing tests and conflicts, skip review comments
- Let me choose specific issues to fix
-
-
-
- 3. **Handle User Choice**: Based on the user's selection, prepare the implementation scope.
- Save the user's choice to `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/implementation_scope.txt`
-
-
-
-
- Fetch Latest from Main and Check Differences
-
- Before implementing fixes, ensure we're working with the latest code and understand what has changed.
-
- 1. **Fetch Latest Changes**:
-
- git fetch origin main
-
-
- 2. **Analyze Differences**: Create a detailed diff report.
-
- git diff origin/main...HEAD --name-status > .roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_file_changes.txt
-
-
- 3. **Check Commit History**: Understand what commits are in this PR.
-
- git log origin/main..HEAD --oneline > .roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_commits.txt
-
-
- 4. **Identify New Commits on Main**: See what has been merged to main since the PR was created.
-
- git log HEAD..origin/main --oneline > .roo/temp/pr-fixer-orchestrator/[TASK_ID]/new_main_commits.txt
-
-
- 5. **Save Merge Strategy**: Based on the analysis, determine if we should rebase or merge.
- Create `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/merge_strategy.txt` with either "rebase" or "merge"
-
-
-
-
- Delegate: Implement Fixes
-
- Launch a subtask in `code` mode to implement all the fixes based on the analysis and user's choices.
-
-
- code
-
- **Task: Implement PR Fixes Based on Analysis**
-
- You are an expert software developer. Your task is to implement fixes for a pull request based on the analysis and plan.
-
- 1. **Read Context Files**:
- - Analysis Report: `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_analysis_report.md`
- - Implementation Scope: `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/implementation_scope.txt`
- - File Changes: `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_file_changes.txt`
- - Merge Strategy: `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/merge_strategy.txt`
-
- 2. **Handle Merge/Rebase First** (if conflicts exist):
- - If merge_strategy.txt says "rebase":
-
- GIT_EDITOR=true git rebase origin/main
-
- - If conflicts occur, resolve them by editing the conflicted files
- - Remember to escape conflict markers when using apply_diff
- - After resolving each file: `git add [file]`
- - Continue rebase: `git rebase --continue`
-
- 3. **Implement Missing Functionality** (if identified in analysis):
- - Add any missing features or functionality noted in the requirements analysis
- - Follow the architectural patterns identified in the analysis
- - Ensure all acceptance criteria are met
- - Update related operations to maintain consistency
-
- 4. **Implement Review Feedback**:
- - Address each actionable review comment from the analysis
- - Make code changes using appropriate file editing tools
- - Ensure changes follow project coding standards
- - Add comments where complex logic is introduced
-
- 5. **Fix Failing Tests**:
- - Based on the root cause analysis, fix test failures
- - This may involve fixing source code or updating tests
- - Run tests locally if possible to verify fixes
- - Document any test changes made
-
- 6. **Track All Changes**: As you make changes, maintain a list of:
- - Files modified with brief description of changes
- - Review comments addressed
- - Tests fixed
- - Missing functionality added
- - Any additional improvements made
-
- 7. **Create Change Summary**: Write a comprehensive summary to:
- `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/changes_implemented.md`
- Include:
- - List of all files modified
- - Review comments addressed (with file:line references)
- - Test fixes applied
- - Conflict resolutions performed
- - Missing functionality implemented
- - Any additional improvements
-
- **Important Reminders:**
- - Follow the implementation plan from the analysis
- - Respect the user's chosen scope
- - Make minimal, targeted changes
- - Preserve existing functionality
- - When resolving conflicts, understand both sides before choosing
- - Ensure all original PR requirements are met
- - **IMPORTANT**: Save all output files to .roo/temp/pr-fixer-orchestrator/[TASK_ID]/
-
- **Completion Protocol:**
- - Once all fixes are implemented and the summary is saved, use `attempt_completion`.
- - Result: "PR fixes implemented and summary saved to .roo/temp/pr-fixer-orchestrator/[TASK_ID]/changes_implemented.md"
-
-
-
- Wait for the implementation subtask to complete before proceeding.
-
-
-
-
- Delegate: Test and Validate Changes
-
- After implementation, delegate testing and validation to ensure all fixes work correctly.
-
-
- test
-
- **Task: Validate PR Fixes and Run Tests**
-
- You are a meticulous QA engineer. Your task is to validate that all PR fixes have been properly implemented.
-
- **Context Files:**
- - Original Analysis: `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_analysis_report.md`
- - Changes Made: `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/changes_implemented.md`
- - Original PR Checks: `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_checks.json`
-
- **Your Steps:**
- 1. **Verify Requirements**: Check that all original PR requirements and acceptance criteria are met.
-
- 2. **Verify Review Comments**: Check that each review comment marked as addressed in changes_implemented.md has been properly fixed.
-
- 3. **Run Local Tests**: Execute relevant test suites.
- - Identify test files related to changed code
- - Run unit tests for modified components
- - Run integration tests if applicable
- - Document all test results
-
- 4. **Validate Code Quality**:
- - Run linters on changed files
- - Check for type errors (if TypeScript)
- - Verify no console.logs or debug code remains
- - Ensure proper error handling
-
- 5. **Check for Regressions**:
- - Verify existing functionality still works
- - Look for potential side effects of changes
- - Test edge cases around modified code
-
- 6. **Create Validation Report**: Write findings to `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/validation_report.md`
- Include:
- - Test results summary (pass/fail counts)
- - Requirements verification checklist
- - Review comment verification checklist
- - Any issues or concerns found
- - Recommendations for additional testing
- - Overall assessment: READY or NEEDS_WORK
-
- **Critical Focus Areas:**
- - Ensure all originally failing tests now pass
- - Verify no new test failures introduced
- - Confirm review feedback properly addressed
- - Check that all PR requirements are fulfilled
- - Check for unintended consequences
- - **IMPORTANT**: Save your report to .roo/temp/pr-fixer-orchestrator/[TASK_ID]/
-
- **Completion Protocol:**
- - Save validation report and use `attempt_completion`
- - Result: "Validation complete. Report saved to .roo/temp/pr-fixer-orchestrator/[TASK_ID]/validation_report.md"
-
-
-
- Wait for validation to complete before proceeding.
-
-
-
-
- Handle Validation Results and Translation Needs
-
- Review validation results and check if translation updates are needed.
-
- 1. **Read Validation Report**:
-
-
-
- .roo/temp/pr-fixer-orchestrator/[TASK_ID]/validation_report.md
-
-
-
-
- 2. **If Validation Failed**: Present issues to user and ask how to proceed.
- If the report indicates NEEDS_WORK, use ask_followup_question to get direction.
-
- 3. **Check for Translation Requirements**:
- Read the changes_implemented.md file and check for:
- - Changes to i18n JSON files
- - Modifications to UI components with user-facing text
- - Updates to announcement files or documentation
- - New error messages or notifications
-
- 4. **Delegate Translation if Needed**:
- If translation is required:
-
- translate
-
- **Task: Update Translations for PR Fixes**
-
- PR #[pr_number] fixes have been implemented. Please handle translation updates for the following changes:
-
- **Changed Files:**
- [List specific files from changes_implemented.md that need translation]
-
- **Specific Changes:**
- [Detail what text was added/modified]
-
- Please ensure all supported languages are updated with appropriate translations.
- Save a summary of translation changes to `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/translation_summary.md`
-
- **IMPORTANT**: Save your summary to the specified file in .roo/temp/pr-fixer-orchestrator/[TASK_ID]/
-
-
-
- 5. **Proceed When Ready**: Only continue after validation passes and translations complete (if needed).
-
-
-
-
- Prepare PR Message and Get User Approval
-
- Before committing changes, prepare the PR update message and get user approval.
-
- 1. **Check Files to be Committed**: List all modified files.
-
- git status --porcelain > .roo/temp/pr-fixer-orchestrator/[TASK_ID]/files_to_commit.txt
-
-
- 2. **Read Implementation Summary**:
-
-
-
- .roo/temp/pr-fixer-orchestrator/[TASK_ID]/changes_implemented.md
-
-
-
-
- 3. **Create PR Update Message**: Based on the changes, create a comprehensive PR update message following the template.
- Save to `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_update_message.md`:
-
- ```markdown
- ## PR Update Summary
-
- This update addresses the review feedback and fixes identified issues.
-
- ## Changes Made
-
- [List from changes_implemented.md]
- - Fixed [specific issue] in [file]
- - Addressed review comment about [topic]
- - Updated tests for [functionality]
- - Resolved merge conflicts in [files]
-
- ## Review Comments Addressed
-
- [For each review comment addressed]
- - ✅ Comment: "[reviewer comment]"
- - Fix: [what was done]
- - Files: [files modified]
-
- ## Test Fixes
-
- [If tests were fixed]
- - Fixed failing test: [test name]
- - Issue: [root cause]
- - Solution: [fix applied]
-
- ## Translations Updated
-
- [If translations were updated]
- - Updated [X] language files for [changes]
- - All user-facing strings properly translated
-
- ## Verification
-
- - [x] All review comments addressed
- - [x] All tests passing locally
- - [x] No regressions introduced
- - [x] Code follows project standards
- - [x] Translations updated (if applicable)
-
- ## Files Modified
-
- [List all files that will be committed]
- ```
-
- 4. **Get User Approval**: Present the changes and ask for confirmation.
-
-
- I've completed all the fixes for PR #[pr_number]. Here's a summary of what will be committed:
-
- **Files to be committed:**
- [Content of files_to_commit.txt]
-
- **PR Update Message:**
- [Content of pr_update_message.md]
-
- Would you like me to proceed with committing these changes?
-
-
- Looks good, go ahead and commit the changes
- I tested the changes and something is wrong - let me describe the issue
- I still need to test the changes manually before committing
- Let me review specific files before committing
-
-
-
- 5. **Handle User Response**:
- - If approved: Continue to commit
- - If issues found: Document the issue and determine next steps
- - If manual testing needed: Wait for user to complete testing
- - If review requested: Show requested files and wait for approval
-
-
-
-
- Commit Changes and Prepare for Push
-
- Once user approves, commit the changes with appropriate message.
-
- 1. **Stage Only Necessary Files**: Review files and stage appropriately.
- Read files_to_commit.txt and ensure only relevant files are staged.
-
- git add [specific files from the implementation]
-
-
- Note: Do NOT use `git add -A` to avoid adding unintended files.
-
- 2. **Create Commit Message**: Based on the changes made, create an appropriate commit message.
-
- git commit -m "fix: address PR feedback and fix failing tests
-
-- addressed review comments
-- fixed failing tests
-- resolved conflicts (if applicable)
-- updated translations (if needed)
-
-See PR for detailed changes"
-
-
- 3. **Verify Remote Configuration**: Check which remote to push to.
-
-
-
- .roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_remote_info.json
-
-
-
-
- 4. **Determine Push Target**:
- - If isCrossRepository is false: push to origin
- - If isCrossRepository is true: push to fork
-
-
-
-
- Delegate: Final PR Review
-
- Before pushing changes, have the PR reviewer mode review all changes to ensure quality.
-
-
- pr-reviewer
-
- **Task: Review PR Fix Implementation**
-
- You are reviewing the fixes applied to PR #[pr_number]. Your task is to ensure all changes are high quality and properly address the original feedback.
-
- **Context Files:**
- - Original PR Analysis: `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_analysis_report.md`
- - Changes Implemented: `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/changes_implemented.md`
- - Validation Report: `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/validation_report.md`
- - Translation Summary (if exists): `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/translation_summary.md`
- - PR Update Message: `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_update_message.md`
-
- **Review Focus:**
- 1. **Completeness**: Verify all identified issues have been addressed
- 2. **Requirements**: Confirm all original PR requirements are met
- 3. **Code Quality**: Check that fixes follow best practices
- 4. **No Regressions**: Ensure no new issues introduced
- 5. **Review Feedback**: Confirm all reviewer comments properly addressed
- 6. **Test Coverage**: Verify tests cover the changes
- 7. **Documentation**: Check if docs/comments are adequate
-
- **Your Task:**
- 1. Review the actual code changes using git diff
- 2. Cross-reference with the original review feedback
- 3. Verify all PR requirements are fulfilled
- 4. Assess the quality of the implementation
- 5. Check for any missed requirements
- 6. Create a final review report
-
- Save your review to `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/final_review.md` with:
- - Overall Assessment: APPROVED or NEEDS_REVISION
- - Quality Score: 1-10
- - Detailed feedback on the implementation
- - Any remaining concerns
- - Recommendations for improvement
-
- **IMPORTANT**: Save your review to the specified file in .roo/temp/pr-fixer-orchestrator/[TASK_ID]/
-
- **Completion Protocol:**
- - Save review and use `attempt_completion`
- - Result: "Final review complete and saved to .roo/temp/pr-fixer-orchestrator/[TASK_ID]/final_review.md"
-
-
-
- Wait for the review to complete.
-
-
-
-
- Process Final Review and Push Changes
-
- Based on the final review, either push changes or address remaining issues.
-
- 1. **Read Final Review**:
-
-
-
- .roo/temp/pr-fixer-orchestrator/[TASK_ID]/final_review.md
-
-
-
-
- 2. **If Review Requests Revisions**:
- Present the feedback to the user and ask if they want to address the issues now or push as-is.
-
- 3. **Push Changes**: If approved or user chooses to push:
- Based on pr_remote_info.json, push to the correct remote:
-
- For same-repository PRs:
-
- git push --force-with-lease origin [branch_name]
-
-
- For cross-repository PRs:
-
- git push --force-with-lease fork [branch_name]
-
-
- 4. **Monitor Push Result**: Ensure the push succeeds.
- If --force-with-lease fails, fetch and retry with --force.
-
-
-
-
- Verify PR Status and Monitor Checks
-
- After pushing, verify the PR is in good state and monitor CI/CD checks.
-
- 1. **Verify PR is Up to Date**:
-
- gh pr view [pr_number] --repo [owner]/[repo] --json mergeable,mergeStateStatus
-
-
- 2. **Monitor CI/CD Checks in Real-Time**:
-
- gh pr checks [pr_number] --repo [owner]/[repo] --watch
-
- This will continuously monitor until all checks complete.
-
- 3. **Get Final Status**: Once monitoring completes, get the final state.
-
- gh pr checks [pr_number] --repo [owner]/[repo] --json name,state,conclusion > .roo/temp/pr-fixer-orchestrator/[TASK_ID]/final_checks.json
-
-
- 4. **Comment on PR**: Add a summary comment about the fixes applied.
- Read the PR update message we prepared:
-
-
-
- .roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_update_message.md
-
-
-
-
- Then post it as a comment:
-
- gh pr comment [pr_number] --repo [owner]/[repo] --body-file .roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_update_message.md
-
-
- 5. **Save PR Message**: Keep the PR message for reference.
- The PR update message has already been saved to `.roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_update_message.md`
-
- 6. **Final Summary**: Present the final status to the user, confirming:
- - All requested changes have been implemented
- - The branch is synced with main
- - CI/CD checks status
- - The PR is ready for maintainer review and merge
- - PR update message has been posted and saved
-
- 7. **Optional Cleanup**: Ask user if they want to clean up temporary files.
-
-
- PR #[pr_number] has been successfully updated!
-
- - All changes committed and pushed
- - CI/CD checks are [status]
- - PR comment posted with update summary
- - PR message saved to .roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_update_message.md
-
- Would you like me to clean up the temporary files?
-
-
- Yes, clean up temporary files
- No, keep the files for reference
-
-
-
- If user chooses cleanup:
-
- rm -rf .roo/temp/pr-fixer-orchestrator/[TASK_ID]
-
-
-
-
\ No newline at end of file
diff --git a/.roo/rules-pr-fixer-orchestrator/2_best_practices.xml b/.roo/rules-pr-fixer-orchestrator/2_best_practices.xml
deleted file mode 100644
index 82f1ba66aa..0000000000
--- a/.roo/rules-pr-fixer-orchestrator/2_best_practices.xml
+++ /dev/null
@@ -1,186 +0,0 @@
-
-
-
- Always Delegate Specialized Work
- The orchestrator coordinates but doesn't implement. Use specialized modes for analysis, coding, testing, and review.
- Each mode has specific expertise and permissions optimized for their tasks.
-
-
-
- Maintain Context Between Steps
- Use temporary files in .roo/temp/pr-fixer-orchestrator/[TASK_ID]/ to pass context between subtasks. ALL delegated tasks must save outputs to this directory.
- Subtasks run in isolation and need explicit context sharing. Files saved elsewhere will be inaccessible to subsequent steps.
-
-
-
- Get User Approval Before Committing
- ALWAYS present changes and get explicit user approval before committing. Show modified files, summarize changes, and ask for confirmation.
- Users must maintain control over what gets committed to their PR. Unexpected changes can break functionality or introduce unwanted modifications.
-
-
-
- Understand Requirements First
- Always analyze the PR's underlying purpose and requirements before fixing issues.
- Fixing review comments without understanding the feature can lead to incomplete or incorrect solutions.
-
-
-
- Handle Large Diffs Gracefully
- Check diff size before processing. If over 2000 lines, create a summary instead of including the full diff.
- Large diffs can overwhelm context windows and make analysis difficult. Summaries maintain clarity.
-
-
-
-
- - Always understand the PR's purpose and requirements first
- - Analyze before implementing - understand all issues comprehensively
- - Address review feedback with the same priority as the reviewer's authority
- - Fix root causes of test failures, not just symptoms
- - Ensure all original PR requirements are met, not just review comments
- - Resolve conflicts carefully, understanding both sides of changes
- - Validate all changes before committing to avoid breaking the PR further
- - NEVER use `git add -A` - always stage specific files intentionally
- - Get user approval before committing any changes
- - Keep commits focused and well-described
- - Always check if PR is from a fork to push to correct remote
- - Monitor CI/CD checks in real-time after pushing
- - Consider translation needs for any user-facing changes
- - Document what was changed and why in the PR update message
- - Use the EXACT PR template format specified in 6_pr_template_format.xml
-
-
-
-
- Non-Interactive Rebasing
- Always use GIT_EDITOR=true for automated rebase operations
- GIT_EDITOR=true git rebase origin/main
-
-
-
- Fork-Aware Pushing
- Always check isCrossRepository before pushing
-
- - Check if PR is from fork using gh pr view --json isCrossRepository
- - Add fork remote if needed
- - Push to correct remote (origin vs fork)
-
-
-
-
- Force with Lease
- Use --force-with-lease for safer force pushing
- If it fails, fetch and use --force
-
-
-
- Selective File Staging
- Always stage files individually, never use git add -A
-
- - Review all modified files with git status
- - Stage only files that were intentionally modified
- - Use git add [specific-file] for each file
- - Double-check staged files with git diff --cached
-
- Prevents accidentally committing temporary files, debug logs, or unintended changes
-
-
-
- Large Diff Handling
- Check diff size before including in context files
-
- - Save diff to file and check line count with wc -l
- - If over 2000 lines, create a summary instead
- - Include file counts, insertion/deletion stats
- - List most significantly changed files
-
-
-
-
-
-
- architect
- Comprehensive analysis and planning
- Detailed reports and implementation plans
- MUST save all outputs to .roo/temp/pr-fixer-orchestrator/[TASK_ID]/
-
-
-
- code
- Executing code changes and fixes
- Implemented solutions and change summaries
- MUST save changes_implemented.md to .roo/temp/pr-fixer-orchestrator/[TASK_ID]/
-
-
-
- test
- Testing and validating changes
- Test results and validation reports
- MUST save validation_report.md to .roo/temp/pr-fixer-orchestrator/[TASK_ID]/
-
-
-
- pr-reviewer
- Final quality review before submission
- Quality assessment and recommendations
- MUST save final_review.md to .roo/temp/pr-fixer-orchestrator/[TASK_ID]/
-
-
-
- translate
- Updating translations for UI changes
- Synchronized translations across languages
- MUST save translation_summary.md to .roo/temp/pr-fixer-orchestrator/[TASK_ID]/
-
-
-
-
-
- GitHub CLI authentication error
- Prompt user to run 'gh auth login'
-
-
-
- No linked issue found
- Extract requirements from PR description and comments
-
-
-
- Force-with-lease push fails
- Fetch latest and retry with --force
-
-
-
- Diff exceeds 2000 lines
- Create summary with stats instead of full diff
-
-
-
- Expected context files not found in temp directory
- Check if delegated task saved to correct location, re-run if needed
-
-
-
-
-
- Pre-Commit Approval
- Always get explicit user approval before committing changes
-
- - Show list of modified files
- - Summarize key changes made
- - Present clear approval options
- - Wait for user confirmation
-
-
-
-
- Clear Communication
- Present information clearly and concisely
-
- - Use bullet points for lists
- - Highlight important warnings
- - Provide actionable suggestions
- - Avoid technical jargon when possible
-
-
-
-
\ No newline at end of file
diff --git a/.roo/rules-pr-fixer-orchestrator/3_github_cli_usage.xml b/.roo/rules-pr-fixer-orchestrator/3_github_cli_usage.xml
deleted file mode 100644
index 94c63b6f3a..0000000000
--- a/.roo/rules-pr-fixer-orchestrator/3_github_cli_usage.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
- This mode uses the GitHub CLI (gh) for all GitHub operations.
- The mode assumes the user has gh installed and authenticated.
- It can work with PRs from both the main repository and forks.
-
-
-
-
- Get comprehensive PR details
- gh pr view [pr-number] --repo [owner]/[repo] --json [fields]
- number,title,body,state,labels,author,headRefName,baseRefName,mergeable,mergeStateStatus,isDraft,isCrossRepository,headRepositoryOwner,reviews,statusCheckRollup,comments
-
-
-
- Checkout PR branch locally
- gh pr checkout [pr-number] --repo [owner]/[repo] --force
- Automatically handles fork setup
-
-
-
- Monitor CI/CD status
- gh pr checks [pr-number] --repo [owner]/[repo] --watch
- Use --json for programmatic access
-
-
-
- Get PR changes
- gh pr diff [pr-number] --repo [owner]/[repo] --name-only
- Use without --name-only for full diff
-
-
-
- Add comment to PR
- gh pr comment [pr-number] --repo [owner]/[repo] --body "[message]"
-
-
-
-
-
- Get issues linked to PR
- gh pr view [pr-number] --repo [owner]/[repo] --json closingIssuesReferences
- Returns array of linked issues
-
-
-
- Get issue details if linked
- gh issue view [issue-number] --repo [owner]/[repo] --json [fields]
- number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author,comments
-
-
-
-
-
- Get detailed CI logs
- gh run view [run-id] --repo [owner]/[repo] --log-failed
- Use to debug failing tests
-
-
-
- Direct API access for advanced operations
-
- - Get PR reviews: gh api repos/[owner]/[repo]/pulls/[pr-number]/reviews
- - Get review comments: gh api repos/[owner]/[repo]/pulls/[pr-number]/comments
-
-
-
-
\ No newline at end of file
diff --git a/.roo/rules-pr-fixer-orchestrator/4_requirements_analysis.xml b/.roo/rules-pr-fixer-orchestrator/4_requirements_analysis.xml
deleted file mode 100644
index 5d5d5dbeb6..0000000000
--- a/.roo/rules-pr-fixer-orchestrator/4_requirements_analysis.xml
+++ /dev/null
@@ -1,120 +0,0 @@
-
-
- The PR Fixer Orchestrator must understand the underlying requirements
- of a PR before fixing issues. This ensures fixes align with the
- original intent and all acceptance criteria are met.
-
-
-
-
- Linked GitHub Issues
- Primary source of requirements and acceptance criteria
-
- - Issue title and body
- - Acceptance criteria sections
- - Technical specifications
- - User stories or use cases
-
-
-
-
- PR Description
- Often contains implementation notes and context
-
- - Feature description
- - Implementation approach
- - Testing notes
- - Breaking changes
-
-
-
-
- PR Comments
- May contain clarifications and additional requirements
-
- - Author clarifications
- - Reviewer questions and answers
- - Scope changes or additions
-
-
-
-
- Code Analysis
- Infer requirements from the implementation
-
- - API contracts
- - Data flow patterns
- - Test cases (reveal expected behavior)
- - Documentation comments
-
-
-
-
-
-
- Extract Explicit Requirements
-
- - Parse linked issues for acceptance criteria
- - Extract requirements from PR description
- - Identify success metrics
-
-
-
-
- Understand Implementation Intent
-
- - Analyze the code changes to understand approach
- - Identify design decisions made
- - Note any architectural patterns used
-
-
-
-
- Map Requirements to Implementation
-
- - Verify each requirement has corresponding code
- - Identify any missing functionality
- - Note any extra functionality added
-
-
-
-
- Identify Gaps
-
- - List unimplemented requirements
- - Note incomplete features
- - Identify missing tests
-
-
-
-
-
-
-
- - Clear description of the bug
- - Steps to reproduce
- - Expected vs actual behavior
- - Affected versions/environments
-
-
-
-
-
- - Feature description
- - User stories or use cases
- - API design (if applicable)
- - UI/UX specifications
- - Performance requirements
-
-
-
-
-
- - Motivation for refactoring
- - Backward compatibility needs
- - Performance improvements expected
- - Migration path (if breaking)
-
-
-
-
\ No newline at end of file
diff --git a/.roo/rules-pr-fixer-orchestrator/5_self_contained_workflow.xml b/.roo/rules-pr-fixer-orchestrator/5_self_contained_workflow.xml
deleted file mode 100644
index 62be497ea4..0000000000
--- a/.roo/rules-pr-fixer-orchestrator/5_self_contained_workflow.xml
+++ /dev/null
@@ -1,99 +0,0 @@
-
-
- The PR Fixer Orchestrator must be completely self-contained and able
- to work on any PR without requiring pre-existing context files from
- other workflows like the Issue Fixer.
-
-
-
-
- No External Dependencies
- Never assume files from other workflows exist
-
- - Create own temp directory structure
- - Gather all needed context independently
- - Generate own analysis and plans
-
-
-
-
- Complete Context Gathering
- Collect all information needed for the task
-
- - Fetch PR details and metadata
- - Get linked issues if they exist
- - Analyze codebase independently
- - Understand requirements from available sources
-
-
-
-
- Flexible Requirements Analysis
- Work with whatever information is available
-
- - Use linked issues when available
- - Fall back to PR description
- - Infer from code changes if needed
- - Ask user for clarification when necessary
-
-
-
-
-
- Create dedicated task directory
- Fetch all PR-related information
- Check for linked issues and fetch if present
- Analyze PR changes to understand scope
- Build complete context from available sources
-
-
-
-
- PR that references a GitHub issue
-
- - Fetch issue details for requirements
- - Use issue acceptance criteria
- - Cross-reference PR implementation with issue requirements
-
-
-
-
- PR without linked issue
-
- - Extract requirements from PR description
- - Analyze code to understand intent
- - Use PR comments for additional context
- - Infer acceptance criteria from tests
-
-
-
-
- PR from a forked repository
-
- - Handle remote configuration properly
- - Ensure push targets correct repository
- - Manage permissions appropriately
-
-
-
-
-
-
- No clear requirements found
-
- - Analyze code changes to infer purpose
- - Look at test changes for expected behavior
- - Ask user for clarification if needed
-
-
-
-
- PR scope is ambiguous
-
- - Present findings to user
- - Ask for specific guidance on what to fix
- - Proceed with user-defined scope
-
-
-
-
\ No newline at end of file
diff --git a/.roo/rules-pr-fixer-orchestrator/6_pr_template_format.xml b/.roo/rules-pr-fixer-orchestrator/6_pr_template_format.xml
deleted file mode 100644
index 26129553c3..0000000000
--- a/.roo/rules-pr-fixer-orchestrator/6_pr_template_format.xml
+++ /dev/null
@@ -1,361 +0,0 @@
-
-
- This file defines the EXACT PR message template that must be used when updating
- pull requests. The format is specific to the Roo Code project and must be followed
- precisely.
-
-
-
-
-
-### Related GitHub Issue
-
-
-
-Closes: #[ISSUE_NUMBER]
-
-### Roo Code Task Context (Optional)
-
-
-
-[TASK_CONTEXT_IF_APPLICABLE]
-
-### Description
-
-
-
-[DESCRIPTION_OF_CHANGES]
-
-### Test Procedure
-
-
-
-[TEST_PROCEDURE_DETAILS]
-
-### Pre-Submission Checklist
-
-
-
-- [x] **Issue Linked**: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
-- [x] **Scope**: My changes are focused on the linked issue (one major feature/fix per PR).
-- [x] **Self-Review**: I have performed a thorough self-review of my code.
-- [x] **Testing**: New and/or updated tests have been added to cover my changes (if applicable).
-- [x] **Documentation Impact**: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
-- [x] **Contribution Guidelines**: I have read and agree to the [Contributor Guidelines](/CONTRIBUTING.md).
-
-### Screenshots / Videos
-
-
-
-[SCREENSHOTS_OR_VIDEOS_IF_UI_CHANGES]
-
-### Documentation Updates
-
-
-
-[DOCUMENTATION_UPDATE_STATUS]
-
-### Additional Notes
-
-
-
-[ADDITIONAL_NOTES]
-
-### Get in Touch
-
-
-
-[DISCORD_USERNAME]
- ]]>
-
-
-
-
- The GitHub issue number this PR closes
- From linked_issues.json or pr_context.json
-
-
-
- Optional Roo Code task links if used
- _No Roo Code task context for this PR._
-
-
-
- Summary of changes and implementation details
-
- This PR addresses the review feedback and fixes identified issues for #[PR_NUMBER].
-
- **Key Changes:**
- - [List major changes from changes_implemented.md]
- - [Implementation details and design choices]
- - [Trade-offs or decisions made]
-
- **Review Comments Addressed:**
- [Summary of addressed review comments]
-
- **Test Failures Fixed:**
- [Summary of test fixes if applicable]
-
- **Conflicts Resolved:**
- [Summary of conflict resolutions if applicable]
-
-
-
-
- How the changes were tested
-
- **Testing performed:**
- 1. Ran all unit tests locally: `[test command used]`
- 2. Ran integration tests: `[test command used]`
- 3. Manual testing steps:
- - [Step 1]
- - [Step 2]
- - [Step 3]
-
- **To verify these changes:**
- 1. Check out this branch
- 2. Run `[specific test commands]`
- 3. [Additional verification steps]
-
- **Test Environment:**
- - Node.js version: [version]
- - OS: [operating system]
- - [Other relevant environment details]
-
-
-
-
- Visual evidence of UI changes
- _No UI changes in this PR._
-
-
-
- Documentation impact assessment
-
-
-
-
-
-
-
- Any additional context for reviewers
-
- [Any special considerations, known issues, or questions for reviewers]
-
- **Files Modified:**
- ```
- [List of modified files from changes_implemented.md]
- ```
-
-
-
-
- Contact information
- Discord: @[username]
-
-
-
-
-
- The template MUST be followed exactly - do not modify the structure or remove any sections
-
-
- All placeholders must be replaced with actual content - no brackets should remain
-
-
- The Pre-Submission Checklist items should all be marked as checked [x] since we're fixing an existing PR
-
-
- Pull information from:
- - changes_implemented.md for the description and file list
- - validation_report.md for test results
- - pr_context.json for issue numbers and PR details
- - translation_summary.md for any translation updates
-
-
- Keep the HTML comments intact - they provide guidance for reviewers
-
-
-
-
- .roo/temp/pr-fixer-orchestrator/[TASK_ID]/pr_update_message.md
-
- - Used as the PR comment body when updating the PR
- - Saved for reference and audit trail
- - Can be edited by user before posting
- - Should NOT be deleted even if temp files are cleaned
-
-
- Post to PR using: gh pr comment [pr_number] --repo [owner]/[repo] --body-file [path_to_file]
-
-
-
-
-
-
-### Related GitHub Issue
-
-
-
-Closes: #456
-
-### Roo Code Task Context (Optional)
-
-
-
-_No Roo Code task context for this PR._
-
-### Description
-
-
-
-This PR addresses the review feedback and fixes identified issues for #789.
-
-**Key Changes:**
-- Fixed TypeScript type errors in the API handler by adding proper type annotations
-- Improved error handling in the authentication flow to handle edge cases
-- Refactored complex functions for better testability and maintainability
-- Added missing user role management functionality
-- Resolved merge conflicts with the latest main branch
-
-**Review Comments Addressed:**
-- Added timeout handling with exponential backoff for network requests
-- Refactored large functions into smaller, testable units
-- Added comprehensive TypeScript interfaces for API responses
-- Improved error messages for better debugging
-
-**Test Failures Fixed:**
-- Updated email validation tests to match new validation rules
-- Fixed mock server responses in integration tests
-- Added missing test coverage for new functionality
-
-### Test Procedure
-
-
-
-**Testing performed:**
-1. Ran all unit tests locally: `npm test`
-2. Ran integration tests: `npm run test:integration`
-3. Manual testing steps:
- - Created new user with various role types
- - Tested authentication flow with invalid credentials
- - Verified timeout handling with slow network simulation
-
-**To verify these changes:**
-1. Check out this branch
-2. Run `npm install && npm test`
-3. Start the dev server with `npm run dev`
-4. Test the authentication flow at http://localhost:3000/login
-
-**Test Environment:**
-- Node.js version: 18.17.0
-- OS: Windows 11
-- Browser: Chrome 120
-
-### Pre-Submission Checklist
-
-
-
-- [x] **Issue Linked**: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
-- [x] **Scope**: My changes are focused on the linked issue (one major feature/fix per PR).
-- [x] **Self-Review**: I have performed a thorough self-review of my code.
-- [x] **Testing**: New and/or updated tests have been added to cover my changes (if applicable).
-- [x] **Documentation Impact**: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
-- [x] **Contribution Guidelines**: I have read and agree to the [Contributor Guidelines](/CONTRIBUTING.md).
-
-### Screenshots / Videos
-
-
-
-_No UI changes in this PR._
-
-### Documentation Updates
-
-
-
-- [x] No documentation updates are required.
-
-### Additional Notes
-
-
-
-All review feedback has been addressed. The main architectural change was refactoring the authentication service to use dependency injection, which improves testability.
-
-**Files Modified:**
-```
-src/api/handler.ts - Added type annotations, improved error handling
-src/services/auth.service.ts - Refactored for dependency injection
-src/services/user.service.ts - Added role management functionality
-src/types/api.types.ts - New TypeScript interfaces
-src/__tests__/services/auth.service.test.ts - Updated tests
-src/__tests__/integration/api.test.ts - Fixed mock responses
-```
-
-### Get in Touch
-
-
-
-Discord: @contributor123
- ]]>
-
-
\ No newline at end of file
diff --git a/.roo/rules-pr-fixer/1_workflow.xml b/.roo/rules-pr-fixer/1_workflow.xml
index 4b43e99217..db74ead7ee 100644
--- a/.roo/rules-pr-fixer/1_workflow.xml
+++ b/.roo/rules-pr-fixer/1_workflow.xml
@@ -1,6 +1,6 @@
- This mode is designed to help resolve issues in existing pull requests. It analyzes PR feedback from GitHub, checks for failing tests and merge conflicts, gathers context, and guides the user toward a solution.
+ This mode is designed to help resolve issues in existing pull requests. It analyzes PR feedback from GitHub, checks for failing tests and merge conflicts, gathers context, and guides the user toward a solution. All GitHub operations are performed using the GitHub CLI.
@@ -13,9 +13,9 @@
Gather PR context
- use_mcp_tool (github): get_pull_request, get_pull_request_comments
- gh cli: Check workflow status and logs for failing tests.
- gh cli: Check for merge conflicts.
+ gh pr view [PR_NUMBER] --repo [owner]/[repo] --json number,title,author,state,body,url,headRefName,baseRefName,files,additions,deletions,changedFiles,comments,reviews
+ gh pr checks [PR_NUMBER] --repo [owner]/[repo] - Check workflow status for failing tests
+ gh pr view [PR_NUMBER] --repo [owner]/[repo] --json mergeable,mergeStateStatus - Check for merge conflicts
@@ -24,9 +24,9 @@
Analyze the gathered information to identify the core problems.
- Summarize review comments and requested changes.
- Identify the root cause of failing tests by analyzing logs.
- Determine if merge conflicts exist.
+ Summarize review comments and requested changes from gh pr view output.
+ Identify the root cause of failing tests by analyzing workflow logs with 'gh run view'.
+ Determine if merge conflicts exist from mergeable status.
@@ -41,13 +41,16 @@
Execute the user's chosen course of action.
- Check out the PR branch locally using 'gh pr checkout --force'.
- Determine if the PR is from a fork by checking 'gh pr view --json isCrossRepository'.
+ Check out the PR branch locally using 'gh pr checkout [PR_NUMBER] --repo [owner]/[repo] --force'.
+ Determine if the PR is from a fork by checking 'gh pr view [PR_NUMBER] --repo [owner]/[repo] --json isCrossRepository'.Apply code changes based on review feedback using file editing tools.Fix failing tests by modifying test files or source code as needed.For conflict resolution: Use GIT_EDITOR=true for non-interactive rebases, then resolve conflicts via file editing.If changes affect user-facing content (i18n files, UI components, announcements), delegate translation updates using the new_task tool with translate mode.
- Commit changes using git commands.
+ Review modified files with 'git status --porcelain' to ensure no temporary files are included.
+ Stage files selectively using 'git add -u' (for modified tracked files) or 'git add ' (for new files).
+ Verify staged files with 'git diff --cached --name-only' before committing.
+ Commit changes using git commands with descriptive messages.Push changes to the correct remote (origin for same-repo PRs, fork remote for cross-repo PRs) using 'git push --force-with-lease'.
@@ -55,10 +58,10 @@
Verify that the pushed changes resolve the issues.
- Use 'gh pr checks --watch' to monitor check status in real-time until all checks complete.
- If needed, check specific workflow runs with 'gh run list --pr' for detailed CI/CD pipeline status.
+ Use 'gh pr checks [PR_NUMBER] --repo [owner]/[repo] --watch' to monitor check status in real-time until all checks complete.
+ If needed, check specific workflow runs with 'gh run list --pr [PR_NUMBER] --repo [owner]/[repo]' for detailed CI/CD pipeline status.Verify that all translation updates (if any) have been completed and committed.
- Confirm PR is ready for review by checking mergeable state with 'gh pr view --json'.
+ Confirm PR is ready for review by checking mergeable state with 'gh pr view [PR_NUMBER] --repo [owner]/[repo] --json mergeable,mergeStateStatus'.
diff --git a/.roo/rules-pr-fixer/2_best_practices.xml b/.roo/rules-pr-fixer/2_best_practices.xml
index e9ef4a8b27..50a8395b9c 100644
--- a/.roo/rules-pr-fixer/2_best_practices.xml
+++ b/.roo/rules-pr-fixer/2_best_practices.xml
@@ -20,6 +20,23 @@
Always push to origin without checking PR source
+
+ Safe File Staging
+ Always review files before staging to avoid committing temporary files, build artifacts, or system files. Use selective git commands that respect .gitignore.
+ Committing unwanted files can expose sensitive data, clutter the repository, and cause CI/CD failures.
+
+ Staging files for commit
+ Use 'git add -u' to stage only modified tracked files, or explicitly list files to add
+ Use 'git add .' which stages everything including temp files
+
+
+ Review git status before staging
+ Check for temporary files (.swp, .DS_Store, *.tmp)
+ Exclude build artifacts (dist/, build/, *.pyc)
+ Avoid IDE-specific files (.idea/, .vscode/)
+ Verify .gitignore is properly configured
+
+
diff --git a/.roo/rules-pr-fixer/3_common_patterns.xml b/.roo/rules-pr-fixer/3_common_patterns.xml
index 5d2c7f033f..1c6c0bcf65 100644
--- a/.roo/rules-pr-fixer/3_common_patterns.xml
+++ b/.roo/rules-pr-fixer/3_common_patterns.xml
@@ -101,10 +101,42 @@
- Commit operations that work in automated environments.
+ Commit operations that work in automated environments while respecting .gitignore.
- git add .
+ Review what files have been modified
+ git status --porcelain
+ Add only tracked files that were modified (respects .gitignore)
+ git add -u
+ If you need to add specific new files, list them explicitly
+ git add git commit -m ""
+
+ Safely stage files for commit while avoiding temporary files and respecting .gitignore.
+
+ First, check what files are currently modified or untracked
+ git status --porcelain
+ Review the output to identify files that should NOT be committed:
+ - Files starting with . (hidden files like .DS_Store, .swp)
+ - Build artifacts (dist/, build/, *.pyc, *.o)
+ - IDE files (.idea/, .vscode/, *.iml)
+ - Temporary files (*.tmp, *.temp, *~)
+
+ Option 1: Stage only modified tracked files (safest)
+ git add -u
+
+ Option 2: Stage specific files by path
+ git add src/file1.ts src/file2.ts
+
+ Option 3: Use pathspec to add files matching a pattern
+ git add '*.ts' '*.tsx' --
+
+ Option 4: Interactive staging to review each change
+ git add -p
+
+ Always verify what's staged before committing
+ git diff --cached --name-only
+
+
diff --git a/.roo/rules-pr-fixer/4_tool_usage.xml b/.roo/rules-pr-fixer/4_tool_usage.xml
index 15833f3dd7..90d20a0382 100644
--- a/.roo/rules-pr-fixer/4_tool_usage.xml
+++ b/.roo/rules-pr-fixer/4_tool_usage.xml
@@ -1,7 +1,7 @@
- use_mcp_tool (server: github)
+ gh pr viewUse at the start to get all review comments and PR metadata.Provides the core context of what needs to be fixed from a human perspective.
@@ -23,14 +23,16 @@
-
+
- Always fetch details to get the branch name, owner, repo slug, and mergeable state.
+ Always fetch details with --json to get structured data: gh pr view [PR_NUMBER] --repo [owner]/[repo] --json number,title,author,state,body,url,headRefName,baseRefName,files,additions,deletions,changedFiles,comments,reviews,mergeable,mergeStateStatus,isCrossRepository
+ Parse the JSON output to extract branch name, owner, repo slug, and mergeable state.
-
+
+ Use gh pr view --json comments to get all comments in structured format.Parse all comments to create a checklist of required changes.Ignore comments that are not actionable or have been resolved.
@@ -40,14 +42,15 @@
Use this command to get the exact error messages from failing tests.Search the log for keywords like 'error', 'failed', or 'exception' to quickly find the root cause.
- Always specify run ID explicitly to avoid interactive selection prompts.
+ Always specify run ID explicitly to avoid interactive selection prompts: gh run view [RUN_ID] --log-failed
+ Get run IDs with: gh run list --pr [PR_NUMBER] --repo [owner]/[repo]
- Use --force flag: 'gh pr checkout --force'
- If gh checkout fails, use: git fetch origin pull//head:
+ Use --force flag: 'gh pr checkout [PR_NUMBER] --repo [owner]/[repo] --force'
+ If gh checkout fails, use: git fetch origin pull/[PR_NUMBER]/head:[branch_name]
@@ -58,9 +61,9 @@
Always determine the correct remote before pushing (origin vs fork).
- Check if PR is from a fork: 'gh pr view --json isCrossRepository'
+ Check if PR is from a fork: 'gh pr view [PR_NUMBER] --repo [owner]/[repo] --json isCrossRepository'If isCrossRepository is true, add fork remote if needed
- Push to appropriate remote: 'git push --force-with-lease '
+ Push to appropriate remote: 'git push --force-with-lease [remote] [branch]'Use 'GIT_EDITOR=true git rebase main' to start rebase
@@ -71,10 +74,10 @@
- Use --watch flag to monitor checks in real-time: 'gh pr checks --watch'
- For one-time status checks, use --json flag: 'gh pr checks --json state,conclusion,name'
+ Use --watch flag to monitor checks in real-time: 'gh pr checks [PR_NUMBER] --repo [owner]/[repo] --watch'
+ For one-time status checks, use --json flag: 'gh pr checks [PR_NUMBER] --repo [owner]/[repo] --json state,conclusion,name'The --watch flag automatically updates the display as check statuses change.
- Use 'gh run list --pr ' to get detailed workflow status if needed.
+ Use 'gh run list --pr [PR_NUMBER] --repo [owner]/[repo]' to get detailed workflow status if needed.
@@ -115,4 +118,19 @@ Please ensure all supported languages (ca, de, es, fr, hi, id, it, ja, ko, nl, p
]]>
+
+
+
+ gh pr view [PR_NUMBER] --repo [owner]/[repo] --json [fields]
+ gh pr checkout [PR_NUMBER] --repo [owner]/[repo] --force
+ gh pr checks [PR_NUMBER] --repo [owner]/[repo] [--watch|--json]
+ gh pr comment [PR_NUMBER] --repo [owner]/[repo] --body "[text]"
+
+
+
+ gh run list --pr [PR_NUMBER] --repo [owner]/[repo]
+ gh run view [RUN_ID] --repo [owner]/[repo] --log-failed
+ gh workflow view [WORKFLOW_NAME] --repo [owner]/[repo]
+
+
\ No newline at end of file
diff --git a/.roo/rules-pr-fixer/5_examples.xml b/.roo/rules-pr-fixer/5_examples.xml
index 0ff98de250..03fa287c16 100644
--- a/.roo/rules-pr-fixer/5_examples.xml
+++ b/.roo/rules-pr-fixer/5_examples.xml
@@ -12,28 +12,9 @@
Get PR details and review comments.
-
- github
- get_pull_request
-
- {
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "pullNumber": 4365
- }
-
-
-
- github
- get_pull_request_comments
-
- {
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "pullNumber": 4365
- }
-
-
+
+gh pr view 4365 --repo RooCodeInc/Roo-Code --json number,title,author,state,body,url,headRefName,baseRefName,files,additions,deletions,changedFiles,comments,reviews,mergeable,mergeStateStatus
+Get the branch name, list of review comments, and check for mergeability.
@@ -42,7 +23,7 @@
Check CI status.
-gh pr checks 4365
+gh pr checks 4365 --repo RooCodeInc/Roo-CodeIdentify which check is failing.
@@ -52,7 +33,17 @@
Get logs for the failing check.
-gh run view --log-failed
+gh run list --pr 4365 --repo RooCodeInc/Roo-Code
+
+
+ Get the run ID of the failing workflow.
+
+
+
+ View the failed logs.
+
+
+gh run view [run_id] --repo RooCodeInc/Roo-Code --log-failedFind the specific error message causing the test to fail.
@@ -62,7 +53,7 @@
Check out the pull request branch.
- gh pr checkout 4365 --force
+ gh pr checkout 4365 --repo RooCodeInc/Roo-Code --forceThe PR branch is now ready for local edits.
@@ -85,7 +76,7 @@
After pushing the changes, monitor PR checks in real-time.
- gh pr checks 4365 --watch
+ gh pr checks 4365 --repo RooCodeInc/Roo-Code --watchMonitor checks continuously until all complete. The --watch flag provides real-time updates as check statuses change.
@@ -94,7 +85,8 @@
Always gather all information before proposing a solution.
- Use a combination of the GitHub MCP server and the `gh` CLI to get a complete picture of the PR's status.
+ Use the GitHub CLI to get a complete picture of the PR's status.
+ The --watch flag on gh pr checks provides real-time monitoring of CI status.
@@ -111,17 +103,9 @@
Get PR details and analyze changes.
-
- github
- get_pull_request
-
- {
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "pullNumber": 1234
- }
-
-
+
+gh pr view 1234 --repo RooCodeInc/Roo-Code --json number,title,author,state,body,url,headRefName,baseRefName,files,additions,deletions,changedFiles,comments,reviews
+Identify the files changed and review feedback requiring UI text modifications.
@@ -130,7 +114,7 @@
Check out PR and apply the requested changes.
-gh pr checkout 1234 --force
+gh pr checkout 1234 --repo RooCodeInc/Roo-Code --forceMake the requested button text changes in the UI components.
@@ -158,20 +142,30 @@ Ensure consistency across all language files and maintain the same context and t
- Commit all changes including translations with automated git configuration.
+ Review and commit changes including translations.
-git add . && git commit -m "fix: update button text and translations as requested in review"
+git status --porcelain
- All code changes and translation updates are now committed.
+ Review the list of modified files to ensure only intended changes are present.
+
+
+
+ Stage only the intended files for commit.
+
+
+git add -u && git commit -m "fix: update button text and translations as requested in review"
+
+
+ Using 'git add -u' stages only modified tracked files, avoiding any temporary files.Check if PR is from a fork and push to correct remote.
-gh pr view 1234 --json isCrossRepository,headRepositoryOwner,headRefName
+gh pr view 1234 --repo RooCodeInc/Roo-Code --json isCrossRepository,headRepositoryOwner,headRefNameDetermine if this is a cross-repository PR to know which remote to push to.
@@ -181,7 +175,7 @@ Ensure consistency across all language files and maintain the same context and t
Push changes to the appropriate remote.
-git push --force-with-lease origin
+git push --force-with-lease origin [branch_name]Push changes safely to update the pull request. Use 'fork' remote instead if PR is from a fork.
@@ -191,7 +185,7 @@ Ensure consistency across all language files and maintain the same context and t
Monitor CI status in real-time.
-gh pr checks 1234 --watch
+gh pr checks 1234 --repo RooCodeInc/Roo-Code --watchWatch CI checks continuously until all tests pass. The --watch flag provides automatic updates as check statuses change.
@@ -203,6 +197,7 @@ Ensure consistency across all language files and maintain the same context and t
Use new_task with translate mode to ensure consistent translation updates.Include detailed context about what changed and why in translation requests.Verify translation completeness before considering the PR fix complete.
+ Use gh pr view --json to get structured data about PR properties.
diff --git a/.roo/rules-pr-reviewer/1_orchestrator_workflow.xml b/.roo/rules-pr-reviewer/1_orchestrator_workflow.xml
index cea0486a26..8bb94694d6 100644
--- a/.roo/rules-pr-reviewer/1_orchestrator_workflow.xml
+++ b/.roo/rules-pr-reviewer/1_orchestrator_workflow.xml
@@ -3,7 +3,7 @@
This workflow orchestrates a comprehensive pull request review process by delegating
specialized analysis tasks to appropriate modes while maintaining context through
structured report files. The orchestrator ensures critical review coverage while
- avoiding redundant feedback.
+ avoiding redundant feedback. All GitHub operations are performed using the GitHub CLI.
@@ -27,14 +27,12 @@
Fetch PR Details and Context
- Try using GitHub MCP tools first. If unavailable or failing, fall back to GitHub CLI.
+ Use GitHub CLI to fetch comprehensive PR details.
-
- Use get_pull_request tool to fetch PR details
-
-
+
gh pr view [PR_NUMBER] --repo [owner]/[repo] --json number,title,author,state,body,url,headRefName,baseRefName,files,additions,deletions,changedFiles
-
+
+ .roo/temp/pr-[PR_NUMBER]/pr-metadata.json
@@ -42,12 +40,10 @@
If PR references an issue, fetch its details for context.
-
- Use get_issue tool if issue is referenced
-
-
+
gh issue view [issue_number] --repo [owner]/[repo] --json number,title,body,author,state
-
+
+ .roo/temp/pr-[PR_NUMBER]/linked-issue.json
@@ -55,12 +51,10 @@
CRITICAL: Get all existing feedback to avoid redundancy.
-
- Use get_pull_request_comments and get_pull_request_reviews
-
-
- gh pr review [PR_NUMBER] --repo [owner]/[repo] --json comments,reviews
-
+
+ gh pr view [PR_NUMBER] --repo [owner]/[repo] --json comments --jq '.comments'
+ gh pr view [PR_NUMBER] --repo [owner]/[repo] --json reviews --jq '.reviews'
+ .roo/temp/pr-[PR_NUMBER]/existing-feedback.json
@@ -178,21 +172,26 @@
Post Review Comment (if approved)
- If user approves and not called by another mode, post review.
+ If user approves and not called by another mode, post review using GitHub CLI.
-
- Use add_issue_comment or create PR review
-
-
+
gh pr comment [PR_NUMBER] --repo [owner]/[repo] --body-file .roo/temp/pr-[PR_NUMBER]/final-review.md
-
+
-
- Always fall back to GitHub CLI commands
-
+
+
+ Inform user to run 'gh auth login' and check authentication status
+
+
+ Verify PR number and repository, ask user to confirm details
+
+
+ Wait briefly and retry, inform user about rate limiting
+
+
Continue with available analysis and note limitations
diff --git a/.roo/rules-pr-reviewer/4_github_operations.xml b/.roo/rules-pr-reviewer/4_github_operations.xml
index dd1c97e1bf..ad1fdc4459 100644
--- a/.roo/rules-pr-reviewer/4_github_operations.xml
+++ b/.roo/rules-pr-reviewer/4_github_operations.xml
@@ -1,226 +1,224 @@
- Guidelines for handling GitHub operations with fallback strategies
- when MCP tools are unavailable or failing.
+ Guidelines for handling GitHub operations using the GitHub CLI (gh).
+ This mode exclusively uses command-line operations for all GitHub interactions.
-
-
- Always try MCP tools first, fall back to GitHub CLI if they fail
-
-
- - Structured data responses
- - Better error handling
- - Integrated with the system
-
-
- - More reliable when MCP is down
- - Direct GitHub API access
- - Can handle complex queries
-
-
+
+
+ GitHub CLI must be installed and authenticated
+ gh auth status
+ https://cli.github.com/
+
+
+ User must be authenticated with appropriate permissions
+ gh auth login
+
+
-
- get_pull_request
-
-github
-get_pull_request
-
-{
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "pullNumber": 123
-}
-
-
- ]]>
-
-
- gh pr view [PR_NUMBER] --repo [owner]/[repo] --json number,title,author,state,body,url,headRefName,baseRefName,files,additions,deletions,changedFiles
- true
-
+ Fetch comprehensive PR metadata
+ gh pr view [PR_NUMBER] --repo [owner]/[repo] --json number,title,author,state,body,url,headRefName,baseRefName,files,additions,deletions,changedFiles
+ JSON
+ .roo/temp/pr-[PR_NUMBER]/pr-metadata.json
-
- get_pull_request_diff
-
-github
-get_pull_request_diff
-
-{
- "owner": "RooCodeInc",
- "repo": "Roo-Code",
- "pullNumber": 123
-}
-
-
- ]]>
-
-
- gh pr diff [PR_NUMBER] --repo [owner]/[repo]
- .roo/temp/pr-[PR_NUMBER]/pr.diff
-
+ Get the full diff of PR changes
+ gh pr diff [PR_NUMBER] --repo [owner]/[repo]
+ .roo/temp/pr-[PR_NUMBER]/pr.diff
-
- get_pull_request_files
-
-
- gh pr view [PR_NUMBER] --repo [owner]/[repo] --json files --jq '.files[].path'
- Lists all files changed in the PR
-
+ List all files changed in the PR
+ gh pr view [PR_NUMBER] --repo [owner]/[repo] --json files --jq '.files[].path'
+ Line-separated file paths
-
- get_pull_request_comments
-
-
- gh pr view [PR_NUMBER] --repo [owner]/[repo] --json comments --jq '.comments'
-
+ Get all comments on the PR
+ gh pr view [PR_NUMBER] --repo [owner]/[repo] --json comments --jq '.comments'
+ JSON array of comments
-
- get_pull_request_reviews
-
-
- gh pr view [PR_NUMBER] --repo [owner]/[repo] --json reviews --jq '.reviews'
-
+ Get all reviews on the PR
+ gh pr view [PR_NUMBER] --repo [owner]/[repo] --json reviews --jq '.reviews'
+ JSON array of reviews
-
- gh pr checkout [PR_NUMBER] --repo [owner]/[repo]
- No MCP equivalent - always use CLI
-
+ Check out PR branch locally for analysis
+ gh pr checkout [PR_NUMBER] --repo [owner]/[repo]
+ This switches the current branch to the PR branch
-
- add_issue_comment
- PRs use same comment system as issues
-
-
- gh pr comment [PR_NUMBER] --repo [owner]/[repo] --body-file [file_path]
- gh pr comment [PR_NUMBER] --repo [owner]/[repo] --body "[comment_text]"
-
+ Post a comment on the PR
+ gh pr comment [PR_NUMBER] --repo [owner]/[repo] --body-file [file_path]
+ gh pr comment [PR_NUMBER] --repo [owner]/[repo] --body "[comment_text]"
-
-
- 1. create_pending_pull_request_review
- 2. add_pull_request_review_comment_to_pending_review (multiple times)
- 3. submit_pending_pull_request_review
-
-
-
- gh pr review [PR_NUMBER] --repo [owner]/[repo] --comment --body-file [review_file]
-
+ Create a PR review with comments
+ gh pr review [PR_NUMBER] --repo [owner]/[repo] --comment --body-file [review_file]
+
+
+
+
+
+
+
+
+ Get issue details (for linked issues)
+ gh issue view [issue_number] --repo [owner]/[repo] --json number,title,body,author,state
+ JSON
-
+
- Error message contains "MCP server" or "github server not found"
+ Error contains "authentication" or "not logged in"
- Immediately switch to CLI commands for all operations
+ 1. Inform user about auth issue
+ 2. Suggest running: gh auth login
+ 3. Check status with: gh auth status
- Error contains "rate limit" or status code 403
+ Error contains "rate limit" or "API rate limit exceeded"
- 1. Wait briefly (30 seconds)
- 2. Retry with CLI using --limit flag
- 3. Reduce number of API calls
-
-
-
-
-
- Error contains "authentication" or status code 401
-
-
- 1. Inform user about auth issue
- 2. Suggest checking gh auth status
- 3. Continue with available data
+ 1. Wait 30-60 seconds before retry
+ 2. Inform user about rate limiting
+ 3. Consider reducing API calls
- Error contains "not found" or status code 404
+ Error contains "not found" or "could not find pull request"
- 1. Verify PR number and repository
- 2. Ask user to confirm details
- 3. Check if PR is from a fork
+ 1. Verify PR number and repository format
+ 2. Check if repository is accessible
+ 3. Ensure correct owner/repo format
+
+
+
+
+
+ Error contains "permission denied" or "403"
+
+
+ 1. Check repository permissions
+ 2. Verify authentication scope
+ 3. May need to re-authenticate with proper scopes
- Always save API responses to temp files
- Preserve data in case of failures
+ Always save command outputs to temp files
+ Preserve data for analysis and recovery
- Use jq or built-in JSON parsing
+ Use jq for JSON parsing when available
gh pr view --json files --jq '.files[].path'
- For PRs with many files, process in batches
+ For PRs with many files, save outputs to files firstMore than 50 files
+ Save to file, then process in chunks
+
+
+
+ Always validate JSON before parsing
+ jq empty < file.json || echo "Invalid JSON"
- gh pr view [number] --json [fields]
-
+ gh pr view [number]
+
+
+
+
+
+
number, title, author, state, body, url,
headRefName, baseRefName, files, additions,
- deletions, changedFiles, comments, reviews
-
+ deletions, changedFiles, comments, reviews,
+ isDraft, mergeable, mergeStateStatus
+
- gh pr checkout [number]
- gh pr diff [number]
- gh pr comment [number] --body "[text]"
- gh pr review [number] --comment --body "[text]"
+
+ gh pr checkout [number]: Check out PR locally
+ gh pr diff [number]: View PR diff
+ gh pr comment [number] --body "[text]": Add comment
+ gh pr review [number]: Create review
+ gh pr close [number]: Close PR
+ gh pr reopen [number]: Reopen PR
+
- gh issue view [number] --json [fields]
-
+ gh issue view [number]
+
number, title, body, author, state,
- labels, assignees, milestone
-
+ labels, assignees, milestone, comments
+
+
+
+
+
+ gh repo view --json [fields]: Get repo info
+ gh repo clone [owner]/[repo]: Clone repository
+ Always specify --repo to avoid ambiguity
- Use --json for structured data
- Save command outputs to temp files
- Check gh auth status before operations
- Handle both personal repos and org repos
+ Use --json for structured data that needs parsing
+ Save command outputs to temp files for reliability
+ Check gh auth status before starting operations
+ Handle both personal repos and organization repos
+ Use meaningful file names when saving outputs
+ Include error handling for all commands
+ Document the expected format of saved files
+
+
+
+ Fetch all PR data for analysis
+
+ gh pr view 123 --repo owner/repo --json number,title,author,state,body,url,headRefName,baseRefName,files,additions,deletions,changedFiles > .roo/temp/pr-123/metadata.json
+ gh pr view 123 --repo owner/repo --json comments > .roo/temp/pr-123/comments.json
+ gh pr view 123 --repo owner/repo --json reviews > .roo/temp/pr-123/reviews.json
+ gh pr diff 123 --repo owner/repo > .roo/temp/pr-123/pr.diff
+
+
+
+
+ Post a comprehensive review
+
+ Create review content in .roo/temp/pr-123/review.md
+ gh pr review 123 --repo owner/repo --comment --body-file .roo/temp/pr-123/review.md
+
+
+
\ No newline at end of file
diff --git a/.roomodes b/.roomodes
index f2bbe35fd1..5cbc37fbc4 100644
--- a/.roomodes
+++ b/.roomodes
@@ -18,6 +18,7 @@ customModes:
- Ensuring instructions are well-organized with proper XML tags
- Following established patterns from existing modes
whenToUse: Use this mode when you need to create a new custom mode.
+ description: Create and implement custom modes.
groups:
- read
- - edit
@@ -33,6 +34,7 @@ customModes:
Your focus is on maintaining high test quality and coverage across the codebase, working primarily with: - Test files in __tests__ directories - Mock implementations in __mocks__ - Test utilities and helpers - Vitest configuration and setup
You ensure tests are: - Well-structured and maintainable - Following Vitest best practices - Properly typed with TypeScript - Providing meaningful coverage - Using appropriate mocking strategies
whenToUse: Use this mode when you need to write, modify, or maintain tests for the codebase.
+ description: Write, modify, and maintain tests.
groups:
- read
- browser
@@ -55,6 +57,8 @@ customModes:
- slug: design-engineer
name: 🎨 Design Engineer
roleDefinition: "You are Roo, an expert Design Engineer focused on VSCode Extension development. Your expertise includes: - Implementing UI designs with high fidelity using React, Shadcn, Tailwind and TypeScript. - Ensuring interfaces are responsive and adapt to different screen sizes. - Collaborating with team members to translate broad directives into robust and detailed designs capturing edge cases. - Maintaining uniformity and consistency across the user interface."
+ whenToUse: Implement UI designs and ensure consistency.
+ description: Implement UI designs; ensure consistency.
groups:
- read
- - edit
@@ -68,6 +72,8 @@ customModes:
- slug: release-engineer
name: 🚀 Release Engineer
roleDefinition: You are Roo, a release engineer specialized in automating the release process for software projects. You have expertise in version control, changelogs, release notes, creating changesets, and coordinating with translation teams to ensure a smooth release process.
+ whenToUse: Automate the release process for software projects.
+ description: Automate the release process.
customInstructions: |-
When preparing a release: 1. Identify the SHA corresponding to the most recent release using GitHub CLI: `gh release view --json tagName,targetCommitish,publishedAt ` 2. Analyze changes since the last release using: `gh pr list --state merged --json number,title,author,url,mergedAt --limit 1000 -q '[.[] | select(.mergedAt > "TIMESTAMP") | {number, title, author: .author.login, url, mergedAt}] | sort_by(.number)'` 3. Summarize the changes and ask the user whether this should be a major, minor, or patch release 4. Create a changeset in .changeset/v[version].md instead of directly modifying package.json. The format is:
``` --- "roo-cline": patch|minor|major ---
@@ -86,6 +92,8 @@ customModes:
- slug: translate
name: 🌐 Translate
roleDefinition: You are Roo, a linguistic specialist focused on translating and managing localization files. Your responsibility is to help maintain and update translation files for the application, ensuring consistency and accuracy across all language resources.
+ whenToUse: Translate and manage localization files.
+ description: Translate and manage localization files.
groups:
- read
- command
@@ -107,6 +115,7 @@ customModes:
You work with issues from any GitHub repository, transforming them into working code that addresses all requirements while maintaining code quality and consistency. You use the GitHub CLI (gh) for all GitHub operations instead of MCP tools.
whenToUse: Use this mode when you have a GitHub issue (bug report or feature request) that needs to be fixed or implemented. Provide the issue URL, and this mode will guide you through understanding the requirements, implementing the solution, and preparing for submission.
+ description: Fix GitHub issues and implement features.
groups:
- read
- edit
@@ -118,6 +127,7 @@ customModes:
You are Roo, a GitHub issue creation specialist focused on crafting well-structured, detailed issues based on the project's issue templates. Your expertise includes: - Understanding and analyzing user requirements for bug reports and feature requests - Exploring codebases thoroughly to gather relevant technical context - Creating comprehensive GitHub issues following XML-based templates - Ensuring issues contain all necessary information for developers - Using GitHub MCP tools to create issues programmatically
You work with two primary issue types: - Bug Reports: Documenting reproducible bugs with clear steps and expected outcomes - Feature Proposals: Creating detailed, actionable feature requests with clear problem statements, solutions, and acceptance criteria
whenToUse: Use this mode when you need to create a GitHub issue for bug reports or feature requests. This mode will guide you through gathering all necessary information, exploring the codebase for context, and creating a well-structured issue in the RooCodeInc/Roo-Code repository.
+ description: Create well-structured GitHub issues.
groups:
- read
- command
@@ -129,6 +139,8 @@ customModes:
You are Roo, an integration testing specialist focused on VSCode E2E tests with expertise in: - Writing and maintaining integration tests using Mocha and VSCode Test framework - Testing Roo Code API interactions and event-driven workflows - Creating complex multi-step task scenarios and mode switching sequences - Validating message formats, API responses, and event emission patterns - Test data generation and fixture management - Coverage analysis and test scenario identification
Your focus is on ensuring comprehensive integration test coverage for the Roo Code extension, working primarily with: - E2E test files in apps/vscode-e2e/src/suite/ - Test utilities and helpers - API type definitions in packages/types/ - Extension API testing patterns
You ensure integration tests are: - Comprehensive and cover critical user workflows - Following established Mocha TDD patterns - Using async/await with proper timeout handling - Validating both success and failure scenarios - Properly typed with TypeScript
+ whenToUse: Write, modify, or maintain integration tests.
+ description: Write and maintain integration tests.
groups:
- read
- command
@@ -156,6 +168,7 @@ customModes:
You work primarily with the RooCodeInc/Roo-Code repository, creating context reports to track findings and delegating complex pattern analysis to specialized modes while maintaining overall review coordination. When called by other modes (Issue Fixer, PR Fixer), you focus only on analysis without commenting on the PR.
whenToUse: Use this mode to critically review pull requests, focusing on code organization, pattern consistency, and identifying redundancy or architectural issues. This mode orchestrates complex analysis tasks while maintaining review context.
+ description: Critically review pull requests.
groups:
- read
- - edit
@@ -168,6 +181,7 @@ customModes:
name: 📚 Docs Extractor
roleDefinition: You are Roo, a comprehensive documentation extraction specialist focused on analyzing and documenting all technical and non-technical information about features and components within codebases.
whenToUse: Use this mode when you need to extract comprehensive documentation about any feature, component, or aspect of a codebase.
+ description: Extract comprehensive documentation.
groups:
- read
- - edit
@@ -179,26 +193,9 @@ customModes:
name: 🛠️ PR Fixer
roleDefinition: "You are Roo, a pull request resolution specialist. Your focus is on addressing feedback and resolving issues within existing pull requests. Your expertise includes: - Analyzing PR review comments to understand required changes. - Checking CI/CD workflow statuses to identify failing tests. - Fetching and analyzing test logs to diagnose failures. - Identifying and resolving merge conflicts. - Guiding the user through the resolution process."
whenToUse: Use this mode to fix pull requests. It can analyze PR feedback from GitHub, check for failing tests, and help resolve merge conflicts before applying the necessary code changes.
+ description: Fix pull requests.
groups:
- read
- edit
- command
- mcp
- - slug: pr-fixer-orchestrator
- name: 🛠️ PR Fixer Orchestrator
- roleDefinition: |-
- You are an orchestrator for fixing pull requests. Your primary role is to coordinate a series of specialized subtasks to resolve PR issues from start to finish, whether or not the PR has existing context from issue fixing.
- **Your Orchestration Responsibilities:** - Delegate analysis, implementation, testing, and review to specialized subtasks using the `new_task` tool. - Manage the workflow and pass context between steps using temporary files. - Present findings, plans, and results to the user for approval at key milestones. - Ensure the PR branch is properly synced with main and ready for merge.
- **Your Core Expertise Includes:** - Analyzing PR feedback, failing tests, and merge conflicts. - Understanding the underlying issue or feature being implemented. - Exploring codebases to identify all affected files and dependencies. - Understanding CI/CD pipeline failures and test results. - Coordinating code fixes based on review comments. - Managing git operations including rebases and conflict resolution. - Ensuring proper testing and validation of changes. - Overseeing PR review before final submission. - Using GitHub CLI (gh) for all GitHub operations.
- whenToUse: Use this mode to orchestrate the process of fixing a pull request. Provide a GitHub PR URL or number, and this mode will coordinate a series of subtasks to analyze the PR issues, understand the underlying requirements, implement fixes, resolve conflicts, test changes, and ensure the PR is ready for merge. This mode works independently and does not require any pre-existing context files.
- groups: []
- source: project
- - slug: issue-fixer-orchestrator
- name: 🔧 Issue Fixer Orchestrator
- roleDefinition: |-
- You are an orchestrator for fixing GitHub issues. Your primary role is to coordinate a series of specialized subtasks to resolve an issue from start to finish.
- **Your Orchestration Responsibilities:** - Delegate analysis, implementation, and testing to specialized subtasks using the `new_task` tool. - Manage the workflow and pass context between steps using temporary files. - Present plans, results, and pull requests to the user for approval at key milestones.
- **Your Core Expertise Includes:** - Analyzing GitHub issues to understand requirements and acceptance criteria. - Exploring codebases to identify all affected files and dependencies. - Guiding the implementation of high-quality fixes and features. - Ensuring comprehensive test coverage. - Overseeing the creation of well-documented pull requests. - Using the GitHub CLI (gh) for all final GitHub operations like creating a pull request.
- whenToUse: Use this mode to orchestrate the process of fixing a GitHub issue. Provide a GitHub issue URL, and this mode will coordinate a series of subtasks to analyze the issue, explore the code, create a plan, implement the solution, and prepare a pull request.
- groups: []
- source: project
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 018b9330da..91091805e8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,26 @@
# Roo Code Changelog
+## [3.23.14] - 2025-07-17
+
+- Log api-initiated tasks to a tmp directory
+
+## [3.23.13] - 2025-07-17
+
+- Add the ability to "undo" enhance prompt changes
+- Fix a bug where the path component of the baseURL for the LiteLLM provider contains path in it (thanks @ChuKhaLi)
+- Add support for Vertex AI model name formatting when using Claude Code with Vertex AI (thanks @janaki-sasidhar)
+- The list-files tool must include at least the first-level directory contents (thanks @qdaxb)
+- Add a configurable limit that controls both consecutive errors and tool repetitions (thanks @MuriloFP)
+- Add `.terraform/` and `.terragrunt-cache/` directories to the checkpoint exclusion patterns (thanks @MuriloFP)
+- Increase Ollama API timeout values (thanks @daniel-lxs)
+- Fix an issue where you need to "discard changes" before saving even though there are no settings changes
+- Fix `DirectoryScanner` memory leak and improve file limit handling (thanks @daniel-lxs)
+- Fix time formatting in environment (thanks @chrarnoldus)
+- Prevent empty mode names from being saved (thanks @daniel-lxs)
+- Improve auto-approve checkbox UX
+- Improve the chat message edit / delete functionality (thanks @liwilliam2021)
+- Add `commandExecutionTimeout` to `GlobalSettings`
+
## [3.23.12] - 2025-07-15
- Update the max-token calculation in model-params to better support Kimi K2 and others
diff --git a/packages/types/npm/package.json b/packages/types/npm/package.json
index 54188d73bc..924e5251cb 100644
--- a/packages/types/npm/package.json
+++ b/packages/types/npm/package.json
@@ -1,6 +1,6 @@
{
"name": "@roo-code/types",
- "version": "1.32.0",
+ "version": "1.35.0",
"description": "TypeScript type definitions for Roo Code.",
"publishConfig": {
"access": "public",
diff --git a/packages/types/src/__tests__/provider-settings.test.ts b/packages/types/src/__tests__/provider-settings.test.ts
new file mode 100644
index 0000000000..87c5bbcc1c
--- /dev/null
+++ b/packages/types/src/__tests__/provider-settings.test.ts
@@ -0,0 +1,79 @@
+import { describe, it, expect } from "vitest"
+import { getApiProtocol } from "../provider-settings.js"
+
+describe("getApiProtocol", () => {
+ describe("Anthropic-style providers", () => {
+ it("should return 'anthropic' for anthropic provider", () => {
+ expect(getApiProtocol("anthropic")).toBe("anthropic")
+ expect(getApiProtocol("anthropic", "gpt-4")).toBe("anthropic")
+ })
+
+ it("should return 'anthropic' for claude-code provider", () => {
+ expect(getApiProtocol("claude-code")).toBe("anthropic")
+ expect(getApiProtocol("claude-code", "some-model")).toBe("anthropic")
+ })
+ })
+
+ describe("Vertex provider with Claude models", () => {
+ it("should return 'anthropic' for vertex provider with claude models", () => {
+ expect(getApiProtocol("vertex", "claude-3-opus")).toBe("anthropic")
+ expect(getApiProtocol("vertex", "Claude-3-Sonnet")).toBe("anthropic")
+ expect(getApiProtocol("vertex", "CLAUDE-instant")).toBe("anthropic")
+ expect(getApiProtocol("vertex", "anthropic/claude-3-haiku")).toBe("anthropic")
+ })
+
+ it("should return 'openai' for vertex provider with non-claude models", () => {
+ expect(getApiProtocol("vertex", "gpt-4")).toBe("openai")
+ expect(getApiProtocol("vertex", "gemini-pro")).toBe("openai")
+ expect(getApiProtocol("vertex", "llama-2")).toBe("openai")
+ })
+ })
+
+ describe("Bedrock provider with Claude models", () => {
+ it("should return 'anthropic' for bedrock provider with claude models", () => {
+ expect(getApiProtocol("bedrock", "claude-3-opus")).toBe("anthropic")
+ expect(getApiProtocol("bedrock", "Claude-3-Sonnet")).toBe("anthropic")
+ expect(getApiProtocol("bedrock", "CLAUDE-instant")).toBe("anthropic")
+ expect(getApiProtocol("bedrock", "anthropic.claude-v2")).toBe("anthropic")
+ })
+
+ it("should return 'openai' for bedrock provider with non-claude models", () => {
+ expect(getApiProtocol("bedrock", "gpt-4")).toBe("openai")
+ expect(getApiProtocol("bedrock", "titan-text")).toBe("openai")
+ expect(getApiProtocol("bedrock", "llama-2")).toBe("openai")
+ })
+ })
+
+ describe("Other providers with Claude models", () => {
+ it("should return 'openai' for non-vertex/bedrock providers with claude models", () => {
+ expect(getApiProtocol("openrouter", "claude-3-opus")).toBe("openai")
+ expect(getApiProtocol("openai", "claude-3-sonnet")).toBe("openai")
+ expect(getApiProtocol("litellm", "claude-instant")).toBe("openai")
+ expect(getApiProtocol("ollama", "claude-model")).toBe("openai")
+ })
+ })
+
+ describe("Edge cases", () => {
+ it("should return 'openai' when provider is undefined", () => {
+ expect(getApiProtocol(undefined)).toBe("openai")
+ expect(getApiProtocol(undefined, "claude-3-opus")).toBe("openai")
+ })
+
+ it("should return 'openai' when model is undefined", () => {
+ expect(getApiProtocol("openai")).toBe("openai")
+ expect(getApiProtocol("vertex")).toBe("openai")
+ expect(getApiProtocol("bedrock")).toBe("openai")
+ })
+
+ it("should handle empty strings", () => {
+ expect(getApiProtocol("vertex", "")).toBe("openai")
+ expect(getApiProtocol("bedrock", "")).toBe("openai")
+ })
+
+ it("should be case-insensitive for claude detection", () => {
+ expect(getApiProtocol("vertex", "CLAUDE-3-OPUS")).toBe("anthropic")
+ expect(getApiProtocol("bedrock", "claude-3-opus")).toBe("anthropic")
+ expect(getApiProtocol("vertex", "ClAuDe-InStAnT")).toBe("anthropic")
+ })
+ })
+})
diff --git a/packages/types/src/global-settings.ts b/packages/types/src/global-settings.ts
index 514b15d783..129ddebdd5 100644
--- a/packages/types/src/global-settings.ts
+++ b/packages/types/src/global-settings.ts
@@ -50,6 +50,8 @@ export const globalSettingsSchema = z.object({
alwaysAllowUpdateTodoList: z.boolean().optional(),
allowedCommands: z.array(z.string()).optional(),
deniedCommands: z.array(z.string()).optional(),
+ commandExecutionTimeout: z.number().optional(),
+ preventCompletionWithOpenTodos: z.boolean().optional(),
allowedMaxRequests: z.number().nullish(),
autoCondenseContext: z.boolean().optional(),
autoCondenseContextPercent: z.number().optional(),
@@ -200,6 +202,8 @@ export const EVALS_SETTINGS: RooCodeSettings = {
alwaysAllowUpdateTodoList: true,
followupAutoApproveTimeoutMs: 0,
allowedCommands: ["*"],
+ commandExecutionTimeout: 30_000,
+ preventCompletionWithOpenTodos: false,
browserToolEnabled: false,
browserViewportSize: "900x600",
diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts
index 3b53627295..be74ae6bb4 100644
--- a/packages/types/src/provider-settings.ts
+++ b/packages/types/src/provider-settings.ts
@@ -303,7 +303,23 @@ export const getModelId = (settings: ProviderSettings): string | undefined => {
// Providers that use Anthropic-style API protocol
export const ANTHROPIC_STYLE_PROVIDERS: ProviderName[] = ["anthropic", "claude-code"]
-// Helper function to determine API protocol for a provider
-export const getApiProtocol = (provider: ProviderName | undefined): "anthropic" | "openai" => {
- return provider && ANTHROPIC_STYLE_PROVIDERS.includes(provider) ? "anthropic" : "openai"
+// Helper function to determine API protocol for a provider and model
+export const getApiProtocol = (provider: ProviderName | undefined, modelId?: string): "anthropic" | "openai" => {
+ // First check if the provider is an Anthropic-style provider
+ if (provider && ANTHROPIC_STYLE_PROVIDERS.includes(provider)) {
+ return "anthropic"
+ }
+
+ // For vertex and bedrock providers, check if the model ID contains "claude" (case-insensitive)
+ if (
+ provider &&
+ (provider === "vertex" || provider === "bedrock") &&
+ modelId &&
+ modelId.toLowerCase().includes("claude")
+ ) {
+ return "anthropic"
+ }
+
+ // Default to OpenAI protocol
+ return "openai"
}
diff --git a/src/core/config/CustomModesManager.ts b/src/core/config/CustomModesManager.ts
index b4bcfa62d6..3da22d1be8 100644
--- a/src/core/config/CustomModesManager.ts
+++ b/src/core/config/CustomModesManager.ts
@@ -401,6 +401,14 @@ export class CustomModesManager {
public async updateCustomMode(slug: string, config: ModeConfig): Promise {
try {
+ // Validate the mode configuration before saving
+ const validationResult = modeConfigSchema.safeParse(config)
+ if (!validationResult.success) {
+ const errors = validationResult.error.errors.map((e) => e.message).join(", ")
+ logger.error(`Invalid mode configuration for ${slug}`, { errors: validationResult.error.errors })
+ throw new Error(`Invalid mode configuration: ${errors}`)
+ }
+
const isProjectMode = config.source === "project"
let targetPath: string
diff --git a/src/core/environment/getEnvironmentDetails.ts b/src/core/environment/getEnvironmentDetails.ts
index 8d4f157f4d..6f0c9fe2bf 100644
--- a/src/core/environment/getEnvironmentDetails.ts
+++ b/src/core/environment/getEnvironmentDetails.ts
@@ -179,22 +179,12 @@ export async function getEnvironmentDetails(cline: Task, includeFileDetails: boo
// Add current time information with timezone.
const now = new Date()
- const formatter = new Intl.DateTimeFormat(undefined, {
- year: "numeric",
- month: "numeric",
- day: "numeric",
- hour: "numeric",
- minute: "numeric",
- second: "numeric",
- hour12: true,
- })
-
- const timeZone = formatter.resolvedOptions().timeZone
+ const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
const timeZoneOffset = -now.getTimezoneOffset() / 60 // Convert to hours and invert sign to match conventional notation
const timeZoneOffsetHours = Math.floor(Math.abs(timeZoneOffset))
const timeZoneOffsetMinutes = Math.abs(Math.round((Math.abs(timeZoneOffset) - timeZoneOffsetHours) * 60))
const timeZoneOffsetStr = `${timeZoneOffset >= 0 ? "+" : "-"}${timeZoneOffsetHours}:${timeZoneOffsetMinutes.toString().padStart(2, "0")}`
- details += `\n\n# Current Time\n${formatter.format(now)} (${timeZone}, UTC${timeZoneOffsetStr})`
+ details += `\n\n# Current Time\nCurrent time in ISO 8601 UTC format: ${now.toISOString()}\nUser time zone: ${timeZone}, UTC${timeZoneOffsetStr}`
// Add context tokens information.
const { contextTokens, totalCost } = getApiMetrics(cline.clineMessages)
diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts
index 8a1bf1101d..53b8ef5b87 100644
--- a/src/core/task/Task.ts
+++ b/src/core/task/Task.ts
@@ -23,6 +23,7 @@ import {
TelemetryEventName,
TodoItem,
getApiProtocol,
+ getModelId,
} from "@roo-code/types"
import { TelemetryService } from "@roo-code/telemetry"
import { CloudService } from "@roo-code/cloud"
@@ -1211,8 +1212,9 @@ export class Task extends EventEmitter {
// take a few seconds. For the best UX we show a placeholder api_req_started
// message with a loading spinner as this happens.
- // Determine API protocol based on provider
- const apiProtocol = getApiProtocol(this.apiConfiguration.apiProvider)
+ // Determine API protocol based on provider and model
+ const modelId = getModelId(this.apiConfiguration)
+ const apiProtocol = getApiProtocol(this.apiConfiguration.apiProvider, modelId)
await this.say(
"api_req_started",
diff --git a/src/core/task/__tests__/Task.spec.ts b/src/core/task/__tests__/Task.spec.ts
index 797714cde8..9aa5a8d7a8 100644
--- a/src/core/task/__tests__/Task.spec.ts
+++ b/src/core/task/__tests__/Task.spec.ts
@@ -1398,5 +1398,100 @@ describe("Cline", () => {
expect(task.diffStrategy).toBeUndefined()
})
})
+
+ describe("getApiProtocol", () => {
+ it("should determine API protocol based on provider and model", async () => {
+ // Test with Anthropic provider
+ const anthropicConfig = {
+ ...mockApiConfig,
+ apiProvider: "anthropic" as const,
+ apiModelId: "gpt-4",
+ }
+ const anthropicTask = new Task({
+ provider: mockProvider,
+ apiConfiguration: anthropicConfig,
+ task: "test task",
+ startTask: false,
+ })
+ // Should use anthropic protocol even with non-claude model
+ expect(anthropicTask.apiConfiguration.apiProvider).toBe("anthropic")
+
+ // Test with OpenRouter provider and Claude model
+ const openrouterClaudeConfig = {
+ apiProvider: "openrouter" as const,
+ openRouterModelId: "anthropic/claude-3-opus",
+ }
+ const openrouterClaudeTask = new Task({
+ provider: mockProvider,
+ apiConfiguration: openrouterClaudeConfig,
+ task: "test task",
+ startTask: false,
+ })
+ expect(openrouterClaudeTask.apiConfiguration.apiProvider).toBe("openrouter")
+
+ // Test with OpenRouter provider and non-Claude model
+ const openrouterGptConfig = {
+ apiProvider: "openrouter" as const,
+ openRouterModelId: "openai/gpt-4",
+ }
+ const openrouterGptTask = new Task({
+ provider: mockProvider,
+ apiConfiguration: openrouterGptConfig,
+ task: "test task",
+ startTask: false,
+ })
+ expect(openrouterGptTask.apiConfiguration.apiProvider).toBe("openrouter")
+
+ // Test with various Claude model formats
+ const claudeModelFormats = [
+ "claude-3-opus",
+ "Claude-3-Sonnet",
+ "CLAUDE-instant",
+ "anthropic/claude-3-haiku",
+ "some-provider/claude-model",
+ ]
+
+ for (const modelId of claudeModelFormats) {
+ const config = {
+ apiProvider: "openai" as const,
+ openAiModelId: modelId,
+ }
+ const task = new Task({
+ provider: mockProvider,
+ apiConfiguration: config,
+ task: "test task",
+ startTask: false,
+ })
+ // Verify the model ID contains claude (case-insensitive)
+ expect(modelId.toLowerCase()).toContain("claude")
+ }
+ })
+
+ it("should handle edge cases for API protocol detection", async () => {
+ // Test with undefined provider
+ const undefinedProviderConfig = {
+ apiModelId: "claude-3-opus",
+ }
+ const undefinedProviderTask = new Task({
+ provider: mockProvider,
+ apiConfiguration: undefinedProviderConfig,
+ task: "test task",
+ startTask: false,
+ })
+ expect(undefinedProviderTask.apiConfiguration.apiProvider).toBeUndefined()
+
+ // Test with no model ID
+ const noModelConfig = {
+ apiProvider: "openai" as const,
+ }
+ const noModelTask = new Task({
+ provider: mockProvider,
+ apiConfiguration: noModelConfig,
+ task: "test task",
+ startTask: false,
+ })
+ expect(noModelTask.apiConfiguration.apiProvider).toBe("openai")
+ })
+ })
})
})
diff --git a/src/core/tools/__tests__/attemptCompletionTool.spec.ts b/src/core/tools/__tests__/attemptCompletionTool.spec.ts
new file mode 100644
index 0000000000..b39c1acac6
--- /dev/null
+++ b/src/core/tools/__tests__/attemptCompletionTool.spec.ts
@@ -0,0 +1,412 @@
+import { describe, it, expect, vi, beforeEach } from "vitest"
+import { TodoItem } from "@roo-code/types"
+import { AttemptCompletionToolUse } from "../../../shared/tools"
+
+// Mock the formatResponse module before importing the tool
+vi.mock("../../prompts/responses", () => ({
+ formatResponse: {
+ toolError: vi.fn((msg: string) => `Error: ${msg}`),
+ },
+}))
+
+// Mock vscode module
+vi.mock("vscode", () => ({
+ workspace: {
+ getConfiguration: vi.fn(() => ({
+ get: vi.fn(),
+ })),
+ },
+}))
+
+// Mock Package module
+vi.mock("../../../shared/package", () => ({
+ Package: {
+ name: "roo-cline",
+ },
+}))
+
+import { attemptCompletionTool } from "../attemptCompletionTool"
+import { Task } from "../../task/Task"
+import * as vscode from "vscode"
+
+describe("attemptCompletionTool", () => {
+ let mockTask: Partial
+ let mockPushToolResult: ReturnType
+ let mockAskApproval: ReturnType
+ let mockHandleError: ReturnType
+ let mockRemoveClosingTag: ReturnType
+ let mockToolDescription: ReturnType
+ let mockAskFinishSubTaskApproval: ReturnType
+ let mockGetConfiguration: ReturnType
+
+ beforeEach(() => {
+ mockPushToolResult = vi.fn()
+ mockAskApproval = vi.fn()
+ mockHandleError = vi.fn()
+ mockRemoveClosingTag = vi.fn()
+ mockToolDescription = vi.fn()
+ mockAskFinishSubTaskApproval = vi.fn()
+ mockGetConfiguration = vi.fn(() => ({
+ get: vi.fn((key: string, defaultValue: any) => {
+ if (key === "preventCompletionWithOpenTodos") {
+ return defaultValue // Default to false unless overridden in test
+ }
+ return defaultValue
+ }),
+ }))
+
+ // Setup vscode mock
+ vi.mocked(vscode.workspace.getConfiguration).mockImplementation(mockGetConfiguration)
+
+ mockTask = {
+ consecutiveMistakeCount: 0,
+ recordToolError: vi.fn(),
+ todoList: undefined,
+ }
+ })
+
+ describe("todo list validation", () => {
+ it("should allow completion when there is no todo list", async () => {
+ const block: AttemptCompletionToolUse = {
+ type: "tool_use",
+ name: "attempt_completion",
+ params: { result: "Task completed successfully" },
+ partial: false,
+ }
+
+ mockTask.todoList = undefined
+
+ await attemptCompletionTool(
+ mockTask as Task,
+ block,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ mockToolDescription,
+ mockAskFinishSubTaskApproval,
+ )
+
+ // Should not call pushToolResult with an error for empty todo list
+ expect(mockTask.consecutiveMistakeCount).toBe(0)
+ expect(mockTask.recordToolError).not.toHaveBeenCalled()
+ })
+
+ it("should allow completion when todo list is empty", async () => {
+ const block: AttemptCompletionToolUse = {
+ type: "tool_use",
+ name: "attempt_completion",
+ params: { result: "Task completed successfully" },
+ partial: false,
+ }
+
+ mockTask.todoList = []
+
+ await attemptCompletionTool(
+ mockTask as Task,
+ block,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ mockToolDescription,
+ mockAskFinishSubTaskApproval,
+ )
+
+ expect(mockTask.consecutiveMistakeCount).toBe(0)
+ expect(mockTask.recordToolError).not.toHaveBeenCalled()
+ })
+
+ it("should allow completion when all todos are completed", async () => {
+ const block: AttemptCompletionToolUse = {
+ type: "tool_use",
+ name: "attempt_completion",
+ params: { result: "Task completed successfully" },
+ partial: false,
+ }
+
+ const completedTodos: TodoItem[] = [
+ { id: "1", content: "First task", status: "completed" },
+ { id: "2", content: "Second task", status: "completed" },
+ ]
+
+ mockTask.todoList = completedTodos
+
+ await attemptCompletionTool(
+ mockTask as Task,
+ block,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ mockToolDescription,
+ mockAskFinishSubTaskApproval,
+ )
+
+ expect(mockTask.consecutiveMistakeCount).toBe(0)
+ expect(mockTask.recordToolError).not.toHaveBeenCalled()
+ })
+
+ it("should prevent completion when there are pending todos", async () => {
+ const block: AttemptCompletionToolUse = {
+ type: "tool_use",
+ name: "attempt_completion",
+ params: { result: "Task completed successfully" },
+ partial: false,
+ }
+
+ const todosWithPending: TodoItem[] = [
+ { id: "1", content: "First task", status: "completed" },
+ { id: "2", content: "Second task", status: "pending" },
+ ]
+
+ mockTask.todoList = todosWithPending
+
+ // Enable the setting to prevent completion with open todos
+ mockGetConfiguration.mockReturnValue({
+ get: vi.fn((key: string, defaultValue: any) => {
+ if (key === "preventCompletionWithOpenTodos") {
+ return true // Setting is enabled
+ }
+ return defaultValue
+ }),
+ })
+
+ await attemptCompletionTool(
+ mockTask as Task,
+ block,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ mockToolDescription,
+ mockAskFinishSubTaskApproval,
+ )
+
+ expect(mockTask.consecutiveMistakeCount).toBe(1)
+ expect(mockTask.recordToolError).toHaveBeenCalledWith("attempt_completion")
+ expect(mockPushToolResult).toHaveBeenCalledWith(
+ expect.stringContaining("Cannot complete task while there are incomplete todos"),
+ )
+ })
+
+ it("should prevent completion when there are in-progress todos", async () => {
+ const block: AttemptCompletionToolUse = {
+ type: "tool_use",
+ name: "attempt_completion",
+ params: { result: "Task completed successfully" },
+ partial: false,
+ }
+
+ const todosWithInProgress: TodoItem[] = [
+ { id: "1", content: "First task", status: "completed" },
+ { id: "2", content: "Second task", status: "in_progress" },
+ ]
+
+ mockTask.todoList = todosWithInProgress
+
+ // Enable the setting to prevent completion with open todos
+ mockGetConfiguration.mockReturnValue({
+ get: vi.fn((key: string, defaultValue: any) => {
+ if (key === "preventCompletionWithOpenTodos") {
+ return true // Setting is enabled
+ }
+ return defaultValue
+ }),
+ })
+
+ await attemptCompletionTool(
+ mockTask as Task,
+ block,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ mockToolDescription,
+ mockAskFinishSubTaskApproval,
+ )
+
+ expect(mockTask.consecutiveMistakeCount).toBe(1)
+ expect(mockTask.recordToolError).toHaveBeenCalledWith("attempt_completion")
+ expect(mockPushToolResult).toHaveBeenCalledWith(
+ expect.stringContaining("Cannot complete task while there are incomplete todos"),
+ )
+ })
+
+ it("should prevent completion when there are mixed incomplete todos", async () => {
+ const block: AttemptCompletionToolUse = {
+ type: "tool_use",
+ name: "attempt_completion",
+ params: { result: "Task completed successfully" },
+ partial: false,
+ }
+
+ const mixedTodos: TodoItem[] = [
+ { id: "1", content: "First task", status: "completed" },
+ { id: "2", content: "Second task", status: "pending" },
+ { id: "3", content: "Third task", status: "in_progress" },
+ ]
+
+ mockTask.todoList = mixedTodos
+
+ // Enable the setting to prevent completion with open todos
+ mockGetConfiguration.mockReturnValue({
+ get: vi.fn((key: string, defaultValue: any) => {
+ if (key === "preventCompletionWithOpenTodos") {
+ return true // Setting is enabled
+ }
+ return defaultValue
+ }),
+ })
+
+ await attemptCompletionTool(
+ mockTask as Task,
+ block,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ mockToolDescription,
+ mockAskFinishSubTaskApproval,
+ )
+
+ expect(mockTask.consecutiveMistakeCount).toBe(1)
+ expect(mockTask.recordToolError).toHaveBeenCalledWith("attempt_completion")
+ expect(mockPushToolResult).toHaveBeenCalledWith(
+ expect.stringContaining("Cannot complete task while there are incomplete todos"),
+ )
+ })
+
+ it("should allow completion when setting is disabled even with incomplete todos", async () => {
+ const block: AttemptCompletionToolUse = {
+ type: "tool_use",
+ name: "attempt_completion",
+ params: { result: "Task completed successfully" },
+ partial: false,
+ }
+
+ const todosWithPending: TodoItem[] = [
+ { id: "1", content: "First task", status: "completed" },
+ { id: "2", content: "Second task", status: "pending" },
+ ]
+
+ mockTask.todoList = todosWithPending
+
+ // Ensure the setting is disabled (default behavior)
+ mockGetConfiguration.mockReturnValue({
+ get: vi.fn((key: string, defaultValue: any) => {
+ if (key === "preventCompletionWithOpenTodos") {
+ return false // Setting is disabled
+ }
+ return defaultValue
+ }),
+ })
+
+ await attemptCompletionTool(
+ mockTask as Task,
+ block,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ mockToolDescription,
+ mockAskFinishSubTaskApproval,
+ )
+
+ // Should not prevent completion when setting is disabled
+ expect(mockTask.consecutiveMistakeCount).toBe(0)
+ expect(mockTask.recordToolError).not.toHaveBeenCalled()
+ expect(mockPushToolResult).not.toHaveBeenCalledWith(
+ expect.stringContaining("Cannot complete task while there are incomplete todos"),
+ )
+ })
+
+ it("should prevent completion when setting is enabled with incomplete todos", async () => {
+ const block: AttemptCompletionToolUse = {
+ type: "tool_use",
+ name: "attempt_completion",
+ params: { result: "Task completed successfully" },
+ partial: false,
+ }
+
+ const todosWithPending: TodoItem[] = [
+ { id: "1", content: "First task", status: "completed" },
+ { id: "2", content: "Second task", status: "pending" },
+ ]
+
+ mockTask.todoList = todosWithPending
+
+ // Enable the setting
+ mockGetConfiguration.mockReturnValue({
+ get: vi.fn((key: string, defaultValue: any) => {
+ if (key === "preventCompletionWithOpenTodos") {
+ return true // Setting is enabled
+ }
+ return defaultValue
+ }),
+ })
+
+ await attemptCompletionTool(
+ mockTask as Task,
+ block,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ mockToolDescription,
+ mockAskFinishSubTaskApproval,
+ )
+
+ // Should prevent completion when setting is enabled and there are incomplete todos
+ expect(mockTask.consecutiveMistakeCount).toBe(1)
+ expect(mockTask.recordToolError).toHaveBeenCalledWith("attempt_completion")
+ expect(mockPushToolResult).toHaveBeenCalledWith(
+ expect.stringContaining("Cannot complete task while there are incomplete todos"),
+ )
+ })
+
+ it("should allow completion when setting is enabled but all todos are completed", async () => {
+ const block: AttemptCompletionToolUse = {
+ type: "tool_use",
+ name: "attempt_completion",
+ params: { result: "Task completed successfully" },
+ partial: false,
+ }
+
+ const completedTodos: TodoItem[] = [
+ { id: "1", content: "First task", status: "completed" },
+ { id: "2", content: "Second task", status: "completed" },
+ ]
+
+ mockTask.todoList = completedTodos
+
+ // Enable the setting
+ mockGetConfiguration.mockReturnValue({
+ get: vi.fn((key: string, defaultValue: any) => {
+ if (key === "preventCompletionWithOpenTodos") {
+ return true // Setting is enabled
+ }
+ return defaultValue
+ }),
+ })
+
+ await attemptCompletionTool(
+ mockTask as Task,
+ block,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ mockToolDescription,
+ mockAskFinishSubTaskApproval,
+ )
+
+ // Should allow completion when setting is enabled but all todos are completed
+ expect(mockTask.consecutiveMistakeCount).toBe(0)
+ expect(mockTask.recordToolError).not.toHaveBeenCalled()
+ expect(mockPushToolResult).not.toHaveBeenCalledWith(
+ expect.stringContaining("Cannot complete task while there are incomplete todos"),
+ )
+ })
+ })
+})
diff --git a/src/core/tools/attemptCompletionTool.ts b/src/core/tools/attemptCompletionTool.ts
index 57f5870022..ef7881854f 100644
--- a/src/core/tools/attemptCompletionTool.ts
+++ b/src/core/tools/attemptCompletionTool.ts
@@ -1,4 +1,5 @@
import Anthropic from "@anthropic-ai/sdk"
+import * as vscode from "vscode"
import { TelemetryService } from "@roo-code/telemetry"
@@ -14,6 +15,7 @@ import {
AskFinishSubTaskApproval,
} from "../../shared/tools"
import { formatResponse } from "../prompts/responses"
+import { Package } from "../../shared/package"
export async function attemptCompletionTool(
cline: Task,
@@ -28,6 +30,25 @@ export async function attemptCompletionTool(
const result: string | undefined = block.params.result
const command: string | undefined = block.params.command
+ // Get the setting for preventing completion with open todos from VSCode configuration
+ const preventCompletionWithOpenTodos = vscode.workspace
+ .getConfiguration(Package.name)
+ .get("preventCompletionWithOpenTodos", false)
+
+ // Check if there are incomplete todos (only if the setting is enabled)
+ const hasIncompleteTodos = cline.todoList && cline.todoList.some((todo) => todo.status !== "completed")
+
+ if (preventCompletionWithOpenTodos && hasIncompleteTodos) {
+ cline.consecutiveMistakeCount++
+ cline.recordToolError("attempt_completion")
+ pushToolResult(
+ formatResponse.toolError(
+ "Cannot complete task while there are incomplete todos. Please finish all todos before attempting completion.",
+ ),
+ )
+ return
+ }
+
try {
const lastMessage = cline.clineMessages.at(-1)
diff --git a/src/core/webview/__tests__/ClineProvider.spec.ts b/src/core/webview/__tests__/ClineProvider.spec.ts
index 19c9a7c9fc..dd9ee12bfc 100644
--- a/src/core/webview/__tests__/ClineProvider.spec.ts
+++ b/src/core/webview/__tests__/ClineProvider.spec.ts
@@ -1163,15 +1163,10 @@ describe("ClineProvider", () => {
describe("deleteMessage", () => {
beforeEach(async () => {
- // Mock window.showInformationMessage
- ;(vscode.window.showInformationMessage as any) = vi.fn()
await provider.resolveWebviewView(mockWebviewView)
})
- test('handles "Just this message" deletion correctly', async () => {
- // Mock user selecting "Just this message"
- ;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.delete_just_this_message")
-
+ test("handles deletion with confirmation dialog", async () => {
// Setup mock messages
const mockMessages = [
{ ts: 1000, type: "say", say: "user_feedback" }, // User message 1
@@ -1202,103 +1197,58 @@ describe("ClineProvider", () => {
historyItem: { id: "test-task-id" },
})
+ // Mock initClineWithHistoryItem
+ ;(provider as any).initClineWithHistoryItem = vi.fn()
+
// Trigger message deletion
const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as any).mock.calls[0][0]
await messageHandler({ type: "deleteMessage", value: 4000 })
- // Verify correct messages were kept
- expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([
- mockMessages[0],
- mockMessages[1],
- mockMessages[4],
- mockMessages[5],
- ])
+ // Verify that the dialog message was sent to webview
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showDeleteMessageDialog",
+ messageTs: 4000,
+ })
- // Verify correct API messages were kept
+ // Simulate user confirming deletion through the dialog
+ await messageHandler({ type: "deleteMessageConfirm", messageTs: 4000 })
+
+ // Verify only messages before the deleted message were kept
+ expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([mockMessages[0], mockMessages[1]])
+
+ // Verify only API messages before the deleted message were kept
expect(mockCline.overwriteApiConversationHistory).toHaveBeenCalledWith([
mockApiHistory[0],
mockApiHistory[1],
- mockApiHistory[4],
- mockApiHistory[5],
])
+
+ // Verify initClineWithHistoryItem was called
+ expect((provider as any).initClineWithHistoryItem).toHaveBeenCalledWith({ id: "test-task-id" })
})
- test('handles "This and all subsequent messages" deletion correctly', async () => {
- // Mock user selecting "This and all subsequent messages"
- ;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.delete_this_and_subsequent")
-
- // Setup mock messages
- const mockMessages = [
- { ts: 1000, type: "say", say: "user_feedback" },
- { ts: 2000, type: "say", say: "text", value: 3000 }, // Message to delete
- { ts: 3000, type: "say", say: "user_feedback" },
- { ts: 4000, type: "say", say: "user_feedback" },
- ] as ClineMessage[]
-
- const mockApiHistory = [
- { ts: 1000 },
- { ts: 2000 },
- { ts: 3000 },
- { ts: 4000 },
- ] as (Anthropic.MessageParam & {
- ts?: number
- })[]
-
- // Setup Cline instance with auto-mock from the top of the file
- const mockCline = new Task(defaultTaskOptions) // Create a new mocked instance
- mockCline.clineMessages = mockMessages
- mockCline.apiConversationHistory = mockApiHistory
- await provider.addClineToStack(mockCline)
-
- // Mock getTaskWithId
- ;(provider as any).getTaskWithId = vi.fn().mockResolvedValue({
- historyItem: { id: "test-task-id" },
- })
-
- // Trigger message deletion
- const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as any).mock.calls[0][0]
- await messageHandler({ type: "deleteMessage", value: 3000 })
-
- // Verify only messages before the deleted message were kept
- expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([mockMessages[0]])
-
- // Verify only API messages before the deleted message were kept
- expect(mockCline.overwriteApiConversationHistory).toHaveBeenCalledWith([mockApiHistory[0]])
- })
-
- test("handles Cancel correctly", async () => {
- // Mock user selecting "Cancel"
- ;(vscode.window.showInformationMessage as any).mockResolvedValue("Cancel")
-
- // Setup Cline instance with auto-mock from the top of the file
- const mockCline = new Task(defaultTaskOptions) // Create a new mocked instance
- mockCline.clineMessages = [{ ts: 1000 }, { ts: 2000 }] as ClineMessage[]
- mockCline.apiConversationHistory = [{ ts: 1000 }, { ts: 2000 }] as (Anthropic.MessageParam & {
- ts?: number
- })[]
- await provider.addClineToStack(mockCline)
+ test("handles case when no current task exists", async () => {
+ // Clear the cline stack
+ ;(provider as any).clineStack = []
// Trigger message deletion
const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as any).mock.calls[0][0]
await messageHandler({ type: "deleteMessage", value: 2000 })
- // Verify no messages were deleted
- expect(mockCline.overwriteClineMessages).not.toHaveBeenCalled()
- expect(mockCline.overwriteApiConversationHistory).not.toHaveBeenCalled()
+ // Verify no dialog was shown since there's no current cline
+ expect(mockPostMessage).not.toHaveBeenCalledWith(
+ expect.objectContaining({
+ type: "showDeleteMessageDialog",
+ }),
+ )
})
})
describe("editMessage", () => {
beforeEach(async () => {
- // Mock window.showWarningMessage
- ;(vscode.window.showWarningMessage as any) = vi.fn()
await provider.resolveWebviewView(mockWebviewView)
})
- test('handles "Proceed" edit correctly', async () => {
- // Mock user selecting "Proceed" - need to use the localized string key
- ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
-
+ test("handles edit with confirmation dialog", async () => {
// Setup mock messages
const mockMessages = [
{ ts: 1000, type: "say", say: "user_feedback" }, // User message 1
@@ -1346,6 +1296,20 @@ describe("ClineProvider", () => {
editedMessageContent: "Edited message content",
})
+ // Verify that the dialog message was sent to webview
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showEditMessageDialog",
+ messageTs: 4000,
+ text: "Edited message content",
+ })
+
+ // Simulate user confirming edit through the dialog
+ await messageHandler({
+ type: "editMessageConfirm",
+ messageTs: 4000,
+ text: "Edited message content",
+ })
+
// Verify correct messages were kept (only messages before the edited one)
expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([mockMessages[0], mockMessages[1]])
@@ -1355,12 +1319,9 @@ describe("ClineProvider", () => {
mockApiHistory[1],
])
- // Verify handleWebviewAskResponse was called with the edited content
- expect(mockCline.handleWebviewAskResponse).toHaveBeenCalledWith(
- "messageResponse",
- "Edited message content",
- undefined,
- )
+ // The new flow calls webviewMessageHandler recursively with askResponse
+ // We need to verify the recursive call happened by checking if the handler was called again
+ expect((mockWebviewView.webview.onDidReceiveMessage as any).mock.calls.length).toBeGreaterThanOrEqual(1)
})
})
@@ -2705,13 +2666,10 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
describe("Edit Messages with Images and Attachments", () => {
beforeEach(async () => {
- ;(vscode.window.showInformationMessage as any) = vi.fn()
await provider.resolveWebviewView(mockWebviewView)
})
test("handles editing messages containing images", async () => {
- ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
-
const mockMessages = [
{ ts: 1000, type: "say", say: "user_feedback", text: "Original message" },
{
@@ -2746,17 +2704,26 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
editedMessageContent: "Edited message with preserved images",
})
- expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
- expect(mockCline.handleWebviewAskResponse).toHaveBeenCalledWith(
- "messageResponse",
- "Edited message with preserved images",
- undefined,
- )
+ // Verify dialog was shown
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showEditMessageDialog",
+ messageTs: 3000,
+ text: "Edited message with preserved images",
+ })
+
+ // Simulate confirmation
+ await messageHandler({
+ type: "editMessageConfirm",
+ messageTs: 3000,
+ text: "Edited message with preserved images",
+ })
+
+ // Verify messages were edited correctly - only the first message should remain
+ expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([mockMessages[0]])
+ expect(mockCline.overwriteApiConversationHistory).toHaveBeenCalledWith([{ ts: 1000 }])
})
test("handles editing messages with file attachments", async () => {
- ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
-
const mockMessages = [
{ ts: 1000, type: "say", say: "user_feedback", text: "Original message" },
{
@@ -2789,6 +2756,20 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
editedMessageContent: "Edited message with file attachment",
})
+ // Verify dialog was shown
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showEditMessageDialog",
+ messageTs: 3000,
+ text: "Edited message with file attachment",
+ })
+
+ // Simulate user confirming the edit
+ await messageHandler({
+ type: "editMessageConfirm",
+ messageTs: 3000,
+ text: "Edited message with file attachment",
+ })
+
expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
expect(mockCline.handleWebviewAskResponse).toHaveBeenCalledWith(
"messageResponse",
@@ -2805,8 +2786,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
})
test("handles network timeout during edit submission", async () => {
- ;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.proceed")
-
const mockCline = new Task(defaultTaskOptions)
mockCline.clineMessages = [
{ ts: 1000, type: "say", say: "user_feedback", text: "Original message", value: 2000 },
@@ -2833,12 +2812,20 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
}),
).resolves.toBeUndefined()
+ // Verify dialog was shown
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showEditMessageDialog",
+ messageTs: 2000,
+ text: "Edited message",
+ })
+
+ // Simulate user confirming the edit
+ await messageHandler({ type: "editMessageConfirm", messageTs: 2000, text: "Edited message" })
+
expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
})
test("handles connection drops during edit operation", async () => {
- ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
-
const mockCline = new Task(defaultTaskOptions)
mockCline.clineMessages = [
{ ts: 1000, type: "say", say: "user_feedback", text: "Original message", value: 2000 },
@@ -2865,6 +2852,17 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
}),
).resolves.toBeUndefined()
+ // Verify dialog was shown
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showEditMessageDialog",
+ messageTs: 2000,
+ text: "Edited message",
+ })
+
+ // Simulate user confirming the edit
+ await messageHandler({ type: "editMessageConfirm", messageTs: 2000, text: "Edited message" })
+
+ // The error should be caught and shown
expect(vscode.window.showErrorMessage).toHaveBeenCalledWith("Error editing message: Connection lost")
})
})
@@ -2876,8 +2874,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
})
test("handles race conditions with simultaneous edits", async () => {
- ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
-
const mockCline = new Task(defaultTaskOptions)
mockCline.clineMessages = [
{ ts: 1000, type: "say", say: "user_feedback", text: "Message 1", value: 2000 },
@@ -2912,6 +2908,22 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
await Promise.all([edit1Promise, edit2Promise])
+ // Verify dialogs were shown for both edits
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showEditMessageDialog",
+ messageTs: 2000,
+ text: "Edited message 1",
+ })
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showEditMessageDialog",
+ messageTs: 4000,
+ text: "Edited message 2",
+ })
+
+ // Simulate user confirming both edits
+ await messageHandler({ type: "editMessageConfirm", messageTs: 2000, text: "Edited message 1" })
+ await messageHandler({ type: "editMessageConfirm", messageTs: 4000, text: "Edited message 2" })
+
// Both operations should complete without throwing
expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
})
@@ -2940,8 +2952,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
})
test("handles authorization failures during edit", async () => {
- ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
-
const mockCline = new Task(defaultTaskOptions)
mockCline.clineMessages = [
{ ts: 1000, type: "say", say: "user_feedback", text: "Original message", value: 2000 },
@@ -2965,6 +2975,13 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
editedMessageContent: "Edited message",
})
+ // Simulate confirmation
+ await messageHandler({
+ type: "editMessageConfirm",
+ messageTs: 2000,
+ text: "Edited message",
+ })
+
expect(vscode.window.showErrorMessage).toHaveBeenCalledWith("Error editing message: Unauthorized")
})
@@ -3058,8 +3075,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
})
test("handles edit operations on deleted messages", async () => {
- ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
-
const mockCline = new Task(defaultTaskOptions)
mockCline.clineMessages = [
{ ts: 1000, type: "say", say: "user_feedback", text: "Existing message" },
@@ -3083,17 +3098,26 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
editedMessageContent: "Edited non-existent message",
})
- // Should show confirmation dialog but not perform any operations
- expect(vscode.window.showWarningMessage).toHaveBeenCalled()
+ // Should show edit dialog
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showEditMessageDialog",
+ messageTs: 5000,
+ text: "Edited non-existent message",
+ })
+
+ // Simulate user confirming the edit
+ await messageHandler({
+ type: "editMessageConfirm",
+ messageTs: 5000,
+ text: "Edited non-existent message",
+ })
+
+ // Should not perform any operations since message doesn't exist
expect(mockCline.overwriteClineMessages).not.toHaveBeenCalled()
expect(mockCline.handleWebviewAskResponse).not.toHaveBeenCalled()
})
test("handles delete operations on non-existent messages", async () => {
- ;(vscode.window.showInformationMessage as any).mockResolvedValue(
- "confirmation.delete_just_this_message",
- )
-
const mockCline = new Task(defaultTaskOptions)
mockCline.clineMessages = [
{ ts: 1000, type: "say", say: "user_feedback", text: "Existing message" },
@@ -3115,8 +3139,16 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
value: 5000,
})
- // Should show confirmation dialog but not perform any operations
- expect(vscode.window.showInformationMessage).toHaveBeenCalled()
+ // Should show delete dialog
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showDeleteMessageDialog",
+ messageTs: 5000,
+ })
+
+ // Simulate user confirming the delete
+ await messageHandler({ type: "deleteMessageConfirm", messageTs: 5000 })
+
+ // Should not perform any operations since message doesn't exist
expect(mockCline.overwriteClineMessages).not.toHaveBeenCalled()
})
})
@@ -3128,8 +3160,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
})
test("validates proper cleanup during failed edit operations", async () => {
- ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
-
const mockCline = new Task(defaultTaskOptions)
mockCline.clineMessages = [
{ ts: 1000, type: "say", say: "user_feedback", text: "Original message", value: 2000 },
@@ -3159,16 +3189,22 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
editedMessageContent: "Edited message",
})
+ // Should show edit dialog
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showEditMessageDialog",
+ messageTs: 2000,
+ text: "Edited message",
+ })
+
+ // Simulate user confirming the edit
+ await messageHandler({ type: "editMessageConfirm", messageTs: 2000, text: "Edited message" })
+
// Verify cleanup was attempted before failure
expect(cleanupSpy).toHaveBeenCalled()
expect(vscode.window.showErrorMessage).toHaveBeenCalledWith("Error editing message: Operation failed")
})
test("validates proper cleanup during failed delete operations", async () => {
- ;(vscode.window.showInformationMessage as any).mockResolvedValue(
- "confirmation.delete_just_this_message",
- )
-
const mockCline = new Task(defaultTaskOptions)
mockCline.clineMessages = [
{ ts: 1000, type: "say", say: "user_feedback", text: "Message to delete" },
@@ -3193,6 +3229,15 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
await messageHandler({ type: "deleteMessage", value: 2000 })
+ // Should show delete dialog
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showDeleteMessageDialog",
+ messageTs: 2000,
+ })
+
+ // Simulate user confirming the delete
+ await messageHandler({ type: "deleteMessageConfirm", messageTs: 2000 })
+
// Verify cleanup was attempted before failure
expect(cleanupSpy).toHaveBeenCalled()
expect(vscode.window.showErrorMessage).toHaveBeenCalledWith(
@@ -3208,8 +3253,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
})
test("handles editing messages with large text content", async () => {
- ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
-
// Create a large message (10KB of text)
const largeText = "A".repeat(10000)
const mockMessages = [
@@ -3238,6 +3281,16 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
editedMessageContent: largeEditedContent,
})
+ // Should show edit dialog
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showEditMessageDialog",
+ messageTs: 2000,
+ text: largeEditedContent,
+ })
+
+ // Simulate user confirming the edit
+ await messageHandler({ type: "editMessageConfirm", messageTs: 2000, text: largeEditedContent })
+
expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
expect(mockCline.handleWebviewAskResponse).toHaveBeenCalledWith(
"messageResponse",
@@ -3247,10 +3300,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
})
test("handles deleting messages with large payloads", async () => {
- ;(vscode.window.showInformationMessage as any).mockResolvedValue(
- "confirmation.delete_this_and_subsequent",
- )
-
// Create messages with large payloads
const largeText = "X".repeat(50000)
const mockMessages = [
@@ -3275,6 +3324,15 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
await messageHandler({ type: "deleteMessage", value: 3000 })
+ // Should show delete dialog
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showDeleteMessageDialog",
+ messageTs: 3000,
+ })
+
+ // Simulate user confirming the delete
+ await messageHandler({ type: "deleteMessageConfirm", messageTs: 3000 })
+
// Should handle large payloads without issues
expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([mockMessages[0]])
expect(mockCline.overwriteApiConversationHistory).toHaveBeenCalledWith([{ ts: 1000 }])
@@ -3285,10 +3343,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
// Note: Error messaging test removed as the implementation may not have proper error handling in place
test("provides user feedback for successful operations", async () => {
- ;(vscode.window.showInformationMessage as any).mockResolvedValue(
- "confirmation.delete_just_this_message",
- )
-
const mockCline = new Task(defaultTaskOptions)
mockCline.clineMessages = [
{ ts: 1000, type: "say", say: "user_feedback", text: "Message to delete" },
@@ -3308,6 +3362,15 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
await messageHandler({ type: "deleteMessage", value: 2000 })
+ // Should show delete dialog
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showDeleteMessageDialog",
+ messageTs: 2000,
+ })
+
+ // Simulate user confirming the delete
+ await messageHandler({ type: "deleteMessageConfirm", messageTs: 2000 })
+
// Verify successful operation completed
expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
expect(provider.initClineWithHistoryItem).toHaveBeenCalled()
@@ -3315,8 +3378,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
})
test("handles user cancellation gracefully", async () => {
- // Mock user canceling the operation
- ;(vscode.window.showWarningMessage as any).mockResolvedValue(undefined)
+ // Test cancellation by not sending confirmation
const mockCline = new Task(defaultTaskOptions)
mockCline.clineMessages = [
@@ -3353,10 +3415,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
})
test("handles messages with identical timestamps", async () => {
- ;(vscode.window.showInformationMessage as any).mockResolvedValue(
- "confirmation.delete_just_this_message",
- )
-
const mockCline = new Task(defaultTaskOptions)
mockCline.clineMessages = [
{ ts: 1000, type: "say", say: "user_feedback", text: "Message 1" },
@@ -3377,13 +3435,20 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
await messageHandler({ type: "deleteMessage", value: 1000 })
+ // Should show delete dialog
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showDeleteMessageDialog",
+ messageTs: 1000,
+ })
+
+ // Simulate user confirming the delete
+ await messageHandler({ type: "deleteMessageConfirm", messageTs: 1000 })
+
// Should handle identical timestamps gracefully
expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
})
test("handles messages with future timestamps", async () => {
- ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
-
const futureTimestamp = Date.now() + 100000 // Future timestamp
const mockCline = new Task(defaultTaskOptions)
mockCline.clineMessages = [
@@ -3419,6 +3484,20 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
editedMessageContent: "Edited future message",
})
+ // Should show edit dialog
+ expect(mockPostMessage).toHaveBeenCalledWith({
+ type: "showEditMessageDialog",
+ messageTs: futureTimestamp + 1000,
+ text: "Edited future message",
+ })
+
+ // Simulate user confirming the edit
+ await messageHandler({
+ type: "editMessageConfirm",
+ messageTs: futureTimestamp + 1000,
+ text: "Edited future message",
+ })
+
// Should handle future timestamps correctly
expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
expect(mockCline.handleWebviewAskResponse).toHaveBeenCalled()
diff --git a/src/core/webview/__tests__/webviewMessageHandler.spec.ts b/src/core/webview/__tests__/webviewMessageHandler.spec.ts
index 2f356aef55..284ee98944 100644
--- a/src/core/webview/__tests__/webviewMessageHandler.spec.ts
+++ b/src/core/webview/__tests__/webviewMessageHandler.spec.ts
@@ -28,9 +28,13 @@ const mockClineProvider = {
globalStorageUri: { fsPath: "/mock/global/storage" },
},
setValue: vi.fn(),
+ getValue: vi.fn(),
},
log: vi.fn(),
postStateToWebview: vi.fn(),
+ getCurrentCline: vi.fn(),
+ getTaskWithId: vi.fn(),
+ initClineWithHistoryItem: vi.fn(),
} as unknown as ClineProvider
import { t } from "../../../i18n"
@@ -482,3 +486,51 @@ describe("webviewMessageHandler - deleteCustomMode", () => {
expect(mockClineProvider.postMessageToWebview).not.toHaveBeenCalled()
})
})
+
+describe("webviewMessageHandler - message dialog preferences", () => {
+ beforeEach(() => {
+ vi.clearAllMocks()
+ // Mock a current Cline instance
+ vi.mocked(mockClineProvider.getCurrentCline).mockReturnValue({
+ taskId: "test-task-id",
+ apiConversationHistory: [],
+ clineMessages: [],
+ } as any)
+ // Reset getValue mock
+ vi.mocked(mockClineProvider.contextProxy.getValue).mockReturnValue(false)
+ })
+
+ describe("deleteMessage", () => {
+ it("should always show dialog for delete confirmation", async () => {
+ vi.mocked(mockClineProvider.getCurrentCline).mockReturnValue({} as any) // Mock current cline exists
+
+ await webviewMessageHandler(mockClineProvider, {
+ type: "deleteMessage",
+ value: 123456789, // Changed from messageTs to value
+ })
+
+ expect(mockClineProvider.postMessageToWebview).toHaveBeenCalledWith({
+ type: "showDeleteMessageDialog",
+ messageTs: 123456789,
+ })
+ })
+ })
+
+ describe("submitEditedMessage", () => {
+ it("should always show dialog for edit confirmation", async () => {
+ vi.mocked(mockClineProvider.getCurrentCline).mockReturnValue({} as any) // Mock current cline exists
+
+ await webviewMessageHandler(mockClineProvider, {
+ type: "submitEditedMessage",
+ value: 123456789, // messageTs as number
+ editedMessageContent: "edited content", // text content in editedMessageContent field
+ })
+
+ expect(mockClineProvider.postMessageToWebview).toHaveBeenCalledWith({
+ type: "showEditMessageDialog",
+ messageTs: 123456789,
+ text: "edited content",
+ })
+ })
+ })
+})
diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts
index fa14f477cc..25eaee3840 100644
--- a/src/core/webview/webviewMessageHandler.ts
+++ b/src/core/webview/webviewMessageHandler.ts
@@ -77,55 +77,6 @@ export const webviewMessageHandler = async (
return { messageIndex, apiConversationHistoryIndex }
}
- /**
- * Removes just the target message, preserving messages after the next user message
- */
- const removeMessagesJustThis = async (
- currentCline: any,
- messageIndex: number,
- apiConversationHistoryIndex: number,
- ) => {
- // Find the next user message first
- const nextUserMessage = currentCline.clineMessages
- .slice(messageIndex + 1)
- .find((msg: ClineMessage) => msg.type === "say" && msg.say === "user_feedback")
-
- // Handle UI messages
- if (nextUserMessage) {
- // Find absolute index of next user message
- const nextUserMessageIndex = currentCline.clineMessages.findIndex(
- (msg: ClineMessage) => msg === nextUserMessage,
- )
-
- // Keep messages before current message and after next user message
- await currentCline.overwriteClineMessages([
- ...currentCline.clineMessages.slice(0, messageIndex),
- ...currentCline.clineMessages.slice(nextUserMessageIndex),
- ])
- } else {
- // If no next user message, keep only messages before current message
- await currentCline.overwriteClineMessages(currentCline.clineMessages.slice(0, messageIndex))
- }
-
- // Handle API messages
- if (apiConversationHistoryIndex !== -1) {
- if (nextUserMessage && nextUserMessage.ts) {
- // Keep messages before current API message and after next user message
- await currentCline.overwriteApiConversationHistory([
- ...currentCline.apiConversationHistory.slice(0, apiConversationHistoryIndex),
- ...currentCline.apiConversationHistory.filter(
- (msg: ApiMessage) => msg.ts && msg.ts >= nextUserMessage.ts,
- ),
- ])
- } else {
- // If no next user message, keep only messages before current API message
- await currentCline.overwriteApiConversationHistory(
- currentCline.apiConversationHistory.slice(0, apiConversationHistoryIndex),
- )
- }
- }
- }
-
/**
* Removes the target message and all subsequent messages
*/
@@ -148,19 +99,19 @@ export const webviewMessageHandler = async (
* Handles message deletion operations with user confirmation
*/
const handleDeleteOperation = async (messageTs: number): Promise => {
- const options = [
- t("common:confirmation.delete_just_this_message"),
- t("common:confirmation.delete_this_and_subsequent"),
- ]
+ // Send message to webview to show delete confirmation dialog
+ await provider.postMessageToWebview({
+ type: "showDeleteMessageDialog",
+ messageTs,
+ })
+ }
- const answer = await vscode.window.showInformationMessage(
- t("common:confirmation.delete_message"),
- { modal: true },
- ...options,
- )
-
- // Only proceed if user selected one of the options and we have a current cline
- if (answer && options.includes(answer) && provider.getCurrentCline()) {
+ /**
+ * Handles confirmed message deletion from webview dialog
+ */
+ const handleDeleteMessageConfirm = async (messageTs: number): Promise => {
+ // Only proceed if we have a current cline
+ if (provider.getCurrentCline()) {
const currentCline = provider.getCurrentCline()!
const { messageIndex, apiConversationHistoryIndex } = findMessageIndices(messageTs, currentCline)
@@ -168,14 +119,8 @@ export const webviewMessageHandler = async (
try {
const { historyItem } = await provider.getTaskWithId(currentCline.taskId)
- // Check which option the user selected
- if (answer === options[0]) {
- // Delete just this message
- await removeMessagesJustThis(currentCline, messageIndex, apiConversationHistoryIndex)
- } else if (answer === options[1]) {
- // Delete this message and all subsequent
- await removeMessagesThisAndSubsequent(currentCline, messageIndex, apiConversationHistoryIndex)
- }
+ // Delete this message and all subsequent messages
+ await removeMessagesThisAndSubsequent(currentCline, messageIndex, apiConversationHistoryIndex)
// Initialize with history item after deletion
await provider.initClineWithHistoryItem(historyItem)
@@ -192,15 +137,26 @@ export const webviewMessageHandler = async (
/**
* Handles message editing operations with user confirmation
*/
- const handleEditOperation = async (messageTs: number, editedContent: string): Promise => {
- const answer = await vscode.window.showWarningMessage(
- t("common:confirmation.edit_warning"),
- { modal: true },
- t("common:confirmation.proceed"),
- )
+ const handleEditOperation = async (messageTs: number, editedContent: string, images?: string[]): Promise => {
+ // Send message to webview to show edit confirmation dialog
+ await provider.postMessageToWebview({
+ type: "showEditMessageDialog",
+ messageTs,
+ text: editedContent,
+ images,
+ })
+ }
- // Only proceed if user selected "Proceed" and we have a current cline
- if (answer === t("common:confirmation.proceed") && provider.getCurrentCline()) {
+ /**
+ * Handles confirmed message editing from webview dialog
+ */
+ const handleEditMessageConfirm = async (
+ messageTs: number,
+ editedContent: string,
+ images?: string[],
+ ): Promise => {
+ // Only proceed if we have a current cline
+ if (provider.getCurrentCline()) {
const currentCline = provider.getCurrentCline()!
// Use findMessageIndices to find messages based on timestamp
@@ -217,6 +173,7 @@ export const webviewMessageHandler = async (
type: "askResponse",
askResponse: "messageResponse",
text: editedContent,
+ images,
})
// Don't initialize with history item for edit operations
@@ -242,11 +199,12 @@ export const webviewMessageHandler = async (
messageTs: number,
operation: "delete" | "edit",
editedContent?: string,
+ images?: string[],
): Promise => {
if (operation === "delete") {
await handleDeleteOperation(messageTs)
} else if (operation === "edit" && editedContent) {
- await handleEditOperation(messageTs, editedContent)
+ await handleEditOperation(messageTs, editedContent, images)
}
}
@@ -416,7 +374,12 @@ export const webviewMessageHandler = async (
break
case "selectImages":
const images = await selectImages()
- await provider.postMessageToWebview({ type: "selectedImages", images })
+ await provider.postMessageToWebview({
+ type: "selectedImages",
+ images,
+ context: message.context,
+ messageTs: message.messageTs,
+ })
break
case "exportCurrentTask":
const currentTaskId = provider.getCurrentCline()?.taskId
@@ -1209,7 +1172,12 @@ export const webviewMessageHandler = async (
message.value &&
message.editedMessageContent
) {
- await handleMessageModificationsOperation(message.value, "edit", message.editedMessageContent)
+ await handleMessageModificationsOperation(
+ message.value,
+ "edit",
+ message.editedMessageContent,
+ message.images,
+ )
}
break
}
@@ -1542,6 +1510,16 @@ export const webviewMessageHandler = async (
}
}
break
+ case "deleteMessageConfirm":
+ if (message.messageTs) {
+ await handleDeleteMessageConfirm(message.messageTs)
+ }
+ break
+ case "editMessageConfirm":
+ if (message.messageTs && message.text) {
+ await handleEditMessageConfirm(message.messageTs, message.text, message.images)
+ }
+ break
case "getListApiConfiguration":
try {
const listApiConfig = await provider.providerSettingsManager.listConfig()
diff --git a/src/extension/api.ts b/src/extension/api.ts
index 3bb538dcb3..7027cb963a 100644
--- a/src/extension/api.ts
+++ b/src/extension/api.ts
@@ -2,6 +2,7 @@ import { EventEmitter } from "events"
import * as vscode from "vscode"
import fs from "fs/promises"
import * as path from "path"
+import * as os from "os"
import {
RooCodeAPI,
@@ -50,7 +51,7 @@ export class API extends EventEmitter implements RooCodeAPI {
console.log(args)
}
- this.logfile = path.join(getWorkspacePath(), "roo-code-messages.log")
+ this.logfile = path.join(os.tmpdir(), "roo-code-messages.log")
} else {
this.log = () => {}
}
@@ -125,6 +126,22 @@ export class API extends EventEmitter implements RooCodeAPI {
.getConfiguration(Package.name)
.update("allowedCommands", configuration.allowedCommands, vscode.ConfigurationTarget.Global)
}
+
+ if (configuration.deniedCommands) {
+ await vscode.workspace
+ .getConfiguration(Package.name)
+ .update("deniedCommands", configuration.deniedCommands, vscode.ConfigurationTarget.Global)
+ }
+
+ if (configuration.commandExecutionTimeout !== undefined) {
+ await vscode.workspace
+ .getConfiguration(Package.name)
+ .update(
+ "commandExecutionTimeout",
+ configuration.commandExecutionTimeout,
+ vscode.ConfigurationTarget.Global,
+ )
+ }
}
await provider.removeClineFromStack()
@@ -223,9 +240,11 @@ export class API extends EventEmitter implements RooCodeAPI {
cline.on("taskCompleted", async (_, tokenUsage, toolUsage) => {
let isSubtask = false
+
if (cline.rootTask != undefined) {
isSubtask = true
}
+
this.emit(RooCodeEventName.TaskCompleted, cline.taskId, tokenUsage, toolUsage, { isSubtask: isSubtask })
this.taskMap.delete(cline.taskId)
diff --git a/src/i18n/locales/ca/common.json b/src/i18n/locales/ca/common.json
index 7dac4d7431..633208d4bc 100644
--- a/src/i18n/locales/ca/common.json
+++ b/src/i18n/locales/ca/common.json
@@ -21,12 +21,7 @@
"confirmation": {
"reset_state": "Estàs segur que vols restablir tots els estats i emmagatzematge secret a l'extensió? Això no es pot desfer.",
"delete_config_profile": "Estàs segur que vols eliminar aquest perfil de configuració?",
- "delete_custom_mode_with_rules": "Esteu segur que voleu suprimir aquest mode {scope}?\n\nAixò també suprimirà la carpeta de regles associada a:\n{rulesFolderPath}",
- "delete_message": "Què vols eliminar?",
- "edit_warning": "Editar aquest missatge eliminarà tots els missatges posteriors de la conversa. Vols continuar?",
- "delete_just_this_message": "Només aquest missatge",
- "delete_this_and_subsequent": "Aquest i tots els missatges posteriors",
- "proceed": "Continuar"
+ "delete_custom_mode_with_rules": "Esteu segur que voleu suprimir aquest mode {scope}?\n\nAixò també suprimirà la carpeta de regles associada a:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "Format d'URI de dades no vàlid",
@@ -171,5 +166,10 @@
"descriptionNoRules": "Esteu segur que voleu suprimir aquest mode personalitzat?",
"confirm": "Suprimeix"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "Evitar la finalització de tasques quan hi ha todos incomplets a la llista de todos"
+ }
}
}
diff --git a/src/i18n/locales/de/common.json b/src/i18n/locales/de/common.json
index db9ba9b51c..71155b1ebe 100644
--- a/src/i18n/locales/de/common.json
+++ b/src/i18n/locales/de/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "Möchtest du wirklich alle Zustände und geheimen Speicher in der Erweiterung zurücksetzen? Dies kann nicht rückgängig gemacht werden.",
"delete_config_profile": "Möchtest du dieses Konfigurationsprofil wirklich löschen?",
- "delete_custom_mode_with_rules": "Bist du sicher, dass du diesen {scope}-Modus löschen möchtest?\n\nDadurch wird auch der zugehörige Regelordner unter folgender Adresse gelöscht:\n{rulesFolderPath}",
- "delete_message": "Was möchtest du löschen?",
- "edit_warning": "Das Bearbeiten dieser Nachricht wird alle nachfolgenden Nachrichten in der Unterhaltung löschen. Möchtest du fortfahren?",
- "delete_just_this_message": "Nur diese Nachricht",
- "delete_this_and_subsequent": "Diese und alle nachfolgenden Nachrichten",
- "proceed": "Fortfahren"
+ "delete_custom_mode_with_rules": "Bist du sicher, dass du diesen {scope}-Modus löschen möchtest?\n\nDadurch wird auch der zugehörige Regelordner unter folgender Adresse gelöscht:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "Ungültiges Daten-URI-Format",
@@ -171,5 +166,10 @@
"descriptionNoRules": "Bist du sicher, dass du diesen benutzerdefinierten Modus löschen möchtest?",
"confirm": "Löschen"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "Aufgabenabschluss verhindern, wenn unvollständige Todos in der Todo-Liste vorhanden sind"
+ }
}
}
diff --git a/src/i18n/locales/en/common.json b/src/i18n/locales/en/common.json
index 84d3798519..6bab0ab9a9 100644
--- a/src/i18n/locales/en/common.json
+++ b/src/i18n/locales/en/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "Are you sure you want to reset all state and secret storage in the extension? This cannot be undone.",
"delete_config_profile": "Are you sure you want to delete this configuration profile?",
- "delete_custom_mode_with_rules": "Are you sure you want to delete this {scope} mode?\n\nThis will also delete the associated rules folder at:\n{rulesFolderPath}",
- "delete_message": "What would you like to delete?",
- "edit_warning": "Editing this message will delete all subsequent messages in the conversation. Do you want to proceed?",
- "delete_just_this_message": "Just this message",
- "delete_this_and_subsequent": "This and all subsequent messages",
- "proceed": "Proceed"
+ "delete_custom_mode_with_rules": "Are you sure you want to delete this {scope} mode?\n\nThis will also delete the associated rules folder at:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "Invalid data URI format",
@@ -160,5 +155,10 @@
"descriptionNoRules": "Are you sure you want to delete this custom mode?",
"confirm": "Delete"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "Prevent task completion when there are incomplete todos in the todo list"
+ }
}
}
diff --git a/src/i18n/locales/es/common.json b/src/i18n/locales/es/common.json
index cdd26831a5..d307800c79 100644
--- a/src/i18n/locales/es/common.json
+++ b/src/i18n/locales/es/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "¿Estás seguro de que deseas restablecer todo el estado y el almacenamiento secreto en la extensión? Esta acción no se puede deshacer.",
"delete_config_profile": "¿Estás seguro de que deseas eliminar este perfil de configuración?",
- "delete_custom_mode_with_rules": "¿Estás seguro de que quieres eliminar este modo {scope}?\n\nEsto también eliminará la carpeta de reglas asociada en:\n{rulesFolderPath}",
- "delete_message": "¿Qué deseas eliminar?",
- "edit_warning": "Editar este mensaje eliminará todos los mensajes posteriores en la conversación. ¿Deseas continuar?",
- "delete_just_this_message": "Solo este mensaje",
- "delete_this_and_subsequent": "Este y todos los mensajes posteriores",
- "proceed": "Continuar"
+ "delete_custom_mode_with_rules": "¿Estás seguro de que quieres eliminar este modo {scope}?\n\nEsto también eliminará la carpeta de reglas asociada en:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "Formato de URI de datos no válido",
@@ -171,5 +166,10 @@
"descriptionNoRules": "¿Estás seguro de que quieres eliminar este modo personalizado?",
"confirm": "Eliminar"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "Prevenir la finalización de tareas cuando hay todos incompletos en la lista de todos"
+ }
}
}
diff --git a/src/i18n/locales/fr/common.json b/src/i18n/locales/fr/common.json
index 3ddacdda59..b0571e3714 100644
--- a/src/i18n/locales/fr/common.json
+++ b/src/i18n/locales/fr/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "Êtes-vous sûr de vouloir réinitialiser le global state et le stockage de secrets de l'extension ? Cette action est irréversible.",
"delete_config_profile": "Êtes-vous sûr de vouloir supprimer ce profil de configuration ?",
- "delete_custom_mode_with_rules": "Êtes-vous sûr de vouloir supprimer ce mode {scope} ?\n\nCela supprimera également le dossier de règles associé à l'adresse :\n{rulesFolderPath}",
- "delete_message": "Que souhaitez-vous supprimer ?",
- "edit_warning": "Modifier ce message supprimera tous les messages suivants dans la conversation. Voulez-vous continuer ?",
- "delete_just_this_message": "Uniquement ce message",
- "delete_this_and_subsequent": "Ce message et tous les messages suivants",
- "proceed": "Continuer"
+ "delete_custom_mode_with_rules": "Êtes-vous sûr de vouloir supprimer ce mode {scope} ?\n\nCela supprimera également le dossier de règles associé à l'adresse :\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "Format d'URI de données invalide",
@@ -171,5 +166,10 @@
"descriptionNoRules": "Êtes-vous sûr de vouloir supprimer ce mode personnalisé ?",
"confirm": "Supprimer"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "Empêcher la finalisation des tâches lorsqu'il y a des todos incomplets dans la liste de todos"
+ }
}
}
diff --git a/src/i18n/locales/hi/common.json b/src/i18n/locales/hi/common.json
index 8637426846..ca4efea535 100644
--- a/src/i18n/locales/hi/common.json
+++ b/src/i18n/locales/hi/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "क्या आप वाकई एक्सटेंशन में सभी स्टेट और गुप्त स्टोरेज रीसेट करना चाहते हैं? इसे पूर्ववत नहीं किया जा सकता है।",
"delete_config_profile": "क्या आप वाकई इस कॉन्फ़िगरेशन प्रोफ़ाइल को हटाना चाहते हैं?",
- "delete_custom_mode_with_rules": "क्या आप वाकई इस {scope} मोड को हटाना चाहते हैं?\n\nयह संबंधित नियम फ़ोल्डर को भी यहाँ हटा देगा:\n{rulesFolderPath}",
- "delete_message": "आप क्या हटाना चाहते हैं?",
- "edit_warning": "इस संदेश को संपादित करने से बातचीत के सभी बाद के संदेश हट जाएंगे। क्या आप जारी रखना चाहते हैं?",
- "delete_just_this_message": "सिर्फ यह संदेश",
- "delete_this_and_subsequent": "यह और सभी बाद के संदेश",
- "proceed": "जारी रखें"
+ "delete_custom_mode_with_rules": "क्या आप वाकई इस {scope} मोड को हटाना चाहते हैं?\n\nयह संबंधित नियम फ़ोल्डर को भी यहाँ हटा देगा:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "अमान्य डेटा URI फॉर्मेट",
@@ -171,5 +166,10 @@
"descriptionNoRules": "क्या आप वाकई इस कस्टम मोड को हटाना चाहते हैं?",
"confirm": "हटाएं"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "जब टूडू सूची में अधूरे टूडू हों तो कार्य पूर्ण होने से रोकें"
+ }
}
}
diff --git a/src/i18n/locales/id/common.json b/src/i18n/locales/id/common.json
index df3fe2cefb..46ce587e61 100644
--- a/src/i18n/locales/id/common.json
+++ b/src/i18n/locales/id/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "Apakah kamu yakin ingin mereset semua state dan secret storage di ekstensi? Ini tidak dapat dibatalkan.",
"delete_config_profile": "Apakah kamu yakin ingin menghapus profil konfigurasi ini?",
- "delete_custom_mode_with_rules": "Anda yakin ingin menghapus mode {scope} ini?\n\nIni juga akan menghapus folder aturan terkait di:\n{rulesFolderPath}",
- "delete_message": "Apa yang ingin kamu hapus?",
- "edit_warning": "Mengedit pesan ini akan menghapus semua pesan selanjutnya dalam percakapan. Apakah kamu ingin melanjutkan?",
- "delete_just_this_message": "Hanya pesan ini",
- "delete_this_and_subsequent": "Ini dan semua pesan selanjutnya",
- "proceed": "Lanjutkan"
+ "delete_custom_mode_with_rules": "Anda yakin ingin menghapus mode {scope} ini?\n\nIni juga akan menghapus folder aturan terkait di:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "Format data URI tidak valid",
@@ -171,5 +166,10 @@
"descriptionNoRules": "Anda yakin ingin menghapus mode kustom ini?",
"confirm": "Hapus"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "Mencegah penyelesaian tugas ketika ada todo yang belum selesai dalam daftar todo"
+ }
}
}
diff --git a/src/i18n/locales/it/common.json b/src/i18n/locales/it/common.json
index d12e376c0c..11bae26eb3 100644
--- a/src/i18n/locales/it/common.json
+++ b/src/i18n/locales/it/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "Sei sicuro di voler reimpostare tutti gli stati e l'archiviazione segreta nell'estensione? Questa azione non può essere annullata.",
"delete_config_profile": "Sei sicuro di voler eliminare questo profilo di configurazione?",
- "delete_custom_mode_with_rules": "Sei sicuro di voler eliminare questa modalità {scope}?\n\nQuesto eliminerà anche la cartella delle regole associata in:\n{rulesFolderPath}",
- "delete_message": "Cosa desideri eliminare?",
- "edit_warning": "Modificare questo messaggio eliminerà tutti i messaggi successivi nella conversazione. Vuoi continuare?",
- "delete_just_this_message": "Solo questo messaggio",
- "delete_this_and_subsequent": "Questo e tutti i messaggi successivi",
- "proceed": "Continua"
+ "delete_custom_mode_with_rules": "Sei sicuro di voler eliminare questa modalità {scope}?\n\nQuesto eliminerà anche la cartella delle regole associata in:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "Formato URI dati non valido",
@@ -171,5 +166,10 @@
"descriptionNoRules": "Sei sicuro di voler eliminare questa modalità personalizzata?",
"confirm": "Elimina"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "Impedire il completamento delle attività quando ci sono todo incompleti nella lista dei todo"
+ }
}
}
diff --git a/src/i18n/locales/ja/common.json b/src/i18n/locales/ja/common.json
index 56be64c44c..52ab094633 100644
--- a/src/i18n/locales/ja/common.json
+++ b/src/i18n/locales/ja/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "拡張機能のすべての状態とシークレットストレージをリセットしてもよろしいですか?この操作は元に戻せません。",
"delete_config_profile": "この設定プロファイルを削除してもよろしいですか?",
- "delete_custom_mode_with_rules": "この{scope}モードを削除してもよろしいですか?\n\nこれにより、関連するルールフォルダも次の場所で削除されます:\n{rulesFolderPath}",
- "delete_message": "何を削除しますか?",
- "edit_warning": "このメッセージを編集すると、会話内のすべての後続メッセージが削除されます。続行しますか?",
- "delete_just_this_message": "このメッセージのみ",
- "delete_this_and_subsequent": "これ以降のすべてのメッセージ",
- "proceed": "続行"
+ "delete_custom_mode_with_rules": "この{scope}モードを削除してもよろしいですか?\n\nこれにより、関連するルールフォルダも次の場所で削除されます:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "データURIフォーマットが無効です",
@@ -171,5 +166,10 @@
"descriptionNoRules": "このカスタムモードを削除してもよろしいですか?",
"confirm": "削除"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "Todoリストに未完了のTodoがある場合、タスクの完了を防ぐ"
+ }
}
}
diff --git a/src/i18n/locales/ko/common.json b/src/i18n/locales/ko/common.json
index 0b12455c0f..63566f946b 100644
--- a/src/i18n/locales/ko/common.json
+++ b/src/i18n/locales/ko/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "확장 프로그램의 모든 상태와 보안 저장소를 재설정하시겠습니까? 이 작업은 취소할 수 없습니다.",
"delete_config_profile": "이 구성 프로필을 삭제하시겠습니까?",
- "delete_custom_mode_with_rules": "이 {scope} 모드를 삭제하시겠습니까?\n\n이렇게 하면 연결된 규칙 폴더도 다음 위치에서 삭제됩니다:\n{rulesFolderPath}",
- "delete_message": "무엇을 삭제하시겠습니까?",
- "edit_warning": "이 메시지를 편집하면 대화의 모든 후속 메시지가 삭제됩니다. 계속하시겠습니까?",
- "delete_just_this_message": "이 메시지만",
- "delete_this_and_subsequent": "이 메시지와 모든 후속 메시지",
- "proceed": "계속"
+ "delete_custom_mode_with_rules": "이 {scope} 모드를 삭제하시겠습니까?\n\n이렇게 하면 연결된 규칙 폴더도 다음 위치에서 삭제됩니다:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "잘못된 데이터 URI 형식",
@@ -171,5 +166,10 @@
"descriptionNoRules": "이 사용자 정의 모드를 삭제하시겠습니까?",
"confirm": "삭제"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "할 일 목록에 미완료된 할 일이 있을 때 작업 완료를 방지"
+ }
}
}
diff --git a/src/i18n/locales/nl/common.json b/src/i18n/locales/nl/common.json
index 43fda70dc2..fc3c1ce018 100644
--- a/src/i18n/locales/nl/common.json
+++ b/src/i18n/locales/nl/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "Weet je zeker dat je alle status en geheime opslag in de extensie wilt resetten? Dit kan niet ongedaan worden gemaakt.",
"delete_config_profile": "Weet je zeker dat je dit configuratieprofiel wilt verwijderen?",
- "delete_custom_mode_with_rules": "Weet je zeker dat je deze {scope}-modus wilt verwijderen?\n\nDit verwijdert ook de bijbehorende regelsmap op:\n{rulesFolderPath}",
- "delete_message": "Wat wil je verwijderen?",
- "delete_just_this_message": "Alleen dit bericht",
- "delete_this_and_subsequent": "Dit en alle volgende berichten",
- "edit_warning": "Het bewerken van dit bericht zal alle volgende berichten in het gesprek verwijderen. Wil je doorgaan?",
- "proceed": "Doorgaan"
+ "delete_custom_mode_with_rules": "Weet je zeker dat je deze {scope}-modus wilt verwijderen?\n\nDit verwijdert ook de bijbehorende regelsmap op:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "Ongeldig data-URI-formaat",
@@ -171,5 +166,10 @@
"descriptionNoRules": "Weet je zeker dat je deze aangepaste modus wilt verwijderen?",
"confirm": "Verwijderen"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "Voorkom taakafronding wanneer er onvolledige todos in de todolijst staan"
+ }
}
}
diff --git a/src/i18n/locales/pl/common.json b/src/i18n/locales/pl/common.json
index 80a299c7df..ef756ec1ce 100644
--- a/src/i18n/locales/pl/common.json
+++ b/src/i18n/locales/pl/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "Czy na pewno chcesz zresetować wszystkie stany i tajne magazyny w rozszerzeniu? Tej operacji nie można cofnąć.",
"delete_config_profile": "Czy na pewno chcesz usunąć ten profil konfiguracyjny?",
- "delete_custom_mode_with_rules": "Czy na pewno chcesz usunąć ten tryb {scope}?\n\nSpowoduje to również usunięcie powiązanego folderu reguł pod adresem:\n{rulesFolderPath}",
- "delete_message": "Co chcesz usunąć?",
- "delete_just_this_message": "Tylko tę wiadomość",
- "delete_this_and_subsequent": "Tę i wszystkie kolejne wiadomości",
- "edit_warning": "Edytowanie tej wiadomości usunie wszystkie kolejne wiadomości w rozmowie. Czy chcesz kontynuować?",
- "proceed": "Kontynuuj"
+ "delete_custom_mode_with_rules": "Czy na pewno chcesz usunąć ten tryb {scope}?\n\nSpowoduje to również usunięcie powiązanego folderu reguł pod adresem:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "Nieprawidłowy format URI danych",
@@ -171,5 +166,10 @@
"descriptionNoRules": "Czy na pewno chcesz usunąć ten tryb niestandardowy?",
"confirm": "Usuń"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "Zapobiegaj ukończeniu zadania gdy na liście zadań są nieukończone zadania"
+ }
}
}
diff --git a/src/i18n/locales/pt-BR/common.json b/src/i18n/locales/pt-BR/common.json
index 6205a5fb7a..8856e541be 100644
--- a/src/i18n/locales/pt-BR/common.json
+++ b/src/i18n/locales/pt-BR/common.json
@@ -21,12 +21,7 @@
"confirmation": {
"reset_state": "Tem certeza de que deseja redefinir todo o estado e armazenamento secreto na extensão? Isso não pode ser desfeito.",
"delete_config_profile": "Tem certeza de que deseja excluir este perfil de configuração?",
- "delete_custom_mode_with_rules": "Tem certeza de que deseja excluir este modo {scope}?\n\nIsso também excluirá a pasta de regras associada em:\n{rulesFolderPath}",
- "delete_message": "O que você gostaria de excluir?",
- "delete_just_this_message": "Apenas esta mensagem",
- "delete_this_and_subsequent": "Esta e todas as mensagens subsequentes",
- "edit_warning": "Editar esta mensagem excluirá todas as mensagens subsequentes na conversa. Deseja continuar?",
- "proceed": "Continuar"
+ "delete_custom_mode_with_rules": "Tem certeza de que deseja excluir este modo {scope}?\n\nIsso também excluirá a pasta de regras associada em:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "Formato de URI de dados inválido",
@@ -171,5 +166,10 @@
"descriptionNoRules": "Tem certeza de que deseja excluir este modo personalizado?",
"confirm": "Excluir"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "Impedir a conclusão de tarefas quando há todos incompletos na lista de todos"
+ }
}
}
diff --git a/src/i18n/locales/ru/common.json b/src/i18n/locales/ru/common.json
index f537d1a2d3..fd23dffe2a 100644
--- a/src/i18n/locales/ru/common.json
+++ b/src/i18n/locales/ru/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "Вы уверены, что хотите сбросить все состояние и секретное хранилище в расширении? Это действие нельзя отменить.",
"delete_config_profile": "Вы уверены, что хотите удалить этот профиль конфигурации?",
- "delete_custom_mode_with_rules": "Вы уверены, что хотите удалить этот режим {scope}?\n\nЭто также приведет к удалению соответствующей папки правил по адресу:\n{rulesFolderPath}",
- "delete_message": "Что вы хотите удалить?",
- "delete_just_this_message": "Только это сообщение",
- "delete_this_and_subsequent": "Это и все последующие сообщения",
- "edit_warning": "Редактирование этого сообщения удалит все последующие сообщения в разговоре. Хотите продолжить?",
- "proceed": "Продолжить"
+ "delete_custom_mode_with_rules": "Вы уверены, что хотите удалить этот режим {scope}?\n\nЭто также приведет к удалению соответствующей папки правил по адресу:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "Неверный формат URI данных",
@@ -171,5 +166,10 @@
"descriptionNoRules": "Вы уверены, что хотите удалить этот пользовательский режим?",
"confirm": "Удалить"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "Предотвратить завершение задач при наличии незавершенных дел в списке дел"
+ }
}
}
diff --git a/src/i18n/locales/tr/common.json b/src/i18n/locales/tr/common.json
index 61e244186e..9eeae720ef 100644
--- a/src/i18n/locales/tr/common.json
+++ b/src/i18n/locales/tr/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "Uzantıdaki tüm durumları ve gizli depolamayı sıfırlamak istediğinizden emin misiniz? Bu işlem geri alınamaz.",
"delete_config_profile": "Bu yapılandırma profilini silmek istediğinizden emin misiniz?",
- "delete_custom_mode_with_rules": "Bu {scope} modunu silmek istediğinizden emin misiniz?\n\nBu işlem, ilişkili kurallar klasörünü de şu konumdan silecektir:\n{rulesFolderPath}",
- "delete_message": "Neyi silmek istersiniz?",
- "delete_just_this_message": "Sadece bu mesajı",
- "delete_this_and_subsequent": "Bu ve sonraki tüm mesajları",
- "edit_warning": "Bu mesajı düzenlemek konuşmadaki tüm sonraki mesajları silecektir. Devam etmek istiyor musunuz?",
- "proceed": "Devam et"
+ "delete_custom_mode_with_rules": "Bu {scope} modunu silmek istediğinizden emin misiniz?\n\nBu işlem, ilişkili kurallar klasörünü de şu konumdan silecektir:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "Geçersiz veri URI formatı",
@@ -171,5 +166,10 @@
"descriptionNoRules": "Bu özel modu silmek istediğinizden emin misiniz?",
"confirm": "Sil"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "Todo listesinde tamamlanmamış todolar olduğunda görev tamamlanmasını engelle"
+ }
}
}
diff --git a/src/i18n/locales/vi/common.json b/src/i18n/locales/vi/common.json
index 6106f71fa0..bd66d623bb 100644
--- a/src/i18n/locales/vi/common.json
+++ b/src/i18n/locales/vi/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "Bạn có chắc chắn muốn đặt lại tất cả trạng thái và lưu trữ bí mật trong tiện ích mở rộng không? Hành động này không thể hoàn tác.",
"delete_config_profile": "Bạn có chắc chắn muốn xóa hồ sơ cấu hình này không?",
- "delete_custom_mode_with_rules": "Bạn có chắc chắn muốn xóa chế độ {scope} này không?\n\nThao tác này cũng sẽ xóa thư mục quy tắc liên quan tại:\n{rulesFolderPath}",
- "delete_message": "Bạn muốn xóa gì?",
- "delete_just_this_message": "Chỉ tin nhắn này",
- "delete_this_and_subsequent": "Tin nhắn này và tất cả tin nhắn tiếp theo",
- "edit_warning": "Chỉnh sửa tin nhắn này sẽ xóa tất cả tin nhắn tiếp theo trong cuộc trò chuyện. Bạn có muốn tiếp tục không?",
- "proceed": "Tiếp tục"
+ "delete_custom_mode_with_rules": "Bạn có chắc chắn muốn xóa chế độ {scope} này không?\n\nThao tác này cũng sẽ xóa thư mục quy tắc liên quan tại:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "Định dạng URI dữ liệu không hợp lệ",
@@ -178,5 +173,10 @@
"descriptionNoRules": "Bạn có chắc chắn muốn xóa chế độ tùy chỉnh này không?",
"confirm": "Xóa"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "Ngăn chặn hoàn thành nhiệm vụ khi có các todo chưa hoàn thành trong danh sách todo"
+ }
}
}
diff --git a/src/i18n/locales/zh-CN/common.json b/src/i18n/locales/zh-CN/common.json
index a629ba6507..515ee7d048 100644
--- a/src/i18n/locales/zh-CN/common.json
+++ b/src/i18n/locales/zh-CN/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "您确定要重置扩展中的所有状态和密钥存储吗?此操作无法撤消。",
"delete_config_profile": "您确定要删除此配置文件吗?",
- "delete_custom_mode_with_rules": "您确定要删除此 {scope} 模式吗?\n\n这也将删除位于以下位置的关联规则文件夹:\n{rulesFolderPath}",
- "delete_message": "您想删除什么?",
- "edit_warning": "编辑此消息将删除对话中的所有后续消息。您要继续吗?",
- "delete_just_this_message": "仅此消息",
- "delete_this_and_subsequent": "此消息及所有后续消息",
- "proceed": "继续"
+ "delete_custom_mode_with_rules": "您确定要删除此 {scope} 模式吗?\n\n这也将删除位于以下位置的关联规则文件夹:\n{rulesFolderPath}"
},
"errors": {
"invalid_mcp_config": "项目MCP配置格式无效",
@@ -176,5 +171,10 @@
"descriptionNoRules": "您确定要删除此自定义模式吗?",
"confirm": "删除"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "当待办事项列表中有未完成的待办事项时阻止任务完成"
+ }
}
}
diff --git a/src/i18n/locales/zh-TW/common.json b/src/i18n/locales/zh-TW/common.json
index 48a37c1438..cceb53e5f3 100644
--- a/src/i18n/locales/zh-TW/common.json
+++ b/src/i18n/locales/zh-TW/common.json
@@ -17,12 +17,7 @@
"confirmation": {
"reset_state": "您確定要重設擴充套件中的所有狀態和金鑰儲存嗎?此操作無法復原。",
"delete_config_profile": "您確定要刪除此設定檔案嗎?",
- "delete_custom_mode_with_rules": "您確定要刪除此 {scope} 模式嗎?\n\n這也將刪除位於以下位置的關聯規則資料夾:\n{rulesFolderPath}",
- "delete_message": "您想刪除哪些內容?",
- "edit_warning": "編輯此訊息將刪除對話中的所有後續訊息。您要繼續嗎?",
- "delete_just_this_message": "僅這則訊息",
- "delete_this_and_subsequent": "這則訊息及所有後續訊息",
- "proceed": "繼續"
+ "delete_custom_mode_with_rules": "您確定要刪除此 {scope} 模式嗎?\n\n這也將刪除位於以下位置的關聯規則資料夾:\n{rulesFolderPath}"
},
"errors": {
"invalid_data_uri": "資料 URI 格式無效",
@@ -171,5 +166,10 @@
"descriptionNoRules": "您確定要刪除此自訂模式嗎?",
"confirm": "刪除"
}
+ },
+ "commands": {
+ "preventCompletionWithOpenTodos": {
+ "description": "當待辦事項清單中有未完成的待辦事項時阻止工作完成"
+ }
}
}
diff --git a/src/package.json b/src/package.json
index 7b3c6a26cc..448463b750 100644
--- a/src/package.json
+++ b/src/package.json
@@ -3,7 +3,7 @@
"displayName": "%extension.displayName%",
"description": "%extension.description%",
"publisher": "RooVeterinaryInc",
- "version": "3.23.12",
+ "version": "3.23.14",
"icon": "assets/icons/icon.png",
"galleryBanner": {
"color": "#617A91",
@@ -224,38 +224,38 @@
"when": "view == roo-cline.SidebarProvider"
},
{
- "command": "roo-cline.settingsButtonClicked",
+ "command": "roo-cline.marketplaceButtonClicked",
"group": "navigation@2",
"when": "view == roo-cline.SidebarProvider"
},
{
- "command": "roo-cline.accountButtonClicked",
+ "command": "roo-cline.settingsButtonClicked",
"group": "navigation@3",
"when": "view == roo-cline.SidebarProvider"
},
+ {
+ "command": "roo-cline.accountButtonClicked",
+ "group": "navigation@4",
+ "when": "view == roo-cline.SidebarProvider"
+ },
{
"command": "roo-cline.historyButtonClicked",
"group": "overflow@1",
"when": "view == roo-cline.SidebarProvider"
},
{
- "command": "roo-cline.marketplaceButtonClicked",
+ "command": "roo-cline.promptsButtonClicked",
"group": "overflow@2",
"when": "view == roo-cline.SidebarProvider"
},
{
- "command": "roo-cline.promptsButtonClicked",
+ "command": "roo-cline.mcpButtonClicked",
"group": "overflow@3",
"when": "view == roo-cline.SidebarProvider"
},
- {
- "command": "roo-cline.mcpButtonClicked",
- "group": "overflow@4",
- "when": "view == roo-cline.SidebarProvider"
- },
{
"command": "roo-cline.popoutButtonClicked",
- "group": "overflow@5",
+ "group": "overflow@4",
"when": "view == roo-cline.SidebarProvider"
}
],
@@ -266,38 +266,38 @@
"when": "activeWebviewPanelId == roo-cline.TabPanelProvider"
},
{
- "command": "roo-cline.settingsButtonClicked",
+ "command": "roo-cline.marketplaceButtonClicked",
"group": "navigation@2",
"when": "activeWebviewPanelId == roo-cline.TabPanelProvider"
},
{
- "command": "roo-cline.accountButtonClicked",
+ "command": "roo-cline.settingsButtonClicked",
"group": "navigation@3",
"when": "activeWebviewPanelId == roo-cline.TabPanelProvider"
},
+ {
+ "command": "roo-cline.accountButtonClicked",
+ "group": "navigation@4",
+ "when": "activeWebviewPanelId == roo-cline.TabPanelProvider"
+ },
{
"command": "roo-cline.historyButtonClicked",
"group": "overflow@1",
"when": "activeWebviewPanelId == roo-cline.TabPanelProvider"
},
{
- "command": "roo-cline.marketplaceButtonClicked",
+ "command": "roo-cline.promptsButtonClicked",
"group": "overflow@2",
"when": "activeWebviewPanelId == roo-cline.TabPanelProvider"
},
{
- "command": "roo-cline.promptsButtonClicked",
+ "command": "roo-cline.mcpButtonClicked",
"group": "overflow@3",
"when": "activeWebviewPanelId == roo-cline.TabPanelProvider"
},
- {
- "command": "roo-cline.mcpButtonClicked",
- "group": "overflow@4",
- "when": "activeWebviewPanelId == roo-cline.TabPanelProvider"
- },
{
"command": "roo-cline.popoutButtonClicked",
- "group": "overflow@5",
+ "group": "overflow@4",
"when": "activeWebviewPanelId == roo-cline.TabPanelProvider"
}
]
@@ -345,6 +345,11 @@
"maximum": 600,
"description": "%commands.commandExecutionTimeout.description%"
},
+ "roo-cline.preventCompletionWithOpenTodos": {
+ "type": "boolean",
+ "default": false,
+ "description": "%commands.preventCompletionWithOpenTodos.description%"
+ },
"roo-cline.vsCodeLmModelSelector": {
"type": "object",
"properties": {
diff --git a/src/package.nls.json b/src/package.nls.json
index c5225c45c8..b52f2d11c2 100644
--- a/src/package.nls.json
+++ b/src/package.nls.json
@@ -29,6 +29,7 @@
"commands.allowedCommands.description": "Commands that can be auto-executed when 'Always approve execute operations' is enabled",
"commands.deniedCommands.description": "Command prefixes that will be automatically denied without asking for approval. In case of conflicts with allowed commands, the longest prefix match takes precedence. Add * to deny all commands.",
"commands.commandExecutionTimeout.description": "Maximum time in seconds to wait for command execution to complete before timing out (0 = no timeout, 1-600s, default: 0s)",
+ "commands.preventCompletionWithOpenTodos.description": "Prevent task completion when there are incomplete todos in the todo list",
"settings.vsCodeLmModelSelector.description": "Settings for VSCode Language Model API",
"settings.vsCodeLmModelSelector.vendor.description": "The vendor of the language model (e.g. copilot)",
"settings.vsCodeLmModelSelector.family.description": "The family of the language model (e.g. gpt-4)",
diff --git a/src/services/code-index/constants/index.ts b/src/services/code-index/constants/index.ts
index c2567f5635..706a73935a 100644
--- a/src/services/code-index/constants/index.ts
+++ b/src/services/code-index/constants/index.ts
@@ -15,7 +15,7 @@ export const QDRANT_CODE_BLOCK_NAMESPACE = "f47ac10b-58cc-4372-a567-0e02b2c3d479
export const MAX_FILE_SIZE_BYTES = 1 * 1024 * 1024 // 1MB
/**Directory Scanner */
-export const MAX_LIST_FILES_LIMIT = 3_000
+export const MAX_LIST_FILES_LIMIT_CODE_INDEX = 50_000
export const BATCH_SEGMENT_THRESHOLD = 60 // Number of code segments to batch for embeddings/upserts
export const MAX_BATCH_RETRIES = 3
export const INITIAL_RETRY_DELAY_MS = 500
diff --git a/src/services/code-index/embedders/ollama.ts b/src/services/code-index/embedders/ollama.ts
index 20b22b92bf..c160d39490 100644
--- a/src/services/code-index/embedders/ollama.ts
+++ b/src/services/code-index/embedders/ollama.ts
@@ -7,6 +7,10 @@ import { withValidationErrorHandling, sanitizeErrorMessage } from "../shared/val
import { TelemetryService } from "@roo-code/telemetry"
import { TelemetryEventName } from "@roo-code/types"
+// Timeout constants for Ollama API requests
+const OLLAMA_EMBEDDING_TIMEOUT_MS = 60000 // 60 seconds for embedding requests
+const OLLAMA_VALIDATION_TIMEOUT_MS = 30000 // 30 seconds for validation requests
+
/**
* Implements the IEmbedder interface using a local Ollama instance.
*/
@@ -61,7 +65,7 @@ export class CodeIndexOllamaEmbedder implements IEmbedder {
// Add timeout to prevent indefinite hanging
const controller = new AbortController()
- const timeoutId = setTimeout(() => controller.abort(), 10000) // 10 second timeout
+ const timeoutId = setTimeout(() => controller.abort(), OLLAMA_EMBEDDING_TIMEOUT_MS)
const response = await fetch(url, {
method: "POST",
@@ -140,7 +144,7 @@ export class CodeIndexOllamaEmbedder implements IEmbedder {
// Add timeout to prevent indefinite hanging
const controller = new AbortController()
- const timeoutId = setTimeout(() => controller.abort(), 5000) // 5 second timeout
+ const timeoutId = setTimeout(() => controller.abort(), OLLAMA_VALIDATION_TIMEOUT_MS)
const modelsResponse = await fetch(modelsUrl, {
method: "GET",
@@ -197,7 +201,7 @@ export class CodeIndexOllamaEmbedder implements IEmbedder {
// Add timeout for test request too
const testController = new AbortController()
- const testTimeoutId = setTimeout(() => testController.abort(), 5000)
+ const testTimeoutId = setTimeout(() => testController.abort(), OLLAMA_VALIDATION_TIMEOUT_MS)
const testResponse = await fetch(testUrl, {
method: "POST",
diff --git a/src/services/code-index/interfaces/file-processor.ts b/src/services/code-index/interfaces/file-processor.ts
index f00c19c619..88b19007c3 100644
--- a/src/services/code-index/interfaces/file-processor.ts
+++ b/src/services/code-index/interfaces/file-processor.ts
@@ -38,7 +38,6 @@ export interface IDirectoryScanner {
onBlocksIndexed?: (indexedCount: number) => void,
onFileParsed?: (fileBlockCount: number) => void,
): Promise<{
- codeBlocks: CodeBlock[]
stats: {
processed: number
skipped: number
diff --git a/src/services/code-index/processors/__tests__/scanner.spec.ts b/src/services/code-index/processors/__tests__/scanner.spec.ts
index f90a6c8159..4d4150b443 100644
--- a/src/services/code-index/processors/__tests__/scanner.spec.ts
+++ b/src/services/code-index/processors/__tests__/scanner.spec.ts
@@ -168,7 +168,16 @@ describe("DirectoryScanner", () => {
expect(mockCodeParser.parseFile).not.toHaveBeenCalled()
})
- it("should parse changed files and return code blocks", async () => {
+ it("should parse changed files and return empty codeBlocks array", async () => {
+ // Create scanner without embedder to test the non-embedding path
+ const scannerNoEmbeddings = new DirectoryScanner(
+ null as any, // No embedder
+ null as any, // No vector store
+ mockCodeParser,
+ mockCacheManager,
+ mockIgnoreInstance,
+ )
+
const { listFiles } = await import("../../../glob/list-files")
vi.mocked(listFiles).mockResolvedValue([["test/file1.js"], false])
const mockBlocks: any[] = [
@@ -185,8 +194,7 @@ describe("DirectoryScanner", () => {
]
;(mockCodeParser.parseFile as any).mockResolvedValue(mockBlocks)
- const result = await scanner.scanDirectory("/test")
- expect(result.codeBlocks).toEqual(mockBlocks)
+ const result = await scannerNoEmbeddings.scanDirectory("/test")
expect(result.stats.processed).toBe(1)
})
@@ -252,6 +260,15 @@ describe("DirectoryScanner", () => {
})
it("should process markdown files alongside code files", async () => {
+ // Create scanner without embedder to test the non-embedding path
+ const scannerNoEmbeddings = new DirectoryScanner(
+ null as any, // No embedder
+ null as any, // No vector store
+ mockCodeParser,
+ mockCacheManager,
+ mockIgnoreInstance,
+ )
+
const { listFiles } = await import("../../../glob/list-files")
vi.mocked(listFiles).mockResolvedValue([["test/README.md", "test/app.js", "docs/guide.markdown"], false])
@@ -306,7 +323,7 @@ describe("DirectoryScanner", () => {
return []
})
- const result = await scanner.scanDirectory("/test")
+ const result = await scannerNoEmbeddings.scanDirectory("/test")
// Verify all files were processed
expect(mockCodeParser.parseFile).toHaveBeenCalledTimes(3)
@@ -314,16 +331,7 @@ describe("DirectoryScanner", () => {
expect(mockCodeParser.parseFile).toHaveBeenCalledWith("test/app.js", expect.any(Object))
expect(mockCodeParser.parseFile).toHaveBeenCalledWith("docs/guide.markdown", expect.any(Object))
- // Verify code blocks include both markdown and code content
- expect(result.codeBlocks).toHaveLength(3)
- expect(result.codeBlocks).toEqual(
- expect.arrayContaining([
- expect.objectContaining({ type: "markdown_header_h1" }),
- expect.objectContaining({ type: "function" }),
- expect.objectContaining({ type: "markdown_header_h2" }),
- ]),
- )
-
+ // Verify processing still works without codeBlocks accumulation
expect(result.stats.processed).toBe(3)
})
diff --git a/src/services/code-index/processors/scanner.ts b/src/services/code-index/processors/scanner.ts
index 538a1252d7..e6ca297399 100644
--- a/src/services/code-index/processors/scanner.ts
+++ b/src/services/code-index/processors/scanner.ts
@@ -17,7 +17,7 @@ import { t } from "../../../i18n"
import {
QDRANT_CODE_BLOCK_NAMESPACE,
MAX_FILE_SIZE_BYTES,
- MAX_LIST_FILES_LIMIT,
+ MAX_LIST_FILES_LIMIT_CODE_INDEX,
BATCH_SEGMENT_THRESHOLD,
MAX_BATCH_RETRIES,
INITIAL_RETRY_DELAY_MS,
@@ -51,13 +51,13 @@ export class DirectoryScanner implements IDirectoryScanner {
onError?: (error: Error) => void,
onBlocksIndexed?: (indexedCount: number) => void,
onFileParsed?: (fileBlockCount: number) => void,
- ): Promise<{ codeBlocks: CodeBlock[]; stats: { processed: number; skipped: number }; totalBlockCount: number }> {
+ ): Promise<{ stats: { processed: number; skipped: number }; totalBlockCount: number }> {
const directoryPath = directory
// Capture workspace context at scan start
const scanWorkspace = getWorkspacePathForContext(directoryPath)
// Get all files recursively (handles .gitignore automatically)
- const [allPaths, _] = await listFiles(directoryPath, true, MAX_LIST_FILES_LIMIT)
+ const [allPaths, _] = await listFiles(directoryPath, true, MAX_LIST_FILES_LIMIT_CODE_INDEX)
// Filter out directories (marked with trailing '/')
const filePaths = allPaths.filter((p) => !p.endsWith("/"))
@@ -85,7 +85,6 @@ export class DirectoryScanner implements IDirectoryScanner {
// Initialize tracking variables
const processedFiles = new Set()
- const codeBlocks: CodeBlock[] = []
let processedCount = 0
let skippedCount = 0
@@ -98,7 +97,7 @@ export class DirectoryScanner implements IDirectoryScanner {
let currentBatchBlocks: CodeBlock[] = []
let currentBatchTexts: string[] = []
let currentBatchFileInfos: { filePath: string; fileHash: string; isNew: boolean }[] = []
- const activeBatchPromises: Promise[] = []
+ const activeBatchPromises = new Set>()
// Initialize block counter
let totalBlockCount = 0
@@ -125,6 +124,7 @@ export class DirectoryScanner implements IDirectoryScanner {
// Check against cache
const cachedFileHash = this.cacheManager.getHash(filePath)
+ const isNewFile = !cachedFileHash
if (cachedFileHash === currentFileHash) {
// File is unchanged
skippedCount++
@@ -135,7 +135,6 @@ export class DirectoryScanner implements IDirectoryScanner {
const blocks = await this.codeParser.parseFile(filePath, { content, fileHash: currentFileHash })
const fileBlockCount = blocks.length
onFileParsed?.(fileBlockCount)
- codeBlocks.push(...blocks)
processedCount++
// Process embeddings if configured
@@ -146,20 +145,11 @@ export class DirectoryScanner implements IDirectoryScanner {
const trimmedContent = block.content.trim()
if (trimmedContent) {
const release = await mutex.acquire()
- totalBlockCount += fileBlockCount
try {
currentBatchBlocks.push(block)
currentBatchTexts.push(trimmedContent)
addedBlocksFromFile = true
- if (addedBlocksFromFile) {
- currentBatchFileInfos.push({
- filePath,
- fileHash: currentFileHash,
- isNew: !this.cacheManager.getHash(filePath),
- })
- }
-
// Check if batch threshold is met
if (currentBatchBlocks.length >= BATCH_SEGMENT_THRESHOLD) {
// Copy current batch data and clear accumulators
@@ -181,13 +171,33 @@ export class DirectoryScanner implements IDirectoryScanner {
onBlocksIndexed,
),
)
- activeBatchPromises.push(batchPromise)
+ activeBatchPromises.add(batchPromise)
+
+ // Clean up completed promises to prevent memory accumulation
+ batchPromise.finally(() => {
+ activeBatchPromises.delete(batchPromise)
+ })
}
} finally {
release()
}
}
}
+
+ // Add file info once per file (outside the block loop)
+ if (addedBlocksFromFile) {
+ const release = await mutex.acquire()
+ try {
+ totalBlockCount += fileBlockCount
+ currentBatchFileInfos.push({
+ filePath,
+ fileHash: currentFileHash,
+ isNew: isNewFile,
+ })
+ } finally {
+ release()
+ }
+ }
} else {
// Only update hash if not being processed in a batch
await this.cacheManager.updateHash(filePath, currentFileHash)
@@ -232,7 +242,12 @@ export class DirectoryScanner implements IDirectoryScanner {
const batchPromise = batchLimiter(() =>
this.processBatch(batchBlocks, batchTexts, batchFileInfos, scanWorkspace, onError, onBlocksIndexed),
)
- activeBatchPromises.push(batchPromise)
+ activeBatchPromises.add(batchPromise)
+
+ // Clean up completed promises to prevent memory accumulation
+ batchPromise.finally(() => {
+ activeBatchPromises.delete(batchPromise)
+ })
} finally {
release()
}
@@ -280,7 +295,6 @@ export class DirectoryScanner implements IDirectoryScanner {
}
return {
- codeBlocks,
stats: {
processed: processedCount,
skipped: skippedCount,
diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts
index 0b2d122e77..53757bb2a3 100644
--- a/src/shared/ExtensionMessage.ts
+++ b/src/shared/ExtensionMessage.ts
@@ -107,6 +107,8 @@ export interface ExtensionMessage {
| "codeIndexSecretStatus"
| "rulesGenerationStatus"
| "existingRuleFiles"
+ | "showDeleteMessageDialog"
+ | "showEditMessageDialog"
text?: string
payload?: any // Add a generic payload for now, can refine later
files?: string[] // For existingRuleFiles
@@ -161,6 +163,8 @@ export interface ExtensionMessage {
visibility?: ShareVisibility
rulesFolderPath?: string
settings?: any
+ messageTs?: number
+ context?: string
}
export type ExtensionState = Pick<
diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts
index 633fc11608..b81e3f737e 100644
--- a/src/shared/WebviewMessage.ts
+++ b/src/shared/WebviewMessage.ts
@@ -111,7 +111,9 @@ export interface WebviewMessage {
| "enhancedPrompt"
| "draggedImages"
| "deleteMessage"
+ | "deleteMessageConfirm"
| "submitEditedMessage"
+ | "editMessageConfirm"
| "terminalOutputLineLimit"
| "terminalShellIntegrationTimeout"
| "terminalShellIntegrationDisabled"
@@ -200,6 +202,7 @@ export interface WebviewMessage {
editedMessageContent?: string
tab?: "settings" | "history" | "mcp" | "modes" | "chat" | "marketplace" | "account"
disabled?: boolean
+ context?: string
dataUri?: string
askResponse?: ClineAskResponse
apiConfiguration?: ProviderSettings
@@ -228,6 +231,7 @@ export interface WebviewMessage {
ids?: string[]
hasSystemPromptOverride?: boolean
terminalOperation?: "continue" | "abort"
+ messageTs?: number
historyPreviewCollapsed?: boolean
filters?: { type?: string; search?: string; tags?: string[] }
url?: string // For openExternal
diff --git a/webview-ui/src/App.tsx b/webview-ui/src/App.tsx
index 332ef18511..3c4c14f5df 100644
--- a/webview-ui/src/App.tsx
+++ b/webview-ui/src/App.tsx
@@ -1,4 +1,4 @@
-import { useCallback, useEffect, useRef, useState, useMemo } from "react"
+import React, { useCallback, useEffect, useRef, useState, useMemo } from "react"
import { useEvent } from "react-use"
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
@@ -18,6 +18,7 @@ import McpView from "./components/mcp/McpView"
import { MarketplaceView } from "./components/marketplace/MarketplaceView"
import ModesView from "./components/modes/ModesView"
import { HumanRelayDialog } from "./components/human-relay/HumanRelayDialog"
+import { DeleteMessageDialog, EditMessageDialog } from "./components/chat/MessageModificationConfirmationDialog"
import { AccountView } from "./components/account/AccountView"
import { useAddNonInteractiveClickListener } from "./components/ui/hooks/useNonInteractiveClick"
import { TooltipProvider } from "./components/ui/tooltip"
@@ -25,6 +26,29 @@ import { STANDARD_TOOLTIP_DELAY } from "./components/ui/standard-tooltip"
type Tab = "settings" | "history" | "mcp" | "modes" | "chat" | "marketplace" | "account"
+interface HumanRelayDialogState {
+ isOpen: boolean
+ requestId: string
+ promptText: string
+}
+
+interface DeleteMessageDialogState {
+ isOpen: boolean
+ messageTs: number
+}
+
+interface EditMessageDialogState {
+ isOpen: boolean
+ messageTs: number
+ text: string
+ images?: string[]
+}
+
+// Memoize dialog components to prevent unnecessary re-renders
+const MemoizedDeleteMessageDialog = React.memo(DeleteMessageDialog)
+const MemoizedEditMessageDialog = React.memo(EditMessageDialog)
+const MemoizedHumanRelayDialog = React.memo(HumanRelayDialog)
+
const tabsByMessageAction: Partial, Tab>> = {
chatButtonClicked: "chat",
settingsButtonClicked: "settings",
@@ -56,16 +80,24 @@ const App = () => {
const [showAnnouncement, setShowAnnouncement] = useState(false)
const [tab, setTab] = useState("chat")
- const [humanRelayDialogState, setHumanRelayDialogState] = useState<{
- isOpen: boolean
- requestId: string
- promptText: string
- }>({
+ const [humanRelayDialogState, setHumanRelayDialogState] = useState({
isOpen: false,
requestId: "",
promptText: "",
})
+ const [deleteMessageDialogState, setDeleteMessageDialogState] = useState({
+ isOpen: false,
+ messageTs: 0,
+ })
+
+ const [editMessageDialogState, setEditMessageDialogState] = useState({
+ isOpen: false,
+ messageTs: 0,
+ text: "",
+ images: [],
+ })
+
const settingsRef = useRef(null)
const chatViewRef = useRef(null)
@@ -121,6 +153,19 @@ const App = () => {
setHumanRelayDialogState({ isOpen: true, requestId, promptText })
}
+ if (message.type === "showDeleteMessageDialog" && message.messageTs) {
+ setDeleteMessageDialogState({ isOpen: true, messageTs: message.messageTs })
+ }
+
+ if (message.type === "showEditMessageDialog" && message.messageTs && message.text) {
+ setEditMessageDialogState({
+ isOpen: true,
+ messageTs: message.messageTs,
+ text: message.text,
+ images: message.images || [],
+ })
+ }
+
if (message.type === "acceptInput") {
chatViewRef.current?.acceptInput()
}
@@ -199,7 +244,7 @@ const App = () => {
showAnnouncement={showAnnouncement}
hideAnnouncement={() => setShowAnnouncement(false)}
/>
- {
onSubmit={(requestId, text) => vscode.postMessage({ type: "humanRelayResponse", requestId, text })}
onCancel={(requestId) => vscode.postMessage({ type: "humanRelayCancel", requestId })}
/>
+ setDeleteMessageDialogState((prev) => ({ ...prev, isOpen: open }))}
+ onConfirm={() => {
+ vscode.postMessage({
+ type: "deleteMessageConfirm",
+ messageTs: deleteMessageDialogState.messageTs,
+ })
+ setDeleteMessageDialogState((prev) => ({ ...prev, isOpen: false }))
+ }}
+ />
+ setEditMessageDialogState((prev) => ({ ...prev, isOpen: open }))}
+ onConfirm={() => {
+ vscode.postMessage({
+ type: "editMessageConfirm",
+ messageTs: editMessageDialogState.messageTs,
+ text: editMessageDialogState.text,
+ images: editMessageDialogState.images,
+ })
+ setEditMessageDialogState((prev) => ({ ...prev, isOpen: false }))
+ }}
+ />
>
)
}
diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx
index ae363a7b63..2e987b7c49 100644
--- a/webview-ui/src/components/chat/AutoApproveMenu.tsx
+++ b/webview-ui/src/components/chat/AutoApproveMenu.tsx
@@ -6,6 +6,9 @@ import { vscode } from "@src/utils/vscode"
import { useExtensionState } from "@src/context/ExtensionStateContext"
import { useAppTranslation } from "@src/i18n/TranslationContext"
import { AutoApproveToggle, AutoApproveSetting, autoApproveSettingsConfig } from "../settings/AutoApproveToggle"
+import { StandardTooltip } from "@src/components/ui"
+import { useAutoApprovalState } from "@src/hooks/useAutoApprovalState"
+import { useAutoApprovalToggles } from "@src/hooks/useAutoApprovalToggles"
interface AutoApproveMenuProps {
style?: React.CSSProperties
@@ -17,16 +20,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
const {
autoApprovalEnabled,
setAutoApprovalEnabled,
- alwaysAllowReadOnly,
- alwaysAllowWrite,
- alwaysAllowExecute,
- alwaysAllowBrowser,
- alwaysAllowMcp,
- alwaysAllowModeSwitch,
- alwaysAllowSubtasks,
alwaysApproveResubmit,
- alwaysAllowFollowupQuestions,
- alwaysAllowUpdateTodoList,
allowedMaxRequests,
setAlwaysAllowReadOnly,
setAlwaysAllowWrite,
@@ -43,10 +37,24 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
const { t } = useAppTranslation()
+ const baseToggles = useAutoApprovalToggles()
+
+ // AutoApproveMenu needs alwaysApproveResubmit in addition to the base toggles
+ const toggles = useMemo(
+ () => ({
+ ...baseToggles,
+ alwaysApproveResubmit: alwaysApproveResubmit,
+ }),
+ [baseToggles, alwaysApproveResubmit],
+ )
+
+ const { hasEnabledOptions, effectiveAutoApprovalEnabled } = useAutoApprovalState(toggles, autoApprovalEnabled)
+
const onAutoApproveToggle = useCallback(
(key: AutoApproveSetting, value: boolean) => {
vscode.postMessage({ type: key, bool: value })
+ // Update the specific toggle state
switch (key) {
case "alwaysAllowReadOnly":
setAlwaysAllowReadOnly(value)
@@ -79,8 +87,30 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
setAlwaysAllowUpdateTodoList(value)
break
}
+
+ // Check if we need to update the master auto-approval state
+ // Create a new toggles state with the updated value
+ const updatedToggles = {
+ ...toggles,
+ [key]: value,
+ }
+
+ const willHaveEnabledOptions = Object.values(updatedToggles).some((v) => !!v)
+
+ // If enabling the first option, enable master auto-approval
+ if (value && !hasEnabledOptions && willHaveEnabledOptions) {
+ setAutoApprovalEnabled(true)
+ vscode.postMessage({ type: "autoApprovalEnabled", bool: true })
+ }
+ // If disabling the last option, disable master auto-approval
+ else if (!value && hasEnabledOptions && !willHaveEnabledOptions) {
+ setAutoApprovalEnabled(false)
+ vscode.postMessage({ type: "autoApprovalEnabled", bool: false })
+ }
},
[
+ toggles,
+ hasEnabledOptions,
setAlwaysAllowReadOnly,
setAlwaysAllowWrite,
setAlwaysAllowExecute,
@@ -91,43 +121,32 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
setAlwaysApproveResubmit,
setAlwaysAllowFollowupQuestions,
setAlwaysAllowUpdateTodoList,
+ setAutoApprovalEnabled,
],
)
- const toggleExpanded = useCallback(() => setIsExpanded((prev) => !prev), [])
+ const toggleExpanded = useCallback(() => {
+ setIsExpanded((prev) => !prev)
+ }, [])
- const toggles = useMemo(
- () => ({
- alwaysAllowReadOnly: alwaysAllowReadOnly,
- alwaysAllowWrite: alwaysAllowWrite,
- alwaysAllowExecute: alwaysAllowExecute,
- alwaysAllowBrowser: alwaysAllowBrowser,
- alwaysAllowMcp: alwaysAllowMcp,
- alwaysAllowModeSwitch: alwaysAllowModeSwitch,
- alwaysAllowSubtasks: alwaysAllowSubtasks,
- alwaysApproveResubmit: alwaysApproveResubmit,
- alwaysAllowFollowupQuestions: alwaysAllowFollowupQuestions,
- alwaysAllowUpdateTodoList: alwaysAllowUpdateTodoList,
- }),
- [
- alwaysAllowReadOnly,
- alwaysAllowWrite,
- alwaysAllowExecute,
- alwaysAllowBrowser,
- alwaysAllowMcp,
- alwaysAllowModeSwitch,
- alwaysAllowSubtasks,
- alwaysApproveResubmit,
- alwaysAllowFollowupQuestions,
- alwaysAllowUpdateTodoList,
- ],
- )
+ // Disable main checkbox while menu is open or no options selected
+ const isCheckboxDisabled = useMemo(() => {
+ return !hasEnabledOptions || isExpanded
+ }, [hasEnabledOptions, isExpanded])
const enabledActionsList = Object.entries(toggles)
.filter(([_key, value]) => !!value)
.map(([key]) => t(autoApproveSettingsConfig[key as AutoApproveSetting].labelKey))
.join(", ")
+ // Update displayed text logic
+ const displayText = useMemo(() => {
+ if (!effectiveAutoApprovalEnabled || !hasEnabledOptions) {
+ return t("chat:autoApprove.none")
+ }
+ return enabledActionsList || t("chat:autoApprove.none")
+ }, [effectiveAutoApprovalEnabled, hasEnabledOptions, enabledActionsList, t])
+
const handleOpenSettings = useCallback(
() =>
window.postMessage({ type: "action", action: "settingsButtonClicked", values: { section: "autoApprove" } }),
@@ -155,14 +174,26 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
}}
onClick={toggleExpanded}>