diff --git a/.roo/rules-issue-writer/1_workflow.xml b/.roo/rules-issue-writer/1_workflow.xml index f24b643e3d..99ef7db5d9 100644 --- a/.roo/rules-issue-writer/1_workflow.xml +++ b/.roo/rules-issue-writer/1_workflow.xml @@ -3,14 +3,24 @@ Initialize Issue Creation Process - When the user requests to create an issue, immediately set up a todo list to track the workflow. + IMPORTANT: This mode assumes the first user message is already a request to create an issue. + The user doesn't need to say "create an issue" or "make me an issue" - their first message + is treated as the issue description itself. + + When the session starts, immediately: + 1. Treat the user's first message as the issue description + 2. Initialize the workflow by using the update_todo_list tool + 3. Begin the issue creation process without asking what they want to do + [ ] Detect current repository information + [ ] Determine repository structure (monorepo/standard) + [ ] Perform initial codebase discovery [ ] Analyze user request to determine issue type - [ ] Gather initial information for the issue + [ ] Gather and verify additional information [ ] Determine if user wants to contribute - [ ] Perform technical analysis (if contributing) + [ ] Perform issue scoping (if contributing) [ ] Draft issue content [ ] Review and confirm with user [ ] Create GitHub issue @@ -21,49 +31,47 @@ - Determine Issue Type + Detect current repository information - Analyze the user's initial request to automatically assess whether they're reporting a bug or proposing a feature. - Look for keywords and context clues: + CRITICAL FIRST STEP: Verify we're in a git repository and get repository information. - Bug indicators: - - Words like "error", "broken", "not working", "fails", "crash", "bug" - - Descriptions of unexpected behavior - - Error messages or stack traces - - References to something that used to work + 1. Check if we're in a git repository: + + git rev-parse --is-inside-work-tree 2>/dev/null || echo "not-git-repo" + - Feature indicators: - - Words like "feature", "enhancement", "add", "implement", "would be nice" - - Descriptions of new functionality - - Suggestions for improvements - - "It would be great if..." + If the output is "not-git-repo", immediately stop and inform the user: - Based on your analysis, order the options with the most likely choice first: + + + This mode must be run from within a GitHub repository. Please navigate to a git repository and try again. + + - - Based on your request, what type of issue would you like to create? - - [If bug indicators found:] - Bug Report - Report a problem with existing functionality - Detailed Feature Proposal - Propose a new feature or enhancement + 2. If in a git repository, get the repository information: + + git remote get-url origin 2>/dev/null | sed -E 's/.*[:/]([^/]+)\/([^/]+)(\.git)?$/\1\/\2/' | sed 's/\.git$//' + - [If feature indicators found:] - Detailed Feature Proposal - Propose a new feature or enhancement - Bug Report - Report a problem with existing functionality + Store this as REPO_FULL_NAME for use throughout the workflow. - [If unclear:] - Bug Report - Report a problem with existing functionality - Detailed Feature Proposal - Propose a new feature or enhancement - - + If no origin remote exists, stop with: + + + No GitHub remote found. This mode requires a GitHub repository with an 'origin' remote configured. + + - After determining the type, update the todo list: + Update todo after detecting repository: - [x] Analyze user request to determine issue type - [-] Gather initial information for the issue + [x] Detect current repository information + [-] Determine repository structure (monorepo/standard) + [ ] Perform initial codebase discovery + [ ] Analyze user request to determine issue type + [ ] Gather and verify additional information [ ] Determine if user wants to contribute - [ ] Perform technical analysis (if contributing) + [ ] Perform issue scoping (if contributing) [ ] Draft issue content [ ] Review and confirm with user [ ] Create GitHub issue @@ -73,37 +81,62 @@ - Gather Initial Information + Determine Repository Structure - Based on the user's initial prompt or request, extract key information. - If the user hasn't provided enough detail, use ask_followup_question to gather - the required fields from the appropriate template. + Check if this is a monorepo or standard repository by looking for common patterns. - For Bug Reports, ensure you have: - - App version (ask user to check in VSCode extension panel if unknown) - - API provider being used - - Model being used - - Clear steps to reproduce - - What happened vs what was expected - - Any error messages or logs + First, check for monorepo indicators: + 1. Look for workspace configuration: + - package.json with "workspaces" field + - lerna.json + - pnpm-workspace.yaml + - rush.json - For Feature Requests, ensure you have: - - Specific problem description with impact (who is affected, when it happens, current vs expected behavior, impact) - - Additional context if available (mockups, screenshots, links) + 2. Check for common monorepo directory patterns: + + . + false + - IMPORTANT: Do NOT ask for solution design, acceptance criteria, or technical details - unless the user explicitly states they want to contribute the implementation. + Look for directories like: + - apps/ (application packages) + - packages/ (shared packages) + - services/ (service packages) + - libs/ (library packages) + - modules/ (module packages) + - src/ (main source if not using workspaces) - Use multiple ask_followup_question calls if needed to gather all information. - Be specific in your questions based on what's missing. + If monorepo detected: + - Dynamically discover packages by looking for package.json files in detected directories + - Build a list of available packages with their paths - After gathering information, update the todo: + Based on the user's description, try to identify which package they're referring to. + If unclear, ask for clarification: + + + I see this is a monorepo with multiple packages. Which specific package or application is your issue related to? + + [Dynamically generated list of discovered packages] + Let me describe which package: [specify] + + + + If standard repository: + - Skip package selection + - Use repository root for all searches + + Store the repository context for all future codebase searches and explorations. + + Update todo after determining context: - [x] Analyze user request to determine issue type - [x] Gather initial information for the issue - [-] Determine if user wants to contribute - [ ] Perform technical analysis (if contributing) + [x] Detect current repository information + [x] Determine repository structure (monorepo/standard) + [-] Perform initial codebase discovery + [ ] Analyze user request to determine issue type + [ ] Gather and verify additional information + [ ] Determine if user wants to contribute + [ ] Perform issue scoping (if contributing) [ ] Draft issue content [ ] Review and confirm with user [ ] Create GitHub issue @@ -113,33 +146,50 @@ - Determine if User Wants to Contribute + Perform Initial Codebase Discovery - Before exploring the codebase, determine if the user wants to contribute the implementation: + Now that we know the repository structure, immediately search the codebase to understand + what the user is talking about before determining the issue type. - - Are you interested in implementing this yourself, or are you just reporting the problem for the Roo team to solve? - - Just reporting the problem - the Roo team can design the solution - I want to contribute and implement this myself - I'm not sure yet, but I'd like to provide technical analysis - - + DISCOVERY ACTIVITIES: - Based on their response: - - If just reporting: Skip to step 5 (Draft Issue - Problem Only) - - If contributing: Continue to step 4 (Technical Analysis) - - If providing analysis: Continue to step 4 but make technical sections optional + 1. Extract keywords and concepts from the user's INITIAL MESSAGE (their issue description) + 2. Search the codebase to verify these concepts exist + 3. Build understanding of the actual implementation + 4. Identify relevant files, components, and code patterns - Update the todo based on the decision: + + [Keywords from user's initial message/description] + [Repository or package path from step 2] + + + Additional searches based on initial findings: + - If error mentioned: search for exact error strings + - If feature mentioned: search for related functionality + - If component mentioned: search for implementation details + + + [repository or package path] + [specific patterns found in initial search] + + + Document findings: + - Components/features found that match user's description + - Actual implementation details discovered + - Related code sections identified + - Any discrepancies between user description and code reality + + Update todos: - [x] Analyze user request to determine issue type - [x] Gather initial information for the issue - [x] Determine if user wants to contribute - [If contributing: [ ] Perform technical analysis (if contributing)] - [If not contributing: [-] Perform technical analysis (skipped - not contributing)] - [-] Draft issue content + [x] Detect current repository information + [x] Determine repository structure (monorepo/standard) + [x] Perform initial codebase discovery + [-] Analyze user request to determine issue type + [ ] Gather and verify additional information + [ ] Determine if user wants to contribute + [ ] Perform issue scoping (if contributing) + [ ] Draft issue content [ ] Review and confirm with user [ ] Create GitHub issue @@ -148,37 +198,54 @@ - Technical Analysis for Contributors + Analyze Request to Determine Issue Type - ONLY perform this step if the user wants to contribute or provide technical analysis. + Using the codebase discoveries from step 2, analyze the user's request to determine + the appropriate issue type with informed context. - This step uses the comprehensive technical analysis sub-workflow defined in - 6_technical_analysis_workflow.xml. The sub-workflow will: + CRITICAL GUIDANCE FOR ISSUE TYPE SELECTION: + For issues that affect user workflows or require behavior changes: + - PREFER the feature proposal template over bug report + - Focus on explaining WHO is affected and WHEN this happens + - Describe the user impact before diving into technical details - 1. Create its own detailed investigation todo list - 2. Perform exhaustive codebase searches using iterative refinement - 3. Analyze all relevant files and dependencies - 4. Form and validate hypotheses about the implementation - 5. Create a comprehensive technical solution - 6. Define detailed acceptance criteria + Based on your findings, classify the issue: - To execute the technical analysis sub-workflow: - - Follow all phases defined in 6_technical_analysis_workflow.xml - - Use the aggressive investigation approach from issue-investigator mode - - Document all findings in extreme detail - - Ensure the analysis is thorough enough for automated implementation + Bug indicators (verified against code): + - Error messages that match actual error handling in code + - Broken functionality in existing features found in codebase + - Regression from previous behavior documented in code/tests + - Code paths that don't work as documented - The sub-workflow will manage its own todo list for the investigation process - and will produce a comprehensive technical analysis section for the issue. + Feature indicators (verified against code): + - New functionality not found in current codebase + - Enhancement to existing features found in code + - Missing capabilities compared to similar features + - Integration points that could be extended + - WORKFLOW IMPROVEMENTS: When existing behavior works but doesn't meet user needs - After completing the technical analysis: + IMPORTANT: Use your codebase findings to inform the question: + + + Based on your request about [specific feature/component found in code], what type of issue would you like to create? + + [Order based on codebase findings and user description] + Bug Report - [Specific component] is not working as expected + Feature Proposal - Add [specific capability] to [existing component] + + + + Update todos: + [x] Detect current repository information + [x] Determine repository structure (monorepo/standard) + [x] Perform initial codebase discovery [x] Analyze user request to determine issue type - [x] Gather initial information for the issue - [x] Determine if user wants to contribute - [x] Perform technical analysis (if contributing) - [-] Draft issue content + [-] Gather and verify additional information + [ ] Determine if user wants to contribute + [ ] Perform issue scoping (if contributing) + [ ] Draft issue content [ ] Review and confirm with user [ ] Create GitHub issue @@ -187,113 +254,709 @@ - Draft Issue Content + Gather and Verify Additional Information - Create the issue body based on whether the user is just reporting or contributing. + Based on the issue type and initial codebase discovery, gather information while + continuously verifying against the actual code implementation. - For Bug Reports, format is the same regardless of contribution intent: - ``` - ## App Version - [version from user] + CRITICAL FOR FEATURE REQUESTS: Be fact-driven and challenge assumptions! + When users describe current behavior as problematic for a feature request, you MUST verify + their claims against the actual code. If their description doesn't match reality, this + might actually be a bug report, not a feature request. - ## API Provider - [provider from dropdown list] + For Bug Reports: + 1. When user describes steps to reproduce: + - Search for the UI components/commands mentioned + - Verify the code paths that would be executed + - Check for existing error handling or known issues + + 2. When user provides error messages: + - Search for exact error strings in codebase + - Find where errors are thrown + - Understand the conditions that trigger them + + 3. For version information: + - Check package.json for actual version + - Look for version-specific code or migrations - ## Model Used - [exact model name] + Example verification searches: + + [repository or package path] + [exact error message from user] + - ## 🔁 Steps to Reproduce + + [feature or component name] implementation + [repository or package path] + - 1. [First step with specific details] - 2. [Second step with exact actions] - 3. [Continue numbering all steps] + For Feature Requests - AGGRESSIVE VERIFICATION WITH CONCRETE EXAMPLES: + 1. When user claims current behavior is X: + - ALWAYS search for the actual implementation + - Read the relevant code to verify their claim + - Check CSS/styling files if UI-related + - Look at configuration files + - Examine test files to understand expected behavior + - TRACE THE DATA FLOW: Follow values from where they're calculated to where they're used + + 2. CRITICAL: Look for existing variables/code that could be reused: + - Search for variables that are calculated but not used where expected + - Identify existing patterns that could be extended + - Find similar features that work correctly for comparison + + 3. If discrepancy found between claim and code: + - Do NOT proceed without clarification + - Present CONCRETE before/after examples with actual values + - Show exactly what happens vs what should happen + - Ask if this might be a bug instead + + Example verification approach: + User says: "Feature X doesn't work properly" - Include: - - Exact button clicks or menu selections - - Specific input text or prompts used - - File names and paths involved - - Any settings or configuration + Your investigation should follow this pattern: + a) What is calculated: Search for where X is computed/defined + b) Where it's stored: Find variables/state holding the value + c) Where it's used: Trace all usages of that value + d) What's missing: Identify gaps in the flow - ## 💥 Outcome Summary + Present findings with concrete examples: - Expected: [what should have happened] - Actual: [what actually happened] + + I investigated the implementation and found something interesting: - ## 📄 Relevant Logs or Errors + Current behavior: + - The value is calculated at [file:line]: `value = computeX()` + - It's stored in variable `calculatedValue` at [file:line] + - BUT it's only used for [purpose A] at [file:line] + - It's NOT used for [purpose B] where you expected it - ```[language] - [paste any error messages or logs] - ``` + Concrete example: + - When you do [action], the system calculates [value] + - This value goes to [location A] + - But [location B] still uses [old/different value] - [If user is contributing, add the comprehensive technical analysis section from step 4] - ``` + Is this the issue you're experiencing? This seems like the calculated value isn't being used where it should be. + + Yes, exactly! The value is calculated but not used in the right place + No, the issue is that the calculation itself is wrong + Actually, I see now that [location B] should use a different value + + - For Feature Requests - PROBLEM REPORTERS (not contributing): - ``` - ## What specific problem does this solve? + 4. Continue verification until facts are established: + - If user confirms it's a bug, switch to bug report workflow + - If user provides more specific context, search again + - Do not accept vague claims without code verification + + 5. For genuine feature requests after verification: + - Document what the code currently does (with evidence and line numbers) + - Show the exact data flow: input → processing → output + - Confirm what the user wants changed with concrete examples + - Ensure the request is based on accurate understanding - [Detailed problem description following the template guidelines] + CRITICAL: For feature requests, if user's description doesn't match codebase reality: + - Challenge the assumption with code evidence AND concrete examples + - Show actual vs expected behavior with specific values + - Suggest it might be a bug if code shows different intent + - Ask for clarification repeatedly if needed + - Do NOT proceed until facts are established - **Who is affected:** [user groups] - **When this happens:** [specific scenarios] - **Current behavior:** [what happens now] - **Expected behavior:** [what should happen] - **Impact:** [time wasted, errors, productivity loss] + Only proceed when you have: + - Verified current behavior in code with line-by-line analysis + - Confirmed user's understanding matches reality + - Determined if it's truly a feature request or actually a bug + - Identified any existing code that could be reused for the fix - ## Additional context - - [Any mockups, screenshots, links, or other supporting information] - ``` - - For Feature Requests - CONTRIBUTORS (implementing the feature): - ``` - ## What specific problem does this solve? - - [Detailed problem description following the template guidelines] - - **Who is affected:** [user groups] - **When this happens:** [specific scenarios] - **Current behavior:** [what happens now] - **Expected behavior:** [what should happen] - **Impact:** [time wasted, errors, productivity loss] - - ## Additional context - - [Any mockups, screenshots, links, or other supporting information] - - --- - - ## 🛠️ Contributing & Technical Analysis - - ✅ **I'm interested in implementing this feature** - ✅ **I understand this needs approval before implementation begins** - - [Insert the comprehensive technical analysis section from step 4, including:] - - Root cause / Implementation target - - Affected components with file paths and line numbers - - Current implementation analysis - - Detailed proposed implementation steps - - Code architecture considerations - - Testing requirements - - Performance impact - - Security considerations - - Migration strategy - - Rollback plan - - Dependencies and breaking changes - - Implementation complexity assessment - - ## Acceptance Criteria - - [Insert the detailed acceptance criteria from the technical analysis] - ``` - - After drafting: + Update todos after verification: + [x] Detect current repository information + [x] Determine repository structure (monorepo/standard) + [x] Perform initial codebase discovery [x] Analyze user request to determine issue type - [x] Gather initial information for the issue + [x] Gather and verify additional information + [-] Determine if user wants to contribute + [ ] Perform issue scoping (if contributing) + [ ] Draft issue content + [ ] Review and confirm with user + [ ] Create GitHub issue + + + + + + + Determine Contribution Intent with Context + + Before asking about contribution, perform a quick technical assessment to provide context: + + 1. Search for complexity indicators: + - Number of files that would need changes + - Existing tests that would need updates + - Dependencies and integration points + + 2. Look for contribution helpers: + - CONTRIBUTING.md guidelines + - Existing similar implementations + - Test patterns to follow + + + CONTRIBUTING guide setup development + + + Based on findings, provide informed context in the question: + + + Based on my analysis, this [issue type] involves [brief complexity assessment from code exploration]. Are you interested in implementing this yourself, or are you reporting it for the project team to handle? + + Just reporting the problem - the project team can design the solution + I want to contribute and implement this myself + I'd like to provide issue scoping to help whoever implements it + + + + Update todos based on response: + + + [x] Detect current repository information + [x] Determine repository structure (monorepo/standard) + [x] Perform initial codebase discovery + [x] Analyze user request to determine issue type + [x] Gather and verify additional information [x] Determine if user wants to contribute - [x] Perform technical analysis (if contributing) + [If contributing: [-] Perform issue scoping (if contributing)] + [If not contributing: [-] Perform issue scoping (skipped - not contributing)] + [-] Draft issue content + [ ] Review and confirm with user + [ ] Create GitHub issue + + + + + + + Issue Scoping for Contributors + + ONLY perform this step if the user wants to contribute or provide issue scoping. + + This step performs a comprehensive, aggressive investigation to create detailed technical + scoping that can guide implementation. The process involves multiple sub-phases: + + + + Perform an exhaustive investigation to produce a comprehensive technical solution + with extreme detail, suitable for automated fix workflows. + + + + Expand the todo list to include detailed investigation steps + + When starting the issue scoping phase, update the main todo list to include + the detailed investigation steps: + + + + [x] Detect current repository information + [x] Determine repository structure (monorepo/standard) + [x] Perform initial codebase discovery + [x] Analyze user request to determine issue type + [x] Gather and verify additional information + [x] Determine if user wants to contribute + [-] Perform issue scoping (if contributing) + [ ] Extract keywords from the issue description + [ ] Perform initial broad codebase search + [ ] Analyze search results and identify key components + [ ] Deep dive into relevant files and implementations + [ ] Form initial hypothesis about the issue/feature + [ ] Attempt to disprove hypothesis through further investigation + [ ] Identify all affected files and dependencies + [ ] Map out the complete implementation approach + [ ] Document technical risks and edge cases + [ ] Formulate comprehensive technical solution + [ ] Create detailed acceptance criteria + [ ] Prepare issue scoping summary + [ ] Draft issue content + [ ] Review and confirm with user + [ ] Create GitHub issue + + + + + + + Extract all relevant keywords, concepts, and technical terms + + - Identify primary technical concepts from user's description + - Extract error messages or specific symptoms + - Note any mentioned file paths or components + - List related features or functionality + - Include synonyms and related terms + + + Update the main todo list to mark "Extract keywords" as complete and move to next phase + + + + + Perform multiple rounds of increasingly focused searches + + + Use codebase_search with all extracted keywords to get an overview of relevant code. + + [Combined keywords from extraction phase] + [Repository or package path] + + + + + Based on initial results, identify key components and search for: + - Related class/function definitions + - Import statements and dependencies + - Configuration files + - Test files that might reveal expected behavior + + + + Search for specific implementation details: + - Error handling patterns + - State management + - API endpoints or routes + - Database queries or models + - UI components and their interactions + + + + Look for: + - Edge cases in the code + - Integration points with other systems + - Configuration options that affect behavior + - Feature flags or conditional logic + + + + After completing all search iterations, update the todo list to show progress + + + + + Thoroughly analyze all relevant files discovered + + - Use list_code_definition_names to understand file structure + - Read complete files to understand full context + - Trace execution paths through the code + - Identify all dependencies and imports + - Map relationships between components + + + Document findings including: + - File paths and their purposes + - Key functions and their responsibilities + - Data flow through the system + - External dependencies + - Potential impact areas + + + + + Form a comprehensive hypothesis about the issue or feature + + - Identify the most likely root cause + - Trace the bug through the execution path + - Determine why the current implementation fails + - Consider environmental factors + + + - Identify the optimal integration points + - Determine required architectural changes + - Plan the implementation approach + - Consider scalability and maintainability + + + + + Aggressively attempt to disprove the hypothesis + + + - Look for similar features implemented differently + - Check for deprecated code that might interfere + + + - Search for configuration that could change behavior + - Look for environment-specific code paths + + + - Find existing tests that might contradict hypothesis + - Look for test cases that reveal edge cases + + + - Search for comments explaining design decisions + - Look for TODO or FIXME comments related to the area + + + + If hypothesis is disproven, return to search phase with new insights. + If hypothesis stands, proceed to solution formulation. + + + + + Create a comprehensive technical solution - PRIORITIZE SIMPLICITY + + CRITICAL: Before proposing any solution, ask yourself: + 1. What existing variables/functions can I reuse? + 2. What's the minimal change that fixes the issue? + 3. Can I leverage existing patterns in the codebase? + 4. Is there a simpler approach I'm overlooking? + + The best solution often reuses existing code rather than creating new complexity. + + + + ALWAYS consider backwards compatibility: + 1. Will existing data/configurations still work with the new code? + 2. Can we detect and handle legacy formats automatically? + 3. What migration paths are needed for existing users? + 4. Are there ways to make changes additive rather than breaking? + 5. Document any compatibility considerations clearly + + + + FIRST, identify what can be reused: + - Variables that are already calculated but not used where needed + - Functions that already do what we need + - Patterns in similar features we can follow + - Configuration that already exists but isn't applied + + Example finding: + "The variable `calculatedValue` already contains what we need at line X, + we just need to use it at line Y instead of recalculating" + + + + - Start with the SIMPLEST possible fix + - Exact files to modify with line numbers + - Prefer changing variable usage over creating new logic + - Specific code changes required (minimal diff) + - Order of implementation steps + - Migration strategy if needed + + + + - All files that import affected code + - API contracts that must be maintained + - Existing tests that validate current behavior + - Configuration changes required (prefer reusing existing) + - Documentation updates needed + + + + - Unit tests to add or modify + - Integration tests required + - Edge cases to test + - Performance testing needs + - Manual testing scenarios + + + + - Breaking changes identified + - Performance implications + - Security considerations + - Backward compatibility issues + - Rollback strategy + + + + + + Create extremely detailed acceptance criteria + + Given [detailed context including system state] + When [specific user or system action] + Then [exact expected outcome] + And [additional verifiable outcomes] + But [what should NOT happen] + + Include: + - Specific UI changes with exact text/behavior + - API response formats + - Database state changes + - Performance requirements + - Error handling scenarios + + + - Each criterion must be independently testable + - Include both positive and negative test cases + - Specify exact error messages and codes + - Define performance thresholds where applicable + + + + + Format the comprehensive issue scoping section + + + + + Additional considerations for monorepo repositories: + - Scope all searches to the identified package (if monorepo) + - Check for cross-package dependencies + - Verify against package-specific conventions + - Look for package-specific configuration + - Check if changes affect multiple packages + - Identify shared dependencies that might be impacted + - Look for workspace-specific scripts or tooling + - Consider package versioning implications + + After completing the comprehensive issue scoping, update the main todo list to show + all investigation steps are complete: + + + [x] Detect current repository information + [x] Determine repository structure (monorepo/standard) + [x] Perform initial codebase discovery + [x] Analyze user request to determine issue type + [x] Gather and verify additional information + [x] Determine if user wants to contribute + [x] Perform issue scoping (if contributing) + [x] Extract keywords from the issue description + [x] Perform initial broad codebase search + [x] Analyze search results and identify key components + [x] Deep dive into relevant files and implementations + [x] Form initial hypothesis about the issue/feature + [x] Attempt to disprove hypothesis through further investigation + [x] Identify all affected files and dependencies + [x] Map out the complete implementation approach + [x] Document technical risks and edge cases + [x] Formulate comprehensive technical solution + [x] Create detailed acceptance criteria + [x] Prepare issue scoping summary + [-] Draft issue content + [ ] Review and confirm with user + [ ] Create GitHub issue + + + + + + + Check for Repository Issue Templates + + Check if the repository has custom issue templates and use them. If not, create a simple generic template. + + 1. Check for issue templates in standard locations: + + .github/ISSUE_TEMPLATE + true + + + 2. Also check for single template file: + + .github + false + + + Look for files like: + - .github/ISSUE_TEMPLATE/*.md + - .github/ISSUE_TEMPLATE/*.yml + - .github/ISSUE_TEMPLATE/*.yaml + - .github/issue_template.md + - .github/ISSUE_TEMPLATE.md + + 3. If templates are found: + a. Parse the template files to extract: + - Template name and description + - Required fields + - Template body structure + - Labels to apply + + b. For YAML templates, look for: + - name: Template display name + - description: Template description + - labels: Default labels + - body: Form fields or markdown template + + c. For Markdown templates, look for: + - Front matter with metadata + - Template structure with placeholders + + 4. If multiple templates exist, ask user to choose: + + I found the following issue templates in this repository. Which one would you like to use? + + [Template 1 name]: [Template 1 description] + [Template 2 name]: [Template 2 description] + + + + 5. If no templates are found: + - Create a simple generic template based on issue type + - For bugs: Basic structure with description, steps to reproduce, expected vs actual + - For features: Problem description, proposed solution, impact + + 6. Store the selected/created template information: + - Template content/structure + - Required fields + - Default labels + - Any special formatting requirements + + Update todos: + + + [x] Detect current repository information + [x] Determine repository structure (monorepo/standard) + [x] Perform initial codebase discovery + [x] Analyze user request to determine issue type + [x] Gather and verify additional information + [x] Determine if user wants to contribute + [x] Perform issue scoping (if contributing) + [x] Check for repository issue templates + [-] Draft issue content + [ ] Review and confirm with user + [ ] Create GitHub issue + + + + + + + Draft Issue Content + + Create the issue body using the template from step 8 and all verified information from codebase exploration. + + If using a repository template: + - Fill in the template fields with gathered information + - Include code references and findings where appropriate + - Respect the template's structure and formatting + + If using a generated template (no repo templates found): + + For Bug Reports: + ``` + ## Description + [Clear description of the bug with code context] + + ## Steps to Reproduce + 1. [Step with relevant code paths] + 2. [Step with component references] + 3. [Continue with specific details] + + ## Expected Behavior + [What should happen based on code logic] + + ## Actual Behavior + [What actually happens] + + ## Additional Context + - Version: [from package.json if found] + - Environment: [any relevant details] + - Error logs: [if any] + + ## Code Investigation + [Include findings from codebase exploration] + - Relevant files: [list with line numbers] + - Possible cause: [hypothesis from code review] + + [If user is contributing, add the comprehensive issue scoping section from step 7] + ``` + + For Feature Requests: + ``` + ## Problem Description + [What problem does this solve, who is affected, when it happens] + + ## Current Behavior + [How it works now with specific examples] + + ## Proposed Solution + [What should change] + + ## Impact + [Who benefits and how] + + ## Technical Context + [Findings from codebase exploration] + - Similar features: [code references] + - Integration points: [from exploration] + - Architecture considerations: [if any] + + [If contributing, add the comprehensive issue scoping section from step 7] + ``` + + Update todos: + + + [x] Detect current repository information + [x] Determine repository structure (monorepo/standard) + [x] Perform initial codebase discovery + [x] Analyze user request to determine issue type + [x] Gather and verify additional information + [x] Determine if user wants to contribute + [x] Perform issue scoping (if contributing) + [x] Check for repository issue templates [x] Draft issue content [-] Review and confirm with user [ ] Create GitHub issue @@ -302,19 +965,26 @@ - + Review and Confirm with User - Present the complete drafted issue to the user for review: + Present the complete drafted issue to the user for review, highlighting the + code-verified information: - I've prepared the following GitHub issue. Please review it carefully: + I've prepared the following GitHub issue based on my analysis of the codebase and your description. I've verified the technical details against the actual implementation. Please review: [Show the complete formatted issue content] + Key verifications made: + - ✓ Component locations confirmed in code + - ✓ Error messages matched to source + - ✓ Architecture compatibility checked + [List other relevant verifications] + Would you like me to create this issue, or would you like to make any changes? - Yes, create this issue in RooCodeInc/Roo-Code + Yes, create this issue in the detected repository Modify the problem description Add more technical details Change the title to: [let me specify] @@ -326,57 +996,164 @@ After confirmation: + [x] Detect current repository information + [x] Determine repository structure (monorepo/standard) + [x] Perform initial codebase discovery [x] Analyze user request to determine issue type - [x] Gather initial information for the issue + [x] Gather and verify additional information [x] Determine if user wants to contribute - [x] Perform technical analysis (if contributing) + [x] Perform issue scoping (if contributing) + [x] Check for repository issue templates [x] Draft issue content [x] Review and confirm with user - [-] Create GitHub issue + [-] Prepare issue for submission + [ ] Handle submission choice - - Create GitHub Issue + + Prepare Issue for Submission - Once user confirms, create the issue using the GitHub CLI: + Once user confirms the issue content, prepare it for submission: - First, save the issue body to a temporary file: + First, perform final duplicate check with refined search based on our findings: - cat > /tmp/issue_body.md << 'EOF' -[The complete formatted issue body from step 5] -EOF + gh issue list --repo $REPO_FULL_NAME --search "[key terms from verified analysis]" --state all --limit 10 - 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" - + If no exact duplicates are found, save the issue content to a temporary file within the project: - 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" - + + ./github_issue_draft.md + [The complete formatted issue body from step 8] + [calculated line count] + - The command will return the issue URL. Inform the user of the created issue number and URL. + After saving the issue draft, ask the user how they would like to proceed: - Clean up the temporary file: - - rm /tmp/issue_body.md - + + I've saved the issue draft to ./github_issue_draft.md. The issue is ready for submission with the following details: + + Title: "[Descriptive title with component name]" + Labels: [appropriate labels based on issue type] + Repository: $REPO_FULL_NAME + + How would you like to proceed? + + Submit the issue now to the repository + Let me make some edits to the issue first + I'll submit it manually later + + - Complete the workflow: + Based on the user's response: + + If "Submit the issue now": + - Use gh issue create with the saved file + - Provide the created issue URL and number + - Clean up the temporary file + - Complete the workflow + + If "Let me make some edits": + - Ask what changes they'd like to make + - Update the draft file with their changes + - Return to the submission question + + If "I'll submit it manually": + - Inform them the draft is saved at the configured location + - Provide the gh command they can use later + - Complete the workflow without submission + + Update todos based on the outcome: + [x] Detect current repository information + [x] Determine repository structure (monorepo/standard) + [x] Perform initial codebase discovery [x] Analyze user request to determine issue type - [x] Gather initial information for the issue + [x] Gather and verify additional information [x] Determine if user wants to contribute - [x] Perform technical analysis (if contributing) + [x] Perform issue scoping (if contributing) + [x] Check for repository issue templates [x] Draft issue content [x] Review and confirm with user - [x] Create GitHub issue + [x] Prepare issue for submission + [-] Handle submission choice + + + + + + + Handle Submission Choice + + This step handles the user's choice from step 9. + + OPTION 1: Submit the issue now + If the user chooses to submit immediately: + + + gh issue create --repo $REPO_FULL_NAME --title "[Descriptive title]" --body-file ./github_issue_draft.md --label "[appropriate labels]" + + + Label selection based on findings: + - Bug: Use "bug" label + - Feature: Use "enhancement" label + - If affects multiple packages in monorepo: add "affects-multiple" label + + After successful creation: + - Capture and display the issue URL + - Clean up the temporary file: + + rm ./github_issue_draft.md + + - Provide a summary of key findings included + + OPTION 2: Make edits + If the user wants to edit: + + + What changes would you like to make to the issue? + + Update the title + Modify the problem description + Add or remove technical details + Change the labels or other metadata + + + + - Apply the requested changes to the draft + - Update the file with write_to_file + - Return to step 9 to ask about submission again + + OPTION 3: Manual submission + If the user will submit manually: + + Provide clear instructions: + "The issue draft has been saved to ./github_issue_draft.md + + To submit it later, you can use: + gh issue create --repo $REPO_FULL_NAME --title "[Your title]" --body-file ./github_issue_draft.md --label "[labels]" + + Or you can copy the content and create the issue through the GitHub web interface." + + Final todo update: + + + [x] Detect current repository information + [x] Determine repository structure (monorepo/standard) + [x] Perform initial codebase discovery + [x] Analyze user request to determine issue type + [x] Gather and verify additional information + [x] Determine if user wants to contribute + [x] Perform issue scoping (if contributing) + [x] Check for repository issue templates + [x] Draft issue content + [x] Review and confirm with user + [x] Prepare issue for submission + [x] Handle submission choice diff --git a/.roo/rules-issue-writer/2_github_issue_templates.xml b/.roo/rules-issue-writer/2_github_issue_templates.xml index 3130f2026e..36b44125dd 100644 --- a/.roo/rules-issue-writer/2_github_issue_templates.xml +++ b/.roo/rules-issue-writer/2_github_issue_templates.xml @@ -1,219 +1,190 @@ - - Bug Report - Clearly report a bug with detailed repro steps - ["bug"] - - - - What version of Roo Code are you using? (e.g., v3.3.1) - - - - - - Anthropic - - AWS Bedrock - - Chutes AI - - DeepSeek - - Glama - - Google Gemini - - Google Vertex AI - - Groq - - Human Relay Provider - - LiteLLM - - LM Studio - - Mistral AI - - Ollama - - OpenAI - - OpenAI Compatible - - OpenRouter - - Requesty - - Unbound - - VS Code Language Model API - - xAI (Grok) - - Not Applicable / Other - - - - - Exact model name (e.g., Claude 3.7 Sonnet). Use N/A if irrelevant. - - - - - Help us see what you saw. Give clear, numbered steps: - - 1. Setup (OS, extension version, settings) - 2. Exact actions (clicks, input, files, commands) - 3. What happened after each step - - Think like you're writing a recipe. Without this, we can't reproduce the issue. - - - - - - Recap what went wrong in one or two lines. - - Example: "Expected code to run, but got an empty response and no error." - - Expected ___, but got ___. - - - - Paste API logs, terminal output, or errors here. Use triple backticks (```) for code formatting. - shell - - - - - - Detailed Feature Proposal - Report a specific problem that needs solving in Roo Code - ["proposal", "enhancement"] - - - - - **Be concrete and detailed.** Explain the problem from a user's perspective. - - ✅ **Good examples (specific, clear impact):** - - "When running large tasks, users wait 5+ minutes because tasks execute sequentially instead of in parallel, blocking productivity" - - "AI can only read one file per request, forcing users to make multiple requests for multi-file projects, increasing wait time from 30s to 5+ minutes" - - "Dark theme users can't see the submit button because it uses white text on light grey background" - - ❌ **Poor examples (vague, unclear impact):** - - "The UI looks weird" -> What specifically looks weird? On which screen? What's the impact? - - "System prompt is not good" -> What's wrong with it? What behaviour does it cause? What should it do instead? - - "Performance could be better" -> Where? How slow is it currently? What's the user impact? - - **Your problem description should answer:** - - Who is affected? (all users, specific user types, etc.) - - When does this happen? (specific scenarios/steps) - - What's the current behaviour vs expected behaviour? - - What's the impact? (time wasted, errors caused, etc.) - - Be specific about the problem, who it affects, and the impact. Avoid generic statements like "it's slow" or "it's confusing." - - - - Mockups, screenshots, links, user quotes, or other relevant information that supports your proposal. - - + + This mode prioritizes using repository-specific issue templates over hardcoded ones. + If no templates exist in the repository, simple generic templates are created on the fly. + + + + + .github/ISSUE_TEMPLATE/*.yml + .github/ISSUE_TEMPLATE/*.yaml + .github/ISSUE_TEMPLATE/*.md + .github/issue_template.md + .github/ISSUE_TEMPLATE.md + - - - - - **Important:** If you check "Yes" below, the technical sections become REQUIRED. - We need detailed technical analysis from contributors to ensure quality implementation. - - - - - - - - - - - **If you want to implement this feature, this section is REQUIRED.** - - **Describe your solution in detail.** Explain not just what to build, but how it should work. - - ✅ **Good examples:** - - "Add parallel task execution: Allow up to 3 tasks to run simultaneously with a queue system for additional tasks. Show progress for each active task in the UI." - - "Enable multi-file AI processing: Modify the request handler to accept multiple files in a single request and process them together, reducing round trips." - - "Fix button contrast: Change submit button to use primary colour on dark theme (white text on blue background) instead of current grey." - - ❌ **Poor examples:** - - "Make it faster" -> How? What specific changes? - - "Improve the UI" -> Which part? What specific improvements? - - "Fix the prompt" -> What should the new prompt do differently? - - **Your solution should explain:** - - What exactly will change? - - How will users interact with it? - - What will the new behaviour look like? - - Describe the specific changes and how they will work. Include user interaction details if relevant. - - - - - **If you want to implement this feature, this section is REQUIRED.** - - **This is crucial - don't skip it.** Define what "working" looks like with specific, testable criteria. - - **Format suggestion:** - ``` - Given [context/situation] - When [user action] - Then [expected result] - And [additional expectations] - But [what should NOT happen] - ``` - - **Example:** - ``` - Given I have 5 large tasks to run - When I start all of them - Then they execute in parallel (max 3 at once, can be configured) - And I see progress for each active task - And queued tasks show "waiting" status - But the UI doesn't freeze or become unresponsive - ``` - - - Define specific, testable criteria. What should users be able to do? What should happen? What should NOT happen? - Use the Given/When/Then format above or your own clear structure. - - - - - - **If you want to implement this feature, this section is REQUIRED.** - - Share technical insights that could help planning: - - Implementation approach or architecture changes - - Performance implications - - Compatibility concerns - - Systems that might be affected - - Potential blockers you can foresee - - e.g., "Will need to refactor task manager", "Could impact memory usage on large files", "Requires a large portion of code to be rewritten" - - - - - **If you want to implement this feature, this section is REQUIRED.** - - What could go wrong or what alternatives did you consider? - - Alternative approaches and why you chose this one - - Potential negative impacts (performance, UX, etc.) - - Breaking changes or migration concerns - - Edge cases that need careful handling - - e.g., "Alternative: use library X but it is 500KB larger", "Risk: might slow older devices", "Breaking: changes API response format" - - - - - - - Template now focuses on problem reporting first, with solution contribution as optional - - - Only problem description and context are required for basic submission - - - Technical fields (solution, acceptance criteria, etc.) are only required if user wants to contribute - - - Users can submit after describing the problem without technical details - - - Implementation guidance moved to contributor section only - - + + Display name of the template + Brief description of when to use this template + Default issue title (optional) + Array of labels to apply + Array of default assignees + Array of form elements or markdown content + + + + + Static markdown content + + The markdown content to display + + + + + Single-line text input + + Unique identifier + Display label + Help text + Placeholder text + Default value + Boolean + + + + + Multi-line text input + + Unique identifier + Display label + Help text + Placeholder text + Default value + Boolean + Language for syntax highlighting + + + + + Dropdown selection + + Unique identifier + Display label + Help text + Array of options + Boolean + + + + + Multiple checkbox options + + Unique identifier + Display label + Help text + Array of checkbox items + + + + + + + Optional YAML front matter with: + - name: Template name + - about: Template description + - title: Default title + - labels: Comma-separated or array + - assignees: Comma-separated or array + + + Markdown content with sections and placeholders + Common patterns: + - Headers with ## + - Placeholder text in brackets or as comments + - Checklists with - [ ] + - Code blocks with ``` + + + + + + + When no repository templates exist, create simple templates based on issue type. + These should be minimal and focused on gathering essential information. + + + + + - Description: Clear explanation of the bug + - Steps to Reproduce: Numbered list + - Expected Behavior: What should happen + - Actual Behavior: What actually happens + - Additional Context: Version, environment, logs + - Code Investigation: Findings from exploration (if any) + + ["bug"] + + + + + - Problem Description: What problem this solves + - Current Behavior: How it works now + - Proposed Solution: What should change + - Impact: Who benefits and how + - Technical Context: Code findings (if any) + + ["enhancement", "proposal"] + + + + + + When parsing YAML templates: + 1. Use a YAML parser to extract the structure + 2. Convert form elements to markdown sections + 3. Preserve required field indicators + 4. Include descriptions as help text + 5. Maintain the intended flow of the template + + + + When parsing Markdown templates: + 1. Extract front matter if present + 2. Identify section headers + 3. Look for placeholder patterns + 4. Preserve formatting and structure + 5. Replace generic placeholders with user's information + + + + For template selection: + 1. If only one template exists, use it automatically + 2. If multiple exist, let user choose based on name/description + 3. Match template to issue type when possible (bug vs feature) + 4. Respect template metadata (labels, assignees, etc.) + + + + + + Fill templates intelligently using gathered information: + - Map user's description to appropriate sections + - Include code investigation findings where relevant + - Preserve template structure and formatting + - Don't leave placeholder text unfilled + - Add contributor scoping if user is contributing + + + + + + + + + + + + + When no templates exist, create appropriate generic templates on the fly. + Keep them simple and focused on essential information. + + + + - Don't overwhelm with too many fields + - Focus on problem description first + - Include technical details only if user is contributing + - Use clear, simple section headers + - Adapt based on issue type (bug vs feature) + + \ No newline at end of file diff --git a/.roo/rules-issue-writer/3_best_practices.xml b/.roo/rules-issue-writer/3_best_practices.xml index 6d70cba144..f2f149ed26 100644 --- a/.roo/rules-issue-writer/3_best_practices.xml +++ b/.roo/rules-issue-writer/3_best_practices.xml @@ -1,38 +1,172 @@ + + - CRITICAL: This mode assumes the user's FIRST message is already an issue description + - Do NOT ask "What would you like to do?" or "Do you want to create an issue?" + - Immediately start the issue creation workflow when the user begins talking + - Treat their initial message as the problem/feature description + - Begin with repository detection and codebase discovery right away + - The user is already in "issue creation mode" by choosing this mode + + + + - ALWAYS check for repository-specific issue templates before creating issues + - Use templates from .github/ISSUE_TEMPLATE/ directory if they exist + - Parse both YAML (.yml/.yaml) and Markdown (.md) template formats + - If multiple templates exist, let the user choose the appropriate one + - If no templates exist, create a simple generic template on the fly + - NEVER fall back to hardcoded templates - always use repo templates or generate minimal ones + - Respect template metadata like labels, assignees, and title patterns + - Fill templates intelligently using gathered information from codebase exploration + + - Focus on helping users describe problems clearly, not solutions - - The Roo team will design solutions unless the user explicitly wants to contribute + - The project team will design solutions unless the user explicitly wants to contribute - Don't push users to provide technical details they may not have - Make it easy for non-technical users to report issues effectively + + CRITICAL: Lead with user impact: + - Always explain WHO is affected and WHEN the problem occurs + - Use concrete examples with actual values, not abstractions + - Show before/after scenarios with specific data + - Example: "Users trying to [action] see [actual result] instead of [expected result]" + + - ALWAYS verify user claims against actual code implementation + - For feature requests, aggressively check if current behavior matches user's description + - If code shows different intent than user describes, it might be a bug not a feature + - Present code evidence when challenging user assumptions + - Do not be agreeable - be fact-driven and question discrepancies + - Continue verification until facts are established + - A "feature request" where code shows the feature should already work is likely a bug + + CRITICAL additions for thorough analysis: + - Trace data flow from where values are created to where they're used + - Look for existing variables/functions that already contain needed data + - Check if the issue is just missing usage of existing code + - Follow imports and exports to understand data availability + - Identify patterns in similar features that work correctly + + - Always search for existing similar issues before creating a new one - - Search GitHub Discussions (especially feature-requests category) for related topics + - Check for and use repository issue templates before creating content - Include specific version numbers and environment details - Use code blocks with syntax highlighting for code snippets - Make titles descriptive but concise (e.g., "Dark theme: Submit button invisible due to white-on-grey text") - For bugs, always test if the issue is reproducible - Include screenshots or mockups when relevant (ask user to provide) - Link to related issues or PRs if found during exploration - - Add "Closes #[number]" for discussions that would be fully addressed by the issue - - Add "Related to #[number]" for partially related discussions + + CRITICAL: Use concrete examples throughout: + - Show actual data values, not just descriptions + - Include specific file paths and line numbers + - Demonstrate the data flow with real examples + - Bad: "The value is incorrect" + - Good: "The function returns '123' when it should return '456'" - - Only explore codebase if user wants to contribute + - Only perform issue scoping if user wants to contribute - Reference specific files and line numbers from codebase exploration - Ensure technical proposals align with project architecture - - Include implementation steps and technical analysis + - Include implementation steps and issue scoping - Provide clear acceptance criteria in Given/When/Then format - Consider trade-offs and alternative approaches + + CRITICAL: Prioritize simple solutions: + - ALWAYS check if needed functionality already exists before proposing new code + - Look for existing variables that just need to be passed/used differently + - Prefer using existing patterns over creating new ones + - The best fix often involves minimal code changes + - Example: "Use existing `modeInfo` from line 234 in export" vs "Create new mode tracking system" + + ALWAYS consider backwards compatibility: + - Think about existing data/configurations already in use + - Propose solutions that handle both old and new formats gracefully + - Consider migration paths for existing users + - Document any breaking changes clearly + - Prefer additive changes over breaking changes when possible + + - Be supportive and encouraging to problem reporters - Don't overwhelm users with technical questions upfront - Clearly indicate when technical sections are optional - Guide contributors through the additional requirements - Make the "submit now" option clear for problem reporters + - When presenting template choices, include template descriptions to help users choose + - Explain that you're using the repository's own templates for consistency + + + + Always check these locations in order: + 1. .github/ISSUE_TEMPLATE/*.yml or *.yaml (GitHub form syntax) + 2. .github/ISSUE_TEMPLATE/*.md (Markdown templates) + 3. .github/issue_template.md (single template) + 4. .github/ISSUE_TEMPLATE.md (alternate naming) + + + + For YAML templates: + - Extract form elements and convert to appropriate markdown sections + - Preserve required field indicators + - Include field descriptions as context + - Respect dropdown options and checkbox lists + + For Markdown templates: + - Parse front matter for metadata + - Identify section headers and structure + - Replace placeholder text with actual information + - Maintain formatting and hierarchy + + + + - Map gathered information to template sections intelligently + - Don't leave placeholder text in the final issue + - Add code investigation findings to relevant sections + - Include contributor scoping in appropriate section if applicable + - Preserve the template's intended structure and flow + + + + When no templates exist: + - Create minimal, focused templates + - Use simple section headers + - Focus on essential information only + - Adapt structure based on issue type + - Don't overwhelm with unnecessary fields + + + + + Before proposing ANY solution: + 1. Use codebase_search extensively to find all related code + 2. Read multiple files to understand the full context + 3. Trace variable usage from creation to consumption + 4. Look for similar working features to understand patterns + 5. Identify what already exists vs what's actually missing + + + + When designing solutions: + 1. Check if the data/function already exists somewhere + 2. Look for configuration options before code changes + 3. Prefer passing existing variables over creating new ones + 4. Use established patterns from similar features + 5. Aim for minimal diff size + + + + Always include: + - Exact file paths and line numbers + - Variable/function names as they appear in code + - Before/after code snippets showing minimal changes + - Clear explanation of why the simple fix works + + \ No newline at end of file diff --git a/.roo/rules-issue-writer/4_common_mistakes_to_avoid.xml b/.roo/rules-issue-writer/4_common_mistakes_to_avoid.xml index 2013bd73d8..a8dd9b590b 100644 --- a/.roo/rules-issue-writer/4_common_mistakes_to_avoid.xml +++ b/.roo/rules-issue-writer/4_common_mistakes_to_avoid.xml @@ -1,4 +1,13 @@ + + - CRITICAL: Asking "What would you like to do?" when mode starts + - Waiting for user to say "create an issue" or "make me an issue" + - Not treating the first user message as the issue description + - Delaying the workflow start with unnecessary questions + - Asking if they want to create an issue when they've already chosen this mode + - Not immediately beginning repository detection and codebase discovery + + - Vague descriptions like "doesn't work" or "broken" - Missing reproduction steps for bugs @@ -12,19 +21,106 @@ - Asking for technical details from non-contributing users - - Exploring codebase before confirming user wants to contribute + - Performing issue scoping before confirming user wants to contribute - Requiring acceptance criteria from problem reporters - Making the process too complex for simple problem reports - Not clearly indicating the "submit now" option - Overwhelming users with contributor requirements upfront + - Using hardcoded templates instead of repository templates + - Not checking for issue templates before creating content + - Ignoring template metadata like labels and assignees - Starting implementation before approval - - Not providing detailed technical analysis when contributing + - Not providing detailed issue scoping when contributing - Missing acceptance criteria for contributed features - Forgetting to include technical context from code exploration - Not considering trade-offs and alternatives - Proposing solutions without understanding current architecture + + + Not tracing data flow completely through the system + Missing that data already exists leads to proposing unnecessary new code + + - Use codebase_search extensively to find ALL related code + - Trace variables from creation to consumption + - Check if needed data is already calculated but not used + - Look for similar working features as patterns + + + Bad: "Add mode tracking to import function" + Good: "The export already includes mode info at line 234, just use it in import at line 567" + + + + + Proposing complex new systems when simple fixes exist + Creates unnecessary complexity, maintenance burden, and potential bugs + + - ALWAYS check if functionality already exists first + - Look for minimal changes that solve the problem + - Prefer using existing variables/functions differently + - Aim for the smallest possible diff + + + Bad: "Create new state management system for mode tracking" + Good: "Pass existing modeInfo variable from line 45 to the function at line 78" + + + + + Not reading actual code before proposing solutions + Solutions don't match the actual codebase structure + + - Always read the relevant files first + - Verify exact line numbers and content + - Check imports/exports to understand data availability + - Look at similar features that work correctly + + + + + Creating new patterns instead of following existing ones + Inconsistent codebase, harder to maintain + + - Find similar features that work correctly + - Follow the same patterns and structures + - Reuse existing utilities and helpers + - Maintain consistency with the codebase style + + + + + Using hardcoded templates when repository templates exist + Issues don't follow repository conventions, may be rejected or need reformatting + + - Always check .github/ISSUE_TEMPLATE/ directory first + - Parse and use repository templates when available + - Only create generic templates when none exist + + + + + Not properly parsing YAML template structure + Missing required fields, incorrect formatting, lost metadata + + - Parse YAML templates to extract all form elements + - Convert form elements to appropriate markdown sections + - Preserve field requirements and descriptions + - Maintain dropdown options and checkbox lists + + + + + Leaving placeholder text in final issue + Unprofessional appearance, confusion about what information is needed + + - Replace all placeholders with actual information + - Remove instruction text meant for template users + - Fill every section with relevant content + - Add "N/A" for truly inapplicable sections + + \ 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 index 8beb024d15..1792be87eb 100644 --- a/.roo/rules-issue-writer/5_github_cli_usage.xml +++ b/.roo/rules-issue-writer/5_github_cli_usage.xml @@ -3,9 +3,8 @@ 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. + Note: This mode prioritizes using repository-specific issue templates over + hardcoded ones. Templates are detected and used dynamically from the repository. @@ -16,7 +15,7 @@ - gh issue list --repo RooCodeInc/Roo-Code --search "dark theme button visibility" --state all --limit 20 + gh issue list --repo $REPO_FULL_NAME --search "dark theme button visibility" --state all --limit 20 @@ -35,7 +34,7 @@ - gh search issues --repo RooCodeInc/Roo-Code "dark theme button" --limit 10 + gh search issues --repo $REPO_FULL_NAME "dark theme button" --limit 10 @@ -47,7 +46,7 @@ - gh issue view 123 --repo RooCodeInc/Roo-Code --comments + gh issue view 123 --repo $REPO_FULL_NAME --comments @@ -58,6 +57,46 @@ + + + + Use to check for issue templates in the repository before creating issues. + This is not a gh command but necessary for template detection. + + + Check for templates in standard location: + + .github/ISSUE_TEMPLATE + true + + + Check for single template file: + + .github + false + + + + + + + Read template files to parse their structure and content. + Used after detecting template files. + + + Read YAML template: + + .github/ISSUE_TEMPLATE/bug_report.yml + + + Read Markdown template: + + .github/ISSUE_TEMPLATE/feature_request.md + + + + + These commands should ONLY be used if the user has indicated they want to @@ -70,7 +109,7 @@ - gh repo view RooCodeInc/Roo-Code --json defaultBranchRef,description,updatedAt + gh repo view $REPO_FULL_NAME --json defaultBranchRef,description,updatedAt @@ -82,7 +121,7 @@ - gh search prs --repo RooCodeInc/Roo-Code "dark theme" --limit 10 --state all + gh search prs --repo $REPO_FULL_NAME "dark theme" --limit 10 --state all @@ -105,18 +144,19 @@ 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 + 2. Checking for and using repository templates + 3. Gathering all required information + 4. Determining if user is contributing or just reporting + 5. 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 $REPO_FULL_NAME --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" + gh issue create --repo $REPO_FULL_NAME --title "[Problem-focused title]" --body-file /tmp/issue_body.md --label "proposal" --label "enhancement" @@ -138,7 +178,7 @@ - gh issue comment 456 --repo RooCodeInc/Roo-Code --body "Additional context or comments." + gh issue comment 456 --repo $REPO_FULL_NAME --body "Additional context or comments." @@ -150,7 +190,7 @@ - gh issue edit 456 --repo RooCodeInc/Roo-Code --title "[Updated title]" --body "[Updated body]" + gh issue edit 456 --repo $REPO_FULL_NAME --title "[Updated title]" --body "[Updated body]" @@ -164,41 +204,41 @@ 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 - + + Template detection (NEW): + 1. Use list_files to check .github/ISSUE_TEMPLATE/ directory + 2. Read any template files found (YAML or Markdown) + 3. Parse template structure and metadata + 4. If multiple templates, let user choose + 5. If no templates, prepare to create generic one + - + 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` + 1. Clone repo locally if needed: `gh repo clone $REPO_FULL_NAME` 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 + 1. Use repository template if found, or generic template if not + 2. Fill template with gathered information + 3. Format differently based on contributor vs problem reporter 4. Save formatted body to temporary file - 5. Use `gh issue create` with appropriate labels + 5. Use `gh issue create` with appropriate labels from template 6. Capture the returned issue URL 7. Show user the created issue URL - + @@ -270,4 +310,33 @@ gh repo clone - Clone repository + + + + When parsing YAML templates: + - Extract 'name' for template identification + - Get 'labels' array for automatic labeling + - Parse 'body' array for form elements + - Convert form elements to markdown sections + - Preserve 'required' field indicators + + + + When parsing Markdown templates: + - Check for YAML front matter + - Extract metadata (labels, assignees) + - Identify section headers + - Replace placeholder text + - Maintain formatting structure + + + + 1. Detect templates with list_files + 2. Read templates with read_file + 3. Parse structure and metadata + 4. Let user choose if multiple exist + 5. Fill template with information + 6. Create issue with template content + + \ No newline at end of file diff --git a/.roo/rules-issue-writer/6_technical_analysis_workflow.xml b/.roo/rules-issue-writer/6_technical_analysis_workflow.xml deleted file mode 100644 index c61d8fc1ca..0000000000 --- a/.roo/rules-issue-writer/6_technical_analysis_workflow.xml +++ /dev/null @@ -1,349 +0,0 @@ - - - This sub-workflow provides an aggressive, thorough, and all-encompassing investigation - process for technical analysis when creating GitHub issues. It employs methods from - the issue-investigator mode to deeply analyze the codebase and formulate comprehensive - technical solutions. This workflow is designed to produce scoped issues that can be - used in automated fix workflows. - - - - - Create Investigation Plan - - When technical analysis is requested, immediately create a comprehensive todo list - to track the investigation progress. - - - -[ ] Extract keywords from the issue description -[ ] Perform initial broad codebase search -[ ] Analyze search results and identify key components -[ ] Deep dive into relevant files and implementations -[ ] Form initial hypothesis about the issue/feature -[ ] Attempt to disprove hypothesis through further investigation -[ ] Identify all affected files and dependencies -[ ] Map out the complete implementation approach -[ ] Document technical risks and edge cases -[ ] Formulate comprehensive technical solution -[ ] Create detailed acceptance criteria -[ ] Prepare technical analysis summary - - - ]]> - - - - - - - Extract all relevant keywords, concepts, and technical terms from the issue description. - Be exhaustive - include function names, error messages, feature names, and related concepts. - - - Identify primary technical concepts - Extract error messages or specific symptoms - Note any mentioned file paths or components - List related features or functionality - Include synonyms and related terms - - Mark "Extract keywords from the issue description" as complete - - - - - Perform multiple rounds of codebase searches, starting broad and progressively - narrowing based on findings. This is an aggressive, exhaustive search process. - - - Initial Broad Search - - Use codebase_search with all extracted keywords to get an overview of relevant code. - -[Combined keywords from extraction phase] - - ]]> - - - - - Component Discovery - - Based on initial results, identify key components and search for: - - Related class/function definitions - - Import statements and dependencies - - Configuration files - - Test files that might reveal expected behavior - - - - - Deep Implementation Search - - Search for specific implementation details: - - Error handling patterns - - State management - - API endpoints or routes - - Database queries or models - - UI components and their interactions - - - - - Edge Case and Integration Search - - Look for: - - Edge cases in the code - - Integration points with other systems - - Configuration options that affect behavior - - Feature flags or conditional logic - - - - Update search-related todos as each iteration completes - - - - - Thoroughly analyze all relevant files discovered during the search phase. - - - Use list_code_definition_names to understand file structure - Read complete files to understand full context - Trace execution paths through the code - Identify all dependencies and imports - Map relationships between components - - - Document findings including: - - File paths and their purposes - - Key functions and their responsibilities - - Data flow through the system - - External dependencies - - Potential impact areas - - Mark file analysis todos as complete - - - - - Form a comprehensive hypothesis about the issue or feature implementation. - - - - Identify the most likely root cause - Trace the bug through the execution path - Determine why the current implementation fails - Consider environmental factors - - - - - Identify the optimal integration points - Determine required architectural changes - Plan the implementation approach - Consider scalability and maintainability - - - Mark hypothesis formation as complete - - - - - Aggressively attempt to disprove the hypothesis by searching for contradictory evidence. - - - - Search for Alternative Implementations - Look for similar features implemented differently - Check for deprecated code that might interfere - - - Configuration and Environment Check - Search for configuration that could change behavior - Look for environment-specific code paths - - - Test Case Analysis - Find existing tests that might contradict hypothesis - Look for test cases that reveal edge cases - - - Historical Context - Search for comments explaining design decisions - Look for TODO or FIXME comments related to the area - - - - If hypothesis is disproven, return to search phase with new insights. - If hypothesis stands, proceed to solution formulation. - - Update hypothesis validation status - - - - - Create a comprehensive technical solution with extreme detail. - - - -
- - Exact files to modify with line numbers - - New files to create with full paths - - Specific code changes required - - Order of implementation steps - - Migration strategy if needed -
-
- - -
- - All files that import affected code - - API contracts that must be maintained - - Database schema changes if any - - Configuration changes required - - Documentation updates needed -
-
- - -
- - Unit tests to add or modify - - Integration tests required - - Edge cases to test - - Performance testing needs - - Manual testing scenarios -
-
- - -
- - Breaking changes identified - - Performance implications - - Security considerations - - Backward compatibility issues - - Rollback strategy -
-
-
- Mark solution formulation as complete -
- - - - Create extremely detailed acceptance criteria that can guide automated implementation. - - - - Each criterion must be independently testable - Include both positive and negative test cases - Specify exact error messages and codes - Define performance thresholds where applicable - - Mark acceptance criteria creation as complete - -
- - - - - - - - All keywords extracted and searched - Multiple search iterations completed - All relevant files analyzed - Hypothesis formed and validated - Comprehensive solution documented - Acceptance criteria defined - All risks and edge cases identified - Technical analysis formatted for issue - - - Mark all investigation todos as complete and update the main workflow todo list - - - \ No newline at end of file diff --git a/.roo/rules-mode-writer/1_mode_creation_workflow.xml b/.roo/rules-mode-writer/1_mode_creation_workflow.xml index 15a48aa804..77a1728599 100644 --- a/.roo/rules-mode-writer/1_mode_creation_workflow.xml +++ b/.roo/rules-mode-writer/1_mode_creation_workflow.xml @@ -1,124 +1,278 @@ - + - This workflow guides you through creating a new custom mode to be used in the Roo Code Software, - from initial requirements gathering to final implementation. + This workflow guides you through creating new custom modes or editing existing modes + for the Roo Code Software, ensuring comprehensive understanding and cohesive implementation. - + - Gather Requirements + Determine User Intent - Understand what the user wants the mode to accomplish + Identify whether the user wants to create a new mode or edit an existing one - - Ask about the mode's primary purpose and use cases - Identify what types of tasks the mode should handle - Determine what tools and file access the mode needs - Clarify any special behaviors or restrictions - - + + + + User mentions a specific mode by name or slug + User references a mode directory path (e.g., .roo/rules-[mode-slug]) + User asks to modify, update, enhance, or fix an existing mode + User says "edit this mode" or "change this mode" + + + + + User asks to create a new mode + User describes a new capability not covered by existing modes + User says "make a mode for" or "create a mode that" + + + + - What is the primary purpose of this new mode? What types of tasks should it handle? + I want to make sure I understand correctly. Are you looking to create a brand new mode or modify an existing one? - A mode for writing and maintaining documentation - A mode for database schema design and migrations - A mode for API endpoint development and testing - A mode for performance optimization and profiling + Create a new mode for a specific purpose + Edit an existing mode to add new capabilities + Fix issues in an existing mode + Enhance an existing mode with better workflows - + + - - Design Mode Configuration - - Create the mode definition with all required fields - - - - Unique identifier (lowercase, hyphens allowed) - Keep it short and descriptive (e.g., "api-dev", "docs-writer") - - - Display name with optional emoji - Use an emoji that represents the mode's purpose - - - Detailed description of the mode's role and expertise - - Start with "You are Roo Code, a [specialist type]..." - List specific areas of expertise - Mention key technologies or methodologies - - - - Tool groups the mode can access - - - - - - - - - - - - Clear description for the Orchestrator - Explain specific scenarios and task types - - - - Do not include customInstructions in the .roomodes configuration. - All detailed instructions should be placed in XML files within - the .roo/rules-[mode-slug]/ directory instead. - - + + + + Gather Requirements for New Mode + + Understand what the user wants the new mode to accomplish + + + Ask about the mode's primary purpose and use cases + Identify what types of tasks the mode should handle + Determine what tools and file access the mode needs + Clarify any special behaviors or restrictions + + + + What is the primary purpose of this new mode? What types of tasks should it handle? + + A mode for writing and maintaining documentation + A mode for database schema design and migrations + A mode for API endpoint development and testing + A mode for performance optimization and profiling + + + + - - Implement File Restrictions - - Configure appropriate file access permissions - - - Restrict edit access to specific file types - + + Design Mode Configuration + + Create the mode definition with all required fields + + + + Unique identifier (lowercase, hyphens allowed) + Keep it short and descriptive (e.g., "api-dev", "docs-writer") + + + Display name with optional emoji + Use an emoji that represents the mode's purpose + + + Detailed description of the mode's role and expertise + + Start with "You are Roo Code, a [specialist type]..." + List specific areas of expertise + Mention key technologies or methodologies + + + + Tool groups the mode can access + + + + + + + + + + + + Clear description for the Orchestrator + Explain specific scenarios and task types + + + + Do not include customInstructions in the .roomodes configuration. + All detailed instructions should be placed in XML files within + the .roo/rules-[mode-slug]/ directory instead. + + + + + Implement File Restrictions + + Configure appropriate file access permissions + + + Restrict edit access to specific file types + groups: - read - - edit - fileRegex: \.(md|txt|rst)$ description: Documentation files only - command - - - - Use regex patterns to limit file editing scope - Provide clear descriptions for restrictions - Consider the principle of least privilege - - + + + + Use regex patterns to limit file editing scope + Provide clear descriptions for restrictions + Consider the principle of least privilege + + - - Create XML Instruction Files + + Create XML Instruction Files + + Design structured instruction files in .roo/rules-[mode-slug]/ + + + Main workflow and step-by-step processes + Guidelines and conventions + Reusable code patterns and examples + Specific tool usage instructions + Complete workflow examples + + + Use semantic tag names that describe content + Nest tags hierarchically for better organization + Include code examples in CDATA sections when needed + Add comments to explain complex sections + + + + + + + Immerse in Existing Mode + + Fully understand the existing mode before making any changes + + + Locate and read the mode configuration in .roomodes + Read all XML instruction files in .roo/rules-[mode-slug]/ + Analyze the mode's current capabilities and limitations + Understand the mode's role in the broader ecosystem + + + + What specific aspects of the mode would you like to change or enhance? + + Add new capabilities or tool permissions + Fix issues with current workflows or instructions + Improve the mode's roleDefinition or whenToUse description + Enhance XML instructions for better clarity + + + + + + + Analyze Change Impact + + Understand how proposed changes will affect the mode + + + Compatibility with existing workflows + Impact on file permissions and tool access + Consistency with mode's core purpose + Integration with other modes + + + + I've analyzed the existing mode. Here's what I understand about your requested changes. Is this correct? + + Yes, that's exactly what I want to change + Mostly correct, but let me clarify some details + No, I meant something different + I'd like to add additional changes + + + + + + + Plan Modifications + + Create a detailed plan for modifying the mode + + + Identify which files need to be modified + Determine if new XML instruction files are needed + Check for potential conflicts or contradictions + Plan the order of changes for minimal disruption + + + + + Implement Changes + + Apply the planned modifications to the mode + + + Update .roomodes configuration if needed + Modify existing XML instruction files + Create new XML instruction files if required + Update examples and documentation + + + + + + + + Validate Cohesion and Consistency - Design structured instruction files in .roo/rules-[mode-slug]/ + Ensure all changes are cohesive and don't contradict each other - - Main workflow and step-by-step processes - Guidelines and conventions - Reusable code patterns and examples - Specific tool usage instructions - Complete workflow examples - - - Use semantic tag names that describe content - Nest tags hierarchically for better organization - Include code examples in CDATA sections when needed - Add comments to explain complex sections - + + + Mode slug follows naming conventions + File restrictions align with mode purpose + Tool permissions are appropriate + whenToUse clearly differentiates from other modes + + + All XML files follow consistent structure + No contradicting instructions between files + Examples align with stated workflows + Tool usage matches granted permissions + + + Mode integrates well with Orchestrator + Clear boundaries with other modes + Handoff points are well-defined + + + + + I've completed the validation checks. Would you like me to review any specific aspect in more detail? + + Review the file permission patterns + Check for workflow contradictions + Verify integration with other modes + Everything looks good, proceed to testing + + + - + Test and Refine Verify the mode works as intended @@ -129,14 +283,19 @@ groups: Instructions are clear and actionable Mode integrates well with Orchestrator All examples are accurate and helpful + Changes don't break existing functionality (for edits) + New capabilities work as expected - + Create mode in .roomodes for project-specific modes Create mode in global custom_modes.yaml for system-wide modes Use list_files to verify .roo folder structure Test file regex patterns with search_files + Use codebase_search to find existing mode implementations + Read all XML files in a mode directory to understand its structure + Always validate changes for cohesion and consistency - \ No newline at end of file + \ No newline at end of file diff --git a/.roo/rules-mode-writer/5_complete_mode_examples.xml b/.roo/rules-mode-writer/5_complete_mode_examples.xml index 45fd577c53..7c8f8a4cde 100644 --- a/.roo/rules-mode-writer/5_complete_mode_examples.xml +++ b/.roo/rules-mode-writer/5_complete_mode_examples.xml @@ -1,96 +1,214 @@ - - - Generate OpenAPI documentation for a REST API with user management endpoints - + + + + Edit the test mode to add support for performance testing and benchmarking + + + + I want to edit the test mode to add benchmark testing capabilities + - - - Discover API endpoints - -express router app.get app.post app.put app.delete @Route @Get @Post - - ]]> - Found routes in src/routes/users.ts - + + + Determine user intent and clarify scope + +I understand you want to edit the test mode to add performance testing capabilities. Before we proceed, let me confirm the scope of changes. What specific performance testing features do you need? + +Add benchmark testing with Vitest's bench API +Include performance profiling and memory usage tracking +Add load testing capabilities for API endpoints +All of the above - comprehensive performance testing suite + + + ]]> + User selected: Add benchmark testing with Vitest's bench API + - - Analyze endpoint implementation - + Immerse in existing test mode configuration + -src/routes/users.ts +.roomodes - ]]> - + ]]> + Found test mode configuration with current roleDefinition and file restrictions + - - Generate OpenAPI specification - + Explore existing test mode instructions + +.roo/rules-test +true + + ]]> + +.roo/rules-test/1_workflow.xml + + ]]> + Understood current test workflows and patterns + + + + Validate changes for cohesion + +I've analyzed the test mode. Adding benchmark testing would require: +1. Updating the roleDefinition to include performance testing expertise +2. Modifying file restrictions to include .bench.ts files +3. Adding new workflow instructions for benchmark creation +4. Including Vitest bench API examples + +This aligns well with the existing testing focus. Should I proceed with all these changes? + +Yes, implement all the changes as described +Start with just the roleDefinition and file restrictions +Focus only on the workflow instructions first +Let me review the specific changes before proceeding + + + ]]> + User selected: Yes, implement all the changes as described + + + + Update mode configuration in .roomodes + +.roomodes + +<<<<<<< SEARCH + roleDefinition: |- + You are Roo, a Vitest testing specialist with deep expertise in: - Writing and maintaining Vitest test suites - Test-driven development (TDD) practices - Mocking and stubbing with Vitest - Integration testing strategies - TypeScript testing patterns - Code coverage analysis - Test performance optimization +======= + roleDefinition: |- + You are Roo, a Vitest testing specialist with deep expertise in: - Writing and maintaining Vitest test suites - Test-driven development (TDD) practices - Mocking and stubbing with Vitest - Integration testing strategies - TypeScript testing patterns - Code coverage analysis - Test performance optimization - Benchmark testing with Vitest bench API - Performance profiling and optimization - Memory usage analysis in tests +>>>>>>> REPLACE + + + ]]> + + + + Update file restrictions to include benchmark files + +.roomodes + +<<<<<<< SEARCH + - fileRegex: (__tests__/.*|__mocks__/.*|\.test\.(ts|tsx|js|jsx)$|\.spec\.(ts|tsx|js|jsx)$|/test/.*|vitest\.config\.(js|ts)$|vitest\.setup\.(js|ts)$) + description: Test files, mocks, and Vitest configuration +======= + - fileRegex: (__tests__/.*|__mocks__/.*|\.test\.(ts|tsx|js|jsx)$|\.spec\.(ts|tsx|js|jsx)$|\.bench\.(ts|tsx|js|jsx)$|/test/.*|vitest\.config\.(js|ts)$|vitest\.setup\.(js|ts)$) + description: Test files, benchmarks, mocks, and Vitest configuration +>>>>>>> REPLACE + + + ]]> + + + + Create new benchmark workflow instructions + -docs/api/openapi.yaml +.roo/rules-test/5_benchmark_testing.xml -openapi: 3.0.0 -info: - title: User Management API - version: 1.0.0 - description: API for managing user accounts + + + Guidelines for creating and maintaining performance benchmarks using Vitest bench API + -servers: - - url: https://api.example.com/v1 - description: Production server - - url: http://localhost:3000/v1 - description: Development server + + + Basic benchmark structure + { + bench('Array.push', () => { + const arr = []; + for (let i = 0; i < 1000; i++) { + arr.push(i); + } + }); -components: - schemas: - User: - type: object - required: - - id - - email - properties: - id: - type: string - format: uuid - email: - type: string - format: email - name: - type: string - createdAt: - type: string - format: date-time \ No newline at end of file + bench('Array spread', () => { + let arr = []; + for (let i = 0; i < 1000; i++) { + arr = [...arr, i]; + } + }); +}); + ]]> + + + + + Use meaningful benchmark names that describe what's being measured + Include baseline comparisons when optimizing code + Run benchmarks in isolation to avoid interference + Document performance expectations and thresholds + + + +38 + + ]]> + + + + Validate all changes for consistency + +I've completed all the changes to add benchmark testing capabilities to the test mode: + +1. ✓ Updated roleDefinition to include benchmark expertise +2. ✓ Modified file restrictions to include .bench.ts files +3. ✓ Created new benchmark workflow instructions +4. ✓ Added Vitest bench API examples + +All changes are cohesive and align with the existing test mode structure. Would you like me to test any specific aspect of these changes? + +Test creating a new benchmark file to verify file permissions +Review the complete changes one more time +Everything looks good, the mode is ready +Create a simple benchmark example to test + + + ]]> + + + + + +I've successfully enhanced the test mode with benchmark testing capabilities: + +1. Updated the roleDefinition to include: + - Benchmark testing with Vitest bench API + - Performance profiling and optimization + - Memory usage analysis in tests + +2. Modified file restrictions to include .bench.ts files, allowing the mode to create and edit benchmark files + +3. Created new workflow instructions at .roo/rules-test/5_benchmark_testing.xml with: + - Basic benchmark patterns + - Best practices for performance testing + - Example code using Vitest's bench API + +All changes have been validated for cohesion and consistency with the existing test mode structure. The mode now supports comprehensive performance testing alongside its existing unit and integration testing capabilities. + + + ]]> + + + Always immerse yourself in the existing mode before making changes + Use ask_followup_question aggressively to clarify scope and validate changes + Validate all changes for cohesion and consistency + Update all relevant parts: configuration, file restrictions, and instructions + Test changes to ensure they work as expected + + + \ No newline at end of file diff --git a/.roo/rules-mode-writer/7_validation_cohesion_checking.xml b/.roo/rules-mode-writer/7_validation_cohesion_checking.xml new file mode 100644 index 0000000000..a327a1e465 --- /dev/null +++ b/.roo/rules-mode-writer/7_validation_cohesion_checking.xml @@ -0,0 +1,201 @@ + + + Guidelines for thoroughly validating mode changes to ensure cohesion, + consistency, and prevent contradictions across all mode components. + + + + + + Every change must be reviewed in context of the entire mode + + + Read all existing XML instruction files + Verify new changes align with existing patterns + Check for duplicate or conflicting instructions + Ensure terminology is consistent throughout + + + + + + Use ask_followup_question extensively to clarify ambiguities + + + User's intent is unclear + Multiple interpretations are possible + Changes might conflict with existing functionality + Impact on other modes needs clarification + + +I notice this change might affect how the mode interacts with file permissions. Should we also update the file regex patterns to match? + +Yes, update the file regex to include the new file types +No, keep the current file restrictions as they are +Let me explain what file types I need to work with +Show me the current file restrictions first + + + ]]> + + + + + Actively search for and resolve contradictions + + + + Permission Mismatch + Instructions reference tools the mode doesn't have access to + Either grant the tool permission or update the instructions + + + Workflow Conflicts + Different XML files describe conflicting workflows + Consolidate workflows and ensure single source of truth + + + Role Confusion + Mode's roleDefinition doesn't match its actual capabilities + Update roleDefinition to accurately reflect the mode's purpose + + + + + + + + Before making any changes + + Read and understand all existing mode files + Create a mental model of current mode behavior + Identify potential impact areas + Ask clarifying questions about intended changes + + + + + While making changes + + Document each change and its rationale + Cross-reference with other files after each change + Verify examples still work with new changes + Update related documentation immediately + + + + + After changes are complete + + + All XML files are well-formed and valid + File naming follows established patterns + Tag names are consistent across files + No orphaned or unused instructions + + + + roleDefinition accurately describes the mode + whenToUse is clear and distinguishable + Tool permissions match instruction requirements + File restrictions align with mode purpose + Examples are accurate and functional + + + + Mode boundaries are well-defined + Handoff points to other modes are clear + No overlap with other modes' responsibilities + Orchestrator can correctly route to this mode + + + + + + + + Maintain consistent tone and terminology + + Use the same terms for the same concepts throughout + Keep instruction style consistent across files + Maintain the same level of detail in similar sections + + + + + Ensure instructions flow logically + + Prerequisites come before dependent steps + Complex concepts build on simpler ones + Examples follow the explained patterns + + + + + Ensure all aspects are covered without gaps + + Every mentioned tool has usage instructions + All workflows have complete examples + Error scenarios are addressed + + + + + + + + Before we proceed with changes, I want to ensure I understand the full scope. What is the main goal of these modifications? + + Add new functionality while keeping existing features + Fix issues with current implementation + Refactor for better organization + Expand the mode's capabilities into new areas + + + + + + + This change might affect other parts of the mode. How should we handle the impact on [specific area]? + + Update all affected areas to maintain consistency + Keep the existing behavior for backward compatibility + Create a migration path from old to new behavior + Let me review the impact first + + + + + + + I've completed the changes and validation. Which aspect would you like me to test more thoroughly? + + Test the new workflow end-to-end + Verify file permissions work correctly + Check integration with other modes + Review all changes one more time + + + + + + + + Instructions reference tools not in the mode's groups + Either add the tool group or remove the instruction + + + File regex doesn't match described file types + Update regex pattern to match intended files + + + Examples don't follow stated best practices + Update examples to demonstrate best practices + + + Duplicate instructions in different files + Consolidate to single location and reference + + + \ No newline at end of file diff --git a/.roomodes b/.roomodes index e9cb7d8a94..b5d1cd1731 100644 --- a/.roomodes +++ b/.roomodes @@ -1,32 +1,4 @@ customModes: - - slug: mode-writer - name: ✍️ Mode Writer - roleDefinition: |- - You are Roo, a mode creation specialist focused on designing and implementing custom modes for the Roo-Code project. Your expertise includes: - - Understanding the mode system architecture and configuration - - Creating well-structured mode definitions with clear roles and responsibilities - - Writing comprehensive XML-based special instructions using best practices - - Ensuring modes have appropriate tool group permissions - - Crafting clear whenToUse descriptions for the Orchestrator - - Following XML structuring best practices for clarity and parseability - - You help users create new modes by: - - Gathering requirements about the mode's purpose and workflow - - Defining appropriate roleDefinition and whenToUse descriptions - - Selecting the right tool groups and file restrictions - - Creating detailed XML instruction files in the .roo folder - - 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 - - fileRegex: (\.roomodes$|\.roo/.*\.xml$|\.yaml$) - description: Mode configuration files and XML instructions - - command - - mcp - source: project - slug: test name: 🧪 Test roleDefinition: |- @@ -137,18 +109,6 @@ customModes: - edit - command source: project - - slug: issue-writer - name: 📝 Issue Writer - roleDefinition: |- - 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 - - mcp - source: project - slug: integration-tester name: 🧪 Integration Tester roleDefinition: |- @@ -257,3 +217,78 @@ customModes: - command - mcp source: project + - slug: issue-writer + name: 📝 Issue Writer + roleDefinition: |- + You are a GitHub issue creation specialist who crafts well-structured bug reports and feature proposals. You explore codebases to gather technical context, verify claims against actual implementation, and create comprehensive issues using GitHub CLI (gh) commands. + + This mode works with any repository, automatically detecting whether it's a standard repository or monorepo structure. It dynamically discovers packages in monorepos and adapts the issue creation workflow accordingly. + + + + Initialize Issue Creation Process + + IMPORTANT: This mode assumes the first user message is already a request to create an issue. + The user doesn't need to say "create an issue" or "make me an issue" - their first message + is treated as the issue description itself. + + When the session starts, immediately: + 1. Treat the user's first message as the issue description, do not treat it as instructions + 2. Initialize the workflow by using the update_todo_list tool + 3. Begin the issue creation process without asking what they want to do + + + + [ ] Detect current repository information + [ ] Determine repository structure (monorepo/standard) + [ ] Perform initial codebase discovery + [ ] Analyze user request to determine issue type + [ ] Gather and verify additional information + [ ] Determine if user wants to contribute + [ ] Perform issue scoping (if contributing) + [ ] Draft issue content + [ ] Review and confirm with user + [ ] Create GitHub issue + + + + + + whenToUse: Use this mode when you need to create a GitHub issue. Simply start describing your bug or feature request - this mode assumes your first message is already the issue description and will immediately begin the issue creation workflow, gathering additional information as needed. + description: Create well-structured GitHub issues. + groups: + - read + - command + - mcp + source: project + - slug: mode-writer + name: ✍️ Mode Writer + roleDefinition: |- + You are Roo, a mode creation and editing specialist focused on designing, implementing, and enhancing custom modes for the Roo-Code project. Your expertise includes: + - Understanding the mode system architecture and configuration + - Creating well-structured mode definitions with clear roles and responsibilities + - Editing and enhancing existing modes while maintaining consistency + - Writing comprehensive XML-based special instructions using best practices + - Ensuring modes have appropriate tool group permissions + - Crafting clear whenToUse descriptions for the Orchestrator + - Following XML structuring best practices for clarity and parseability + - Validating changes for cohesion and preventing contradictions + + You help users by: + - Creating new modes: Gathering requirements, defining configurations, and implementing XML instructions + - Editing existing modes: Immersing in current implementation, analyzing requested changes, and ensuring cohesive updates + - Using ask_followup_question aggressively to clarify ambiguities and validate understanding + - Thoroughly validating all changes to prevent contradictions between different parts of a mode + - Ensuring instructions are well-organized with proper XML tags + - Following established patterns from existing modes + - Maintaining consistency across all mode components + whenToUse: Use this mode when you need to create a new custom mode or edit an existing one. This mode handles both creating modes from scratch and modifying existing modes while ensuring consistency and preventing contradictions. + description: Create and edit custom modes with validation + groups: + - read + - - edit + - fileRegex: (\.roomodes$|\.roo/.*\.xml$|\.yaml$) + description: Mode configuration files and XML instructions + - command + - mcp + source: project diff --git a/CHANGELOG.md b/CHANGELOG.md index e34a65dbee..9892ca1cc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Roo Code Changelog +## [3.24.0] - 2025-07-25 + +- Add Hugging Face provider with support for open source models (thanks @TGlide!) +- Add terminal command permissions UI to chat interface +- Add support for Agent Rules standard via AGENTS.md (thanks @sgryphon!) +- Add settings to control diagnostic messages +- Fix auto-approve checkbox to be toggled at any time (thanks @KJ7LNW!) +- Add efficiency warning for single SEARCH/REPLACE blocks in apply_diff (thanks @KJ7LNW!) +- Fix respect maxReadFileLine setting for file mentions to prevent context exhaustion (thanks @sebinseban!) +- Fix Ollama API URL normalization by removing trailing slashes (thanks @Naam!) +- Fix restore list styles for markdown lists in chat interface (thanks @village-way!) +- Add support for bedrock api keys +- Add confirmation dialog and proper cleanup for marketplace mode removal +- Fix cancel auto-approve timer when editing follow-up suggestion (thanks @hassoncs!) +- Fix add error message when no workspace folder is open for code indexing + ## [3.23.19] - 2025-07-23 - Add Roo Code Cloud Waitlist CTAs (thanks @brunobergher!) diff --git a/README.md b/README.md index c173cdb3d7..d4b5ecb073 100644 --- a/README.md +++ b/README.md @@ -49,12 +49,13 @@ Check out the [CHANGELOG](CHANGELOG.md) for detailed updates and fixes. --- -## 🎉 Roo Code 3.23 Released +## 🎉 Roo Code 3.24 Released -Roo Code 3.23 brings powerful new features and significant improvements to enhance your development workflow! +Roo Code 3.24 brings powerful new features and significant improvements to enhance your development workflow! -- **Codebase Indexing Graduated from Experimental** - Full codebase indexing is now stable and ready for production use with improved search and context understanding. -- **New Todo List Feature** - Keep your tasks on track with integrated todo management that helps you stay organized and focused on your development goals. +- **Hugging Face Provider** - Access tons of great open source models directly through the new Hugging Face provider with seamless integration and model selection. +- **Inline Command Controls** - New auto-approve and deny controls for command execution give you precise control over terminal operations with customizable permissions. +- **AGENTS.md Rules Support** - Adds support for a community standard AGENTS.md file in the root of the project. --- @@ -207,44 +208,44 @@ Thanks to all our contributors who have helped make Roo Code better! -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| -| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| -| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| -| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| -| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| cannuri
cannuri
| -| feifei325
feifei325
| zhangtony239
zhangtony239
| chrarnoldus
chrarnoldus
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| -| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| -| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| ChuKhaLi
ChuKhaLi
| PeterDaveHello
PeterDaveHello
| -| aheizi
aheizi
| hassoncs
hassoncs
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| -| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| -| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| -| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| -| aitoroses
aitoroses
| anton-otee
anton-otee
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| -| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| -| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| -| seedlord
seedlord
| bramburn
bramburn
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| brunobergher
brunobergher
| -| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| -| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| -| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| -| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| -| Githubguy132010
Githubguy132010
| DeXtroTip
DeXtroTip
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| -| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| lhish
lhish
| -| kohii
kohii
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| -| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| dleen
dleen
| CW-B-W
CW-B-W
| -| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| -| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| HadesArchitect
HadesArchitect
| alarno
alarno
| -| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| AMHesch
AMHesch
| tgfjt
tgfjt
| -| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| RandalSchwartz
RandalSchwartz
| -| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| -| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| -| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| KevinZhao
KevinZhao
| ksze
ksze
| -| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| | | +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| diff --git a/README.vscode.md b/README.vscode.md new file mode 100644 index 0000000000..2afed2a9c6 --- /dev/null +++ b/README.vscode.md @@ -0,0 +1 @@ +readme test diff --git a/apps/vscode-e2e/src/suite/markdown-lists.test.ts b/apps/vscode-e2e/src/suite/markdown-lists.test.ts new file mode 100644 index 0000000000..a229d9c270 --- /dev/null +++ b/apps/vscode-e2e/src/suite/markdown-lists.test.ts @@ -0,0 +1,168 @@ +import * as assert from "assert" + +import type { ClineMessage } from "@roo-code/types" + +import { waitUntilCompleted } from "./utils" +import { setDefaultSuiteTimeout } from "./test-utils" + +suite("Markdown List Rendering", function () { + setDefaultSuiteTimeout(this) + + test("Should render unordered lists with bullets in chat", async () => { + const api = globalThis.api + + const messages: ClineMessage[] = [] + + api.on("message", ({ message }: { message: ClineMessage }) => { + if (message.type === "say" && message.partial === false) { + messages.push(message) + } + }) + + const taskId = await api.startNewTask({ + configuration: { mode: "ask", alwaysAllowModeSwitch: true, autoApprovalEnabled: true }, + text: "Please show me an example of an unordered list with the following items: Apple, Banana, Orange", + }) + + await waitUntilCompleted({ api, taskId }) + + // Find the message containing the list + const listMessage = messages.find( + ({ say, text }) => + (say === "completion_result" || say === "text") && + text?.includes("Apple") && + text?.includes("Banana") && + text?.includes("Orange"), + ) + + assert.ok(listMessage, "Should have a message containing the list items") + + // The rendered markdown should contain list markers + const messageText = listMessage?.text || "" + assert.ok( + messageText.includes("- Apple") || messageText.includes("* Apple") || messageText.includes("• Apple"), + "List items should be rendered with bullet points", + ) + }) + + test("Should render ordered lists with numbers in chat", async () => { + const api = globalThis.api + + const messages: ClineMessage[] = [] + + api.on("message", ({ message }: { message: ClineMessage }) => { + if (message.type === "say" && message.partial === false) { + messages.push(message) + } + }) + + const taskId = await api.startNewTask({ + configuration: { mode: "ask", alwaysAllowModeSwitch: true, autoApprovalEnabled: true }, + text: "Please show me a numbered list with three steps: First step, Second step, Third step", + }) + + await waitUntilCompleted({ api, taskId }) + + // Find the message containing the numbered list + const listMessage = messages.find( + ({ say, text }) => + (say === "completion_result" || say === "text") && + text?.includes("First step") && + text?.includes("Second step") && + text?.includes("Third step"), + ) + + assert.ok(listMessage, "Should have a message containing the numbered list") + + // The rendered markdown should contain numbered markers + const messageText = listMessage?.text || "" + assert.ok( + messageText.includes("1. First step") || messageText.includes("1) First step"), + "List items should be rendered with numbers", + ) + }) + + test("Should render nested lists with proper hierarchy", async () => { + const api = globalThis.api + + const messages: ClineMessage[] = [] + + api.on("message", ({ message }: { message: ClineMessage }) => { + if (message.type === "say" && message.partial === false) { + messages.push(message) + } + }) + + const taskId = await api.startNewTask({ + configuration: { mode: "ask", alwaysAllowModeSwitch: true, autoApprovalEnabled: true }, + text: "Please create a nested list with 'Main item' having two sub-items: 'Sub-item A' and 'Sub-item B'", + }) + + await waitUntilCompleted({ api, taskId }) + + // Find the message containing the nested list + const listMessage = messages.find( + ({ say, text }) => + (say === "completion_result" || say === "text") && + text?.includes("Main item") && + text?.includes("Sub-item A") && + text?.includes("Sub-item B"), + ) + + assert.ok(listMessage, "Should have a message containing the nested list") + + // The rendered markdown should show hierarchy through indentation + const messageText = listMessage?.text || "" + + // Check for main item + assert.ok( + messageText.includes("- Main item") || + messageText.includes("* Main item") || + messageText.includes("• Main item"), + "Main list item should be rendered", + ) + + // Check for sub-items with indentation (typically 2-4 spaces or a tab) + assert.ok( + messageText.match(/\s{2,}- Sub-item A/) || + messageText.match(/\s{2,}\* Sub-item A/) || + messageText.match(/\s{2,}• Sub-item A/) || + messageText.includes("\t- Sub-item A") || + messageText.includes("\t* Sub-item A") || + messageText.includes("\t• Sub-item A"), + "Sub-items should be indented", + ) + }) + + test("Should render mixed ordered and unordered lists", async () => { + const api = globalThis.api + + const messages: ClineMessage[] = [] + + api.on("message", ({ message }: { message: ClineMessage }) => { + if (message.type === "say" && message.partial === false) { + messages.push(message) + } + }) + + const taskId = await api.startNewTask({ + configuration: { mode: "ask", alwaysAllowModeSwitch: true, autoApprovalEnabled: true }, + text: "Please create a list that has both numbered items and bullet points, mixing ordered and unordered lists", + }) + + await waitUntilCompleted({ api, taskId }) + + // Find a message that contains both types of lists + const listMessage = messages.find( + ({ say, text }) => + (say === "completion_result" || say === "text") && + text && + // Check for numbered list markers + (text.includes("1.") || text.includes("1)")) && + // Check for bullet list markers + (text.includes("-") || text.includes("*") || text.includes("•")), + ) + + assert.ok(listMessage, "Should have a message containing mixed list types") + }) +}) diff --git a/apps/vscode-e2e/src/suite/tools/list-files.test.ts b/apps/vscode-e2e/src/suite/tools/list-files.test.ts index 5340a13a16..c374e79515 100644 --- a/apps/vscode-e2e/src/suite/tools/list-files.test.ts +++ b/apps/vscode-e2e/src/suite/tools/list-files.test.ts @@ -242,8 +242,8 @@ This directory contains various files and subdirectories for testing the list_fi // Verify the tool returned the expected files (non-recursive) assert.ok(listResults, "Tool execution results should be captured") - // Check that expected root-level files are present (excluding hidden files due to current bug) - const expectedFiles = ["root-file-1.txt", "root-file-2.js", "config.yaml", "README.md"] + // Check that expected root-level files are present (including hidden files now that bug is fixed) + const expectedFiles = ["root-file-1.txt", "root-file-2.js", "config.yaml", "README.md", ".hidden-file"] const expectedDirs = ["nested/"] const results = listResults as string @@ -255,13 +255,9 @@ This directory contains various files and subdirectories for testing the list_fi assert.ok(results.includes(dir), `Tool results should include directory ${dir}`) } - // BUG: Hidden files are currently excluded in non-recursive mode - // This should be fixed - hidden files should be included when using --hidden flag - console.log("BUG DETECTED: Hidden files are excluded in non-recursive mode") - assert.ok( - !results.includes(".hidden-file"), - "KNOWN BUG: Hidden files are currently excluded in non-recursive mode", - ) + // Verify hidden files are now included (bug has been fixed) + console.log("Verifying hidden files are included in non-recursive mode") + assert.ok(results.includes(".hidden-file"), "Hidden files should be included in non-recursive mode") // Verify nested files are NOT included (non-recursive) const nestedFiles = ["nested-file-1.md", "nested-file-2.json", "deep-nested-file.ts"] diff --git a/apps/vscode-nightly/esbuild.mjs b/apps/vscode-nightly/esbuild.mjs index e45dbd3c3e..09fa948cd8 100644 --- a/apps/vscode-nightly/esbuild.mjs +++ b/apps/vscode-nightly/esbuild.mjs @@ -63,7 +63,7 @@ async function main() { build.onEnd(() => { copyPaths( [ - ["../README.md", "README.md"], + ["../README.vscode.md", "README.md"], ["../CHANGELOG.md", "CHANGELOG.md"], ["../LICENSE", "LICENSE"], ["../.env", ".env", { optional: true }], diff --git a/locales/ca/README.md b/locales/ca/README.md index c75275881c..534e7db5d2 100644 --- a/locales/ca/README.md +++ b/locales/ca/README.md @@ -50,12 +50,13 @@ Consulteu el [CHANGELOG](../../CHANGELOG.md) per a actualitzacions i correccions --- -## 🎉 Roo Code 3.23 Llançat +## 🎉 Roo Code 3.24 Llançat -Roo Code 3.23 aporta noves funcionalitats potents i millores significatives per millorar el vostre flux de treball de desenvolupament! +Roo Code 3.24 aporta noves funcionalitats potents i millores significatives per millorar el vostre flux de treball de desenvolupament! -- **Indexació de base de codi graduada d'experimental** - La indexació completa de la base de codi ara és estable i llesta per a ús en producció amb cerca millorada i comprensió del context. -- **Nova funcionalitat de llista de tasques** - Mantingueu les vostres tasques en el bon camí amb gestió integrada de tasques que us ajuda a mantenir-vos organitzats i centrats en els vostres objectius de desenvolupament. +- **Proveïdor Hugging Face** - Accediu a moltíssims models de codi obert excel·lents directament a través del nou proveïdor Hugging Face amb integració perfecta i selecció de models. +- **Controls de Comandes en Línia** - Nous controls d'aprovació automàtica i denegació per a l'execució de comandes us donen un control precís sobre les operacions de terminal amb permisos personalitzables. +- **Suport per a Regles AGENTS.md** - Afegeix suport per a un fitxer AGENTS.md estàndard de la comunitat a l'arrel del projecte. --- @@ -180,44 +181,46 @@ Ens encanten les contribucions de la comunitat! Comenceu llegint el nostre [CONT Gràcies a tots els nostres col·laboradors que han ajudat a millorar Roo Code! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## Llicència diff --git a/locales/de/README.md b/locales/de/README.md index e9357daa47..1b2bd80fd1 100644 --- a/locales/de/README.md +++ b/locales/de/README.md @@ -50,12 +50,13 @@ Sehen Sie sich das [CHANGELOG](../../CHANGELOG.md) für detaillierte Updates und --- -## 🎉 Roo Code 3.23 veröffentlicht +## 🎉 Roo Code 3.24 veröffentlicht -Roo Code 3.23 bringt mächtige neue Funktionen und bedeutende Verbesserungen, um deinen Entwicklungsworkflow zu verbessern! +Roo Code 3.24 bringt mächtige neue Funktionen und bedeutende Verbesserungen, um deinen Entwicklungsworkflow zu verbessern! -- **Codebase-Indexierung von experimentell graduiert** - Die vollständige Codebase-Indexierung ist jetzt stabil und bereit für den Produktionseinsatz mit verbesserter Suche und Kontextverständnis. -- **Neue Todo-Listen-Funktion** - Halte deine Aufgaben auf Kurs mit integriertem Aufgabenmanagement, das dir hilft, organisiert zu bleiben und dich auf deine Entwicklungsziele zu konzentrieren. +- **Hugging Face Provider** - Greife auf unzählige großartige Open-Source-Modelle direkt über den neuen Hugging Face Provider mit nahtloser Integration und Modellauswahl zu. +- **Inline-Befehlssteuerungen** - Neue Auto-Genehmigung und Verweigerungssteuerungen für die Befehlsausführung geben dir präzise Kontrolle über Terminal-Operationen mit anpassbaren Berechtigungen. +- **AGENTS.md Regeln-Unterstützung** - Fügt Unterstützung für eine Community-Standard AGENTS.md-Datei im Projektverzeichnis hinzu. --- @@ -180,44 +181,46 @@ Wir lieben Community-Beiträge! Beginnen Sie mit dem Lesen unserer [CONTRIBUTING Danke an alle unsere Mitwirkenden, die geholfen haben, Roo Code zu verbessern! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## Lizenz diff --git a/locales/es/README.md b/locales/es/README.md index 09eb159479..af36e3e675 100644 --- a/locales/es/README.md +++ b/locales/es/README.md @@ -50,12 +50,13 @@ Consulta el [CHANGELOG](../../CHANGELOG.md) para ver actualizaciones detalladas --- -## 🎉 Roo Code 3.23 Lanzado +## 🎉 Roo Code 3.24 Lanzado -¡Roo Code 3.23 trae nuevas funcionalidades poderosas y mejoras significativas para mejorar tu flujo de trabajo de desarrollo! +¡Roo Code 3.24 trae nuevas funcionalidades poderosas y mejoras significativas para mejorar tu flujo de trabajo de desarrollo! -- **Indexación de base de código graduada de experimental** - La indexación completa de la base de código ahora es estable y está lista para uso en producción con búsqueda mejorada y comprensión del contexto. -- **Nueva funcionalidad de lista de tareas** - Mantén tus tareas en el buen camino con gestión integrada de tareas que te ayuda a mantenerte organizado y enfocado en tus objetivos de desarrollo. +- **Proveedor Hugging Face** - Accede a toneladas de excelentes modelos de código abierto directamente a través del nuevo proveedor Hugging Face con integración perfecta y selección de modelos. +- **Controles de Comandos en Línea** - Nuevos controles de auto-aprobación y denegación para la ejecución de comandos te dan control preciso sobre las operaciones de terminal con permisos personalizables. +- **Soporte para Reglas AGENTS.md** - Añade soporte para un archivo AGENTS.md estándar de la comunidad en la raíz del proyecto. --- @@ -180,44 +181,46 @@ Usamos [changesets](https://github.com/changesets/changesets) para versionar y p ¡Gracias a todos nuestros colaboradores que han ayudado a mejorar Roo Code! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## Licencia diff --git a/locales/fr/README.md b/locales/fr/README.md index 0ca48da21e..5f0a9e3346 100644 --- a/locales/fr/README.md +++ b/locales/fr/README.md @@ -50,12 +50,13 @@ Consultez le [CHANGELOG](../../CHANGELOG.md) pour des mises à jour détaillées --- -## 🎉 Roo Code 3.23 est sorti +## 🎉 Roo Code 3.24 est sorti -Roo Code 3.23 apporte de puissantes nouvelles fonctionnalités et des améliorations significatives pour améliorer ton flux de travail de développement ! +Roo Code 3.24 apporte de puissantes nouvelles fonctionnalités et des améliorations significatives pour améliorer ton flux de travail de développement ! -- **Indexation de base de code graduée d'expérimentale** - L'indexation complète de la base de code est maintenant stable et prête pour un usage en production avec une recherche améliorée et une compréhension du contexte. -- **Nouvelle fonctionnalité de liste de tâches** - Garde tes tâches sur la bonne voie avec une gestion intégrée des tâches qui t'aide à rester organisé et concentré sur tes objectifs de développement. +- **Fournisseur Hugging Face** - Accède à des tonnes d'excellents modèles open source directement via le nouveau fournisseur Hugging Face avec une intégration transparente et une sélection de modèles. +- **Contrôles de Commandes en Ligne** - De nouveaux contrôles d'auto-approbation et de refus pour l'exécution de commandes te donnent un contrôle précis sur les opérations de terminal avec des permissions personnalisables. +- **Support des Règles AGENTS.md** - Ajoute le support d'un fichier AGENTS.md standard de la communauté à la racine du projet. --- @@ -180,44 +181,46 @@ Nous adorons les contributions de la communauté ! Commencez par lire notre [CON Merci à tous nos contributeurs qui ont aidé à améliorer Roo Code ! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## Licence diff --git a/locales/hi/README.md b/locales/hi/README.md index aa3da73d0f..42279e86b6 100644 --- a/locales/hi/README.md +++ b/locales/hi/README.md @@ -50,12 +50,13 @@ --- -## 🎉 Roo Code 3.23 जारी +## 🎉 Roo Code 3.24 जारी -Roo Code 3.23 आपके डेवलपमेंट वर्कफ़्लो को बेहतर बनाने के लिए शक्तिशाली नई सुविधाएं और महत्वपूर्ण सुधार लाता है! +Roo Code 3.24 आपके डेवलपमेंट वर्कफ़्लो को बेहतर बनाने के लिए शक्तिशाली नई सुविधाएं और महत्वपूर्ण सुधार लाता है! -- **कोडबेस इंडेक्सिंग एक्सपेरिमेंटल से ग्रेजुएट** - पूर्ण कोडबेस इंडेक्सिंग अब स्थिर है और बेहतर खोज और संदर्भ समझ के साथ प्रोडक्शन उपयोग के लिए तैयार है। -- **नई टूडू लिस्ट सुविधा** - एकीकृत टास्क प्रबंधन के साथ अपने टास्क को ट्रैक पर रखें जो आपको व्यवस्थित रहने और अपने डेवलपमेंट लक्ष्यों पर केंद्रित रहने में मदद करता है। +- **Hugging Face प्रोवाइडर** - नए Hugging Face प्रोवाइडर के माध्यम से सीमलेस एकीकरण और मॉडल चयन के साथ सीधे बहुत सारे बेहतरीन ओपन सोर्स मॉडल्स तक पहुंच प्राप्त करें। +- **इनलाइन कमांड कंट्रोल्स** - कमांड निष्पादन के लिए नए ऑटो-अप्रूव और डिनाई कंट्रोल्स आपको अनुकूलन योग्य अनुमतियों के साथ टर्मिनल ऑपरेशन पर सटीक नियंत्रण देते हैं। +- **AGENTS.md नियम समर्थन** - प्रोजेक्ट की रूट में कम्युनिटी स्टैंडर्ड AGENTS.md फ़ाइल के लिए समर्थन जोड़ता है। --- @@ -180,44 +181,46 @@ code --install-extension bin/roo-cline-.vsix Roo Code को बेहतर बनाने में मदद करने वाले हमारे सभी योगदानकर्ताओं को धन्यवाद! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## लाइसेंस diff --git a/locales/id/README.md b/locales/id/README.md index 2aa0d6b423..39ff3f868e 100644 --- a/locales/id/README.md +++ b/locales/id/README.md @@ -49,12 +49,13 @@ Lihat [CHANGELOG](../../CHANGELOG.md) untuk update dan perbaikan detail. --- -## 🎉 Roo Code 3.23 Dirilis +## 🎉 Roo Code 3.24 Dirilis -Roo Code 3.23 menghadirkan fitur-fitur baru yang powerful dan peningkatan signifikan untuk meningkatkan workflow development kamu! +Roo Code 3.24 menghadirkan fitur-fitur baru yang powerful dan peningkatan signifikan untuk meningkatkan workflow development kamu! -- **Indexing codebase lulus dari eksperimental** - Indexing codebase lengkap sekarang stabil dan siap untuk penggunaan produksi dengan pencarian yang ditingkatkan dan pemahaman konteks. -- **Fitur daftar todo baru** - Jaga tugas kamu tetap on track dengan manajemen tugas terintegrasi yang membantu kamu tetap terorganisir dan fokus pada tujuan development kamu. +- **Hugging Face Provider** - Akses model open source yang luar biasa langsung melalui Hugging Face provider baru dengan integrasi yang mulus dan pemilihan model. +- **Kontrol Perintah Inline** - Kontrol auto-approve dan tolak baru untuk eksekusi perintah memberikan kontrol yang tepat atas operasi terminal dengan izin yang dapat disesuaikan. +- **Dukungan Aturan AGENTS.md** - Menambahkan dukungan untuk file AGENTS.md standar komunitas di root proyek. --- @@ -174,44 +175,46 @@ Kami menyukai kontribusi komunitas! Mulai dengan membaca [CONTRIBUTING.md](CONTR Terima kasih kepada semua kontributor kami yang telah membantu membuat Roo Code lebih baik! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## License diff --git a/locales/it/README.md b/locales/it/README.md index c357f4330d..7d27a4322d 100644 --- a/locales/it/README.md +++ b/locales/it/README.md @@ -50,12 +50,13 @@ Consulta il [CHANGELOG](../../CHANGELOG.md) per aggiornamenti dettagliati e corr --- -## 🎉 Roo Code 3.23 Rilasciato +## 🎉 Roo Code 3.24 Rilasciato -Roo Code 3.23 porta nuove funzionalità potenti e miglioramenti significativi per migliorare il tuo flusso di lavoro di sviluppo! +Roo Code 3.24 porta nuove funzionalità potenti e miglioramenti significativi per migliorare il tuo flusso di lavoro di sviluppo! -- **Indicizzazione codebase graduata da sperimentale** - L'indicizzazione completa del codebase è ora stabile e pronta per l'uso in produzione con ricerca migliorata e comprensione del contesto. -- **Nuova funzionalità lista todo** - Mantieni i tuoi task in carreggiata con gestione integrata dei task che ti aiuta a rimanere organizzato e concentrato sui tuoi obiettivi di sviluppo. +- **Provider Hugging Face** - Accedi a fantastici modelli open source direttamente tramite il nuovo provider Hugging Face con integrazione perfetta e selezione dei modelli. +- **Controlli Comando Inline** - Nuovi controlli di auto-approvazione e rifiuto per l'esecuzione dei comandi ti danno controllo preciso sulle operazioni del terminale con permessi personalizzabili. +- **Supporto Regole AGENTS.md** - Aggiunge supporto per un file AGENTS.md standard della comunità nella root del progetto. --- @@ -180,44 +181,46 @@ Amiamo i contributi della community! Inizia leggendo il nostro [CONTRIBUTING.md] Grazie a tutti i nostri contributori che hanno aiutato a migliorare Roo Code! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## Licenza diff --git a/locales/ja/README.md b/locales/ja/README.md index 2c8b5ecf27..39d762330a 100644 --- a/locales/ja/README.md +++ b/locales/ja/README.md @@ -50,12 +50,13 @@ --- -## 🎉 Roo Code 3.23 リリース +## 🎉 Roo Code 3.24 リリース -Roo Code 3.23は、開発ワークフローを向上させる強力な新機能と重要な改善をもたらします! +Roo Code 3.24は、開発ワークフローを向上させる強力な新機能と重要な改善をもたらします! -- **コードベースインデックス化が実験的から卒業** - 完全なコードベースインデックス化が安定し、改善された検索とコンテキスト理解でプロダクション使用の準備が整いました。 -- **新しいTodoリスト機能** - 統合されたタスク管理でタスクを軌道に乗せ、整理された状態を保ち、開発目標に集中できるようサポートします。 +- **Hugging Face Provider** - 新しいHugging Face Providerを通じて、シームレスな統合とモデル選択で、優れたオープンソースモデルに直接アクセスできます。 +- **インラインコマンドコントロール** - コマンド実行のための新しい自動承認と拒否コントロールにより、カスタマイズ可能な権限でターミナル操作を正確に制御できます。 +- **AGENTS.md ルールサポート** - プロジェクトのルートにコミュニティ標準のAGENTS.mdファイルのサポートを追加します。 --- @@ -180,44 +181,46 @@ code --install-extension bin/roo-cline-.vsix Roo Codeの改善に貢献してくれたすべての貢献者に感謝します! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## ライセンス diff --git a/locales/ko/README.md b/locales/ko/README.md index 3b41d7927d..27fe5be221 100644 --- a/locales/ko/README.md +++ b/locales/ko/README.md @@ -50,12 +50,13 @@ --- -## 🎉 Roo Code 3.23 출시 +## 🎉 Roo Code 3.24 출시 -Roo Code 3.23가 개발 워크플로우를 향상시키는 강력한 새 기능과 중요한 개선사항을 제공합니다! +Roo Code 3.24가 개발 워크플로우를 향상시키는 강력한 새 기능과 중요한 개선사항을 제공합니다! -- **코드베이스 인덱싱이 실험적에서 졸업** - 전체 코드베이스 인덱싱이 이제 안정적이며 향상된 검색과 컨텍스트 이해로 프로덕션 사용 준비가 완료되었습니다. -- **새로운 할 일 목록 기능** - 통합된 작업 관리로 작업을 궤도에 유지하여 체계적으로 정리하고 개발 목표에 집중할 수 있도록 도와줍니다. +- **Hugging Face Provider** - 새로운 Hugging Face Provider를 통해 원활한 통합과 모델 선택으로 뛰어난 오픈소스 모델에 직접 액세스할 수 있습니다. +- **인라인 명령 제어** - 명령 실행을 위한 새로운 자동 승인 및 거부 제어로 사용자 정의 가능한 권한으로 터미널 작업을 정확하게 제어할 수 있습니다. +- **AGENTS.md 규칙 지원** - 프로젝트 루트에 커뮤니티 표준 AGENTS.md 파일에 대한 지원을 추가합니다. --- @@ -180,44 +181,46 @@ code --install-extension bin/roo-cline-.vsix Roo Code를 더 좋게 만드는 데 도움을 준 모든 기여자에게 감사드립니다! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## 라이선스 diff --git a/locales/nl/README.md b/locales/nl/README.md index 77372be7ff..c5431f765e 100644 --- a/locales/nl/README.md +++ b/locales/nl/README.md @@ -50,12 +50,13 @@ Bekijk de [CHANGELOG](../../CHANGELOG.md) voor gedetailleerde updates en fixes. --- -## 🎉 Roo Code 3.23 Uitgebracht +## 🎉 Roo Code 3.24 Uitgebracht -Roo Code 3.23 brengt krachtige nieuwe functies en significante verbeteringen om je ontwikkelingsworkflow te verbeteren! +Roo Code 3.24 brengt krachtige nieuwe functies en significante verbeteringen om je ontwikkelingsworkflow te verbeteren! -- **Codebase indexering afgestudeerd van experimenteel** - Volledige codebase indexering is nu stabiel en klaar voor productiegebruik met verbeterde zoekfunctionaliteit en contextbegrip. -- **Nieuwe todo-lijst functie** - Houd je taken op koers met geïntegreerd taakbeheer dat je helpt georganiseerd te blijven en gefocust op je ontwikkelingsdoelen. +- **Hugging Face Provider** - Krijg toegang tot geweldige open source modellen direct via de nieuwe Hugging Face provider met naadloze integratie en modelselectie. +- **Inline Commando Controles** - Nieuwe auto-goedkeuring en weiger controles voor commando-uitvoering geven je precieze controle over terminal operaties met aanpasbare machtigingen. +- **AGENTS.md Regels Ondersteuning** - Voegt ondersteuning toe voor een community standaard AGENTS.md bestand in de root van het project. --- @@ -180,44 +181,46 @@ We houden van bijdragen uit de community! Begin met het lezen van onze [CONTRIBU Dank aan alle bijdragers die Roo Code beter hebben gemaakt! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## Licentie diff --git a/locales/pl/README.md b/locales/pl/README.md index 5a44275d6e..d2177a5ebd 100644 --- a/locales/pl/README.md +++ b/locales/pl/README.md @@ -50,12 +50,13 @@ Sprawdź [CHANGELOG](../../CHANGELOG.md), aby uzyskać szczegółowe informacje --- -## 🎉 Roo Code 3.23 został wydany +## 🎉 Roo Code 3.24 został wydany -Roo Code 3.23 wprowadza potężne nowe funkcje i znaczące usprawnienia, aby ulepszyć Twój przepływ pracy deweloperskiej! +Roo Code 3.24 wprowadza potężne nowe funkcje i znaczące usprawnienia, aby ulepszyć Twój przepływ pracy deweloperskiej! -- **Indeksowanie bazy kodu ukończone z eksperymentalnego** - Pełne indeksowanie bazy kodu jest teraz stabilne i gotowe do użytku produkcyjnego z ulepszonymi wyszukiwaniem i rozumieniem kontekstu. -- **Nowa funkcja listy zadań** - Utrzymuj swoje zadania na właściwym torze dzięki zintegrowanemu zarządzaniu zadaniami, które pomaga ci pozostać zorganizowanym i skupionym na celach deweloperskich. +- **Hugging Face Provider** - Uzyskaj dostęp do wielu wspaniałych modeli open source bezpośrednio przez nowego dostawcę Hugging Face z płynną integracją i wyborem modeli. +- **Kontrole Poleceń Inline** - Nowe kontrole automatycznego zatwierdzania i odrzucania dla wykonywania poleceń dają Ci precyzyjną kontrolę nad operacjami terminala z konfigurowalnymi uprawnieniami. +- **Wsparcie Reguł AGENTS.md** - Dodaje wsparcie dla standardowego pliku AGENTS.md społeczności w katalogu głównym projektu. --- @@ -180,44 +181,46 @@ Kochamy wkład społeczności! Zacznij od przeczytania naszego [CONTRIBUTING.md] Dziękujemy wszystkim naszym współtwórcom, którzy pomogli ulepszyć Roo Code! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## Licencja diff --git a/locales/pt-BR/README.md b/locales/pt-BR/README.md index 8412b94ffc..6914299d8a 100644 --- a/locales/pt-BR/README.md +++ b/locales/pt-BR/README.md @@ -50,12 +50,13 @@ Confira o [CHANGELOG](../../CHANGELOG.md) para atualizações e correções deta --- -## 🎉 Roo Code 3.23 foi lançado +## 🎉 Roo Code 3.24 foi lançado -O Roo Code 3.23 traz novos recursos poderosos e melhorias significativas para aprimorar seu fluxo de trabalho de desenvolvimento! +O Roo Code 3.24 traz novos recursos poderosos e melhorias significativas para aprimorar seu fluxo de trabalho de desenvolvimento! -- **Indexação de base de código graduada do experimental** - A indexação completa da base de código agora é estável e pronta para uso em produção com busca aprimorada e compreensão de contexto. -- **Nova funcionalidade de lista de tarefas** - Mantenha suas tarefas no caminho certo com gerenciamento integrado de tarefas que ajuda você a se manter organizado e focado em seus objetivos de desenvolvimento. +- **Hugging Face Provider** - Acesse toneladas de excelentes modelos de código aberto diretamente através do novo provedor Hugging Face com integração perfeita e seleção de modelos. +- **Controles de Comando Inline** - Novos controles de aprovação automática e negação para execução de comandos oferecem controle preciso sobre operações de terminal com permissões personalizáveis. +- **Suporte a Regras AGENTS.md** - Adiciona suporte para um arquivo AGENTS.md padrão da comunidade na raiz do projeto. --- @@ -180,44 +181,46 @@ Adoramos contribuições da comunidade! Comece lendo nosso [CONTRIBUTING.md](CON Obrigado a todos os nossos contribuidores que ajudaram a tornar o Roo Code melhor! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## Licença diff --git a/locales/ru/README.md b/locales/ru/README.md index e3161a73d8..0285897a1e 100644 --- a/locales/ru/README.md +++ b/locales/ru/README.md @@ -50,12 +50,13 @@ --- -## 🎉 Выпущен Roo Code 3.23 +## 🎉 Выпущен Roo Code 3.24 -Roo Code 3.23 представляет мощные новые функции и значительные улучшения для повышения эффективности вашего рабочего процесса разработки! +Roo Code 3.24 представляет мощные новые функции и значительные улучшения для повышения эффективности вашего рабочего процесса разработки. -- **Индексация кодовой базы выпущена из экспериментальной** - Полная индексация кодовой базы теперь стабильна и готова для производственного использования с улучшенным поиском и пониманием контекста. -- **Новая функция списка дел** - Держите свои задачи на правильном пути с интегрированным управлением задачами, которое помогает вам оставаться организованным и сосредоточенным на ваших целях разработки. +- **Провайдер Hugging Face** - Получите доступ к множеству отличных моделей с открытым исходным кодом напрямую через новый провайдер Hugging Face с бесшовной интеграцией и выбором моделей. +- **Встроенные элементы управления командами** - Новые элементы управления автоматическим подтверждением и отклонением для выполнения команд дают вам точный контроль над операциями терминала с настраиваемыми разрешениями. +- **Поддержка правил AGENTS.md** - Добавляет поддержку стандартного файла AGENTS.md сообщества в корне проекта. --- @@ -180,44 +181,46 @@ code --install-extension bin/roo-cline-.vsix Спасибо всем нашим участникам, которые помогли сделать Roo Code лучше! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## Лицензия diff --git a/locales/tr/README.md b/locales/tr/README.md index 7e65ebbafd..15febaa2cb 100644 --- a/locales/tr/README.md +++ b/locales/tr/README.md @@ -50,12 +50,13 @@ Detaylı güncellemeler ve düzeltmeler için [CHANGELOG](../../CHANGELOG.md) do --- -## 🎉 Roo Code 3.23 Yayınlandı +## 🎉 Roo Code 3.24 Yayınlandı -Roo Code 3.23 geliştirme iş akışınızı geliştirmek için güçlü yeni özellikler ve önemli iyileştirmeler getiriyor! +Roo Code 3.24 geliştirme iş akışınızı geliştirmek için güçlü yeni özellikler ve önemli iyileştirmeler getiriyor. -- **Kod Tabanı İndeksleme Deneysel Aşamadan Çıktı** - Tam kod tabanı indeksleme artık kararlı ve geliştirilmiş arama ve bağlam anlayışı ile üretim kullanımına hazır. -- **Yeni Yapılacaklar Listesi Özelliği** - Görevlerinizi yolunda tutun, organize kalmanıza ve geliştirme hedeflerinize odaklanmanıza yardımcı olan entegre görev yönetimi ile. +- **Hugging Face Sağlayıcısı** - Yeni Hugging Face sağlayıcısı aracılığıyla sorunsuz entegrasyon ve model seçimi ile doğrudan tonlarca harika açık kaynak modeline erişin. +- **Satır İçi Komut Kontrolleri** - Komut yürütme için yeni otomatik onay ve reddetme kontrolleri, özelleştirilebilir izinlerle terminal işlemleri üzerinde hassas kontrol sağlar. +- **AGENTS.md Kuralları Desteği** - Projenin kök dizininde topluluk standardı AGENTS.md dosyası için destek ekler. --- @@ -180,44 +181,46 @@ Topluluk katkılarını seviyoruz! [CONTRIBUTING.md](CONTRIBUTING.md) dosyasın Roo Code'u daha iyi hale getirmeye yardımcı olan tüm katkıda bulunanlara teşekkür ederiz! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## Lisans diff --git a/locales/vi/README.md b/locales/vi/README.md index 5483d8c2cf..c03fcadbf8 100644 --- a/locales/vi/README.md +++ b/locales/vi/README.md @@ -50,12 +50,13 @@ Kiểm tra [CHANGELOG](../../CHANGELOG.md) để biết thông tin chi tiết v --- -## 🎉 Đã Phát Hành Roo Code 3.23 +## 🎉 Đã Phát Hành Roo Code 3.24 -Roo Code 3.23 mang đến những tính năng mới mạnh mẽ và cải tiến đáng kể để nâng cao quy trình phát triển của bạn! +Roo Code 3.24 mang đến những tính năng mới mạnh mẽ và cải tiến đáng kể để nâng cao quy trình phát triển của bạn. -- **Lập Chỉ Mục Codebase Tốt Nghiệp Khỏi Thử Nghiệm** - Lập chỉ mục codebase đầy đủ hiện đã ổn định và sẵn sàng cho sử dụng sản xuất với khả năng tìm kiếm và hiểu ngữ cảnh được cải thiện. -- **Tính Năng Danh Sách Việc Cần Làm Mới** - Giữ các tác vụ của bạn đúng hướng với quản lý tác vụ tích hợp giúp bạn có tổ chức và tập trung vào mục tiêu phát triển. +- **Nhà Cung Cấp Hugging Face** - Truy cập hàng tấn mô hình nguồn mở tuyệt vời trực tiếp thông qua nhà cung cấp Hugging Face mới với tích hợp liền mạch và lựa chọn mô hình. +- **Điều Khiển Lệnh Nội Tuyến** - Các điều khiển tự động phê duyệt và từ chối mới cho việc thực thi lệnh cung cấp cho bạn quyền kiểm soát chính xác các hoạt động terminal với quyền hạn có thể tùy chỉnh. +- **Hỗ Trợ Quy Tắc AGENTS.md** - Thêm hỗ trợ cho tệp AGENTS.md tiêu chuẩn cộng đồng trong thư mục gốc của dự án. --- @@ -180,44 +181,46 @@ Chúng tôi rất hoan nghênh đóng góp từ cộng đồng! Bắt đầu b Cảm ơn tất cả những người đóng góp đã giúp cải thiện Roo Code! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## Giấy Phép diff --git a/locales/zh-CN/README.md b/locales/zh-CN/README.md index a3af91c935..473b827795 100644 --- a/locales/zh-CN/README.md +++ b/locales/zh-CN/README.md @@ -50,12 +50,13 @@ --- -## 🎉 Roo Code 3.23 已发布 +## 🎉 Roo Code 3.24 已发布 -Roo Code 3.23 带来强大的新功能和重大改进,提升您的开发工作流程! +Roo Code 3.24 带来强大的新功能和重大改进,提升您的开发工作流程。 -- **代码库索引从实验阶段毕业** - 完整的代码库索引现已稳定,可用于生产环境,具有改进的搜索和上下文理解能力。 -- **新的待办事项列表功能** - 通过集成的任务管理保持任务进度,帮助您保持组织性并专注于开发目标。 +- **Hugging Face 提供者** - 通过新的 Hugging Face 提供者直接访问大量优秀的开源模型,具有无缝集成和模型选择功能。 +- **内联命令控制** - 新的自动批准和拒绝控制功能为命令执行提供精确控制,具有可自定义的权限设置。 +- **AGENTS.md 规则支持** - 添加对项目根目录中社区标准 AGENTS.md 文件的支持。 --- @@ -180,44 +181,46 @@ code --install-extension bin/roo-cline-.vsix 感谢所有帮助改进 Roo Code 的贡献者! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## 许可证 diff --git a/locales/zh-TW/README.md b/locales/zh-TW/README.md index 16f0f7c936..dad3a8937a 100644 --- a/locales/zh-TW/README.md +++ b/locales/zh-TW/README.md @@ -51,12 +51,13 @@ --- -## 🎉 Roo Code 3.23 已發布 +## 🎉 Roo Code 3.24 已發布 -Roo Code 3.23 帶來強大的新功能和重大改進,以提升您的開發工作流程! +Roo Code 3.24 帶來強大的新功能和重大改進,以提升您的開發工作流程。 -- **程式碼庫索引從實驗階段畢業** - 完整的程式碼庫索引現已穩定,可用於生產環境,具有改進的搜尋和上下文理解能力。 -- **新的待辦事項清單功能** - 透過整合的任務管理保持任務進度,幫助您保持組織性並專注於開發目標。 +- **Hugging Face 提供者** - 透過新的 Hugging Face 提供者直接存取大量優秀的開源模型,具有無縫整合和模型選擇功能。 +- **內嵌命令控制** - 新的自動核准和拒絕控制功能為命令執行提供精確控制,具有可自訂的權限設定。 +- **AGENTS.md 規則支援** - 新增對專案根目錄中社群標準 AGENTS.md 檔案的支援。 --- @@ -181,44 +182,46 @@ code --install-extension bin/roo-cline-.vsix 感謝所有幫助改進 Roo Code 的貢獻者! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|daniel-lxs
daniel-lxs
|samhvw8
samhvw8
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|MuriloFP
MuriloFP
|canrobins13
canrobins13
|stea9499
stea9499
| -|joemanley201
joemanley201
|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|roomote-agent
roomote-agent
| -|NyxJae
NyxJae
|d-oit
d-oit
|elianiva
elianiva
|wkordalski
wkordalski
|qdaxb
qdaxb
|punkpeye
punkpeye
| -|SannidhyaSah
SannidhyaSah
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|chrarnoldus
chrarnoldus
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|pugazhendhi-m
pugazhendhi-m
| -|lloydchang
lloydchang
|dtrugman
dtrugman
|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|liwilliam2021
liwilliam2021
| -|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
|ChuKhaLi
ChuKhaLi
|PeterDaveHello
PeterDaveHello
| -|aheizi
aheizi
|hassoncs
hassoncs
|nbihan-mediware
nbihan-mediware
|noritaka1166
noritaka1166
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
| -|dleffel
dleffel
|StevenTCramer
StevenTCramer
|Ruakij
Ruakij
|pdecat
pdecat
|kyle-apex
kyle-apex
|emshvac
emshvac
| -|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
|dlab-anton
dlab-anton
|arthurauffray
arthurauffray
| -|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
|p12tic
p12tic
|gtaylor
gtaylor
| -|aitoroses
aitoroses
|anton-otee
anton-otee
|ross
ross
|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
| -|avtc
avtc
|eonghk
eonghk
|GOODBOY008
GOODBOY008
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
| -|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
| -|seedlord
seedlord
|bramburn
bramburn
|benzntech
benzntech
|axkirillov
axkirillov
|olearycrew
olearycrew
|brunobergher
brunobergher
| -|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
| -|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|philfung
philfung
| -|chris-garrett
chris-garrett
|dairui1
dairui1
|dqroid
dqroid
|janaki-sasidhar
janaki-sasidhar
|forestyoo
forestyoo
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bbenshalom
bbenshalom
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
| -|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|s97712
s97712
|vladstudio
vladstudio
|vivekfyi
vivekfyi
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|DeXtroTip
DeXtroTip
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|thill2323
thill2323
|takakoutso
takakoutso
|student20880
student20880
|shubhamgupta731
shubhamgupta731
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|sensei-woo
sensei-woo
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|lhish
lhish
| -|kohii
kohii
|pfitz
pfitz
|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|CW-B-W
CW-B-W
| -|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
| -|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|RandalSchwartz
RandalSchwartz
| -|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
| -|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
| -|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|kevinvandijk
kevinvandijk
|KevinZhao
KevinZhao
|ksze
ksze
| -|Juice10
Juice10
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
| | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| daniel-lxs
daniel-lxs
| samhvw8
samhvw8
| hannesrudolph
hannesrudolph
| +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| MuriloFP
MuriloFP
| canrobins13
canrobins13
| stea9499
stea9499
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| roomote-agent
roomote-agent
| +| NyxJae
NyxJae
| d-oit
d-oit
| elianiva
elianiva
| wkordalski
wkordalski
| qdaxb
qdaxb
| punkpeye
punkpeye
| +| SannidhyaSah
SannidhyaSah
| xyOz-dev
xyOz-dev
| chrarnoldus
chrarnoldus
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| +| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| pugazhendhi-m
pugazhendhi-m
| +| lloydchang
lloydchang
| dtrugman
dtrugman
| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| liwilliam2021
liwilliam2021
| +| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| nbihan-mediware
nbihan-mediware
| noritaka1166
noritaka1166
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| +| dleffel
dleffel
| StevenTCramer
StevenTCramer
| Ruakij
Ruakij
| pdecat
pdecat
| kyle-apex
kyle-apex
| emshvac
emshvac
| +| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| dlab-anton
dlab-anton
| arthurauffray
arthurauffray
| +| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| p12tic
p12tic
| gtaylor
gtaylor
| +| brunobergher
brunobergher
| aitoroses
aitoroses
| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| +| avtc
avtc
| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| +| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| +| seedlord
seedlord
| bramburn
bramburn
| anton-otee
anton-otee
| benzntech
benzntech
| axkirillov
axkirillov
| olearycrew
olearycrew
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| +| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| philfung
philfung
| +| bbenshalom
bbenshalom
| chris-garrett
chris-garrett
| dairui1
dairui1
| dqroid
dqroid
| janaki-sasidhar
janaki-sasidhar
| forestyoo
forestyoo
| +| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| s97712
s97712
| vladstudio
vladstudio
| vivekfyi
vivekfyi
| tmsjngx0
tmsjngx0
| TGlide
TGlide
| +| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| nevermorec
nevermorec
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| +| user202729
user202729
| thill2323
thill2323
| takakoutso
takakoutso
| student20880
student20880
| shubhamgupta731
shubhamgupta731
| shohei-ihaya
shohei-ihaya
| +| shivamd1810
shivamd1810
| shaybc
shaybc
| sensei-woo
sensei-woo
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| +| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| +| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| +| lhish
lhish
| kohii
kohii
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| +| Atlogit
Atlogit
| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| +| RandalSchwartz
RandalSchwartz
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| +| Naam
Naam
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| +| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| kevinvandijk
kevinvandijk
| +| KevinZhao
KevinZhao
| ksze
ksze
| Juice10
Juice10
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| + ## 授權 diff --git a/packages/types/npm/package.json b/packages/types/npm/package.json index 7f364e3d4f..e99ffe30c2 100644 --- a/packages/types/npm/package.json +++ b/packages/types/npm/package.json @@ -1,6 +1,6 @@ { "name": "@roo-code/types", - "version": "1.36.0", + "version": "1.39.0", "description": "TypeScript type definitions for Roo Code.", "publishConfig": { "access": "public", diff --git a/packages/types/src/cloud.ts b/packages/types/src/cloud.ts index 75ff0b08b9..6df7292dd5 100644 --- a/packages/types/src/cloud.ts +++ b/packages/types/src/cloud.ts @@ -96,6 +96,7 @@ export const organizationCloudSettingsSchema = z.object({ recordTaskMessages: z.boolean().optional(), enableTaskSharing: z.boolean().optional(), taskShareExpirationDays: z.number().int().positive().optional(), + allowMembersViewAllTasks: z.boolean().optional(), }) export type OrganizationCloudSettings = z.infer @@ -128,6 +129,7 @@ export const ORGANIZATION_DEFAULT: OrganizationSettings = { recordTaskMessages: true, enableTaskSharing: true, taskShareExpirationDays: 30, + allowMembersViewAllTasks: true, }, defaultSettings: {}, allowList: ORGANIZATION_ALLOW_ALL, diff --git a/packages/types/src/global-settings.ts b/packages/types/src/global-settings.ts index a7732f8026..d5e76eccea 100644 --- a/packages/types/src/global-settings.ts +++ b/packages/types/src/global-settings.ts @@ -164,6 +164,7 @@ export const SECRET_STATE_KEYS = [ "glamaApiKey", "openRouterApiKey", "awsAccessKey", + "awsApiKey", "awsSecretKey", "awsSessionToken", "openAiApiKey", diff --git a/packages/types/src/message.ts b/packages/types/src/message.ts index 0c87655fc0..eaec2ad886 100644 --- a/packages/types/src/message.ts +++ b/packages/types/src/message.ts @@ -174,3 +174,19 @@ export const tokenUsageSchema = z.object({ }) export type TokenUsage = z.infer + +/** + * QueuedMessage + */ + +/** + * Represents a message that is queued to be sent when sending is enabled + */ +export interface QueuedMessage { + /** Unique identifier for the queued message */ + id: string + /** The text content of the message */ + text: string + /** Array of image data URLs attached to the message */ + images: string[] +} diff --git a/packages/types/src/mode.ts b/packages/types/src/mode.ts index 175ec095fc..88dcbb9574 100644 --- a/packages/types/src/mode.ts +++ b/packages/types/src/mode.ts @@ -128,3 +128,68 @@ export type CustomModePrompts = z.infer export const customSupportPromptsSchema = z.record(z.string(), z.string().optional()) export type CustomSupportPrompts = z.infer + +/** + * DEFAULT_MODES + */ + +export const DEFAULT_MODES: readonly ModeConfig[] = [ + { + slug: "architect", + name: "🏗️ Architect", + roleDefinition: + "You are Roo, an experienced technical leader who is inquisitive and an excellent planner. Your goal is to gather information and get context to create a detailed plan for accomplishing the user's task, which the user will review and approve before they switch into another mode to implement the solution.", + whenToUse: + "Use this mode when you need to plan, design, or strategize before implementation. Perfect for breaking down complex problems, creating technical specifications, designing system architecture, or brainstorming solutions before coding.", + description: "Plan and design before implementation", + groups: ["read", ["edit", { fileRegex: "\\.md$", description: "Markdown files only" }], "browser", "mcp"], + customInstructions: + "1. Do some information gathering (using provided tools) to get more context about the task.\n\n2. You should also ask the user clarifying questions to get a better understanding of the task.\n\n3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:\n - Specific and actionable\n - Listed in logical execution order\n - Focused on a single, well-defined outcome\n - Clear enough that another mode could execute it independently\n\n **Note:** If the `update_todo_list` tool is not available, write the plan to a markdown file (e.g., `plan.md` or `todo.md`) instead.\n\n4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.\n\n5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list.\n\n6. Include Mermaid diagrams if they help clarify complex workflows or system architecture. Please avoid using double quotes (\"\") and parentheses () inside square brackets ([]) in Mermaid diagrams, as this can cause parsing errors.\n\n7. Use the switch_mode tool to request that the user switch to another mode to implement the solution.\n\n**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**", + }, + { + slug: "code", + name: "💻 Code", + roleDefinition: + "You are Roo, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.", + whenToUse: + "Use this mode when you need to write, modify, or refactor code. Ideal for implementing features, fixing bugs, creating new files, or making code improvements across any programming language or framework.", + description: "Write, modify, and refactor code", + groups: ["read", "edit", "browser", "command", "mcp"], + }, + { + slug: "ask", + name: "❓ Ask", + roleDefinition: + "You are Roo, a knowledgeable technical assistant focused on answering questions and providing information about software development, technology, and related topics.", + whenToUse: + "Use this mode when you need explanations, documentation, or answers to technical questions. Best for understanding concepts, analyzing existing code, getting recommendations, or learning about technologies without making changes.", + description: "Get answers and explanations", + groups: ["read", "browser", "mcp"], + customInstructions: + "You can analyze code, explain concepts, and access external resources. Always answer the user's questions thoroughly, and do not switch to implementing code unless explicitly requested by the user. Include Mermaid diagrams when they clarify your response.", + }, + { + slug: "debug", + name: "🪲 Debug", + roleDefinition: + "You are Roo, an expert software debugger specializing in systematic problem diagnosis and resolution.", + whenToUse: + "Use this mode when you're troubleshooting issues, investigating errors, or diagnosing problems. Specialized in systematic debugging, adding logging, analyzing stack traces, and identifying root causes before applying fixes.", + description: "Diagnose and fix software issues", + groups: ["read", "edit", "browser", "command", "mcp"], + customInstructions: + "Reflect on 5-7 different possible sources of the problem, distill those down to 1-2 most likely sources, and then add logs to validate your assumptions. Explicitly ask the user to confirm the diagnosis before fixing the problem.", + }, + { + slug: "orchestrator", + name: "🪃 Orchestrator", + roleDefinition: + "You are Roo, a strategic workflow orchestrator who coordinates complex tasks by delegating them to appropriate specialized modes. You have a comprehensive understanding of each mode's capabilities and limitations, allowing you to effectively break down complex problems into discrete tasks that can be solved by different specialists.", + whenToUse: + "Use this mode for complex, multi-step projects that require coordination across different specialties. Ideal when you need to break down large tasks into subtasks, manage workflows, or coordinate work that spans multiple domains or expertise areas.", + description: "Coordinate tasks across multiple modes", + groups: [], + customInstructions: + "Your role is to coordinate complex workflows by delegating tasks to specialized modes. As an orchestrator, you should:\n\n1. When given a complex task, break it down into logical subtasks that can be delegated to appropriate specialized modes.\n\n2. For each subtask, use the `new_task` tool to delegate. Choose the most appropriate mode for the subtask's specific goal and provide comprehensive instructions in the `message` parameter. These instructions must include:\n * All necessary context from the parent task or previous subtasks required to complete the work.\n * A clearly defined scope, specifying exactly what the subtask should accomplish.\n * An explicit statement that the subtask should *only* perform the work outlined in these instructions and not deviate.\n * An instruction for the subtask to signal completion by using the `attempt_completion` tool, providing a concise yet thorough summary of the outcome in the `result` parameter, keeping in mind that this summary will be the source of truth used to keep track of what was completed on this project.\n * A statement that these specific instructions supersede any conflicting general instructions the subtask's mode might have.\n\n3. Track and manage the progress of all subtasks. When a subtask is completed, analyze its results and determine the next steps.\n\n4. Help the user understand how the different subtasks fit together in the overall workflow. Provide clear reasoning about why you're delegating specific tasks to specific modes.\n\n5. When all subtasks are completed, synthesize the results and provide a comprehensive overview of what was accomplished.\n\n6. Ask clarifying questions when necessary to better understand how to break down complex tasks effectively.\n\n7. Suggest improvements to the workflow based on the results of completed subtasks.\n\nUse subtasks to maintain clarity. If a request significantly shifts focus or requires a different expertise (mode), consider creating a subtask rather than overloading the current one.", + }, +] as const diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index ea7089a81e..8cdb5296b2 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -114,6 +114,8 @@ const bedrockSchema = apiModelIdProviderModelSchema.extend({ awsUsePromptCache: z.boolean().optional(), awsProfile: z.string().optional(), awsUseProfile: z.boolean().optional(), + awsApiKey: z.string().optional(), + awsUseApiKey: z.boolean().optional(), awsCustomArn: z.string().optional(), awsModelContextWindow: z.number().optional(), awsBedrockEndpointEnabled: z.boolean().optional(), @@ -167,6 +169,8 @@ const lmStudioSchema = baseProviderSettingsSchema.extend({ const geminiSchema = apiModelIdProviderModelSchema.extend({ geminiApiKey: z.string().optional(), googleGeminiBaseUrl: z.string().optional(), + enableUrlContext: z.boolean().optional(), + enableGrounding: z.boolean().optional(), }) const geminiCliSchema = apiModelIdProviderModelSchema.extend({ @@ -234,6 +238,7 @@ const litellmSchema = baseProviderSettingsSchema.extend({ litellmBaseUrl: z.string().optional(), litellmApiKey: z.string().optional(), litellmModelId: z.string().optional(), + litellmUsePromptCache: z.boolean().optional(), }) const defaultSchema = z.object({ diff --git a/packages/types/src/providers/bedrock.ts b/packages/types/src/providers/bedrock.ts index 58e860dd94..9c1f349334 100644 --- a/packages/types/src/providers/bedrock.ts +++ b/packages/types/src/providers/bedrock.ts @@ -360,7 +360,7 @@ export const BEDROCK_MAX_TOKENS = 4096 export const BEDROCK_DEFAULT_CONTEXT = 128_000 -// AWS Bedrock Inference Profile mapping based on official documentation +// Amazon Bedrock Inference Profile mapping based on official documentation // https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html // This mapping is pre-ordered by pattern length (descending) to ensure more specific patterns match first export const AWS_INFERENCE_PROFILE_MAPPING: Array<[string, string]> = [ @@ -378,7 +378,7 @@ export const AWS_INFERENCE_PROFILE_MAPPING: Array<[string, string]> = [ ["sa-", "sa."], ] -// AWS Bedrock supported regions for the regions dropdown +// Amazon Bedrock supported regions for the regions dropdown // Based on official AWS documentation export const BEDROCK_REGIONS = [ { value: "us-east-1", label: "us-east-1" }, diff --git a/packages/types/src/providers/huggingface.ts b/packages/types/src/providers/huggingface.ts new file mode 100644 index 0000000000..d2571a073e --- /dev/null +++ b/packages/types/src/providers/huggingface.ts @@ -0,0 +1,17 @@ +/** + * HuggingFace provider constants + */ + +// Default values for HuggingFace models +export const HUGGINGFACE_DEFAULT_MAX_TOKENS = 2048 +export const HUGGINGFACE_MAX_TOKENS_FALLBACK = 8192 +export const HUGGINGFACE_DEFAULT_CONTEXT_WINDOW = 128_000 + +// UI constants +export const HUGGINGFACE_SLIDER_STEP = 256 +export const HUGGINGFACE_SLIDER_MIN = 1 +export const HUGGINGFACE_TEMPERATURE_MAX_VALUE = 2 + +// API constants +export const HUGGINGFACE_API_URL = "https://router.huggingface.co/v1/models?collection=roocode" +export const HUGGINGFACE_CACHE_DURATION = 1000 * 60 * 60 // 1 hour diff --git a/packages/types/src/providers/index.ts b/packages/types/src/providers/index.ts index e4e506b8a7..f5061f152c 100644 --- a/packages/types/src/providers/index.ts +++ b/packages/types/src/providers/index.ts @@ -6,6 +6,7 @@ export * from "./deepseek.js" export * from "./gemini.js" export * from "./glama.js" export * from "./groq.js" +export * from "./huggingface.js" export * from "./lite-llm.js" export * from "./lm-studio.js" export * from "./mistral.js" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0b94b47a1e..4f278db58a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -568,11 +568,11 @@ importers: specifier: ^0.7.0 version: 0.7.0 '@aws-sdk/client-bedrock-runtime': - specifier: ^3.779.0 - version: 3.817.0 + specifier: ^3.848.0 + version: 3.848.0 '@aws-sdk/credential-providers': - specifier: ^3.806.0 - version: 3.817.0 + specifier: ^3.848.0 + version: 3.848.0 '@google/genai': specifier: ^1.0.0 version: 1.3.0(@modelcontextprotocol/sdk@1.12.0) @@ -654,6 +654,9 @@ importers: google-auth-library: specifier: ^9.15.1 version: 9.15.1 + gray-matter: + specifier: ^4.0.3 + version: 4.0.3 i18next: specifier: ^25.0.0 version: 25.2.1(typescript@5.8.3) @@ -1188,111 +1191,123 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/client-bedrock-runtime@3.817.0': - resolution: {integrity: sha512-fG3QAjIEq7P0a134E2P8r4qw/V6rL0X5voUPIcXte1oNKUXUjNXJb21N/NGmcDLCUVWvYXb24dD0YXyQ2kwZdA==} + '@aws-sdk/client-bedrock-runtime@3.848.0': + resolution: {integrity: sha512-oWXy0eLanklzZLz6TQwcxxnwqYFjdDCHnKkdMWLOHSPgPJVZxqGfr1KD72XHwg9386+vxInZ0VYIggs0cut/Hw==} engines: {node: '>=18.0.0'} - '@aws-sdk/client-cognito-identity@3.817.0': - resolution: {integrity: sha512-MNGwOJDQU0jpvsLLPSuPQDhPtDzFTc/k7rLmiKoPrIlgb3Y8pSF4crpJ+ZH3+xod2NWyyOVMEMQeMaKFFdMaKw==} + '@aws-sdk/client-cognito-identity@3.848.0': + resolution: {integrity: sha512-Sin8aLnA81MgvUJrfQsBIQ1UJg4klWT3NuYYjExLiVQf3A0/F7Bfx1HTIyWXtSchY4QgGr7MMone0/0KZ4Dy9g==} engines: {node: '>=18.0.0'} - '@aws-sdk/client-sso@3.817.0': - resolution: {integrity: sha512-fCh5rUHmWmWDvw70NNoWpE5+BRdtNi45kDnIoeoszqVg7UKF79SlG+qYooUT52HKCgDNHqgbWaXxMOSqd2I/OQ==} + '@aws-sdk/client-sso@3.848.0': + resolution: {integrity: sha512-mD+gOwoeZQvbecVLGoCmY6pS7kg02BHesbtIxUj+PeBqYoZV5uLvjUOmuGfw1SfoSobKvS11urxC9S7zxU/Maw==} engines: {node: '>=18.0.0'} - '@aws-sdk/core@3.816.0': - resolution: {integrity: sha512-Lx50wjtyarzKpMFV6V+gjbSZDgsA/71iyifbClGUSiNPoIQ4OCV0KVOmAAj7mQRVvGJqUMWKVM+WzK79CjbjWA==} + '@aws-sdk/core@3.846.0': + resolution: {integrity: sha512-7CX0pM906r4WSS68fCTNMTtBCSkTtf3Wggssmx13gD40gcWEZXsU00KzPp1bYheNRyPlAq3rE22xt4wLPXbuxA==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-cognito-identity@3.817.0': - resolution: {integrity: sha512-+dzgWGmdmMNDdeSF+VvONN+hwqoGKX5A6Z3+siMO4CIoKWN7u5nDOx/JLjTGdVQji3522pJjJ+o9veQJNWOMRg==} + '@aws-sdk/credential-provider-cognito-identity@3.848.0': + resolution: {integrity: sha512-2cm/Ye6ktagW1h7FmF4sgo8STZyBr2+0+L9lr/veuPKZVWoi/FyhJR3l0TtKrd8z78no9P5xbsGUmxoDLtsxiw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-env@3.816.0': - resolution: {integrity: sha512-wUJZwRLe+SxPxRV9AENYBLrJZRrNIo+fva7ZzejsC83iz7hdfq6Rv6B/aHEdPwG/nQC4+q7UUvcRPlomyrpsBA==} + '@aws-sdk/credential-provider-env@3.846.0': + resolution: {integrity: sha512-QuCQZET9enja7AWVISY+mpFrEIeHzvkx/JEEbHYzHhUkxcnC2Kq2c0bB7hDihGD0AZd3Xsm653hk1O97qu69zg==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-http@3.816.0': - resolution: {integrity: sha512-gcWGzMQ7yRIF+ljTkR8Vzp7727UY6cmeaPrFQrvcFB8PhOqWpf7g0JsgOf5BSaP8CkkSQcTQHc0C5ZYAzUFwPg==} + '@aws-sdk/credential-provider-http@3.846.0': + resolution: {integrity: sha512-Jh1iKUuepdmtreMYozV2ePsPcOF5W9p3U4tWhi3v6nDvz0GsBjzjAROW+BW8XMz9vAD3I9R+8VC3/aq63p5nlw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-ini@3.817.0': - resolution: {integrity: sha512-kyEwbQyuXE+phWVzloMdkFv6qM6NOon+asMXY5W0fhDKwBz9zQLObDRWBrvQX9lmqq8BbDL1sCfZjOh82Y+RFw==} + '@aws-sdk/credential-provider-ini@3.848.0': + resolution: {integrity: sha512-r6KWOG+En2xujuMhgZu7dzOZV3/M5U/5+PXrG8dLQ3rdPRB3vgp5tc56KMqLwm/EXKRzAOSuw/UE4HfNOAB8Hw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-node@3.817.0': - resolution: {integrity: sha512-b5mz7av0Lhavs1Bz3Zb+jrs0Pki93+8XNctnVO0drBW98x1fM4AR38cWvGbM/w9F9Q0/WEH3TinkmrMPrP4T/w==} + '@aws-sdk/credential-provider-node@3.848.0': + resolution: {integrity: sha512-AblNesOqdzrfyASBCo1xW3uweiSro4Kft9/htdxLeCVU1KVOnFWA5P937MNahViRmIQm2sPBCqL8ZG0u9lnh5g==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-process@3.816.0': - resolution: {integrity: sha512-9Tm+AxMoV2Izvl5b9tyMQRbBwaex8JP06HN7ZeCXgC5sAsSN+o8dsThnEhf8jKN+uBpT6CLWKN1TXuUMrAmW1A==} + '@aws-sdk/credential-provider-process@3.846.0': + resolution: {integrity: sha512-mEpwDYarJSH+CIXnnHN0QOe0MXI+HuPStD6gsv3z/7Q6ESl8KRWon3weFZCDnqpiJMUVavlDR0PPlAFg2MQoPg==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-sso@3.817.0': - resolution: {integrity: sha512-gFUAW3VmGvdnueK1bh6TOcRX+j99Xm0men1+gz3cA4RE+rZGNy1Qjj8YHlv0hPwI9OnTPZquvPzA5fkviGREWg==} + '@aws-sdk/credential-provider-sso@3.848.0': + resolution: {integrity: sha512-pozlDXOwJZL0e7w+dqXLgzVDB7oCx4WvtY0sk6l4i07uFliWF/exupb6pIehFWvTUcOvn5aFTTqcQaEzAD5Wsg==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-web-identity@3.817.0': - resolution: {integrity: sha512-A2kgkS9g6NY0OMT2f2EdXHpL17Ym81NhbGnQ8bRXPqESIi7TFypFD2U6osB2VnsFv+MhwM+Ke4PKXSmLun22/A==} + '@aws-sdk/credential-provider-web-identity@3.848.0': + resolution: {integrity: sha512-D1fRpwPxtVDhcSc/D71exa2gYweV+ocp4D3brF0PgFd//JR3XahZ9W24rVnTQwYEcK9auiBZB89Ltv+WbWN8qw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-providers@3.817.0': - resolution: {integrity: sha512-i6Q2MyktWHG4YG+EmLlnXTgNVjW9/yeNHSKzF55GTho5fjqfU+t9beJfuMWclanRCifamm3N5e5OCm52rVDdTQ==} + '@aws-sdk/credential-providers@3.848.0': + resolution: {integrity: sha512-lRDuU05YC+r/1JmRULngJQli7scP5hmq0/7D+xw1s8eRM0H2auaH7LQFlq/SLxQZLMkVNPCrmsug3b3KcLj1NA==} engines: {node: '>=18.0.0'} - '@aws-sdk/eventstream-handler-node@3.804.0': - resolution: {integrity: sha512-LZddQVBUCB86tZtLJRhqiDyIqr4hfRxZCcUp1fZSfpBMcf419lgcFRGWMR3J/kCWHQ0G05aor7fSeoeaxskuNQ==} + '@aws-sdk/eventstream-handler-node@3.840.0': + resolution: {integrity: sha512-m/zVrSSAEHq+6h4sy0JUEBScB1pGgs/1+iRVhfzfbnf+/gTr4ut2jRq4tDiNEX9pQ1oFVvw+ntPua5qfquQeRQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-eventstream@3.804.0': - resolution: {integrity: sha512-3lPxZshOJoKSxIMUq8FCiIre+FZ1g/t+O7DHwOMB6EuzJ8lp5QyUeh1wE5iD/gB8VhWZoj90rGIaWCmT8ccEuA==} + '@aws-sdk/middleware-eventstream@3.840.0': + resolution: {integrity: sha512-4khgf7AjJ4llh3aiNmZ+x4PGl4vkKNxRHn0xTgi6Iw1J3SChsF2mnNaLXK8hoXeydx756rw+JhqOuZH91i5l4w==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-host-header@3.804.0': - resolution: {integrity: sha512-bum1hLVBrn2lJCi423Z2fMUYtsbkGI2s4N+2RI2WSjvbaVyMSv/WcejIrjkqiiMR+2Y7m5exgoKeg4/TODLDPQ==} + '@aws-sdk/middleware-host-header@3.840.0': + resolution: {integrity: sha512-ub+hXJAbAje94+Ya6c6eL7sYujoE8D4Bumu1NUI8TXjUhVVn0HzVWQjpRLshdLsUp1AW7XyeJaxyajRaJQ8+Xg==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-logger@3.804.0': - resolution: {integrity: sha512-w/qLwL3iq0KOPQNat0Kb7sKndl9BtceigINwBU7SpkYWX9L/Lem6f8NPEKrC9Tl4wDBht3Yztub4oRTy/horJA==} + '@aws-sdk/middleware-logger@3.840.0': + resolution: {integrity: sha512-lSV8FvjpdllpGaRspywss4CtXV8M7NNNH+2/j86vMH+YCOZ6fu2T/TyFd/tHwZ92vDfHctWkRbQxg0bagqwovA==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-recursion-detection@3.804.0': - resolution: {integrity: sha512-zqHOrvLRdsUdN/ehYfZ9Tf8svhbiLLz5VaWUz22YndFv6m9qaAcijkpAOlKexsv3nLBMJdSdJ6GUTAeIy3BZzw==} + '@aws-sdk/middleware-recursion-detection@3.840.0': + resolution: {integrity: sha512-Gu7lGDyfddyhIkj1Z1JtrY5NHb5+x/CRiB87GjaSrKxkDaydtX2CU977JIABtt69l9wLbcGDIQ+W0uJ5xPof7g==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-user-agent@3.816.0': - resolution: {integrity: sha512-bHRSlWZ0xDsFR8E2FwDb//0Ff6wMkVx4O+UKsfyNlAbtqCiiHRt5ANNfKPafr95cN2CCxLxiPvFTFVblQM5TsQ==} + '@aws-sdk/middleware-user-agent@3.848.0': + resolution: {integrity: sha512-rjMuqSWJEf169/ByxvBqfdei1iaduAnfolTshsZxwcmLIUtbYrFUmts0HrLQqsAG8feGPpDLHA272oPl+NTCCA==} engines: {node: '>=18.0.0'} - '@aws-sdk/nested-clients@3.817.0': - resolution: {integrity: sha512-vQ2E06A48STJFssueJQgxYD8lh1iGJoLJnHdshRDWOQb8gy1wVQR+a7MkPGhGR6lGoS0SCnF/Qp6CZhnwLsqsQ==} + '@aws-sdk/middleware-websocket@3.844.0': + resolution: {integrity: sha512-5ZtntUZ9ZMdUbQZ3kI5e5tpiZPN/O57h6fnGZ+GHB+wpSVSOQS78TBt0qYZW+CoZr8iyRsVkJheGETajFCMaUg==} + engines: {node: '>= 14.0.0'} + + '@aws-sdk/nested-clients@3.848.0': + resolution: {integrity: sha512-joLsyyo9u61jnZuyYzo1z7kmS7VgWRAkzSGESVzQHfOA1H2PYeUFek6vLT4+c9xMGrX/Z6B0tkRdzfdOPiatLg==} engines: {node: '>=18.0.0'} - '@aws-sdk/region-config-resolver@3.808.0': - resolution: {integrity: sha512-9x2QWfphkARZY5OGkl9dJxZlSlYM2l5inFeo2bKntGuwg4A4YUe5h7d5yJ6sZbam9h43eBrkOdumx03DAkQF9A==} + '@aws-sdk/region-config-resolver@3.840.0': + resolution: {integrity: sha512-Qjnxd/yDv9KpIMWr90ZDPtRj0v75AqGC92Lm9+oHXZ8p1MjG5JE2CW0HL8JRgK9iKzgKBL7pPQRXI8FkvEVfrA==} engines: {node: '>=18.0.0'} - '@aws-sdk/token-providers@3.817.0': - resolution: {integrity: sha512-CYN4/UO0VaqyHf46ogZzNrVX7jI3/CfiuktwKlwtpKA6hjf2+ivfgHSKzPpgPBcSEfiibA/26EeLuMnB6cpSrQ==} + '@aws-sdk/token-providers@3.848.0': + resolution: {integrity: sha512-oNPyM4+Di2Umu0JJRFSxDcKQ35+Chl/rAwD47/bS0cDPI8yrao83mLXLeDqpRPHyQW4sXlP763FZcuAibC0+mg==} engines: {node: '>=18.0.0'} '@aws-sdk/types@3.804.0': resolution: {integrity: sha512-A9qnsy9zQ8G89vrPPlNG9d1d8QcKRGqJKqwyGgS0dclJpwy6d1EWgQLIolKPl6vcFpLoe6avLOLxr+h8ur5wpg==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-endpoints@3.808.0': - resolution: {integrity: sha512-N6Lic98uc4ADB7fLWlzx+1uVnq04VgVjngZvwHoujcRg9YDhIg9dUDiTzD5VZv13g1BrPYmvYP1HhsildpGV6w==} + '@aws-sdk/types@3.840.0': + resolution: {integrity: sha512-xliuHaUFZxEx1NSXeLLZ9Dyu6+EJVQKEoD+yM+zqUo3YDZ7medKJWY6fIOKiPX/N7XbLdBYwajb15Q7IL8KkeA==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/util-endpoints@3.848.0': + resolution: {integrity: sha512-fY/NuFFCq/78liHvRyFKr+aqq1aA/uuVSANjzr5Ym8c+9Z3HRPE9OrExAHoMrZ6zC8tHerQwlsXYYH5XZ7H+ww==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/util-format-url@3.840.0': + resolution: {integrity: sha512-VB1PWyI1TQPiPvg4w7tgUGGQER1xxXPNUqfh3baxUSFi1Oh8wHrDnFywkxLm3NMmgDmnLnSZ5Q326qAoyqKLSg==} engines: {node: '>=18.0.0'} '@aws-sdk/util-locate-window@3.804.0': resolution: {integrity: sha512-zVoRfpmBVPodYlnMjgVjfGoEZagyRF5IPn3Uo6ZvOZp24chnW/FRstH7ESDHDDRga4z3V+ElUQHKpFDXWyBW5A==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-user-agent-browser@3.804.0': - resolution: {integrity: sha512-KfW6T6nQHHM/vZBBdGn6fMyG/MgX5lq82TDdX4HRQRRuHKLgBWGpKXqqvBwqIaCdXwWHgDrg2VQups6GqOWW2A==} + '@aws-sdk/util-user-agent-browser@3.840.0': + resolution: {integrity: sha512-JdyZM3EhhL4PqwFpttZu1afDpPJCCc3eyZOLi+srpX11LsGj6sThf47TYQN75HT1CarZ7cCdQHGzP2uy3/xHfQ==} - '@aws-sdk/util-user-agent-node@3.816.0': - resolution: {integrity: sha512-Q6dxmuj4hL7pudhrneWEQ7yVHIQRBFr0wqKLF1opwOi1cIePuoEbPyJ2jkel6PDEv1YMfvsAKaRshp6eNA8VHg==} + '@aws-sdk/util-user-agent-node@3.848.0': + resolution: {integrity: sha512-Zz1ft9NiLqbzNj/M0jVNxaoxI2F4tGXN0ZbZIj+KJ+PbJo+w5+Jo6d0UDAtbj3AEd79pjcCaP4OA9NTVzItUdw==} engines: {node: '>=18.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -1303,6 +1318,10 @@ packages: '@aws-sdk/util-utf8-browser@3.259.0': resolution: {integrity: sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==} + '@aws-sdk/xml-builder@3.821.0': + resolution: {integrity: sha512-DIIotRnefVL6DiaHtO6/21DhJ4JZnnIwdNbpwiAhdt/AVbttcE4yw925gsjur0OGv5BTYXQXU3YnANBYnZjuQA==} + engines: {node: '>=18.0.0'} + '@azure/abort-controller@2.1.2': resolution: {integrity: sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==} engines: {node: '>=18.0.0'} @@ -3103,66 +3122,66 @@ packages: resolution: {integrity: sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw==} engines: {node: '>=14.0.0'} - '@smithy/abort-controller@4.0.3': - resolution: {integrity: sha512-AqXFf6DXnuRBXy4SoK/n1mfgHaKaq36bmkphmD1KO0nHq6xK/g9KHSW4HEsPQUBCGdIEfuJifGHwxFXPIFay9Q==} + '@smithy/abort-controller@4.0.4': + resolution: {integrity: sha512-gJnEjZMvigPDQWHrW3oPrFhQtkrgqBkyjj3pCIdF3A5M6vsZODG93KNlfJprv6bp4245bdT32fsHK4kkH3KYDA==} engines: {node: '>=18.0.0'} - '@smithy/config-resolver@4.1.3': - resolution: {integrity: sha512-N5e7ofiyYDmHxnPnqF8L4KtsbSDwyxFRfDK9bp1d9OyPO4ytRLd0/XxCqi5xVaaqB65v4woW8uey6jND6zxzxQ==} + '@smithy/config-resolver@4.1.4': + resolution: {integrity: sha512-prmU+rDddxHOH0oNcwemL+SwnzcG65sBF2yXRO7aeXIn/xTlq2pX7JLVbkBnVLowHLg4/OL4+jBmv9hVrVGS+w==} engines: {node: '>=18.0.0'} - '@smithy/core@3.4.0': - resolution: {integrity: sha512-dDYISQo7k0Ml/rXlFIjkTmTcQze/LxhtIRAEmZ6HJ/EI0inVxVEVnrUXJ7jPx6ZP0GHUhFm40iQcCgS5apXIXA==} + '@smithy/core@3.7.1': + resolution: {integrity: sha512-ExRCsHnXFtBPnM7MkfKBPcBBdHw1h/QS/cbNw4ho95qnyNHvnpmGbR39MIAv9KggTr5qSPxRSEL+hRXlyGyGQw==} engines: {node: '>=18.0.0'} - '@smithy/credential-provider-imds@4.0.5': - resolution: {integrity: sha512-saEAGwrIlkb9XxX/m5S5hOtzjoJPEK6Qw2f9pYTbIsMPOFyGSXBBTw95WbOyru8A1vIS2jVCCU1Qhz50QWG3IA==} + '@smithy/credential-provider-imds@4.0.6': + resolution: {integrity: sha512-hKMWcANhUiNbCJouYkZ9V3+/Qf9pteR1dnwgdyzR09R4ODEYx8BbUysHwRSyex4rZ9zapddZhLFTnT4ZijR4pw==} engines: {node: '>=18.0.0'} '@smithy/eventstream-codec@2.2.0': resolution: {integrity: sha512-8janZoJw85nJmQZc4L8TuePp2pk1nxLgkxIR0TUjKJ5Dkj5oelB9WtiSSGXCQvNsJl0VSTvK/2ueMXxvpa9GVw==} - '@smithy/eventstream-codec@4.0.3': - resolution: {integrity: sha512-V22KIPXZsE2mc4zEgYGANM/7UbL9jWlOACEolyGyMuTY+jjHJ2PQ0FdopOTS1CS7u6PlAkALmypkv2oQ4aftcg==} + '@smithy/eventstream-codec@4.0.4': + resolution: {integrity: sha512-7XoWfZqWb/QoR/rAU4VSi0mWnO2vu9/ltS6JZ5ZSZv0eovLVfDfu0/AX4ub33RsJTOth3TiFWSHS5YdztvFnig==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-browser@4.0.3': - resolution: {integrity: sha512-oe1d/tfCGVZBMX8O6HApaM4G+fF9JNdyLP7tWXt00epuL/kLOdp/4o9VqheLFeJaXgao+9IaBgs/q/oM48hxzg==} + '@smithy/eventstream-serde-browser@4.0.4': + resolution: {integrity: sha512-3fb/9SYaYqbpy/z/H3yIi0bYKyAa89y6xPmIqwr2vQiUT2St+avRt8UKwsWt9fEdEasc5d/V+QjrviRaX1JRFA==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-config-resolver@4.1.1': - resolution: {integrity: sha512-XXCPGjRNwpFWHKQJMKIjGLfFKYULYckFnxGcWmBC2mBf3NsrvUKgqHax4NCqc0TfbDAimPDHOc6HOKtzsXK9Gw==} + '@smithy/eventstream-serde-config-resolver@4.1.2': + resolution: {integrity: sha512-JGtambizrWP50xHgbzZI04IWU7LdI0nh/wGbqH3sJesYToMi2j/DcoElqyOcqEIG/D4tNyxgRuaqBXWE3zOFhQ==} engines: {node: '>=18.0.0'} '@smithy/eventstream-serde-node@2.2.0': resolution: {integrity: sha512-zpQMtJVqCUMn+pCSFcl9K/RPNtQE0NuMh8sKpCdEHafhwRsjP50Oq/4kMmvxSRy6d8Jslqd8BLvDngrUtmN9iA==} engines: {node: '>=14.0.0'} - '@smithy/eventstream-serde-node@4.0.3': - resolution: {integrity: sha512-HOEbRmm9TrikCoFrypYu0J/gC4Lsk8gl5LtOz1G3laD2Jy44+ht2Pd2E9qjNQfhMJIzKDZ/gbuUH0s0v4kWQ0A==} + '@smithy/eventstream-serde-node@4.0.4': + resolution: {integrity: sha512-RD6UwNZ5zISpOWPuhVgRz60GkSIp0dy1fuZmj4RYmqLVRtejFqQ16WmfYDdoSoAjlp1LX+FnZo+/hkdmyyGZ1w==} engines: {node: '>=18.0.0'} '@smithy/eventstream-serde-universal@2.2.0': resolution: {integrity: sha512-pvoe/vvJY0mOpuF84BEtyZoYfbehiFj8KKWk1ds2AT0mTLYFVs+7sBJZmioOFdBXKd48lfrx1vumdPdmGlCLxA==} engines: {node: '>=14.0.0'} - '@smithy/eventstream-serde-universal@4.0.3': - resolution: {integrity: sha512-ShOP512CZrYI9n+h64PJ84udzoNHUQtPddyh1j175KNTKsSnMEDNscOWJWyEoLQiuhWWw51lSa+k6ea9ZGXcRg==} + '@smithy/eventstream-serde-universal@4.0.4': + resolution: {integrity: sha512-UeJpOmLGhq1SLox79QWw/0n2PFX+oPRE1ZyRMxPIaFEfCqWaqpB7BU9C8kpPOGEhLF7AwEqfFbtwNxGy4ReENA==} engines: {node: '>=18.0.0'} '@smithy/fetch-http-handler@2.5.0': resolution: {integrity: sha512-BOWEBeppWhLn/no/JxUL/ghTfANTjT7kg3Ww2rPqTUY9R4yHPXxJ9JhMe3Z03LN3aPwiwlpDIUcVw1xDyHqEhw==} - '@smithy/fetch-http-handler@5.0.3': - resolution: {integrity: sha512-yBZwavI31roqTndNI7ONHqesfH01JmjJK6L3uUpZAhyAmr86LN5QiPzfyZGIxQmed8VEK2NRSQT3/JX5V1njfQ==} + '@smithy/fetch-http-handler@5.1.0': + resolution: {integrity: sha512-mADw7MS0bYe2OGKkHYMaqarOXuDwRbO6ArD91XhHcl2ynjGCFF+hvqf0LyQcYxkA1zaWjefSkU7Ne9mqgApSgQ==} engines: {node: '>=18.0.0'} - '@smithy/hash-node@4.0.3': - resolution: {integrity: sha512-W5Uhy6v/aYrgtjh9y0YP332gIQcwccQ+EcfWhllL0B9rPae42JngTTUpb8W6wuxaNFzqps4xq5klHckSSOy5fw==} + '@smithy/hash-node@4.0.4': + resolution: {integrity: sha512-qnbTPUhCVnCgBp4z4BUJUhOEkVwxiEi1cyFM+Zj6o+aY8OFGxUQleKWq8ltgp3dujuhXojIvJWdoqpm6dVO3lQ==} engines: {node: '>=18.0.0'} - '@smithy/invalid-dependency@4.0.3': - resolution: {integrity: sha512-1Bo8Ur1ZGqxvwTqBmv6DZEn0rXtwJGeqiiO2/JFcCtz3nBakOqeXbJBElXJMMzd0ghe8+eB6Dkw98nMYctgizg==} + '@smithy/invalid-dependency@4.0.4': + resolution: {integrity: sha512-bNYMi7WKTJHu0gn26wg8OscncTt1t2b8KcsZxvOv56XA6cyXtOAAAaNP7+m45xfppXfOatXF3Sb1MNsLUgVLTw==} engines: {node: '>=18.0.0'} '@smithy/is-array-buffer@2.2.0': @@ -3177,112 +3196,112 @@ packages: resolution: {integrity: sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==} engines: {node: '>=18.0.0'} - '@smithy/middleware-content-length@4.0.3': - resolution: {integrity: sha512-NE/Zph4BP5u16bzYq2csq9qD0T6UBLeg4AuNrwNJ7Gv9uLYaGEgelZUOdRndGdMGcUfSGvNlXGb2aA2hPCwJ6g==} + '@smithy/middleware-content-length@4.0.4': + resolution: {integrity: sha512-F7gDyfI2BB1Kc+4M6rpuOLne5LOcEknH1n6UQB69qv+HucXBR1rkzXBnQTB2q46sFy1PM/zuSJOB532yc8bg3w==} engines: {node: '>=18.0.0'} '@smithy/middleware-endpoint@2.5.1': resolution: {integrity: sha512-1/8kFp6Fl4OsSIVTWHnNjLnTL8IqpIb/D3sTSczrKFnrE9VMNWxnrRKNvpUHOJ6zpGD5f62TPm7+17ilTJpiCQ==} engines: {node: '>=14.0.0'} - '@smithy/middleware-endpoint@4.1.7': - resolution: {integrity: sha512-KDzM7Iajo6K7eIWNNtukykRT4eWwlHjCEsULZUaSfi/SRSBK8BPRqG5FsVfp58lUxcvre8GT8AIPIqndA0ERKw==} + '@smithy/middleware-endpoint@4.1.16': + resolution: {integrity: sha512-plpa50PIGLqzMR2ANKAw2yOW5YKS626KYKqae3atwucbz4Ve4uQ9K9BEZxDLIFmCu7hKLcrq2zmj4a+PfmUV5w==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.1.8': - resolution: {integrity: sha512-e2OtQgFzzlSG0uCjcJmi02QuFSRTrpT11Eh2EcqqDFy7DYriteHZJkkf+4AsxsrGDugAtPFcWBz1aq06sSX5fQ==} + '@smithy/middleware-retry@4.1.17': + resolution: {integrity: sha512-gsCimeG6BApj0SBecwa1Be+Z+JOJe46iy3B3m3A8jKJHf7eIihP76Is4LwLrbJ1ygoS7Vg73lfqzejmLOrazUA==} engines: {node: '>=18.0.0'} '@smithy/middleware-serde@2.3.0': resolution: {integrity: sha512-sIADe7ojwqTyvEQBe1nc/GXB9wdHhi9UwyX0lTyttmUWDJLP655ZYE1WngnNyXREme8I27KCaUhyhZWRXL0q7Q==} engines: {node: '>=14.0.0'} - '@smithy/middleware-serde@4.0.6': - resolution: {integrity: sha512-YECyl7uNII+jCr/9qEmCu8xYL79cU0fqjo0qxpcVIU18dAPHam/iYwcknAu4Jiyw1uN+sAx7/SMf/Kmef/Jjsg==} + '@smithy/middleware-serde@4.0.8': + resolution: {integrity: sha512-iSSl7HJoJaGyMIoNn2B7czghOVwJ9nD7TMvLhMWeSB5vt0TnEYyRRqPJu/TqW76WScaNvYYB8nRoiBHR9S1Ddw==} engines: {node: '>=18.0.0'} '@smithy/middleware-stack@2.2.0': resolution: {integrity: sha512-Qntc3jrtwwrsAC+X8wms8zhrTr0sFXnyEGhZd9sLtsJ/6gGQKFzNB+wWbOcpJd7BR8ThNCoKt76BuQahfMvpeA==} engines: {node: '>=14.0.0'} - '@smithy/middleware-stack@4.0.3': - resolution: {integrity: sha512-baeV7t4jQfQtFxBADFmnhmqBmqR38dNU5cvEgHcMK/Kp3D3bEI0CouoX2Sr/rGuntR+Eg0IjXdxnGGTc6SbIkw==} + '@smithy/middleware-stack@4.0.4': + resolution: {integrity: sha512-kagK5ggDrBUCCzI93ft6DjteNSfY8Ulr83UtySog/h09lTIOAJ/xUSObutanlPT0nhoHAkpmW9V5K8oPyLh+QA==} engines: {node: '>=18.0.0'} '@smithy/node-config-provider@2.3.0': resolution: {integrity: sha512-0elK5/03a1JPWMDPaS726Iw6LpQg80gFut1tNpPfxFuChEEklo2yL823V94SpTZTxmKlXFtFgsP55uh3dErnIg==} engines: {node: '>=14.0.0'} - '@smithy/node-config-provider@4.1.2': - resolution: {integrity: sha512-SUvNup8iU1v7fmM8XPk+27m36udmGCfSz+VZP5Gb0aJ3Ne0X28K/25gnsrg3X1rWlhcnhzNUUysKW/Ied46ivQ==} + '@smithy/node-config-provider@4.1.3': + resolution: {integrity: sha512-HGHQr2s59qaU1lrVH6MbLlmOBxadtzTsoO4c+bF5asdgVik3I8o7JIOzoeqWc5MjVa+vD36/LWE0iXKpNqooRw==} engines: {node: '>=18.0.0'} '@smithy/node-http-handler@2.5.0': resolution: {integrity: sha512-mVGyPBzkkGQsPoxQUbxlEfRjrj6FPyA3u3u2VXGr9hT8wilsoQdZdvKpMBFMB8Crfhv5dNkKHIW0Yyuc7eABqA==} engines: {node: '>=14.0.0'} - '@smithy/node-http-handler@4.0.5': - resolution: {integrity: sha512-T7QglZC1vS7SPT44/1qSIAQEx5bFKb3LfO6zw/o4Xzt1eC5HNoH1TkS4lMYA9cWFbacUhx4hRl/blLun4EOCkg==} + '@smithy/node-http-handler@4.1.0': + resolution: {integrity: sha512-vqfSiHz2v8b3TTTrdXi03vNz1KLYYS3bhHCDv36FYDqxT7jvTll1mMnCrkD+gOvgwybuunh/2VmvOMqwBegxEg==} engines: {node: '>=18.0.0'} '@smithy/property-provider@2.2.0': resolution: {integrity: sha512-+xiil2lFhtTRzXkx8F053AV46QnIw6e7MV8od5Mi68E1ICOjCeCHw2XfLnDEUHnT9WGUIkwcqavXjfwuJbGlpg==} engines: {node: '>=14.0.0'} - '@smithy/property-provider@4.0.3': - resolution: {integrity: sha512-Wcn17QNdawJZcZZPBuMuzyBENVi1AXl4TdE0jvzo4vWX2x5df/oMlmr/9M5XAAC6+yae4kWZlOYIsNsgDrMU9A==} + '@smithy/property-provider@4.0.4': + resolution: {integrity: sha512-qHJ2sSgu4FqF4U/5UUp4DhXNmdTrgmoAai6oQiM+c5RZ/sbDwJ12qxB1M6FnP+Tn/ggkPZf9ccn4jqKSINaquw==} engines: {node: '>=18.0.0'} '@smithy/protocol-http@3.3.0': resolution: {integrity: sha512-Xy5XK1AFWW2nlY/biWZXu6/krgbaf2dg0q492D8M5qthsnU2H+UgFeZLbM76FnH7s6RO/xhQRkj+T6KBO3JzgQ==} engines: {node: '>=14.0.0'} - '@smithy/protocol-http@5.1.1': - resolution: {integrity: sha512-Vsay2mzq05DwNi9jK01yCFtfvu9HimmgC7a4HTs7lhX12Sx8aWsH0mfz6q/02yspSp+lOB+Q2HJwi4IV2GKz7A==} + '@smithy/protocol-http@5.1.2': + resolution: {integrity: sha512-rOG5cNLBXovxIrICSBm95dLqzfvxjEmuZx4KK3hWwPFHGdW3lxY0fZNXfv2zebfRO7sJZ5pKJYHScsqopeIWtQ==} engines: {node: '>=18.0.0'} '@smithy/querystring-builder@2.2.0': resolution: {integrity: sha512-L1kSeviUWL+emq3CUVSgdogoM/D9QMFaqxL/dd0X7PCNWmPXqt+ExtrBjqT0V7HLN03Vs9SuiLrG3zy3JGnE5A==} engines: {node: '>=14.0.0'} - '@smithy/querystring-builder@4.0.3': - resolution: {integrity: sha512-UUzIWMVfPmDZcOutk2/r1vURZqavvQW0OHvgsyNV0cKupChvqg+/NKPRMaMEe+i8tP96IthMFeZOZWpV+E4RAw==} + '@smithy/querystring-builder@4.0.4': + resolution: {integrity: sha512-SwREZcDnEYoh9tLNgMbpop+UTGq44Hl9tdj3rf+yeLcfH7+J8OXEBaMc2kDxtyRHu8BhSg9ADEx0gFHvpJgU8w==} engines: {node: '>=18.0.0'} '@smithy/querystring-parser@2.2.0': resolution: {integrity: sha512-BvHCDrKfbG5Yhbpj4vsbuPV2GgcpHiAkLeIlcA1LtfpMz3jrqizP1+OguSNSj1MwBHEiN+jwNisXLGdajGDQJA==} engines: {node: '>=14.0.0'} - '@smithy/querystring-parser@4.0.3': - resolution: {integrity: sha512-K5M4ZJQpFCblOJ5Oyw7diICpFg1qhhR47m2/5Ef1PhGE19RaIZf50tjYFrxa6usqcuXyTiFPGo4d1geZdH4YcQ==} + '@smithy/querystring-parser@4.0.4': + resolution: {integrity: sha512-6yZf53i/qB8gRHH/l2ZwUG5xgkPgQF15/KxH0DdXMDHjesA9MeZje/853ifkSY0x4m5S+dfDZ+c4x439PF0M2w==} engines: {node: '>=18.0.0'} - '@smithy/service-error-classification@4.0.4': - resolution: {integrity: sha512-W5ScbQ1bTzgH91kNEE2CvOzM4gXlDOqdow4m8vMFSIXCel2scbHwjflpVNnC60Y3F1m5i7w2gQg9lSnR+JsJAA==} + '@smithy/service-error-classification@4.0.6': + resolution: {integrity: sha512-RRoTDL//7xi4tn5FrN2NzH17jbgmnKidUqd4KvquT0954/i6CXXkh1884jBiunq24g9cGtPBEXlU40W6EpNOOg==} engines: {node: '>=18.0.0'} '@smithy/shared-ini-file-loader@2.4.0': resolution: {integrity: sha512-WyujUJL8e1B6Z4PBfAqC/aGY1+C7T0w20Gih3yrvJSk97gpiVfB+y7c46T4Nunk+ZngLq0rOIdeVeIklk0R3OA==} engines: {node: '>=14.0.0'} - '@smithy/shared-ini-file-loader@4.0.3': - resolution: {integrity: sha512-vHwlrqhZGIoLwaH8vvIjpHnloShqdJ7SUPNM2EQtEox+yEDFTVQ7E+DLZ+6OhnYEgFUwPByJyz6UZaOu2tny6A==} + '@smithy/shared-ini-file-loader@4.0.4': + resolution: {integrity: sha512-63X0260LoFBjrHifPDs+nM9tV0VMkOTl4JRMYNuKh/f5PauSjowTfvF3LogfkWdcPoxsA9UjqEOgjeYIbhb7Nw==} engines: {node: '>=18.0.0'} '@smithy/signature-v4@3.1.2': resolution: {integrity: sha512-3BcPylEsYtD0esM4Hoyml/+s7WP2LFhcM3J2AGdcL2vx9O60TtfpDOL72gjb4lU8NeRPeKAwR77YNyyGvMbuEA==} engines: {node: '>=16.0.0'} - '@smithy/signature-v4@5.1.1': - resolution: {integrity: sha512-zy8Repr5zvT0ja+Tf5wjV/Ba6vRrhdiDcp/ww6cvqYbSEudIkziDe3uppNRlFoCViyJXdPnLcwyZdDLA4CHzSg==} + '@smithy/signature-v4@5.1.2': + resolution: {integrity: sha512-d3+U/VpX7a60seHziWnVZOHuEgJlclufjkS6zhXvxcJgkJq4UWdH5eOBLzHRMx6gXjsdT9h6lfpmLzbrdupHgQ==} engines: {node: '>=18.0.0'} '@smithy/smithy-client@2.5.1': resolution: {integrity: sha512-jrbSQrYCho0yDaaf92qWgd+7nAeap5LtHTI51KXqmpIFCceKU3K9+vIVTUH72bOJngBMqa4kyu1VJhRcSrk/CQ==} engines: {node: '>=14.0.0'} - '@smithy/smithy-client@4.3.0': - resolution: {integrity: sha512-DNsRA38pN6tYHUjebmwD9e4KcgqTLldYQb2gC6K+oxXYdCTxPn6wV9+FvOa6wrU2FQEnGJoi+3GULzOTKck/tg==} + '@smithy/smithy-client@4.4.8': + resolution: {integrity: sha512-pcW691/lx7V54gE+dDGC26nxz8nrvnvRSCJaIYD6XLPpOInEZeKdV/SpSux+wqeQ4Ine7LJQu8uxMvobTIBK0w==} engines: {node: '>=18.0.0'} '@smithy/types@2.12.0': @@ -3293,15 +3312,15 @@ packages: resolution: {integrity: sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg==} engines: {node: '>=16.0.0'} - '@smithy/types@4.3.0': - resolution: {integrity: sha512-+1iaIQHthDh9yaLhRzaoQxRk+l9xlk+JjMFxGRhNLz+m9vKOkjNeU8QuB4w3xvzHyVR/BVlp/4AXDHjoRIkfgQ==} + '@smithy/types@4.3.1': + resolution: {integrity: sha512-UqKOQBL2x6+HWl3P+3QqFD4ncKq0I8Nuz9QItGv5WuKuMHuuwlhvqcZCoXGfc+P1QmfJE7VieykoYYmrOoFJxA==} engines: {node: '>=18.0.0'} '@smithy/url-parser@2.2.0': resolution: {integrity: sha512-hoA4zm61q1mNTpksiSWp2nEl1dt3j726HdRhiNgVJQMj7mLp7dprtF57mOB6JvEk/x9d2bsuL5hlqZbBuHQylQ==} - '@smithy/url-parser@4.0.3': - resolution: {integrity: sha512-n5/DnosDu/tweOqUUNtUbu7eRIR4J/Wz9nL7V5kFYQQVb8VYdj7a4G5NJHCw6o21ul7CvZoJkOpdTnsQDLT0tQ==} + '@smithy/url-parser@4.0.4': + resolution: {integrity: sha512-eMkc144MuN7B0TDA4U2fKs+BqczVbk3W+qIvcoCY6D1JY3hnAdCuhCZODC+GAeaxj0p6Jroz4+XMUn3PCxQQeQ==} engines: {node: '>=18.0.0'} '@smithy/util-base64@2.3.0': @@ -3336,16 +3355,16 @@ packages: resolution: {integrity: sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.0.15': - resolution: {integrity: sha512-bJJ/B8owQbHAflatSq92f9OcV8858DJBQF1Y3GRjB8psLyUjbISywszYPFw16beREHO/C3I3taW4VGH+tOuwrQ==} + '@smithy/util-defaults-mode-browser@4.0.24': + resolution: {integrity: sha512-UkQNgaQ+bidw1MgdgPO1z1k95W/v8Ej/5o/T/Is8PiVUYPspl/ZxV6WO/8DrzZQu5ULnmpB9CDdMSRwgRc21AA==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.0.15': - resolution: {integrity: sha512-8CUrEW2Ni5q+NmYkj8wsgkfqoP7l4ZquptFbq92yQE66xevc4SxqP2zH6tMtN158kgBqBDsZ+qlrRwXWOjCR8A==} + '@smithy/util-defaults-mode-node@4.0.24': + resolution: {integrity: sha512-phvGi/15Z4MpuQibTLOYIumvLdXb+XIJu8TA55voGgboln85jytA3wiD7CkUE8SNcWqkkb+uptZKPiuFouX/7g==} engines: {node: '>=18.0.0'} - '@smithy/util-endpoints@3.0.5': - resolution: {integrity: sha512-PjDpqLk24/vAl340tmtCA++Q01GRRNH9cwL9qh46NspAX9S+IQVcK+GOzPt0GLJ6KYGyn8uOgo2kvJhiThclJw==} + '@smithy/util-endpoints@3.0.6': + resolution: {integrity: sha512-YARl3tFL3WgPuLzljRUnrS2ngLiUtkwhQtj8PAL13XZSyUiNLQxwG3fBBq3QXFqGFUXepIN73pINp3y8c2nBmA==} engines: {node: '>=18.0.0'} '@smithy/util-hex-encoding@2.2.0': @@ -3368,20 +3387,20 @@ packages: resolution: {integrity: sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow==} engines: {node: '>=16.0.0'} - '@smithy/util-middleware@4.0.3': - resolution: {integrity: sha512-iIsC6qZXxkD7V3BzTw3b1uK8RVC1M8WvwNxK1PKrH9FnxntCd30CSunXjL/8iJBE8Z0J14r2P69njwIpRG4FBQ==} + '@smithy/util-middleware@4.0.4': + resolution: {integrity: sha512-9MLKmkBmf4PRb0ONJikCbCwORACcil6gUWojwARCClT7RmLzF04hUR4WdRprIXal7XVyrddadYNfp2eF3nrvtQ==} engines: {node: '>=18.0.0'} - '@smithy/util-retry@4.0.4': - resolution: {integrity: sha512-Aoqr9W2jDYGrI6OxljN8VmLDQIGO4VdMAUKMf9RGqLG8hn6or+K41NEy1Y5dtum9q8F7e0obYAuKl2mt/GnpZg==} + '@smithy/util-retry@4.0.6': + resolution: {integrity: sha512-+YekoF2CaSMv6zKrA6iI/N9yva3Gzn4L6n35Luydweu5MMPYpiGZlWqehPHDHyNbnyaYlz/WJyYAZnC+loBDZg==} engines: {node: '>=18.0.0'} '@smithy/util-stream@2.2.0': resolution: {integrity: sha512-17faEXbYWIRst1aU9SvPZyMdWmqIrduZjVOqCPMIsWFNxs5yQQgFrJL6b2SdiCzyW9mJoDjFtgi53xx7EH+BXA==} engines: {node: '>=14.0.0'} - '@smithy/util-stream@4.2.1': - resolution: {integrity: sha512-W3IR0x5DY6iVtjj5p902oNhD+Bz7vs5S+p6tppbPa509rV9BdeXZjGuRSCtVEad9FA0Mba+tNUtUmtnSI1nwUw==} + '@smithy/util-stream@4.2.3': + resolution: {integrity: sha512-cQn412DWHHFNKrQfbHY8vSFI3nTROY1aIKji9N0tpp8gUABRilr7wdf8fqBbSlXresobM+tQFNk6I+0LXK/YZg==} engines: {node: '>=18.0.0'} '@smithy/util-uri-escape@2.2.0': @@ -5628,6 +5647,10 @@ packages: exsolve@1.0.5: resolution: {integrity: sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==} + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} @@ -5674,14 +5697,14 @@ packages: fast-shallow-equal@1.0.0: resolution: {integrity: sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==} - fast-xml-parser@4.4.1: - resolution: {integrity: sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==} - hasBin: true - fast-xml-parser@5.2.3: resolution: {integrity: sha512-OdCYfRqfpuLUFonTNjvd30rCBZUneHpSQkCqfaeWQ9qrKcl6XlWeDBNVwGb+INAIxRshuN2jF+BE0L6gbBO2mw==} hasBin: true + fast-xml-parser@5.2.5: + resolution: {integrity: sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==} + hasBin: true + fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} @@ -6010,6 +6033,10 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + gtoken@7.1.0: resolution: {integrity: sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==} engines: {node: '>=14.0.0'} @@ -6324,6 +6351,10 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} hasBin: true + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -8416,6 +8447,10 @@ packages: resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==} engines: {node: '>=0.10.0'} + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + seed-random@2.2.0: resolution: {integrity: sha512-34EQV6AAHQGhoc0tn/96a9Fsi6v2xdqe/dMUwljGRaFOzR3EgRmECvD0O8vi8X+/uQ50LGHfkNu/Eue5TPKZkQ==} @@ -8728,6 +8763,10 @@ packages: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -8767,9 +8806,6 @@ packages: strip-literal@3.0.0: resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} - strnum@1.1.2: - resolution: {integrity: sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==} - strnum@2.1.1: resolution: {integrity: sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==} @@ -9753,8 +9789,8 @@ snapshots: dependencies: '@anthropic-ai/sdk': 0.37.0 '@aws-crypto/sha256-js': 4.0.0 - '@aws-sdk/client-bedrock-runtime': 3.817.0 - '@aws-sdk/credential-providers': 3.817.0 + '@aws-sdk/client-bedrock-runtime': 3.848.0 + '@aws-sdk/credential-providers': 3.848.0 '@smithy/eventstream-serde-node': 2.2.0 '@smithy/fetch-http-handler': 2.5.0 '@smithy/protocol-http': 3.3.0 @@ -9797,13 +9833,13 @@ snapshots: '@aws-crypto/crc32@3.0.0': dependencies: '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.804.0 + '@aws-sdk/types': 3.840.0 tslib: 1.14.1 '@aws-crypto/crc32@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.804.0 + '@aws-sdk/types': 3.840.0 tslib: 2.8.1 '@aws-crypto/sha256-browser@5.2.0': @@ -9811,7 +9847,7 @@ snapshots: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.804.0 + '@aws-sdk/types': 3.840.0 '@aws-sdk/util-locate-window': 3.804.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 @@ -9825,7 +9861,7 @@ snapshots: '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.804.0 + '@aws-sdk/types': 3.840.0 tslib: 2.8.1 '@aws-crypto/supports-web-crypto@5.2.0': @@ -9834,67 +9870,69 @@ snapshots: '@aws-crypto/util@3.0.0': dependencies: - '@aws-sdk/types': 3.804.0 + '@aws-sdk/types': 3.840.0 '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 '@aws-crypto/util@4.0.0': dependencies: - '@aws-sdk/types': 3.804.0 + '@aws-sdk/types': 3.840.0 '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.804.0 + '@aws-sdk/types': 3.840.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/client-bedrock-runtime@3.817.0': + '@aws-sdk/client-bedrock-runtime@3.848.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.816.0 - '@aws-sdk/credential-provider-node': 3.817.0 - '@aws-sdk/eventstream-handler-node': 3.804.0 - '@aws-sdk/middleware-eventstream': 3.804.0 - '@aws-sdk/middleware-host-header': 3.804.0 - '@aws-sdk/middleware-logger': 3.804.0 - '@aws-sdk/middleware-recursion-detection': 3.804.0 - '@aws-sdk/middleware-user-agent': 3.816.0 - '@aws-sdk/region-config-resolver': 3.808.0 - '@aws-sdk/types': 3.804.0 - '@aws-sdk/util-endpoints': 3.808.0 - '@aws-sdk/util-user-agent-browser': 3.804.0 - '@aws-sdk/util-user-agent-node': 3.816.0 - '@smithy/config-resolver': 4.1.3 - '@smithy/core': 3.4.0 - '@smithy/eventstream-serde-browser': 4.0.3 - '@smithy/eventstream-serde-config-resolver': 4.1.1 - '@smithy/eventstream-serde-node': 4.0.3 - '@smithy/fetch-http-handler': 5.0.3 - '@smithy/hash-node': 4.0.3 - '@smithy/invalid-dependency': 4.0.3 - '@smithy/middleware-content-length': 4.0.3 - '@smithy/middleware-endpoint': 4.1.7 - '@smithy/middleware-retry': 4.1.8 - '@smithy/middleware-serde': 4.0.6 - '@smithy/middleware-stack': 4.0.3 - '@smithy/node-config-provider': 4.1.2 - '@smithy/node-http-handler': 4.0.5 - '@smithy/protocol-http': 5.1.1 - '@smithy/smithy-client': 4.3.0 - '@smithy/types': 4.3.0 - '@smithy/url-parser': 4.0.3 + '@aws-sdk/core': 3.846.0 + '@aws-sdk/credential-provider-node': 3.848.0 + '@aws-sdk/eventstream-handler-node': 3.840.0 + '@aws-sdk/middleware-eventstream': 3.840.0 + '@aws-sdk/middleware-host-header': 3.840.0 + '@aws-sdk/middleware-logger': 3.840.0 + '@aws-sdk/middleware-recursion-detection': 3.840.0 + '@aws-sdk/middleware-user-agent': 3.848.0 + '@aws-sdk/middleware-websocket': 3.844.0 + '@aws-sdk/region-config-resolver': 3.840.0 + '@aws-sdk/token-providers': 3.848.0 + '@aws-sdk/types': 3.840.0 + '@aws-sdk/util-endpoints': 3.848.0 + '@aws-sdk/util-user-agent-browser': 3.840.0 + '@aws-sdk/util-user-agent-node': 3.848.0 + '@smithy/config-resolver': 4.1.4 + '@smithy/core': 3.7.1 + '@smithy/eventstream-serde-browser': 4.0.4 + '@smithy/eventstream-serde-config-resolver': 4.1.2 + '@smithy/eventstream-serde-node': 4.0.4 + '@smithy/fetch-http-handler': 5.1.0 + '@smithy/hash-node': 4.0.4 + '@smithy/invalid-dependency': 4.0.4 + '@smithy/middleware-content-length': 4.0.4 + '@smithy/middleware-endpoint': 4.1.16 + '@smithy/middleware-retry': 4.1.17 + '@smithy/middleware-serde': 4.0.8 + '@smithy/middleware-stack': 4.0.4 + '@smithy/node-config-provider': 4.1.3 + '@smithy/node-http-handler': 4.1.0 + '@smithy/protocol-http': 5.1.2 + '@smithy/smithy-client': 4.4.8 + '@smithy/types': 4.3.1 + '@smithy/url-parser': 4.0.4 '@smithy/util-base64': 4.0.0 '@smithy/util-body-length-browser': 4.0.0 '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.15 - '@smithy/util-defaults-mode-node': 4.0.15 - '@smithy/util-endpoints': 3.0.5 - '@smithy/util-middleware': 4.0.3 - '@smithy/util-retry': 4.0.4 - '@smithy/util-stream': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.0.24 + '@smithy/util-defaults-mode-node': 4.0.24 + '@smithy/util-endpoints': 3.0.6 + '@smithy/util-middleware': 4.0.4 + '@smithy/util-retry': 4.0.6 + '@smithy/util-stream': 4.2.3 '@smithy/util-utf8': 4.0.0 '@types/uuid': 9.0.8 tslib: 2.8.1 @@ -9902,373 +9940,408 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-cognito-identity@3.817.0': + '@aws-sdk/client-cognito-identity@3.848.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.816.0 - '@aws-sdk/credential-provider-node': 3.817.0 - '@aws-sdk/middleware-host-header': 3.804.0 - '@aws-sdk/middleware-logger': 3.804.0 - '@aws-sdk/middleware-recursion-detection': 3.804.0 - '@aws-sdk/middleware-user-agent': 3.816.0 - '@aws-sdk/region-config-resolver': 3.808.0 - '@aws-sdk/types': 3.804.0 - '@aws-sdk/util-endpoints': 3.808.0 - '@aws-sdk/util-user-agent-browser': 3.804.0 - '@aws-sdk/util-user-agent-node': 3.816.0 - '@smithy/config-resolver': 4.1.3 - '@smithy/core': 3.4.0 - '@smithy/fetch-http-handler': 5.0.3 - '@smithy/hash-node': 4.0.3 - '@smithy/invalid-dependency': 4.0.3 - '@smithy/middleware-content-length': 4.0.3 - '@smithy/middleware-endpoint': 4.1.7 - '@smithy/middleware-retry': 4.1.8 - '@smithy/middleware-serde': 4.0.6 - '@smithy/middleware-stack': 4.0.3 - '@smithy/node-config-provider': 4.1.2 - '@smithy/node-http-handler': 4.0.5 - '@smithy/protocol-http': 5.1.1 - '@smithy/smithy-client': 4.3.0 - '@smithy/types': 4.3.0 - '@smithy/url-parser': 4.0.3 + '@aws-sdk/core': 3.846.0 + '@aws-sdk/credential-provider-node': 3.848.0 + '@aws-sdk/middleware-host-header': 3.840.0 + '@aws-sdk/middleware-logger': 3.840.0 + '@aws-sdk/middleware-recursion-detection': 3.840.0 + '@aws-sdk/middleware-user-agent': 3.848.0 + '@aws-sdk/region-config-resolver': 3.840.0 + '@aws-sdk/types': 3.840.0 + '@aws-sdk/util-endpoints': 3.848.0 + '@aws-sdk/util-user-agent-browser': 3.840.0 + '@aws-sdk/util-user-agent-node': 3.848.0 + '@smithy/config-resolver': 4.1.4 + '@smithy/core': 3.7.1 + '@smithy/fetch-http-handler': 5.1.0 + '@smithy/hash-node': 4.0.4 + '@smithy/invalid-dependency': 4.0.4 + '@smithy/middleware-content-length': 4.0.4 + '@smithy/middleware-endpoint': 4.1.16 + '@smithy/middleware-retry': 4.1.17 + '@smithy/middleware-serde': 4.0.8 + '@smithy/middleware-stack': 4.0.4 + '@smithy/node-config-provider': 4.1.3 + '@smithy/node-http-handler': 4.1.0 + '@smithy/protocol-http': 5.1.2 + '@smithy/smithy-client': 4.4.8 + '@smithy/types': 4.3.1 + '@smithy/url-parser': 4.0.4 '@smithy/util-base64': 4.0.0 '@smithy/util-body-length-browser': 4.0.0 '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.15 - '@smithy/util-defaults-mode-node': 4.0.15 - '@smithy/util-endpoints': 3.0.5 - '@smithy/util-middleware': 4.0.3 - '@smithy/util-retry': 4.0.4 + '@smithy/util-defaults-mode-browser': 4.0.24 + '@smithy/util-defaults-mode-node': 4.0.24 + '@smithy/util-endpoints': 3.0.6 + '@smithy/util-middleware': 4.0.4 + '@smithy/util-retry': 4.0.6 '@smithy/util-utf8': 4.0.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso@3.817.0': + '@aws-sdk/client-sso@3.848.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.816.0 - '@aws-sdk/middleware-host-header': 3.804.0 - '@aws-sdk/middleware-logger': 3.804.0 - '@aws-sdk/middleware-recursion-detection': 3.804.0 - '@aws-sdk/middleware-user-agent': 3.816.0 - '@aws-sdk/region-config-resolver': 3.808.0 - '@aws-sdk/types': 3.804.0 - '@aws-sdk/util-endpoints': 3.808.0 - '@aws-sdk/util-user-agent-browser': 3.804.0 - '@aws-sdk/util-user-agent-node': 3.816.0 - '@smithy/config-resolver': 4.1.3 - '@smithy/core': 3.4.0 - '@smithy/fetch-http-handler': 5.0.3 - '@smithy/hash-node': 4.0.3 - '@smithy/invalid-dependency': 4.0.3 - '@smithy/middleware-content-length': 4.0.3 - '@smithy/middleware-endpoint': 4.1.7 - '@smithy/middleware-retry': 4.1.8 - '@smithy/middleware-serde': 4.0.6 - '@smithy/middleware-stack': 4.0.3 - '@smithy/node-config-provider': 4.1.2 - '@smithy/node-http-handler': 4.0.5 - '@smithy/protocol-http': 5.1.1 - '@smithy/smithy-client': 4.3.0 - '@smithy/types': 4.3.0 - '@smithy/url-parser': 4.0.3 + '@aws-sdk/core': 3.846.0 + '@aws-sdk/middleware-host-header': 3.840.0 + '@aws-sdk/middleware-logger': 3.840.0 + '@aws-sdk/middleware-recursion-detection': 3.840.0 + '@aws-sdk/middleware-user-agent': 3.848.0 + '@aws-sdk/region-config-resolver': 3.840.0 + '@aws-sdk/types': 3.840.0 + '@aws-sdk/util-endpoints': 3.848.0 + '@aws-sdk/util-user-agent-browser': 3.840.0 + '@aws-sdk/util-user-agent-node': 3.848.0 + '@smithy/config-resolver': 4.1.4 + '@smithy/core': 3.7.1 + '@smithy/fetch-http-handler': 5.1.0 + '@smithy/hash-node': 4.0.4 + '@smithy/invalid-dependency': 4.0.4 + '@smithy/middleware-content-length': 4.0.4 + '@smithy/middleware-endpoint': 4.1.16 + '@smithy/middleware-retry': 4.1.17 + '@smithy/middleware-serde': 4.0.8 + '@smithy/middleware-stack': 4.0.4 + '@smithy/node-config-provider': 4.1.3 + '@smithy/node-http-handler': 4.1.0 + '@smithy/protocol-http': 5.1.2 + '@smithy/smithy-client': 4.4.8 + '@smithy/types': 4.3.1 + '@smithy/url-parser': 4.0.4 '@smithy/util-base64': 4.0.0 '@smithy/util-body-length-browser': 4.0.0 '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.15 - '@smithy/util-defaults-mode-node': 4.0.15 - '@smithy/util-endpoints': 3.0.5 - '@smithy/util-middleware': 4.0.3 - '@smithy/util-retry': 4.0.4 + '@smithy/util-defaults-mode-browser': 4.0.24 + '@smithy/util-defaults-mode-node': 4.0.24 + '@smithy/util-endpoints': 3.0.6 + '@smithy/util-middleware': 4.0.4 + '@smithy/util-retry': 4.0.6 '@smithy/util-utf8': 4.0.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.816.0': + '@aws-sdk/core@3.846.0': dependencies: - '@aws-sdk/types': 3.804.0 - '@smithy/core': 3.4.0 - '@smithy/node-config-provider': 4.1.2 - '@smithy/property-provider': 4.0.3 - '@smithy/protocol-http': 5.1.1 - '@smithy/signature-v4': 5.1.1 - '@smithy/smithy-client': 4.3.0 - '@smithy/types': 4.3.0 - '@smithy/util-middleware': 4.0.3 - fast-xml-parser: 4.4.1 + '@aws-sdk/types': 3.840.0 + '@aws-sdk/xml-builder': 3.821.0 + '@smithy/core': 3.7.1 + '@smithy/node-config-provider': 4.1.3 + '@smithy/property-provider': 4.0.4 + '@smithy/protocol-http': 5.1.2 + '@smithy/signature-v4': 5.1.2 + '@smithy/smithy-client': 4.4.8 + '@smithy/types': 4.3.1 + '@smithy/util-base64': 4.0.0 + '@smithy/util-body-length-browser': 4.0.0 + '@smithy/util-middleware': 4.0.4 + '@smithy/util-utf8': 4.0.0 + fast-xml-parser: 5.2.5 tslib: 2.8.1 - '@aws-sdk/credential-provider-cognito-identity@3.817.0': + '@aws-sdk/credential-provider-cognito-identity@3.848.0': dependencies: - '@aws-sdk/client-cognito-identity': 3.817.0 - '@aws-sdk/types': 3.804.0 - '@smithy/property-provider': 4.0.3 - '@smithy/types': 4.3.0 + '@aws-sdk/client-cognito-identity': 3.848.0 + '@aws-sdk/types': 3.840.0 + '@smithy/property-provider': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-env@3.816.0': + '@aws-sdk/credential-provider-env@3.846.0': dependencies: - '@aws-sdk/core': 3.816.0 - '@aws-sdk/types': 3.804.0 - '@smithy/property-provider': 4.0.3 - '@smithy/types': 4.3.0 + '@aws-sdk/core': 3.846.0 + '@aws-sdk/types': 3.840.0 + '@smithy/property-provider': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.816.0': + '@aws-sdk/credential-provider-http@3.846.0': dependencies: - '@aws-sdk/core': 3.816.0 - '@aws-sdk/types': 3.804.0 - '@smithy/fetch-http-handler': 5.0.3 - '@smithy/node-http-handler': 4.0.5 - '@smithy/property-provider': 4.0.3 - '@smithy/protocol-http': 5.1.1 - '@smithy/smithy-client': 4.3.0 - '@smithy/types': 4.3.0 - '@smithy/util-stream': 4.2.1 + '@aws-sdk/core': 3.846.0 + '@aws-sdk/types': 3.840.0 + '@smithy/fetch-http-handler': 5.1.0 + '@smithy/node-http-handler': 4.1.0 + '@smithy/property-provider': 4.0.4 + '@smithy/protocol-http': 5.1.2 + '@smithy/smithy-client': 4.4.8 + '@smithy/types': 4.3.1 + '@smithy/util-stream': 4.2.3 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.817.0': + '@aws-sdk/credential-provider-ini@3.848.0': dependencies: - '@aws-sdk/core': 3.816.0 - '@aws-sdk/credential-provider-env': 3.816.0 - '@aws-sdk/credential-provider-http': 3.816.0 - '@aws-sdk/credential-provider-process': 3.816.0 - '@aws-sdk/credential-provider-sso': 3.817.0 - '@aws-sdk/credential-provider-web-identity': 3.817.0 - '@aws-sdk/nested-clients': 3.817.0 - '@aws-sdk/types': 3.804.0 - '@smithy/credential-provider-imds': 4.0.5 - '@smithy/property-provider': 4.0.3 - '@smithy/shared-ini-file-loader': 4.0.3 - '@smithy/types': 4.3.0 + '@aws-sdk/core': 3.846.0 + '@aws-sdk/credential-provider-env': 3.846.0 + '@aws-sdk/credential-provider-http': 3.846.0 + '@aws-sdk/credential-provider-process': 3.846.0 + '@aws-sdk/credential-provider-sso': 3.848.0 + '@aws-sdk/credential-provider-web-identity': 3.848.0 + '@aws-sdk/nested-clients': 3.848.0 + '@aws-sdk/types': 3.840.0 + '@smithy/credential-provider-imds': 4.0.6 + '@smithy/property-provider': 4.0.4 + '@smithy/shared-ini-file-loader': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.817.0': + '@aws-sdk/credential-provider-node@3.848.0': dependencies: - '@aws-sdk/credential-provider-env': 3.816.0 - '@aws-sdk/credential-provider-http': 3.816.0 - '@aws-sdk/credential-provider-ini': 3.817.0 - '@aws-sdk/credential-provider-process': 3.816.0 - '@aws-sdk/credential-provider-sso': 3.817.0 - '@aws-sdk/credential-provider-web-identity': 3.817.0 - '@aws-sdk/types': 3.804.0 - '@smithy/credential-provider-imds': 4.0.5 - '@smithy/property-provider': 4.0.3 - '@smithy/shared-ini-file-loader': 4.0.3 - '@smithy/types': 4.3.0 + '@aws-sdk/credential-provider-env': 3.846.0 + '@aws-sdk/credential-provider-http': 3.846.0 + '@aws-sdk/credential-provider-ini': 3.848.0 + '@aws-sdk/credential-provider-process': 3.846.0 + '@aws-sdk/credential-provider-sso': 3.848.0 + '@aws-sdk/credential-provider-web-identity': 3.848.0 + '@aws-sdk/types': 3.840.0 + '@smithy/credential-provider-imds': 4.0.6 + '@smithy/property-provider': 4.0.4 + '@smithy/shared-ini-file-loader': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-process@3.816.0': + '@aws-sdk/credential-provider-process@3.846.0': dependencies: - '@aws-sdk/core': 3.816.0 - '@aws-sdk/types': 3.804.0 - '@smithy/property-provider': 4.0.3 - '@smithy/shared-ini-file-loader': 4.0.3 - '@smithy/types': 4.3.0 + '@aws-sdk/core': 3.846.0 + '@aws-sdk/types': 3.840.0 + '@smithy/property-provider': 4.0.4 + '@smithy/shared-ini-file-loader': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.817.0': + '@aws-sdk/credential-provider-sso@3.848.0': dependencies: - '@aws-sdk/client-sso': 3.817.0 - '@aws-sdk/core': 3.816.0 - '@aws-sdk/token-providers': 3.817.0 - '@aws-sdk/types': 3.804.0 - '@smithy/property-provider': 4.0.3 - '@smithy/shared-ini-file-loader': 4.0.3 - '@smithy/types': 4.3.0 + '@aws-sdk/client-sso': 3.848.0 + '@aws-sdk/core': 3.846.0 + '@aws-sdk/token-providers': 3.848.0 + '@aws-sdk/types': 3.840.0 + '@smithy/property-provider': 4.0.4 + '@smithy/shared-ini-file-loader': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.817.0': + '@aws-sdk/credential-provider-web-identity@3.848.0': dependencies: - '@aws-sdk/core': 3.816.0 - '@aws-sdk/nested-clients': 3.817.0 - '@aws-sdk/types': 3.804.0 - '@smithy/property-provider': 4.0.3 - '@smithy/types': 4.3.0 + '@aws-sdk/core': 3.846.0 + '@aws-sdk/nested-clients': 3.848.0 + '@aws-sdk/types': 3.840.0 + '@smithy/property-provider': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-providers@3.817.0': + '@aws-sdk/credential-providers@3.848.0': dependencies: - '@aws-sdk/client-cognito-identity': 3.817.0 - '@aws-sdk/core': 3.816.0 - '@aws-sdk/credential-provider-cognito-identity': 3.817.0 - '@aws-sdk/credential-provider-env': 3.816.0 - '@aws-sdk/credential-provider-http': 3.816.0 - '@aws-sdk/credential-provider-ini': 3.817.0 - '@aws-sdk/credential-provider-node': 3.817.0 - '@aws-sdk/credential-provider-process': 3.816.0 - '@aws-sdk/credential-provider-sso': 3.817.0 - '@aws-sdk/credential-provider-web-identity': 3.817.0 - '@aws-sdk/nested-clients': 3.817.0 - '@aws-sdk/types': 3.804.0 - '@smithy/config-resolver': 4.1.3 - '@smithy/core': 3.4.0 - '@smithy/credential-provider-imds': 4.0.5 - '@smithy/node-config-provider': 4.1.2 - '@smithy/property-provider': 4.0.3 - '@smithy/types': 4.3.0 + '@aws-sdk/client-cognito-identity': 3.848.0 + '@aws-sdk/core': 3.846.0 + '@aws-sdk/credential-provider-cognito-identity': 3.848.0 + '@aws-sdk/credential-provider-env': 3.846.0 + '@aws-sdk/credential-provider-http': 3.846.0 + '@aws-sdk/credential-provider-ini': 3.848.0 + '@aws-sdk/credential-provider-node': 3.848.0 + '@aws-sdk/credential-provider-process': 3.846.0 + '@aws-sdk/credential-provider-sso': 3.848.0 + '@aws-sdk/credential-provider-web-identity': 3.848.0 + '@aws-sdk/nested-clients': 3.848.0 + '@aws-sdk/types': 3.840.0 + '@smithy/config-resolver': 4.1.4 + '@smithy/core': 3.7.1 + '@smithy/credential-provider-imds': 4.0.6 + '@smithy/node-config-provider': 4.1.3 + '@smithy/property-provider': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/eventstream-handler-node@3.804.0': + '@aws-sdk/eventstream-handler-node@3.840.0': dependencies: - '@aws-sdk/types': 3.804.0 - '@smithy/eventstream-codec': 4.0.3 - '@smithy/types': 4.3.0 + '@aws-sdk/types': 3.840.0 + '@smithy/eventstream-codec': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 - '@aws-sdk/middleware-eventstream@3.804.0': + '@aws-sdk/middleware-eventstream@3.840.0': dependencies: - '@aws-sdk/types': 3.804.0 - '@smithy/protocol-http': 5.1.1 - '@smithy/types': 4.3.0 + '@aws-sdk/types': 3.840.0 + '@smithy/protocol-http': 5.1.2 + '@smithy/types': 4.3.1 tslib: 2.8.1 - '@aws-sdk/middleware-host-header@3.804.0': + '@aws-sdk/middleware-host-header@3.840.0': dependencies: - '@aws-sdk/types': 3.804.0 - '@smithy/protocol-http': 5.1.1 - '@smithy/types': 4.3.0 + '@aws-sdk/types': 3.840.0 + '@smithy/protocol-http': 5.1.2 + '@smithy/types': 4.3.1 tslib: 2.8.1 - '@aws-sdk/middleware-logger@3.804.0': + '@aws-sdk/middleware-logger@3.840.0': dependencies: - '@aws-sdk/types': 3.804.0 - '@smithy/types': 4.3.0 + '@aws-sdk/types': 3.840.0 + '@smithy/types': 4.3.1 tslib: 2.8.1 - '@aws-sdk/middleware-recursion-detection@3.804.0': + '@aws-sdk/middleware-recursion-detection@3.840.0': dependencies: - '@aws-sdk/types': 3.804.0 - '@smithy/protocol-http': 5.1.1 - '@smithy/types': 4.3.0 + '@aws-sdk/types': 3.840.0 + '@smithy/protocol-http': 5.1.2 + '@smithy/types': 4.3.1 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.816.0': + '@aws-sdk/middleware-user-agent@3.848.0': dependencies: - '@aws-sdk/core': 3.816.0 - '@aws-sdk/types': 3.804.0 - '@aws-sdk/util-endpoints': 3.808.0 - '@smithy/core': 3.4.0 - '@smithy/protocol-http': 5.1.1 - '@smithy/types': 4.3.0 + '@aws-sdk/core': 3.846.0 + '@aws-sdk/types': 3.840.0 + '@aws-sdk/util-endpoints': 3.848.0 + '@smithy/core': 3.7.1 + '@smithy/protocol-http': 5.1.2 + '@smithy/types': 4.3.1 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.817.0': + '@aws-sdk/middleware-websocket@3.844.0': + dependencies: + '@aws-sdk/types': 3.840.0 + '@aws-sdk/util-format-url': 3.840.0 + '@smithy/eventstream-codec': 4.0.4 + '@smithy/eventstream-serde-browser': 4.0.4 + '@smithy/fetch-http-handler': 5.1.0 + '@smithy/protocol-http': 5.1.2 + '@smithy/signature-v4': 5.1.2 + '@smithy/types': 4.3.1 + '@smithy/util-hex-encoding': 4.0.0 + tslib: 2.8.1 + + '@aws-sdk/nested-clients@3.848.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.816.0 - '@aws-sdk/middleware-host-header': 3.804.0 - '@aws-sdk/middleware-logger': 3.804.0 - '@aws-sdk/middleware-recursion-detection': 3.804.0 - '@aws-sdk/middleware-user-agent': 3.816.0 - '@aws-sdk/region-config-resolver': 3.808.0 - '@aws-sdk/types': 3.804.0 - '@aws-sdk/util-endpoints': 3.808.0 - '@aws-sdk/util-user-agent-browser': 3.804.0 - '@aws-sdk/util-user-agent-node': 3.816.0 - '@smithy/config-resolver': 4.1.3 - '@smithy/core': 3.4.0 - '@smithy/fetch-http-handler': 5.0.3 - '@smithy/hash-node': 4.0.3 - '@smithy/invalid-dependency': 4.0.3 - '@smithy/middleware-content-length': 4.0.3 - '@smithy/middleware-endpoint': 4.1.7 - '@smithy/middleware-retry': 4.1.8 - '@smithy/middleware-serde': 4.0.6 - '@smithy/middleware-stack': 4.0.3 - '@smithy/node-config-provider': 4.1.2 - '@smithy/node-http-handler': 4.0.5 - '@smithy/protocol-http': 5.1.1 - '@smithy/smithy-client': 4.3.0 - '@smithy/types': 4.3.0 - '@smithy/url-parser': 4.0.3 + '@aws-sdk/core': 3.846.0 + '@aws-sdk/middleware-host-header': 3.840.0 + '@aws-sdk/middleware-logger': 3.840.0 + '@aws-sdk/middleware-recursion-detection': 3.840.0 + '@aws-sdk/middleware-user-agent': 3.848.0 + '@aws-sdk/region-config-resolver': 3.840.0 + '@aws-sdk/types': 3.840.0 + '@aws-sdk/util-endpoints': 3.848.0 + '@aws-sdk/util-user-agent-browser': 3.840.0 + '@aws-sdk/util-user-agent-node': 3.848.0 + '@smithy/config-resolver': 4.1.4 + '@smithy/core': 3.7.1 + '@smithy/fetch-http-handler': 5.1.0 + '@smithy/hash-node': 4.0.4 + '@smithy/invalid-dependency': 4.0.4 + '@smithy/middleware-content-length': 4.0.4 + '@smithy/middleware-endpoint': 4.1.16 + '@smithy/middleware-retry': 4.1.17 + '@smithy/middleware-serde': 4.0.8 + '@smithy/middleware-stack': 4.0.4 + '@smithy/node-config-provider': 4.1.3 + '@smithy/node-http-handler': 4.1.0 + '@smithy/protocol-http': 5.1.2 + '@smithy/smithy-client': 4.4.8 + '@smithy/types': 4.3.1 + '@smithy/url-parser': 4.0.4 '@smithy/util-base64': 4.0.0 '@smithy/util-body-length-browser': 4.0.0 '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.15 - '@smithy/util-defaults-mode-node': 4.0.15 - '@smithy/util-endpoints': 3.0.5 - '@smithy/util-middleware': 4.0.3 - '@smithy/util-retry': 4.0.4 + '@smithy/util-defaults-mode-browser': 4.0.24 + '@smithy/util-defaults-mode-node': 4.0.24 + '@smithy/util-endpoints': 3.0.6 + '@smithy/util-middleware': 4.0.4 + '@smithy/util-retry': 4.0.6 '@smithy/util-utf8': 4.0.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/region-config-resolver@3.808.0': + '@aws-sdk/region-config-resolver@3.840.0': dependencies: - '@aws-sdk/types': 3.804.0 - '@smithy/node-config-provider': 4.1.2 - '@smithy/types': 4.3.0 + '@aws-sdk/types': 3.840.0 + '@smithy/node-config-provider': 4.1.3 + '@smithy/types': 4.3.1 '@smithy/util-config-provider': 4.0.0 - '@smithy/util-middleware': 4.0.3 + '@smithy/util-middleware': 4.0.4 tslib: 2.8.1 - '@aws-sdk/token-providers@3.817.0': + '@aws-sdk/token-providers@3.848.0': dependencies: - '@aws-sdk/core': 3.816.0 - '@aws-sdk/nested-clients': 3.817.0 - '@aws-sdk/types': 3.804.0 - '@smithy/property-provider': 4.0.3 - '@smithy/shared-ini-file-loader': 4.0.3 - '@smithy/types': 4.3.0 + '@aws-sdk/core': 3.846.0 + '@aws-sdk/nested-clients': 3.848.0 + '@aws-sdk/types': 3.840.0 + '@smithy/property-provider': 4.0.4 + '@smithy/shared-ini-file-loader': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt '@aws-sdk/types@3.804.0': dependencies: - '@smithy/types': 4.3.0 + '@smithy/types': 4.3.1 tslib: 2.8.1 - '@aws-sdk/util-endpoints@3.808.0': + '@aws-sdk/types@3.840.0': dependencies: - '@aws-sdk/types': 3.804.0 - '@smithy/types': 4.3.0 - '@smithy/util-endpoints': 3.0.5 + '@smithy/types': 4.3.1 + tslib: 2.8.1 + + '@aws-sdk/util-endpoints@3.848.0': + dependencies: + '@aws-sdk/types': 3.840.0 + '@smithy/types': 4.3.1 + '@smithy/url-parser': 4.0.4 + '@smithy/util-endpoints': 3.0.6 + tslib: 2.8.1 + + '@aws-sdk/util-format-url@3.840.0': + dependencies: + '@aws-sdk/types': 3.840.0 + '@smithy/querystring-builder': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@aws-sdk/util-locate-window@3.804.0': dependencies: tslib: 2.8.1 - '@aws-sdk/util-user-agent-browser@3.804.0': + '@aws-sdk/util-user-agent-browser@3.840.0': dependencies: - '@aws-sdk/types': 3.804.0 - '@smithy/types': 4.3.0 + '@aws-sdk/types': 3.840.0 + '@smithy/types': 4.3.1 bowser: 2.11.0 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.816.0': + '@aws-sdk/util-user-agent-node@3.848.0': dependencies: - '@aws-sdk/middleware-user-agent': 3.816.0 - '@aws-sdk/types': 3.804.0 - '@smithy/node-config-provider': 4.1.2 - '@smithy/types': 4.3.0 + '@aws-sdk/middleware-user-agent': 3.848.0 + '@aws-sdk/types': 3.840.0 + '@smithy/node-config-provider': 4.1.3 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@aws-sdk/util-utf8-browser@3.259.0': dependencies: tslib: 2.8.1 + '@aws-sdk/xml-builder@3.821.0': + dependencies: + '@smithy/types': 4.3.1 + tslib: 2.8.1 + '@azure/abort-controller@2.1.2': dependencies: tslib: 2.8.1 @@ -12133,36 +12206,37 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.8.1 - '@smithy/abort-controller@4.0.3': + '@smithy/abort-controller@4.0.4': dependencies: - '@smithy/types': 4.3.0 + '@smithy/types': 4.3.1 tslib: 2.8.1 - '@smithy/config-resolver@4.1.3': + '@smithy/config-resolver@4.1.4': dependencies: - '@smithy/node-config-provider': 4.1.2 - '@smithy/types': 4.3.0 + '@smithy/node-config-provider': 4.1.3 + '@smithy/types': 4.3.1 '@smithy/util-config-provider': 4.0.0 - '@smithy/util-middleware': 4.0.3 + '@smithy/util-middleware': 4.0.4 tslib: 2.8.1 - '@smithy/core@3.4.0': + '@smithy/core@3.7.1': dependencies: - '@smithy/middleware-serde': 4.0.6 - '@smithy/protocol-http': 5.1.1 - '@smithy/types': 4.3.0 + '@smithy/middleware-serde': 4.0.8 + '@smithy/protocol-http': 5.1.2 + '@smithy/types': 4.3.1 + '@smithy/util-base64': 4.0.0 '@smithy/util-body-length-browser': 4.0.0 - '@smithy/util-middleware': 4.0.3 - '@smithy/util-stream': 4.2.1 + '@smithy/util-middleware': 4.0.4 + '@smithy/util-stream': 4.2.3 '@smithy/util-utf8': 4.0.0 tslib: 2.8.1 - '@smithy/credential-provider-imds@4.0.5': + '@smithy/credential-provider-imds@4.0.6': dependencies: - '@smithy/node-config-provider': 4.1.2 - '@smithy/property-provider': 4.0.3 - '@smithy/types': 4.3.0 - '@smithy/url-parser': 4.0.3 + '@smithy/node-config-provider': 4.1.3 + '@smithy/property-provider': 4.0.4 + '@smithy/types': 4.3.1 + '@smithy/url-parser': 4.0.4 tslib: 2.8.1 '@smithy/eventstream-codec@2.2.0': @@ -12172,22 +12246,22 @@ snapshots: '@smithy/util-hex-encoding': 2.2.0 tslib: 2.8.1 - '@smithy/eventstream-codec@4.0.3': + '@smithy/eventstream-codec@4.0.4': dependencies: '@aws-crypto/crc32': 5.2.0 - '@smithy/types': 4.3.0 + '@smithy/types': 4.3.1 '@smithy/util-hex-encoding': 4.0.0 tslib: 2.8.1 - '@smithy/eventstream-serde-browser@4.0.3': + '@smithy/eventstream-serde-browser@4.0.4': dependencies: - '@smithy/eventstream-serde-universal': 4.0.3 - '@smithy/types': 4.3.0 + '@smithy/eventstream-serde-universal': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 - '@smithy/eventstream-serde-config-resolver@4.1.1': + '@smithy/eventstream-serde-config-resolver@4.1.2': dependencies: - '@smithy/types': 4.3.0 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@smithy/eventstream-serde-node@2.2.0': @@ -12196,10 +12270,10 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.8.1 - '@smithy/eventstream-serde-node@4.0.3': + '@smithy/eventstream-serde-node@4.0.4': dependencies: - '@smithy/eventstream-serde-universal': 4.0.3 - '@smithy/types': 4.3.0 + '@smithy/eventstream-serde-universal': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@smithy/eventstream-serde-universal@2.2.0': @@ -12208,10 +12282,10 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.8.1 - '@smithy/eventstream-serde-universal@4.0.3': + '@smithy/eventstream-serde-universal@4.0.4': dependencies: - '@smithy/eventstream-codec': 4.0.3 - '@smithy/types': 4.3.0 + '@smithy/eventstream-codec': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@smithy/fetch-http-handler@2.5.0': @@ -12222,24 +12296,24 @@ snapshots: '@smithy/util-base64': 2.3.0 tslib: 2.8.1 - '@smithy/fetch-http-handler@5.0.3': + '@smithy/fetch-http-handler@5.1.0': dependencies: - '@smithy/protocol-http': 5.1.1 - '@smithy/querystring-builder': 4.0.3 - '@smithy/types': 4.3.0 + '@smithy/protocol-http': 5.1.2 + '@smithy/querystring-builder': 4.0.4 + '@smithy/types': 4.3.1 '@smithy/util-base64': 4.0.0 tslib: 2.8.1 - '@smithy/hash-node@4.0.3': + '@smithy/hash-node@4.0.4': dependencies: - '@smithy/types': 4.3.0 + '@smithy/types': 4.3.1 '@smithy/util-buffer-from': 4.0.0 '@smithy/util-utf8': 4.0.0 tslib: 2.8.1 - '@smithy/invalid-dependency@4.0.3': + '@smithy/invalid-dependency@4.0.4': dependencies: - '@smithy/types': 4.3.0 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@smithy/is-array-buffer@2.2.0': @@ -12254,10 +12328,10 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/middleware-content-length@4.0.3': + '@smithy/middleware-content-length@4.0.4': dependencies: - '@smithy/protocol-http': 5.1.1 - '@smithy/types': 4.3.0 + '@smithy/protocol-http': 5.1.2 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@smithy/middleware-endpoint@2.5.1': @@ -12270,26 +12344,26 @@ snapshots: '@smithy/util-middleware': 2.2.0 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.1.7': + '@smithy/middleware-endpoint@4.1.16': dependencies: - '@smithy/core': 3.4.0 - '@smithy/middleware-serde': 4.0.6 - '@smithy/node-config-provider': 4.1.2 - '@smithy/shared-ini-file-loader': 4.0.3 - '@smithy/types': 4.3.0 - '@smithy/url-parser': 4.0.3 - '@smithy/util-middleware': 4.0.3 + '@smithy/core': 3.7.1 + '@smithy/middleware-serde': 4.0.8 + '@smithy/node-config-provider': 4.1.3 + '@smithy/shared-ini-file-loader': 4.0.4 + '@smithy/types': 4.3.1 + '@smithy/url-parser': 4.0.4 + '@smithy/util-middleware': 4.0.4 tslib: 2.8.1 - '@smithy/middleware-retry@4.1.8': + '@smithy/middleware-retry@4.1.17': dependencies: - '@smithy/node-config-provider': 4.1.2 - '@smithy/protocol-http': 5.1.1 - '@smithy/service-error-classification': 4.0.4 - '@smithy/smithy-client': 4.3.0 - '@smithy/types': 4.3.0 - '@smithy/util-middleware': 4.0.3 - '@smithy/util-retry': 4.0.4 + '@smithy/node-config-provider': 4.1.3 + '@smithy/protocol-http': 5.1.2 + '@smithy/service-error-classification': 4.0.6 + '@smithy/smithy-client': 4.4.8 + '@smithy/types': 4.3.1 + '@smithy/util-middleware': 4.0.4 + '@smithy/util-retry': 4.0.6 tslib: 2.8.1 uuid: 9.0.1 @@ -12298,10 +12372,10 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.8.1 - '@smithy/middleware-serde@4.0.6': + '@smithy/middleware-serde@4.0.8': dependencies: - '@smithy/protocol-http': 5.1.1 - '@smithy/types': 4.3.0 + '@smithy/protocol-http': 5.1.2 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@smithy/middleware-stack@2.2.0': @@ -12309,9 +12383,9 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.8.1 - '@smithy/middleware-stack@4.0.3': + '@smithy/middleware-stack@4.0.4': dependencies: - '@smithy/types': 4.3.0 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@smithy/node-config-provider@2.3.0': @@ -12321,11 +12395,11 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.8.1 - '@smithy/node-config-provider@4.1.2': + '@smithy/node-config-provider@4.1.3': dependencies: - '@smithy/property-provider': 4.0.3 - '@smithy/shared-ini-file-loader': 4.0.3 - '@smithy/types': 4.3.0 + '@smithy/property-provider': 4.0.4 + '@smithy/shared-ini-file-loader': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@smithy/node-http-handler@2.5.0': @@ -12336,12 +12410,12 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.8.1 - '@smithy/node-http-handler@4.0.5': + '@smithy/node-http-handler@4.1.0': dependencies: - '@smithy/abort-controller': 4.0.3 - '@smithy/protocol-http': 5.1.1 - '@smithy/querystring-builder': 4.0.3 - '@smithy/types': 4.3.0 + '@smithy/abort-controller': 4.0.4 + '@smithy/protocol-http': 5.1.2 + '@smithy/querystring-builder': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@smithy/property-provider@2.2.0': @@ -12349,9 +12423,9 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.8.1 - '@smithy/property-provider@4.0.3': + '@smithy/property-provider@4.0.4': dependencies: - '@smithy/types': 4.3.0 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@smithy/protocol-http@3.3.0': @@ -12359,9 +12433,9 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.8.1 - '@smithy/protocol-http@5.1.1': + '@smithy/protocol-http@5.1.2': dependencies: - '@smithy/types': 4.3.0 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@smithy/querystring-builder@2.2.0': @@ -12370,9 +12444,9 @@ snapshots: '@smithy/util-uri-escape': 2.2.0 tslib: 2.8.1 - '@smithy/querystring-builder@4.0.3': + '@smithy/querystring-builder@4.0.4': dependencies: - '@smithy/types': 4.3.0 + '@smithy/types': 4.3.1 '@smithy/util-uri-escape': 4.0.0 tslib: 2.8.1 @@ -12381,23 +12455,23 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.8.1 - '@smithy/querystring-parser@4.0.3': + '@smithy/querystring-parser@4.0.4': dependencies: - '@smithy/types': 4.3.0 + '@smithy/types': 4.3.1 tslib: 2.8.1 - '@smithy/service-error-classification@4.0.4': + '@smithy/service-error-classification@4.0.6': dependencies: - '@smithy/types': 4.3.0 + '@smithy/types': 4.3.1 '@smithy/shared-ini-file-loader@2.4.0': dependencies: '@smithy/types': 2.12.0 tslib: 2.8.1 - '@smithy/shared-ini-file-loader@4.0.3': + '@smithy/shared-ini-file-loader@4.0.4': dependencies: - '@smithy/types': 4.3.0 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@smithy/signature-v4@3.1.2': @@ -12410,13 +12484,13 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.8.1 - '@smithy/signature-v4@5.1.1': + '@smithy/signature-v4@5.1.2': dependencies: '@smithy/is-array-buffer': 4.0.0 - '@smithy/protocol-http': 5.1.1 - '@smithy/types': 4.3.0 + '@smithy/protocol-http': 5.1.2 + '@smithy/types': 4.3.1 '@smithy/util-hex-encoding': 4.0.0 - '@smithy/util-middleware': 4.0.3 + '@smithy/util-middleware': 4.0.4 '@smithy/util-uri-escape': 4.0.0 '@smithy/util-utf8': 4.0.0 tslib: 2.8.1 @@ -12430,14 +12504,14 @@ snapshots: '@smithy/util-stream': 2.2.0 tslib: 2.8.1 - '@smithy/smithy-client@4.3.0': + '@smithy/smithy-client@4.4.8': dependencies: - '@smithy/core': 3.4.0 - '@smithy/middleware-endpoint': 4.1.7 - '@smithy/middleware-stack': 4.0.3 - '@smithy/protocol-http': 5.1.1 - '@smithy/types': 4.3.0 - '@smithy/util-stream': 4.2.1 + '@smithy/core': 3.7.1 + '@smithy/middleware-endpoint': 4.1.16 + '@smithy/middleware-stack': 4.0.4 + '@smithy/protocol-http': 5.1.2 + '@smithy/types': 4.3.1 + '@smithy/util-stream': 4.2.3 tslib: 2.8.1 '@smithy/types@2.12.0': @@ -12448,7 +12522,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/types@4.3.0': + '@smithy/types@4.3.1': dependencies: tslib: 2.8.1 @@ -12458,10 +12532,10 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.8.1 - '@smithy/url-parser@4.0.3': + '@smithy/url-parser@4.0.4': dependencies: - '@smithy/querystring-parser': 4.0.3 - '@smithy/types': 4.3.0 + '@smithy/querystring-parser': 4.0.4 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@smithy/util-base64@2.3.0': @@ -12503,28 +12577,28 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.0.15': + '@smithy/util-defaults-mode-browser@4.0.24': dependencies: - '@smithy/property-provider': 4.0.3 - '@smithy/smithy-client': 4.3.0 - '@smithy/types': 4.3.0 + '@smithy/property-provider': 4.0.4 + '@smithy/smithy-client': 4.4.8 + '@smithy/types': 4.3.1 bowser: 2.11.0 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.0.15': + '@smithy/util-defaults-mode-node@4.0.24': dependencies: - '@smithy/config-resolver': 4.1.3 - '@smithy/credential-provider-imds': 4.0.5 - '@smithy/node-config-provider': 4.1.2 - '@smithy/property-provider': 4.0.3 - '@smithy/smithy-client': 4.3.0 - '@smithy/types': 4.3.0 + '@smithy/config-resolver': 4.1.4 + '@smithy/credential-provider-imds': 4.0.6 + '@smithy/node-config-provider': 4.1.3 + '@smithy/property-provider': 4.0.4 + '@smithy/smithy-client': 4.4.8 + '@smithy/types': 4.3.1 tslib: 2.8.1 - '@smithy/util-endpoints@3.0.5': + '@smithy/util-endpoints@3.0.6': dependencies: - '@smithy/node-config-provider': 4.1.2 - '@smithy/types': 4.3.0 + '@smithy/node-config-provider': 4.1.3 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@smithy/util-hex-encoding@2.2.0': @@ -12549,15 +12623,15 @@ snapshots: '@smithy/types': 3.7.2 tslib: 2.8.1 - '@smithy/util-middleware@4.0.3': + '@smithy/util-middleware@4.0.4': dependencies: - '@smithy/types': 4.3.0 + '@smithy/types': 4.3.1 tslib: 2.8.1 - '@smithy/util-retry@4.0.4': + '@smithy/util-retry@4.0.6': dependencies: - '@smithy/service-error-classification': 4.0.4 - '@smithy/types': 4.3.0 + '@smithy/service-error-classification': 4.0.6 + '@smithy/types': 4.3.1 tslib: 2.8.1 '@smithy/util-stream@2.2.0': @@ -12571,11 +12645,11 @@ snapshots: '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@smithy/util-stream@4.2.1': + '@smithy/util-stream@4.2.3': dependencies: - '@smithy/fetch-http-handler': 5.0.3 - '@smithy/node-http-handler': 4.0.5 - '@smithy/types': 4.3.0 + '@smithy/fetch-http-handler': 5.1.0 + '@smithy/node-http-handler': 4.1.0 + '@smithy/types': 4.3.1 '@smithy/util-base64': 4.0.0 '@smithy/util-buffer-from': 4.0.0 '@smithy/util-hex-encoding': 4.0.0 @@ -15123,6 +15197,10 @@ snapshots: exsolve@1.0.5: {} + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + extend@3.0.2: {} extendable-error@0.1.7: {} @@ -15176,14 +15254,14 @@ snapshots: fast-shallow-equal@1.0.0: {} - fast-xml-parser@4.4.1: - dependencies: - strnum: 1.1.2 - fast-xml-parser@5.2.3: dependencies: strnum: 2.1.1 + fast-xml-parser@5.2.5: + dependencies: + strnum: 2.1.1 + fastest-levenshtein@1.0.16: {} fastest-stable-stringify@2.0.2: {} @@ -15546,6 +15624,13 @@ snapshots: graphemer@1.4.0: {} + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.1 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + gtoken@7.1.0: dependencies: gaxios: 6.7.1 @@ -15908,6 +15993,8 @@ snapshots: is-docker@3.0.0: {} + is-extendable@0.1.1: {} + is-extglob@2.1.1: {} is-finalizationregistry@1.1.1: @@ -18428,6 +18515,11 @@ snapshots: screenfull@5.2.0: {} + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + seed-random@2.2.0: {} semver@5.7.2: {} @@ -18822,6 +18914,8 @@ snapshots: dependencies: ansi-regex: 6.1.0 + strip-bom-string@1.0.0: {} + strip-bom@3.0.0: {} strip-bom@5.0.0: {} @@ -18847,8 +18941,6 @@ snapshots: dependencies: js-tokens: 9.0.1 - strnum@1.1.2: {} - strnum@2.1.1: {} strong-type@0.1.6: {} diff --git a/src/__tests__/command-integration.spec.ts b/src/__tests__/command-integration.spec.ts new file mode 100644 index 0000000000..e884325b68 --- /dev/null +++ b/src/__tests__/command-integration.spec.ts @@ -0,0 +1,56 @@ +import { describe, it, expect } from "vitest" +import { getCommands, getCommand, getCommandNames } from "../services/command/commands" +import * as path from "path" + +describe("Command Integration Tests", () => { + const testWorkspaceDir = path.join(__dirname, "../../") + + it("should discover command files in .roo/commands/", async () => { + const commands = await getCommands(testWorkspaceDir) + + // Should be able to discover commands (may be empty in test environment) + expect(Array.isArray(commands)).toBe(true) + + // If commands exist, verify they have valid properties + commands.forEach((command) => { + expect(command.name).toBeDefined() + expect(typeof command.name).toBe("string") + expect(command.source).toMatch(/^(project|global)$/) + expect(command.content).toBeDefined() + expect(typeof command.content).toBe("string") + }) + }) + + it("should return command names correctly", async () => { + const commandNames = await getCommandNames(testWorkspaceDir) + + // Should return an array (may be empty in test environment) + expect(Array.isArray(commandNames)).toBe(true) + + // If command names exist, they should be strings + commandNames.forEach((name) => { + expect(typeof name).toBe("string") + expect(name.length).toBeGreaterThan(0) + }) + }) + + it("should load command content if commands exist", async () => { + const commands = await getCommands(testWorkspaceDir) + + if (commands.length > 0) { + const firstCommand = commands[0] + const loadedCommand = await getCommand(testWorkspaceDir, firstCommand.name) + + expect(loadedCommand).toBeDefined() + expect(loadedCommand?.name).toBe(firstCommand.name) + expect(loadedCommand?.source).toMatch(/^(project|global)$/) + expect(loadedCommand?.content).toBeDefined() + expect(typeof loadedCommand?.content).toBe("string") + } + }) + + it("should handle non-existent commands gracefully", async () => { + const nonExistentCommand = await getCommand(testWorkspaceDir, "non-existent-command") + expect(nonExistentCommand).toBeUndefined() + }) +}) diff --git a/src/__tests__/command-mentions.spec.ts b/src/__tests__/command-mentions.spec.ts new file mode 100644 index 0000000000..d4de0bbba7 --- /dev/null +++ b/src/__tests__/command-mentions.spec.ts @@ -0,0 +1,307 @@ +import { describe, it, expect, beforeEach, vi } from "vitest" +import { parseMentions } from "../core/mentions" +import { UrlContentFetcher } from "../services/browser/UrlContentFetcher" +import { getCommand } from "../services/command/commands" + +// Mock the dependencies +vi.mock("../services/command/commands") +vi.mock("../services/browser/UrlContentFetcher") + +const MockedUrlContentFetcher = vi.mocked(UrlContentFetcher) +const mockGetCommand = vi.mocked(getCommand) + +describe("Command Mentions", () => { + let mockUrlContentFetcher: any + + beforeEach(() => { + vi.clearAllMocks() + + // Create a mock UrlContentFetcher instance + mockUrlContentFetcher = { + launchBrowser: vi.fn(), + urlToMarkdown: vi.fn(), + closeBrowser: vi.fn(), + } + + MockedUrlContentFetcher.mockImplementation(() => mockUrlContentFetcher) + }) + + // Helper function to call parseMentions with required parameters + const callParseMentions = async (text: string) => { + return await parseMentions( + text, + "/test/cwd", // cwd + mockUrlContentFetcher, // urlContentFetcher + undefined, // fileContextTracker + undefined, // rooIgnoreController + true, // showRooIgnoredFiles + true, // includeDiagnosticMessages + 50, // maxDiagnosticMessages + undefined, // maxReadFileLine + ) + } + + describe("parseMentions with command support", () => { + it("should parse command mentions and include content", async () => { + const commandContent = "# Setup Environment\n\nRun the following commands:\n```bash\nnpm install\n```" + mockGetCommand.mockResolvedValue({ + name: "setup", + content: commandContent, + source: "project", + filePath: "/project/.roo/commands/setup.md", + }) + + const input = "/setup Please help me set up the project" + const result = await callParseMentions(input) + + expect(mockGetCommand).toHaveBeenCalledWith("/test/cwd", "setup") + expect(result).toContain('') + expect(result).toContain(commandContent) + expect(result).toContain("") + expect(result).toContain("Please help me set up the project") + }) + + it("should handle multiple commands in message", async () => { + mockGetCommand + .mockResolvedValueOnce({ + name: "setup", + content: "# Setup instructions", + source: "project", + filePath: "/project/.roo/commands/setup.md", + }) + .mockResolvedValueOnce({ + name: "deploy", + content: "# Deploy instructions", + source: "project", + filePath: "/project/.roo/commands/deploy.md", + }) + + // Both commands should be recognized + const input = "/setup the project\nThen /deploy later" + const result = await callParseMentions(input) + + expect(mockGetCommand).toHaveBeenCalledWith("/test/cwd", "setup") + expect(mockGetCommand).toHaveBeenCalledWith("/test/cwd", "deploy") + expect(mockGetCommand).toHaveBeenCalledTimes(2) // Both commands called + expect(result).toContain('') + expect(result).toContain("# Setup instructions") + expect(result).toContain('') + expect(result).toContain("# Deploy instructions") + }) + + it("should handle non-existent command gracefully", async () => { + mockGetCommand.mockResolvedValue(undefined) + + const input = "/nonexistent command" + const result = await callParseMentions(input) + + expect(mockGetCommand).toHaveBeenCalledWith("/test/cwd", "nonexistent") + expect(result).toContain('') + expect(result).toContain("Command 'nonexistent' not found") + expect(result).toContain("") + }) + + it("should handle command loading errors", async () => { + mockGetCommand.mockRejectedValue(new Error("Failed to load command")) + + const input = "/error-command test" + const result = await callParseMentions(input) + + expect(result).toContain('') + expect(result).toContain("Error loading command") + expect(result).toContain("") + }) + + it("should handle command names with hyphens and underscores at start", async () => { + mockGetCommand.mockResolvedValue({ + name: "setup-dev", + content: "# Dev setup", + source: "project", + filePath: "/project/.roo/commands/setup-dev.md", + }) + + const input = "/setup-dev for the project" + const result = await callParseMentions(input) + + expect(mockGetCommand).toHaveBeenCalledWith("/test/cwd", "setup-dev") + expect(result).toContain('') + expect(result).toContain("# Dev setup") + }) + + it("should preserve command content formatting", async () => { + const commandContent = `# Complex Command + +## Step 1 +Run this command: +\`\`\`bash +npm install +\`\`\` + +## Step 2 +- Check file1.js +- Update file2.ts +- Test everything + +> **Note**: This is important!` + + mockGetCommand.mockResolvedValue({ + name: "complex", + content: commandContent, + source: "project", + filePath: "/project/.roo/commands/complex.md", + }) + + const input = "/complex command" + const result = await callParseMentions(input) + + expect(result).toContain('') + expect(result).toContain("# Complex Command") + expect(result).toContain("```bash") + expect(result).toContain("npm install") + expect(result).toContain("- Check file1.js") + expect(result).toContain("> **Note**: This is important!") + expect(result).toContain("") + }) + + it("should handle empty command content", async () => { + mockGetCommand.mockResolvedValue({ + name: "empty", + content: "", + source: "project", + filePath: "/project/.roo/commands/empty.md", + }) + + const input = "/empty command" + const result = await callParseMentions(input) + + expect(result).toContain('') + expect(result).toContain("") + // Should still include the command tags even with empty content + }) + }) + + describe("command mention regex patterns", () => { + it("should match valid command mention patterns anywhere", () => { + const commandRegex = /\/([a-zA-Z0-9_\.-]+)(?=\s|$)/g + + const validPatterns = ["/setup", "/build-prod", "/test_suite", "/my-command", "/command123"] + + validPatterns.forEach((pattern) => { + const match = pattern.match(commandRegex) + expect(match).toBeTruthy() + expect(match![0]).toBe(pattern) + }) + }) + + it("should match command patterns in middle of text", () => { + const commandRegex = /\/([a-zA-Z0-9_\.-]+)(?=\s|$)/g + + const validPatterns = ["Please /setup", "Run /build now", "Use /deploy here"] + + validPatterns.forEach((pattern) => { + const match = pattern.match(commandRegex) + expect(match).toBeTruthy() + expect(match![0]).toMatch(/^\/[a-zA-Z0-9_\.-]+$/) + }) + }) + + it("should match commands at start of new lines", () => { + const commandRegex = /\/([a-zA-Z0-9_\.-]+)(?=\s|$)/g + + const multilineText = "First line\n/setup the project\nAnother line\n/deploy when ready" + const matches = multilineText.match(commandRegex) + + // Should match both commands now + expect(matches).toBeTruthy() + expect(matches).toHaveLength(2) + expect(matches![0]).toBe("/setup") + expect(matches![1]).toBe("/deploy") + }) + + it("should match multiple commands in message", () => { + const commandRegex = /(?:^|\s)\/([a-zA-Z0-9_\.-]+)(?=\s|$)/g + + const validText = "/setup the project\nThen /deploy later" + const matches = validText.match(commandRegex) + + expect(matches).toBeTruthy() + expect(matches).toHaveLength(2) + expect(matches![0]).toBe("/setup") + expect(matches![1]).toBe(" /deploy") // Note: includes leading space + }) + + it("should not match invalid command patterns", () => { + const commandRegex = /\/([a-zA-Z0-9_\.-]+)(?=\s|$)/g + + const invalidPatterns = ["/ space", "/with space", "/with/slash", "//double", "/with@symbol"] + + invalidPatterns.forEach((pattern) => { + const match = pattern.match(commandRegex) + if (match) { + // If it matches, it should not be the full invalid pattern + expect(match[0]).not.toBe(pattern) + } + }) + }) + }) + + describe("command mention text transformation", () => { + it("should transform command mentions at start of message", async () => { + const input = "/setup the project" + const result = await callParseMentions(input) + + expect(result).toContain("Command 'setup' (see below for command content)") + }) + + it("should process multiple commands in message", async () => { + mockGetCommand + .mockResolvedValueOnce({ + name: "setup", + content: "# Setup instructions", + source: "project", + filePath: "/project/.roo/commands/setup.md", + }) + .mockResolvedValueOnce({ + name: "deploy", + content: "# Deploy instructions", + source: "project", + filePath: "/project/.roo/commands/deploy.md", + }) + + const input = "/setup the project\nThen /deploy later" + const result = await callParseMentions(input) + + expect(result).toContain("Command 'setup' (see below for command content)") + expect(result).toContain("Command 'deploy' (see below for command content)") + }) + + it("should match commands anywhere with proper word boundaries", async () => { + mockGetCommand.mockResolvedValue({ + name: "build", + content: "# Build instructions", + source: "project", + filePath: "/project/.roo/commands/build.md", + }) + + // At the beginning - should match + let input = "/build the project" + let result = await callParseMentions(input) + expect(result).toContain("Command 'build'") + + // After space - should match + input = "Please /build and test" + result = await callParseMentions(input) + expect(result).toContain("Command 'build'") + + // At the end - should match + input = "Run the /build" + result = await callParseMentions(input) + expect(result).toContain("Command 'build'") + + // At start of new line - should match + input = "Some text\n/build the project" + result = await callParseMentions(input) + expect(result).toContain("Command 'build'") + }) + }) +}) diff --git a/src/__tests__/commands.spec.ts b/src/__tests__/commands.spec.ts new file mode 100644 index 0000000000..9401050062 --- /dev/null +++ b/src/__tests__/commands.spec.ts @@ -0,0 +1,97 @@ +import { describe, it, expect } from "vitest" +import { + getCommands, + getCommand, + getCommandNames, + getCommandNameFromFile, + isMarkdownFile, +} from "../services/command/commands" + +describe("Command Utilities", () => { + const testCwd = "/test/project" + + describe("getCommandNameFromFile", () => { + it("should strip .md extension only", () => { + expect(getCommandNameFromFile("my-command.md")).toBe("my-command") + expect(getCommandNameFromFile("test.txt")).toBe("test.txt") + expect(getCommandNameFromFile("no-extension")).toBe("no-extension") + expect(getCommandNameFromFile("multiple.dots.file.md")).toBe("multiple.dots.file") + expect(getCommandNameFromFile("api.config.md")).toBe("api.config") + expect(getCommandNameFromFile("deploy_prod.md")).toBe("deploy_prod") + }) + }) + + describe("isMarkdownFile", () => { + it("should identify markdown files correctly", () => { + // Markdown files + expect(isMarkdownFile("command.md")).toBe(true) + expect(isMarkdownFile("my-command.md")).toBe(true) + expect(isMarkdownFile("README.MD")).toBe(true) + expect(isMarkdownFile("test.Md")).toBe(true) + + // Non-markdown files + expect(isMarkdownFile("command.txt")).toBe(false) + expect(isMarkdownFile("script.sh")).toBe(false) + expect(isMarkdownFile("config.json")).toBe(false) + expect(isMarkdownFile("no-extension")).toBe(false) + expect(isMarkdownFile("file.md.bak")).toBe(false) + }) + }) + + describe("getCommands", () => { + it("should return empty array when no command directories exist", async () => { + // This will fail to find directories but should return empty array gracefully + const commands = await getCommands(testCwd) + expect(Array.isArray(commands)).toBe(true) + }) + }) + + describe("getCommandNames", () => { + it("should return empty array when no commands exist", async () => { + const names = await getCommandNames(testCwd) + expect(Array.isArray(names)).toBe(true) + }) + }) + + describe("getCommand", () => { + it("should return undefined for non-existent command", async () => { + const result = await getCommand(testCwd, "non-existent") + expect(result).toBeUndefined() + }) + }) + + describe("command name extraction edge cases", () => { + it("should handle various filename formats", () => { + // Files without extensions + expect(getCommandNameFromFile("command")).toBe("command") + expect(getCommandNameFromFile("my-command")).toBe("my-command") + + // Files with multiple dots - only strip .md extension + expect(getCommandNameFromFile("my.complex.command.md")).toBe("my.complex.command") + expect(getCommandNameFromFile("v1.2.3.txt")).toBe("v1.2.3.txt") + + // Edge cases + expect(getCommandNameFromFile(".")).toBe(".") + expect(getCommandNameFromFile("..")).toBe("..") + expect(getCommandNameFromFile(".hidden.md")).toBe(".hidden") + }) + }) + + describe("command loading behavior", () => { + it("should handle multiple calls to getCommands", async () => { + const commands1 = await getCommands(testCwd) + const commands2 = await getCommands(testCwd) + expect(Array.isArray(commands1)).toBe(true) + expect(Array.isArray(commands2)).toBe(true) + }) + }) + + describe("error handling", () => { + it("should handle invalid command names gracefully", async () => { + // These should not throw errors + expect(await getCommand(testCwd, "")).toBeUndefined() + expect(await getCommand(testCwd, " ")).toBeUndefined() + expect(await getCommand(testCwd, "non/existent/path")).toBeUndefined() + }) + }) +}) diff --git a/src/api/huggingface-models.ts b/src/api/huggingface-models.ts deleted file mode 100644 index ec1915d0e3..0000000000 --- a/src/api/huggingface-models.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { fetchHuggingFaceModels, type HuggingFaceModel } from "../services/huggingface-models" - -export interface HuggingFaceModelsResponse { - models: HuggingFaceModel[] - cached: boolean - timestamp: number -} - -export async function getHuggingFaceModels(): Promise { - const models = await fetchHuggingFaceModels() - - return { - models, - cached: false, // We could enhance this to track if data came from cache - timestamp: Date.now(), - } -} diff --git a/src/api/providers/__tests__/bedrock-inference-profiles.spec.ts b/src/api/providers/__tests__/bedrock-inference-profiles.spec.ts index 7eef16d241..16ee002e20 100644 --- a/src/api/providers/__tests__/bedrock-inference-profiles.spec.ts +++ b/src/api/providers/__tests__/bedrock-inference-profiles.spec.ts @@ -16,7 +16,7 @@ vitest.mock("@aws-sdk/client-bedrock-runtime", () => { } }) -describe("AWS Bedrock Inference Profiles", () => { +describe("Amazon Bedrock Inference Profiles", () => { // Helper function to create a handler with specific options const createHandler = (options: Partial = {}) => { const defaultOptions: ApiHandlerOptions = { diff --git a/src/api/providers/__tests__/bedrock-reasoning.spec.ts b/src/api/providers/__tests__/bedrock-reasoning.spec.ts index f11a27fa96..f8d9beb0eb 100644 --- a/src/api/providers/__tests__/bedrock-reasoning.spec.ts +++ b/src/api/providers/__tests__/bedrock-reasoning.spec.ts @@ -278,5 +278,51 @@ describe("AwsBedrockHandler - Extended Thinking", () => { expect(reasoningChunks[0].text).toBe("Let me think...") expect(reasoningChunks[1].text).toBe(" about this problem.") }) + + it("should support API key authentication", async () => { + handler = new AwsBedrockHandler({ + apiProvider: "bedrock", + apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", + awsRegion: "us-east-1", + awsUseApiKey: true, + awsApiKey: "test-api-key-token", + }) + + mockSend.mockResolvedValue({ + stream: (async function* () { + yield { messageStart: { role: "assistant" } } + yield { + contentBlockStart: { + start: { text: "Hello from API key auth" }, + contentBlockIndex: 0, + }, + } + yield { metadata: { usage: { inputTokens: 100, outputTokens: 50 } } } + })(), + }) + + const messages = [{ role: "user" as const, content: "Test message" }] + const stream = handler.createMessage("System prompt", messages) + + const chunks = [] + for await (const chunk of stream) { + chunks.push(chunk) + } + + // Verify the client was created with API key token + expect(BedrockRuntimeClient).toHaveBeenCalledWith( + expect.objectContaining({ + region: "us-east-1", + token: { token: "test-api-key-token" }, + authSchemePreference: ["httpBearerAuth"], + }), + ) + + // Verify the stream worked correctly + expect(mockSend).toHaveBeenCalledTimes(1) + const textChunks = chunks.filter((c) => c.type === "text") + expect(textChunks).toHaveLength(1) + expect(textChunks[0].text).toBe("Hello from API key auth") + }) }) }) diff --git a/src/api/providers/__tests__/bedrock-vpc-endpoint.spec.ts b/src/api/providers/__tests__/bedrock-vpc-endpoint.spec.ts index ca8329ec11..7823775bea 100644 --- a/src/api/providers/__tests__/bedrock-vpc-endpoint.spec.ts +++ b/src/api/providers/__tests__/bedrock-vpc-endpoint.spec.ts @@ -29,7 +29,7 @@ import { BedrockRuntimeClient } from "@aws-sdk/client-bedrock-runtime" // Get access to the mocked functions const mockBedrockRuntimeClient = vi.mocked(BedrockRuntimeClient) -describe("AWS Bedrock VPC Endpoint Functionality", () => { +describe("Amazon Bedrock VPC Endpoint Functionality", () => { beforeEach(() => { // Clear all mocks before each test vi.clearAllMocks() diff --git a/src/api/providers/__tests__/gemini-handler.spec.ts b/src/api/providers/__tests__/gemini-handler.spec.ts new file mode 100644 index 0000000000..7c61639cfd --- /dev/null +++ b/src/api/providers/__tests__/gemini-handler.spec.ts @@ -0,0 +1,137 @@ +import { describe, it, expect, vi } from "vitest" +import { t } from "i18next" +import { GeminiHandler } from "../gemini" +import type { ApiHandlerOptions } from "../../../shared/api" + +describe("GeminiHandler backend support", () => { + it("passes tools for URL context and grounding in config", async () => { + const options = { + apiProvider: "gemini", + enableUrlContext: true, + enableGrounding: true, + } as ApiHandlerOptions + const handler = new GeminiHandler(options) + const stub = vi.fn().mockReturnValue((async function* () {})()) + // @ts-ignore access private client + handler["client"].models.generateContentStream = stub + await handler.createMessage("instr", [] as any).next() + const config = stub.mock.calls[0][0].config + expect(config.tools).toEqual([{ urlContext: {} }, { googleSearch: {} }]) + }) + + it("completePrompt passes config overrides without tools when URL context and grounding disabled", async () => { + const options = { + apiProvider: "gemini", + enableUrlContext: false, + enableGrounding: false, + } as ApiHandlerOptions + const handler = new GeminiHandler(options) + const stub = vi.fn().mockResolvedValue({ text: "ok" }) + // @ts-ignore access private client + handler["client"].models.generateContent = stub + const res = await handler.completePrompt("hi") + expect(res).toBe("ok") + const promptConfig = stub.mock.calls[0][0].config + expect(promptConfig.tools).toBeUndefined() + }) + + describe("error scenarios", () => { + it("should handle grounding metadata extraction failure gracefully", async () => { + const options = { + apiProvider: "gemini", + enableGrounding: true, + } as ApiHandlerOptions + const handler = new GeminiHandler(options) + + const mockStream = async function* () { + yield { + candidates: [ + { + groundingMetadata: { + // Invalid structure - missing groundingChunks + }, + content: { parts: [{ text: "test response" }] }, + }, + ], + usageMetadata: { promptTokenCount: 10, candidatesTokenCount: 5 }, + } + } + + const stub = vi.fn().mockReturnValue(mockStream()) + // @ts-ignore access private client + handler["client"].models.generateContentStream = stub + + const messages = [] + for await (const chunk of handler.createMessage("test", [] as any)) { + messages.push(chunk) + } + + // Should still return the main content without sources + expect(messages.some((m) => m.type === "text" && m.text === "test response")).toBe(true) + expect(messages.some((m) => m.type === "text" && m.text?.includes("Sources:"))).toBe(false) + }) + + it("should handle malformed grounding metadata", async () => { + const options = { + apiProvider: "gemini", + enableGrounding: true, + } as ApiHandlerOptions + const handler = new GeminiHandler(options) + + const mockStream = async function* () { + yield { + candidates: [ + { + groundingMetadata: { + groundingChunks: [ + { web: null }, // Missing URI + { web: { uri: "https://example.com" } }, // Valid + {}, // Missing web property entirely + ], + }, + content: { parts: [{ text: "test response" }] }, + }, + ], + usageMetadata: { promptTokenCount: 10, candidatesTokenCount: 5 }, + } + } + + const stub = vi.fn().mockReturnValue(mockStream()) + // @ts-ignore access private client + handler["client"].models.generateContentStream = stub + + const messages = [] + for await (const chunk of handler.createMessage("test", [] as any)) { + messages.push(chunk) + } + + // Should only include valid citations + const sourceMessage = messages.find((m) => m.type === "text" && m.text?.includes("[2]")) + expect(sourceMessage).toBeDefined() + if (sourceMessage && "text" in sourceMessage) { + expect(sourceMessage.text).toContain("https://example.com") + expect(sourceMessage.text).not.toContain("[1]") + expect(sourceMessage.text).not.toContain("[3]") + } + }) + + it("should handle API errors when tools are enabled", async () => { + const options = { + apiProvider: "gemini", + enableUrlContext: true, + enableGrounding: true, + } as ApiHandlerOptions + const handler = new GeminiHandler(options) + + const mockError = new Error("API rate limit exceeded") + const stub = vi.fn().mockRejectedValue(mockError) + // @ts-ignore access private client + handler["client"].models.generateContentStream = stub + + await expect(async () => { + const generator = handler.createMessage("test", [] as any) + await generator.next() + }).rejects.toThrow(t("common:errors.gemini.generate_stream", { error: "API rate limit exceeded" })) + }) + }) +}) diff --git a/src/api/providers/__tests__/gemini.spec.ts b/src/api/providers/__tests__/gemini.spec.ts index 8a7fd24fe3..812c1ae1a6 100644 --- a/src/api/providers/__tests__/gemini.spec.ts +++ b/src/api/providers/__tests__/gemini.spec.ts @@ -4,6 +4,7 @@ import { Anthropic } from "@anthropic-ai/sdk" import { type ModelInfo, geminiDefaultModelId } from "@roo-code/types" +import { t } from "i18next" import { GeminiHandler } from "../gemini" const GEMINI_20_FLASH_THINKING_NAME = "gemini-2.0-flash-thinking-exp-1219" @@ -129,7 +130,7 @@ describe("GeminiHandler", () => { ;(handler["client"].models.generateContent as any).mockRejectedValue(mockError) await expect(handler.completePrompt("Test prompt")).rejects.toThrow( - "Gemini completion error: Gemini API error", + t("common:errors.gemini.generate_complete_prompt", { error: "Gemini API error" }), ) }) diff --git a/src/api/providers/__tests__/lite-llm.spec.ts b/src/api/providers/__tests__/lite-llm.spec.ts new file mode 100644 index 0000000000..26ebbc3525 --- /dev/null +++ b/src/api/providers/__tests__/lite-llm.spec.ts @@ -0,0 +1,158 @@ +import { describe, it, expect, vi, beforeEach } from "vitest" +import OpenAI from "openai" +import { Anthropic } from "@anthropic-ai/sdk" + +import { LiteLLMHandler } from "../lite-llm" +import { ApiHandlerOptions } from "../../../shared/api" +import { litellmDefaultModelId, litellmDefaultModelInfo } from "@roo-code/types" + +// Mock vscode first to avoid import errors +vi.mock("vscode", () => ({})) + +// Mock OpenAI +vi.mock("openai", () => { + const mockStream = { + [Symbol.asyncIterator]: vi.fn(), + } + + const mockCreate = vi.fn().mockReturnValue({ + withResponse: vi.fn().mockResolvedValue({ data: mockStream }), + }) + + return { + default: vi.fn().mockImplementation(() => ({ + chat: { + completions: { + create: mockCreate, + }, + }, + })), + } +}) + +// Mock model fetching +vi.mock("../fetchers/modelCache", () => ({ + getModels: vi.fn().mockImplementation(() => { + return Promise.resolve({ + [litellmDefaultModelId]: litellmDefaultModelInfo, + }) + }), +})) + +describe("LiteLLMHandler", () => { + let handler: LiteLLMHandler + let mockOptions: ApiHandlerOptions + let mockOpenAIClient: any + + beforeEach(() => { + vi.clearAllMocks() + mockOptions = { + litellmApiKey: "test-key", + litellmBaseUrl: "http://localhost:4000", + litellmModelId: litellmDefaultModelId, + } + handler = new LiteLLMHandler(mockOptions) + mockOpenAIClient = new OpenAI() + }) + + describe("prompt caching", () => { + it("should add cache control headers when litellmUsePromptCache is enabled", async () => { + const optionsWithCache: ApiHandlerOptions = { + ...mockOptions, + litellmUsePromptCache: true, + } + handler = new LiteLLMHandler(optionsWithCache) + + const systemPrompt = "You are a helpful assistant" + const messages: Anthropic.Messages.MessageParam[] = [ + { role: "user", content: "Hello" }, + { role: "assistant", content: "Hi there!" }, + { role: "user", content: "How are you?" }, + ] + + // Mock the stream response + const mockStream = { + async *[Symbol.asyncIterator]() { + yield { + choices: [{ delta: { content: "I'm doing well!" } }], + usage: { + prompt_tokens: 100, + completion_tokens: 50, + cache_creation_input_tokens: 20, + cache_read_input_tokens: 30, + }, + } + }, + } + + mockOpenAIClient.chat.completions.create.mockReturnValue({ + withResponse: vi.fn().mockResolvedValue({ data: mockStream }), + }) + + const generator = handler.createMessage(systemPrompt, messages) + const results = [] + for await (const chunk of generator) { + results.push(chunk) + } + + // Verify that create was called with cache control headers + const createCall = mockOpenAIClient.chat.completions.create.mock.calls[0][0] + + // Check system message has cache control in the proper format + expect(createCall.messages[0]).toMatchObject({ + role: "system", + content: [ + { + type: "text", + text: systemPrompt, + cache_control: { type: "ephemeral" }, + }, + ], + }) + + // Check that the last two user messages have cache control + const userMessageIndices = createCall.messages + .map((msg: any, idx: number) => (msg.role === "user" ? idx : -1)) + .filter((idx: number) => idx !== -1) + + const lastUserIdx = userMessageIndices[userMessageIndices.length - 1] + const secondLastUserIdx = userMessageIndices[userMessageIndices.length - 2] + + // Check last user message has proper structure with cache control + expect(createCall.messages[lastUserIdx]).toMatchObject({ + role: "user", + content: [ + { + type: "text", + text: "How are you?", + cache_control: { type: "ephemeral" }, + }, + ], + }) + + // Check second last user message (first user message in this case) + if (secondLastUserIdx !== -1) { + expect(createCall.messages[secondLastUserIdx]).toMatchObject({ + role: "user", + content: [ + { + type: "text", + text: "Hello", + cache_control: { type: "ephemeral" }, + }, + ], + }) + } + + // Verify usage includes cache tokens + const usageChunk = results.find((chunk) => chunk.type === "usage") + expect(usageChunk).toMatchObject({ + type: "usage", + inputTokens: 100, + outputTokens: 50, + cacheWriteTokens: 20, + cacheReadTokens: 30, + }) + }) + }) +}) diff --git a/src/api/providers/__tests__/vertex.spec.ts b/src/api/providers/__tests__/vertex.spec.ts index 8e9add524d..d147e79ba8 100644 --- a/src/api/providers/__tests__/vertex.spec.ts +++ b/src/api/providers/__tests__/vertex.spec.ts @@ -7,6 +7,7 @@ import { Anthropic } from "@anthropic-ai/sdk" import { ApiStreamChunk } from "../../transform/stream" +import { t } from "i18next" import { VertexHandler } from "../vertex" describe("VertexHandler", () => { @@ -105,7 +106,7 @@ describe("VertexHandler", () => { ;(handler["client"].models.generateContent as any).mockRejectedValue(mockError) await expect(handler.completePrompt("Test prompt")).rejects.toThrow( - "Gemini completion error: Vertex API error", + t("common:errors.gemini.generate_complete_prompt", { error: "Vertex API error" }), ) }) diff --git a/src/api/providers/bedrock.ts b/src/api/providers/bedrock.ts index a25fea5200..76e502e6c7 100644 --- a/src/api/providers/bedrock.ts +++ b/src/api/providers/bedrock.ts @@ -222,7 +222,11 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH this.options.awsBedrockEndpointEnabled && { endpoint: this.options.awsBedrockEndpoint }), } - if (this.options.awsUseProfile && this.options.awsProfile) { + if (this.options.awsUseApiKey && this.options.awsApiKey) { + // Use API key/token-based authentication if enabled and API key is set + clientConfig.token = { token: this.options.awsApiKey } + clientConfig.authSchemePreference = ["httpBearerAuth"] // Otherwise there's no end of credential problems. + } else if (this.options.awsUseProfile && this.options.awsProfile) { // Use profile-based credentials if enabled and profile is set clientConfig.credentials = fromIni({ profile: this.options.awsProfile, @@ -1078,7 +1082,7 @@ Please verify: "throttl", "rate", "limit", - "bedrock is unable to process your request", // AWS Bedrock specific throttling message + "bedrock is unable to process your request", // Amazon Bedrock specific throttling message "please wait", "quota exceeded", "service unavailable", @@ -1124,7 +1128,7 @@ Suggestions: Please try: 1. Contact AWS support to request a quota increase 2. Reduce request frequency temporarily -3. Check your AWS Bedrock quotas in the AWS console +3. Check your Amazon Bedrock quotas in the AWS console 4. Consider using a different model or region with available capacity `, @@ -1139,7 +1143,7 @@ Please try: Please try: 1. Wait a few minutes and retry -2. Check the model status in AWS Bedrock console +2. Check the model status in Amazon Bedrock console 3. Verify the model is properly provisioned `, @@ -1147,7 +1151,7 @@ Please try: }, INTERNAL_SERVER_ERROR: { patterns: ["internal server error", "internal error", "server error", "service error"], - messageTemplate: `AWS Bedrock internal server error. This is a temporary service issue. + messageTemplate: `Amazon Bedrock internal server error. This is a temporary service issue. Please try: 1. Retry the request after a brief delay @@ -1184,7 +1188,7 @@ Please try: ], messageTemplate: `Parameter validation error: {errorMessage} -This error indicates that the request parameters don't match AWS Bedrock's expected format. +This error indicates that the request parameters don't match Amazon Bedrock's expected format. Common causes: 1. Extended thinking parameter format is incorrect @@ -1193,7 +1197,7 @@ Common causes: Please check: - Model supports the requested features (extended thinking, etc.) -- Parameter format matches AWS Bedrock specification +- Parameter format matches Amazon Bedrock specification - Model ID is correct for the requested features`, logLevel: "error", }, @@ -1218,7 +1222,7 @@ Please check: return "THROTTLING" } - // Check for AWS Bedrock specific throttling exception names + // Check for Amazon Bedrock specific throttling exception names if ((error as any).name === "ThrottlingException" || (error as any).__type === "ThrottlingException") { return "THROTTLING" } diff --git a/src/api/providers/fetchers/huggingface.ts b/src/api/providers/fetchers/huggingface.ts new file mode 100644 index 0000000000..7a45c74535 --- /dev/null +++ b/src/api/providers/fetchers/huggingface.ts @@ -0,0 +1,290 @@ +import axios from "axios" +import { z } from "zod" +import type { ModelInfo } from "@roo-code/types" +import { + HUGGINGFACE_API_URL, + HUGGINGFACE_CACHE_DURATION, + HUGGINGFACE_DEFAULT_MAX_TOKENS, + HUGGINGFACE_DEFAULT_CONTEXT_WINDOW, +} from "@roo-code/types" +import type { ModelRecord } from "../../../shared/api" + +/** + * HuggingFace Provider Schema + */ +const huggingFaceProviderSchema = z.object({ + provider: z.string(), + status: z.enum(["live", "staging", "error"]), + supports_tools: z.boolean().optional(), + supports_structured_output: z.boolean().optional(), + context_length: z.number().optional(), + pricing: z + .object({ + input: z.number(), + output: z.number(), + }) + .optional(), +}) + +/** + * Represents a provider that can serve a HuggingFace model + * @property provider - The provider identifier (e.g., "sambanova", "together") + * @property status - The current status of the provider + * @property supports_tools - Whether the provider supports tool/function calling + * @property supports_structured_output - Whether the provider supports structured output + * @property context_length - The maximum context length supported by this provider + * @property pricing - The pricing information for input/output tokens + */ +export type HuggingFaceProvider = z.infer + +/** + * HuggingFace Model Schema + */ +const huggingFaceModelSchema = z.object({ + id: z.string(), + object: z.literal("model"), + created: z.number(), + owned_by: z.string(), + providers: z.array(huggingFaceProviderSchema), +}) + +/** + * Represents a HuggingFace model available through the router API + * @property id - The unique identifier of the model + * @property object - The object type (always "model") + * @property created - Unix timestamp of when the model was created + * @property owned_by - The organization that owns the model + * @property providers - List of providers that can serve this model + */ +export type HuggingFaceModel = z.infer + +/** + * HuggingFace API Response Schema + */ +const huggingFaceApiResponseSchema = z.object({ + object: z.string(), + data: z.array(huggingFaceModelSchema), +}) + +/** + * Represents the response from the HuggingFace router API + * @property object - The response object type + * @property data - Array of available models + */ +type HuggingFaceApiResponse = z.infer + +/** + * Cache entry for storing fetched models + * @property data - The cached model records + * @property timestamp - Unix timestamp of when the cache was last updated + */ +interface CacheEntry { + data: ModelRecord + rawModels?: HuggingFaceModel[] + timestamp: number +} + +let cache: CacheEntry | null = null + +/** + * Parse a HuggingFace model into ModelInfo format + * @param model - The HuggingFace model to parse + * @param provider - Optional specific provider to use for capabilities + * @returns ModelInfo object compatible with the application's model system + */ +function parseHuggingFaceModel(model: HuggingFaceModel, provider?: HuggingFaceProvider): ModelInfo { + // Use provider-specific values if available, otherwise find first provider with values + const contextLength = + provider?.context_length || + model.providers.find((p) => p.context_length)?.context_length || + HUGGINGFACE_DEFAULT_CONTEXT_WINDOW + + const pricing = provider?.pricing || model.providers.find((p) => p.pricing)?.pricing + + // Include provider name in description if specific provider is given + const description = provider ? `${model.id} via ${provider.provider}` : `${model.id} via HuggingFace` + + return { + maxTokens: Math.min(contextLength, HUGGINGFACE_DEFAULT_MAX_TOKENS), + contextWindow: contextLength, + supportsImages: false, // HuggingFace API doesn't provide this info yet + supportsPromptCache: false, + supportsComputerUse: false, + inputPrice: pricing?.input, + outputPrice: pricing?.output, + description, + } +} + +/** + * Fetches available models from HuggingFace + * + * @returns A promise that resolves to a record of model IDs to model info + * @throws Will throw an error if the request fails + */ +export async function getHuggingFaceModels(): Promise { + const now = Date.now() + + // Check cache + if (cache && now - cache.timestamp < HUGGINGFACE_CACHE_DURATION) { + return cache.data + } + + const models: ModelRecord = {} + + try { + const response = await axios.get(HUGGINGFACE_API_URL, { + headers: { + "Upgrade-Insecure-Requests": "1", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + Priority: "u=0, i", + Pragma: "no-cache", + "Cache-Control": "no-cache", + }, + timeout: 10000, // 10 second timeout + }) + + const result = huggingFaceApiResponseSchema.safeParse(response.data) + + if (!result.success) { + console.error("HuggingFace models response validation failed:", result.error.format()) + throw new Error("Invalid response format from HuggingFace API") + } + + const validModels = result.data.data.filter((model) => model.providers.length > 0) + + for (const model of validModels) { + // Add the base model + models[model.id] = parseHuggingFaceModel(model) + + // Add provider-specific variants for all live providers + for (const provider of model.providers) { + if (provider.status === "live") { + const providerKey = `${model.id}:${provider.provider}` + const providerModel = parseHuggingFaceModel(model, provider) + + // Always add provider variants to show all available providers + models[providerKey] = providerModel + } + } + } + + // Update cache + cache = { + data: models, + rawModels: validModels, + timestamp: now, + } + + return models + } catch (error) { + console.error("Error fetching HuggingFace models:", error) + + // Return cached data if available + if (cache) { + return cache.data + } + + // Re-throw with more context + if (axios.isAxiosError(error)) { + if (error.response) { + throw new Error( + `Failed to fetch HuggingFace models: ${error.response.status} ${error.response.statusText}`, + ) + } else if (error.request) { + throw new Error( + "Failed to fetch HuggingFace models: No response from server. Check your internet connection.", + ) + } + } + + throw new Error( + `Failed to fetch HuggingFace models: ${error instanceof Error ? error.message : "Unknown error"}`, + ) + } +} + +/** + * Get cached models without making an API request + */ +export function getCachedHuggingFaceModels(): ModelRecord | null { + return cache?.data || null +} + +/** + * Get cached raw models for UI display + */ +export function getCachedRawHuggingFaceModels(): HuggingFaceModel[] | null { + return cache?.rawModels || null +} + +/** + * Clear the cache + */ +export function clearHuggingFaceCache(): void { + cache = null +} + +/** + * HuggingFace Models Response Interface + */ +export interface HuggingFaceModelsResponse { + models: HuggingFaceModel[] + cached: boolean + timestamp: number +} + +/** + * Get HuggingFace models with response metadata + * This function provides a higher-level API that includes cache status and timestamp + */ +export async function getHuggingFaceModelsWithMetadata(): Promise { + try { + // First, trigger the fetch to populate cache + await getHuggingFaceModels() + + // Get the raw models from cache + const cachedRawModels = getCachedRawHuggingFaceModels() + + if (cachedRawModels) { + return { + models: cachedRawModels, + cached: true, + timestamp: Date.now(), + } + } + + // If no cached raw models, fetch directly from API + const response = await axios.get(HUGGINGFACE_API_URL, { + headers: { + "Upgrade-Insecure-Requests": "1", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + Priority: "u=0, i", + Pragma: "no-cache", + "Cache-Control": "no-cache", + }, + timeout: 10000, + }) + + const models = response.data?.data || [] + + return { + models, + cached: false, + timestamp: Date.now(), + } + } catch (error) { + console.error("Failed to get HuggingFace models:", error) + return { + models: [], + cached: false, + timestamp: Date.now(), + } + } +} diff --git a/src/api/providers/gemini.ts b/src/api/providers/gemini.ts index 6765c8676d..5e547edbdc 100644 --- a/src/api/providers/gemini.ts +++ b/src/api/providers/gemini.ts @@ -4,6 +4,7 @@ import { type GenerateContentResponseUsageMetadata, type GenerateContentParameters, type GenerateContentConfig, + type GroundingMetadata, } from "@google/genai" import type { JWTInput } from "google-auth-library" @@ -13,6 +14,7 @@ import type { ApiHandlerOptions } from "../../shared/api" import { safeJsonParse } from "../../shared/safeJsonParse" import { convertAnthropicContentToGemini, convertAnthropicMessageToGemini } from "../transform/gemini-format" +import { t } from "i18next" import type { ApiStream } from "../transform/stream" import { getModelParams } from "../transform/model-params" @@ -67,72 +69,103 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl const contents = messages.map(convertAnthropicMessageToGemini) + const tools: GenerateContentConfig["tools"] = [] + if (this.options.enableUrlContext) { + tools.push({ urlContext: {} }) + } + + if (this.options.enableGrounding) { + tools.push({ googleSearch: {} }) + } + const config: GenerateContentConfig = { systemInstruction, httpOptions: this.options.googleGeminiBaseUrl ? { baseUrl: this.options.googleGeminiBaseUrl } : undefined, thinkingConfig, maxOutputTokens: this.options.modelMaxTokens ?? maxTokens ?? undefined, temperature: this.options.modelTemperature ?? 0, + ...(tools.length > 0 ? { tools } : {}), } const params: GenerateContentParameters = { model, contents, config } - const result = await this.client.models.generateContentStream(params) + try { + const result = await this.client.models.generateContentStream(params) - let lastUsageMetadata: GenerateContentResponseUsageMetadata | undefined + let lastUsageMetadata: GenerateContentResponseUsageMetadata | undefined + let pendingGroundingMetadata: GroundingMetadata | undefined - for await (const chunk of result) { - // Process candidates and their parts to separate thoughts from content - if (chunk.candidates && chunk.candidates.length > 0) { - const candidate = chunk.candidates[0] - if (candidate.content && candidate.content.parts) { - for (const part of candidate.content.parts) { - if (part.thought) { - // This is a thinking/reasoning part - if (part.text) { - yield { type: "reasoning", text: part.text } - } - } else { - // This is regular content - if (part.text) { - yield { type: "text", text: part.text } + for await (const chunk of result) { + // Process candidates and their parts to separate thoughts from content + if (chunk.candidates && chunk.candidates.length > 0) { + const candidate = chunk.candidates[0] + + if (candidate.groundingMetadata) { + pendingGroundingMetadata = candidate.groundingMetadata + } + + if (candidate.content && candidate.content.parts) { + for (const part of candidate.content.parts) { + if (part.thought) { + // This is a thinking/reasoning part + if (part.text) { + yield { type: "reasoning", text: part.text } + } + } else { + // This is regular content + if (part.text) { + yield { type: "text", text: part.text } + } } } } } + + // Fallback to the original text property if no candidates structure + else if (chunk.text) { + yield { type: "text", text: chunk.text } + } + + if (chunk.usageMetadata) { + lastUsageMetadata = chunk.usageMetadata + } } - // Fallback to the original text property if no candidates structure - else if (chunk.text) { - yield { type: "text", text: chunk.text } + if (pendingGroundingMetadata) { + const citations = this.extractCitationsOnly(pendingGroundingMetadata) + if (citations) { + yield { type: "text", text: `\n\n${t("common:errors.gemini.sources")} ${citations}` } + } } - if (chunk.usageMetadata) { - lastUsageMetadata = chunk.usageMetadata - } - } + if (lastUsageMetadata) { + const inputTokens = lastUsageMetadata.promptTokenCount ?? 0 + const outputTokens = lastUsageMetadata.candidatesTokenCount ?? 0 + const cacheReadTokens = lastUsageMetadata.cachedContentTokenCount + const reasoningTokens = lastUsageMetadata.thoughtsTokenCount - if (lastUsageMetadata) { - const inputTokens = lastUsageMetadata.promptTokenCount ?? 0 - const outputTokens = lastUsageMetadata.candidatesTokenCount ?? 0 - const cacheReadTokens = lastUsageMetadata.cachedContentTokenCount - const reasoningTokens = lastUsageMetadata.thoughtsTokenCount - - yield { - type: "usage", - inputTokens, - outputTokens, - cacheReadTokens, - reasoningTokens, - totalCost: this.calculateCost({ info, inputTokens, outputTokens, cacheReadTokens }), + yield { + type: "usage", + inputTokens, + outputTokens, + cacheReadTokens, + reasoningTokens, + totalCost: this.calculateCost({ info, inputTokens, outputTokens, cacheReadTokens }), + } } + } catch (error) { + if (error instanceof Error) { + throw new Error(t("common:errors.gemini.generate_stream", { error: error.message })) + } + + throw error } } override getModel() { const modelId = this.options.apiModelId let id = modelId && modelId in geminiModels ? (modelId as GeminiModelId) : geminiDefaultModelId - const info: ModelInfo = geminiModels[id] + let info: ModelInfo = geminiModels[id] const params = getModelParams({ format: "gemini", modelId: id, model: info, settings: this.options }) // The `:thinking` suffix indicates that the model is a "Hybrid" @@ -142,25 +175,69 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl return { id: id.endsWith(":thinking") ? id.replace(":thinking", "") : id, info, ...params } } + private extractCitationsOnly(groundingMetadata?: GroundingMetadata): string | null { + const chunks = groundingMetadata?.groundingChunks + + if (!chunks) { + return null + } + + const citationLinks = chunks + .map((chunk, i) => { + const uri = chunk.web?.uri + if (uri) { + return `[${i + 1}](${uri})` + } + return null + }) + .filter((link): link is string => link !== null) + + if (citationLinks.length > 0) { + return citationLinks.join(", ") + } + + return null + } + async completePrompt(prompt: string): Promise { try { const { id: model } = this.getModel() + const tools: GenerateContentConfig["tools"] = [] + if (this.options.enableUrlContext) { + tools.push({ urlContext: {} }) + } + if (this.options.enableGrounding) { + tools.push({ googleSearch: {} }) + } + const promptConfig: GenerateContentConfig = { + httpOptions: this.options.googleGeminiBaseUrl + ? { baseUrl: this.options.googleGeminiBaseUrl } + : undefined, + temperature: this.options.modelTemperature ?? 0, + ...(tools.length > 0 ? { tools } : {}), + } + const result = await this.client.models.generateContent({ model, contents: [{ role: "user", parts: [{ text: prompt }] }], - config: { - httpOptions: this.options.googleGeminiBaseUrl - ? { baseUrl: this.options.googleGeminiBaseUrl } - : undefined, - temperature: this.options.modelTemperature ?? 0, - }, + config: promptConfig, }) - return result.text ?? "" + let text = result.text ?? "" + + const candidate = result.candidates?.[0] + if (candidate?.groundingMetadata) { + const citations = this.extractCitationsOnly(candidate.groundingMetadata) + if (citations) { + text += `\n\n${t("common:errors.gemini.sources")} ${citations}` + } + } + + return text } catch (error) { if (error instanceof Error) { - throw new Error(`Gemini completion error: ${error.message}`) + throw new Error(t("common:errors.gemini.generate_complete_prompt", { error: error.message })) } throw error diff --git a/src/api/providers/huggingface.ts b/src/api/providers/huggingface.ts index 913605bd92..aa158654c9 100644 --- a/src/api/providers/huggingface.ts +++ b/src/api/providers/huggingface.ts @@ -1,16 +1,18 @@ import OpenAI from "openai" import { Anthropic } from "@anthropic-ai/sdk" -import type { ApiHandlerOptions } from "../../shared/api" +import type { ApiHandlerOptions, ModelRecord } from "../../shared/api" import { ApiStream } from "../transform/stream" import { convertToOpenAiMessages } from "../transform/openai-format" import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index" import { DEFAULT_HEADERS } from "./constants" import { BaseProvider } from "./base-provider" +import { getHuggingFaceModels, getCachedHuggingFaceModels } from "./fetchers/huggingface" export class HuggingFaceHandler extends BaseProvider implements SingleCompletionHandler { private client: OpenAI private options: ApiHandlerOptions + private modelCache: ModelRecord | null = null constructor(options: ApiHandlerOptions) { super() @@ -25,6 +27,20 @@ export class HuggingFaceHandler extends BaseProvider implements SingleCompletion apiKey: this.options.huggingFaceApiKey, defaultHeaders: DEFAULT_HEADERS, }) + + // Try to get cached models first + this.modelCache = getCachedHuggingFaceModels() + + // Fetch models asynchronously + this.fetchModels() + } + + private async fetchModels() { + try { + this.modelCache = await getHuggingFaceModels() + } catch (error) { + console.error("Failed to fetch HuggingFace models:", error) + } } override async *createMessage( @@ -43,6 +59,11 @@ export class HuggingFaceHandler extends BaseProvider implements SingleCompletion stream_options: { include_usage: true }, } + // Add max_tokens if specified + if (this.options.includeMaxTokens && this.options.modelMaxTokens) { + params.max_tokens = this.options.modelMaxTokens + } + const stream = await this.client.chat.completions.create(params) for await (const chunk of stream) { @@ -86,6 +107,18 @@ export class HuggingFaceHandler extends BaseProvider implements SingleCompletion override getModel() { const modelId = this.options.huggingFaceModelId || "meta-llama/Llama-3.3-70B-Instruct" + + // Try to get model info from cache + const modelInfo = this.modelCache?.[modelId] + + if (modelInfo) { + return { + id: modelId, + info: modelInfo, + } + } + + // Fallback to default values if model not found in cache return { id: modelId, info: { diff --git a/src/api/providers/lite-llm.ts b/src/api/providers/lite-llm.ts index e8cd58b12c..7cea7411fe 100644 --- a/src/api/providers/lite-llm.ts +++ b/src/api/providers/lite-llm.ts @@ -39,10 +39,70 @@ export class LiteLLMHandler extends RouterProvider implements SingleCompletionHa ): ApiStream { const { id: modelId, info } = await this.fetchModel() - const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ - { role: "system", content: systemPrompt }, - ...convertToOpenAiMessages(messages), - ] + const openAiMessages = convertToOpenAiMessages(messages) + + // Prepare messages with cache control if enabled and supported + let systemMessage: OpenAI.Chat.ChatCompletionMessageParam + let enhancedMessages: OpenAI.Chat.ChatCompletionMessageParam[] + + if (this.options.litellmUsePromptCache && info.supportsPromptCache) { + // Create system message with cache control in the proper format + systemMessage = { + role: "system", + content: [ + { + type: "text", + text: systemPrompt, + cache_control: { type: "ephemeral" }, + } as any, + ], + } + + // Find the last two user messages to apply caching + const userMsgIndices = openAiMessages.reduce( + (acc, msg, index) => (msg.role === "user" ? [...acc, index] : acc), + [] as number[], + ) + const lastUserMsgIndex = userMsgIndices[userMsgIndices.length - 1] ?? -1 + const secondLastUserMsgIndex = userMsgIndices[userMsgIndices.length - 2] ?? -1 + + // Apply cache_control to the last two user messages + enhancedMessages = openAiMessages.map((message, index) => { + if ((index === lastUserMsgIndex || index === secondLastUserMsgIndex) && message.role === "user") { + // Handle both string and array content types + if (typeof message.content === "string") { + return { + ...message, + content: [ + { + type: "text", + text: message.content, + cache_control: { type: "ephemeral" }, + } as any, + ], + } + } else if (Array.isArray(message.content)) { + // Apply cache control to the last content item in the array + return { + ...message, + content: message.content.map((content, contentIndex) => + contentIndex === message.content.length - 1 + ? ({ + ...content, + cache_control: { type: "ephemeral" }, + } as any) + : content, + ), + } + } + } + return message + }) + } else { + // No cache control - use simple format + systemMessage = { role: "system", content: systemPrompt } + enhancedMessages = openAiMessages + } // Required by some providers; others default to max tokens allowed let maxTokens: number | undefined = info.maxTokens ?? undefined @@ -50,7 +110,7 @@ export class LiteLLMHandler extends RouterProvider implements SingleCompletionHa const requestOptions: OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming = { model: modelId, max_tokens: maxTokens, - messages: openAiMessages, + messages: [systemMessage, ...enhancedMessages], stream: true, stream_options: { include_usage: true, @@ -80,20 +140,30 @@ export class LiteLLMHandler extends RouterProvider implements SingleCompletionHa } if (lastUsage) { + // Extract cache-related information if available + // LiteLLM may use different field names for cache tokens + const cacheWriteTokens = + lastUsage.cache_creation_input_tokens || (lastUsage as any).prompt_cache_miss_tokens || 0 + const cacheReadTokens = + lastUsage.prompt_tokens_details?.cached_tokens || + (lastUsage as any).cache_read_input_tokens || + (lastUsage as any).prompt_cache_hit_tokens || + 0 + const usageData: ApiStreamUsageChunk = { type: "usage", inputTokens: lastUsage.prompt_tokens || 0, outputTokens: lastUsage.completion_tokens || 0, - cacheWriteTokens: lastUsage.cache_creation_input_tokens || 0, - cacheReadTokens: lastUsage.prompt_tokens_details?.cached_tokens || 0, + cacheWriteTokens: cacheWriteTokens > 0 ? cacheWriteTokens : undefined, + cacheReadTokens: cacheReadTokens > 0 ? cacheReadTokens : undefined, } usageData.totalCost = calculateApiCostOpenAI( info, usageData.inputTokens, usageData.outputTokens, - usageData.cacheWriteTokens, - usageData.cacheReadTokens, + usageData.cacheWriteTokens || 0, + usageData.cacheReadTokens || 0, ) yield usageData diff --git a/src/core/config/CustomModesManager.ts b/src/core/config/CustomModesManager.ts index c388c1a537..d40aa423d6 100644 --- a/src/core/config/CustomModesManager.ts +++ b/src/core/config/CustomModesManager.ts @@ -786,7 +786,9 @@ export class CustomModesManager { const relativePath = isGlobalMode ? path.relative(baseDir, filePath) : path.relative(path.join(baseDir, ".roo"), filePath) - rulesFiles.push({ relativePath, content: content.trim() }) + // Normalize path to use forward slashes for cross-platform compatibility + const normalizedRelativePath = relativePath.toPosix() + rulesFiles.push({ relativePath: normalizedRelativePath, content: content.trim() }) } } } diff --git a/src/core/config/__tests__/CustomModesManager.spec.ts b/src/core/config/__tests__/CustomModesManager.spec.ts index 682696fd03..aa7d6422d9 100644 --- a/src/core/config/__tests__/CustomModesManager.spec.ts +++ b/src/core/config/__tests__/CustomModesManager.spec.ts @@ -1699,5 +1699,59 @@ describe("CustomModesManager", () => { expect(result.yaml).toContain("global-test-mode") expect(result.yaml).toContain("Global rule content") }) + + it("should normalize paths to use forward slashes in exported YAML", async () => { + const roomodesContent = { + customModes: [ + { + slug: "test-mode", + name: "Test Mode", + roleDefinition: "Test Role", + groups: ["read"], + }, + ], + } + + ;(fileExistsAtPath as Mock).mockImplementation(async (path: string) => { + return path === mockRoomodes + }) + ;(fs.readFile as Mock).mockImplementation(async (path: string) => { + if (path === mockRoomodes) { + return yaml.stringify(roomodesContent) + } + if (path.includes("rules-test-mode")) { + return "Rule content" + } + throw new Error("File not found") + }) + ;(fs.stat as Mock).mockResolvedValue({ isDirectory: () => true }) + + // Mock readdir to return entries with subdirectories + ;(fs.readdir as Mock).mockResolvedValue([ + { name: "rule1.md", isFile: () => true }, + { name: "rule2.md", isFile: () => true }, + ]) + + const result = await manager.exportModeWithRules("test-mode") + + expect(result.success).toBe(true) + + // Parse the YAML to check the paths + const exportedData = yaml.parse(result.yaml!) + const rulesFiles = exportedData.customModes[0].rulesFiles + + // Verify that all paths use forward slashes + expect(rulesFiles).toBeDefined() + expect(rulesFiles.length).toBe(2) + + // Check that all paths use forward slashes + rulesFiles.forEach((file: any) => { + expect(file.relativePath).not.toContain("\\") + expect(file.relativePath).toMatch(/^rules-test-mode\//) + }) + + // Ensure no backslashes in the entire exported YAML + expect(result.yaml).not.toContain("\\") + }) }) }) diff --git a/src/core/mentions/__tests__/processUserContentMentions.spec.ts b/src/core/mentions/__tests__/processUserContentMentions.spec.ts new file mode 100644 index 0000000000..3aebd66e53 --- /dev/null +++ b/src/core/mentions/__tests__/processUserContentMentions.spec.ts @@ -0,0 +1,353 @@ +// npx vitest core/mentions/__tests__/processUserContentMentions.spec.ts + +import { describe, it, expect, vi, beforeEach } from "vitest" +import { processUserContentMentions } from "../processUserContentMentions" +import { parseMentions } from "../index" +import { UrlContentFetcher } from "../../../services/browser/UrlContentFetcher" +import { FileContextTracker } from "../../context-tracking/FileContextTracker" + +// Mock the parseMentions function +vi.mock("../index", () => ({ + parseMentions: vi.fn(), +})) + +describe("processUserContentMentions", () => { + let mockUrlContentFetcher: UrlContentFetcher + let mockFileContextTracker: FileContextTracker + let mockRooIgnoreController: any + + beforeEach(() => { + vi.clearAllMocks() + + mockUrlContentFetcher = {} as UrlContentFetcher + mockFileContextTracker = {} as FileContextTracker + mockRooIgnoreController = {} + + // Default mock implementation + vi.mocked(parseMentions).mockImplementation(async (text) => `parsed: ${text}`) + }) + + describe("maxReadFileLine parameter", () => { + it("should pass maxReadFileLine to parseMentions when provided", async () => { + const userContent = [ + { + type: "text" as const, + text: "Read file with limit", + }, + ] + + await processUserContentMentions({ + userContent, + cwd: "/test", + urlContentFetcher: mockUrlContentFetcher, + fileContextTracker: mockFileContextTracker, + rooIgnoreController: mockRooIgnoreController, + maxReadFileLine: 100, + }) + + expect(parseMentions).toHaveBeenCalledWith( + "Read file with limit", + "/test", + mockUrlContentFetcher, + mockFileContextTracker, + mockRooIgnoreController, + true, + true, // includeDiagnosticMessages + 50, // maxDiagnosticMessages + 100, + ) + }) + + it("should pass undefined maxReadFileLine when not provided", async () => { + const userContent = [ + { + type: "text" as const, + text: "Read file without limit", + }, + ] + + await processUserContentMentions({ + userContent, + cwd: "/test", + urlContentFetcher: mockUrlContentFetcher, + fileContextTracker: mockFileContextTracker, + rooIgnoreController: mockRooIgnoreController, + }) + + expect(parseMentions).toHaveBeenCalledWith( + "Read file without limit", + "/test", + mockUrlContentFetcher, + mockFileContextTracker, + mockRooIgnoreController, + true, + true, // includeDiagnosticMessages + 50, // maxDiagnosticMessages + undefined, + ) + }) + + it("should handle UNLIMITED_LINES constant correctly", async () => { + const userContent = [ + { + type: "text" as const, + text: "Read unlimited lines", + }, + ] + + await processUserContentMentions({ + userContent, + cwd: "/test", + urlContentFetcher: mockUrlContentFetcher, + fileContextTracker: mockFileContextTracker, + rooIgnoreController: mockRooIgnoreController, + maxReadFileLine: -1, + }) + + expect(parseMentions).toHaveBeenCalledWith( + "Read unlimited lines", + "/test", + mockUrlContentFetcher, + mockFileContextTracker, + mockRooIgnoreController, + true, + true, // includeDiagnosticMessages + 50, // maxDiagnosticMessages + -1, + ) + }) + }) + + describe("content processing", () => { + it("should process text blocks with tags", async () => { + const userContent = [ + { + type: "text" as const, + text: "Do something", + }, + ] + + const result = await processUserContentMentions({ + userContent, + cwd: "/test", + urlContentFetcher: mockUrlContentFetcher, + fileContextTracker: mockFileContextTracker, + }) + + expect(parseMentions).toHaveBeenCalled() + expect(result[0]).toEqual({ + type: "text", + text: "parsed: Do something", + }) + }) + + it("should process text blocks with tags", async () => { + const userContent = [ + { + type: "text" as const, + text: "Fix this issue", + }, + ] + + const result = await processUserContentMentions({ + userContent, + cwd: "/test", + urlContentFetcher: mockUrlContentFetcher, + fileContextTracker: mockFileContextTracker, + }) + + expect(parseMentions).toHaveBeenCalled() + expect(result[0]).toEqual({ + type: "text", + text: "parsed: Fix this issue", + }) + }) + + it("should not process text blocks without task or feedback tags", async () => { + const userContent = [ + { + type: "text" as const, + text: "Regular text without special tags", + }, + ] + + const result = await processUserContentMentions({ + userContent, + cwd: "/test", + urlContentFetcher: mockUrlContentFetcher, + fileContextTracker: mockFileContextTracker, + }) + + expect(parseMentions).not.toHaveBeenCalled() + expect(result[0]).toEqual(userContent[0]) + }) + + it("should process tool_result blocks with string content", async () => { + const userContent = [ + { + type: "tool_result" as const, + tool_use_id: "123", + content: "Tool feedback", + }, + ] + + const result = await processUserContentMentions({ + userContent, + cwd: "/test", + urlContentFetcher: mockUrlContentFetcher, + fileContextTracker: mockFileContextTracker, + }) + + expect(parseMentions).toHaveBeenCalled() + expect(result[0]).toEqual({ + type: "tool_result", + tool_use_id: "123", + content: "parsed: Tool feedback", + }) + }) + + it("should process tool_result blocks with array content", async () => { + const userContent = [ + { + type: "tool_result" as const, + tool_use_id: "123", + content: [ + { + type: "text" as const, + text: "Array task", + }, + { + type: "text" as const, + text: "Regular text", + }, + ], + }, + ] + + const result = await processUserContentMentions({ + userContent, + cwd: "/test", + urlContentFetcher: mockUrlContentFetcher, + fileContextTracker: mockFileContextTracker, + }) + + expect(parseMentions).toHaveBeenCalledTimes(1) + expect(result[0]).toEqual({ + type: "tool_result", + tool_use_id: "123", + content: [ + { + type: "text", + text: "parsed: Array task", + }, + { + type: "text", + text: "Regular text", + }, + ], + }) + }) + + it("should handle mixed content types", async () => { + const userContent = [ + { + type: "text" as const, + text: "First task", + }, + { + type: "image" as const, + source: { + type: "base64" as const, + media_type: "image/png" as const, + data: "base64data", + }, + }, + { + type: "tool_result" as const, + tool_use_id: "456", + content: "Feedback", + }, + ] + + const result = await processUserContentMentions({ + userContent, + cwd: "/test", + urlContentFetcher: mockUrlContentFetcher, + fileContextTracker: mockFileContextTracker, + maxReadFileLine: 50, + }) + + expect(parseMentions).toHaveBeenCalledTimes(2) + expect(result).toHaveLength(3) + expect(result[0]).toEqual({ + type: "text", + text: "parsed: First task", + }) + expect(result[1]).toEqual(userContent[1]) // Image block unchanged + expect(result[2]).toEqual({ + type: "tool_result", + tool_use_id: "456", + content: "parsed: Feedback", + }) + }) + }) + + describe("showRooIgnoredFiles parameter", () => { + it("should default showRooIgnoredFiles to true", async () => { + const userContent = [ + { + type: "text" as const, + text: "Test default", + }, + ] + + await processUserContentMentions({ + userContent, + cwd: "/test", + urlContentFetcher: mockUrlContentFetcher, + fileContextTracker: mockFileContextTracker, + }) + + expect(parseMentions).toHaveBeenCalledWith( + "Test default", + "/test", + mockUrlContentFetcher, + mockFileContextTracker, + undefined, + true, // showRooIgnoredFiles should default to true + true, // includeDiagnosticMessages + 50, // maxDiagnosticMessages + undefined, + ) + }) + + it("should respect showRooIgnoredFiles when explicitly set to false", async () => { + const userContent = [ + { + type: "text" as const, + text: "Test explicit false", + }, + ] + + await processUserContentMentions({ + userContent, + cwd: "/test", + urlContentFetcher: mockUrlContentFetcher, + fileContextTracker: mockFileContextTracker, + showRooIgnoredFiles: false, + }) + + expect(parseMentions).toHaveBeenCalledWith( + "Test explicit false", + "/test", + mockUrlContentFetcher, + mockFileContextTracker, + undefined, + false, + true, // includeDiagnosticMessages + 50, // maxDiagnosticMessages + undefined, + ) + }) + }) +}) diff --git a/src/core/mentions/index.ts b/src/core/mentions/index.ts index 7ce54b984e..b6a9dd4d0d 100644 --- a/src/core/mentions/index.ts +++ b/src/core/mentions/index.ts @@ -4,7 +4,7 @@ import * as path from "path" import * as vscode from "vscode" import { isBinaryFile } from "isbinaryfile" -import { mentionRegexGlobal, unescapeSpaces } from "../../shared/context-mentions" +import { mentionRegexGlobal, commandRegexGlobal, unescapeSpaces } from "../../shared/context-mentions" import { getCommitInfo, getWorkingState } from "../../utils/git" import { getWorkspacePath } from "../../utils/path" @@ -18,6 +18,7 @@ import { UrlContentFetcher } from "../../services/browser/UrlContentFetcher" import { FileContextTracker } from "../context-tracking/FileContextTracker" import { RooIgnoreController } from "../ignore/RooIgnoreController" +import { getCommand } from "../../services/command/commands" import { t } from "../../i18n" @@ -82,9 +83,19 @@ export async function parseMentions( showRooIgnoredFiles: boolean = true, includeDiagnosticMessages: boolean = true, maxDiagnosticMessages: number = 50, + maxReadFileLine?: number, ): Promise { const mentions: Set = new Set() - let parsedText = text.replace(mentionRegexGlobal, (match, mention) => { + const commandMentions: Set = new Set() + + // First pass: extract command mentions (starting with /) + let parsedText = text.replace(commandRegexGlobal, (match, commandName) => { + commandMentions.add(commandName) + return `Command '${commandName}' (see below for command content)` + }) + + // Second pass: handle regular mentions + parsedText = parsedText.replace(mentionRegexGlobal, (match, mention) => { mentions.add(mention) if (mention.startsWith("http")) { return `'${mention}' (see below for site content)` @@ -149,7 +160,13 @@ export async function parseMentions( } else if (mention.startsWith("/")) { const mentionPath = mention.slice(1) try { - const content = await getFileOrFolderContent(mentionPath, cwd, rooIgnoreController, showRooIgnoredFiles) + const content = await getFileOrFolderContent( + mentionPath, + cwd, + rooIgnoreController, + showRooIgnoredFiles, + maxReadFileLine, + ) if (mention.endsWith("/")) { parsedText += `\n\n\n${content}\n` } else { @@ -196,6 +213,25 @@ export async function parseMentions( } } + // Process command mentions + for (const commandName of commandMentions) { + try { + const command = await getCommand(cwd, commandName) + if (command) { + let commandOutput = "" + if (command.description) { + commandOutput += `Description: ${command.description}\n\n` + } + commandOutput += command.content + parsedText += `\n\n\n${commandOutput}\n` + } else { + parsedText += `\n\n\nCommand '${commandName}' not found. Available commands can be found in .roo/commands/ or ~/.roo/commands/\n` + } + } catch (error) { + parsedText += `\n\n\nError loading command '${commandName}': ${error.message}\n` + } + } + if (urlMention) { try { await urlContentFetcher.closeBrowser() @@ -212,6 +248,7 @@ async function getFileOrFolderContent( cwd: string, rooIgnoreController?: any, showRooIgnoredFiles: boolean = true, + maxReadFileLine?: number, ): Promise { const unescapedPath = unescapeSpaces(mentionPath) const absPath = path.resolve(cwd, unescapedPath) @@ -224,7 +261,7 @@ async function getFileOrFolderContent( return `(File ${mentionPath} is ignored by .rooignore)` } try { - const content = await extractTextFromFile(absPath) + const content = await extractTextFromFile(absPath, maxReadFileLine) return content } catch (error) { return `(Failed to read contents of ${mentionPath}): ${error.message}` @@ -264,7 +301,7 @@ async function getFileOrFolderContent( if (isBinary) { return undefined } - const content = await extractTextFromFile(absoluteFilePath) + const content = await extractTextFromFile(absoluteFilePath, maxReadFileLine) return `\n${content}\n` } catch (error) { return undefined diff --git a/src/core/mentions/processUserContentMentions.ts b/src/core/mentions/processUserContentMentions.ts index 0649c4bc3c..245a25b379 100644 --- a/src/core/mentions/processUserContentMentions.ts +++ b/src/core/mentions/processUserContentMentions.ts @@ -15,6 +15,7 @@ export async function processUserContentMentions({ showRooIgnoredFiles = true, includeDiagnosticMessages = true, maxDiagnosticMessages = 50, + maxReadFileLine, }: { userContent: Anthropic.Messages.ContentBlockParam[] cwd: string @@ -24,6 +25,7 @@ export async function processUserContentMentions({ showRooIgnoredFiles?: boolean includeDiagnosticMessages?: boolean maxDiagnosticMessages?: number + maxReadFileLine?: number }) { // Process userContent array, which contains various block types: // TextBlockParam, ImageBlockParam, ToolUseBlockParam, and ToolResultBlockParam. @@ -52,6 +54,7 @@ export async function processUserContentMentions({ showRooIgnoredFiles, includeDiagnosticMessages, maxDiagnosticMessages, + maxReadFileLine, ), } } @@ -71,6 +74,7 @@ export async function processUserContentMentions({ showRooIgnoredFiles, includeDiagnosticMessages, maxDiagnosticMessages, + maxReadFileLine, ), } } @@ -91,6 +95,7 @@ export async function processUserContentMentions({ showRooIgnoredFiles, includeDiagnosticMessages, maxDiagnosticMessages, + maxReadFileLine, ), } } diff --git a/src/core/sliding-window/__tests__/sliding-window.spec.ts b/src/core/sliding-window/__tests__/sliding-window.spec.ts index 393d50307e..0f2c70c81b 100644 --- a/src/core/sliding-window/__tests__/sliding-window.spec.ts +++ b/src/core/sliding-window/__tests__/sliding-window.spec.ts @@ -250,7 +250,6 @@ describe("Sliding Window", () => { { role: "assistant", content: "Fourth message" }, { role: "user", content: "Fifth message" }, ] - it("should not truncate if tokens are below max tokens threshold", async () => { const modelInfo = createModelInfo(100000, 30000) const dynamicBuffer = modelInfo.contextWindow * TOKEN_BUFFER_PERCENTAGE // 10000 diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 95d12f66aa..fe8fd0f68f 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -1230,6 +1230,7 @@ export class Task extends EventEmitter { showRooIgnoredFiles = true, includeDiagnosticMessages = true, maxDiagnosticMessages = 50, + maxReadFileLine = -1, } = (await this.providerRef.deref()?.getState()) ?? {} const parsedUserContent = await processUserContentMentions({ @@ -1241,6 +1242,7 @@ export class Task extends EventEmitter { showRooIgnoredFiles, includeDiagnosticMessages, maxDiagnosticMessages, + maxReadFileLine, }) const environmentDetails = await getEnvironmentDetails(this, includeFileDetails) diff --git a/src/core/tools/applyDiffTool.ts b/src/core/tools/applyDiffTool.ts index ad4bb0590f..f046ba67d2 100644 --- a/src/core/tools/applyDiffTool.ts +++ b/src/core/tools/applyDiffTool.ts @@ -193,10 +193,17 @@ export async function applyDiffToolLegacy( // Get the formatted response message const message = await cline.diffViewProvider.pushToolWriteResult(cline, cline.cwd, !fileExists) + // Check for single SEARCH/REPLACE block warning + const searchBlocks = (diffContent.match(/<<<<<<< SEARCH/g) || []).length + const singleBlockNotice = + searchBlocks === 1 + ? "\nMaking multiple related changes in a single apply_diff is more efficient. If other changes are needed in this file, please include them as additional SEARCH/REPLACE blocks." + : "" + if (partFailHint) { - pushToolResult(partFailHint + message) + pushToolResult(partFailHint + message + singleBlockNotice) } else { - pushToolResult(message) + pushToolResult(message + singleBlockNotice) } await cline.diffViewProvider.reset() diff --git a/src/core/tools/multiApplyDiffTool.ts b/src/core/tools/multiApplyDiffTool.ts index 4ddef4880b..ec8c77a63b 100644 --- a/src/core/tools/multiApplyDiffTool.ts +++ b/src/core/tools/multiApplyDiffTool.ts @@ -601,8 +601,22 @@ ${errorDetails ? `\nTechnical details:\n${errorDetails}\n` : ""} await cline.say("diff_error", allDiffErrors.join("\n")) } + // Check for single SEARCH/REPLACE block warning + let totalSearchBlocks = 0 + for (const operation of operations) { + for (const diffItem of operation.diff) { + const searchBlocks = (diffItem.content.match(/<<<<<<< SEARCH/g) || []).length + totalSearchBlocks += searchBlocks + } + } + + const singleBlockNotice = + totalSearchBlocks === 1 + ? "\nMaking multiple related changes in a single apply_diff is more efficient. If other changes are needed in this file, please include them as additional SEARCH/REPLACE blocks." + : "" + // Push the final result combining all operation results - pushToolResult(results.join("\n\n")) + pushToolResult(results.join("\n\n") + singleBlockNotice) return } catch (error) { await handleError("applying diff", error) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 0b9645d0a0..f1f5719e99 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -112,7 +112,7 @@ export class ClineProvider public isViewLaunched = false public settingsImportedAt?: number - public readonly latestAnnouncementId = "jul-09-2025-3-23-0" // Update for v3.23.0 announcement + public readonly latestAnnouncementId = "jul-26-2025-3-24-0" // Update for v3.24.0 announcement public readonly providerSettingsManager: ProviderSettingsManager public readonly customModesManager: CustomModesManager diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index fb80c6ced8..a0f8a51d28 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -682,8 +682,8 @@ export const webviewMessageHandler = async ( break case "requestHuggingFaceModels": try { - const { getHuggingFaceModels } = await import("../../api/huggingface-models") - const huggingFaceModelsResponse = await getHuggingFaceModels() + const { getHuggingFaceModelsWithMetadata } = await import("../../api/providers/fetchers/huggingface") + const huggingFaceModelsResponse = await getHuggingFaceModelsWithMetadata() provider.postMessageToWebview({ type: "huggingFaceModels", huggingFaceModels: huggingFaceModelsResponse.models, @@ -2098,6 +2098,19 @@ export const webviewMessageHandler = async ( } } } + } else { + // No workspace open - send error status + provider.log("Cannot save code index settings: No workspace folder open") + await provider.postMessageToWebview({ + type: "indexingStatusUpdate", + values: { + systemStatus: "Error", + message: t("embeddings:orchestrator.indexingRequiresWorkspace"), + processedItems: 0, + totalItems: 0, + currentItemUnit: "items", + }, + }) } } catch (error) { provider.log(`Error saving code index settings: ${error.message || error}`) @@ -2111,7 +2124,22 @@ export const webviewMessageHandler = async ( } case "requestIndexingStatus": { - const status = provider.codeIndexManager!.getCurrentStatus() + const manager = provider.codeIndexManager + if (!manager) { + // No workspace open - send error status + provider.postMessageToWebview({ + type: "indexingStatusUpdate", + values: { + systemStatus: "Error", + message: t("embeddings:orchestrator.indexingRequiresWorkspace"), + processedItems: 0, + totalItems: 0, + currentItemUnit: "items", + }, + }) + return + } + const status = manager.getCurrentStatus() provider.postMessageToWebview({ type: "indexingStatusUpdate", values: status, @@ -2142,7 +2170,22 @@ export const webviewMessageHandler = async ( } case "startIndexing": { try { - const manager = provider.codeIndexManager! + const manager = provider.codeIndexManager + if (!manager) { + // No workspace open - send error status + provider.postMessageToWebview({ + type: "indexingStatusUpdate", + values: { + systemStatus: "Error", + message: t("embeddings:orchestrator.indexingRequiresWorkspace"), + processedItems: 0, + totalItems: 0, + currentItemUnit: "items", + }, + }) + provider.log("Cannot start indexing: No workspace folder open") + return + } if (manager.isFeatureEnabled && manager.isFeatureConfigured) { if (!manager.isInitialized) { await manager.initialize(provider.contextProxy) @@ -2157,7 +2200,18 @@ export const webviewMessageHandler = async ( } case "clearIndexData": { try { - const manager = provider.codeIndexManager! + const manager = provider.codeIndexManager + if (!manager) { + provider.log("Cannot clear index data: No workspace folder open") + provider.postMessageToWebview({ + type: "indexCleared", + values: { + success: false, + error: t("embeddings:orchestrator.indexingRequiresWorkspace"), + }, + }) + return + } await manager.clearIndexData() provider.postMessageToWebview({ type: "indexCleared", values: { success: true } }) } catch (error) { @@ -2308,5 +2362,198 @@ export const webviewMessageHandler = async ( } break } + case "requestCommands": { + try { + const { getCommands } = await import("../../services/command/commands") + const commands = await getCommands(provider.cwd || "") + + // Convert to the format expected by the frontend + const commandList = commands.map((command) => ({ + name: command.name, + source: command.source, + filePath: command.filePath, + description: command.description, + })) + + await provider.postMessageToWebview({ + type: "commands", + commands: commandList, + }) + } catch (error) { + provider.log(`Error fetching commands: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`) + // Send empty array on error + await provider.postMessageToWebview({ + type: "commands", + commands: [], + }) + } + break + } + case "openCommandFile": { + try { + if (message.text) { + const { getCommand } = await import("../../services/command/commands") + const command = await getCommand(provider.cwd || "", message.text) + + if (command && command.filePath) { + openFile(command.filePath) + } else { + vscode.window.showErrorMessage(t("common:errors.command_not_found", { name: message.text })) + } + } + } catch (error) { + provider.log( + `Error opening command file: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`, + ) + vscode.window.showErrorMessage(t("common:errors.open_command_file")) + } + break + } + case "deleteCommand": { + try { + if (message.text && message.values?.source) { + const { getCommand } = await import("../../services/command/commands") + const command = await getCommand(provider.cwd || "", message.text) + + if (command && command.filePath) { + // Delete the command file + await fs.unlink(command.filePath) + provider.log(`Deleted command file: ${command.filePath}`) + } else { + vscode.window.showErrorMessage(t("common:errors.command_not_found", { name: message.text })) + } + } + } catch (error) { + provider.log(`Error deleting command: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`) + vscode.window.showErrorMessage(t("common:errors.delete_command")) + } + break + } + case "createCommand": { + try { + const source = message.values?.source as "global" | "project" + const fileName = message.text // Custom filename from user input + + if (!source) { + provider.log("Missing source for createCommand") + break + } + + // Determine the commands directory based on source + let commandsDir: string + if (source === "global") { + const globalConfigDir = path.join(os.homedir(), ".roo") + commandsDir = path.join(globalConfigDir, "commands") + } else { + // Project commands + const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath + if (!workspaceRoot) { + vscode.window.showErrorMessage(t("common:errors.no_workspace_for_project_command")) + break + } + commandsDir = path.join(workspaceRoot, ".roo", "commands") + } + + // Ensure the commands directory exists + await fs.mkdir(commandsDir, { recursive: true }) + + // Use provided filename or generate a unique one + let commandName: string + if (fileName && fileName.trim()) { + let cleanFileName = fileName.trim() + + // Strip leading slash if present + if (cleanFileName.startsWith("/")) { + cleanFileName = cleanFileName.substring(1) + } + + // Remove .md extension if present BEFORE slugification + if (cleanFileName.toLowerCase().endsWith(".md")) { + cleanFileName = cleanFileName.slice(0, -3) + } + + // Slugify the command name: lowercase, replace spaces with dashes, remove special characters + commandName = cleanFileName + .toLowerCase() + .replace(/\s+/g, "-") // Replace spaces with dashes + .replace(/[^a-z0-9-]/g, "") // Remove special characters except dashes + .replace(/-+/g, "-") // Replace multiple dashes with single dash + .replace(/^-|-$/g, "") // Remove leading/trailing dashes + + // Ensure we have a valid command name + if (!commandName || commandName.length === 0) { + commandName = "new-command" + } + } else { + // Generate a unique command name + commandName = "new-command" + let counter = 1 + let filePath = path.join(commandsDir, `${commandName}.md`) + + while ( + await fs + .access(filePath) + .then(() => true) + .catch(() => false) + ) { + commandName = `new-command-${counter}` + filePath = path.join(commandsDir, `${commandName}.md`) + counter++ + } + } + + const filePath = path.join(commandsDir, `${commandName}.md`) + + // Check if file already exists + if ( + await fs + .access(filePath) + .then(() => true) + .catch(() => false) + ) { + vscode.window.showErrorMessage(t("common:errors.command_already_exists", { commandName })) + break + } + + // Create the command file with template content + const templateContent = t("common:errors.command_template_content") + + await fs.writeFile(filePath, templateContent, "utf8") + provider.log(`Created new command file: ${filePath}`) + + // Open the new file in the editor + openFile(filePath) + + // Refresh commands list + const { getCommands } = await import("../../services/command/commands") + const commands = await getCommands(provider.cwd || "") + const commandList = commands.map((command) => ({ + name: command.name, + source: command.source, + filePath: command.filePath, + description: command.description, + })) + await provider.postMessageToWebview({ + type: "commands", + commands: commandList, + }) + } catch (error) { + provider.log(`Error creating command: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`) + vscode.window.showErrorMessage(t("common:errors.create_command_failed")) + } + break + } + + case "insertTextIntoTextarea": { + const text = message.text + if (text) { + // Send message to insert text into the chat textarea + await provider.postMessageToWebview({ + type: "insertTextIntoTextarea", + text: text, + }) + } + break + } } } diff --git a/src/i18n/locales/ca/common.json b/src/i18n/locales/ca/common.json index 39bc1df8f8..0fba764080 100644 --- a/src/i18n/locales/ca/common.json +++ b/src/i18n/locales/ca/common.json @@ -74,6 +74,13 @@ "share_not_enabled": "La compartició de tasques no està habilitada per a aquesta organització.", "share_task_not_found": "Tasca no trobada o accés denegat.", "delete_rules_folder_failed": "Error en eliminar la carpeta de regles: {{rulesFolderPath}}. Error: {{error}}", + "command_not_found": "Ordre '{{name}}' no trobada", + "open_command_file": "Error en obrir el fitxer d'ordres", + "delete_command": "Error en eliminar l'ordre", + "no_workspace_for_project_command": "No s'ha trobat cap carpeta d'espai de treball per a l'ordre del projecte", + "command_already_exists": "L'ordre \"{{commandName}}\" ja existeix", + "create_command_failed": "Error en crear l'ordre", + "command_template_content": "---\ndescription: \"Breu descripció del que fa aquesta ordre\"\n---\n\nAquesta és una nova ordre slash. Edita aquest fitxer per personalitzar el comportament de l'ordre.", "claudeCode": { "processExited": "El procés Claude Code ha sortit amb codi {{exitCode}}.", "errorOutput": "Sortida d'error: {{output}}", @@ -81,6 +88,11 @@ "stoppedWithReason": "Claude Code s'ha aturat per la raó: {{reason}}", "apiKeyModelPlanMismatch": "Les claus API i els plans de subscripció permeten models diferents. Assegura't que el model seleccionat estigui inclòs al teu pla." }, + "gemini": { + "generate_stream": "Error del flux de context de generació de Gemini: {{error}}", + "generate_complete_prompt": "Error de finalització de Gemini: {{error}}", + "sources": "Fonts:" + }, "mode_import_failed": "Ha fallat la importació del mode: {{error}}" }, "warnings": { diff --git a/src/i18n/locales/ca/embeddings.json b/src/i18n/locales/ca/embeddings.json index 651bc2b80f..35ddca3b10 100644 --- a/src/i18n/locales/ca/embeddings.json +++ b/src/i18n/locales/ca/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "No s'ha pogut determinar la dimensió del vector per al model '{{modelId}}' amb el proveïdor '{{provider}}'. Comprova els perfils del model o la configuració.", "qdrantUrlMissing": "Falta l'URL de Qdrant per crear l'emmagatzematge de vectors", "codeIndexingNotConfigured": "No es poden crear serveis: La indexació de codi no està configurada correctament" + }, + "orchestrator": { + "indexingFailedNoBlocks": "Indexació fallida: No s'ha indexat cap bloc de codi amb èxit. Això normalment indica un problema de configuració de l'embedder.", + "indexingFailedCritical": "Indexació fallida: No s'ha indexat cap bloc de codi amb èxit malgrat trobar fitxers per processar. Això indica una fallida crítica de l'embedder.", + "fileWatcherStarted": "Monitor de fitxers iniciat.", + "fileWatcherStopped": "Monitor de fitxers aturat.", + "failedDuringInitialScan": "Ha fallat durant l'escaneig inicial: {{errorMessage}}", + "unknownError": "Error desconegut", + "indexingRequiresWorkspace": "Indexació requereix una carpeta de workspace oberta" } } diff --git a/src/i18n/locales/de/common.json b/src/i18n/locales/de/common.json index fbd800f602..1c60189b2f 100644 --- a/src/i18n/locales/de/common.json +++ b/src/i18n/locales/de/common.json @@ -71,12 +71,24 @@ "share_task_not_found": "Aufgabe nicht gefunden oder Zugriff verweigert.", "mode_import_failed": "Fehler beim Importieren des Modus: {{error}}", "delete_rules_folder_failed": "Fehler beim Löschen des Regelordners: {{rulesFolderPath}}. Fehler: {{error}}", + "command_not_found": "Befehl '{{name}}' nicht gefunden", + "open_command_file": "Fehler beim Öffnen der Befehlsdatei", + "delete_command": "Fehler beim Löschen des Befehls", + "no_workspace_for_project_command": "Kein Arbeitsbereich-Ordner für Projektbefehl gefunden", + "command_already_exists": "Befehl \"{{commandName}}\" existiert bereits", + "create_command_failed": "Fehler beim Erstellen des Befehls", + "command_template_content": "---\ndescription: \"Kurze Beschreibung dessen, was dieser Befehl macht\"\n---\n\nDies ist ein neuer Slash-Befehl. Bearbeite diese Datei, um das Befehlsverhalten anzupassen.", "claudeCode": { "processExited": "Claude Code Prozess wurde mit Code {{exitCode}} beendet.", "errorOutput": "Fehlerausgabe: {{output}}", "processExitedWithError": "Claude Code Prozess wurde mit Code {{exitCode}} beendet. Fehlerausgabe: {{output}}", "stoppedWithReason": "Claude Code wurde mit Grund gestoppt: {{reason}}", "apiKeyModelPlanMismatch": "API-Schlüssel und Abonnement-Pläne erlauben verschiedene Modelle. Stelle sicher, dass das ausgewählte Modell in deinem Plan enthalten ist." + }, + "gemini": { + "generate_stream": "Fehler beim Generieren des Kontext-Streams von Gemini: {{error}}", + "generate_complete_prompt": "Fehler bei der Vervollständigung durch Gemini: {{error}}", + "sources": "Quellen:" } }, "warnings": { diff --git a/src/i18n/locales/de/embeddings.json b/src/i18n/locales/de/embeddings.json index 167abc516c..f5aa7339ef 100644 --- a/src/i18n/locales/de/embeddings.json +++ b/src/i18n/locales/de/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "Konnte die Vektordimension für Modell '{{modelId}}' mit Anbieter '{{provider}}' nicht bestimmen. Überprüfe die Modellprofile oder Konfiguration.", "qdrantUrlMissing": "Qdrant-URL fehlt für die Erstellung des Vektorspeichers", "codeIndexingNotConfigured": "Kann keine Dienste erstellen: Code-Indizierung ist nicht richtig konfiguriert" + }, + "orchestrator": { + "indexingFailedNoBlocks": "Indizierung fehlgeschlagen: Keine Code-Blöcke wurden erfolgreich indiziert. Dies deutet normalerweise auf ein Embedder-Konfigurationsproblem hin.", + "indexingFailedCritical": "Indizierung fehlgeschlagen: Keine Code-Blöcke wurden erfolgreich indiziert, obwohl zu verarbeitende Dateien gefunden wurden. Dies deutet auf einen kritischen Embedder-Fehler hin.", + "fileWatcherStarted": "Datei-Watcher gestartet.", + "fileWatcherStopped": "Datei-Watcher gestoppt.", + "failedDuringInitialScan": "Fehler während des ersten Scans: {{errorMessage}}", + "unknownError": "Unbekannter Fehler", + "indexingRequiresWorkspace": "Indexierung erfordert einen offenen Workspace-Ordner" } } diff --git a/src/i18n/locales/en/common.json b/src/i18n/locales/en/common.json index db6341c312..114e129f45 100644 --- a/src/i18n/locales/en/common.json +++ b/src/i18n/locales/en/common.json @@ -71,12 +71,24 @@ "share_task_not_found": "Task not found or access denied.", "mode_import_failed": "Failed to import mode: {{error}}", "delete_rules_folder_failed": "Failed to delete rules folder: {{rulesFolderPath}}. Error: {{error}}", + "command_not_found": "Command '{{name}}' not found", + "open_command_file": "Failed to open command file", + "delete_command": "Failed to delete command", + "no_workspace_for_project_command": "No workspace folder found for project command", + "command_already_exists": "Command \"{{commandName}}\" already exists", + "create_command_failed": "Failed to create command", + "command_template_content": "---\ndescription: \"Brief description of what this command does\"\n---\n\nThis is a new slash command. Edit this file to customize the command behavior.", "claudeCode": { "processExited": "Claude Code process exited with code {{exitCode}}.", "errorOutput": "Error output: {{output}}", "processExitedWithError": "Claude Code process exited with code {{exitCode}}. Error output: {{output}}", "stoppedWithReason": "Claude Code stopped with reason: {{reason}}", "apiKeyModelPlanMismatch": "API keys and subscription plans allow different models. Make sure the selected model is included in your plan." + }, + "gemini": { + "generate_stream": "Gemini generate context stream error: {{error}}", + "generate_complete_prompt": "Gemini completion error: {{error}}", + "sources": "Sources:" } }, "warnings": { diff --git a/src/i18n/locales/en/embeddings.json b/src/i18n/locales/en/embeddings.json index 270a8d193b..66465d8c35 100644 --- a/src/i18n/locales/en/embeddings.json +++ b/src/i18n/locales/en/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "Could not determine vector dimension for model '{{modelId}}' with provider '{{provider}}'. Check model profiles or configuration.", "qdrantUrlMissing": "Qdrant URL missing for vector store creation", "codeIndexingNotConfigured": "Cannot create services: Code indexing is not properly configured" + }, + "orchestrator": { + "indexingFailedNoBlocks": "Indexing failed: No code blocks were successfully indexed. This usually indicates an embedder configuration issue.", + "indexingFailedCritical": "Indexing failed: No code blocks were successfully indexed despite finding files to process. This indicates a critical embedder failure.", + "fileWatcherStarted": "File watcher started.", + "fileWatcherStopped": "File watcher stopped.", + "failedDuringInitialScan": "Failed during initial scan: {{errorMessage}}", + "unknownError": "Unknown error", + "indexingRequiresWorkspace": "Indexing requires an open workspace folder" } } diff --git a/src/i18n/locales/es/common.json b/src/i18n/locales/es/common.json index cc04abfdae..62ab4dcb6e 100644 --- a/src/i18n/locales/es/common.json +++ b/src/i18n/locales/es/common.json @@ -71,12 +71,24 @@ "share_task_not_found": "Tarea no encontrada o acceso denegado.", "mode_import_failed": "Error al importar el modo: {{error}}", "delete_rules_folder_failed": "Error al eliminar la carpeta de reglas: {{rulesFolderPath}}. Error: {{error}}", + "command_not_found": "Comando '{{name}}' no encontrado", + "open_command_file": "Error al abrir el archivo de comandos", + "delete_command": "Error al eliminar el comando", + "no_workspace_for_project_command": "No se encontró carpeta de espacio de trabajo para comando de proyecto", + "command_already_exists": "El comando \"{{commandName}}\" ya existe", + "create_command_failed": "Error al crear comando", + "command_template_content": "---\ndescription: \"Breve descripción de lo que hace este comando\"\n---\n\nEste es un nuevo comando slash. Edita este archivo para personalizar el comportamiento del comando.", "claudeCode": { "processExited": "El proceso de Claude Code terminó con código {{exitCode}}.", "errorOutput": "Salida de error: {{output}}", "processExitedWithError": "El proceso de Claude Code terminó con código {{exitCode}}. Salida de error: {{output}}", "stoppedWithReason": "Claude Code se detuvo por la razón: {{reason}}", "apiKeyModelPlanMismatch": "Las claves API y los planes de suscripción permiten diferentes modelos. Asegúrate de que el modelo seleccionado esté incluido en tu plan." + }, + "gemini": { + "generate_stream": "Error del stream de contexto de generación de Gemini: {{error}}", + "generate_complete_prompt": "Error de finalización de Gemini: {{error}}", + "sources": "Fuentes:" } }, "warnings": { diff --git a/src/i18n/locales/es/embeddings.json b/src/i18n/locales/es/embeddings.json index 06478f1d50..51621b6d17 100644 --- a/src/i18n/locales/es/embeddings.json +++ b/src/i18n/locales/es/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "No se pudo determinar la dimensión del vector para el modelo '{{modelId}}' con el proveedor '{{provider}}'. Verifica los perfiles del modelo o la configuración.", "qdrantUrlMissing": "Falta la URL de Qdrant para crear el almacén de vectores", "codeIndexingNotConfigured": "No se pueden crear servicios: La indexación de código no está configurada correctamente" + }, + "orchestrator": { + "indexingFailedNoBlocks": "Indexación fallida: No se indexaron exitosamente bloques de código. Esto usualmente indica un problema de configuración del incrustador.", + "indexingFailedCritical": "Indexación fallida: No se indexaron exitosamente bloques de código a pesar de encontrar archivos para procesar. Esto indica una falla crítica del incrustador.", + "fileWatcherStarted": "Monitor de archivos iniciado.", + "fileWatcherStopped": "Monitor de archivos detenido.", + "failedDuringInitialScan": "Falló durante el escaneo inicial: {{errorMessage}}", + "unknownError": "Error desconocido", + "indexingRequiresWorkspace": "La indexación requiere una carpeta de workspace abierta" } } diff --git a/src/i18n/locales/fr/common.json b/src/i18n/locales/fr/common.json index 73f3e3d396..aae4d5d7b1 100644 --- a/src/i18n/locales/fr/common.json +++ b/src/i18n/locales/fr/common.json @@ -71,12 +71,24 @@ "share_task_not_found": "Tâche non trouvée ou accès refusé.", "mode_import_failed": "Échec de l'importation du mode : {{error}}", "delete_rules_folder_failed": "Échec de la suppression du dossier de règles : {{rulesFolderPath}}. Erreur : {{error}}", + "command_not_found": "Commande '{{name}}' introuvable", + "open_command_file": "Échec de l'ouverture du fichier de commande", + "delete_command": "Échec de la suppression de la commande", + "no_workspace_for_project_command": "Aucun dossier d'espace de travail trouvé pour la commande de projet", + "command_already_exists": "La commande \"{{commandName}}\" existe déjà", + "create_command_failed": "Échec de la création de la commande", + "command_template_content": "---\ndescription: \"Brève description de ce que fait cette commande\"\n---\n\nCeci est une nouvelle commande slash. Modifie ce fichier pour personnaliser le comportement de la commande.", "claudeCode": { "processExited": "Le processus Claude Code s'est terminé avec le code {{exitCode}}.", "errorOutput": "Sortie d'erreur : {{output}}", "processExitedWithError": "Le processus Claude Code s'est terminé avec le code {{exitCode}}. Sortie d'erreur : {{output}}", "stoppedWithReason": "Claude Code s'est arrêté pour la raison : {{reason}}", "apiKeyModelPlanMismatch": "Les clés API et les plans d'abonnement permettent différents modèles. Assurez-vous que le modèle sélectionné est inclus dans votre plan." + }, + "gemini": { + "generate_stream": "Erreur du flux de contexte de génération Gemini : {{error}}", + "generate_complete_prompt": "Erreur d'achèvement de Gemini : {{error}}", + "sources": "Sources :" } }, "warnings": { diff --git a/src/i18n/locales/fr/embeddings.json b/src/i18n/locales/fr/embeddings.json index 167d093e7a..e3a9227234 100644 --- a/src/i18n/locales/fr/embeddings.json +++ b/src/i18n/locales/fr/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "Impossible de déterminer la dimension du vecteur pour le modèle '{{modelId}}' avec le fournisseur '{{provider}}'. Vérifie les profils du modèle ou la configuration.", "qdrantUrlMissing": "URL Qdrant manquante pour la création du stockage de vecteurs", "codeIndexingNotConfigured": "Impossible de créer les services : L'indexation du code n'est pas correctement configurée" + }, + "orchestrator": { + "indexingFailedNoBlocks": "Échec de l'indexation : Aucun bloc de code n'a été indexé avec succès. Cela indique généralement un problème de configuration de l'embedder.", + "indexingFailedCritical": "Échec de l'indexation : Aucun bloc de code n'a été indexé avec succès malgré la découverte de fichiers à traiter. Cela indique une défaillance critique de l'embedder.", + "fileWatcherStarted": "Surveillant de fichiers démarré.", + "fileWatcherStopped": "Surveillant de fichiers arrêté.", + "failedDuringInitialScan": "Échec lors du scan initial : {{errorMessage}}", + "unknownError": "Erreur inconnue", + "indexingRequiresWorkspace": "L'indexation nécessite l'ouverture d'un dossier workspace" } } diff --git a/src/i18n/locales/hi/common.json b/src/i18n/locales/hi/common.json index 03f74e1af5..fae7c42be9 100644 --- a/src/i18n/locales/hi/common.json +++ b/src/i18n/locales/hi/common.json @@ -71,12 +71,24 @@ "share_task_not_found": "कार्य नहीं मिला या पहुंच अस्वीकृत।", "mode_import_failed": "मोड आयात करने में विफल: {{error}}", "delete_rules_folder_failed": "नियम फ़ोल्डर हटाने में विफल: {{rulesFolderPath}}। त्रुटि: {{error}}", + "command_not_found": "कमांड '{{name}}' नहीं मिला", + "open_command_file": "कमांड फ़ाइल खोलने में विफल", + "delete_command": "कमांड हटाने में विफल", + "no_workspace_for_project_command": "प्रोजेक्ट कमांड के लिए वर्कस्पेस फ़ोल्डर नहीं मिला", + "command_already_exists": "कमांड \"{{commandName}}\" पहले से मौजूद है", + "create_command_failed": "कमांड बनाने में विफल", + "command_template_content": "---\ndescription: \"इस कमांड के कार्य का संक्षिप्त विवरण\"\n---\n\nयह एक नया स्लैश कमांड है। कमांड व्यवहार को कस्टमाइज़ करने के लिए इस फ़ाइल को संपादित करें।", "claudeCode": { "processExited": "Claude Code प्रक्रिया कोड {{exitCode}} के साथ समाप्त हुई।", "errorOutput": "त्रुटि आउटपुट: {{output}}", "processExitedWithError": "Claude Code प्रक्रिया कोड {{exitCode}} के साथ समाप्त हुई। त्रुटि आउटपुट: {{output}}", "stoppedWithReason": "Claude Code इस कारण से रुका: {{reason}}", "apiKeyModelPlanMismatch": "API कुंजी और सब्सक्रिप्शन प्लान अलग-अलग मॉडल की अनुमति देते हैं। सुनिश्चित करें कि चयनित मॉडल आपकी योजना में शामिल है।" + }, + "gemini": { + "generate_stream": "जेमिनी जनरेट कॉन्टेक्स्ट स्ट्रीम त्रुटि: {{error}}", + "generate_complete_prompt": "जेमिनी समापन त्रुटि: {{error}}", + "sources": "स्रोत:" } }, "warnings": { diff --git a/src/i18n/locales/hi/embeddings.json b/src/i18n/locales/hi/embeddings.json index ad24cfe9d1..01563e833a 100644 --- a/src/i18n/locales/hi/embeddings.json +++ b/src/i18n/locales/hi/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "प्रदाता '{{provider}}' के साथ मॉडल '{{modelId}}' के लिए वेक्टर आयाम निर्धारित नहीं कर सका। मॉडल प्रोफ़ाइल या कॉन्फ़िगरेशन की जांच करें।", "qdrantUrlMissing": "वेक्टर स्टोर बनाने के लिए Qdrant URL गायब है", "codeIndexingNotConfigured": "सेवाएं नहीं बना सकते: कोड इंडेक्सिंग ठीक से कॉन्फ़िगर नहीं है" + }, + "orchestrator": { + "indexingFailedNoBlocks": "इंडेक्सिंग असफल: कोई भी कोड ब्लॉक सफलतापूर्वक इंडेक्स नहीं हुआ। यह आमतौर पर एम्बेडर कॉन्फ़िगरेशन समस्या को दर्शाता है।", + "indexingFailedCritical": "इंडेक्सिंग असफल: प्रोसेस करने के लिए फाइलें मिलने के बावजूद कोई भी कोड ब्लॉक सफलतापूर्वक इंडेक्स नहीं हुआ। यह एक गंभीर एम्बेडर विफलता को दर्शाता है।", + "fileWatcherStarted": "फाइल वॉचर शुरू हुआ।", + "fileWatcherStopped": "फाइल वॉचर रुक गया।", + "failedDuringInitialScan": "प्रारंभिक स्कैन के दौरान असफल: {{errorMessage}}", + "unknownError": "अज्ञात त्रुटि", + "indexingRequiresWorkspace": "इंडेक्सिंग के लिए एक खुला वर्कस्पेस फ़ोल्डर आवश्यक है" } } diff --git a/src/i18n/locales/id/common.json b/src/i18n/locales/id/common.json index 822341f529..eb2db5ac84 100644 --- a/src/i18n/locales/id/common.json +++ b/src/i18n/locales/id/common.json @@ -71,12 +71,24 @@ "share_task_not_found": "Tugas tidak ditemukan atau akses ditolak.", "mode_import_failed": "Gagal mengimpor mode: {{error}}", "delete_rules_folder_failed": "Gagal menghapus folder aturan: {{rulesFolderPath}}. Error: {{error}}", + "command_not_found": "Perintah '{{name}}' tidak ditemukan", + "open_command_file": "Gagal membuka file perintah", + "delete_command": "Gagal menghapus perintah", + "no_workspace_for_project_command": "Tidak ditemukan folder workspace untuk perintah proyek", + "command_already_exists": "Perintah \"{{commandName}}\" sudah ada", + "create_command_failed": "Gagal membuat perintah", + "command_template_content": "---\ndescription: \"Deskripsi singkat tentang fungsi perintah ini\"\n---\n\nIni adalah perintah slash baru. Edit file ini untuk menyesuaikan perilaku perintah.", "claudeCode": { "processExited": "Proses Claude Code keluar dengan kode {{exitCode}}.", "errorOutput": "Output error: {{output}}", "processExitedWithError": "Proses Claude Code keluar dengan kode {{exitCode}}. Output error: {{output}}", "stoppedWithReason": "Claude Code berhenti karena alasan: {{reason}}", "apiKeyModelPlanMismatch": "Kunci API dan paket berlangganan memungkinkan model yang berbeda. Pastikan model yang dipilih termasuk dalam paket Anda." + }, + "gemini": { + "generate_stream": "Kesalahan aliran konteks pembuatan Gemini: {{error}}", + "generate_complete_prompt": "Kesalahan penyelesaian Gemini: {{error}}", + "sources": "Sumber:" } }, "warnings": { diff --git a/src/i18n/locales/id/embeddings.json b/src/i18n/locales/id/embeddings.json index 997c6e8018..a66c1965ab 100644 --- a/src/i18n/locales/id/embeddings.json +++ b/src/i18n/locales/id/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "Tidak dapat menentukan dimensi vektor untuk model '{{modelId}}' dengan penyedia '{{provider}}'. Periksa profil model atau konfigurasi.", "qdrantUrlMissing": "URL Qdrant tidak ada untuk membuat penyimpanan vektor", "codeIndexingNotConfigured": "Tidak dapat membuat layanan: Pengindeksan kode tidak dikonfigurasi dengan benar" + }, + "orchestrator": { + "indexingFailedNoBlocks": "Pengindeksan gagal: Tidak ada blok kode yang berhasil diindeks. Ini biasanya menunjukkan masalah konfigurasi embedder.", + "indexingFailedCritical": "Pengindeksan gagal: Tidak ada blok kode yang berhasil diindeks meskipun menemukan file untuk diproses. Ini menunjukkan kegagalan kritis embedder.", + "fileWatcherStarted": "Pemantau file dimulai.", + "fileWatcherStopped": "Pemantau file dihentikan.", + "failedDuringInitialScan": "Gagal selama pemindaian awal: {{errorMessage}}", + "unknownError": "Kesalahan tidak diketahui", + "indexingRequiresWorkspace": "Pengindeksan memerlukan folder workspace yang terbuka" } } diff --git a/src/i18n/locales/it/common.json b/src/i18n/locales/it/common.json index 7ae45cc4c5..a7ef4b075a 100644 --- a/src/i18n/locales/it/common.json +++ b/src/i18n/locales/it/common.json @@ -71,12 +71,24 @@ "share_task_not_found": "Attività non trovata o accesso negato.", "mode_import_failed": "Importazione della modalità non riuscita: {{error}}", "delete_rules_folder_failed": "Impossibile eliminare la cartella delle regole: {{rulesFolderPath}}. Errore: {{error}}", + "command_not_found": "Comando '{{name}}' non trovato", + "open_command_file": "Impossibile aprire il file di comando", + "delete_command": "Impossibile eliminare il comando", + "no_workspace_for_project_command": "Nessuna cartella workspace trovata per il comando di progetto", + "command_already_exists": "Il comando \"{{commandName}}\" esiste già", + "create_command_failed": "Errore nella creazione del comando", + "command_template_content": "---\ndescription: \"Breve descrizione di cosa fa questo comando\"\n---\n\nQuesto è un nuovo comando slash. Modifica questo file per personalizzare il comportamento del comando.", "claudeCode": { "processExited": "Il processo Claude Code è terminato con codice {{exitCode}}.", "errorOutput": "Output di errore: {{output}}", "processExitedWithError": "Il processo Claude Code è terminato con codice {{exitCode}}. Output di errore: {{output}}", "stoppedWithReason": "Claude Code si è fermato per il motivo: {{reason}}", "apiKeyModelPlanMismatch": "Le chiavi API e i piani di abbonamento consentono modelli diversi. Assicurati che il modello selezionato sia incluso nel tuo piano." + }, + "gemini": { + "generate_stream": "Errore del flusso di contesto di generazione Gemini: {{error}}", + "generate_complete_prompt": "Errore di completamento Gemini: {{error}}", + "sources": "Fonti:" } }, "warnings": { diff --git a/src/i18n/locales/it/embeddings.json b/src/i18n/locales/it/embeddings.json index 1bc406aecb..d59bc2c26d 100644 --- a/src/i18n/locales/it/embeddings.json +++ b/src/i18n/locales/it/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "Impossibile determinare la dimensione del vettore per il modello '{{modelId}}' con il provider '{{provider}}'. Controlla i profili del modello o la configurazione.", "qdrantUrlMissing": "URL Qdrant mancante per la creazione dello storage vettoriale", "codeIndexingNotConfigured": "Impossibile creare i servizi: L'indicizzazione del codice non è configurata correttamente" + }, + "orchestrator": { + "indexingFailedNoBlocks": "Indicizzazione fallita: Nessun blocco di codice è stato indicizzato con successo. Questo di solito indica un problema di configurazione dell'embedder.", + "indexingFailedCritical": "Indicizzazione fallita: Nessun blocco di codice è stato indicizzato con successo nonostante siano stati trovati file da elaborare. Questo indica un errore critico dell'embedder.", + "fileWatcherStarted": "Monitoraggio file avviato.", + "fileWatcherStopped": "Monitoraggio file fermato.", + "failedDuringInitialScan": "Fallito durante la scansione iniziale: {{errorMessage}}", + "unknownError": "Errore sconosciuto", + "indexingRequiresWorkspace": "L'indicizzazione richiede una cartella di workspace aperta" } } diff --git a/src/i18n/locales/ja/common.json b/src/i18n/locales/ja/common.json index da8124b48c..6e7e0b8a3e 100644 --- a/src/i18n/locales/ja/common.json +++ b/src/i18n/locales/ja/common.json @@ -71,12 +71,24 @@ "share_task_not_found": "タスクが見つからないか、アクセスが拒否されました。", "mode_import_failed": "モードのインポートに失敗しました:{{error}}", "delete_rules_folder_failed": "ルールフォルダの削除に失敗しました:{{rulesFolderPath}}。エラー:{{error}}", + "command_not_found": "コマンド '{{name}}' が見つかりません", + "open_command_file": "コマンドファイルを開けませんでした", + "delete_command": "コマンドの削除に失敗しました", + "no_workspace_for_project_command": "プロジェクトコマンド用のワークスペースフォルダが見つかりません", + "command_already_exists": "コマンド \"{{commandName}}\" は既に存在します", + "create_command_failed": "コマンドの作成に失敗しました", + "command_template_content": "---\ndescription: \"このコマンドが何をするかの簡潔な説明\"\n---\n\nこれは新しいスラッシュコマンドです。このファイルを編集してコマンドの動作をカスタマイズしてください。", "claudeCode": { "processExited": "Claude Code プロセスがコード {{exitCode}} で終了しました。", "errorOutput": "エラー出力:{{output}}", "processExitedWithError": "Claude Code プロセスがコード {{exitCode}} で終了しました。エラー出力:{{output}}", "stoppedWithReason": "Claude Code が理由により停止しました:{{reason}}", "apiKeyModelPlanMismatch": "API キーとサブスクリプションプランでは異なるモデルが利用可能です。選択したモデルがプランに含まれていることを確認してください。" + }, + "gemini": { + "generate_stream": "Gemini 生成コンテキスト ストリーム エラー: {{error}}", + "generate_complete_prompt": "Gemini 完了エラー: {{error}}", + "sources": "ソース:" } }, "warnings": { diff --git a/src/i18n/locales/ja/embeddings.json b/src/i18n/locales/ja/embeddings.json index 7152eb52df..799c6745fa 100644 --- a/src/i18n/locales/ja/embeddings.json +++ b/src/i18n/locales/ja/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "プロバイダー '{{provider}}' のモデル '{{modelId}}' の埋め込み次元を決定できませんでした。モデルプロファイルまたは設定を確認してください。", "qdrantUrlMissing": "ベクターストア作成のためのQdrant URLがありません", "codeIndexingNotConfigured": "サービスを作成できません: コードインデックスが正しく設定されていません" + }, + "orchestrator": { + "indexingFailedNoBlocks": "インデックス作成に失敗しました:コードブロックが正常にインデックス化されませんでした。これは通常、エンベッダーの設定問題を示しています。", + "indexingFailedCritical": "インデックス作成に失敗しました:処理するファイルが見つかったにもかかわらず、コードブロックが正常にインデックス化されませんでした。これは重大なエンベッダーの障害を示しています。", + "fileWatcherStarted": "ファイルウォッチャーが開始されました。", + "fileWatcherStopped": "ファイルウォッチャーが停止されました。", + "failedDuringInitialScan": "初期スキャン中に失敗しました:{{errorMessage}}", + "unknownError": "不明なエラー", + "indexingRequiresWorkspace": "インデックス作成には、開かれたワークスペースフォルダーが必要です" } } diff --git a/src/i18n/locales/ko/common.json b/src/i18n/locales/ko/common.json index a95908ffec..1d0a5f3c4a 100644 --- a/src/i18n/locales/ko/common.json +++ b/src/i18n/locales/ko/common.json @@ -71,12 +71,24 @@ "share_task_not_found": "작업을 찾을 수 없거나 액세스가 거부되었습니다.", "mode_import_failed": "모드 가져오기 실패: {{error}}", "delete_rules_folder_failed": "규칙 폴더 삭제 실패: {{rulesFolderPath}}. 오류: {{error}}", + "command_not_found": "'{{name}}' 명령을 찾을 수 없습니다", + "open_command_file": "명령 파일을 열 수 없습니다", + "delete_command": "명령 삭제 실패", + "no_workspace_for_project_command": "프로젝트 명령용 워크스페이스 폴더를 찾을 수 없습니다", + "command_already_exists": "명령 \"{{commandName}}\"이(가) 이미 존재합니다", + "create_command_failed": "명령 생성에 실패했습니다", + "command_template_content": "---\ndescription: \"이 명령이 수행하는 작업에 대한 간단한 설명\"\n---\n\n이것은 새로운 슬래시 명령입니다. 이 파일을 편집하여 명령 동작을 사용자 정의하세요.", "claudeCode": { "processExited": "Claude Code 프로세스가 코드 {{exitCode}}로 종료되었습니다.", "errorOutput": "오류 출력: {{output}}", "processExitedWithError": "Claude Code 프로세스가 코드 {{exitCode}}로 종료되었습니다. 오류 출력: {{output}}", "stoppedWithReason": "Claude Code가 다음 이유로 중지되었습니다: {{reason}}", "apiKeyModelPlanMismatch": "API 키와 구독 플랜에서 다른 모델을 허용합니다. 선택한 모델이 플랜에 포함되어 있는지 확인하세요." + }, + "gemini": { + "generate_stream": "Gemini 생성 컨텍스트 스트림 오류: {{error}}", + "generate_complete_prompt": "Gemini 완료 오류: {{error}}", + "sources": "출처:" } }, "warnings": { diff --git a/src/i18n/locales/ko/embeddings.json b/src/i18n/locales/ko/embeddings.json index f1c40f66bc..3817135982 100644 --- a/src/i18n/locales/ko/embeddings.json +++ b/src/i18n/locales/ko/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "프로바이더 '{{provider}}'의 모델 '{{modelId}}'에 대한 벡터 차원을 결정할 수 없습니다. 모델 프로필 또는 구성을 확인하세요.", "qdrantUrlMissing": "벡터 저장소 생성을 위한 Qdrant URL이 누락되었습니다", "codeIndexingNotConfigured": "서비스를 생성할 수 없습니다: 코드 인덱싱이 올바르게 구성되지 않았습니다" + }, + "orchestrator": { + "indexingFailedNoBlocks": "인덱싱 실패: 코드 블록이 성공적으로 인덱싱되지 않았습니다. 이는 일반적으로 임베더 구성 문제를 나타냅니다.", + "indexingFailedCritical": "인덱싱 실패: 처리할 파일을 찾았음에도 불구하고 코드 블록이 성공적으로 인덱싱되지 않았습니다. 이는 중요한 임베더 오류를 나타냅니다.", + "fileWatcherStarted": "파일 감시자가 시작되었습니다.", + "fileWatcherStopped": "파일 감시자가 중지되었습니다.", + "failedDuringInitialScan": "초기 스캔 중 실패: {{errorMessage}}", + "unknownError": "알 수 없는 오류", + "indexingRequiresWorkspace": "인덱싱에는 열린 워크스페이스 폴더가 필요합니다" } } diff --git a/src/i18n/locales/nl/common.json b/src/i18n/locales/nl/common.json index ac7df81e42..bb7d3c0f23 100644 --- a/src/i18n/locales/nl/common.json +++ b/src/i18n/locales/nl/common.json @@ -71,12 +71,24 @@ "share_task_not_found": "Taak niet gevonden of toegang geweigerd.", "mode_import_failed": "Importeren van modus mislukt: {{error}}", "delete_rules_folder_failed": "Kan regelmap niet verwijderen: {{rulesFolderPath}}. Fout: {{error}}", + "command_not_found": "Opdracht '{{name}}' niet gevonden", + "open_command_file": "Kan opdrachtbestand niet openen", + "delete_command": "Kan opdracht niet verwijderen", + "no_workspace_for_project_command": "Geen werkruimtemap gevonden voor projectopdracht", + "command_already_exists": "Opdracht \"{{commandName}}\" bestaat al", + "create_command_failed": "Kan opdracht niet aanmaken", + "command_template_content": "---\ndescription: \"Korte beschrijving van wat deze opdracht doet\"\n---\n\nDit is een nieuwe slash-opdracht. Bewerk dit bestand om het opdrachtgedrag aan te passen.", "claudeCode": { "processExited": "Claude Code proces beëindigd met code {{exitCode}}.", "errorOutput": "Foutuitvoer: {{output}}", "processExitedWithError": "Claude Code proces beëindigd met code {{exitCode}}. Foutuitvoer: {{output}}", "stoppedWithReason": "Claude Code gestopt om reden: {{reason}}", "apiKeyModelPlanMismatch": "API-sleutels en abonnementsplannen staan verschillende modellen toe. Zorg ervoor dat het geselecteerde model is opgenomen in je plan." + }, + "gemini": { + "generate_stream": "Fout bij het genereren van contextstream door Gemini: {{error}}", + "generate_complete_prompt": "Fout bij het voltooien door Gemini: {{error}}", + "sources": "Bronnen:" } }, "warnings": { diff --git a/src/i18n/locales/nl/embeddings.json b/src/i18n/locales/nl/embeddings.json index 19b7bfeaa2..52d675c890 100644 --- a/src/i18n/locales/nl/embeddings.json +++ b/src/i18n/locales/nl/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "Kan de vectordimensie voor model '{{modelId}}' met provider '{{provider}}' niet bepalen. Controleer modelprofielen of configuratie.", "qdrantUrlMissing": "Qdrant URL ontbreekt voor het maken van vectoropslag", "codeIndexingNotConfigured": "Kan geen services maken: Code-indexering is niet correct geconfigureerd" + }, + "orchestrator": { + "indexingFailedNoBlocks": "Indexering mislukt: Geen codeblokken werden succesvol geïndexeerd. Dit duidt meestal op een embedder configuratieprobleem.", + "indexingFailedCritical": "Indexering mislukt: Geen codeblokken werden succesvol geïndexeerd ondanks het vinden van bestanden om te verwerken. Dit duidt op een kritieke embedder fout.", + "fileWatcherStarted": "Bestandsmonitor gestart.", + "fileWatcherStopped": "Bestandsmonitor gestopt.", + "failedDuringInitialScan": "Mislukt tijdens initiële scan: {{errorMessage}}", + "unknownError": "Onbekende fout", + "indexingRequiresWorkspace": "Indexering vereist een geopende workspace map" } } diff --git a/src/i18n/locales/pl/common.json b/src/i18n/locales/pl/common.json index e24960af89..953f52ea79 100644 --- a/src/i18n/locales/pl/common.json +++ b/src/i18n/locales/pl/common.json @@ -71,12 +71,24 @@ "share_task_not_found": "Zadanie nie znalezione lub dostęp odmówiony.", "mode_import_failed": "Import trybu nie powiódł się: {{error}}", "delete_rules_folder_failed": "Nie udało się usunąć folderu reguł: {{rulesFolderPath}}. Błąd: {{error}}", + "command_not_found": "Polecenie '{{name}}' nie zostało znalezione", + "open_command_file": "Nie udało się otworzyć pliku polecenia", + "delete_command": "Nie udało się usunąć polecenia", + "no_workspace_for_project_command": "Nie znaleziono folderu obszaru roboczego dla polecenia projektu", + "command_already_exists": "Polecenie \"{{commandName}}\" już istnieje", + "create_command_failed": "Nie udało się utworzyć polecenia", + "command_template_content": "---\ndescription: \"Krótki opis tego, co robi to polecenie\"\n---\n\nTo jest nowe polecenie slash. Edytuj ten plik, aby dostosować zachowanie polecenia.", "claudeCode": { "processExited": "Proces Claude Code zakończył się kodem {{exitCode}}.", "errorOutput": "Wyjście błędu: {{output}}", "processExitedWithError": "Proces Claude Code zakończył się kodem {{exitCode}}. Wyjście błędu: {{output}}", "stoppedWithReason": "Claude Code zatrzymał się z powodu: {{reason}}", "apiKeyModelPlanMismatch": "Klucze API i plany subskrypcji pozwalają na różne modele. Upewnij się, że wybrany model jest zawarty w twoim planie." + }, + "gemini": { + "generate_stream": "Błąd strumienia kontekstu generowania Gemini: {{error}}", + "generate_complete_prompt": "Błąd uzupełniania Gemini: {{error}}", + "sources": "Źródła:" } }, "warnings": { diff --git a/src/i18n/locales/pl/embeddings.json b/src/i18n/locales/pl/embeddings.json index 46e761cb8b..4d1ad0316c 100644 --- a/src/i18n/locales/pl/embeddings.json +++ b/src/i18n/locales/pl/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "Nie można określić wymiaru wektora dla modelu '{{modelId}}' z dostawcą '{{provider}}'. Sprawdź profile modelu lub konfigurację.", "qdrantUrlMissing": "Brak adresu URL Qdrant do utworzenia magazynu wektorów", "codeIndexingNotConfigured": "Nie można utworzyć usług: Indeksowanie kodu nie jest poprawnie skonfigurowane" + }, + "orchestrator": { + "indexingFailedNoBlocks": "Indeksowanie nie powiodło się: Żadne bloki kodu nie zostały pomyślnie zaindeksowane. To zwykle wskazuje na problem z konfiguracją embeddera.", + "indexingFailedCritical": "Indeksowanie nie powiodło się: Żadne bloki kodu nie zostały pomyślnie zaindeksowane pomimo znalezienia plików do przetworzenia. To wskazuje na krytyczny błąd embeddera.", + "fileWatcherStarted": "Monitor plików uruchomiony.", + "fileWatcherStopped": "Monitor plików zatrzymany.", + "failedDuringInitialScan": "Niepowodzenie podczas początkowego skanowania: {{errorMessage}}", + "unknownError": "Nieznany błąd", + "indexingRequiresWorkspace": "Indeksowanie wymaga otwartego folderu workspace" } } diff --git a/src/i18n/locales/pt-BR/common.json b/src/i18n/locales/pt-BR/common.json index 6007beb41a..21aca727a1 100644 --- a/src/i18n/locales/pt-BR/common.json +++ b/src/i18n/locales/pt-BR/common.json @@ -75,12 +75,24 @@ "share_task_not_found": "Tarefa não encontrada ou acesso negado.", "mode_import_failed": "Falha ao importar o modo: {{error}}", "delete_rules_folder_failed": "Falha ao excluir pasta de regras: {{rulesFolderPath}}. Erro: {{error}}", + "command_not_found": "Comando '{{name}}' não encontrado", + "open_command_file": "Falha ao abrir arquivo de comando", + "delete_command": "Falha ao excluir comando", + "no_workspace_for_project_command": "Nenhuma pasta de workspace encontrada para comando de projeto", + "command_already_exists": "Comando \"{{commandName}}\" já existe", + "create_command_failed": "Falha ao criar comando", + "command_template_content": "---\ndescription: \"Breve descrição do que este comando faz\"\n---\n\nEste é um novo comando slash. Edite este arquivo para personalizar o comportamento do comando.", "claudeCode": { "processExited": "O processo Claude Code saiu com código {{exitCode}}.", "errorOutput": "Saída de erro: {{output}}", "processExitedWithError": "O processo Claude Code saiu com código {{exitCode}}. Saída de erro: {{output}}", "stoppedWithReason": "Claude Code parou pela razão: {{reason}}", "apiKeyModelPlanMismatch": "Chaves de API e planos de assinatura permitem modelos diferentes. Certifique-se de que o modelo selecionado esteja incluído no seu plano." + }, + "gemini": { + "generate_stream": "Erro de fluxo de contexto de geração do Gemini: {{error}}", + "generate_complete_prompt": "Erro de conclusão do Gemini: {{error}}", + "sources": "Fontes:" } }, "warnings": { diff --git a/src/i18n/locales/pt-BR/embeddings.json b/src/i18n/locales/pt-BR/embeddings.json index 816b1ecded..875bba95dc 100644 --- a/src/i18n/locales/pt-BR/embeddings.json +++ b/src/i18n/locales/pt-BR/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "Não foi possível determinar a dimensão do vetor para o modelo '{{modelId}}' com o provedor '{{provider}}'. Verifique os perfis do modelo ou a configuração.", "qdrantUrlMissing": "URL do Qdrant ausente para criação do armazenamento de vetores", "codeIndexingNotConfigured": "Não é possível criar serviços: A indexação de código não está configurada corretamente" + }, + "orchestrator": { + "indexingFailedNoBlocks": "Indexação falhou: Nenhum bloco de código foi indexado com sucesso. Isso geralmente indica um problema de configuração do embedder.", + "indexingFailedCritical": "Indexação falhou: Nenhum bloco de código foi indexado com sucesso apesar de encontrar arquivos para processar. Isso indica uma falha crítica do embedder.", + "fileWatcherStarted": "Monitor de arquivos iniciado.", + "fileWatcherStopped": "Monitor de arquivos parado.", + "failedDuringInitialScan": "Falhou durante a varredura inicial: {{errorMessage}}", + "unknownError": "Erro desconhecido", + "indexingRequiresWorkspace": "A indexação requer uma pasta de workspace aberta" } } diff --git a/src/i18n/locales/ru/common.json b/src/i18n/locales/ru/common.json index 4d3daaf743..30913e16e9 100644 --- a/src/i18n/locales/ru/common.json +++ b/src/i18n/locales/ru/common.json @@ -71,12 +71,24 @@ "share_task_not_found": "Задача не найдена или доступ запрещен.", "mode_import_failed": "Не удалось импортировать режим: {{error}}", "delete_rules_folder_failed": "Не удалось удалить папку правил: {{rulesFolderPath}}. Ошибка: {{error}}", + "command_not_found": "Команда '{{name}}' не найдена", + "open_command_file": "Не удалось открыть файл команды", + "delete_command": "Не удалось удалить команду", + "no_workspace_for_project_command": "Не найдена папка рабочего пространства для команды проекта", + "command_already_exists": "Команда \"{{commandName}}\" уже существует", + "create_command_failed": "Не удалось создать команду", + "command_template_content": "---\ndescription: \"Краткое описание того, что делает эта команда\"\n---\n\nЭто новая slash-команда. Отредактируйте этот файл, чтобы настроить поведение команды.", "claudeCode": { "processExited": "Процесс Claude Code завершился с кодом {{exitCode}}.", "errorOutput": "Вывод ошибки: {{output}}", "processExitedWithError": "Процесс Claude Code завершился с кодом {{exitCode}}. Вывод ошибки: {{output}}", "stoppedWithReason": "Claude Code остановился по причине: {{reason}}", "apiKeyModelPlanMismatch": "API-ключи и планы подписки позволяют использовать разные модели. Убедитесь, что выбранная модель включена в ваш план." + }, + "gemini": { + "generate_stream": "Ошибка потока контекста генерации Gemini: {{error}}", + "generate_complete_prompt": "Ошибка завершения Gemini: {{error}}", + "sources": "Источники:" } }, "warnings": { diff --git a/src/i18n/locales/ru/embeddings.json b/src/i18n/locales/ru/embeddings.json index fb1688e2ca..80dfa9a594 100644 --- a/src/i18n/locales/ru/embeddings.json +++ b/src/i18n/locales/ru/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "Не удалось определить размерность вектора для модели '{{modelId}}' с провайдером '{{provider}}'. Проверьте профили модели или конфигурацию.", "qdrantUrlMissing": "Отсутствует URL Qdrant для создания векторного хранилища", "codeIndexingNotConfigured": "Невозможно создать сервисы: Индексация кода не настроена должным образом" + }, + "orchestrator": { + "indexingFailedNoBlocks": "Индексация не удалась: Ни один блок кода не был успешно проиндексирован. Это обычно указывает на проблему конфигурации эмбеддера.", + "indexingFailedCritical": "Индексация не удалась: Ни один блок кода не был успешно проиндексирован, несмотря на обнаружение файлов для обработки. Это указывает на критическую ошибку эмбеддера.", + "fileWatcherStarted": "Наблюдатель файлов запущен.", + "fileWatcherStopped": "Наблюдатель файлов остановлен.", + "failedDuringInitialScan": "Ошибка во время первоначального сканирования: {{errorMessage}}", + "unknownError": "Неизвестная ошибка", + "indexingRequiresWorkspace": "Для индексации требуется открытая папка рабочего пространства" } } diff --git a/src/i18n/locales/tr/common.json b/src/i18n/locales/tr/common.json index e2dfca734b..6892c7c8f1 100644 --- a/src/i18n/locales/tr/common.json +++ b/src/i18n/locales/tr/common.json @@ -71,12 +71,24 @@ "share_task_not_found": "Görev bulunamadı veya erişim reddedildi.", "mode_import_failed": "Mod içe aktarılamadı: {{error}}", "delete_rules_folder_failed": "Kurallar klasörü silinemedi: {{rulesFolderPath}}. Hata: {{error}}", + "command_not_found": "'{{name}}' komutu bulunamadı", + "open_command_file": "Komut dosyası açılamadı", + "delete_command": "Komut silinemedi", + "no_workspace_for_project_command": "Proje komutu için çalışma alanı klasörü bulunamadı", + "command_already_exists": "\"{{commandName}}\" komutu zaten mevcut", + "create_command_failed": "Komut oluşturulamadı", + "command_template_content": "---\ndescription: \"Bu komutun ne yaptığının kısa açıklaması\"\n---\n\nBu yeni bir slash komutudur. Komut davranışını özelleştirmek için bu dosyayı düzenleyin.", "claudeCode": { "processExited": "Claude Code işlemi {{exitCode}} koduyla çıktı.", "errorOutput": "Hata çıktısı: {{output}}", "processExitedWithError": "Claude Code işlemi {{exitCode}} koduyla çıktı. Hata çıktısı: {{output}}", "stoppedWithReason": "Claude Code şu nedenle durdu: {{reason}}", "apiKeyModelPlanMismatch": "API anahtarları ve abonelik planları farklı modellere izin verir. Seçilen modelin planınıza dahil olduğundan emin olun." + }, + "gemini": { + "generate_stream": "Gemini oluşturma bağlam akışı hatası: {{error}}", + "generate_complete_prompt": "Gemini tamamlama hatası: {{error}}", + "sources": "Kaynaklar:" } }, "warnings": { diff --git a/src/i18n/locales/tr/embeddings.json b/src/i18n/locales/tr/embeddings.json index 5023190929..ba717b7c82 100644 --- a/src/i18n/locales/tr/embeddings.json +++ b/src/i18n/locales/tr/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "'{{provider}}' sağlayıcısı ile '{{modelId}}' modeli için vektör boyutu belirlenemedi. Model profillerini veya yapılandırmayı kontrol et.", "qdrantUrlMissing": "Vektör deposu oluşturmak için Qdrant URL'si eksik", "codeIndexingNotConfigured": "Hizmetler oluşturulamıyor: Kod indeksleme düzgün yapılandırılmamış" + }, + "orchestrator": { + "indexingFailedNoBlocks": "İndeksleme başarısız: Hiçbir kod bloğu başarıyla indekslenemedi. Bu genellikle bir embedder yapılandırma sorunu olduğunu gösterir.", + "indexingFailedCritical": "İndeksleme başarısız: İşlenecek dosyalar bulunmasına rağmen hiçbir kod bloğu başarıyla indekslenemedi. Bu kritik bir embedder hatası olduğunu gösterir.", + "fileWatcherStarted": "Dosya izleyici başlatıldı.", + "fileWatcherStopped": "Dosya izleyici durduruldu.", + "failedDuringInitialScan": "İlk tarama sırasında başarısız: {{errorMessage}}", + "unknownError": "Bilinmeyen hata", + "indexingRequiresWorkspace": "İndeksleme açık bir workspace klasörü gerektirir" } } diff --git a/src/i18n/locales/vi/common.json b/src/i18n/locales/vi/common.json index 15e4ef8b77..f88120098d 100644 --- a/src/i18n/locales/vi/common.json +++ b/src/i18n/locales/vi/common.json @@ -71,12 +71,24 @@ "share_task_not_found": "Không tìm thấy nhiệm vụ hoặc truy cập bị từ chối.", "mode_import_failed": "Nhập chế độ thất bại: {{error}}", "delete_rules_folder_failed": "Không thể xóa thư mục quy tắc: {{rulesFolderPath}}. Lỗi: {{error}}", + "command_not_found": "Không tìm thấy lệnh '{{name}}'", + "open_command_file": "Không thể mở tệp lệnh", + "delete_command": "Không thể xóa lệnh", + "no_workspace_for_project_command": "Không tìm thấy thư mục workspace cho lệnh dự án", + "command_already_exists": "Lệnh \"{{commandName}}\" đã tồn tại", + "create_command_failed": "Không thể tạo lệnh", + "command_template_content": "---\ndescription: \"Mô tả ngắn gọn về chức năng của lệnh này\"\n---\n\nĐây là một lệnh slash mới. Chỉnh sửa tệp này để tùy chỉnh hành vi của lệnh.", "claudeCode": { "processExited": "Tiến trình Claude Code thoát với mã {{exitCode}}.", "errorOutput": "Đầu ra lỗi: {{output}}", "processExitedWithError": "Tiến trình Claude Code thoát với mã {{exitCode}}. Đầu ra lỗi: {{output}}", "stoppedWithReason": "Claude Code dừng lại vì lý do: {{reason}}", "apiKeyModelPlanMismatch": "Khóa API và gói đăng ký cho phép các mô hình khác nhau. Đảm bảo rằng mô hình đã chọn được bao gồm trong gói của bạn." + }, + "gemini": { + "generate_stream": "Lỗi luồng ngữ cảnh tạo Gemini: {{error}}", + "generate_complete_prompt": "Lỗi hoàn thành Gemini: {{error}}", + "sources": "Nguồn:" } }, "warnings": { diff --git a/src/i18n/locales/vi/embeddings.json b/src/i18n/locales/vi/embeddings.json index 626f0f6862..12980b3345 100644 --- a/src/i18n/locales/vi/embeddings.json +++ b/src/i18n/locales/vi/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "Không thể xác định kích thước vector cho mô hình '{{modelId}}' với nhà cung cấp '{{provider}}'. Kiểm tra hồ sơ mô hình hoặc cấu hình.", "qdrantUrlMissing": "Thiếu URL Qdrant để tạo kho lưu trữ vector", "codeIndexingNotConfigured": "Không thể tạo dịch vụ: Lập chỉ mục mã không được cấu hình đúng cách" + }, + "orchestrator": { + "indexingFailedNoBlocks": "Lập chỉ mục thất bại: Không có khối mã nào được lập chỉ mục thành công. Điều này thường cho thấy vấn đề cấu hình embedder.", + "indexingFailedCritical": "Lập chỉ mục thất bại: Không có khối mã nào được lập chỉ mục thành công mặc dù đã tìm thấy tệp để xử lý. Điều này cho thấy lỗi nghiêm trọng của embedder.", + "fileWatcherStarted": "Trình theo dõi tệp đã khởi động.", + "fileWatcherStopped": "Trình theo dõi tệp đã dừng.", + "failedDuringInitialScan": "Thất bại trong quá trình quét ban đầu: {{errorMessage}}", + "unknownError": "Lỗi không xác định", + "indexingRequiresWorkspace": "Lập chỉ mục yêu cầu một thư mục workspace đang mở" } } diff --git a/src/i18n/locales/zh-CN/common.json b/src/i18n/locales/zh-CN/common.json index edbbb6ae8c..e81b7d589a 100644 --- a/src/i18n/locales/zh-CN/common.json +++ b/src/i18n/locales/zh-CN/common.json @@ -76,12 +76,24 @@ "share_task_not_found": "未找到任务或访问被拒绝。", "mode_import_failed": "导入模式失败:{{error}}", "delete_rules_folder_failed": "删除规则文件夹失败:{{rulesFolderPath}}。错误:{{error}}", + "command_not_found": "未找到命令 '{{name}}'", + "open_command_file": "打开命令文件失败", + "delete_command": "删除命令失败", + "no_workspace_for_project_command": "未找到项目命令的工作区文件夹", + "command_already_exists": "命令 \"{{commandName}}\" 已存在", + "create_command_failed": "创建命令失败", + "command_template_content": "---\ndescription: \"此命令功能的简要描述\"\n---\n\n这是一个新的斜杠命令。编辑此文件以自定义命令行为。", "claudeCode": { "processExited": "Claude Code 进程退出,退出码:{{exitCode}}。", "errorOutput": "错误输出:{{output}}", "processExitedWithError": "Claude Code 进程退出,退出码:{{exitCode}}。错误输出:{{output}}", "stoppedWithReason": "Claude Code 停止,原因:{{reason}}", "apiKeyModelPlanMismatch": "API 密钥和订阅计划支持不同的模型。请确保所选模型包含在您的计划中。" + }, + "gemini": { + "generate_stream": "Gemini 生成上下文流错误:{{error}}", + "generate_complete_prompt": "Gemini 完成错误:{{error}}", + "sources": "来源:" } }, "warnings": { diff --git a/src/i18n/locales/zh-CN/embeddings.json b/src/i18n/locales/zh-CN/embeddings.json index 3247631bb2..1589689c06 100644 --- a/src/i18n/locales/zh-CN/embeddings.json +++ b/src/i18n/locales/zh-CN/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "无法确定提供商 '{{provider}}' 的模型 '{{modelId}}' 的向量维度。请检查模型配置文件或配置。", "qdrantUrlMissing": "创建向量存储缺少 Qdrant URL", "codeIndexingNotConfigured": "无法创建服务:代码索引未正确配置" + }, + "orchestrator": { + "indexingFailedNoBlocks": "索引失败:没有代码块被成功索引。这通常表示 Embedder 配置问题。", + "indexingFailedCritical": "索引失败:尽管找到了要处理的文件,但没有代码块被成功索引。这表示 Embedder 出现严重故障。", + "fileWatcherStarted": "文件监控已启动。", + "fileWatcherStopped": "文件监控已停止。", + "failedDuringInitialScan": "初始扫描失败:{{errorMessage}}", + "unknownError": "未知错误", + "indexingRequiresWorkspace": "索引需要打开的工作区文件夹" } } diff --git a/src/i18n/locales/zh-TW/common.json b/src/i18n/locales/zh-TW/common.json index e7887025f1..1c800d4d37 100644 --- a/src/i18n/locales/zh-TW/common.json +++ b/src/i18n/locales/zh-TW/common.json @@ -70,6 +70,13 @@ "share_not_enabled": "此組織未啟用工作分享功能。", "share_task_not_found": "未找到工作或存取被拒絕。", "delete_rules_folder_failed": "刪除規則資料夾失敗: {{rulesFolderPath}}。錯誤: {{error}}", + "command_not_found": "找不到指令 '{{name}}'", + "open_command_file": "開啟指令檔案失敗", + "delete_command": "刪除指令失敗", + "no_workspace_for_project_command": "找不到專案指令的工作區資料夾", + "command_already_exists": "指令 \"{{commandName}}\" 已存在", + "create_command_failed": "建立指令失敗", + "command_template_content": "---\ndescription: \"此指令功能的簡要描述\"\n---\n\n這是一個新的斜線指令。編輯此檔案以自訂指令行為。", "claudeCode": { "processExited": "Claude Code 程序退出,退出碼:{{exitCode}}。", "errorOutput": "錯誤輸出:{{output}}", @@ -77,6 +84,11 @@ "stoppedWithReason": "Claude Code 停止,原因:{{reason}}", "apiKeyModelPlanMismatch": "API 金鑰和訂閱方案允許不同的模型。請確保所選模型包含在您的方案中。" }, + "gemini": { + "generate_stream": "Gemini 產生內容串流錯誤:{{error}}", + "generate_complete_prompt": "Gemini 完成錯誤:{{error}}", + "sources": "來源:" + }, "mode_import_failed": "匯入模式失敗:{{error}}" }, "warnings": { diff --git a/src/i18n/locales/zh-TW/embeddings.json b/src/i18n/locales/zh-TW/embeddings.json index b3b3231d4a..2dc41221f3 100644 --- a/src/i18n/locales/zh-TW/embeddings.json +++ b/src/i18n/locales/zh-TW/embeddings.json @@ -52,5 +52,14 @@ "vectorDimensionNotDetermined": "無法確定提供商 '{{provider}}' 的模型 '{{modelId}}' 的向量維度。請檢查模型設定檔或設定。", "qdrantUrlMissing": "建立向量儲存缺少 Qdrant URL", "codeIndexingNotConfigured": "無法建立服務:程式碼索引未正確設定" + }, + "orchestrator": { + "indexingFailedNoBlocks": "索引失敗:沒有程式碼區塊被成功索引。這通常表示 Embedder 設定問題。", + "indexingFailedCritical": "索引失敗:儘管找到了要處理的檔案,但沒有程式碼區塊被成功索引。這表示 Embedder 出現嚴重故障。", + "fileWatcherStarted": "檔案監控已啟動。", + "fileWatcherStopped": "檔案監控已停止。", + "failedDuringInitialScan": "初始掃描失敗:{{errorMessage}}", + "unknownError": "未知錯誤", + "indexingRequiresWorkspace": "索引需要開啟的工作區資料夾" } } diff --git a/src/integrations/misc/__tests__/extract-text-large-files.spec.ts b/src/integrations/misc/__tests__/extract-text-large-files.spec.ts new file mode 100644 index 0000000000..fc2f7f54b6 --- /dev/null +++ b/src/integrations/misc/__tests__/extract-text-large-files.spec.ts @@ -0,0 +1,221 @@ +// npx vitest run integrations/misc/__tests__/extract-text-large-files.spec.ts + +import { describe, it, expect, vi, beforeEach, Mock } from "vitest" +import * as fs from "fs/promises" +import { extractTextFromFile } from "../extract-text" +import { countFileLines } from "../line-counter" +import { readLines } from "../read-lines" +import { isBinaryFile } from "isbinaryfile" + +// Mock all dependencies +vi.mock("fs/promises") +vi.mock("../line-counter") +vi.mock("../read-lines") +vi.mock("isbinaryfile") + +describe("extractTextFromFile - Large File Handling", () => { + // Type the mocks + const mockedFs = vi.mocked(fs) + const mockedCountFileLines = vi.mocked(countFileLines) + const mockedReadLines = vi.mocked(readLines) + const mockedIsBinaryFile = vi.mocked(isBinaryFile) + + beforeEach(() => { + vi.clearAllMocks() + // Set default mock behavior + mockedFs.access.mockResolvedValue(undefined) + mockedIsBinaryFile.mockResolvedValue(false) + }) + + it("should truncate files that exceed maxReadFileLine limit", async () => { + const largeFileContent = Array(150) + .fill(null) + .map((_, i) => `Line ${i + 1}: This is a test line with some content`) + .join("\n") + + mockedCountFileLines.mockResolvedValue(150) + mockedReadLines.mockResolvedValue( + Array(100) + .fill(null) + .map((_, i) => `Line ${i + 1}: This is a test line with some content`) + .join("\n"), + ) + + const result = await extractTextFromFile("/test/large-file.ts", 100) + + // Should only include first 100 lines with line numbers + expect(result).toContain(" 1 | Line 1: This is a test line with some content") + expect(result).toContain("100 | Line 100: This is a test line with some content") + expect(result).not.toContain("101 | Line 101: This is a test line with some content") + + // Should include truncation message + expect(result).toContain( + "[File truncated: showing 100 of 150 total lines. The file is too large and may exhaust the context window if read in full.]", + ) + }) + + it("should not truncate files within the maxReadFileLine limit", async () => { + const smallFileContent = Array(50) + .fill(null) + .map((_, i) => `Line ${i + 1}: This is a test line`) + .join("\n") + + mockedCountFileLines.mockResolvedValue(50) + mockedFs.readFile.mockResolvedValue(smallFileContent as any) + + const result = await extractTextFromFile("/test/small-file.ts", 100) + + // Should include all lines with line numbers + expect(result).toContain(" 1 | Line 1: This is a test line") + expect(result).toContain("50 | Line 50: This is a test line") + + // Should not include truncation message + expect(result).not.toContain("[File truncated:") + }) + + it("should handle files with exactly maxReadFileLine lines", async () => { + const exactFileContent = Array(100) + .fill(null) + .map((_, i) => `Line ${i + 1}`) + .join("\n") + + mockedCountFileLines.mockResolvedValue(100) + mockedFs.readFile.mockResolvedValue(exactFileContent as any) + + const result = await extractTextFromFile("/test/exact-file.ts", 100) + + // Should include all lines with line numbers + expect(result).toContain(" 1 | Line 1") + expect(result).toContain("100 | Line 100") + + // Should not include truncation message + expect(result).not.toContain("[File truncated:") + }) + + it("should handle undefined maxReadFileLine by not truncating", async () => { + const largeFileContent = Array(200) + .fill(null) + .map((_, i) => `Line ${i + 1}`) + .join("\n") + + mockedFs.readFile.mockResolvedValue(largeFileContent as any) + + const result = await extractTextFromFile("/test/large-file.ts", undefined) + + // Should include all lines with line numbers when maxReadFileLine is undefined + expect(result).toContain(" 1 | Line 1") + expect(result).toContain("200 | Line 200") + + // Should not include truncation message + expect(result).not.toContain("[File truncated:") + }) + + it("should handle empty files", async () => { + mockedFs.readFile.mockResolvedValue("" as any) + + const result = await extractTextFromFile("/test/empty-file.ts", 100) + + expect(result).toBe("") + expect(result).not.toContain("[File truncated:") + }) + + it("should handle files with only newlines", async () => { + const newlineOnlyContent = "\n\n\n\n\n" + + mockedCountFileLines.mockResolvedValue(6) // 5 newlines = 6 lines + mockedReadLines.mockResolvedValue("\n\n") + + const result = await extractTextFromFile("/test/newline-file.ts", 3) + + // Should truncate at line 3 + expect(result).toContain("[File truncated: showing 3 of 6 total lines") + }) + + it("should handle very large files efficiently", async () => { + // Simulate a 10,000 line file + mockedCountFileLines.mockResolvedValue(10000) + mockedReadLines.mockResolvedValue( + Array(500) + .fill(null) + .map((_, i) => `Line ${i + 1}: Some content here`) + .join("\n"), + ) + + const result = await extractTextFromFile("/test/very-large-file.ts", 500) + + // Should only include first 500 lines with line numbers + expect(result).toContain(" 1 | Line 1: Some content here") + expect(result).toContain("500 | Line 500: Some content here") + expect(result).not.toContain("501 | Line 501: Some content here") + + // Should show truncation message + expect(result).toContain("[File truncated: showing 500 of 10000 total lines") + }) + + it("should handle maxReadFileLine of 0 by throwing an error", async () => { + const fileContent = "Line 1\nLine 2\nLine 3" + + mockedFs.readFile.mockResolvedValue(fileContent as any) + + // maxReadFileLine of 0 should throw an error + await expect(extractTextFromFile("/test/file.ts", 0)).rejects.toThrow( + "Invalid maxReadFileLine: 0. Must be a positive integer or -1 for unlimited.", + ) + }) + + it("should handle negative maxReadFileLine by treating as undefined", async () => { + const fileContent = "Line 1\nLine 2\nLine 3" + + mockedFs.readFile.mockResolvedValue(fileContent as any) + + const result = await extractTextFromFile("/test/file.ts", -1) + + // Should include all content with line numbers when negative + expect(result).toContain("1 | Line 1") + expect(result).toContain("2 | Line 2") + expect(result).toContain("3 | Line 3") + expect(result).not.toContain("[File truncated:") + }) + + it("should preserve file content structure when truncating", async () => { + const structuredContent = [ + "function example() {", + " const x = 1;", + " const y = 2;", + " return x + y;", + "}", + "", + "// More code below", + ].join("\n") + + mockedCountFileLines.mockResolvedValue(7) + mockedReadLines.mockResolvedValue(["function example() {", " const x = 1;", " const y = 2;"].join("\n")) + + const result = await extractTextFromFile("/test/structured.ts", 3) + + // Should preserve the first 3 lines with line numbers + expect(result).toContain("1 | function example() {") + expect(result).toContain("2 | const x = 1;") + expect(result).toContain("3 | const y = 2;") + expect(result).not.toContain("4 | return x + y;") + + // Should include truncation info + expect(result).toContain("[File truncated: showing 3 of 7 total lines") + }) + + it("should handle binary files by throwing an error", async () => { + mockedIsBinaryFile.mockResolvedValue(true) + + await expect(extractTextFromFile("/test/binary.bin", 100)).rejects.toThrow( + "Cannot read text for file type: .bin", + ) + }) + + it("should handle file not found errors", async () => { + mockedFs.access.mockRejectedValue(new Error("ENOENT")) + + await expect(extractTextFromFile("/test/nonexistent.ts", 100)).rejects.toThrow( + "File not found: /test/nonexistent.ts", + ) + }) +}) diff --git a/src/integrations/misc/extract-text.ts b/src/integrations/misc/extract-text.ts index eb02f63b95..8231c609be 100644 --- a/src/integrations/misc/extract-text.ts +++ b/src/integrations/misc/extract-text.ts @@ -5,6 +5,8 @@ import mammoth from "mammoth" import fs from "fs/promises" import { isBinaryFile } from "isbinaryfile" import { extractTextFromXLSX } from "./extract-text-from-xlsx" +import { countFileLines } from "./line-counter" +import { readLines } from "./read-lines" async function extractTextFromPDF(filePath: string): Promise { const dataBuffer = await fs.readFile(filePath) @@ -48,7 +50,27 @@ export function getSupportedBinaryFormats(): string[] { return Object.keys(SUPPORTED_BINARY_FORMATS) } -export async function extractTextFromFile(filePath: string): Promise { +/** + * Extracts text content from a file, with support for various formats including PDF, DOCX, XLSX, and plain text. + * For large text files, can limit the number of lines read to prevent context exhaustion. + * + * @param filePath - Path to the file to extract text from + * @param maxReadFileLine - Maximum number of lines to read from text files. + * Use UNLIMITED_LINES (-1) or undefined for no limit. + * Must be a positive integer or UNLIMITED_LINES. + * @returns Promise resolving to the extracted text content with line numbers + * @throws {Error} If file not found, unsupported format, or invalid parameters + */ +export async function extractTextFromFile(filePath: string, maxReadFileLine?: number): Promise { + // Validate maxReadFileLine parameter + if (maxReadFileLine !== undefined && maxReadFileLine !== -1) { + if (!Number.isInteger(maxReadFileLine) || maxReadFileLine < 1) { + throw new Error( + `Invalid maxReadFileLine: ${maxReadFileLine}. Must be a positive integer or -1 for unlimited.`, + ) + } + } + try { await fs.access(filePath) } catch (error) { @@ -67,6 +89,20 @@ export async function extractTextFromFile(filePath: string): Promise { const isBinary = await isBinaryFile(filePath).catch(() => false) if (!isBinary) { + // Check if we need to apply line limit + if (maxReadFileLine !== undefined && maxReadFileLine !== -1) { + const totalLines = await countFileLines(filePath) + if (totalLines > maxReadFileLine) { + // Read only up to maxReadFileLine (endLine is 0-based and inclusive) + const content = await readLines(filePath, maxReadFileLine - 1, 0) + const numberedContent = addLineNumbers(content) + return ( + numberedContent + + `\n\n[File truncated: showing ${maxReadFileLine} of ${totalLines} total lines. The file is too large and may exhaust the context window if read in full.]` + ) + } + } + // Read the entire file if no limit or file is within limit return addLineNumbers(await fs.readFile(filePath, "utf8")) } else { throw new Error(`Cannot read text for file type: ${fileExtension}`) diff --git a/src/package.json b/src/package.json index 1fac5fb365..954082185a 100644 --- a/src/package.json +++ b/src/package.json @@ -3,7 +3,7 @@ "displayName": "%extension.displayName%", "description": "%extension.description%", "publisher": "RooVeterinaryInc", - "version": "3.23.19", + "version": "3.24.0", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", @@ -413,8 +413,8 @@ "@anthropic-ai/bedrock-sdk": "^0.10.2", "@anthropic-ai/sdk": "^0.37.0", "@anthropic-ai/vertex-sdk": "^0.7.0", - "@aws-sdk/client-bedrock-runtime": "^3.779.0", - "@aws-sdk/credential-providers": "^3.806.0", + "@aws-sdk/client-bedrock-runtime": "^3.848.0", + "@aws-sdk/credential-providers": "^3.848.0", "@google/genai": "^1.0.0", "@lmstudio/sdk": "^1.1.1", "@mistralai/mistralai": "^1.3.6", @@ -442,6 +442,7 @@ "fzf": "^0.5.2", "get-folder-size": "^5.0.0", "google-auth-library": "^9.15.1", + "gray-matter": "^4.0.3", "i18next": "^25.0.0", "ignore": "^7.0.3", "isbinaryfile": "^5.0.2", diff --git a/src/services/code-index/embedders/__tests__/ollama.spec.ts b/src/services/code-index/embedders/__tests__/ollama.spec.ts index ad95a18a3a..253158dd50 100644 --- a/src/services/code-index/embedders/__tests__/ollama.spec.ts +++ b/src/services/code-index/embedders/__tests__/ollama.spec.ts @@ -80,6 +80,90 @@ describe("CodeIndexOllamaEmbedder", () => { const embedderWithDefaults = new CodeIndexOllamaEmbedder({}) expect(embedderWithDefaults.embedderInfo.name).toBe("ollama") }) + + it("should normalize URLs with trailing slashes", async () => { + // Create embedder with URL that has a trailing slash + const embedderWithTrailingSlash = new CodeIndexOllamaEmbedder({ + ollamaBaseUrl: "http://localhost:11434/", + ollamaModelId: "nomic-embed-text", + }) + + // Mock successful /api/tags call to test the normalized URL + mockFetch.mockImplementationOnce(() => + Promise.resolve({ + ok: true, + status: 200, + json: () => Promise.resolve({ models: [{ name: "nomic-embed-text" }] }), + } as Response), + ) + + // Call a method that uses the baseUrl + await embedderWithTrailingSlash.validateConfiguration() + + // Verify the URL used in the fetch call doesn't have a trailing slash + expect(mockFetch).toHaveBeenCalledWith( + "http://localhost:11434/api/tags", + expect.objectContaining({ + method: "GET", + }), + ) + }) + + it("should not modify URLs without trailing slashes", async () => { + // Create embedder with URL that doesn't have a trailing slash + const embedderWithoutTrailingSlash = new CodeIndexOllamaEmbedder({ + ollamaBaseUrl: "http://localhost:11434", + ollamaModelId: "nomic-embed-text", + }) + + // Mock successful /api/tags call + mockFetch.mockImplementationOnce(() => + Promise.resolve({ + ok: true, + status: 200, + json: () => Promise.resolve({ models: [{ name: "nomic-embed-text" }] }), + } as Response), + ) + + // Call a method that uses the baseUrl + await embedderWithoutTrailingSlash.validateConfiguration() + + // Verify the URL used in the fetch call is correct + expect(mockFetch).toHaveBeenCalledWith( + "http://localhost:11434/api/tags", + expect.objectContaining({ + method: "GET", + }), + ) + }) + + it("should handle multiple trailing slashes", async () => { + // Create embedder with URL that has multiple trailing slashes + const embedderWithMultipleTrailingSlashes = new CodeIndexOllamaEmbedder({ + ollamaBaseUrl: "http://localhost:11434///", + ollamaModelId: "nomic-embed-text", + }) + + // Mock successful /api/tags call + mockFetch.mockImplementationOnce(() => + Promise.resolve({ + ok: true, + status: 200, + json: () => Promise.resolve({ models: [{ name: "nomic-embed-text" }] }), + } as Response), + ) + + // Call a method that uses the baseUrl + await embedderWithMultipleTrailingSlashes.validateConfiguration() + + // Verify the URL used in the fetch call doesn't have trailing slashes + expect(mockFetch).toHaveBeenCalledWith( + "http://localhost:11434/api/tags", + expect.objectContaining({ + method: "GET", + }), + ) + }) }) describe("validateConfiguration", () => { diff --git a/src/services/code-index/embedders/ollama.ts b/src/services/code-index/embedders/ollama.ts index c160d39490..9688a15ff0 100644 --- a/src/services/code-index/embedders/ollama.ts +++ b/src/services/code-index/embedders/ollama.ts @@ -20,7 +20,12 @@ export class CodeIndexOllamaEmbedder implements IEmbedder { constructor(options: ApiHandlerOptions) { // Ensure ollamaBaseUrl and ollamaModelId exist on ApiHandlerOptions or add defaults - this.baseUrl = options.ollamaBaseUrl || "http://localhost:11434" + let baseUrl = options.ollamaBaseUrl || "http://localhost:11434" + + // Normalize the baseUrl by removing all trailing slashes + baseUrl = baseUrl.replace(/\/+$/, "") + + this.baseUrl = baseUrl this.defaultModelId = options.ollamaModelId || "nomic-embed-text:latest" } diff --git a/src/services/code-index/orchestrator.ts b/src/services/code-index/orchestrator.ts index 505aee7668..fbc4a24118 100644 --- a/src/services/code-index/orchestrator.ts +++ b/src/services/code-index/orchestrator.ts @@ -7,6 +7,7 @@ import { DirectoryScanner } from "./processors" import { CacheManager } from "./cache-manager" import { TelemetryService } from "@roo-code/telemetry" import { TelemetryEventName } from "@roo-code/types" +import { t } from "../../i18n" /** * Manages the code indexing workflow, coordinating between different services and managers. @@ -94,6 +95,13 @@ export class CodeIndexOrchestrator { * Initiates the indexing process (initial scan and starts watcher). */ public async startIndexing(): Promise { + // Check if workspace is available first + if (!vscode.workspace.workspaceFolders || vscode.workspace.workspaceFolders.length === 0) { + this.stateManager.setSystemState("Error", t("embeddings:orchestrator.indexingRequiresWorkspace")) + console.warn("[CodeIndexOrchestrator] Start rejected: No workspace folder open.") + return + } + if (!this.configManager.isFeatureConfigured) { this.stateManager.setSystemState("Standby", "Missing configuration. Save your settings to start indexing.") console.warn("[CodeIndexOrchestrator] Start rejected: Missing configuration.") @@ -165,9 +173,7 @@ export class CodeIndexOrchestrator { const firstError = batchErrors[0] throw new Error(`Indexing failed: ${firstError.message}`) } else { - throw new Error( - "Indexing failed: No code blocks were successfully indexed. This usually indicates an embedder configuration issue.", - ) + throw new Error(t("embeddings:orchestrator.indexingFailedNoBlocks")) } } @@ -191,14 +197,12 @@ export class CodeIndexOrchestrator { // Final sanity check: If we found blocks but indexed none and somehow no errors were reported, // this is still a failure if (cumulativeBlocksFoundSoFar > 0 && cumulativeBlocksIndexed === 0) { - throw new Error( - "Indexing failed: No code blocks were successfully indexed despite finding files to process. This indicates a critical embedder failure.", - ) + throw new Error(t("embeddings:orchestrator.indexingFailedCritical")) } await this._startWatcher() - this.stateManager.setSystemState("Indexed", "File watcher started.") + this.stateManager.setSystemState("Indexed", t("embeddings:orchestrator.fileWatcherStarted")) } catch (error: any) { console.error("[CodeIndexOrchestrator] Error during indexing:", error) TelemetryService.instance.captureEvent(TelemetryEventName.CODE_INDEX_ERROR, { @@ -219,7 +223,12 @@ export class CodeIndexOrchestrator { await this.cacheManager.clearCacheFile() - this.stateManager.setSystemState("Error", `Failed during initial scan: ${error.message || "Unknown error"}`) + this.stateManager.setSystemState( + "Error", + t("embeddings:orchestrator.failedDuringInitialScan", { + errorMessage: error.message || t("embeddings:orchestrator.unknownError"), + }), + ) this.stopWatcher() } finally { this._isProcessing = false @@ -235,7 +244,7 @@ export class CodeIndexOrchestrator { this._fileWatcherSubscriptions = [] if (this.stateManager.state !== "Error") { - this.stateManager.setSystemState("Standby", "File watcher stopped.") + this.stateManager.setSystemState("Standby", t("embeddings:orchestrator.fileWatcherStopped")) } this._isProcessing = false } diff --git a/src/services/command/__tests__/frontmatter-commands.spec.ts b/src/services/command/__tests__/frontmatter-commands.spec.ts new file mode 100644 index 0000000000..e40f351003 --- /dev/null +++ b/src/services/command/__tests__/frontmatter-commands.spec.ts @@ -0,0 +1,231 @@ +import { describe, it, expect, beforeEach, vi } from "vitest" +import fs from "fs/promises" +import * as path from "path" +import { getCommand, getCommands } from "../commands" + +// Mock fs and path modules +vi.mock("fs/promises") +vi.mock("../roo-config", () => ({ + getGlobalRooDirectory: vi.fn(() => "/mock/global/.roo"), + getProjectRooDirectoryForCwd: vi.fn(() => "/mock/project/.roo"), +})) + +const mockFs = vi.mocked(fs) + +describe("Command loading with frontmatter", () => { + beforeEach(() => { + vi.clearAllMocks() + }) + + describe("getCommand with frontmatter", () => { + it("should load command with description from frontmatter", async () => { + const commandContent = `--- +description: Sets up the development environment +author: John Doe +--- + +# Setup Command + +Run the following commands: +\`\`\`bash +npm install +npm run build +\`\`\`` + + mockFs.stat = vi.fn().mockResolvedValue({ isDirectory: () => true }) + mockFs.readFile = vi.fn().mockResolvedValue(commandContent) + + const result = await getCommand("/test/cwd", "setup") + + expect(result).toEqual({ + name: "setup", + content: "# Setup Command\n\nRun the following commands:\n```bash\nnpm install\nnpm run build\n```", + source: "project", + filePath: path.join("/test/cwd", ".roo", "commands", "setup.md"), + description: "Sets up the development environment", + }) + }) + + it("should load command without frontmatter", async () => { + const commandContent = `# Setup Command + +Run the following commands: +\`\`\`bash +npm install +npm run build +\`\`\`` + + mockFs.stat = vi.fn().mockResolvedValue({ isDirectory: () => true }) + mockFs.readFile = vi.fn().mockResolvedValue(commandContent) + + const result = await getCommand("/test/cwd", "setup") + + expect(result).toEqual({ + name: "setup", + content: "# Setup Command\n\nRun the following commands:\n```bash\nnpm install\nnpm run build\n```", + source: "project", + filePath: path.join("/test/cwd", ".roo", "commands", "setup.md"), + description: undefined, + }) + }) + + it("should handle empty description in frontmatter", async () => { + const commandContent = `--- +description: "" +author: John Doe +--- + +# Setup Command + +Command content here.` + + mockFs.stat = vi.fn().mockResolvedValue({ isDirectory: () => true }) + mockFs.readFile = vi.fn().mockResolvedValue(commandContent) + + const result = await getCommand("/test/cwd", "setup") + + expect(result?.description).toBeUndefined() + }) + + it("should handle malformed frontmatter gracefully", async () => { + const commandContent = `--- +description: Test +invalid: yaml: [ +--- + +# Setup Command + +Command content here.` + + mockFs.stat = vi.fn().mockResolvedValue({ isDirectory: () => true }) + mockFs.readFile = vi.fn().mockResolvedValue(commandContent) + + const result = await getCommand("/test/cwd", "setup") + + expect(result).toEqual({ + name: "setup", + content: commandContent.trim(), + source: "project", + filePath: path.join("/test/cwd", ".roo", "commands", "setup.md"), + description: undefined, + }) + }) + + it("should prioritize project commands over global commands", async () => { + const projectCommandContent = `--- +description: Project-specific setup +--- + +# Project Setup + +Project-specific setup instructions.` + + const globalCommandContent = `--- +description: Global setup +--- + +# Global Setup + +Global setup instructions.` + + mockFs.stat = vi.fn().mockResolvedValue({ isDirectory: () => true }) + mockFs.readFile = vi + .fn() + .mockResolvedValueOnce(projectCommandContent) // First call for project + .mockResolvedValueOnce(globalCommandContent) // Second call for global (shouldn't be used) + + const result = await getCommand("/test/cwd", "setup") + + expect(result).toEqual({ + name: "setup", + content: "# Project Setup\n\nProject-specific setup instructions.", + source: "project", + filePath: path.join("/test/cwd", ".roo", "commands", "setup.md"), + description: "Project-specific setup", + }) + }) + + it("should fall back to global command if project command doesn't exist", async () => { + const globalCommandContent = `--- +description: Global setup command +--- + +# Global Setup + +Global setup instructions.` + + mockFs.stat = vi.fn().mockResolvedValue({ isDirectory: () => true }) + mockFs.readFile = vi + .fn() + .mockRejectedValueOnce(new Error("File not found")) // Project command doesn't exist + .mockResolvedValueOnce(globalCommandContent) // Global command exists + + const result = await getCommand("/test/cwd", "setup") + + expect(result).toEqual({ + name: "setup", + content: "# Global Setup\n\nGlobal setup instructions.", + source: "global", + filePath: expect.stringContaining(path.join(".roo", "commands", "setup.md")), + description: "Global setup command", + }) + }) + }) + + describe("getCommands with frontmatter", () => { + it("should load multiple commands with descriptions", async () => { + const setupContent = `--- +description: Sets up the development environment +--- + +# Setup Command + +Setup instructions.` + + const deployContent = `--- +description: Deploys the application to production +--- + +# Deploy Command + +Deploy instructions.` + + const buildContent = `# Build Command + +Build instructions without frontmatter.` + + mockFs.stat = vi.fn().mockResolvedValue({ isDirectory: () => true }) + mockFs.readdir = vi.fn().mockResolvedValue([ + { name: "setup.md", isFile: () => true }, + { name: "deploy.md", isFile: () => true }, + { name: "build.md", isFile: () => true }, + { name: "not-markdown.txt", isFile: () => true }, // Should be ignored + ]) + mockFs.readFile = vi + .fn() + .mockResolvedValueOnce(setupContent) + .mockResolvedValueOnce(deployContent) + .mockResolvedValueOnce(buildContent) + + const result = await getCommands("/test/cwd") + + expect(result).toHaveLength(3) + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + name: "setup", + description: "Sets up the development environment", + }), + expect.objectContaining({ + name: "deploy", + description: "Deploys the application to production", + }), + expect.objectContaining({ + name: "build", + description: undefined, + }), + ]), + ) + }) + }) +}) diff --git a/src/services/command/commands.ts b/src/services/command/commands.ts new file mode 100644 index 0000000000..00549675c0 --- /dev/null +++ b/src/services/command/commands.ts @@ -0,0 +1,191 @@ +import fs from "fs/promises" +import * as path from "path" +import matter from "gray-matter" +import { getGlobalRooDirectory, getProjectRooDirectoryForCwd } from "../roo-config" + +export interface Command { + name: string + content: string + source: "global" | "project" + filePath: string + description?: string +} + +/** + * Get all available commands from both global and project directories + */ +export async function getCommands(cwd: string): Promise { + const commands = new Map() + + // Scan global commands first + const globalDir = path.join(getGlobalRooDirectory(), "commands") + await scanCommandDirectory(globalDir, "global", commands) + + // Scan project commands (these override global ones) + const projectDir = path.join(getProjectRooDirectoryForCwd(cwd), "commands") + await scanCommandDirectory(projectDir, "project", commands) + + return Array.from(commands.values()) +} + +/** + * Get a specific command by name (optimized to avoid scanning all commands) + */ +export async function getCommand(cwd: string, name: string): Promise { + // Try to find the command directly without scanning all commands + const projectDir = path.join(getProjectRooDirectoryForCwd(cwd), "commands") + const globalDir = path.join(getGlobalRooDirectory(), "commands") + + // Check project directory first (project commands override global ones) + const projectCommand = await tryLoadCommand(projectDir, name, "project") + if (projectCommand) { + return projectCommand + } + + // Check global directory if not found in project + const globalCommand = await tryLoadCommand(globalDir, name, "global") + return globalCommand +} + +/** + * Try to load a specific command from a directory + */ +async function tryLoadCommand( + dirPath: string, + name: string, + source: "global" | "project", +): Promise { + try { + const stats = await fs.stat(dirPath) + if (!stats.isDirectory()) { + return undefined + } + + // Try to find the command file directly + const commandFileName = `${name}.md` + const filePath = path.join(dirPath, commandFileName) + + try { + const content = await fs.readFile(filePath, "utf-8") + + let parsed + let description: string | undefined + let commandContent: string + + try { + // Try to parse frontmatter with gray-matter + parsed = matter(content) + description = + typeof parsed.data.description === "string" && parsed.data.description.trim() + ? parsed.data.description.trim() + : undefined + commandContent = parsed.content.trim() + } catch (frontmatterError) { + // If frontmatter parsing fails, treat the entire content as command content + description = undefined + commandContent = content.trim() + } + + return { + name, + content: commandContent, + source, + filePath, + description, + } + } catch (error) { + // File doesn't exist or can't be read + return undefined + } + } catch (error) { + // Directory doesn't exist or can't be read + return undefined + } +} + +/** + * Get command names for autocomplete + */ +export async function getCommandNames(cwd: string): Promise { + const commands = await getCommands(cwd) + return commands.map((cmd) => cmd.name) +} + +/** + * Scan a specific command directory + */ +async function scanCommandDirectory( + dirPath: string, + source: "global" | "project", + commands: Map, +): Promise { + try { + const stats = await fs.stat(dirPath) + if (!stats.isDirectory()) { + return + } + + const entries = await fs.readdir(dirPath, { withFileTypes: true }) + + for (const entry of entries) { + if (entry.isFile() && isMarkdownFile(entry.name)) { + const filePath = path.join(dirPath, entry.name) + const commandName = getCommandNameFromFile(entry.name) + + try { + const content = await fs.readFile(filePath, "utf-8") + + let parsed + let description: string | undefined + let commandContent: string + + try { + // Try to parse frontmatter with gray-matter + parsed = matter(content) + description = + typeof parsed.data.description === "string" && parsed.data.description.trim() + ? parsed.data.description.trim() + : undefined + commandContent = parsed.content.trim() + } catch (frontmatterError) { + // If frontmatter parsing fails, treat the entire content as command content + description = undefined + commandContent = content.trim() + } + + // Project commands override global ones + if (source === "project" || !commands.has(commandName)) { + commands.set(commandName, { + name: commandName, + content: commandContent, + source, + filePath, + description, + }) + } + } catch (error) { + console.warn(`Failed to read command file ${filePath}:`, error) + } + } + } + } catch (error) { + // Directory doesn't exist or can't be read - this is fine + } +} + +/** + * Extract command name from filename (strip .md extension only) + */ +export function getCommandNameFromFile(filename: string): string { + if (filename.toLowerCase().endsWith(".md")) { + return filename.slice(0, -3) + } + return filename +} + +/** + * Check if a file is a markdown file + */ +export function isMarkdownFile(filename: string): boolean { + return filename.toLowerCase().endsWith(".md") +} diff --git a/src/services/glob/__tests__/list-files.spec.ts b/src/services/glob/__tests__/list-files.spec.ts index 6c133a732a..d855388002 100644 --- a/src/services/glob/__tests__/list-files.spec.ts +++ b/src/services/glob/__tests__/list-files.spec.ts @@ -3,6 +3,18 @@ import * as path from "path" import { listFiles } from "../list-files" import * as childProcess from "child_process" +vi.mock("child_process") +vi.mock("fs") +vi.mock("vscode", () => ({ + env: { + appRoot: "/mock/vscode/app/root", + }, +})) + +vi.mock("../../ripgrep", () => ({ + getBinPath: vi.fn().mockResolvedValue("/mock/path/to/rg"), +})) + vi.mock("../list-files", async () => { const actual = await vi.importActual("../list-files") return { @@ -83,8 +95,11 @@ describe("list-files symlink support", () => { mockSpawn.mockReturnValue(mockProcess as any) + // Use a test directory path + const testDir = "/test/dir" + // Call listFiles to trigger ripgrep execution - await listFiles("/test/dir", false, 100) + await listFiles(testDir, false, 100) // Verify that spawn was called with --follow flag (the critical fix) const [rgPath, args] = mockSpawn.mock.calls[0] @@ -93,9 +108,12 @@ describe("list-files symlink support", () => { expect(args).toContain("--hidden") expect(args).toContain("--follow") // This is the critical assertion - the fix should add this flag - // Platform-agnostic path check - verify the last argument is the resolved path - const expectedPath = path.resolve("/test/dir") - expect(args[args.length - 1]).toBe(expectedPath) + // Platform-agnostic path check - verify the last argument ends with the expected path + const lastArg = args[args.length - 1] + // On Windows, the path might be resolved to something like D:\test\dir + // On Unix, it would be /test/dir + // So we just check that it ends with the expected segments + expect(lastArg).toMatch(/[/\\]test[/\\]dir$/) }) it("should include --follow flag for recursive listings too", async () => { @@ -124,8 +142,11 @@ describe("list-files symlink support", () => { mockSpawn.mockReturnValue(mockProcess as any) + // Use a test directory path + const testDir = "/test/dir" + // Call listFiles with recursive=true - await listFiles("/test/dir", true, 100) + await listFiles(testDir, true, 100) // Verify that spawn was called with --follow flag (the critical fix) const [rgPath, args] = mockSpawn.mock.calls[0] @@ -134,9 +155,12 @@ describe("list-files symlink support", () => { expect(args).toContain("--hidden") expect(args).toContain("--follow") // This should be present in recursive mode too - // Platform-agnostic path check - verify the last argument is the resolved path - const expectedPath = path.resolve("/test/dir") - expect(args[args.length - 1]).toBe(expectedPath) + // Platform-agnostic path check - verify the last argument ends with the expected path + const lastArg = args[args.length - 1] + // On Windows, the path might be resolved to something like D:\test\dir + // On Unix, it would be /test/dir + // So we just check that it ends with the expected segments + expect(lastArg).toMatch(/[/\\]test[/\\]dir$/) }) it("should ensure first-level directories are included when limit is reached", async () => { @@ -159,18 +183,19 @@ describe("list-files symlink support", () => { on: vi.fn((event, callback) => { if (event === "data") { // Return many file paths to trigger the limit + // Note: ripgrep returns relative paths const paths = [ - "/test/dir/a_dir/", - "/test/dir/a_dir/subdir1/", - "/test/dir/a_dir/subdir1/file1.txt", - "/test/dir/a_dir/subdir1/file2.txt", - "/test/dir/a_dir/subdir2/", - "/test/dir/a_dir/subdir2/file3.txt", - "/test/dir/a_dir/file4.txt", - "/test/dir/a_dir/file5.txt", - "/test/dir/file1.txt", - "/test/dir/file2.txt", + "a_dir/", + "a_dir/subdir1/", + "a_dir/subdir1/file1.txt", + "a_dir/subdir1/file2.txt", + "a_dir/subdir2/", + "a_dir/subdir2/file3.txt", + "a_dir/file4.txt", + "a_dir/file5.txt", + "file1.txt", + "file2.txt", // Note: b_dir and c_dir are missing from ripgrep output ].join("\n") + "\n" setTimeout(() => callback(paths), 10) @@ -216,3 +241,321 @@ describe("list-files symlink support", () => { expect(hasCDir).toBe(true) }) }) + +describe("hidden directory exclusion", () => { + beforeEach(() => { + vi.clearAllMocks() + }) + + it("should exclude .git subdirectories from recursive directory listing", async () => { + // Mock filesystem structure with .git subdirectories + const mockReaddir = vi.fn() + vi.mocked(fs.promises).readdir = mockReaddir + + // Mock the directory structure: + // /test/ + // .git/ + // hooks/ + // objects/ + // src/ + // components/ + mockReaddir + .mockResolvedValueOnce([ + { name: ".git", isDirectory: () => true, isSymbolicLink: () => false }, + { name: "src", isDirectory: () => true, isSymbolicLink: () => false }, + ]) + .mockResolvedValueOnce([ + // src subdirectories (should be included) + { name: "components", isDirectory: () => true, isSymbolicLink: () => false }, + ]) + .mockResolvedValueOnce([]) // components/ is empty + + // Mock ripgrep to return no files + const mockSpawn = vi.mocked(childProcess.spawn) + const mockProcess = { + stdout: { + on: vi.fn((event, callback) => { + if (event === "data") { + // No files returned + } + }), + }, + stderr: { + on: vi.fn(), + }, + on: vi.fn((event, callback) => { + if (event === "close") { + setTimeout(() => callback(0), 10) + } + }), + kill: vi.fn(), + } + mockSpawn.mockReturnValue(mockProcess as any) + + // Call listFiles with recursive=true + const [result] = await listFiles("/test", true, 100) + + // Verify that .git subdirectories are NOT included + const directories = result.filter((item) => item.endsWith("/")) + + // More specific checks - look for exact paths + const hasSrcDir = directories.some((dir) => dir.endsWith("/test/src/") || dir.endsWith("src/")) + const hasComponentsDir = directories.some( + (dir) => + dir.endsWith("/test/src/components/") || dir.endsWith("src/components/") || dir.includes("components/"), + ) + const hasGitDir = directories.some((dir) => dir.includes(".git/")) + + // Should include src/ and src/components/ but NOT .git/ or its subdirectories + expect(hasSrcDir).toBe(true) + expect(hasComponentsDir).toBe(true) + + // Should NOT include .git (hidden directories are excluded) + expect(hasGitDir).toBe(false) + }) + + it("should allow explicit targeting of hidden directories", async () => { + // Mock filesystem structure for explicit .roo-memory targeting + const mockReaddir = vi.fn() + vi.mocked(fs.promises).readdir = mockReaddir + + // Mock .roo-memory directory contents + mockReaddir.mockResolvedValueOnce([ + { name: "tasks", isDirectory: () => true, isSymbolicLink: () => false }, + { name: "context", isDirectory: () => true, isSymbolicLink: () => false }, + ]) + + // Mock ripgrep to return no files + const mockSpawn = vi.mocked(childProcess.spawn) + const mockProcess = { + stdout: { + on: vi.fn((event, callback) => { + if (event === "data") { + // No files returned + } + }), + }, + stderr: { + on: vi.fn(), + }, + on: vi.fn((event, callback) => { + if (event === "close") { + setTimeout(() => callback(0), 10) + } + }), + kill: vi.fn(), + } + mockSpawn.mockReturnValue(mockProcess as any) + + // Call listFiles explicitly targeting .roo-memory directory + const [result] = await listFiles("/test/.roo-memory", true, 100) + + // When explicitly targeting a hidden directory, its subdirectories should be included + const directories = result.filter((item) => item.endsWith("/")) + + const hasTasksDir = directories.some((dir) => dir.includes(".roo-memory/tasks/") || dir.includes("tasks/")) + const hasContextDir = directories.some( + (dir) => dir.includes(".roo-memory/context/") || dir.includes("context/"), + ) + + expect(hasTasksDir).toBe(true) + expect(hasContextDir).toBe(true) + }) + + it("should include top-level files when recursively listing a hidden directory that's also in DIRS_TO_IGNORE", async () => { + // This test specifically addresses the bug where files at the root level of .roo/temp + // were being excluded when using recursive listing + const mockSpawn = vi.mocked(childProcess.spawn) + const mockProcess = { + stdout: { + on: vi.fn((event, callback) => { + if (event === "data") { + // Simulate files that should be found in .roo/temp + // Note: ripgrep returns relative paths + setTimeout(() => { + callback("teste1.md\n") + callback("22/test2.md\n") + }, 10) + } + }), + }, + stderr: { + on: vi.fn(), + }, + on: vi.fn((event, callback) => { + if (event === "close") { + setTimeout(() => callback(0), 20) + } + }), + kill: vi.fn(), + } + + mockSpawn.mockReturnValue(mockProcess as any) + + // Mock directory listing for .roo/temp + const mockReaddir = vi.fn() + vi.mocked(fs.promises).readdir = mockReaddir + mockReaddir.mockResolvedValueOnce([{ name: "22", isDirectory: () => true, isSymbolicLink: () => false }]) + + // Call listFiles targeting .roo/temp (which is both hidden and in DIRS_TO_IGNORE) + const [files] = await listFiles("/test/.roo/temp", true, 100) + + // Verify ripgrep was called with correct arguments + const [rgPath, args] = mockSpawn.mock.calls[0] + expect(args).toContain("--no-ignore-vcs") + expect(args).toContain("--no-ignore") + + // Check for the inclusion patterns that should be added + expect(args).toContain("-g") + const gIndex = args.indexOf("-g") + expect(args[gIndex + 1]).toBe("*") + + // Verify that both top-level and nested files are included + const fileNames = files.map((f) => path.basename(f)) + expect(fileNames).toContain("teste1.md") + expect(fileNames).toContain("test2.md") + + // Ensure the top-level file is actually included + const topLevelFile = files.find((f) => f.endsWith("teste1.md")) + expect(topLevelFile).toBeTruthy() + }) +}) + +describe("buildRecursiveArgs edge cases", () => { + beforeEach(() => { + vi.clearAllMocks() + }) + + it("should correctly detect hidden directories with trailing slashes", async () => { + const mockSpawn = vi.mocked(childProcess.spawn) + const mockProcess = { + stdout: { + on: vi.fn((event, callback) => { + if (event === "data") { + setTimeout(() => callback("file.txt\n"), 10) + } + }), + }, + stderr: { + on: vi.fn(), + }, + on: vi.fn((event, callback) => { + if (event === "close") { + setTimeout(() => callback(0), 20) + } + }), + kill: vi.fn(), + } + mockSpawn.mockReturnValue(mockProcess as any) + + // Test with trailing slash on hidden directory + await listFiles("/test/.hidden/", true, 100) + + const [rgPath, args] = mockSpawn.mock.calls[0] + // When targeting a hidden directory, these flags should be present + expect(args).toContain("--no-ignore-vcs") + expect(args).toContain("--no-ignore") + expect(args).toContain("-g") + const gIndex = args.indexOf("-g") + expect(args[gIndex + 1]).toBe("*") + }) + + it("should correctly detect hidden directories with redundant separators", async () => { + const mockSpawn = vi.mocked(childProcess.spawn) + const mockProcess = { + stdout: { + on: vi.fn((event, callback) => { + if (event === "data") { + setTimeout(() => callback("file.txt\n"), 10) + } + }), + }, + stderr: { + on: vi.fn(), + }, + on: vi.fn((event, callback) => { + if (event === "close") { + setTimeout(() => callback(0), 20) + } + }), + kill: vi.fn(), + } + mockSpawn.mockReturnValue(mockProcess as any) + + // Test with redundant separators before hidden directory + await listFiles("/test//.hidden", true, 100) + + const [rgPath, args] = mockSpawn.mock.calls[0] + // When targeting a hidden directory, these flags should be present + expect(args).toContain("--no-ignore-vcs") + expect(args).toContain("--no-ignore") + expect(args).toContain("-g") + const gIndex = args.indexOf("-g") + expect(args[gIndex + 1]).toBe("*") + }) + + it("should correctly detect nested hidden directories with mixed separators", async () => { + const mockSpawn = vi.mocked(childProcess.spawn) + const mockProcess = { + stdout: { + on: vi.fn((event, callback) => { + if (event === "data") { + setTimeout(() => callback("file.txt\n"), 10) + } + }), + }, + stderr: { + on: vi.fn(), + }, + on: vi.fn((event, callback) => { + if (event === "close") { + setTimeout(() => callback(0), 20) + } + }), + kill: vi.fn(), + } + mockSpawn.mockReturnValue(mockProcess as any) + + // Test with complex path including hidden directory + await listFiles("/test//normal/.hidden//subdir/", true, 100) + + const [rgPath, args] = mockSpawn.mock.calls[0] + // When targeting a path containing a hidden directory, these flags should be present + expect(args).toContain("--no-ignore-vcs") + expect(args).toContain("--no-ignore") + expect(args).toContain("-g") + const gIndex = args.indexOf("-g") + expect(args[gIndex + 1]).toBe("*") + }) + + it("should not detect hidden directories when path only has dots in filenames", async () => { + const mockSpawn = vi.mocked(childProcess.spawn) + const mockProcess = { + stdout: { + on: vi.fn((event, callback) => { + if (event === "data") { + setTimeout(() => callback("file.txt\n"), 10) + } + }), + }, + stderr: { + on: vi.fn(), + }, + on: vi.fn((event, callback) => { + if (event === "close") { + setTimeout(() => callback(0), 20) + } + }), + kill: vi.fn(), + } + mockSpawn.mockReturnValue(mockProcess as any) + + // Test with a path that has dots but no hidden directories + await listFiles("/test/file.with.dots/normal", true, 100) + + const [rgPath, args] = mockSpawn.mock.calls[0] + // Should NOT have the special flags for hidden directories + expect(args).not.toContain("--no-ignore-vcs") + expect(args).not.toContain("--no-ignore") + }) +}) diff --git a/src/services/glob/constants.ts b/src/services/glob/constants.ts index 1ddcc37df9..380e4afaf3 100644 --- a/src/services/glob/constants.ts +++ b/src/services/glob/constants.ts @@ -20,5 +20,6 @@ export const DIRS_TO_IGNORE = [ "deps", "pkg", "Pods", + ".git", ".*", ] diff --git a/src/services/glob/list-files.ts b/src/services/glob/list-files.ts index 05fa8a1d7b..7347515784 100644 --- a/src/services/glob/list-files.ts +++ b/src/services/glob/list-files.ts @@ -8,6 +8,20 @@ import { arePathsEqual } from "../../utils/path" import { getBinPath } from "../../services/ripgrep" import { DIRS_TO_IGNORE } from "./constants" +/** + * Context object for directory scanning operations + */ +interface ScanContext { + /** Whether this is the explicitly targeted directory */ + isTargetDir: boolean + /** Whether we're inside an explicitly targeted hidden directory */ + insideExplicitHiddenTarget: boolean + /** The base path for the scan operation */ + basePath: string + /** The ignore instance for gitignore handling */ + ignoreInstance: ReturnType +} + /** * List files in a directory, with optional recursive traversal * @@ -70,7 +84,13 @@ async function getFirstLevelDirectories(dirPath: string, ignoreInstance: ReturnT for (const entry of entries) { if (entry.isDirectory() && !entry.isSymbolicLink()) { const fullDirPath = path.join(absolutePath, entry.name) - if (shouldIncludeDirectory(entry.name, fullDirPath, dirPath, ignoreInstance)) { + const context: ScanContext = { + isTargetDir: false, + insideExplicitHiddenTarget: false, + basePath: dirPath, + ignoreInstance, + } + if (shouldIncludeDirectory(entry.name, fullDirPath, context)) { const formattedPath = fullDirPath.endsWith("/") ? fullDirPath : `${fullDirPath}/` directories.push(formattedPath) } @@ -179,9 +199,14 @@ async function listFilesWithRipgrep( recursive: boolean, limit: number, ): Promise { + const rgArgs = buildRipgrepArgs(dirPath, recursive) + + const relativePaths = await execRipgrep(rgPath, rgArgs, limit) + + // Convert relative paths from ripgrep to absolute paths + // Resolve dirPath once here for the mapping operation const absolutePath = path.resolve(dirPath) - const rgArgs = buildRipgrepArgs(absolutePath, recursive) - return execRipgrep(rgPath, rgArgs, limit) + return relativePaths.map((relativePath) => path.resolve(absolutePath, relativePath)) } /** @@ -192,7 +217,7 @@ function buildRipgrepArgs(dirPath: string, recursive: boolean): string[] { const args = ["--files", "--hidden", "--follow"] if (recursive) { - return [...args, ...buildRecursiveArgs(), dirPath] + return [...args, ...buildRecursiveArgs(dirPath), dirPath] } else { return [...args, ...buildNonRecursiveArgs(), dirPath] } @@ -201,14 +226,62 @@ function buildRipgrepArgs(dirPath: string, recursive: boolean): string[] { /** * Build ripgrep arguments for recursive directory traversal */ -function buildRecursiveArgs(): string[] { +function buildRecursiveArgs(dirPath: string): string[] { const args: string[] = [] // In recursive mode, respect .gitignore by default // (ripgrep does this automatically) + // Check if we're explicitly targeting a hidden directory + // Normalize the path first to handle edge cases + const normalizedPath = path.normalize(dirPath) + // Split by separator and filter out empty parts + // This handles cases like trailing slashes, multiple separators, etc. + const pathParts = normalizedPath.split(path.sep).filter((part) => part.length > 0) + const isTargetingHiddenDir = pathParts.some((part) => part.startsWith(".")) + + // Get the target directory name to check if it's in the ignore list + const targetDirName = path.basename(dirPath) + const isTargetInIgnoreList = DIRS_TO_IGNORE.includes(targetDirName) + + // If targeting a hidden directory or a directory in the ignore list, + // use special handling to ensure all files are shown + if (isTargetingHiddenDir || isTargetInIgnoreList) { + args.push("--no-ignore-vcs") + args.push("--no-ignore") + + // When targeting an ignored directory, we need to be careful with glob patterns + // Add a pattern to explicitly include files at the root level + args.push("-g", "*") + args.push("-g", "**/*") + } + // Apply directory exclusions for recursive searches for (const dir of DIRS_TO_IGNORE) { + // Special handling for hidden directories pattern + if (dir === ".*") { + // If we're explicitly targeting a hidden directory, don't exclude hidden files/dirs + // This allows the target hidden directory and all its contents to be listed + if (!isTargetingHiddenDir) { + // Not targeting hidden dir: exclude all hidden directories + args.push("-g", `!**/.*/**`) + } + // If targeting hidden dir: don't add any exclusion for hidden directories + continue + } + + // When explicitly targeting a directory that's in the ignore list (e.g., "temp"), + // we need special handling: + // - Don't add any exclusion pattern for the target directory itself + // - Only exclude nested subdirectories with the same name + // This ensures all files in the target directory are listed, while still + // preventing recursion into nested directories with the same ignored name + if (dir === targetDirName && isTargetInIgnoreList) { + // Skip adding any exclusion pattern - we want to see everything in the target directory + continue + } + + // For all other cases, exclude the directory pattern globally args.push("-g", `!**/${dir}/**`) } @@ -231,8 +304,11 @@ function buildNonRecursiveArgs(): string[] { // Apply directory exclusions for non-recursive searches for (const dir of DIRS_TO_IGNORE) { if (dir === ".*") { - // For hidden files/dirs in non-recursive mode - args.push("-g", "!.*") + // For hidden directories in non-recursive mode, we want to show the directories + // themselves but not their contents. Since we're using --maxdepth 1, this + // naturally happens - we just need to avoid excluding the directories entirely. + // We'll let the directory scanning logic handle the visibility. + continue } else { // Direct children only args.push("-g", `!${dir}`) @@ -261,7 +337,7 @@ async function createIgnoreInstance(dirPath: string): Promise { + // For environment details generation, we don't want to treat the root as a "target" + // if we're doing a general recursive scan, as this would include hidden directories + // Only treat as target if we're explicitly scanning a single hidden directory + const isExplicitHiddenTarget = path.basename(absolutePath).startsWith(".") + + // Create initial context for the scan + const initialContext: ScanContext = { + isTargetDir: isExplicitHiddenTarget, + insideExplicitHiddenTarget: isExplicitHiddenTarget, + basePath: dirPath, + ignoreInstance, + } + + async function scanDirectory(currentPath: string, context: ScanContext): Promise { try { // List all entries in the current directory const entries = await fs.promises.readdir(currentPath, { withFileTypes: true }) @@ -323,61 +412,155 @@ async function listFilteredDirectories( const dirName = entry.name const fullDirPath = path.join(currentPath, dirName) + // Create context for subdirectory checks + // Subdirectories found during scanning are never target directories themselves + const subdirContext: ScanContext = { + ...context, + isTargetDir: false, + } + // Check if this directory should be included - if (shouldIncludeDirectory(dirName, fullDirPath, dirPath, ignoreInstance)) { + if (shouldIncludeDirectory(dirName, fullDirPath, subdirContext)) { // Add the directory to our results (with trailing slash) + // fullDirPath is already absolute since it's built with path.join from absolutePath const formattedPath = fullDirPath.endsWith("/") ? fullDirPath : `${fullDirPath}/` directories.push(formattedPath) + } - // If recursive mode and not a ignored directory, scan subdirectories - if (recursive && !isDirectoryExplicitlyIgnored(dirName)) { - await scanDirectory(fullDirPath) + // If recursive mode and not a ignored directory, scan subdirectories + // Don't recurse into hidden directories unless they are the explicit target + // or we're already inside an explicitly targeted hidden directory + const isHiddenDir = dirName.startsWith(".") + + // Use the same logic as shouldIncludeDirectory for recursion decisions + // When inside an explicitly targeted hidden directory, only block critical directories + let shouldRecurseIntoDir = true + if (context.insideExplicitHiddenTarget) { + // Only apply the most critical ignore patterns when inside explicit hidden target + shouldRecurseIntoDir = !CRITICAL_IGNORE_PATTERNS.has(dirName) + } else { + shouldRecurseIntoDir = !isDirectoryExplicitlyIgnored(dirName) + } + + const shouldRecurse = + recursive && + shouldRecurseIntoDir && + !( + isHiddenDir && + DIRS_TO_IGNORE.includes(".*") && + !context.isTargetDir && + !context.insideExplicitHiddenTarget + ) + if (shouldRecurse) { + // If we're entering a hidden directory that's the target, or we're already inside one, + // mark that we're inside an explicitly targeted hidden directory + const newInsideExplicitHiddenTarget = + context.insideExplicitHiddenTarget || (isHiddenDir && context.isTargetDir) + const newContext: ScanContext = { + ...context, + isTargetDir: false, + insideExplicitHiddenTarget: newInsideExplicitHiddenTarget, } + await scanDirectory(fullDirPath, newContext) } } } } catch (err) { - // Silently continue if we can't read a directory + // Continue if we can't read a directory console.warn(`Could not read directory ${currentPath}: ${err}`) } } // Start scanning from the root directory - await scanDirectory(absolutePath) + await scanDirectory(absolutePath, initialContext) return directories } /** - * Determine if a directory should be included in results based on filters + * Critical directories that should always be ignored, even inside explicitly targeted hidden directories */ -function shouldIncludeDirectory( - dirName: string, +const CRITICAL_IGNORE_PATTERNS = new Set(["node_modules", ".git", "__pycache__", "venv", "env"]) + +/** + * Check if a directory matches any of the given patterns + */ +function matchesIgnorePattern(dirName: string, patterns: string[]): boolean { + for (const pattern of patterns) { + if (pattern === dirName || (pattern.includes("/") && pattern.split("/")[0] === dirName)) { + return true + } + } + return false +} + +/** + * Check if a directory is ignored by gitignore + */ +function isIgnoredByGitignore( fullDirPath: string, basePath: string, ignoreInstance: ReturnType, ): boolean { - // Skip hidden directories if configured to ignore them - if (dirName.startsWith(".") && DIRS_TO_IGNORE.includes(".*")) { - return false - } - - // Check against explicit ignore patterns - if (isDirectoryExplicitlyIgnored(dirName)) { - return false - } - - // Check against gitignore patterns using the ignore library - // Calculate relative path from the base directory const relativePath = path.relative(basePath, fullDirPath) const normalizedPath = relativePath.replace(/\\/g, "/") + return ignoreInstance.ignores(normalizedPath) || ignoreInstance.ignores(normalizedPath + "/") +} - // Check if the directory is ignored by .gitignore - if (ignoreInstance.ignores(normalizedPath) || ignoreInstance.ignores(normalizedPath + "/")) { +/** + * Check if a target directory should be included + */ +function shouldIncludeTargetDirectory(dirName: string): boolean { + // Only apply non-hidden-directory ignore rules to target directories + const nonHiddenIgnorePatterns = DIRS_TO_IGNORE.filter((pattern) => pattern !== ".*") + return !matchesIgnorePattern(dirName, nonHiddenIgnorePatterns) +} + +/** + * Check if a directory inside an explicitly targeted hidden directory should be included + */ +function shouldIncludeInsideHiddenTarget(dirName: string, fullDirPath: string, context: ScanContext): boolean { + // Only apply the most critical ignore patterns when inside explicit hidden target + if (CRITICAL_IGNORE_PATTERNS.has(dirName)) { return false } - return true + // Check against gitignore patterns + return !isIgnoredByGitignore(fullDirPath, context.basePath, context.ignoreInstance) +} + +/** + * Check if a regular directory should be included + */ +function shouldIncludeRegularDirectory(dirName: string, fullDirPath: string, context: ScanContext): boolean { + // Check against explicit ignore patterns (excluding the ".*" pattern) + const nonHiddenIgnorePatterns = DIRS_TO_IGNORE.filter((pattern) => pattern !== ".*") + if (matchesIgnorePattern(dirName, nonHiddenIgnorePatterns)) { + return false + } + + // Check against gitignore patterns + return !isIgnoredByGitignore(fullDirPath, context.basePath, context.ignoreInstance) +} + +/** + * Determine if a directory should be included in results based on filters + */ +function shouldIncludeDirectory(dirName: string, fullDirPath: string, context: ScanContext): boolean { + // If this is the explicitly targeted directory, allow it even if it's hidden + // This preserves the ability to explicitly target hidden directories like .roo-memory + if (context.isTargetDir) { + return shouldIncludeTargetDirectory(dirName) + } + + // If we're inside an explicitly targeted hidden directory, allow subdirectories + // even if they would normally be filtered out by the ".*" pattern or other ignore rules + if (context.insideExplicitHiddenTarget) { + return shouldIncludeInsideHiddenTarget(dirName, fullDirPath, context) + } + + // Regular directory inclusion logic + return shouldIncludeRegularDirectory(dirName, fullDirPath, context) } /** @@ -390,6 +573,11 @@ function isDirectoryExplicitlyIgnored(dirName: string): boolean { return true } + // Skip the ".*" pattern - it's handled specially to allow top-level visibility + if (pattern === ".*") { + continue + } + // Path patterns that contain / if (pattern.includes("/")) { const pathParts = pattern.split("/") @@ -432,6 +620,9 @@ function formatAndCombineResults(files: string[], directories: string[], limit: */ async function execRipgrep(rgPath: string, args: string[], limit: number): Promise { return new Promise((resolve, reject) => { + // Extract the directory path from args (it's the last argument) + const searchDir = args[args.length - 1] + const rgProcess = childProcess.spawn(rgPath, args) let output = "" let results: string[] = [] @@ -497,6 +688,7 @@ async function execRipgrep(rgPath: string, args: string[], limit: number): Promi // Process each complete line for (const line of lines) { if (line.trim() && results.length < limit) { + // Keep the relative path as returned by ripgrep results.push(line) } else if (results.length >= limit) { break diff --git a/src/services/huggingface-models.ts b/src/services/huggingface-models.ts deleted file mode 100644 index 9c0bc406f9..0000000000 --- a/src/services/huggingface-models.ts +++ /dev/null @@ -1,171 +0,0 @@ -export interface HuggingFaceModel { - _id: string - id: string - inferenceProviderMapping: InferenceProviderMapping[] - trendingScore: number - config: ModelConfig - tags: string[] - pipeline_tag: "text-generation" | "image-text-to-text" - library_name?: string -} - -export interface InferenceProviderMapping { - provider: string - providerId: string - status: "live" | "staging" | "error" - task: "conversational" -} - -export interface ModelConfig { - architectures: string[] - model_type: string - tokenizer_config?: { - chat_template?: string | Array<{ name: string; template: string }> - model_max_length?: number - } -} - -interface HuggingFaceApiParams { - pipeline_tag?: "text-generation" | "image-text-to-text" - filter: string - inference_provider: string - limit: number - expand: string[] -} - -const DEFAULT_PARAMS: HuggingFaceApiParams = { - filter: "conversational", - inference_provider: "all", - limit: 100, - expand: [ - "inferenceProviderMapping", - "config", - "library_name", - "pipeline_tag", - "tags", - "mask_token", - "trendingScore", - ], -} - -const BASE_URL = "https://huggingface.co/api/models" -const CACHE_DURATION = 1000 * 60 * 60 // 1 hour - -interface CacheEntry { - data: HuggingFaceModel[] - timestamp: number - status: "success" | "partial" | "error" -} - -let cache: CacheEntry | null = null - -function buildApiUrl(params: HuggingFaceApiParams): string { - const url = new URL(BASE_URL) - - // Add simple params - Object.entries(params).forEach(([key, value]) => { - if (!Array.isArray(value)) { - url.searchParams.append(key, String(value)) - } - }) - - // Handle array params specially - params.expand.forEach((item) => { - url.searchParams.append("expand[]", item) - }) - - return url.toString() -} - -const headers: HeadersInit = { - "Upgrade-Insecure-Requests": "1", - "Sec-Fetch-Dest": "document", - "Sec-Fetch-Mode": "navigate", - "Sec-Fetch-Site": "none", - "Sec-Fetch-User": "?1", - Priority: "u=0, i", - Pragma: "no-cache", - "Cache-Control": "no-cache", -} - -const requestInit: RequestInit = { - credentials: "include", - headers, - method: "GET", - mode: "cors", -} - -export async function fetchHuggingFaceModels(): Promise { - const now = Date.now() - - // Check cache - if (cache && now - cache.timestamp < CACHE_DURATION) { - console.log("Using cached Hugging Face models") - return cache.data - } - - try { - console.log("Fetching Hugging Face models from API...") - - // Fetch both text-generation and image-text-to-text models in parallel - const [textGenResponse, imgTextResponse] = await Promise.allSettled([ - fetch(buildApiUrl({ ...DEFAULT_PARAMS, pipeline_tag: "text-generation" }), requestInit), - fetch(buildApiUrl({ ...DEFAULT_PARAMS, pipeline_tag: "image-text-to-text" }), requestInit), - ]) - - let textGenModels: HuggingFaceModel[] = [] - let imgTextModels: HuggingFaceModel[] = [] - let hasErrors = false - - // Process text-generation models - if (textGenResponse.status === "fulfilled" && textGenResponse.value.ok) { - textGenModels = await textGenResponse.value.json() - } else { - console.error("Failed to fetch text-generation models:", textGenResponse) - hasErrors = true - } - - // Process image-text-to-text models - if (imgTextResponse.status === "fulfilled" && imgTextResponse.value.ok) { - imgTextModels = await imgTextResponse.value.json() - } else { - console.error("Failed to fetch image-text-to-text models:", imgTextResponse) - hasErrors = true - } - - // Combine and filter models - const allModels = [...textGenModels, ...imgTextModels] - .filter((model) => model.inferenceProviderMapping.length > 0) - .sort((a, b) => a.id.toLowerCase().localeCompare(b.id.toLowerCase())) - - // Update cache - cache = { - data: allModels, - timestamp: now, - status: hasErrors ? "partial" : "success", - } - - console.log(`Fetched ${allModels.length} Hugging Face models (status: ${cache.status})`) - return allModels - } catch (error) { - console.error("Error fetching Hugging Face models:", error) - - // Return cached data if available - if (cache) { - console.log("Using stale cached data due to fetch error") - cache.status = "error" - return cache.data - } - - // No cache available, return empty array - return [] - } -} - -export function getCachedModels(): HuggingFaceModel[] | null { - return cache?.data || null -} - -export function clearCache(): void { - cache = null -} diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index a848fe509c..7e3fbf060b 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -19,6 +19,14 @@ import { Mode } from "./modes" import { RouterModels } from "./api" import type { MarketplaceItem } from "@roo-code/types" +// Command interface for frontend/backend communication +export interface Command { + name: string + source: "global" | "project" + filePath?: string + description?: string +} + // Type for marketplace installed metadata export interface MarketplaceInstalledMetadata { project: Record @@ -109,6 +117,8 @@ export interface ExtensionMessage { | "codeIndexSecretStatus" | "showDeleteMessageDialog" | "showEditMessageDialog" + | "commands" + | "insertTextIntoTextarea" text?: string payload?: any // Add a generic payload for now, can refine later action?: @@ -140,26 +150,21 @@ export interface ExtensionMessage { lmStudioModels?: string[] vsCodeLmModels?: { vendor?: string; family?: string; version?: string; id?: string }[] huggingFaceModels?: Array<{ - _id: string id: string - inferenceProviderMapping: Array<{ + object: string + created: number + owned_by: string + providers: Array<{ provider: string - providerId: string status: "live" | "staging" | "error" - task: "conversational" - }> - trendingScore: number - config: { - architectures: string[] - model_type: string - tokenizer_config?: { - chat_template?: string | Array<{ name: string; template: string }> - model_max_length?: number + supports_tools?: boolean + supports_structured_output?: boolean + context_length?: number + pricing?: { + input: number + output: number } - } - tags: string[] - pipeline_tag: "text-generation" | "image-text-to-text" - library_name?: string + }> }> mcpServers?: McpServer[] commits?: GitCommit[] @@ -187,6 +192,7 @@ export interface ExtensionMessage { settings?: any messageTs?: number context?: string + commands?: Command[] } export type ExtensionState = Pick< diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 2552150ff2..55fa68e4d7 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -201,6 +201,11 @@ export interface WebviewMessage { | "checkRulesDirectoryResult" | "saveCodeIndexSettingsAtomic" | "requestCodeIndexSecretStatus" + | "requestCommands" + | "openCommandFile" + | "deleteCommand" + | "createCommand" + | "insertTextIntoTextarea" text?: string editedMessageContent?: string tab?: "settings" | "history" | "mcp" | "modes" | "chat" | "marketplace" | "account" diff --git a/src/shared/context-mentions.ts b/src/shared/context-mentions.ts index 2edb99de6a..d7e59a77dd 100644 --- a/src/shared/context-mentions.ts +++ b/src/shared/context-mentions.ts @@ -57,6 +57,9 @@ export const mentionRegex = /(? { + const mockCommands: Command[] = [ + { name: "setup", source: "project" }, + { name: "build", source: "project" }, + { name: "deploy", source: "global" }, + { name: "test-suite", source: "project" }, + { name: "cleanup_old", source: "global" }, + ] + + const mockQueryItems = [ + { type: ContextMenuOptionType.File, value: "/src/app.ts" }, + { type: ContextMenuOptionType.Problems, value: "problems" }, + ] + + describe("slash command command suggestions", () => { + it('should return all commands when query is just "/"', () => { + const options = getContextMenuOptions("/", "/", null, mockQueryItems, [], [], mockCommands) + + // Should have 6 items: 1 section header + 5 commands + expect(options).toHaveLength(6) + + // Filter out section headers to check commands + const commandOptions = options.filter((option) => option.type === ContextMenuOptionType.Command) + expect(commandOptions).toHaveLength(5) + + const commandNames = commandOptions.map((option) => option.value) + expect(commandNames).toContain("setup") + expect(commandNames).toContain("build") + expect(commandNames).toContain("deploy") + expect(commandNames).toContain("test-suite") + expect(commandNames).toContain("cleanup_old") + }) + + it("should filter commands based on fuzzy search", () => { + const options = getContextMenuOptions("/set", "/set", null, mockQueryItems, [], [], mockCommands) + + // Should match 'setup' (fuzzy search behavior may vary) + expect(options.length).toBeGreaterThan(0) + const commandNames = options.map((option) => option.value) + expect(commandNames).toContain("setup") + // Note: fuzzy search may not match 'test-suite' for 'set' query + }) + + it("should return commands with correct format", () => { + const options = getContextMenuOptions("/setup", "/setup", null, mockQueryItems, [], [], mockCommands) + + const setupOption = options.find((option) => option.value === "setup") + expect(setupOption).toBeDefined() + expect(setupOption!.type).toBe(ContextMenuOptionType.Command) + expect(setupOption!.slashCommand).toBe("/setup") + expect(setupOption!.value).toBe("setup") + }) + + it("should handle empty command list", () => { + const options = getContextMenuOptions("/setup", "/setup", null, mockQueryItems, [], [], []) + + // Should return NoResults when no commands match + expect(options).toHaveLength(1) + expect(options[0].type).toBe(ContextMenuOptionType.NoResults) + }) + + it("should handle no matching commands", () => { + const options = getContextMenuOptions( + "/nonexistent", + "/nonexistent", + null, + mockQueryItems, + [], + [], + mockCommands, + ) + + // Should return NoResults when no commands match + expect(options).toHaveLength(1) + expect(options[0].type).toBe(ContextMenuOptionType.NoResults) + }) + + it("should not return command suggestions for non-slash queries", () => { + const options = getContextMenuOptions("setup", "setup", null, mockQueryItems, [], [], mockCommands) + + // Should not contain command options for non-slash queries + const commandOptions = options.filter((option) => option.type === ContextMenuOptionType.Command) + expect(commandOptions).toHaveLength(0) + }) + + it("should handle commands with special characters in names", () => { + const specialCommands: Command[] = [ + { name: "setup-dev", source: "project" }, + { name: "test_suite", source: "project" }, + { name: "deploy.prod", source: "global" }, + ] + + const options = getContextMenuOptions("/setup", "/setup", null, mockQueryItems, [], [], specialCommands) + + const setupDevOption = options.find((option) => option.value === "setup-dev") + expect(setupDevOption).toBeDefined() + expect(setupDevOption!.slashCommand).toBe("/setup-dev") + }) + + it("should handle case-insensitive fuzzy matching", () => { + const options = getContextMenuOptions("/setup", "/setup", null, mockQueryItems, [], [], mockCommands) + + const commandNames = options.map((option) => option.value) + expect(commandNames).toContain("setup") + }) + + it("should prioritize exact matches in fuzzy search", () => { + const commandsWithSimilarNames: Command[] = [ + { name: "test", source: "project" }, + { name: "test-suite", source: "project" }, + { name: "integration-test", source: "project" }, + ] + + const options = getContextMenuOptions( + "/test", + "/test", + null, + mockQueryItems, + [], + [], + commandsWithSimilarNames, + ) + + // Filter out section headers and check the first command + const commandOptions = options.filter((option) => option.type === ContextMenuOptionType.Command) + expect(commandOptions[0].value).toBe("test") + }) + + it("should handle partial matches correctly", () => { + const options = getContextMenuOptions("/te", "/te", null, mockQueryItems, [], [], mockCommands) + + // Should match 'test-suite' + const commandNames = options.map((option) => option.value) + expect(commandNames).toContain("test-suite") + }) + }) + + describe("command integration with modes", () => { + const mockModes = [ + { + name: "Code", + slug: "code", + description: "Write and edit code", + roleDefinition: "You are a code assistant", + groups: ["read", "edit"], + }, + { + name: "Debug", + slug: "debug", + description: "Debug applications", + roleDefinition: "You are a debug assistant", + groups: ["read", "edit"], + }, + ] as any[] + + it("should return both modes and commands for slash commands", () => { + const options = getContextMenuOptions("/", "/", null, mockQueryItems, [], mockModes, mockCommands) + + const modeOptions = options.filter((option) => option.type === ContextMenuOptionType.Mode) + const commandOptions = options.filter((option) => option.type === ContextMenuOptionType.Command) + + expect(modeOptions.length).toBe(2) + expect(commandOptions.length).toBe(5) + }) + + it("should filter both modes and commands based on query", () => { + const options = getContextMenuOptions("/co", "/co", null, mockQueryItems, [], mockModes, mockCommands) + + // Should match 'code' mode and possibly some commands (fuzzy search may match) + const modeOptions = options.filter((option) => option.type === ContextMenuOptionType.Mode) + const commandOptions = options.filter((option) => option.type === ContextMenuOptionType.Command) + + expect(modeOptions.length).toBe(1) + expect(modeOptions[0].value).toBe("code") + // Fuzzy search might match some commands, so we just check it's a reasonable number + expect(commandOptions.length).toBeGreaterThanOrEqual(0) + }) + }) + + describe("command source indication", () => { + it("should not expose source information in autocomplete", () => { + const options = getContextMenuOptions("/setup", "/setup", null, mockQueryItems, [], [], mockCommands) + + const setupOption = options.find((option) => option.value === "setup") + expect(setupOption).toBeDefined() + + // Source should not be exposed in the UI + if (setupOption!.description) { + expect(setupOption!.description).not.toContain("project") + expect(setupOption!.description).not.toContain("global") + expect(setupOption!.description).toBe("Trigger the setup command") + } + }) + }) + + describe("edge cases", () => { + it("should handle undefined commands gracefully", () => { + const options = getContextMenuOptions("/setup", "/setup", null, mockQueryItems, [], [], undefined) + + expect(options).toHaveLength(1) + expect(options[0].type).toBe(ContextMenuOptionType.NoResults) + }) + + it("should handle empty query with commands", () => { + const options = getContextMenuOptions("", "", null, mockQueryItems, [], [], mockCommands) + + // Should not return command options for empty query + const commandOptions = options.filter((option) => option.type === ContextMenuOptionType.Command) + expect(commandOptions).toHaveLength(0) + }) + + it("should handle very long command names", () => { + const longNameCommands: Command[] = [ + { name: "very-long-command-name-that-exceeds-normal-length", source: "project" }, + ] + + const options = getContextMenuOptions("/very", "/very", null, mockQueryItems, [], [], longNameCommands) + + // Should have 2 items: 1 section header + 1 command + expect(options.length).toBe(2) + const commandOptions = options.filter((option) => option.type === ContextMenuOptionType.Command) + expect(commandOptions[0].value).toBe("very-long-command-name-that-exceeds-normal-length") + }) + + it("should handle commands with numeric names", () => { + const numericCommands: Command[] = [ + { name: "command1", source: "project" }, + { name: "v2-setup", source: "project" }, + { name: "123test", source: "project" }, + ] + + const options = getContextMenuOptions("/v", "/v", null, mockQueryItems, [], [], numericCommands) + + const commandNames = options.map((option) => option.value) + expect(commandNames).toContain("v2-setup") + }) + }) +}) diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index fa0781c865..65b78c3cd6 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -82,6 +82,16 @@ const Announcement = ({ hideAnnouncement }: AnnouncementProps) => { }} /> +
  • + •{" "} + , + code: , + }} + /> +
  • void + triggerClassName?: string + listApiConfigMeta: Array<{ id: string; name: string }> + pinnedApiConfigs?: Record + togglePinnedApiConfig: (id: string) => void +} + +export const ApiConfigSelector = ({ + value, + displayName, + disabled = false, + title = "", + onChange, + triggerClassName = "", + listApiConfigMeta, + pinnedApiConfigs, + togglePinnedApiConfig, +}: ApiConfigSelectorProps) => { + const { t } = useAppTranslation() + const [open, setOpen] = useState(false) + const [searchValue, setSearchValue] = useState("") + const portalContainer = useRooPortal("roo-portal") + + // Create searchable items for fuzzy search + const searchableItems = useMemo(() => { + return listApiConfigMeta.map((config) => ({ + original: config, + searchStr: config.name, + })) + }, [listApiConfigMeta]) + + // Create Fzf instance + const fzfInstance = useMemo(() => { + return new Fzf(searchableItems, { + selector: (item) => item.searchStr, + }) + }, [searchableItems]) + + // Filter configs based on search + const filteredConfigs = useMemo(() => { + if (!searchValue) return listApiConfigMeta + + const matchingItems = fzfInstance.find(searchValue).map((result) => result.item.original) + return matchingItems + }, [listApiConfigMeta, searchValue, fzfInstance]) + + // Separate pinned and unpinned configs + const { pinnedConfigs, unpinnedConfigs } = useMemo(() => { + const pinned = filteredConfigs.filter((config) => pinnedApiConfigs?.[config.id]) + const unpinned = filteredConfigs.filter((config) => !pinnedApiConfigs?.[config.id]) + return { pinnedConfigs: pinned, unpinnedConfigs: unpinned } + }, [filteredConfigs, pinnedApiConfigs]) + + const handleSelect = useCallback( + (configId: string) => { + onChange(configId) + setOpen(false) + setSearchValue("") + }, + [onChange], + ) + + const handleEditClick = useCallback(() => { + vscode.postMessage({ + type: "switchTab", + tab: "settings", + }) + setOpen(false) + }, []) + + const renderConfigItem = useCallback( + (config: { id: string; name: string }, isPinned: boolean) => { + const isCurrentConfig = config.id === value + + return ( +
    handleSelect(config.id)} + className={cn( + "px-3 py-1.5 text-sm cursor-pointer flex items-center group", + "hover:bg-vscode-list-hoverBackground", + isCurrentConfig && + "bg-vscode-list-activeSelectionBackground text-vscode-list-activeSelectionForeground", + )}> + {config.name} +
    + {isCurrentConfig && ( +
    + +
    + )} + + + +
    +
    + ) + }, + [value, handleSelect, t, togglePinnedApiConfig], + ) + + const triggerContent = ( + + + {displayName} + + ) + + return ( + + {title ? {triggerContent} : triggerContent} + +
    + {/* Search input or info blurb */} + {listApiConfigMeta.length > 6 ? ( +
    + setSearchValue(e.target.value)} + placeholder={t("common:ui.search_placeholder")} + className="w-full h-8 px-2 py-1 text-xs bg-vscode-input-background text-vscode-input-foreground border border-vscode-input-border rounded focus:outline-0" + autoFocus + /> + {searchValue.length > 0 && ( +
    + setSearchValue("")} + /> +
    + )} +
    + ) : ( +
    +

    + {t("prompts:apiConfiguration.select")} +

    +
    + )} + + {/* Config list */} +
    + {filteredConfigs.length === 0 && searchValue ? ( +
    + {t("common:ui.no_results")} +
    + ) : ( +
    + {/* Pinned configs */} + {pinnedConfigs.map((config) => renderConfigItem(config, true))} + + {/* Separator between pinned and unpinned */} + {pinnedConfigs.length > 0 && unpinnedConfigs.length > 0 && ( +
    + )} + + {/* Unpinned configs */} + {unpinnedConfigs.map((config) => renderConfigItem(config, false))} +
    + )} +
    + + {/* Bottom bar with buttons on left and title on right */} +
    +
    + +
    + + {/* Info icon and title on the right with matching spacing */} +
    + {listApiConfigMeta.length > 6 && ( + + + + )} +

    + {t("prompts:apiConfiguration.title")} +

    +
    +
    +
    + + + ) +} diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx index 2e987b7c49..0feafae15d 100644 --- a/webview-ui/src/components/chat/AutoApproveMenu.tsx +++ b/webview-ui/src/components/chat/AutoApproveMenu.tsx @@ -1,4 +1,4 @@ -import { useCallback, useMemo, useState } from "react" +import { memo, useCallback, useMemo, useState } from "react" import { Trans } from "react-i18next" import { VSCodeCheckbox, VSCodeLink, VSCodeTextField } from "@vscode/webview-ui-toolkit/react" @@ -129,11 +129,6 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { setIsExpanded((prev) => !prev) }, []) - // 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)) @@ -178,7 +173,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { content={!hasEnabledOptions ? t("chat:autoApprove.selectOptionsFirst") : undefined}> { ) } -export default AutoApproveMenu +export default memo(AutoApproveMenu) diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 6c541353eb..29d9fe61a6 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -19,14 +19,16 @@ import { SearchResult, } from "@src/utils/context-mentions" import { convertToMentionPath } from "@/utils/path-mentions" -import { SelectDropdown, DropdownOptionType, Button, StandardTooltip } from "@/components/ui" +import { StandardTooltip } from "@/components/ui" import Thumbnails from "../common/Thumbnails" import ModeSelector from "./ModeSelector" +import { ApiConfigSelector } from "./ApiConfigSelector" import { MAX_IMAGES_PER_MESSAGE } from "./ChatView" import ContextMenu from "./ContextMenu" -import { VolumeX, Pin, Check, Image, WandSparkles, SendHorizontal } from "lucide-react" +import { VolumeX, Image, WandSparkles, SendHorizontal } from "lucide-react" import { IndexingStatusBadge } from "./IndexingStatusBadge" +import { SlashCommandsPopover } from "./SlashCommandsPopover" import { cn } from "@/lib/utils" import { usePromptHistory } from "./hooks/usePromptHistory" import { EditModeControls } from "./EditModeControls" @@ -86,6 +88,7 @@ const ChatTextArea = forwardRef( togglePinnedApiConfig, taskHistory, clineMessages, + commands, } = useExtensionState() // Find the ID and display text for the currently selected API configuration @@ -143,6 +146,36 @@ const ChatTextArea = forwardRef( } setIsEnhancingPrompt(false) + } else if (message.type === "insertTextIntoTextarea") { + if (message.text && textAreaRef.current) { + // Insert the command text at the current cursor position + const textarea = textAreaRef.current + const currentValue = inputValue + const cursorPos = textarea.selectionStart || 0 + + // Check if we need to add a space before the command + const textBefore = currentValue.slice(0, cursorPos) + const needsSpaceBefore = textBefore.length > 0 && !textBefore.endsWith(" ") + const prefix = needsSpaceBefore ? " " : "" + + // Insert the text at cursor position + const newValue = + currentValue.slice(0, cursorPos) + + prefix + + message.text + + " " + + currentValue.slice(cursorPos) + setInputValue(newValue) + + // Set cursor position after the inserted text + const newCursorPos = cursorPos + prefix.length + message.text.length + 1 + setTimeout(() => { + if (textAreaRef.current) { + textAreaRef.current.focus() + textAreaRef.current.setSelectionRange(newCursorPos, newCursorPos) + } + }, 0) + } } else if (message.type === "commitSearchResults") { const commits = message.commits.map((commit: any) => ({ type: ContextMenuOptionType.Git, @@ -163,7 +196,7 @@ const ChatTextArea = forwardRef( window.addEventListener("message", messageHandler) return () => window.removeEventListener("message", messageHandler) - }, [setInputValue, searchRequestId]) + }, [setInputValue, searchRequestId, inputValue]) const [isDraggingOver, setIsDraggingOver] = useState(false) const [textAreaBaseHeight, setTextAreaBaseHeight] = useState(undefined) @@ -202,10 +235,6 @@ const ChatTextArea = forwardRef( }, [selectedType, searchQuery]) const handleEnhancePrompt = useCallback(() => { - if (sendingDisabled) { - return - } - const trimmedInput = inputValue.trim() if (trimmedInput) { @@ -214,7 +243,7 @@ const ChatTextArea = forwardRef( } else { setInputValue(t("chat:enhancePromptDescription")) } - }, [inputValue, sendingDisabled, setInputValue, t]) + }, [inputValue, setInputValue, t]) const allModes = useMemo(() => getAllModes(customModes), [customModes]) @@ -273,6 +302,27 @@ const ChatTextArea = forwardRef( return } + if (type === ContextMenuOptionType.Command && value) { + // Handle command selection. + setSelectedMenuIndex(-1) + setInputValue("") + setShowContextMenu(false) + + // Insert the command mention into the textarea + const commandMention = `/${value}` + setInputValue(commandMention + " ") + setCursorPosition(commandMention.length + 1) + setIntendedCursorPosition(commandMention.length + 1) + + // Focus the textarea + setTimeout(() => { + if (textAreaRef.current) { + textAreaRef.current.focus() + } + }, 0) + return + } + if ( type === ContextMenuOptionType.File || type === ContextMenuOptionType.Folder || @@ -302,6 +352,8 @@ const ChatTextArea = forwardRef( insertValue = "terminal" } else if (type === ContextMenuOptionType.Git) { insertValue = value || "" + } else if (type === ContextMenuOptionType.Command) { + insertValue = value ? `/${value}` : "" } const { newValue, mentionIndex } = insertMention( @@ -348,6 +400,7 @@ const ChatTextArea = forwardRef( queryItems, fileSearchResults, allModes, + commands, ) const optionsLength = options.length @@ -385,6 +438,7 @@ const ChatTextArea = forwardRef( queryItems, fileSearchResults, allModes, + commands, )[selectedMenuIndex] if ( selectedOption && @@ -407,11 +461,9 @@ const ChatTextArea = forwardRef( if (event.key === "Enter" && !event.shiftKey && !isComposing) { event.preventDefault() - if (!sendingDisabled) { - // Reset history navigation state when sending - resetHistoryNavigation() - onSend() - } + // Always call onSend - let ChatView handle queueing when disabled + resetHistoryNavigation() + onSend() } if (event.key === "Backspace" && !isComposing) { @@ -459,7 +511,6 @@ const ChatTextArea = forwardRef( } }, [ - sendingDisabled, onSend, showContextMenu, searchQuery, @@ -475,6 +526,7 @@ const ChatTextArea = forwardRef( fileSearchResults, handleHistoryNavigation, resetHistoryNavigation, + commands, ], ) @@ -504,10 +556,12 @@ const ChatTextArea = forwardRef( if (showMenu) { if (newValue.startsWith("/")) { - // Handle slash command. + // Handle slash command - request fresh commands const query = newValue setSearchQuery(query) setSelectedMenuIndex(0) + // Request commands fresh each time slash menu is shown + vscode.postMessage({ type: "requestCommands" }) } else { // Existing @ mention handling. const lastAtIndex = newValue.lastIndexOf("@", newCursorPosition - 1) @@ -824,122 +878,11 @@ const ChatTextArea = forwardRef( /> ) - // Helper function to get API config dropdown options - const getApiConfigOptions = useMemo(() => { - const pinnedConfigs = (listApiConfigMeta || []) - .filter((config) => pinnedApiConfigs && pinnedApiConfigs[config.id]) - .map((config) => ({ - value: config.id, - label: config.name, - name: config.name, - type: DropdownOptionType.ITEM, - pinned: true, - })) - .sort((a, b) => a.label.localeCompare(b.label)) - - const unpinnedConfigs = (listApiConfigMeta || []) - .filter((config) => !pinnedApiConfigs || !pinnedApiConfigs[config.id]) - .map((config) => ({ - value: config.id, - label: config.name, - name: config.name, - type: DropdownOptionType.ITEM, - pinned: false, - })) - .sort((a, b) => a.label.localeCompare(b.label)) - - const hasPinnedAndUnpinned = pinnedConfigs.length > 0 && unpinnedConfigs.length > 0 - - return [ - ...pinnedConfigs, - ...(hasPinnedAndUnpinned - ? [ - { - value: "sep-pinned", - label: t("chat:separator"), - type: DropdownOptionType.SEPARATOR, - }, - ] - : []), - ...unpinnedConfigs, - { - value: "sep-2", - label: t("chat:separator"), - type: DropdownOptionType.SEPARATOR, - }, - { - value: "settingsButtonClicked", - label: t("chat:edit"), - type: DropdownOptionType.ACTION, - }, - ] - }, [listApiConfigMeta, pinnedApiConfigs, t]) - // Helper function to handle API config change const handleApiConfigChange = useCallback((value: string) => { - if (value === "settingsButtonClicked") { - vscode.postMessage({ - type: "loadApiConfiguration", - text: value, - values: { section: "providers" }, - }) - } else { - vscode.postMessage({ type: "loadApiConfigurationById", text: value }) - } + vscode.postMessage({ type: "loadApiConfigurationById", text: value }) }, []) - // Helper function to render API config item - const renderApiConfigItem = useCallback( - ({ type, value, label, pinned }: any) => { - if (type !== DropdownOptionType.ITEM) { - return label - } - - const config = listApiConfigMeta?.find((c) => c.id === value) - const isCurrentConfig = config?.name === currentApiConfigName - - return ( -
    -
    - {label} -
    -
    -
    - -
    - - - -
    -
    - ) - }, - [listApiConfigMeta, currentApiConfigName, t, togglePinnedApiConfig], - ) - // Helper function to render non-edit mode controls const renderNonEditModeControls = () => (
    @@ -947,17 +890,16 @@ const ChatTextArea = forwardRef(
    {renderModeSelector()}
    -
    @@ -983,6 +925,7 @@ const ChatTextArea = forwardRef( )} + @@ -1138,8 +1079,8 @@ const ChatTextArea = forwardRef( @@ -1245,6 +1184,7 @@ const ChatTextArea = forwardRef( modes={allModes} loading={searchLoading} dynamicSearchResults={fileSearchResults} + commands={commands} />
    )} diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index b89a1fdc2e..d001ab4d7d 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -54,7 +54,9 @@ import AutoApproveMenu from "./AutoApproveMenu" import SystemPromptWarning from "./SystemPromptWarning" import ProfileViolationWarning from "./ProfileViolationWarning" import { CheckpointWarning } from "./CheckpointWarning" +import QueuedMessages from "./QueuedMessages" import { getLatestTodo } from "@roo/todo" +import { QueuedMessage } from "@roo-code/types" export interface ChatViewProps { isHidden: boolean @@ -154,6 +156,10 @@ const ChatViewComponent: React.ForwardRefRenderFunction(null) const [sendingDisabled, setSendingDisabled] = useState(false) const [selectedImages, setSelectedImages] = useState([]) + const [messageQueue, setMessageQueue] = useState([]) + const isProcessingQueueRef = useRef(false) + const retryCountRef = useRef>(new Map()) + const MAX_RETRY_ATTEMPTS = 3 // we need to hold on to the ask because useEffect > lastMessage will always let us know when an ask comes in and handle it, but by the time handleMessage is called, the last message might not be the ask anymore (it could be a say that followed) const [clineAsk, setClineAsk] = useState(undefined) @@ -439,6 +445,11 @@ const ChatViewComponent: React.ForwardRefRenderFunction { @@ -538,47 +549,133 @@ const ChatViewComponent: React.ForwardRefRenderFunction { - text = text.trim() + (text: string, images: string[], fromQueue = false) => { + try { + text = text.trim() - if (text || images.length > 0) { - // Mark that user has responded - this prevents any pending auto-approvals - userRespondedRef.current = true + if (text || images.length > 0) { + if (sendingDisabled && !fromQueue) { + // Generate a more unique ID using timestamp + random component + const messageId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}` + setMessageQueue((prev) => [...prev, { id: messageId, text, images }]) + setInputValue("") + setSelectedImages([]) + return + } + // Mark that user has responded - this prevents any pending auto-approvals + userRespondedRef.current = true - if (messagesRef.current.length === 0) { - vscode.postMessage({ type: "newTask", text, images }) - } else if (clineAskRef.current) { - if (clineAskRef.current === "followup") { - markFollowUpAsAnswered() + if (messagesRef.current.length === 0) { + vscode.postMessage({ type: "newTask", text, images }) + } else if (clineAskRef.current) { + if (clineAskRef.current === "followup") { + markFollowUpAsAnswered() + } + + // Use clineAskRef.current + switch ( + clineAskRef.current // Use clineAskRef.current + ) { + case "followup": + case "tool": + case "browser_action_launch": + case "command": // User can provide feedback to a tool or command use. + case "command_output": // User can send input to command stdin. + case "use_mcp_server": + case "completion_result": // If this happens then the user has feedback for the completion result. + case "resume_task": + case "resume_completed_task": + case "mistake_limit_reached": + vscode.postMessage({ + type: "askResponse", + askResponse: "messageResponse", + text, + images, + }) + break + // There is no other case that a textfield should be enabled. + } + } else { + // This is a new message in an ongoing task. + vscode.postMessage({ type: "askResponse", askResponse: "messageResponse", text, images }) } - // Use clineAskRef.current - switch ( - clineAskRef.current // Use clineAskRef.current - ) { - case "followup": - case "tool": - case "browser_action_launch": - case "command": // User can provide feedback to a tool or command use. - case "command_output": // User can send input to command stdin. - case "use_mcp_server": - case "completion_result": // If this happens then the user has feedback for the completion result. - case "resume_task": - case "resume_completed_task": - case "mistake_limit_reached": - vscode.postMessage({ type: "askResponse", askResponse: "messageResponse", text, images }) - break - // There is no other case that a textfield should be enabled. - } + handleChatReset() } - - handleChatReset() + } catch (error) { + console.error("Error in handleSendMessage:", error) + // If this was a queued message, we should handle it differently + if (fromQueue) { + throw error // Re-throw to be caught by the queue processor + } + // For direct sends, we could show an error to the user + // but for now we'll just log it } }, - [handleChatReset, markFollowUpAsAnswered], // messagesRef and clineAskRef are stable + [handleChatReset, markFollowUpAsAnswered, sendingDisabled], // messagesRef and clineAskRef are stable ) + useEffect(() => { + // Early return if conditions aren't met + // Also don't process queue if there's an API error (clineAsk === "api_req_failed") + if ( + sendingDisabled || + messageQueue.length === 0 || + isProcessingQueueRef.current || + clineAsk === "api_req_failed" + ) { + return + } + + // Mark as processing immediately to prevent race conditions + isProcessingQueueRef.current = true + + // Process the first message in the queue + const [nextMessage, ...remaining] = messageQueue + + // Update queue immediately to prevent duplicate processing + setMessageQueue(remaining) + + // Process the message + Promise.resolve() + .then(() => { + handleSendMessage(nextMessage.text, nextMessage.images, true) + // Clear retry count on success + retryCountRef.current.delete(nextMessage.id) + }) + .catch((error) => { + console.error("Failed to send queued message:", error) + + // Get current retry count + const retryCount = retryCountRef.current.get(nextMessage.id) || 0 + + // Only re-add if under retry limit + if (retryCount < MAX_RETRY_ATTEMPTS) { + retryCountRef.current.set(nextMessage.id, retryCount + 1) + // Re-add the message to the end of the queue + setMessageQueue((current) => [...current, nextMessage]) + } else { + console.error(`Message ${nextMessage.id} failed after ${MAX_RETRY_ATTEMPTS} attempts, discarding`) + retryCountRef.current.delete(nextMessage.id) + } + }) + .finally(() => { + isProcessingQueueRef.current = false + }) + + // Cleanup function to handle component unmount + return () => { + isProcessingQueueRef.current = false + } + }, [sendingDisabled, messageQueue, handleSendMessage, clineAsk]) + const handleSetChatBoxMessage = useCallback( (text: string, images: string[]) => { // Avoid nested template literals by breaking down the logic @@ -594,6 +691,18 @@ const ChatViewComponent: React.ForwardRefRenderFunction { + // Store refs in variables to avoid stale closure issues + const retryCountMap = retryCountRef.current + const isProcessingRef = isProcessingQueueRef + + return () => { + retryCountMap.clear() + isProcessingRef.current = false + } + }, []) + const startNewTask = useCallback(() => { vscode.postMessage({ type: "clearTask" }) // Focus the textarea directly after starting a new task @@ -1588,8 +1697,8 @@ const ChatViewComponent: React.ForwardRefRenderFunction { // Check for Command/Ctrl + Period (with or without Shift) - // Using event.code for better cross-platform compatibility - if ((event.metaKey || event.ctrlKey) && event.code === "Period") { + // Using event.key to respect keyboard layouts (e.g., Dvorak) + if ((event.metaKey || event.ctrlKey) && event.key === ".") { event.preventDefault() // Prevent default browser behavior if (event.shiftKey) { @@ -1634,7 +1743,9 @@ const ChatViewComponent: React.ForwardRefRenderFunction +
    {(showAnnouncement || showAnnouncementModal) && ( { @@ -1840,6 +1951,13 @@ const ChatViewComponent: React.ForwardRefRenderFunction )} + setMessageQueue((prev) => prev.filter((_, i) => i !== index))} + onUpdate={(index, newText) => { + setMessageQueue((prev) => prev.map((msg, i) => (i === index ? { ...msg, text: newText } : msg))) + }} + /> { - const { terminalShellIntegrationDisabled = false } = useExtensionState() + const { + terminalShellIntegrationDisabled = false, + allowedCommands = [], + deniedCommands = [], + setAllowedCommands, + setDeniedCommands, + } = useExtensionState() const { command, output: parsedOutput } = useMemo(() => parseCommandAndOutput(text), [text]) @@ -37,6 +51,37 @@ export const CommandExecution = ({ executionId, text, icon, title }: CommandExec // streaming output (this is the case for running commands). const output = streamingOutput || parsedOutput + // Extract command patterns from the actual command that was executed + const commandPatterns = useMemo(() => { + const extractedPatterns = extractPatternsFromCommand(command) + return extractedPatterns.map((pattern) => ({ + pattern, + })) + }, [command]) + + // Handle pattern changes + const handleAllowPatternChange = (pattern: string) => { + const isAllowed = allowedCommands.includes(pattern) + const newAllowed = isAllowed ? allowedCommands.filter((p) => p !== pattern) : [...allowedCommands, pattern] + const newDenied = deniedCommands.filter((p) => p !== pattern) + + setAllowedCommands(newAllowed) + setDeniedCommands(newDenied) + vscode.postMessage({ type: "allowedCommands", commands: newAllowed }) + vscode.postMessage({ type: "deniedCommands", commands: newDenied }) + } + + const handleDenyPatternChange = (pattern: string) => { + const isDenied = deniedCommands.includes(pattern) + const newDenied = isDenied ? deniedCommands.filter((p) => p !== pattern) : [...deniedCommands, pattern] + const newAllowed = allowedCommands.filter((p) => p !== pattern) + + setAllowedCommands(newAllowed) + setDeniedCommands(newDenied) + vscode.postMessage({ type: "allowedCommands", commands: newAllowed }) + vscode.postMessage({ type: "deniedCommands", commands: newDenied }) + } + const onMessage = useCallback( (event: MessageEvent) => { const message: ExtensionMessage = event.data @@ -121,9 +166,21 @@ export const CommandExecution = ({ executionId, text, icon, title }: CommandExec
    -
    - - +
    +
    + + +
    + {command && command.trim() && ( + + )}
    ) diff --git a/webview-ui/src/components/chat/CommandPatternSelector.tsx b/webview-ui/src/components/chat/CommandPatternSelector.tsx new file mode 100644 index 0000000000..87ccb1bab7 --- /dev/null +++ b/webview-ui/src/components/chat/CommandPatternSelector.tsx @@ -0,0 +1,193 @@ +import React, { useState, useMemo } from "react" +import { Check, ChevronDown, Info, X } from "lucide-react" +import { cn } from "../../lib/utils" +import { useTranslation, Trans } from "react-i18next" +import { VSCodeLink } from "@vscode/webview-ui-toolkit/react" +import { StandardTooltip } from "../ui/standard-tooltip" + +interface CommandPattern { + pattern: string + description?: string +} + +interface CommandPatternSelectorProps { + command: string + patterns: CommandPattern[] + allowedCommands: string[] + deniedCommands: string[] + onAllowPatternChange: (pattern: string) => void + onDenyPatternChange: (pattern: string) => void +} + +export const CommandPatternSelector: React.FC = ({ + command, + patterns, + allowedCommands, + deniedCommands, + onAllowPatternChange, + onDenyPatternChange, +}) => { + const { t } = useTranslation() + const [isExpanded, setIsExpanded] = useState(false) + const [editingStates, setEditingStates] = useState>({}) + + const handleOpenSettings = () => { + window.postMessage({ type: "action", action: "settingsButtonClicked", values: { section: "autoApprove" } }) + } + + // Create a combined list with full command first, then patterns + const allPatterns = useMemo(() => { + // Trim the command to ensure consistency with extracted patterns + const trimmedCommand = command.trim() + const fullCommandPattern: CommandPattern = { pattern: trimmedCommand } + + // Create a set to track unique patterns we've already seen + const seenPatterns = new Set() + seenPatterns.add(trimmedCommand) // Add the trimmed full command first + + // Filter out any patterns that are duplicates or are the same as the full command + const uniquePatterns = patterns.filter((p) => { + if (seenPatterns.has(p.pattern)) { + return false + } + seenPatterns.add(p.pattern) + return true + }) + + return [fullCommandPattern, ...uniquePatterns] + }, [command, patterns]) + + const getPatternStatus = (pattern: string): "allowed" | "denied" | "none" => { + if (allowedCommands.includes(pattern)) return "allowed" + if (deniedCommands.includes(pattern)) return "denied" + return "none" + } + + const getEditState = (pattern: string) => { + return editingStates[pattern] || { isEditing: false, value: pattern } + } + + const setEditState = (pattern: string, isEditing: boolean, value?: string) => { + setEditingStates((prev) => ({ + ...prev, + [pattern]: { isEditing, value: value ?? pattern }, + })) + } + + return ( +
    +
    + + + {isExpanded && ( +
    + {allPatterns.map((item) => { + const editState = getEditState(item.pattern) + const status = getPatternStatus(editState.value) + + return ( +
    +
    + {editState.isEditing ? ( + setEditState(item.pattern, true, e.target.value)} + onBlur={() => setEditState(item.pattern, false)} + onKeyDown={(e) => { + if (e.key === "Enter") { + setEditState(item.pattern, false) + } + if (e.key === "Escape") { + setEditState(item.pattern, false, item.pattern) + } + }} + className="font-mono text-xs bg-vscode-input-background text-vscode-input-foreground border border-vscode-input-border rounded px-2 py-1.5 w-full focus:outline-0 focus:ring-1 focus:ring-vscode-focusBorder" + placeholder={item.pattern} + autoFocus + /> + ) : ( +
    setEditState(item.pattern, true)} + className="font-mono text-xs text-vscode-foreground cursor-pointer hover:bg-vscode-list-hoverBackground px-2 py-1.5 rounded transition-colors border border-transparent break-all" + title="Click to edit pattern"> + {editState.value} + {item.description && ( + + - {item.description} + + )} +
    + )} +
    +
    + + +
    +
    + ) + })} +
    + )} +
    + ) +} diff --git a/webview-ui/src/components/chat/ContextMenu.tsx b/webview-ui/src/components/chat/ContextMenu.tsx index 1672c35ee3..b938e06bef 100644 --- a/webview-ui/src/components/chat/ContextMenu.tsx +++ b/webview-ui/src/components/chat/ContextMenu.tsx @@ -2,6 +2,7 @@ import React, { useEffect, useMemo, useRef, useState } from "react" import { getIconForFilePath, getIconUrlByName, getIconForDirectoryPath } from "vscode-material-icons" import type { ModeConfig } from "@roo-code/types" +import type { Command } from "@roo/ExtensionMessage" import { ContextMenuOptionType, @@ -23,6 +24,7 @@ interface ContextMenuProps { modes?: ModeConfig[] loading?: boolean dynamicSearchResults?: SearchResult[] + commands?: Command[] } const ContextMenu: React.FC = ({ @@ -36,13 +38,22 @@ const ContextMenu: React.FC = ({ queryItems, modes, dynamicSearchResults = [], + commands = [], }) => { const [materialIconsBaseUri, setMaterialIconsBaseUri] = useState("") const menuRef = useRef(null) const filteredOptions = useMemo(() => { - return getContextMenuOptions(searchQuery, inputValue, selectedType, queryItems, dynamicSearchResults, modes) - }, [searchQuery, inputValue, selectedType, queryItems, dynamicSearchResults, modes]) + return getContextMenuOptions( + searchQuery, + inputValue, + selectedType, + queryItems, + dynamicSearchResults, + modes, + commands, + ) + }, [searchQuery, inputValue, selectedType, queryItems, dynamicSearchResults, modes, commands]) useEffect(() => { if (menuRef.current) { @@ -68,10 +79,46 @@ const ContextMenu: React.FC = ({ const renderOptionContent = (option: ContextMenuQueryItem) => { switch (option.type) { + case ContextMenuOptionType.SectionHeader: + return ( + + {option.label} + + ) case ContextMenuOptionType.Mode: return (
    - {option.label} +
    + {option.slashCommand} +
    + {option.description && ( + + {option.description} + + )} +
    + ) + case ContextMenuOptionType.Command: + return ( +
    +
    + {option.slashCommand} +
    {option.description && ( = ({ switch (option.type) { case ContextMenuOptionType.Mode: return "symbol-misc" + case ContextMenuOptionType.Command: + return "play" case ContextMenuOptionType.OpenedFile: return "window" case ContextMenuOptionType.File: @@ -194,7 +243,11 @@ const ContextMenu: React.FC = ({ } const isOptionSelectable = (option: ContextMenuQueryItem): boolean => { - return option.type !== ContextMenuOptionType.NoResults && option.type !== ContextMenuOptionType.URL + return ( + option.type !== ContextMenuOptionType.NoResults && + option.type !== ContextMenuOptionType.URL && + option.type !== ContextMenuOptionType.SectionHeader + ) } return ( @@ -217,8 +270,9 @@ const ContextMenu: React.FC = ({ zIndex: 1000, display: "flex", flexDirection: "column", - maxHeight: "200px", + maxHeight: "300px", overflowY: "auto", + overflowX: "hidden", }}> {filteredOptions && filteredOptions.length > 0 ? ( filteredOptions.map((option, index) => ( @@ -226,12 +280,20 @@ const ContextMenu: React.FC = ({ key={`${option.type}-${option.value || index}`} onClick={() => isOptionSelectable(option) && onSelect(option.type, option.value)} style={{ - padding: "4px 6px", + padding: + option.type === ContextMenuOptionType.SectionHeader ? "8px 6px 4px 6px" : "4px 6px", cursor: isOptionSelectable(option) ? "pointer" : "default", color: "var(--vscode-dropdown-foreground)", display: "flex", alignItems: "center", justifyContent: "space-between", + position: "relative", + ...(option.type === ContextMenuOptionType.SectionHeader + ? { + borderBottom: "1px solid var(--vscode-editorGroup-border)", + marginBottom: "2px", + } + : {}), ...(index === selectedIndex && isOptionSelectable(option) ? { backgroundColor: "var(--vscode-list-activeSelectionBackground)", @@ -248,6 +310,7 @@ const ContextMenu: React.FC = ({ minWidth: 0, overflow: "hidden", paddingTop: 0, + position: "relative", }}> {(option.type === ContextMenuOptionType.File || option.type === ContextMenuOptionType.Folder || @@ -264,9 +327,11 @@ const ContextMenu: React.FC = ({ /> )} {option.type !== ContextMenuOptionType.Mode && + option.type !== ContextMenuOptionType.Command && option.type !== ContextMenuOptionType.File && option.type !== ContextMenuOptionType.Folder && option.type !== ContextMenuOptionType.OpenedFile && + option.type !== ContextMenuOptionType.SectionHeader && getIconForOption(option) && ( { e.stopPropagation() + // Cancel the auto-approve timer when edit button is clicked + setSuggestionSelected(true) + onCancelAutoApproval?.() // Simulate shift-click by directly calling the handler with shiftKey=true. onSuggestionClick?.(suggestion, { ...e, shiftKey: true }) }}> diff --git a/webview-ui/src/components/chat/Markdown.tsx b/webview-ui/src/components/chat/Markdown.tsx index ba838284d7..87780d5df8 100644 --- a/webview-ui/src/components/chat/Markdown.tsx +++ b/webview-ui/src/components/chat/Markdown.tsx @@ -21,7 +21,7 @@ export const Markdown = memo(({ markdown, partial }: { markdown?: string; partia onMouseEnter={() => setIsHovering(true)} onMouseLeave={() => setIsHovering(false)} style={{ position: "relative" }}> -
    +
    {markdown && !partial && isHovering && ( diff --git a/webview-ui/src/components/chat/ModeSelector.tsx b/webview-ui/src/components/chat/ModeSelector.tsx index 336e9f8357..93dd2f1f4f 100644 --- a/webview-ui/src/components/chat/ModeSelector.tsx +++ b/webview-ui/src/components/chat/ModeSelector.tsx @@ -1,5 +1,5 @@ import React from "react" -import { ChevronUp, Check } from "lucide-react" +import { ChevronUp, Check, X } from "lucide-react" import { cn } from "@/lib/utils" import { useRooPortal } from "@/components/ui/hooks/useRooPortal" import { Popover, PopoverContent, PopoverTrigger, StandardTooltip } from "@/components/ui" @@ -11,6 +11,10 @@ import { Mode, getAllModes } from "@roo/modes" import { ModeConfig, CustomModePrompts } from "@roo-code/types" import { telemetryClient } from "@/utils/TelemetryClient" import { TelemetryEventName } from "@roo-code/types" +import { Fzf } from "fzf" + +// Minimum number of modes required to show search functionality +const SEARCH_THRESHOLD = 6 interface ModeSelectorProps { value: Mode @@ -21,6 +25,7 @@ interface ModeSelectorProps { modeShortcutText: string customModes?: ModeConfig[] customModePrompts?: CustomModePrompts + disableSearch?: boolean } export const ModeSelector = ({ @@ -32,13 +37,16 @@ export const ModeSelector = ({ modeShortcutText, customModes, customModePrompts, + disableSearch = false, }: ModeSelectorProps) => { const [open, setOpen] = React.useState(false) + const [searchValue, setSearchValue] = React.useState("") + const searchInputRef = React.useRef(null) const portalContainer = useRooPortal("roo-portal") const { hasOpenedModeSelector, setHasOpenedModeSelector } = useExtensionState() const { t } = useAppTranslation() - const trackModeSelectorOpened = () => { + const trackModeSelectorOpened = React.useCallback(() => { // Track telemetry every time the mode selector is opened telemetryClient.capture(TelemetryEventName.MODE_SELECTOR_OPENED) @@ -47,7 +55,7 @@ export const ModeSelector = ({ setHasOpenedModeSelector(true) vscode.postMessage({ type: "hasOpenedModeSelector", bool: true }) } - } + }, [hasOpenedModeSelector, setHasOpenedModeSelector]) // Get all modes including custom modes and merge custom prompt descriptions const modes = React.useMemo(() => { @@ -61,6 +69,96 @@ export const ModeSelector = ({ // Find the selected mode const selectedMode = React.useMemo(() => modes.find((mode) => mode.slug === value), [modes, value]) + // Memoize searchable items for fuzzy search with separate name and description search + const nameSearchItems = React.useMemo(() => { + return modes.map((mode) => ({ + original: mode, + searchStr: [mode.name, mode.slug].filter(Boolean).join(" "), + })) + }, [modes]) + + const descriptionSearchItems = React.useMemo(() => { + return modes.map((mode) => ({ + original: mode, + searchStr: mode.description || "", + })) + }, [modes]) + + // Create memoized Fzf instances for name and description searches + const nameFzfInstance = React.useMemo(() => { + return new Fzf(nameSearchItems, { + selector: (item) => item.searchStr, + }) + }, [nameSearchItems]) + + const descriptionFzfInstance = React.useMemo(() => { + return new Fzf(descriptionSearchItems, { + selector: (item) => item.searchStr, + }) + }, [descriptionSearchItems]) + + // Filter modes based on search value using fuzzy search with priority + const filteredModes = React.useMemo(() => { + if (!searchValue) return modes + + // First search in names/slugs + const nameMatches = nameFzfInstance.find(searchValue) + const nameMatchedModes = new Set(nameMatches.map((result) => result.item.original.slug)) + + // Then search in descriptions + const descriptionMatches = descriptionFzfInstance.find(searchValue) + + // Combine results: name matches first, then description matches + const combinedResults = [ + ...nameMatches.map((result) => result.item.original), + ...descriptionMatches + .filter((result) => !nameMatchedModes.has(result.item.original.slug)) + .map((result) => result.item.original), + ] + + return combinedResults + }, [modes, searchValue, nameFzfInstance, descriptionFzfInstance]) + + const onClearSearch = React.useCallback(() => { + setSearchValue("") + searchInputRef.current?.focus() + }, []) + + const handleSelect = React.useCallback( + (modeSlug: string) => { + onChange(modeSlug as Mode) + setOpen(false) + // Clear search after selection + setSearchValue("") + }, + [onChange], + ) + + const onOpenChange = React.useCallback( + (isOpen: boolean) => { + if (isOpen) trackModeSelectorOpened() + setOpen(isOpen) + // Clear search when closing + if (!isOpen) { + setSearchValue("") + } + }, + [trackModeSelectorOpened], + ) + + // Auto-focus search input when popover opens + React.useEffect(() => { + if (open && searchInputRef.current) { + searchInputRef.current.focus() + } + }, [open]) + + // Determine if search should be shown + const showSearch = !disableSearch && modes.length > SEARCH_THRESHOLD + + // Combine instruction text for tooltip + const instructionText = `${t("chat:modeSelector.description")} ${modeShortcutText}` + const trigger = ( { - if (isOpen) trackModeSelectorOpened() - setOpen(isOpen) - }} - data-testid="mode-selector-root"> + {title ? {trigger} : trigger}
    -
    -
    -

    {t("chat:modeSelector.title")}

    -
    - { - window.postMessage( - { - type: "action", - action: "marketplaceButtonClicked", - values: { marketplaceTab: "mode" }, - }, - "*", - ) - - setOpen(false) - }} - /> - { - vscode.postMessage({ - type: "switchTab", - tab: "modes", - }) - setOpen(false) - }} - /> -
    + {/* Show search bar only when there are more than SEARCH_THRESHOLD items, otherwise show info blurb */} + {showSearch ? ( +
    + setSearchValue(e.target.value)} + placeholder={t("chat:modeSelector.searchPlaceholder")} + className="w-full h-8 px-2 py-1 text-xs bg-vscode-input-background text-vscode-input-foreground border border-vscode-input-border rounded focus:outline-0" + data-testid="mode-search-input" + /> + {searchValue.length > 0 && ( +
    + +
    + )}
    -

    - {t("chat:modeSelector.description")} -
    - {modeShortcutText} -

    -
    + ) : ( +
    +

    {instructionText}

    +
    + )} {/* Mode List */} -
    - {modes.map((mode) => ( -
    + {filteredModes.length === 0 && searchValue ? ( +
    + {t("chat:modeSelector.noResults")} +
    + ) : ( +
    + {filteredModes.map((mode) => ( +
    handleSelect(mode.slug)} + className={cn( + "px-3 py-1.5 text-sm cursor-pointer flex items-center", + "hover:bg-vscode-list-hoverBackground", + mode.slug === value + ? "bg-vscode-list-activeSelectionBackground text-vscode-list-activeSelectionForeground" + : "", + )} + data-testid="mode-selector-item"> +
    +
    {mode.name}
    + {mode.description && ( +
    + {mode.description} +
    + )} +
    + {mode.slug === value && } +
    + ))} +
    + )} +
    + + {/* Bottom bar with buttons on left and title on right */} +
    +
    + { - onChange(mode.slug as Mode) + window.postMessage( + { + type: "action", + action: "marketplaceButtonClicked", + values: { marketplaceTab: "mode" }, + }, + "*", + ) setOpen(false) }} - data-testid="mode-selector-item"> -
    -

    {mode.name}

    - {mode.description && ( -

    - {mode.description} -

    - )} -
    - {mode.slug === value ? ( - - ) : ( -
    - )} -
    - ))} + /> + { + vscode.postMessage({ + type: "switchTab", + tab: "modes", + }) + setOpen(false) + }} + /> +
    + + {/* Info icon and title on the right - only show info icon when search bar is visible */} +
    + {showSearch && ( + + + + )} +

    + {t("chat:modeSelector.title")} +

    +
    diff --git a/webview-ui/src/components/chat/QueuedMessages.tsx b/webview-ui/src/components/chat/QueuedMessages.tsx new file mode 100644 index 0000000000..cd3ee6d896 --- /dev/null +++ b/webview-ui/src/components/chat/QueuedMessages.tsx @@ -0,0 +1,112 @@ +import React, { useState } from "react" +import { useTranslation } from "react-i18next" +import Thumbnails from "../common/Thumbnails" +import { QueuedMessage } from "@roo-code/types" +import { Mention } from "./Mention" +import { Button } from "@src/components/ui" + +interface QueuedMessagesProps { + queue: QueuedMessage[] + onRemove: (index: number) => void + onUpdate: (index: number, newText: string) => void +} + +const QueuedMessages: React.FC = ({ queue, onRemove, onUpdate }) => { + const { t } = useTranslation("chat") + const [editingStates, setEditingStates] = useState>({}) + + if (queue.length === 0) { + return null + } + + const getEditState = (messageId: string, currentText: string) => { + return editingStates[messageId] || { isEditing: false, value: currentText } + } + + const setEditState = (messageId: string, isEditing: boolean, value?: string) => { + setEditingStates((prev) => ({ + ...prev, + [messageId]: { isEditing, value: value ?? prev[messageId]?.value ?? "" }, + })) + } + + const handleSaveEdit = (index: number, messageId: string, newValue: string) => { + onUpdate(index, newValue) + setEditState(messageId, false) + } + + return ( +
    +
    {t("queuedMessages.title")}
    +
    + {queue.map((message, index) => { + const editState = getEditState(message.id, message.text) + + return ( +
    +
    +
    + {editState.isEditing ? ( +