diff --git a/.changeset/large-olives-wink.md b/.changeset/large-olives-wink.md deleted file mode 100644 index a3b4486f1e..0000000000 --- a/.changeset/large-olives-wink.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"roo-cline": patch ---- - -Fix model search being prefilled in dropdown to prevent confusion in available models diff --git a/.changeset/stale-rivers-travel.md b/.changeset/stale-rivers-travel.md deleted file mode 100644 index ba8047b2c8..0000000000 --- a/.changeset/stale-rivers-travel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -roo-code: minor ---- - -Add copy prompt button to task actions. Based on [@vultrnerd's feedback](https://github.com/Kilo-Org/kilocode/discussions/850). diff --git a/.gitattributes b/.gitattributes index e8eeb58b23..02ddd6b634 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,6 @@ demo.gif filter=lfs diff=lfs merge=lfs -text assets/docs/demo.gif filter=lfs diff=lfs merge=lfs -text src/assets/docs/demo.gif filter=lfs diff=lfs merge=lfs -text + +# Test snapshot files - mark as linguist-generated to exclude from GitHub language statistics +*.snap linguist-generated=true diff --git a/.roomodes b/.roomodes index 4ae740a6b4..f2bbe35fd1 100644 --- a/.roomodes +++ b/.roomodes @@ -153,7 +153,7 @@ customModes: - Providing direct, constructive feedback that improves code quality - Being appropriately critical to maintain high code standards - Using GitHub CLI when MCP tools are unavailable - + You work primarily with the RooCodeInc/Roo-Code repository, creating context reports to track findings and delegating complex pattern analysis to specialized modes while maintaining overall review coordination. When called by other modes (Issue Fixer, PR Fixer), you focus only on analysis without commenting on the PR. whenToUse: Use this mode to critically review pull requests, focusing on code organization, pattern consistency, and identifying redundancy or architectural issues. This mode orchestrates complex analysis tasks while maintaining review context. groups: @@ -184,18 +184,6 @@ customModes: - edit - command - mcp - - slug: issue-fixer-orchestrator - name: 🔧 Issue Fixer Orchestrator - roleDefinition: |- - You are an orchestrator for fixing GitHub issues. Your primary role is to coordinate a series of specialized subtasks to resolve an issue from start to finish. - **Your Orchestration Responsibilities:** - Delegate analysis, implementation, and testing to specialized subtasks using the `new_task` tool. - Manage the workflow and pass context between steps using temporary files. - Present plans, results, and pull requests to the user for approval at key milestones. - **Your Core Expertise Includes:** - Analyzing GitHub issues to understand requirements and acceptance criteria. - Exploring codebases to identify all affected files and dependencies. - Guiding the implementation of high-quality fixes and features. - Ensuring comprehensive test coverage. - Overseeing the creation of well-documented pull requests. - Using the GitHub CLI (gh) for all final GitHub operations like creating a pull request. - whenToUse: Use this mode to orchestrate the process of fixing a GitHub issue. Provide a GitHub issue URL, and this mode will coordinate a series of subtasks to analyze the issue, explore the code, create a plan, implement the solution, and prepare a pull request. - groups: - - read - - edit - - command - source: project - slug: pr-fixer-orchestrator name: 🛠️ PR Fixer Orchestrator roleDefinition: |- @@ -203,8 +191,14 @@ customModes: **Your Orchestration Responsibilities:** - Delegate analysis, implementation, testing, and review to specialized subtasks using the `new_task` tool. - Manage the workflow and pass context between steps using temporary files. - Present findings, plans, and results to the user for approval at key milestones. - Ensure the PR branch is properly synced with main and ready for merge. **Your Core Expertise Includes:** - Analyzing PR feedback, failing tests, and merge conflicts. - Understanding the underlying issue or feature being implemented. - Exploring codebases to identify all affected files and dependencies. - Understanding CI/CD pipeline failures and test results. - Coordinating code fixes based on review comments. - Managing git operations including rebases and conflict resolution. - Ensuring proper testing and validation of changes. - Overseeing PR review before final submission. - Using GitHub CLI (gh) for all GitHub operations. whenToUse: Use this mode to orchestrate the process of fixing a pull request. Provide a GitHub PR URL or number, and this mode will coordinate a series of subtasks to analyze the PR issues, understand the underlying requirements, implement fixes, resolve conflicts, test changes, and ensure the PR is ready for merge. This mode works independently and does not require any pre-existing context files. - groups: - - read - - edit - - command + groups: [] + source: project + - slug: issue-fixer-orchestrator + name: 🔧 Issue Fixer Orchestrator + roleDefinition: |- + You are an orchestrator for fixing GitHub issues. Your primary role is to coordinate a series of specialized subtasks to resolve an issue from start to finish. + **Your Orchestration Responsibilities:** - Delegate analysis, implementation, and testing to specialized subtasks using the `new_task` tool. - Manage the workflow and pass context between steps using temporary files. - Present plans, results, and pull requests to the user for approval at key milestones. + **Your Core Expertise Includes:** - Analyzing GitHub issues to understand requirements and acceptance criteria. - Exploring codebases to identify all affected files and dependencies. - Guiding the implementation of high-quality fixes and features. - Ensuring comprehensive test coverage. - Overseeing the creation of well-documented pull requests. - Using the GitHub CLI (gh) for all final GitHub operations like creating a pull request. + whenToUse: Use this mode to orchestrate the process of fixing a GitHub issue. Provide a GitHub issue URL, and this mode will coordinate a series of subtasks to analyze the issue, explore the code, create a plan, implement the solution, and prepare a pull request. + groups: [] source: project diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a629487e0..e94c518a66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,49 @@ # Roo Code Changelog +## [3.23.3] - 2025-07-09 + +- Remove erroneous line from announcement modal + +## [3.23.2] - 2025-07-09 + +- Fix bug where auto-approval was intermittently failing + +## [3.23.1] - 2025-07-09 + +- Always show the code indexing dot under the chat text area + +## [3.23.0] - 2025-07-08 + +- Move codebase indexing out of experimental (thanks @daniel-lxs and @MuriloFP!) +- Add todo list tool (thanks @qdaxb!) +- Fix code index secret persistence and improve settings UX (thanks @daniel-lxs!) +- Add Gemini embedding provider for codebase indexing (thanks @SannidhyaSah!) +- Support full endpoint URLs in OpenAI Compatible provider (thanks @SannidhyaSah!) +- Add markdown support to codebase indexing (thanks @MuriloFP!) +- Add Search/Filter Functionality to API Provider Selection in Settings (thanks @GOODBOY008!) +- Add configurable max search results (thanks @MuriloFP!) +- Add copy prompt button to task actions (thanks @Juice10 and @vultrnerd!) +- Fix insertContentTool to create new files with content (thanks @Ruakij!) +- Fix typescript compiler watch path inconsistency (thanks @bbenshalom!) +- Use actual max_completion_tokens from OpenRouter API (thanks @shariqriazz!) +- Prevent completion sound from replaying when reopening completed tasks (thanks @SannidhyaSah!) +- Fix access_mcp_resource fails to handle images correctly (thanks @s97712!) +- Prevent chatbox focus loss during automated file editing (thanks @hannesrudolph!) +- Resolve intermittent hangs and lack of clear error feedback in apply_diff tool (thanks @lhish!) +- Resolve Go duplicate references in tree-sitter queries (thanks @MuriloFP!) +- Chat UI consistency and layout shifts (thanks @seedlord!) +- Chat index UI enhancements (thanks @MuriloFP!) +- Fix model search being prefilled on dropdown (thanks @kevinvandijk!) +- Improve chat UI - add camera icon margin and make placeholder non-selectable (thanks @MuriloFP!) +- Delete .roo/rules-{mode} folder when custom mode is deleted +- Enforce file restrictions for all edit tools in architect mode +- Add User-Agent header to API providers +- Fix auto question timer unmount (thanks @liwilliam2021!) +- Fix new_task tool streaming issue +- Optimize file listing when maxWorkspaceFiles is 0 (thanks @daniel-lxs!) +- Correct export/import of OpenAI Compatible codebase indexing settings (thanks @MuriloFP!) +- Resolve workspace path inconsistency in code indexing for multi-workspace scenarios + ## [3.22.6] - 2025-07-02 - Add timer-based auto approve for follow up questions (thanks @liwilliam2021!) diff --git a/README.md b/README.md index 4d6e5cd9db..65d284ab7c 100644 --- a/README.md +++ b/README.md @@ -49,13 +49,12 @@ Check out the [CHANGELOG](CHANGELOG.md) for detailed updates and fixes. --- -## 🎉 Roo Code 3.22 Released +## 🎉 Roo Code 3.23 Released -Roo Code 3.22 brings powerful new features and significant improvements to enhance your development workflow! +Roo Code 3.23 brings powerful new features and significant improvements to enhance your development workflow! -- **1-Click Task Sharing** - Share your tasks instantly with colleagues and the community with a single click. -- **Global .roo Directory Support** - Load rules and configurations from a global .roo directory for consistent settings across projects. -- **Improved Architect to Code Transitions** - Seamless handoffs from planning in Architect mode to implementation in Code mode. +- **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. --- @@ -208,42 +207,43 @@ Thanks to all our contributors who have helped make Roo Code better! -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| MuriloFP
MuriloFP
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| qdaxb
qdaxb
| -| feifei325
feifei325
| zhangtony239
zhangtony239
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| sachasayan
sachasayan
| cannuri
cannuri
| -| vigneshsubbiah16
vigneshsubbiah16
| shariqriazz
shariqriazz
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| dtrugman
dtrugman
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| Premshay
Premshay
| kiwina
kiwina
| -| lupuletic
lupuletic
| aheizi
aheizi
| SannidhyaSah
SannidhyaSah
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| -| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| StevenTCramer
StevenTCramer
| pdecat
pdecat
| -| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| -| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| liwilliam2021
liwilliam2021
| avtc
avtc
| dlab-anton
dlab-anton
| -| eonghk
eonghk
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| -| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| -| bramburn
bramburn
| 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
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| -| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| -| kinandan
kinandan
| nevermorec
nevermorec
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| -| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| -| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| -| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| shaybc
shaybc
| seedlord
seedlord
| -| 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
| kohii
kohii
| 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
| -| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| -| KevinZhao
KevinZhao
| ksze
ksze
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| -| pfitz
pfitz
| ExactDoug
ExactDoug
| | | | | +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | diff --git a/locales/ca/README.md b/locales/ca/README.md index 511175d766..12d0d06ffa 100644 --- a/locales/ca/README.md +++ b/locales/ca/README.md @@ -50,13 +50,12 @@ Consulteu el [CHANGELOG](../../CHANGELOG.md) per a actualitzacions i correccions --- -## 🎉 Roo Code 3.22 Llançat +## 🎉 Roo Code 3.23 Llançat -Roo Code 3.22 aporta noves funcionalitats potents i millores significatives per millorar el vostre flux de treball de desenvolupament! +Roo Code 3.23 aporta noves funcionalitats potents i millores significatives per millorar el vostre flux de treball de desenvolupament! -- **Compartir tasques amb 1 clic** - Comparteix les teves tasques instantàniament amb col·legues i la comunitat amb un sol clic. -- **Suport de directori .roo global** - Carrega regles i configuracions des d'un directori .roo global per a configuracions consistents entre projectes. -- **Transicions millorades d'Arquitecte a Codi** - Transferències fluides des de la planificació en mode Arquitecte fins a la implementació en mode Codi. +- **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. --- @@ -181,42 +180,45 @@ 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
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## Llicència diff --git a/locales/de/README.md b/locales/de/README.md index 2dbaaa4363..93cd49e5d9 100644 --- a/locales/de/README.md +++ b/locales/de/README.md @@ -50,13 +50,12 @@ Sehen Sie sich das [CHANGELOG](../../CHANGELOG.md) für detaillierte Updates und --- -## 🎉 Roo Code 3.22 veröffentlicht +## 🎉 Roo Code 3.23 veröffentlicht -Roo Code 3.22 bringt mächtige neue Funktionen und bedeutende Verbesserungen, um deinen Entwicklungsworkflow zu verbessern! +Roo Code 3.23 bringt mächtige neue Funktionen und bedeutende Verbesserungen, um deinen Entwicklungsworkflow zu verbessern! -- **1-Klick-Aufgaben-Teilen** - Teile deine Aufgaben sofort mit Kollegen und der Community mit einem einzigen Klick. -- **Globale .roo-Verzeichnis-Unterstützung** - Lade Regeln und Konfigurationen aus einem globalen .roo-Verzeichnis für konsistente Einstellungen über Projekte hinweg. -- **Verbesserte Übergänge von Architekt zu Code** - Nahtlose Übergaben von der Planung im Architekten-Modus zur Implementierung im Code-Modus. +- **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. --- @@ -181,42 +180,45 @@ 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
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## Lizenz diff --git a/locales/es/README.md b/locales/es/README.md index 45942a0ee5..42ce7a2cdf 100644 --- a/locales/es/README.md +++ b/locales/es/README.md @@ -50,13 +50,12 @@ Consulta el [CHANGELOG](../../CHANGELOG.md) para ver actualizaciones detalladas --- -## 🎉 Roo Code 3.22 Lanzado +## 🎉 Roo Code 3.23 Lanzado -¡Roo Code 3.22 trae nuevas funcionalidades poderosas y mejoras significativas para mejorar tu flujo de trabajo de desarrollo! +¡Roo Code 3.23 trae nuevas funcionalidades poderosas y mejoras significativas para mejorar tu flujo de trabajo de desarrollo! -- **Compartir tareas con 1 clic** - Comparte tus tareas instantáneamente con colegas y la comunidad con un solo clic. -- **Soporte de directorio .roo global** - Carga reglas y configuraciones desde un directorio .roo global para configuraciones consistentes entre proyectos. -- **Transiciones mejoradas de Arquitecto a Código** - Transferencias fluidas desde la planificación en modo Arquitecto hasta la implementación en modo Código. +- **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. --- @@ -181,42 +180,45 @@ 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
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## Licencia diff --git a/locales/fr/README.md b/locales/fr/README.md index cb7c02166b..6f97f8289d 100644 --- a/locales/fr/README.md +++ b/locales/fr/README.md @@ -50,13 +50,12 @@ Consultez le [CHANGELOG](../../CHANGELOG.md) pour des mises à jour détaillées --- -## 🎉 Roo Code 3.22 est sorti +## 🎉 Roo Code 3.23 est sorti -Roo Code 3.22 apporte de puissantes nouvelles fonctionnalités et des améliorations significatives pour améliorer ton flux de travail de développement ! +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 ! -- **Partage de tâches en 1 clic** - Partage tes tâches instantanément avec tes collègues et la communauté en un seul clic. -- **Support du répertoire .roo global** - Charge les règles et configurations depuis un répertoire .roo global pour des paramètres cohérents entre les projets. -- **Transitions améliorées d'Architecte vers Code** - Transferts fluides de la planification en mode Architecte vers l'implémentation en mode Code. +- **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. --- @@ -181,42 +180,45 @@ 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
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## Licence diff --git a/locales/hi/README.md b/locales/hi/README.md index 38cfae33a4..40f17b84bb 100644 --- a/locales/hi/README.md +++ b/locales/hi/README.md @@ -50,13 +50,12 @@ --- -## 🎉 Roo Code 3.21 जारी +## 🎉 Roo Code 3.23 जारी -Roo Code 3.21 आपकी प्रतिक्रियाओं के आधार पर प्रमुख नई सुविधाएँ और सुधार लाता है! +Roo Code 3.23 आपके डेवलपमेंट वर्कफ़्लो को बेहतर बनाने के लिए शक्तिशाली नई सुविधाएं और महत्वपूर्ण सुधार लाता है! -- **मार्केटप्लेस अब लाइव है! मार्केटप्लेस अब लाइव है!** मोड्स और MCPs को पहले से कहीं आसान तरीके से खोजें और इंस्टॉल करें। -- **नए Gemini 2.5 Pro, Flash और Flash Lite मॉडल्स के लिए समर्थन जोड़ा गया।** -- **Excel (.xlsx) फ़ाइल समर्थन और अधिक!** - उन्नत MCP समर्थन, अधिक Mermaid नियंत्रण, Amazon Bedrock में विचार समर्थन, और बहुत कुछ! +- **कोडबेस इंडेक्सिंग एक्सपेरिमेंटल से ग्रेजुएट** - पूर्ण कोडबेस इंडेक्सिंग अब स्थिर है और बेहतर खोज और संदर्भ समझ के साथ प्रोडक्शन उपयोग के लिए तैयार है। +- **नई टूडू लिस्ट सुविधा** - एकीकृत टास्क प्रबंधन के साथ अपने टास्क को ट्रैक पर रखें जो आपको व्यवस्थित रहने और अपने डेवलपमेंट लक्ष्यों पर केंद्रित रहने में मदद करता है। --- @@ -181,42 +180,45 @@ code --install-extension bin/roo-cline-.vsix Roo Code को बेहतर बनाने में मदद करने वाले हमारे सभी योगदानकर्ताओं को धन्यवाद! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## लाइसेंस diff --git a/locales/id/README.md b/locales/id/README.md index 2dfd3000fd..b940bafdd5 100644 --- a/locales/id/README.md +++ b/locales/id/README.md @@ -49,13 +49,12 @@ Lihat [CHANGELOG](../../CHANGELOG.md) untuk update dan perbaikan detail. --- -## 🎉 Roo Code 3.21 Dirilis +## 🎉 Roo Code 3.23 Dirilis -Roo Code 3.21 menghadirkan fitur baru utama dan perbaikan berdasarkan feedback kamu! +Roo Code 3.23 menghadirkan fitur-fitur baru yang powerful dan peningkatan signifikan untuk meningkatkan workflow development kamu! -- **Marketplace sekarang live! Marketplace sekarang live!** Temukan dan install mode serta MCP lebih mudah dari sebelumnya. -- **Ditambahkan dukungan untuk model Gemini 2.5 Pro, Flash, dan Flash Lite yang baru.** -- **Dukungan File Excel (.xlsx) & Lainnya!** - Dukungan MCP yang ditingkatkan, kontrol Mermaid lebih banyak, dukungan thinking di Amazon Bedrock, dan masih banyak lagi! +- **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. --- @@ -175,42 +174,45 @@ 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
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## License diff --git a/locales/it/README.md b/locales/it/README.md index 34f6d3d029..71a25df3e3 100644 --- a/locales/it/README.md +++ b/locales/it/README.md @@ -50,13 +50,12 @@ Consulta il [CHANGELOG](../../CHANGELOG.md) per aggiornamenti dettagliati e corr --- -## 🎉 Roo Code 3.21 Rilasciato +## 🎉 Roo Code 3.23 Rilasciato -Roo Code 3.21 porta nuove funzionalità principali e miglioramenti basati sui vostri feedback! +Roo Code 3.23 porta nuove funzionalità potenti e miglioramenti significativi per migliorare il tuo flusso di lavoro di sviluppo! -- **Il marketplace è ora live! Il marketplace è ora live!** Scopri e installa mode e MCP più facilmente che mai. -- **Aggiunto supporto per i nuovi modelli Gemini 2.5 Pro, Flash e Flash Lite.** -- **Supporto File Excel (.xlsx) e Altro!** - Supporto MCP migliorato, più controlli Mermaid, supporto thinking in Amazon Bedrock, e molto altro! +- **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. --- @@ -181,42 +180,45 @@ 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
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## Licenza diff --git a/locales/ja/README.md b/locales/ja/README.md index 07b12f1792..396f03fa11 100644 --- a/locales/ja/README.md +++ b/locales/ja/README.md @@ -50,13 +50,12 @@ --- -## 🎉 Roo Code 3.22 リリース +## 🎉 Roo Code 3.23 リリース -Roo Code 3.22は、開発ワークフローを向上させる強力な新機能と重要な改善をもたらします! +Roo Code 3.23は、開発ワークフローを向上させる強力な新機能と重要な改善をもたらします! -- **1クリックタスク共有** - 同僚やコミュニティとタスクを1クリックで瞬時に共有できます。 -- **グローバル.rooディレクトリサポート** - プロジェクト間で一貫した設定のためにグローバル.rooディレクトリからルールと設定を読み込みます。 -- **改善されたアーキテクトからコードへの移行** - アーキテクトモードでの計画からコードモードでの実装へのシームレスな引き継ぎ。 +- **コードベースインデックス化が実験的から卒業** - 完全なコードベースインデックス化が安定し、改善された検索とコンテキスト理解でプロダクション使用の準備が整いました。 +- **新しいTodoリスト機能** - 統合されたタスク管理でタスクを軌道に乗せ、整理された状態を保ち、開発目標に集中できるようサポートします。 --- @@ -181,42 +180,45 @@ code --install-extension bin/roo-cline-.vsix Roo Codeの改善に貢献してくれたすべての貢献者に感謝します! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## ライセンス diff --git a/locales/ko/README.md b/locales/ko/README.md index 8d9e0381c1..7e240eb174 100644 --- a/locales/ko/README.md +++ b/locales/ko/README.md @@ -50,13 +50,12 @@ --- -## 🎉 Roo Code 3.22 출시 +## 🎉 Roo Code 3.23 출시 -Roo Code 3.22가 개발 워크플로우를 향상시키는 강력한 새 기능과 중요한 개선사항을 제공합니다! +Roo Code 3.23가 개발 워크플로우를 향상시키는 강력한 새 기능과 중요한 개선사항을 제공합니다! -- **1클릭 작업 공유** - 동료와 커뮤니티에 한 번의 클릭으로 즉시 작업을 공유하세요. -- **글로벌 .roo 디렉토리 지원** - 프로젝트 간 일관된 설정을 위해 글로벌 .roo 디렉토리에서 규칙과 구성을 로드합니다. -- **개선된 아키텍트에서 코드로의 전환** - 아키텍트 모드에서의 계획부터 코드 모드에서의 구현까지 원활한 인수인계. +- **코드베이스 인덱싱이 실험적에서 졸업** - 전체 코드베이스 인덱싱이 이제 안정적이며 향상된 검색과 컨텍스트 이해로 프로덕션 사용 준비가 완료되었습니다. +- **새로운 할 일 목록 기능** - 통합된 작업 관리로 작업을 궤도에 유지하여 체계적으로 정리하고 개발 목표에 집중할 수 있도록 도와줍니다. --- @@ -181,42 +180,45 @@ code --install-extension bin/roo-cline-.vsix Roo Code를 더 좋게 만드는 데 도움을 준 모든 기여자에게 감사드립니다! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## 라이선스 diff --git a/locales/nl/README.md b/locales/nl/README.md index b083ddf1b1..6bf3843c16 100644 --- a/locales/nl/README.md +++ b/locales/nl/README.md @@ -50,13 +50,12 @@ Bekijk de [CHANGELOG](../../CHANGELOG.md) voor gedetailleerde updates en fixes. --- -## 🎉 Roo Code 3.22 Uitgebracht +## 🎉 Roo Code 3.23 Uitgebracht -Roo Code 3.22 brengt krachtige nieuwe functies en significante verbeteringen om je ontwikkelingsworkflow te verbeteren! +Roo Code 3.23 brengt krachtige nieuwe functies en significante verbeteringen om je ontwikkelingsworkflow te verbeteren! -- **1-Klik Taak Delen** - Deel je taken direct met collega's en de gemeenschap met een enkele klik. -- **Globale .roo Directory Ondersteuning** - Laad regels en configuraties vanuit een globale .roo directory voor consistente instellingen tussen projecten. -- **Verbeterde Architect naar Code Overgangen** - Naadloze overdrachten van planning in Architect-modus naar implementatie in Code-modus. +- **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. --- @@ -181,42 +180,45 @@ 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
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## Licentie diff --git a/locales/pl/README.md b/locales/pl/README.md index 86be4bc846..8c0e0f7a94 100644 --- a/locales/pl/README.md +++ b/locales/pl/README.md @@ -50,13 +50,12 @@ Sprawdź [CHANGELOG](../../CHANGELOG.md), aby uzyskać szczegółowe informacje --- -## 🎉 Roo Code 3.22 został wydany +## 🎉 Roo Code 3.23 został wydany -Roo Code 3.22 wprowadza potężne nowe funkcje i znaczące usprawnienia, aby ulepszyć Twój przepływ pracy deweloperskiej! +Roo Code 3.23 wprowadza potężne nowe funkcje i znaczące usprawnienia, aby ulepszyć Twój przepływ pracy deweloperskiej! -- **Udostępnianie zadań jednym kliknięciem** - Udostępniaj swoje zadania natychmiast współpracownikom i społeczności jednym kliknięciem. -- **Wsparcie globalnego katalogu .roo** - Ładuj zasady i konfiguracje z globalnego katalogu .roo dla spójnych ustawień między projektami. -- **Ulepszone przejścia z Architekta do Kodu** - Płynne przekazania od planowania w trybie Architekta do implementacji w trybie Kodu. +- **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. --- @@ -181,42 +180,45 @@ 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
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## Licencja diff --git a/locales/pt-BR/README.md b/locales/pt-BR/README.md index ffcdd994d3..acccb68ad8 100644 --- a/locales/pt-BR/README.md +++ b/locales/pt-BR/README.md @@ -50,13 +50,12 @@ Confira o [CHANGELOG](../../CHANGELOG.md) para atualizações e correções deta --- -## 🎉 Roo Code 3.22 foi lançado +## 🎉 Roo Code 3.23 foi lançado -O Roo Code 3.22 traz novos recursos poderosos e melhorias significativas para aprimorar seu fluxo de trabalho de desenvolvimento! +O Roo Code 3.23 traz novos recursos poderosos e melhorias significativas para aprimorar seu fluxo de trabalho de desenvolvimento! -- **Compartilhamento de Tarefas com 1 Clique** - Compartilhe suas tarefas instantaneamente com colegas e a comunidade com um único clique. -- **Suporte a Diretório .roo Global** - Carregue regras e configurações de um diretório .roo global para configurações consistentes entre projetos. -- **Transições Aprimoradas de Arquiteto para Código** - Transferências perfeitas do planejamento no modo Arquiteto para implementação no modo Código. +- **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. --- @@ -181,42 +180,45 @@ 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
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## Licença diff --git a/locales/ru/README.md b/locales/ru/README.md index 35250c85ec..be125a54a2 100644 --- a/locales/ru/README.md +++ b/locales/ru/README.md @@ -50,13 +50,12 @@ --- -## 🎉 Выпущен Roo Code 3.22 +## 🎉 Выпущен Roo Code 3.23 -Roo Code 3.22 представляет мощные новые функции и значительные улучшения для повышения эффективности вашего рабочего процесса разработки! +Roo Code 3.23 представляет мощные новые функции и значительные улучшения для повышения эффективности вашего рабочего процесса разработки! -- **Обмен задачами в 1 клик** - Мгновенно делитесь своими задачами с коллегами и сообществом одним кликом. -- **Поддержка глобального каталога .roo** - Загружайте правила и конфигурации из глобального каталога .roo для согласованных настроек между проектами. -- **Улучшенные переходы от Архитектора к Коду** - Плавные передачи от планирования в режиме Архитектора к реализации в режиме Кода. +- **Индексация кодовой базы выпущена из экспериментальной** - Полная индексация кодовой базы теперь стабильна и готова для производственного использования с улучшенным поиском и пониманием контекста. +- **Новая функция списка дел** - Держите свои задачи на правильном пути с интегрированным управлением задачами, которое помогает вам оставаться организованным и сосредоточенным на ваших целях разработки. --- @@ -181,42 +180,45 @@ code --install-extension bin/roo-cline-.vsix Спасибо всем нашим участникам, которые помогли сделать Roo Code лучше! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## Лицензия diff --git a/locales/tr/README.md b/locales/tr/README.md index ae52f4aeec..b546ada19d 100644 --- a/locales/tr/README.md +++ b/locales/tr/README.md @@ -50,13 +50,12 @@ Detaylı güncellemeler ve düzeltmeler için [CHANGELOG](../../CHANGELOG.md) do --- -## 🎉 Roo Code 3.22 Yayınlandı +## 🎉 Roo Code 3.23 Yayınlandı -Roo Code 3.22 geliştirme iş akışınızı geliştirmek için güçlü yeni özellikler ve önemli iyileştirmeler getiriyor! +Roo Code 3.23 geliştirme iş akışınızı geliştirmek için güçlü yeni özellikler ve önemli iyileştirmeler getiriyor! -- **1-Tık Görev Paylaşımı** - Görevlerinizi tek tıkla meslektaşlarınız ve toplulukla anında paylaşın. -- **Global .roo Dizin Desteği** - Projeler arası tutarlı ayarlar için global .roo dizininden kuralları ve konfigürasyonları yükleyin. -- **Gelişmiş Mimar'dan Kod'a Geçişler** - Mimar modunda planlamadan Kod modunda uygulamaya sorunsuz aktarımlar. +- **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. --- @@ -181,42 +180,45 @@ 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
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## Lisans diff --git a/locales/vi/README.md b/locales/vi/README.md index 9bc0a1a0a3..4f12a2dca6 100644 --- a/locales/vi/README.md +++ b/locales/vi/README.md @@ -50,13 +50,12 @@ Kiểm tra [CHANGELOG](../../CHANGELOG.md) để biết thông tin chi tiết v --- -## 🎉 Đã Phát Hành Roo Code 3.22 +## 🎉 Đã Phát Hành Roo Code 3.23 -Roo Code 3.22 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.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! -- **Chia Sẻ Tác Vụ 1-Cú Nhấp** - Chia sẻ tác vụ của bạn ngay lập tức với đồng nghiệp và cộng đồng chỉ bằng một cú nhấp. -- **Hỗ Trợ Thư Mục .roo Toàn Cục** - Tải quy tắc và cấu hình từ thư mục .roo toàn cục để có cài đặt nhất quán giữa các dự án. -- **Cải Thiện Chuyển Đổi từ Architect sang Code** - Chuyển giao liền mạch từ lập kế hoạch trong chế độ Architect sang triển khai trong chế độ Code. +- **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. --- @@ -181,42 +180,45 @@ 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
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## Giấy Phép diff --git a/locales/zh-CN/README.md b/locales/zh-CN/README.md index c8e06ba65b..1bc03b7120 100644 --- a/locales/zh-CN/README.md +++ b/locales/zh-CN/README.md @@ -50,13 +50,12 @@ --- -## 🎉 Roo Code 3.22 已发布 +## 🎉 Roo Code 3.23 已发布 -Roo Code 3.22 带来强大的新功能和重大改进,提升您的开发工作流程! +Roo Code 3.23 带来强大的新功能和重大改进,提升您的开发工作流程! -- **一键任务分享** - 一键即可与同事和社区分享您的任务。 -- **全局 .roo 目录支持** - 从全局 .roo 目录加载规则和配置,确保项目间设置一致。 -- **改进的架构师到代码模式转换** - 从架构师模式的规划到代码模式的实现,实现无缝交接。 +- **代码库索引从实验阶段毕业** - 完整的代码库索引现已稳定,可用于生产环境,具有改进的搜索和上下文理解能力。 +- **新的待办事项列表功能** - 通过集成的任务管理保持任务进度,帮助您保持组织性并专注于开发目标。 --- @@ -181,42 +180,45 @@ code --install-extension bin/roo-cline-.vsix 感谢所有帮助改进 Roo Code 的贡献者! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## 许可证 diff --git a/locales/zh-TW/README.md b/locales/zh-TW/README.md index 770d0303a5..1416694230 100644 --- a/locales/zh-TW/README.md +++ b/locales/zh-TW/README.md @@ -51,13 +51,12 @@ --- -## 🎉 Roo Code 3.22 已發布 +## 🎉 Roo Code 3.23 已發布 -Roo Code 3.22 帶來強大的新功能和重大改進,以提升您的開發工作流程! +Roo Code 3.23 帶來強大的新功能和重大改進,以提升您的開發工作流程! -- **一鍵任務分享** - 只需一鍵即可立即與同事和社群分享您的任務。 -- **全域 .roo 目錄支援** - 從全域 .roo 目錄載入規則和設定,確保專案間設定的一致性。 -- **改進的架構師到程式碼轉換** - 從架構師模式的規劃到程式碼模式的實作,實現無縫交接。 +- **程式碼庫索引從實驗階段畢業** - 完整的程式碼庫索引現已穩定,可用於生產環境,具有改進的搜尋和上下文理解能力。 +- **新的待辦事項清單功能** - 透過整合的任務管理保持任務進度,幫助您保持組織性並專注於開發目標。 --- @@ -182,42 +181,45 @@ code --install-extension bin/roo-cline-.vsix 感謝所有幫助改進 Roo Code 的貢獻者! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| -|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| -|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| -|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| -|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| -|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| -|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| -|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| -|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| -|bramburn
bramburn
|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
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| -|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| -|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| -|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| -|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| -|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| -|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
|kohii
kohii
|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
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|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
| -|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| -|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| MuriloFP
MuriloFP
| +| joemanley201
joemanley201
| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| roomote-bot
roomote-bot
| qdaxb
qdaxb
| +| xyOz-dev
xyOz-dev
| feifei325
feifei325
| zhangtony239
zhangtony239
| sachasayan
sachasayan
| monotykamary
monotykamary
| cannuri
cannuri
| +| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| +| SannidhyaSah
SannidhyaSah
| dtrugman
dtrugman
| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| +| Premshay
Premshay
| kiwina
kiwina
| lupuletic
lupuletic
| aheizi
aheizi
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| +| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| liwilliam2021
liwilliam2021
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| +| StevenTCramer
StevenTCramer
| pdecat
pdecat
| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| +| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| +| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| +| ross
ross
| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| GOODBOY008
GOODBOY008
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| +| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| seedlord
seedlord
| +| axkirillov
axkirillov
| anton-otee
anton-otee
| benzntech
benzntech
| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| +| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| philfung
philfung
| napter
napter
| mdp
mdp
| +| SplittyDev
SplittyDev
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| +| jwcraig
jwcraig
| shoopapa
shoopapa
| im47cn
im47cn
| hongzio
hongzio
| hatsu38
hatsu38
| forestyoo
forestyoo
| +| dqroid
dqroid
| dairui1
dairui1
| bbenshalom
bbenshalom
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| +| amittell
amittell
| nevermorec
nevermorec
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| s97712
s97712
| +| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| +| cdlliuy
cdlliuy
| user202729
user202729
| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| samir-nimbly
samir-nimbly
| zetaloop
zetaloop
| 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
| PretzelVector
PretzelVector
| kinandan
kinandan
| 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
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| 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
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| | | | + ## 授權 diff --git a/packages/types/npm/package.json b/packages/types/npm/package.json index eba5049426..50b3a1ec43 100644 --- a/packages/types/npm/package.json +++ b/packages/types/npm/package.json @@ -1,6 +1,6 @@ { "name": "@roo-code/types", - "version": "1.29.0", + "version": "1.31.0", "description": "TypeScript type definitions for Roo Code.", "publishConfig": { "access": "public", diff --git a/src/api/providers/__tests__/constants.spec.ts b/src/api/providers/__tests__/constants.spec.ts new file mode 100644 index 0000000000..8a04416d72 --- /dev/null +++ b/src/api/providers/__tests__/constants.spec.ts @@ -0,0 +1,61 @@ +// npx vitest run src/api/providers/__tests__/constants.spec.ts + +import { describe, it, expect } from "vitest" +import { DEFAULT_HEADERS } from "../constants" +import { Package } from "../../../shared/package" + +describe("DEFAULT_HEADERS", () => { + it("should contain all required headers", () => { + expect(DEFAULT_HEADERS).toHaveProperty("HTTP-Referer") + expect(DEFAULT_HEADERS).toHaveProperty("X-Title") + expect(DEFAULT_HEADERS).toHaveProperty("User-Agent") + }) + + it("should have correct HTTP-Referer value", () => { + expect(DEFAULT_HEADERS["HTTP-Referer"]).toBe("https://github.com/RooVetGit/Roo-Cline") + }) + + it("should have correct X-Title value", () => { + expect(DEFAULT_HEADERS["X-Title"]).toBe("Roo Code") + }) + + it("should have correct User-Agent format", () => { + const userAgent = DEFAULT_HEADERS["User-Agent"] + expect(userAgent).toBe(`RooCode/${Package.version}`) + + // Verify it follows the tool_name/version pattern + expect(userAgent).toMatch(/^[a-zA-Z-]+\/\d+\.\d+\.\d+$/) + }) + + it("should have User-Agent with correct tool name", () => { + const userAgent = DEFAULT_HEADERS["User-Agent"] + expect(userAgent.startsWith("RooCode/")).toBe(true) + }) + + it("should have User-Agent with semantic version format", () => { + const userAgent = DEFAULT_HEADERS["User-Agent"] + const version = userAgent.split("/")[1] + + // Check semantic version format (major.minor.patch) + expect(version).toMatch(/^\d+\.\d+\.\d+$/) + + // Verify current version matches package version + expect(version).toBe(Package.version) + }) + + it("should be an object with string values", () => { + expect(typeof DEFAULT_HEADERS).toBe("object") + expect(DEFAULT_HEADERS).not.toBeNull() + + Object.values(DEFAULT_HEADERS).forEach((value) => { + expect(typeof value).toBe("string") + expect(value.length).toBeGreaterThan(0) + }) + }) + + it("should have exactly 3 headers", () => { + const headerKeys = Object.keys(DEFAULT_HEADERS) + expect(headerKeys).toHaveLength(3) + expect(headerKeys).toEqual(["HTTP-Referer", "X-Title", "User-Agent"]) + }) +}) diff --git a/src/api/providers/__tests__/openai.spec.ts b/src/api/providers/__tests__/openai.spec.ts index 86d57ab3f5..b4b5f29204 100644 --- a/src/api/providers/__tests__/openai.spec.ts +++ b/src/api/providers/__tests__/openai.spec.ts @@ -5,6 +5,7 @@ import { ApiHandlerOptions } from "../../../shared/api" import { Anthropic } from "@anthropic-ai/sdk" import OpenAI from "openai" import { openAiModelInfoSaneDefaults } from "@roo-code/types" +import { Package } from "../../../shared/package" const mockCreate = vitest.fn() @@ -104,6 +105,7 @@ describe("OpenAiHandler", () => { defaultHeaders: { "HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline", "X-Title": "Roo Code", + "User-Agent": `RooCode/${Package.version}`, }, }) }) diff --git a/src/api/providers/__tests__/openrouter.spec.ts b/src/api/providers/__tests__/openrouter.spec.ts index 5c0e52c2c2..ea850c47be 100644 --- a/src/api/providers/__tests__/openrouter.spec.ts +++ b/src/api/providers/__tests__/openrouter.spec.ts @@ -8,6 +8,7 @@ import OpenAI from "openai" import { OpenRouterHandler } from "../openrouter" import { ApiHandlerOptions } from "../../../shared/api" +import { Package } from "../../../shared/package" // Mock dependencies vitest.mock("openai") @@ -62,6 +63,7 @@ describe("OpenRouterHandler", () => { defaultHeaders: { "HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline", "X-Title": "Roo Code", + "User-Agent": `RooCode/${Package.version}`, }, }) }) diff --git a/src/api/providers/__tests__/requesty.spec.ts b/src/api/providers/__tests__/requesty.spec.ts index 7f7fc2d527..55fb976fd1 100644 --- a/src/api/providers/__tests__/requesty.spec.ts +++ b/src/api/providers/__tests__/requesty.spec.ts @@ -5,6 +5,7 @@ import OpenAI from "openai" import { RequestyHandler } from "../requesty" import { ApiHandlerOptions } from "../../../shared/api" +import { Package } from "../../../shared/package" const mockCreate = vitest.fn() @@ -59,6 +60,7 @@ describe("RequestyHandler", () => { defaultHeaders: { "HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline", "X-Title": "Roo Code", + "User-Agent": `RooCode/${Package.version}`, }, }) }) diff --git a/src/api/providers/constants.ts b/src/api/providers/constants.ts index e7c4398324..144ff72349 100644 --- a/src/api/providers/constants.ts +++ b/src/api/providers/constants.ts @@ -1,4 +1,7 @@ +import { Package } from "../../shared/package" + export const DEFAULT_HEADERS = { "HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline", "X-Title": "Roo Code", + "User-Agent": `RooCode/${Package.version}`, } diff --git a/src/core/config/__tests__/importExport.spec.ts b/src/core/config/__tests__/importExport.spec.ts index 052bfc77f8..361d6b23b0 100644 --- a/src/core/config/__tests__/importExport.spec.ts +++ b/src/core/config/__tests__/importExport.spec.ts @@ -628,7 +628,7 @@ describe("importExport", () => { codebaseIndexEmbedderBaseUrl: "http://localhost:11434", // Wrong URL from Ollama // OpenAI Compatible settings are now stored directly in codebaseIndexConfig codebaseIndexOpenAiCompatibleBaseUrl: "https://custom-openai-api.example.com/v1", - codebaseIndexOpenAiCompatibleModelDimension: 1536, + codebaseIndexEmbedderModelDimension: 1536, }, } @@ -673,7 +673,7 @@ describe("importExport", () => { codebaseIndexEmbedderBaseUrl: "", // OpenAI Compatible settings are now stored directly in codebaseIndexConfig codebaseIndexOpenAiCompatibleBaseUrl: "https://api.example.com/v1", - codebaseIndexOpenAiCompatibleModelDimension: 768, + codebaseIndexEmbedderModelDimension: 768, }, } @@ -688,9 +688,7 @@ describe("importExport", () => { const exportedData = (safeWriteJson as Mock).mock.calls[0][1] // Settings are now exported as-is from codebaseIndexConfig - expect( - exportedData.globalSettings.codebaseIndexConfig.codebaseIndexOpenAiCompatibleModelDimension, - ).toBe(768) + expect(exportedData.globalSettings.codebaseIndexConfig.codebaseIndexEmbedderModelDimension).toBe(768) expect(exportedData.globalSettings.codebaseIndexConfig.codebaseIndexOpenAiCompatibleBaseUrl).toBe( "https://api.example.com/v1", ) @@ -731,7 +729,7 @@ describe("importExport", () => { codebaseIndexEmbedderBaseUrl: "http://localhost:11434", // Wrong URL from Ollama // OpenAI Compatible settings are now stored directly in codebaseIndexConfig codebaseIndexOpenAiCompatibleBaseUrl: "https://openai-compatible.example.com/v1", - codebaseIndexOpenAiCompatibleModelDimension: 1536, + codebaseIndexEmbedderModelDimension: 1536, }, } @@ -749,9 +747,7 @@ describe("importExport", () => { expect(exportedData.globalSettings.codebaseIndexConfig.codebaseIndexOpenAiCompatibleBaseUrl).toBe( "https://openai-compatible.example.com/v1", ) - expect( - exportedData.globalSettings.codebaseIndexConfig.codebaseIndexOpenAiCompatibleModelDimension, - ).toBe(1536) + expect(exportedData.globalSettings.codebaseIndexConfig.codebaseIndexEmbedderModelDimension).toBe(1536) // The generic embedder base URL is still there expect(exportedData.globalSettings.codebaseIndexConfig.codebaseIndexEmbedderBaseUrl).toBe( "http://localhost:11434", @@ -921,7 +917,6 @@ describe("importExport", () => { codebaseIndexEmbedderModelDimension: 1536, // OpenAI Compatible settings are now stored directly here codebaseIndexOpenAiCompatibleBaseUrl: "https://imported-url.example.com/v1", - codebaseIndexOpenAiCompatibleModelDimension: 1536, }, }, }) @@ -956,7 +951,7 @@ describe("importExport", () => { expect.objectContaining({ codebaseIndexConfig: expect.objectContaining({ codebaseIndexOpenAiCompatibleBaseUrl: "https://imported-url.example.com/v1", - codebaseIndexOpenAiCompatibleModelDimension: 1536, + codebaseIndexEmbedderModelDimension: 1536, }), }), ) @@ -1105,7 +1100,6 @@ describe("importExport", () => { codebaseIndexEmbedderModelDimension: testModelDimension, // OpenAI Compatible settings are now stored directly in codebaseIndexConfig codebaseIndexOpenAiCompatibleBaseUrl: "https://api.example.com/v1", - codebaseIndexOpenAiCompatibleModelDimension: testModelDimension, }, } @@ -1160,7 +1154,7 @@ describe("importExport", () => { // Step 9: Verify that the model dimension was preserved exactly in global settings const importedGlobalSettings = mockContextProxy.setValues.mock.calls[0][0] - expect(importedGlobalSettings.codebaseIndexConfig?.codebaseIndexOpenAiCompatibleModelDimension).toBe( + expect(importedGlobalSettings.codebaseIndexConfig?.codebaseIndexEmbedderModelDimension).toBe( testModelDimension, ) expect(importedGlobalSettings.codebaseIndexConfig?.codebaseIndexOpenAiCompatibleBaseUrl).toBe( @@ -1198,7 +1192,7 @@ describe("importExport", () => { codebaseIndexEmbedderBaseUrl: "https://api.example.com/v1", // OpenAI Compatible settings are now stored directly in codebaseIndexConfig codebaseIndexOpenAiCompatibleBaseUrl: "https://api.example.com/v1", - codebaseIndexOpenAiCompatibleModelDimension: testModelDimension, // 0 is a valid value + codebaseIndexEmbedderModelDimension: testModelDimension, // 0 is a valid value }, } @@ -1219,7 +1213,7 @@ describe("importExport", () => { // Verify the exported data includes the model dimension even when it's 0 const exportedData = (safeWriteJson as Mock).mock.calls[0][1] - expect(exportedData.globalSettings.codebaseIndexConfig.codebaseIndexOpenAiCompatibleModelDimension).toBe(0) + expect(exportedData.globalSettings.codebaseIndexConfig.codebaseIndexEmbedderModelDimension).toBe(0) // Test import roundtrip const exportedFileContent = JSON.stringify(exportedData) @@ -1247,7 +1241,7 @@ describe("importExport", () => { // Verify that model dimension 0 was preserved in global settings const setValuesCall = mockContextProxy.setValues.mock.calls[0][0] - expect(setValuesCall.codebaseIndexConfig?.codebaseIndexOpenAiCompatibleModelDimension).toBe(0) + expect(setValuesCall.codebaseIndexConfig?.codebaseIndexEmbedderModelDimension).toBe(0) }) it("should handle missing model dimension gracefully", async () => { diff --git a/src/core/environment/reminder.ts b/src/core/environment/reminder.ts index eb1b39dfb5..6edb24364d 100644 --- a/src/core/environment/reminder.ts +++ b/src/core/environment/reminder.ts @@ -5,7 +5,7 @@ import { TodoItem, TodoStatus } from "@roo-code/types" */ export function formatReminderSection(todoList?: TodoItem[]): string { if (!todoList || todoList.length === 0) { - return "" + return "You have not created a todo list yet. Create one with `update_todo_list` if your task is complicated or involves multiple steps." } const statusMap: Record = { pending: "Pending", diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap index 31b49ec682..9e08cccf36 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap @@ -489,7 +489,7 @@ RULES - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with `cd`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run `npm install` in a project outside of '/test/path', you would need to prepend with a `cd` i.e. pseudocode for this would be `cd (path to project) && (command, in this case npm install)`. - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes. - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser. -- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to existing files), search_and_replace (for finding and replacing individual pieces of text). +- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to files), search_and_replace (for finding and replacing individual pieces of text). - The insert_content tool adds lines of text to files at a specific line number, such as adding a new function to a JavaScript file or inserting a new route in a Python file. Use line number 0 to append at the end of the file, or any positive number to insert before that line. - The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once. - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files. @@ -549,13 +549,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. 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: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. 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 plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. 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. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**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.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/ask-mode-prompt.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/ask-mode-prompt.snap index 33b6addf28..a169a1f3af 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/ask-mode-prompt.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/ask-mode-prompt.snap @@ -386,7 +386,7 @@ RULES - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with `cd`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run `npm install` in a project outside of '/test/path', you would need to prepend with a `cd` i.e. pseudocode for this would be `cd (path to project) && (command, in this case npm install)`. - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes. - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser. -- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to existing files), search_and_replace (for finding and replacing individual pieces of text). +- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to files), search_and_replace (for finding and replacing individual pieces of text). - The insert_content tool adds lines of text to files at a specific line number, such as adding a new function to a JavaScript file or inserting a new route in a Python file. Use line number 0 to append at the end of the file, or any positive number to insert before that line. - The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once. - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files. diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap index b2b0abfad4..a42be559d1 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap @@ -551,7 +551,7 @@ RULES - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with `cd`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run `npm install` in a project outside of '/test/path', you would need to prepend with a `cd` i.e. pseudocode for this would be `cd (path to project) && (command, in this case npm install)`. - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes. - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser. -- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to existing files), search_and_replace (for finding and replacing individual pieces of text). +- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to files), search_and_replace (for finding and replacing individual pieces of text). - The insert_content tool adds lines of text to files at a specific line number, such as adding a new function to a JavaScript file or inserting a new route in a Python file. Use line number 0 to append at the end of the file, or any positive number to insert before that line. - The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once. - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files. @@ -611,13 +611,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. 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: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. 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 plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. 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. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**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.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap index 0eecf0482e..b12f208b1a 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap @@ -557,7 +557,7 @@ RULES - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with `cd`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run `npm install` in a project outside of '/test/path', you would need to prepend with a `cd` i.e. pseudocode for this would be `cd (path to project) && (command, in this case npm install)`. - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes. - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser. -- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to existing files), search_and_replace (for finding and replacing individual pieces of text). +- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to files), search_and_replace (for finding and replacing individual pieces of text). - The insert_content tool adds lines of text to files at a specific line number, such as adding a new function to a JavaScript file or inserting a new route in a Python file. Use line number 0 to append at the end of the file, or any positive number to insert before that line. - The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once. - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files. @@ -617,13 +617,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. 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: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. 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 plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. 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. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**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.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap index 731f4b29a7..d641a7efd9 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap @@ -494,7 +494,7 @@ RULES - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with `cd`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run `npm install` in a project outside of '/test/path', you would need to prepend with a `cd` i.e. pseudocode for this would be `cd (path to project) && (command, in this case npm install)`. - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes. - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser. -- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to existing files), search_and_replace (for finding and replacing individual pieces of text). +- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to files), search_and_replace (for finding and replacing individual pieces of text). - The insert_content tool adds lines of text to files at a specific line number, such as adding a new function to a JavaScript file or inserting a new route in a Python file. Use line number 0 to append at the end of the file, or any positive number to insert before that line. - The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once. - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files. @@ -554,13 +554,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. 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: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. 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 plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. 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. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**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.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap index 31b49ec682..9e08cccf36 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap @@ -489,7 +489,7 @@ RULES - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with `cd`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run `npm install` in a project outside of '/test/path', you would need to prepend with a `cd` i.e. pseudocode for this would be `cd (path to project) && (command, in this case npm install)`. - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes. - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser. -- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to existing files), search_and_replace (for finding and replacing individual pieces of text). +- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to files), search_and_replace (for finding and replacing individual pieces of text). - The insert_content tool adds lines of text to files at a specific line number, such as adding a new function to a JavaScript file or inserting a new route in a Python file. Use line number 0 to append at the end of the file, or any positive number to insert before that line. - The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once. - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files. @@ -549,13 +549,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. 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: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. 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 plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. 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. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**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.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap index fda93c1c77..83e0c424dd 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap @@ -544,7 +544,7 @@ RULES - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with `cd`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run `npm install` in a project outside of '/test/path', you would need to prepend with a `cd` i.e. pseudocode for this would be `cd (path to project) && (command, in this case npm install)`. - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes. - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser. -- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to existing files), search_and_replace (for finding and replacing individual pieces of text). +- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to files), search_and_replace (for finding and replacing individual pieces of text). - The insert_content tool adds lines of text to files at a specific line number, such as adding a new function to a JavaScript file or inserting a new route in a Python file. Use line number 0 to append at the end of the file, or any positive number to insert before that line. - The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once. - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files. @@ -605,13 +605,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. 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: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. 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 plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. 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. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**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.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap index 31b49ec682..9e08cccf36 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap @@ -489,7 +489,7 @@ RULES - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with `cd`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run `npm install` in a project outside of '/test/path', you would need to prepend with a `cd` i.e. pseudocode for this would be `cd (path to project) && (command, in this case npm install)`. - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes. - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser. -- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to existing files), search_and_replace (for finding and replacing individual pieces of text). +- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to files), search_and_replace (for finding and replacing individual pieces of text). - The insert_content tool adds lines of text to files at a specific line number, such as adding a new function to a JavaScript file or inserting a new route in a Python file. Use line number 0 to append at the end of the file, or any positive number to insert before that line. - The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once. - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files. @@ -549,13 +549,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. 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: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. 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 plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. 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. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**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.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap index 8db4d0b377..817447e176 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap @@ -577,7 +577,7 @@ RULES - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with `cd`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run `npm install` in a project outside of '/test/path', you would need to prepend with a `cd` i.e. pseudocode for this would be `cd (path to project) && (command, in this case npm install)`. - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using apply_diff or write_to_file to make informed changes. - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser. -- For editing files, you have access to these tools: apply_diff (for replacing lines in existing files), write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to existing files), search_and_replace (for finding and replacing individual pieces of text). +- For editing files, you have access to these tools: apply_diff (for replacing lines in existing files), write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to files), search_and_replace (for finding and replacing individual pieces of text). - The insert_content tool adds lines of text to files at a specific line number, such as adding a new function to a JavaScript file or inserting a new route in a Python file. Use line number 0 to append at the end of the file, or any positive number to insert before that line. - The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once. - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files. @@ -637,13 +637,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. 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: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. 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 plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. 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. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**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.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap index 31b49ec682..9e08cccf36 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap @@ -489,7 +489,7 @@ RULES - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with `cd`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run `npm install` in a project outside of '/test/path', you would need to prepend with a `cd` i.e. pseudocode for this would be `cd (path to project) && (command, in this case npm install)`. - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes. - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser. -- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to existing files), search_and_replace (for finding and replacing individual pieces of text). +- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to files), search_and_replace (for finding and replacing individual pieces of text). - The insert_content tool adds lines of text to files at a specific line number, such as adding a new function to a JavaScript file or inserting a new route in a Python file. Use line number 0 to append at the end of the file, or any positive number to insert before that line. - The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once. - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files. @@ -549,13 +549,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. 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: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. 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 plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. 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. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**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.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap index 44d5b58327..56426cf289 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap @@ -544,7 +544,7 @@ RULES - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with `cd`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run `npm install` in a project outside of '/test/path', you would need to prepend with a `cd` i.e. pseudocode for this would be `cd (path to project) && (command, in this case npm install)`. - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes. - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser. -- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to existing files), search_and_replace (for finding and replacing individual pieces of text). +- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to files), search_and_replace (for finding and replacing individual pieces of text). - The insert_content tool adds lines of text to files at a specific line number, such as adding a new function to a JavaScript file or inserting a new route in a Python file. Use line number 0 to append at the end of the file, or any positive number to insert before that line. - The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once. - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files. @@ -605,13 +605,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. 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: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. 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 plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. 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. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**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.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap index 0eecf0482e..b12f208b1a 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap @@ -557,7 +557,7 @@ RULES - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with `cd`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run `npm install` in a project outside of '/test/path', you would need to prepend with a `cd` i.e. pseudocode for this would be `cd (path to project) && (command, in this case npm install)`. - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes. - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser. -- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to existing files), search_and_replace (for finding and replacing individual pieces of text). +- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to files), search_and_replace (for finding and replacing individual pieces of text). - The insert_content tool adds lines of text to files at a specific line number, such as adding a new function to a JavaScript file or inserting a new route in a Python file. Use line number 0 to append at the end of the file, or any positive number to insert before that line. - The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once. - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files. @@ -617,13 +617,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. 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: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. 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 plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. 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. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**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.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap index 31b49ec682..9e08cccf36 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap @@ -489,7 +489,7 @@ RULES - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with `cd`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run `npm install` in a project outside of '/test/path', you would need to prepend with a `cd` i.e. pseudocode for this would be `cd (path to project) && (command, in this case npm install)`. - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes. - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser. -- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to existing files), search_and_replace (for finding and replacing individual pieces of text). +- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), insert_content (for adding lines to files), search_and_replace (for finding and replacing individual pieces of text). - The insert_content tool adds lines of text to files at a specific line number, such as adding a new function to a JavaScript file or inserting a new route in a Python file. Use line number 0 to append at the end of the file, or any positive number to insert before that line. - The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once. - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files. @@ -549,13 +549,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. 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: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. 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 plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. 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. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**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.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/get-prompt-component.spec.ts b/src/core/prompts/__tests__/get-prompt-component.spec.ts new file mode 100644 index 0000000000..7c4229b9c6 --- /dev/null +++ b/src/core/prompts/__tests__/get-prompt-component.spec.ts @@ -0,0 +1,88 @@ +import { describe, it, expect } from "vitest" +import { getPromptComponent } from "../system" +import type { CustomModePrompts } from "@roo-code/types" + +describe("getPromptComponent", () => { + it("should return undefined for empty objects", () => { + const customModePrompts: CustomModePrompts = { + architect: {}, + } + + const result = getPromptComponent(customModePrompts, "architect") + expect(result).toBeUndefined() + }) + + it("should return the component for objects with any properties", () => { + const customModePrompts: CustomModePrompts = { + architect: { + foo: "bar", + baz: 123, + } as any, + } + + const result = getPromptComponent(customModePrompts, "architect") + expect(result).toEqual({ foo: "bar", baz: 123 }) + }) + + it("should return undefined for missing mode", () => { + const customModePrompts: CustomModePrompts = {} + + const result = getPromptComponent(customModePrompts, "architect") + expect(result).toBeUndefined() + }) + + it("should return undefined when customModePrompts is undefined", () => { + const result = getPromptComponent(undefined, "architect") + expect(result).toBeUndefined() + }) + + it.each([ + ["roleDefinition", { roleDefinition: "Test role" }], + ["customInstructions", { customInstructions: "Test instructions" }], + ["whenToUse", { whenToUse: "Test when to use" }], + ["description", { description: "Test description" }], + ])("should return the component when it has %s", (property, component) => { + const customModePrompts: CustomModePrompts = { + architect: component, + } + + const result = getPromptComponent(customModePrompts, "architect") + expect(result).toEqual(component) + }) + + it("should return the component when it has multiple properties", () => { + const customModePrompts: CustomModePrompts = { + architect: { + roleDefinition: "Test role", + customInstructions: "Test instructions", + whenToUse: "Test when to use", + description: "Test description", + }, + } + + const result = getPromptComponent(customModePrompts, "architect") + expect(result).toEqual({ + roleDefinition: "Test role", + customInstructions: "Test instructions", + whenToUse: "Test when to use", + description: "Test description", + }) + }) + + it("should return the component when it has both relevant and irrelevant properties", () => { + const customModePrompts: CustomModePrompts = { + architect: { + roleDefinition: "Test role", + foo: "bar", + baz: 123, + } as any, + } + + const result = getPromptComponent(customModePrompts, "architect") + expect(result).toEqual({ + roleDefinition: "Test role", + foo: "bar", + baz: 123, + }) + }) +}) diff --git a/src/core/prompts/sections/__tests__/objective.spec.ts b/src/core/prompts/sections/__tests__/objective.spec.ts index 6c5517e5f4..e129392925 100644 --- a/src/core/prompts/sections/__tests__/objective.spec.ts +++ b/src/core/prompts/sections/__tests__/objective.spec.ts @@ -22,9 +22,10 @@ describe("getObjectiveSection", () => { // Check that the objective includes the codebase_search enforcement expect(objective).toContain( - "if the task involves understanding existing code or functionality, you MUST use the `codebase_search` tool", + "for ANY exploration of code you haven't examined yet in this conversation, you MUST use the `codebase_search` tool", ) expect(objective).toContain("BEFORE using any other search or file exploration tools") + expect(objective).toContain("This applies throughout the entire task, not just at the beginning") }) }) diff --git a/src/core/prompts/sections/__tests__/tool-use-guidelines.spec.ts b/src/core/prompts/sections/__tests__/tool-use-guidelines.spec.ts index f08bd475d8..98e4da3a73 100644 --- a/src/core/prompts/sections/__tests__/tool-use-guidelines.spec.ts +++ b/src/core/prompts/sections/__tests__/tool-use-guidelines.spec.ts @@ -22,11 +22,11 @@ describe("getToolUseGuidelinesSection", () => { // Check that the guidelines include the codebase_search enforcement expect(guidelines).toContain( - "IMPORTANT: When starting a new task or when you need to understand existing code/functionality, you MUST use the `codebase_search` tool FIRST", + "CRITICAL: For ANY exploration of code you haven't examined yet in this conversation, you MUST use the `codebase_search` tool FIRST", ) - expect(guidelines).toContain("before any other search tools") + expect(guidelines).toContain("before any other search or file exploration tools") expect(guidelines).toContain( - "semantic search tool helps you find relevant code based on meaning rather than just keywords", + "semantic search to find relevant code based on meaning rather than just keywords", ) }) @@ -35,7 +35,7 @@ describe("getToolUseGuidelinesSection", () => { // Check that all numbered items are present expect(guidelines).toContain("1. In tags") - expect(guidelines).toContain("2. **IMPORTANT:") + expect(guidelines).toContain("2. **CRITICAL:") expect(guidelines).toContain("3. Choose the most appropriate tool") expect(guidelines).toContain("4. If multiple actions are needed") expect(guidelines).toContain("5. Formulate your tool use") @@ -50,9 +50,9 @@ describe("getToolUseGuidelinesSection", () => { // Check that the guidelines do not include the codebase_search enforcement expect(guidelines).not.toContain( - "IMPORTANT: When starting a new task or when you need to understand existing code/functionality, you MUST use the `codebase_search` tool FIRST", + "CRITICAL: For ANY exploration of code you haven't examined yet in this conversation, you MUST use the `codebase_search` tool FIRST", ) - expect(guidelines).not.toContain("semantic search tool helps you find relevant code based on meaning") + expect(guidelines).not.toContain("semantic search to find relevant code based on meaning") }) it("should maintain proper numbering without codebase_search", () => { diff --git a/src/core/prompts/sections/objective.ts b/src/core/prompts/sections/objective.ts index 845db046a0..3d18a7e209 100644 --- a/src/core/prompts/sections/objective.ts +++ b/src/core/prompts/sections/objective.ts @@ -11,7 +11,7 @@ export function getObjectiveSection( codeIndexManager.isInitialized const codebaseSearchInstruction = isCodebaseSearchAvailable - ? "First, if the task involves understanding existing code or functionality, you MUST use the `codebase_search` tool to search for relevant code based on the task's intent BEFORE using any other search or file exploration tools. Then, " + ? "First, for ANY exploration of code you haven't examined yet in this conversation, you MUST use the `codebase_search` tool to search for relevant code based on the task's intent BEFORE using any other search or file exploration tools. This applies throughout the entire task, not just at the beginning - whenever you need to explore a new area of code, codebase_search must come first. Then, " : "First, " return `==== diff --git a/src/core/prompts/sections/rules.ts b/src/core/prompts/sections/rules.ts index 3b2e992085..5828568ac4 100644 --- a/src/core/prompts/sections/rules.ts +++ b/src/core/prompts/sections/rules.ts @@ -15,7 +15,7 @@ function getEditingInstructions(diffStrategy?: DiffStrategy): string { availableTools.push("write_to_file (for creating new files or complete file rewrites)") } - availableTools.push("insert_content (for adding lines to existing files)") + availableTools.push("insert_content (for adding lines to files)") availableTools.push("search_and_replace (for finding and replacing individual pieces of text)") // Base editing instruction mentioning all available tools @@ -58,7 +58,7 @@ export function getRulesSection( codeIndexManager.isInitialized const codebaseSearchRule = isCodebaseSearchAvailable - ? "- **CRITICAL: When you need to understand existing code or functionality, ALWAYS use the `codebase_search` tool FIRST before using search_files or other file exploration tools.** The codebase_search tool uses semantic search to find relevant code based on meaning, not just keywords, making it much more effective for understanding how features are implemented.\n" + ? "- **CRITICAL: For ANY exploration of code you haven't examined yet in this conversation, you MUST use the `codebase_search` tool FIRST before using search_files or other file exploration tools.** This requirement applies throughout the entire conversation, not just when starting a task. The codebase_search tool uses semantic search to find relevant code based on meaning, not just keywords, making it much more effective for understanding how features are implemented. Even if you've already explored some parts of the codebase, any new area or functionality you need to understand requires using codebase_search first.\n" : "" return `==== diff --git a/src/core/prompts/sections/tool-use-guidelines.ts b/src/core/prompts/sections/tool-use-guidelines.ts index 6f19b7e235..a526bbc711 100644 --- a/src/core/prompts/sections/tool-use-guidelines.ts +++ b/src/core/prompts/sections/tool-use-guidelines.ts @@ -19,10 +19,10 @@ export function getToolUseGuidelinesSection(codeIndexManager?: CodeIndexManager) // Conditional codebase search guideline if (isCodebaseSearchAvailable) { guidelinesList.push( - `${itemNumber++}. **IMPORTANT: When starting a new task or when you need to understand existing code/functionality, you MUST use the \`codebase_search\` tool FIRST before any other search tools.** This semantic search tool helps you find relevant code based on meaning rather than just keywords. Only after using codebase_search should you use other tools like search_files, list_files, or read_file for more specific exploration.`, + `${itemNumber++}. **CRITICAL: For ANY exploration of code you haven't examined yet in this conversation, you MUST use the \`codebase_search\` tool FIRST before any other search or file exploration tools.** This applies throughout the entire conversation, not just at the beginning. The codebase_search tool uses semantic search to find relevant code based on meaning rather than just keywords, making it far more effective than regex-based search_files for understanding implementations. Even if you've already explored some code, any new area of exploration requires codebase_search first.`, ) guidelinesList.push( - `${itemNumber++}. Choose the most appropriate tool based on the task and the tool descriptions provided. Assess if you need additional information to proceed, and which of the available tools would be most effective for gathering this information. For example using the list_files tool is more effective than running a command like \`ls\` in the terminal. It's critical that you think about each available tool and use the one that best fits the current step in the task.`, + `${itemNumber++}. Choose the most appropriate tool based on the task and the tool descriptions provided. After using codebase_search for initial exploration of any new code area, you may then use more specific tools like search_files (for regex patterns), list_files, or read_file for detailed examination. For example, using the list_files tool is more effective than running a command like \`ls\` in the terminal. It's critical that you think about each available tool and use the one that best fits the current step in the task.`, ) } else { guidelinesList.push( diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index be3b91f146..bfc12930a0 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -6,6 +6,7 @@ import type { ModeConfig, PromptComponent, CustomModePrompts, TodoItem } from "@ import { Mode, modes, defaultModeSlug, getModeBySlug, getGroupName, getModeSelection } from "../../shared/modes" import { DiffStrategy } from "../../shared/tools" import { formatLanguage } from "../../shared/language" +import { isEmpty } from "../../utils/object" import { McpHub } from "../../services/mcp/McpHub" import { CodeIndexManager } from "../../services/code-index/manager" @@ -26,6 +27,19 @@ import { markdownFormattingSection, } from "./sections" +// Helper function to get prompt component, filtering out empty objects +export function getPromptComponent( + customModePrompts: CustomModePrompts | undefined, + mode: string, +): PromptComponent | undefined { + const component = customModePrompts?.[mode] + // Return undefined if component is empty + if (isEmpty(component)) { + return undefined + } + return component +} + async function generatePrompt( context: vscode.ExtensionContext, cwd: string, @@ -129,13 +143,6 @@ export const SYSTEM_PROMPT = async ( throw new Error("Extension context is required for generating system prompt") } - const getPromptComponent = (value: unknown) => { - if (typeof value === "object" && value !== null) { - return value as PromptComponent - } - return undefined - } - // Try to load custom system prompt from file const variablesForPrompt: PromptVariables = { workspace: cwd, @@ -147,7 +154,7 @@ export const SYSTEM_PROMPT = async ( const fileCustomSystemPrompt = await loadSystemPromptFile(cwd, mode, variablesForPrompt) // Check if it's a custom mode - const promptComponent = getPromptComponent(customModePrompts?.[mode]) + const promptComponent = getPromptComponent(customModePrompts, mode) // Get full mode config from custom modes or fall back to built-in modes const currentMode = getModeBySlug(mode, customModes) || modes.find((m) => m.slug === mode) || modes[0] diff --git a/src/core/tools/__tests__/insertContentTool.spec.ts b/src/core/tools/__tests__/insertContentTool.spec.ts new file mode 100644 index 0000000000..c980ee17ec --- /dev/null +++ b/src/core/tools/__tests__/insertContentTool.spec.ts @@ -0,0 +1,225 @@ +import * as fs from "fs/promises" +import * as path from "path" +import type { MockedFunction } from "vitest" + +import { fileExistsAtPath } from "../../../utils/fs" +import { ToolUse, ToolResponse } from "../../../shared/tools" +import { insertContentTool } from "../insertContentTool" + +// Helper to normalize paths to POSIX format for cross-platform testing +const toPosix = (filePath: string) => filePath.replace(/\\/g, "/") + +// Mock external dependencies +vi.mock("fs/promises", () => ({ + readFile: vi.fn(), + writeFile: vi.fn(), +})) + +vi.mock("delay", () => ({ + default: vi.fn(), +})) + +vi.mock("../../../utils/fs", () => ({ + fileExistsAtPath: vi.fn().mockResolvedValue(false), +})) + +vi.mock("../../prompts/responses", () => ({ + formatResponse: { + toolError: vi.fn((msg) => `Error: ${msg}`), + rooIgnoreError: vi.fn((path) => `Access denied: ${path}`), + createPrettyPatch: vi.fn((_path, original, updated) => `Diff: ${original} -> ${updated}`), + }, +})) + +vi.mock("../../../utils/path", () => ({ + getReadablePath: vi.fn().mockReturnValue("test/path.txt"), +})) + +vi.mock("../../ignore/RooIgnoreController", () => ({ + RooIgnoreController: class { + initialize() { + return Promise.resolve() + } + validateAccess() { + return true + } + }, +})) + +describe("insertContentTool", () => { + const testFilePath = "test/file.txt" + // Use a consistent mock absolute path for testing + const absoluteFilePath = "/test/file.txt" + + const mockedFileExistsAtPath = fileExistsAtPath as MockedFunction + const mockedFsReadFile = fs.readFile as MockedFunction + + let mockCline: any + let mockAskApproval: ReturnType + let mockHandleError: ReturnType + let mockPushToolResult: ReturnType + let mockRemoveClosingTag: ReturnType + let toolResult: ToolResponse | undefined + + beforeEach(() => { + vi.clearAllMocks() + + mockedFileExistsAtPath.mockResolvedValue(true) // Assume file exists by default for insert + mockedFsReadFile.mockResolvedValue("") // Default empty file content + + mockCline = { + cwd: "/", + consecutiveMistakeCount: 0, + didEditFile: false, + rooIgnoreController: { + validateAccess: vi.fn().mockReturnValue(true), + }, + diffViewProvider: { + editType: undefined, + isEditing: false, + originalContent: "", + open: vi.fn().mockResolvedValue(undefined), + update: vi.fn().mockResolvedValue(undefined), + reset: vi.fn().mockResolvedValue(undefined), + revertChanges: vi.fn().mockResolvedValue(undefined), + saveChanges: vi.fn().mockResolvedValue({ + newProblemsMessage: "", + userEdits: null, + finalContent: "final content", + }), + scrollToFirstDiff: vi.fn(), + pushToolWriteResult: vi.fn().mockImplementation(async function ( + this: any, + task: any, + cwd: string, + isNewFile: boolean, + ) { + return "Tool result message" + }), + }, + fileContextTracker: { + trackFileContext: vi.fn().mockResolvedValue(undefined), + }, + say: vi.fn().mockResolvedValue(undefined), + ask: vi.fn().mockResolvedValue({ response: "yesButtonClicked" }), // Default to approval + recordToolError: vi.fn(), + sayAndCreateMissingParamError: vi.fn().mockResolvedValue("Missing param error"), + } + + mockAskApproval = vi.fn().mockResolvedValue(true) + mockHandleError = vi.fn().mockResolvedValue(undefined) + mockRemoveClosingTag = vi.fn((tag, content) => content) + + toolResult = undefined + }) + + async function executeInsertContentTool( + params: Partial = {}, + options: { + fileExists?: boolean + isPartial?: boolean + accessAllowed?: boolean + fileContent?: string + askApprovalResponse?: "yesButtonClicked" | "noButtonClicked" | string + } = {}, + ): Promise { + const fileExists = options.fileExists ?? true + const isPartial = options.isPartial ?? false + const accessAllowed = options.accessAllowed ?? true + const fileContent = options.fileContent ?? "" + + mockedFileExistsAtPath.mockResolvedValue(fileExists) + mockedFsReadFile.mockResolvedValue(fileContent) + mockCline.rooIgnoreController.validateAccess.mockReturnValue(accessAllowed) + mockCline.ask.mockResolvedValue({ response: options.askApprovalResponse ?? "yesButtonClicked" }) + + const toolUse: ToolUse = { + type: "tool_use", + name: "insert_content", + params: { + path: testFilePath, + line: "1", + content: "New content", + ...params, + }, + partial: isPartial, + } + + await insertContentTool( + mockCline, + toolUse, + mockAskApproval, + mockHandleError, + (result: ToolResponse) => { + toolResult = result + }, + mockRemoveClosingTag, + ) + + return toolResult + } + + describe("new file creation logic", () => { + it("creates a new file and inserts content at line 0 (append)", async () => { + const contentToInsert = "New Line 1\nNew Line 2" + await executeInsertContentTool( + { line: "0", content: contentToInsert }, + { fileExists: false, fileContent: "" }, + ) + + // Normalize the path that was called with to POSIX format for comparison + const calledPath = mockedFileExistsAtPath.mock.calls[0][0] + expect(toPosix(calledPath)).toContain(testFilePath) + expect(mockedFsReadFile).not.toHaveBeenCalled() // Should not read if file doesn't exist + expect(mockCline.diffViewProvider.update).toHaveBeenCalledWith(contentToInsert, true) + expect(mockCline.diffViewProvider.editType).toBe("create") + expect(mockCline.diffViewProvider.pushToolWriteResult).toHaveBeenCalledWith(mockCline, mockCline.cwd, true) + }) + + it("creates a new file and inserts content at line 1 (beginning)", async () => { + const contentToInsert = "Hello World!" + await executeInsertContentTool( + { line: "1", content: contentToInsert }, + { fileExists: false, fileContent: "" }, + ) + + // Normalize the path that was called with to POSIX format for comparison + const calledPath = mockedFileExistsAtPath.mock.calls[0][0] + expect(toPosix(calledPath)).toContain(testFilePath) + expect(mockedFsReadFile).not.toHaveBeenCalled() + expect(mockCline.diffViewProvider.update).toHaveBeenCalledWith(contentToInsert, true) + expect(mockCline.diffViewProvider.editType).toBe("create") + expect(mockCline.diffViewProvider.pushToolWriteResult).toHaveBeenCalledWith(mockCline, mockCline.cwd, true) + }) + + it("creates an empty new file if content is empty string", async () => { + await executeInsertContentTool({ line: "1", content: "" }, { fileExists: false, fileContent: "" }) + + // Normalize the path that was called with to POSIX format for comparison + const calledPath = mockedFileExistsAtPath.mock.calls[0][0] + expect(toPosix(calledPath)).toContain(testFilePath) + expect(mockedFsReadFile).not.toHaveBeenCalled() + expect(mockCline.diffViewProvider.update).toHaveBeenCalledWith("", true) + expect(mockCline.diffViewProvider.editType).toBe("create") + expect(mockCline.diffViewProvider.pushToolWriteResult).toHaveBeenCalledWith(mockCline, mockCline.cwd, true) + }) + + it("returns an error when inserting content at an arbitrary line number into a new file", async () => { + const contentToInsert = "Arbitrary insert" + const result = await executeInsertContentTool( + { line: "5", content: contentToInsert }, + { fileExists: false, fileContent: "" }, + ) + + // Normalize the path that was called with to POSIX format for comparison + const calledPath = mockedFileExistsAtPath.mock.calls[0][0] + expect(toPosix(calledPath)).toContain(testFilePath) + expect(mockedFsReadFile).not.toHaveBeenCalled() + expect(mockCline.consecutiveMistakeCount).toBe(1) + expect(mockCline.recordToolError).toHaveBeenCalledWith("insert_content") + expect(mockCline.say).toHaveBeenCalledWith("error", expect.stringContaining("non-existent file")) + expect(mockCline.diffViewProvider.update).not.toHaveBeenCalled() + expect(mockCline.diffViewProvider.pushToolWriteResult).not.toHaveBeenCalled() + }) + }) +}) diff --git a/src/core/tools/insertContentTool.ts b/src/core/tools/insertContentTool.ts index af8d91713f..b76769fcf0 100644 --- a/src/core/tools/insertContentTool.ts +++ b/src/core/tools/insertContentTool.ts @@ -51,7 +51,7 @@ export async function insertContentTool( return } - if (!content) { + if (content === undefined) { cline.consecutiveMistakeCount++ cline.recordToolError("insert_content") pushToolResult(await cline.sayAndCreateMissingParamError("insert_content", "content")) @@ -70,17 +70,6 @@ export async function insertContentTool( const isWriteProtected = cline.rooProtectedController?.isWriteProtected(relPath) || false const absolutePath = path.resolve(cline.cwd, relPath) - const fileExists = await fileExistsAtPath(absolutePath) - - if (!fileExists) { - cline.consecutiveMistakeCount++ - cline.recordToolError("insert_content") - const formattedError = `File does not exist at path: ${absolutePath}\n\n\nThe specified file could not be found. Please verify the file path and try again.\n` - await cline.say("error", formattedError) - pushToolResult(formattedError) - return - } - const lineNumber = parseInt(line, 10) if (isNaN(lineNumber) || lineNumber < 0) { cline.consecutiveMistakeCount++ @@ -89,13 +78,26 @@ export async function insertContentTool( return } + const fileExists = await fileExistsAtPath(absolutePath) + let fileContent: string = "" + if (!fileExists) { + if (lineNumber > 1) { + cline.consecutiveMistakeCount++ + cline.recordToolError("insert_content") + const formattedError = `Cannot insert content at line ${lineNumber} into a non-existent file. For new files, 'line' must be 0 (to append) or 1 (to insert at the beginning).` + await cline.say("error", formattedError) + pushToolResult(formattedError) + return + } + } else { + fileContent = await fs.readFile(absolutePath, "utf8") + } + cline.consecutiveMistakeCount = 0 - // Read the file - const fileContent = await fs.readFile(absolutePath, "utf8") - cline.diffViewProvider.editType = "modify" + cline.diffViewProvider.editType = fileExists ? "modify" : "create" cline.diffViewProvider.originalContent = fileContent - const lines = fileContent.split("\n") + const lines = fileExists ? fileContent.split("\n") : [] const updatedContent = insertGroups(lines, [ { @@ -114,11 +116,22 @@ export async function insertContentTool( await delay(200) } - const diff = formatResponse.createPrettyPatch(relPath, fileContent, updatedContent) + // For consistency with writeToFileTool, handle new files differently + let diff: string | undefined + let approvalContent: string | undefined - if (!diff) { - pushToolResult(`No changes needed for '${relPath}'`) - return + if (fileExists) { + // For existing files, generate diff and check for changes + diff = formatResponse.createPrettyPatch(relPath, fileContent, updatedContent) + if (!diff) { + pushToolResult(`No changes needed for '${relPath}'`) + return + } + approvalContent = undefined + } else { + // For new files, skip diff generation and provide full content + diff = undefined + approvalContent = updatedContent } await cline.diffViewProvider.update(updatedContent, true) @@ -126,6 +139,7 @@ export async function insertContentTool( const completeMessage = JSON.stringify({ ...sharedMessageProps, diff, + content: approvalContent, lineNumber: lineNumber, isProtected: isWriteProtected, } satisfies ClineSayTool) @@ -151,11 +165,7 @@ export async function insertContentTool( cline.didEditFile = true // Get the formatted response message - const message = await cline.diffViewProvider.pushToolWriteResult( - cline, - cline.cwd, - false, // Always false for insert_content - ) + const message = await cline.diffViewProvider.pushToolWriteResult(cline, cline.cwd, !fileExists) pushToolResult(message) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 8eb2e70a8c..4a934e9fa0 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -110,7 +110,7 @@ export class ClineProvider public isViewLaunched = false public settingsImportedAt?: number - public readonly latestAnnouncementId = "jul-02-2025-3-22-6" // Update for v3.22.6 announcement + public readonly latestAnnouncementId = "jul-09-2025-3-23-0" // Update for v3.23.0 announcement public readonly providerSettingsManager: ProviderSettingsManager public readonly customModesManager: CustomModesManager @@ -1510,7 +1510,7 @@ export class ClineProvider customCondensingPrompt, codebaseIndexModels: codebaseIndexModels ?? EMBEDDING_MODEL_PROFILES, codebaseIndexConfig: codebaseIndexConfig ?? { - codebaseIndexEnabled: false, + codebaseIndexEnabled: true, codebaseIndexQdrantUrl: "http://localhost:6333", codebaseIndexEmbedderProvider: "openai", codebaseIndexEmbedderBaseUrl: "", @@ -1668,7 +1668,7 @@ export class ClineProvider customCondensingPrompt: stateValues.customCondensingPrompt, codebaseIndexModels: stateValues.codebaseIndexModels ?? EMBEDDING_MODEL_PROFILES, codebaseIndexConfig: stateValues.codebaseIndexConfig ?? { - codebaseIndexEnabled: false, + codebaseIndexEnabled: true, codebaseIndexQdrantUrl: "http://localhost:6333", codebaseIndexEmbedderProvider: "openai", codebaseIndexEmbedderBaseUrl: "", diff --git a/src/core/webview/__tests__/ClineProvider.spec.ts b/src/core/webview/__tests__/ClineProvider.spec.ts index 0b128aeaec..19c9a7c9fc 100644 --- a/src/core/webview/__tests__/ClineProvider.spec.ts +++ b/src/core/webview/__tests__/ClineProvider.spec.ts @@ -145,6 +145,7 @@ vi.mock("vscode", () => ({ }, window: { showInformationMessage: vi.fn(), + showWarningMessage: vi.fn(), showErrorMessage: vi.fn(), }, workspace: { @@ -500,7 +501,7 @@ describe("ClineProvider", () => { alwaysAllowReadOnlyOutsideWorkspace: false, alwaysAllowWrite: false, codebaseIndexConfig: { - codebaseIndexEnabled: false, + codebaseIndexEnabled: true, codebaseIndexQdrantUrl: "", codebaseIndexEmbedderProvider: "openai", codebaseIndexEmbedderBaseUrl: "", @@ -1289,14 +1290,14 @@ describe("ClineProvider", () => { describe("editMessage", () => { beforeEach(async () => { - // Mock window.showInformationMessage - ;(vscode.window.showInformationMessage as any) = vi.fn() + // Mock window.showWarningMessage + ;(vscode.window.showWarningMessage as any) = vi.fn() await provider.resolveWebviewView(mockWebviewView) }) - test('handles "No, just edit this one" edit correctly', async () => { - // Mock user selecting "No, just edit this one" - ;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.edit_just_this_message") + test('handles "Proceed" edit correctly', async () => { + // Mock user selecting "Proceed" - need to use the localized string key + ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed") // Setup mock messages const mockMessages = [ @@ -1345,20 +1346,13 @@ describe("ClineProvider", () => { editedMessageContent: "Edited message content", }) - // Verify correct messages were kept - expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([ - mockMessages[0], - mockMessages[1], - mockMessages[4], - mockMessages[5], - ]) + // Verify correct messages were kept (only messages before the edited one) + expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([mockMessages[0], mockMessages[1]]) - // Verify correct API messages were kept + // Verify correct API messages were kept (only messages before the edited one) expect(mockCline.overwriteApiConversationHistory).toHaveBeenCalledWith([ mockApiHistory[0], mockApiHistory[1], - mockApiHistory[4], - mockApiHistory[5], ]) // Verify handleWebviewAskResponse was called with the edited content @@ -1368,103 +1362,6 @@ describe("ClineProvider", () => { undefined, ) }) - - test('handles "Yes" (edit and delete subsequent) correctly', async () => { - // Mock user selecting "Yes" - ;(vscode.window.showInformationMessage as any).mockResolvedValue( - "confirmation.edit_this_and_delete_subsequent", - ) - - // Setup mock messages - const mockMessages = [ - { ts: 1000, type: "say", say: "user_feedback" }, - { ts: 2000, type: "say", say: "text", value: 3000 }, // Message to edit - { ts: 3000, type: "say", say: "user_feedback" }, - { ts: 4000, type: "say", say: "user_feedback" }, - ] as ClineMessage[] - - const mockApiHistory = [ - { ts: 1000 }, - { ts: 2000 }, - { ts: 3000 }, - { ts: 4000 }, - ] as (Anthropic.MessageParam & { - ts?: number - })[] - - // Setup Cline instance with auto-mock from the top of the file - const mockCline = new Task(defaultTaskOptions) // Create a new mocked instance - mockCline.clineMessages = mockMessages - mockCline.apiConversationHistory = mockApiHistory - - // Explicitly mock the overwrite methods since they're not being called in the tests - mockCline.overwriteClineMessages = vi.fn() - mockCline.overwriteApiConversationHistory = vi.fn() - mockCline.handleWebviewAskResponse = vi.fn() - - await provider.addClineToStack(mockCline) - - // Mock getTaskWithId - ;(provider as any).getTaskWithId = vi.fn().mockResolvedValue({ - historyItem: { id: "test-task-id" }, - }) - - // Trigger message edit - // Get the message handler function that was registered with the webview - const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as any).mock.calls[0][0] - - // Call the message handler with a submitEditedMessage message - await messageHandler({ - type: "submitEditedMessage", - value: 3000, - editedMessageContent: "Edited message content", - }) - - // Verify only messages before the edited message were kept - expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([mockMessages[0]]) - - // Verify only API messages before the edited message were kept - expect(mockCline.overwriteApiConversationHistory).toHaveBeenCalledWith([mockApiHistory[0]]) - - // Verify handleWebviewAskResponse was called with the edited content - expect(mockCline.handleWebviewAskResponse).toHaveBeenCalledWith( - "messageResponse", - "Edited message content", - undefined, - ) - }) - - test("handles Cancel correctly", async () => { - // Mock user selecting "Cancel" - ;(vscode.window.showInformationMessage as any).mockResolvedValue("Cancel") - - // Setup Cline instance with auto-mock from the top of the file - const mockCline = new Task(defaultTaskOptions) // Create a new mocked instance - mockCline.clineMessages = [{ ts: 1000 }, { ts: 2000 }] as ClineMessage[] - mockCline.apiConversationHistory = [{ ts: 1000 }, { ts: 2000 }] as (Anthropic.MessageParam & { - ts?: number - })[] - - // Explicitly mock the overwrite methods since they're not being called in the tests - mockCline.overwriteClineMessages = vi.fn() - mockCline.overwriteApiConversationHistory = vi.fn() - mockCline.handleWebviewAskResponse = vi.fn() - - await provider.addClineToStack(mockCline) - - // Trigger message edit - const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as any).mock.calls[0][0] - await messageHandler({ - type: "submitEditedMessage", - value: 2000, - editedMessageContent: "Edited message content", - }) - - // Verify no messages were edited or deleted - expect(mockCline.overwriteClineMessages).not.toHaveBeenCalled() - expect(mockCline.overwriteApiConversationHistory).not.toHaveBeenCalled() - expect(mockCline.handleWebviewAskResponse).not.toHaveBeenCalled() - }) }) describe("getSystemPrompt", () => { @@ -2813,7 +2710,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => { }) test("handles editing messages containing images", async () => { - ;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.edit_just_this_message") + ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed") const mockMessages = [ { ts: 1000, type: "say", say: "user_feedback", text: "Original message" }, @@ -2858,7 +2755,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => { }) test("handles editing messages with file attachments", async () => { - ;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.edit_just_this_message") + ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed") const mockMessages = [ { ts: 1000, type: "say", say: "user_feedback", text: "Original message" }, @@ -2908,7 +2805,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => { }) test("handles network timeout during edit submission", async () => { - ;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.edit_just_this_message") + ;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.proceed") const mockCline = new Task(defaultTaskOptions) mockCline.clineMessages = [ @@ -2940,7 +2837,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => { }) test("handles connection drops during edit operation", async () => { - ;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.edit_just_this_message") + ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed") const mockCline = new Task(defaultTaskOptions) mockCline.clineMessages = [ @@ -2979,7 +2876,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => { }) test("handles race conditions with simultaneous edits", async () => { - ;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.edit_just_this_message") + ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed") const mockCline = new Task(defaultTaskOptions) mockCline.clineMessages = [ @@ -3043,7 +2940,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => { }) test("handles authorization failures during edit", async () => { - ;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.edit_just_this_message") + ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed") const mockCline = new Task(defaultTaskOptions) mockCline.clineMessages = [ @@ -3161,7 +3058,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => { }) test("handles edit operations on deleted messages", async () => { - ;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.edit_just_this_message") + ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed") const mockCline = new Task(defaultTaskOptions) mockCline.clineMessages = [ @@ -3187,7 +3084,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => { }) // Should show confirmation dialog but not perform any operations - expect(vscode.window.showInformationMessage).toHaveBeenCalled() + expect(vscode.window.showWarningMessage).toHaveBeenCalled() expect(mockCline.overwriteClineMessages).not.toHaveBeenCalled() expect(mockCline.handleWebviewAskResponse).not.toHaveBeenCalled() }) @@ -3231,7 +3128,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => { }) test("validates proper cleanup during failed edit operations", async () => { - ;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.edit_just_this_message") + ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed") const mockCline = new Task(defaultTaskOptions) mockCline.clineMessages = [ @@ -3311,7 +3208,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => { }) test("handles editing messages with large text content", async () => { - ;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.edit_just_this_message") + ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed") // Create a large message (10KB of text) const largeText = "A".repeat(10000) @@ -3419,7 +3316,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => { test("handles user cancellation gracefully", async () => { // Mock user canceling the operation - ;(vscode.window.showInformationMessage as any).mockResolvedValue(undefined) + ;(vscode.window.showWarningMessage as any).mockResolvedValue(undefined) const mockCline = new Task(defaultTaskOptions) mockCline.clineMessages = [ @@ -3485,7 +3382,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => { }) test("handles messages with future timestamps", async () => { - ;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.edit_just_this_message") + ;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed") const futureTimestamp = Date.now() + 100000 // Future timestamp const mockCline = new Task(defaultTaskOptions) diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index 219e52974e..a6577fb2fb 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -193,32 +193,23 @@ export const webviewMessageHandler = async ( * Handles message editing operations with user confirmation */ const handleEditOperation = async (messageTs: number, editedContent: string): Promise => { - const options = [ - t("common:confirmation.edit_this_and_delete_subsequent"), - t("common:confirmation.edit_just_this_message"), - ] - - const answer = await vscode.window.showInformationMessage( - t("common:confirmation.edit_message"), + const answer = await vscode.window.showWarningMessage( + t("common:confirmation.edit_warning"), { modal: true }, - ...options, + t("common:confirmation.proceed"), ) - // Only proceed if user selected one of the options and we have a current cline - if (answer && options.includes(answer) && provider.getCurrentCline()) { + // Only proceed if user selected "Proceed" and we have a current cline + if (answer === t("common:confirmation.proceed") && provider.getCurrentCline()) { const currentCline = provider.getCurrentCline()! + + // Use findMessageIndices to find messages based on timestamp const { messageIndex, apiConversationHistoryIndex } = findMessageIndices(messageTs, currentCline) if (messageIndex !== -1) { try { - // Check which option the user selected - if (answer === options[0]) { - // Edit this message and delete subsequent - await removeMessagesThisAndSubsequent(currentCline, messageIndex, apiConversationHistoryIndex) - } else if (answer === options[1]) { - // Edit just this message - await removeMessagesJustThis(currentCline, messageIndex, apiConversationHistoryIndex) - } + // Edit this message and delete subsequent + await removeMessagesThisAndSubsequent(currentCline, messageIndex, apiConversationHistoryIndex) // Process the edited message as a regular user message // This will add it to the conversation and trigger an AI response @@ -1230,21 +1221,6 @@ export const webviewMessageHandler = async ( break case "browserToolEnabled": await updateGlobalState("browserToolEnabled", message.bool ?? true) - await provider.postStateToWebview() - break - case "codebaseIndexEnabled": - // Update the codebaseIndexConfig with the new enabled state - const currentCodebaseConfig = getGlobalState("codebaseIndexConfig") || {} - await updateGlobalState("codebaseIndexConfig", { - ...currentCodebaseConfig, - codebaseIndexEnabled: message.bool ?? false, - }) - - // Notify the code index manager about the change - if (provider.codeIndexManager) { - await provider.codeIndexManager.handleSettingsChange() - } - await provider.postStateToWebview() break case "language": @@ -1967,8 +1943,8 @@ export const webviewMessageHandler = async ( codebaseIndexEmbedderProvider: settings.codebaseIndexEmbedderProvider, codebaseIndexEmbedderBaseUrl: settings.codebaseIndexEmbedderBaseUrl, codebaseIndexEmbedderModelId: settings.codebaseIndexEmbedderModelId, + codebaseIndexEmbedderModelDimension: settings.codebaseIndexEmbedderModelDimension, // Generic dimension codebaseIndexOpenAiCompatibleBaseUrl: settings.codebaseIndexOpenAiCompatibleBaseUrl, - codebaseIndexOpenAiCompatibleModelDimension: settings.codebaseIndexOpenAiCompatibleModelDimension, codebaseIndexSearchMaxResults: settings.codebaseIndexSearchMaxResults, codebaseIndexSearchMinScore: settings.codebaseIndexSearchMinScore, } diff --git a/src/i18n/locales/ca/common.json b/src/i18n/locales/ca/common.json index c3b5406e92..04938e3625 100644 --- a/src/i18n/locales/ca/common.json +++ b/src/i18n/locales/ca/common.json @@ -23,11 +23,10 @@ "delete_config_profile": "Estàs segur que vols eliminar aquest perfil de configuració?", "delete_custom_mode_with_rules": "Esteu segur que voleu suprimir aquest mode {scope}?\n\nAixò també suprimirà la carpeta de regles associada a:\n{rulesFolderPath}", "delete_message": "Què vols eliminar?", - "edit_message": "Eliminar tots els missatges després d'aquest?", + "edit_warning": "Editar aquest missatge eliminarà tots els missatges posteriors de la conversa. Vols continuar?", "delete_just_this_message": "Només aquest missatge", - "edit_just_this_message": "No, només editar aquest", "delete_this_and_subsequent": "Aquest i tots els missatges posteriors", - "edit_this_and_delete_subsequent": "Sí" + "proceed": "Continuar" }, "errors": { "invalid_data_uri": "Format d'URI de dades no vàlid", @@ -111,13 +110,11 @@ "answers": { "yes": "Sí", "no": "No", - "cancel": "Cancel·lar", "remove": "Eliminar", "keep": "Mantenir" }, "buttons": { "save": "Desar", - "cancel": "Cancel·lar", "edit": "Editar" }, "tasks": { @@ -171,7 +168,6 @@ "title": "Suprimeix el mode personalitzat", "description": "Esteu segur que voleu suprimir aquest mode {{scope}}? Això també suprimirà la carpeta de regles associada a: {{rulesFolderPath}}", "descriptionNoRules": "Esteu segur que voleu suprimir aquest mode personalitzat?", - "cancel": "Cancel·la", "confirm": "Suprimeix" } } diff --git a/src/i18n/locales/ca/embeddings.json b/src/i18n/locales/ca/embeddings.json index 35be4089d4..1d3c5f2476 100644 --- a/src/i18n/locales/ca/embeddings.json +++ b/src/i18n/locales/ca/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "URL base no vàlida. Comproveu la vostra configuració d'URL.", "invalidModel": "Model no vàlid. Comproveu la vostra configuració de model.", "invalidResponse": "Resposta no vàlida del servei d'incrustació. Comproveu la vostra configuració." + }, + "serviceFactory": { + "openAiConfigMissing": "Falta la configuració d'OpenAI per crear l'embedder", + "ollamaConfigMissing": "Falta la configuració d'Ollama per crear l'embedder", + "openAiCompatibleConfigMissing": "Falta la configuració compatible amb OpenAI per crear l'embedder", + "geminiConfigMissing": "Falta la configuració de Gemini per crear l'embedder", + "invalidEmbedderType": "Tipus d'embedder configurat no vàlid: {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "No s'ha pogut determinar la dimensió del vector per al model '{{modelId}}' amb el proveïdor '{{provider}}'. Assegura't que la 'Dimensió d'incrustació' estigui configurada correctament als paràmetres del proveïdor compatible amb OpenAI.", + "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" } } diff --git a/src/i18n/locales/de/common.json b/src/i18n/locales/de/common.json index afcb496c64..9fa27c89c6 100644 --- a/src/i18n/locales/de/common.json +++ b/src/i18n/locales/de/common.json @@ -19,11 +19,10 @@ "delete_config_profile": "Möchtest du dieses Konfigurationsprofil wirklich löschen?", "delete_custom_mode_with_rules": "Bist du sicher, dass du diesen {scope}-Modus löschen möchtest?\n\nDadurch wird auch der zugehörige Regelordner unter folgender Adresse gelöscht:\n{rulesFolderPath}", "delete_message": "Was möchtest du löschen?", - "edit_message": "Alle Nachrichten nach dieser löschen?", + "edit_warning": "Das Bearbeiten dieser Nachricht wird alle nachfolgenden Nachrichten in der Unterhaltung löschen. Möchtest du fortfahren?", "delete_just_this_message": "Nur diese Nachricht", - "edit_just_this_message": "Nein, nur diese bearbeiten", "delete_this_and_subsequent": "Diese und alle nachfolgenden Nachrichten", - "edit_this_and_delete_subsequent": "Ja" + "proceed": "Fortfahren" }, "errors": { "invalid_data_uri": "Ungültiges Daten-URI-Format", @@ -107,13 +106,11 @@ "answers": { "yes": "Ja", "no": "Nein", - "cancel": "Abbrechen", "remove": "Entfernen", "keep": "Behalten" }, "buttons": { "save": "Speichern", - "cancel": "Abbrechen", "edit": "Bearbeiten" }, "tasks": { @@ -171,7 +168,6 @@ "title": "Benutzerdefinierten Modus löschen", "description": "Bist du sicher, dass du diesen {{scope}}-Modus löschen möchtest? Dadurch wird auch der zugehörige Regelordner unter {{rulesFolderPath}} gelöscht", "descriptionNoRules": "Bist du sicher, dass du diesen benutzerdefinierten Modus löschen möchtest?", - "cancel": "Abbrechen", "confirm": "Löschen" } } diff --git a/src/i18n/locales/de/embeddings.json b/src/i18n/locales/de/embeddings.json index 7d96ddb511..f4abcb3e15 100644 --- a/src/i18n/locales/de/embeddings.json +++ b/src/i18n/locales/de/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "Ungültige Basis-URL. Bitte überprüfe deine URL-Konfiguration.", "invalidModel": "Ungültiges Modell. Bitte überprüfe deine Modellkonfiguration.", "invalidResponse": "Ungültige Antwort vom Embedder-Dienst. Bitte überprüfe deine Konfiguration." + }, + "serviceFactory": { + "openAiConfigMissing": "OpenAI-Konfiguration fehlt für die Erstellung des Embedders", + "ollamaConfigMissing": "Ollama-Konfiguration fehlt für die Erstellung des Embedders", + "openAiCompatibleConfigMissing": "OpenAI-kompatible Konfiguration fehlt für die Erstellung des Embedders", + "geminiConfigMissing": "Gemini-Konfiguration fehlt für die Erstellung des Embedders", + "invalidEmbedderType": "Ungültiger Embedder-Typ konfiguriert: {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "Konnte die Vektordimension für Modell '{{modelId}}' mit Anbieter '{{provider}}' nicht bestimmen. Stelle sicher, dass die 'Embedding-Dimension' in den OpenAI-kompatiblen Anbietereinstellungen korrekt eingestellt ist.", + "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" } } diff --git a/src/i18n/locales/en/common.json b/src/i18n/locales/en/common.json index 9d23152e29..f907a5745b 100644 --- a/src/i18n/locales/en/common.json +++ b/src/i18n/locales/en/common.json @@ -19,11 +19,10 @@ "delete_config_profile": "Are you sure you want to delete this configuration profile?", "delete_custom_mode_with_rules": "Are you sure you want to delete this {scope} mode?\n\nThis will also delete the associated rules folder at:\n{rulesFolderPath}", "delete_message": "What would you like to delete?", - "edit_message": "Delete all messages after this one?", + "edit_warning": "Editing this message will delete all subsequent messages in the conversation. Do you want to proceed?", "delete_just_this_message": "Just this message", - "edit_just_this_message": "No, just edit this one", "delete_this_and_subsequent": "This and all subsequent messages", - "edit_this_and_delete_subsequent": "Yes" + "proceed": "Proceed" }, "errors": { "invalid_data_uri": "Invalid data URI format", @@ -107,13 +106,11 @@ "answers": { "yes": "Yes", "no": "No", - "cancel": "Cancel", "remove": "Remove", "keep": "Keep" }, "buttons": { "save": "Save", - "cancel": "Cancel", "edit": "Edit" }, "tasks": { @@ -160,7 +157,6 @@ "title": "Delete Custom Mode", "description": "Are you sure you want to delete this {{scope}} mode? This will also delete the associated rules folder at: {{rulesFolderPath}}", "descriptionNoRules": "Are you sure you want to delete this custom mode?", - "cancel": "Cancel", "confirm": "Delete" } } diff --git a/src/i18n/locales/en/embeddings.json b/src/i18n/locales/en/embeddings.json index 012b2323cf..b2ed2a64c4 100644 --- a/src/i18n/locales/en/embeddings.json +++ b/src/i18n/locales/en/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "Invalid base URL. Please check your URL configuration.", "invalidModel": "Invalid model. Please check your model configuration.", "invalidResponse": "Invalid response from embedder service. Please check your configuration." + }, + "serviceFactory": { + "openAiConfigMissing": "OpenAI configuration missing for embedder creation", + "ollamaConfigMissing": "Ollama configuration missing for embedder creation", + "openAiCompatibleConfigMissing": "OpenAI Compatible configuration missing for embedder creation", + "geminiConfigMissing": "Gemini configuration missing for embedder creation", + "invalidEmbedderType": "Invalid embedder type configured: {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "Could not determine vector dimension for model '{{modelId}}' with provider '{{provider}}'. Please ensure the 'Embedding Dimension' is correctly set in the OpenAI-Compatible provider settings.", + "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" } } diff --git a/src/i18n/locales/es/common.json b/src/i18n/locales/es/common.json index d2181113a8..68750e888f 100644 --- a/src/i18n/locales/es/common.json +++ b/src/i18n/locales/es/common.json @@ -19,11 +19,10 @@ "delete_config_profile": "¿Estás seguro de que deseas eliminar este perfil de configuración?", "delete_custom_mode_with_rules": "¿Estás seguro de que quieres eliminar este modo {scope}?\n\nEsto también eliminará la carpeta de reglas asociada en:\n{rulesFolderPath}", "delete_message": "¿Qué deseas eliminar?", - "edit_message": "¿Eliminar todos los mensajes posteriores a este?", + "edit_warning": "Editar este mensaje eliminará todos los mensajes posteriores en la conversación. ¿Deseas continuar?", "delete_just_this_message": "Solo este mensaje", - "edit_just_this_message": "No, solo editar este", "delete_this_and_subsequent": "Este y todos los mensajes posteriores", - "edit_this_and_delete_subsequent": "Sí" + "proceed": "Continuar" }, "errors": { "invalid_data_uri": "Formato de URI de datos no válido", @@ -107,13 +106,11 @@ "answers": { "yes": "Sí", "no": "No", - "cancel": "Cancelar", "remove": "Eliminar", "keep": "Mantener" }, "buttons": { "save": "Guardar", - "cancel": "Cancelar", "edit": "Editar" }, "tasks": { @@ -171,7 +168,6 @@ "title": "Eliminar modo personalizado", "description": "¿Estás seguro de que quieres eliminar este modo {{scope}}? Esto también eliminará la carpeta de reglas asociada en: {{rulesFolderPath}}", "descriptionNoRules": "¿Estás seguro de que quieres eliminar este modo personalizado?", - "cancel": "Cancelar", "confirm": "Eliminar" } } diff --git a/src/i18n/locales/es/embeddings.json b/src/i18n/locales/es/embeddings.json index 5fa46f9c45..8cb0dd7f1f 100644 --- a/src/i18n/locales/es/embeddings.json +++ b/src/i18n/locales/es/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "URL base no válida. Comprueba la configuración de tu URL.", "invalidModel": "Modelo no válido. Comprueba la configuración de tu modelo.", "invalidResponse": "Respuesta no válida del servicio de embedder. Comprueba tu configuración." + }, + "serviceFactory": { + "openAiConfigMissing": "Falta la configuración de OpenAI para crear el incrustador", + "ollamaConfigMissing": "Falta la configuración de Ollama para crear el incrustador", + "openAiCompatibleConfigMissing": "Falta la configuración compatible con OpenAI para crear el incrustador", + "geminiConfigMissing": "Falta la configuración de Gemini para crear el incrustador", + "invalidEmbedderType": "Tipo de incrustador configurado inválido: {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "No se pudo determinar la dimensión del vector para el modelo '{{modelId}}' con el proveedor '{{provider}}'. Asegúrate de que la 'Dimensión de incrustación' esté configurada correctamente en los ajustes del proveedor compatible con OpenAI.", + "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" } } diff --git a/src/i18n/locales/fr/common.json b/src/i18n/locales/fr/common.json index 72e0ff41ae..e985fe9468 100644 --- a/src/i18n/locales/fr/common.json +++ b/src/i18n/locales/fr/common.json @@ -19,11 +19,10 @@ "delete_config_profile": "Êtes-vous sûr de vouloir supprimer ce profil de configuration ?", "delete_custom_mode_with_rules": "Êtes-vous sûr de vouloir supprimer ce mode {scope} ?\n\nCela supprimera également le dossier de règles associé à l'adresse :\n{rulesFolderPath}", "delete_message": "Que souhaitez-vous supprimer ?", - "edit_message": "Supprimer tous les messages après celui-ci ?", + "edit_warning": "Modifier ce message supprimera tous les messages suivants dans la conversation. Voulez-vous continuer ?", "delete_just_this_message": "Uniquement ce message", - "edit_just_this_message": "Non, modifier uniquement celui-ci", "delete_this_and_subsequent": "Ce message et tous les messages suivants", - "edit_this_and_delete_subsequent": "Oui" + "proceed": "Continuer" }, "errors": { "invalid_data_uri": "Format d'URI de données invalide", @@ -107,13 +106,11 @@ "answers": { "yes": "Oui", "no": "Non", - "cancel": "Annuler", "remove": "Supprimer", "keep": "Conserver" }, "buttons": { "save": "Enregistrer", - "cancel": "Annuler", "edit": "Modifier" }, "tasks": { @@ -171,7 +168,6 @@ "title": "Supprimer le mode personnalisé", "description": "Êtes-vous sûr de vouloir supprimer ce mode {{scope}} ? Cela supprimera également le dossier de règles associé à l'adresse : {{rulesFolderPath}}", "descriptionNoRules": "Êtes-vous sûr de vouloir supprimer ce mode personnalisé ?", - "cancel": "Annuler", "confirm": "Supprimer" } } diff --git a/src/i18n/locales/fr/embeddings.json b/src/i18n/locales/fr/embeddings.json index b6ef0d8786..23d70650e8 100644 --- a/src/i18n/locales/fr/embeddings.json +++ b/src/i18n/locales/fr/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "URL de base invalide. Veuillez vérifier votre configuration d'URL.", "invalidModel": "Modèle invalide. Veuillez vérifier votre configuration de modèle.", "invalidResponse": "Réponse invalide du service d'embedder. Veuillez vérifier votre configuration." + }, + "serviceFactory": { + "openAiConfigMissing": "Configuration OpenAI manquante pour la création de l'embedder", + "ollamaConfigMissing": "Configuration Ollama manquante pour la création de l'embedder", + "openAiCompatibleConfigMissing": "Configuration compatible OpenAI manquante pour la création de l'embedder", + "geminiConfigMissing": "Configuration Gemini manquante pour la création de l'embedder", + "invalidEmbedderType": "Type d'embedder configuré invalide : {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "Impossible de déterminer la dimension du vecteur pour le modèle '{{modelId}}' avec le fournisseur '{{provider}}'. Assure-toi que la 'Dimension d'embedding' est correctement définie dans les paramètres du fournisseur compatible OpenAI.", + "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" } } diff --git a/src/i18n/locales/hi/common.json b/src/i18n/locales/hi/common.json index 5c1aec76a4..a16a22ece5 100644 --- a/src/i18n/locales/hi/common.json +++ b/src/i18n/locales/hi/common.json @@ -19,11 +19,10 @@ "delete_config_profile": "क्या आप वाकई इस कॉन्फ़िगरेशन प्रोफ़ाइल को हटाना चाहते हैं?", "delete_custom_mode_with_rules": "क्या आप वाकई इस {scope} मोड को हटाना चाहते हैं?\n\nयह संबंधित नियम फ़ोल्डर को भी यहाँ हटा देगा:\n{rulesFolderPath}", "delete_message": "आप क्या हटाना चाहते हैं?", - "edit_message": "इसके बाद के सभी संदेशों को हटाएं?", + "edit_warning": "इस संदेश को संपादित करने से बातचीत के सभी बाद के संदेश हट जाएंगे। क्या आप जारी रखना चाहते हैं?", "delete_just_this_message": "सिर्फ यह संदेश", - "edit_just_this_message": "नहीं, केवल इसे संपादित करें", "delete_this_and_subsequent": "यह और सभी बाद के संदेश", - "edit_this_and_delete_subsequent": "हां" + "proceed": "जारी रखें" }, "errors": { "invalid_data_uri": "अमान्य डेटा URI फॉर्मेट", @@ -107,13 +106,11 @@ "answers": { "yes": "हां", "no": "नहीं", - "cancel": "रद्द करें", "remove": "हटाएं", "keep": "रखें" }, "buttons": { "save": "सहेजें", - "cancel": "रद्द करें", "edit": "संपादित करें" }, "tasks": { @@ -171,7 +168,6 @@ "title": "कस्टम मोड हटाएं", "description": "क्या आप वाकई इस {{scope}} मोड को हटाना चाहते हैं? यह संबंधित नियम फ़ोल्डर को भी {{rulesFolderPath}} पर हटा देगा", "descriptionNoRules": "क्या आप वाकई इस कस्टम मोड को हटाना चाहते हैं?", - "cancel": "रद्द करें", "confirm": "हटाएं" } } diff --git a/src/i18n/locales/hi/embeddings.json b/src/i18n/locales/hi/embeddings.json index 5ec34e5624..e6a0aa2bbc 100644 --- a/src/i18n/locales/hi/embeddings.json +++ b/src/i18n/locales/hi/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "अमान्य बेस यूआरएल। कृपया अपनी यूआरएल कॉन्फ़िगरेशन जांचें।", "invalidModel": "अमान्य मॉडल। कृपया अपनी मॉडल कॉन्फ़िगरेशन जांचें।", "invalidResponse": "एम्बेडर सेवा से अमान्य प्रतिक्रिया। कृपया अपनी कॉन्फ़िगरेशन जांचें।" + }, + "serviceFactory": { + "openAiConfigMissing": "एम्बेडर बनाने के लिए OpenAI कॉन्फ़िगरेशन गायब है", + "ollamaConfigMissing": "एम्बेडर बनाने के लिए Ollama कॉन्फ़िगरेशन गायब है", + "openAiCompatibleConfigMissing": "एम्बेडर बनाने के लिए OpenAI संगत कॉन्फ़िगरेशन गायब है", + "geminiConfigMissing": "एम्बेडर बनाने के लिए Gemini कॉन्फ़िगरेशन गायब है", + "invalidEmbedderType": "अमान्य एम्बेडर प्रकार कॉन्फ़िगर किया गया: {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "प्रदाता '{{provider}}' के साथ मॉडल '{{modelId}}' के लिए वेक्टर आयाम निर्धारित नहीं कर सका। कृपया सुनिश्चित करें कि OpenAI-संगत प्रदाता सेटिंग्स में 'एम्बेडिंग आयाम' सही तरीके से सेट है।", + "vectorDimensionNotDetermined": "प्रदाता '{{provider}}' के साथ मॉडल '{{modelId}}' के लिए वेक्टर आयाम निर्धारित नहीं कर सका। मॉडल प्रोफ़ाइल या कॉन्फ़िगरेशन की जांच करें।", + "qdrantUrlMissing": "वेक्टर स्टोर बनाने के लिए Qdrant URL गायब है", + "codeIndexingNotConfigured": "सेवाएं नहीं बना सकते: कोड इंडेक्सिंग ठीक से कॉन्फ़िगर नहीं है" } } diff --git a/src/i18n/locales/id/common.json b/src/i18n/locales/id/common.json index 3f227c0046..d40bce9186 100644 --- a/src/i18n/locales/id/common.json +++ b/src/i18n/locales/id/common.json @@ -19,11 +19,10 @@ "delete_config_profile": "Apakah kamu yakin ingin menghapus profil konfigurasi ini?", "delete_custom_mode_with_rules": "Anda yakin ingin menghapus mode {scope} ini?\n\nIni juga akan menghapus folder aturan terkait di:\n{rulesFolderPath}", "delete_message": "Apa yang ingin kamu hapus?", - "edit_message": "Hapus semua pesan setelah ini?", + "edit_warning": "Mengedit pesan ini akan menghapus semua pesan selanjutnya dalam percakapan. Apakah kamu ingin melanjutkan?", "delete_just_this_message": "Hanya pesan ini", - "edit_just_this_message": "Tidak, hanya edit yang ini", "delete_this_and_subsequent": "Ini dan semua pesan selanjutnya", - "edit_this_and_delete_subsequent": "Ya" + "proceed": "Lanjutkan" }, "errors": { "invalid_data_uri": "Format data URI tidak valid", @@ -107,13 +106,11 @@ "answers": { "yes": "Ya", "no": "Tidak", - "cancel": "Batal", "remove": "Hapus", "keep": "Simpan" }, "buttons": { "save": "Simpan", - "cancel": "Batal", "edit": "Edit" }, "tasks": { @@ -171,7 +168,6 @@ "title": "Hapus Mode Kustom", "description": "Anda yakin ingin menghapus mode {{scope}} ini? Ini juga akan menghapus folder aturan terkait di: {{rulesFolderPath}}", "descriptionNoRules": "Anda yakin ingin menghapus mode kustom ini?", - "cancel": "Batal", "confirm": "Hapus" } } diff --git a/src/i18n/locales/id/embeddings.json b/src/i18n/locales/id/embeddings.json index 0082ec8dcf..5ba042e7ef 100644 --- a/src/i18n/locales/id/embeddings.json +++ b/src/i18n/locales/id/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "URL dasar tidak valid. Silakan periksa konfigurasi URL Anda.", "invalidModel": "Model tidak valid. Silakan periksa konfigurasi model Anda.", "invalidResponse": "Respons tidak valid dari layanan embedder. Silakan periksa konfigurasi Anda." + }, + "serviceFactory": { + "openAiConfigMissing": "Konfigurasi OpenAI tidak ada untuk membuat embedder", + "ollamaConfigMissing": "Konfigurasi Ollama tidak ada untuk membuat embedder", + "openAiCompatibleConfigMissing": "Konfigurasi yang kompatibel dengan OpenAI tidak ada untuk membuat embedder", + "geminiConfigMissing": "Konfigurasi Gemini tidak ada untuk membuat embedder", + "invalidEmbedderType": "Tipe embedder yang dikonfigurasi tidak valid: {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "Tidak dapat menentukan dimensi vektor untuk model '{{modelId}}' dengan penyedia '{{provider}}'. Pastikan 'Dimensi Embedding' diatur dengan benar di pengaturan penyedia yang kompatibel dengan OpenAI.", + "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" } } diff --git a/src/i18n/locales/it/common.json b/src/i18n/locales/it/common.json index a13f9b77da..a6782267ce 100644 --- a/src/i18n/locales/it/common.json +++ b/src/i18n/locales/it/common.json @@ -19,11 +19,10 @@ "delete_config_profile": "Sei sicuro di voler eliminare questo profilo di configurazione?", "delete_custom_mode_with_rules": "Sei sicuro di voler eliminare questa modalità {scope}?\n\nQuesto eliminerà anche la cartella delle regole associata in:\n{rulesFolderPath}", "delete_message": "Cosa desideri eliminare?", - "edit_message": "Eliminare tutti i messaggi dopo questo?", + "edit_warning": "Modificare questo messaggio eliminerà tutti i messaggi successivi nella conversazione. Vuoi continuare?", "delete_just_this_message": "Solo questo messaggio", - "edit_just_this_message": "No, modifica solo questo", "delete_this_and_subsequent": "Questo e tutti i messaggi successivi", - "edit_this_and_delete_subsequent": "Sì" + "proceed": "Continua" }, "errors": { "invalid_data_uri": "Formato URI dati non valido", @@ -107,13 +106,11 @@ "answers": { "yes": "Sì", "no": "No", - "cancel": "Annulla", "remove": "Rimuovi", "keep": "Mantieni" }, "buttons": { "save": "Salva", - "cancel": "Annulla", "edit": "Modifica" }, "tasks": { @@ -171,7 +168,6 @@ "title": "Elimina Modalità Personalizzata", "description": "Sei sicuro di voler eliminare questa modalità {{scope}}? Questo eliminerà anche la cartella delle regole associata a: {{rulesFolderPath}}", "descriptionNoRules": "Sei sicuro di voler eliminare questa modalità personalizzata?", - "cancel": "Annulla", "confirm": "Elimina" } } diff --git a/src/i18n/locales/it/embeddings.json b/src/i18n/locales/it/embeddings.json index 19e6af332f..38f502ae78 100644 --- a/src/i18n/locales/it/embeddings.json +++ b/src/i18n/locales/it/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "URL di base non valido. Controlla la configurazione del tuo URL.", "invalidModel": "Modello non valido. Controlla la configurazione del tuo modello.", "invalidResponse": "Risposta non valida dal servizio embedder. Controlla la tua configurazione." + }, + "serviceFactory": { + "openAiConfigMissing": "Configurazione OpenAI mancante per la creazione dell'embedder", + "ollamaConfigMissing": "Configurazione Ollama mancante per la creazione dell'embedder", + "openAiCompatibleConfigMissing": "Configurazione compatibile con OpenAI mancante per la creazione dell'embedder", + "geminiConfigMissing": "Configurazione Gemini mancante per la creazione dell'embedder", + "invalidEmbedderType": "Tipo di embedder configurato non valido: {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "Impossibile determinare la dimensione del vettore per il modello '{{modelId}}' con il provider '{{provider}}'. Assicurati che la 'Dimensione di embedding' sia impostata correttamente nelle impostazioni del provider compatibile con OpenAI.", + "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" } } diff --git a/src/i18n/locales/ja/common.json b/src/i18n/locales/ja/common.json index 0105ac4220..9722281d0c 100644 --- a/src/i18n/locales/ja/common.json +++ b/src/i18n/locales/ja/common.json @@ -19,11 +19,10 @@ "delete_config_profile": "この設定プロファイルを削除してもよろしいですか?", "delete_custom_mode_with_rules": "この{scope}モードを削除してもよろしいですか?\n\nこれにより、関連するルールフォルダも次の場所で削除されます:\n{rulesFolderPath}", "delete_message": "何を削除しますか?", - "edit_message": "これ以降のメッセージをすべて削除しますか?", + "edit_warning": "このメッセージを編集すると、会話内のすべての後続メッセージが削除されます。続行しますか?", "delete_just_this_message": "このメッセージのみ", - "edit_just_this_message": "いいえ、これだけを編集", "delete_this_and_subsequent": "これ以降のすべてのメッセージ", - "edit_this_and_delete_subsequent": "はい" + "proceed": "続行" }, "errors": { "invalid_data_uri": "データURIフォーマットが無効です", @@ -107,13 +106,11 @@ "answers": { "yes": "はい", "no": "いいえ", - "cancel": "キャンセル", "remove": "削除", "keep": "保持" }, "buttons": { "save": "保存", - "cancel": "キャンセル", "edit": "編集" }, "tasks": { @@ -171,7 +168,6 @@ "title": "カスタムモードの削除", "description": "この{{scope}}モードを削除してもよろしいですか?これにより、関連するルールフォルダーも{{rulesFolderPath}}で削除されます", "descriptionNoRules": "このカスタムモードを削除してもよろしいですか?", - "cancel": "キャンセル", "confirm": "削除" } } diff --git a/src/i18n/locales/ja/embeddings.json b/src/i18n/locales/ja/embeddings.json index fcf426a14c..817287cff9 100644 --- a/src/i18n/locales/ja/embeddings.json +++ b/src/i18n/locales/ja/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "無効なベースURLです。URL構成を確認してください。", "invalidModel": "無効なモデルです。モデル構成を確認してください。", "invalidResponse": "エンベッダーサービスからの無効な応答です。設定を確認してください。" + }, + "serviceFactory": { + "openAiConfigMissing": "エンベッダー作成のためのOpenAI設定がありません", + "ollamaConfigMissing": "エンベッダー作成のためのOllama設定がありません", + "openAiCompatibleConfigMissing": "エンベッダー作成のためのOpenAI互換設定がありません", + "geminiConfigMissing": "エンベッダー作成のためのGemini設定がありません", + "invalidEmbedderType": "無効なエンベッダータイプが設定されています: {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "プロバイダー '{{provider}}' のモデル '{{modelId}}' の埋め込み次元を決定できませんでした。OpenAI互換プロバイダー設定で「埋め込み次元」が正しく設定されていることを確認してください。", + "vectorDimensionNotDetermined": "プロバイダー '{{provider}}' のモデル '{{modelId}}' の埋め込み次元を決定できませんでした。モデルプロファイルまたは設定を確認してください。", + "qdrantUrlMissing": "ベクターストア作成のためのQdrant URLがありません", + "codeIndexingNotConfigured": "サービスを作成できません: コードインデックスが正しく設定されていません" } } diff --git a/src/i18n/locales/ko/common.json b/src/i18n/locales/ko/common.json index 236bb22bdd..81c80154d0 100644 --- a/src/i18n/locales/ko/common.json +++ b/src/i18n/locales/ko/common.json @@ -19,11 +19,10 @@ "delete_config_profile": "이 구성 프로필을 삭제하시겠습니까?", "delete_custom_mode_with_rules": "이 {scope} 모드를 삭제하시겠습니까?\n\n이렇게 하면 연결된 규칙 폴더도 다음 위치에서 삭제됩니다:\n{rulesFolderPath}", "delete_message": "무엇을 삭제하시겠습니까?", - "edit_message": "이 메시지 이후의 모든 메시지를 삭제하시겠습니까?", + "edit_warning": "이 메시지를 편집하면 대화의 모든 후속 메시지가 삭제됩니다. 계속하시겠습니까?", "delete_just_this_message": "이 메시지만", - "edit_just_this_message": "아니요, 이것만 편집", "delete_this_and_subsequent": "이 메시지와 모든 후속 메시지", - "edit_this_and_delete_subsequent": "예" + "proceed": "계속" }, "errors": { "invalid_data_uri": "잘못된 데이터 URI 형식", @@ -107,13 +106,11 @@ "answers": { "yes": "예", "no": "아니오", - "cancel": "취소", "remove": "제거", "keep": "유지" }, "buttons": { "save": "저장", - "cancel": "취소", "edit": "편집" }, "tasks": { @@ -171,7 +168,6 @@ "title": "사용자 정의 모드 삭제", "description": "이 {{scope}} 모드를 삭제하시겠습니까? 이렇게 하면 {{rulesFolderPath}}의 관련 규칙 폴더도 삭제됩니다.", "descriptionNoRules": "이 사용자 정의 모드를 삭제하시겠습니까?", - "cancel": "취소", "confirm": "삭제" } } diff --git a/src/i18n/locales/ko/embeddings.json b/src/i18n/locales/ko/embeddings.json index 16d119c959..272ac74cc7 100644 --- a/src/i18n/locales/ko/embeddings.json +++ b/src/i18n/locales/ko/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "잘못된 기본 URL입니다. URL 구성을 확인하세요.", "invalidModel": "잘못된 모델입니다. 모델 구성을 확인하세요.", "invalidResponse": "임베더 서비스에서 잘못된 응답이 왔습니다. 구성을 확인하세요." + }, + "serviceFactory": { + "openAiConfigMissing": "임베더 생성을 위한 OpenAI 구성이 누락되었습니다", + "ollamaConfigMissing": "임베더 생성을 위한 Ollama 구성이 누락되었습니다", + "openAiCompatibleConfigMissing": "임베더 생성을 위한 OpenAI 호환 구성이 누락되었습니다", + "geminiConfigMissing": "임베더 생성을 위한 Gemini 구성이 누락되었습니다", + "invalidEmbedderType": "잘못된 임베더 유형이 구성되었습니다: {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "프로바이더 '{{provider}}'의 모델 '{{modelId}}'에 대한 벡터 차원을 결정할 수 없습니다. OpenAI 호환 프로바이더 설정에서 '임베딩 차원'이 올바르게 설정되어 있는지 확인하세요.", + "vectorDimensionNotDetermined": "프로바이더 '{{provider}}'의 모델 '{{modelId}}'에 대한 벡터 차원을 결정할 수 없습니다. 모델 프로필 또는 구성을 확인하세요.", + "qdrantUrlMissing": "벡터 저장소 생성을 위한 Qdrant URL이 누락되었습니다", + "codeIndexingNotConfigured": "서비스를 생성할 수 없습니다: 코드 인덱싱이 올바르게 구성되지 않았습니다" } } diff --git a/src/i18n/locales/nl/common.json b/src/i18n/locales/nl/common.json index 5e51c1e8a1..68ad31e728 100644 --- a/src/i18n/locales/nl/common.json +++ b/src/i18n/locales/nl/common.json @@ -21,9 +21,8 @@ "delete_message": "Wat wil je verwijderen?", "delete_just_this_message": "Alleen dit bericht", "delete_this_and_subsequent": "Dit en alle volgende berichten", - "edit_message": "Alle berichten na dit bericht verwijderen?", - "edit_just_this_message": "Nee, alleen dit bericht bewerken", - "edit_this_and_delete_subsequent": "Ja" + "edit_warning": "Het bewerken van dit bericht zal alle volgende berichten in het gesprek verwijderen. Wil je doorgaan?", + "proceed": "Doorgaan" }, "errors": { "invalid_data_uri": "Ongeldig data-URI-formaat", @@ -107,13 +106,11 @@ "answers": { "yes": "Ja", "no": "Nee", - "cancel": "Annuleren", "remove": "Verwijderen", "keep": "Behouden" }, "buttons": { "save": "Opslaan", - "cancel": "Annuleren", "edit": "Bewerken" }, "tasks": { @@ -171,7 +168,6 @@ "title": "Aangepaste modus verwijderen", "description": "Weet je zeker dat je deze {{scope}}-modus wilt verwijderen? Dit zal ook de bijbehorende regelsmap op {{rulesFolderPath}} verwijderen", "descriptionNoRules": "Weet je zeker dat je deze aangepaste modus wilt verwijderen?", - "cancel": "Annuleren", "confirm": "Verwijderen" } } diff --git a/src/i18n/locales/nl/embeddings.json b/src/i18n/locales/nl/embeddings.json index 9eeb5a04ea..055d27b607 100644 --- a/src/i18n/locales/nl/embeddings.json +++ b/src/i18n/locales/nl/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "Ongeldige basis-URL. Controleer je URL-configuratie.", "invalidModel": "Ongeldig model. Controleer je modelconfiguratie.", "invalidResponse": "Ongeldige reactie van embedder-service. Controleer je configuratie." + }, + "serviceFactory": { + "openAiConfigMissing": "OpenAI-configuratie ontbreekt voor het maken van embedder", + "ollamaConfigMissing": "Ollama-configuratie ontbreekt voor het maken van embedder", + "openAiCompatibleConfigMissing": "OpenAI-compatibele configuratie ontbreekt voor het maken van embedder", + "geminiConfigMissing": "Gemini-configuratie ontbreekt voor het maken van embedder", + "invalidEmbedderType": "Ongeldig embedder-type geconfigureerd: {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "Kan de vectordimensie voor model '{{modelId}}' met provider '{{provider}}' niet bepalen. Zorg ervoor dat de 'Embedding Dimensie' correct is ingesteld in de OpenAI-compatibele provider-instellingen.", + "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" } } diff --git a/src/i18n/locales/pl/common.json b/src/i18n/locales/pl/common.json index 1e370ff49c..7dc510e71c 100644 --- a/src/i18n/locales/pl/common.json +++ b/src/i18n/locales/pl/common.json @@ -21,9 +21,8 @@ "delete_message": "Co chcesz usunąć?", "delete_just_this_message": "Tylko tę wiadomość", "delete_this_and_subsequent": "Tę i wszystkie kolejne wiadomości", - "edit_message": "Usunąć wszystkie wiadomości po tej?", - "edit_just_this_message": "Nie, tylko edytuj tę wiadomość", - "edit_this_and_delete_subsequent": "Tak" + "edit_warning": "Edytowanie tej wiadomości usunie wszystkie kolejne wiadomości w rozmowie. Czy chcesz kontynuować?", + "proceed": "Kontynuuj" }, "errors": { "invalid_data_uri": "Nieprawidłowy format URI danych", @@ -107,13 +106,11 @@ "answers": { "yes": "Tak", "no": "Nie", - "cancel": "Anuluj", "remove": "Usuń", "keep": "Zachowaj" }, "buttons": { "save": "Zapisz", - "cancel": "Anuluj", "edit": "Edytuj" }, "tasks": { @@ -171,7 +168,6 @@ "title": "Usuń tryb niestandardowy", "description": "Czy na pewno chcesz usunąć ten tryb {{scope}}? Spowoduje to również usunięcie powiązanego folderu z regułami w {{rulesFolderPath}}", "descriptionNoRules": "Czy na pewno chcesz usunąć ten tryb niestandardowy?", - "cancel": "Anuluj", "confirm": "Usuń" } } diff --git a/src/i18n/locales/pl/embeddings.json b/src/i18n/locales/pl/embeddings.json index dd10c1ec4c..874fcf7e00 100644 --- a/src/i18n/locales/pl/embeddings.json +++ b/src/i18n/locales/pl/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "Nieprawidłowy podstawowy adres URL. Sprawdź konfigurację adresu URL.", "invalidModel": "Nieprawidłowy model. Sprawdź konfigurację modelu.", "invalidResponse": "Nieprawidłowa odpowiedź z usługi embedder. Sprawdź swoją konfigurację." + }, + "serviceFactory": { + "openAiConfigMissing": "Brak konfiguracji OpenAI do utworzenia embeddera", + "ollamaConfigMissing": "Brak konfiguracji Ollama do utworzenia embeddera", + "openAiCompatibleConfigMissing": "Brak konfiguracji kompatybilnej z OpenAI do utworzenia embeddera", + "geminiConfigMissing": "Brak konfiguracji Gemini do utworzenia embeddera", + "invalidEmbedderType": "Skonfigurowano nieprawidłowy typ embeddera: {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "Nie można określić wymiaru wektora dla modelu '{{modelId}}' z dostawcą '{{provider}}'. Upewnij się, że 'Wymiar osadzania' jest poprawnie ustawiony w ustawieniach dostawcy kompatybilnego z OpenAI.", + "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" } } diff --git a/src/i18n/locales/pt-BR/common.json b/src/i18n/locales/pt-BR/common.json index c36b853e78..7ee3b8a658 100644 --- a/src/i18n/locales/pt-BR/common.json +++ b/src/i18n/locales/pt-BR/common.json @@ -25,9 +25,8 @@ "delete_message": "O que você gostaria de excluir?", "delete_just_this_message": "Apenas esta mensagem", "delete_this_and_subsequent": "Esta e todas as mensagens subsequentes", - "edit_message": "Excluir todas as mensagens após esta?", - "edit_just_this_message": "Não, apenas editar esta", - "edit_this_and_delete_subsequent": "Sim" + "edit_warning": "Editar esta mensagem excluirá todas as mensagens subsequentes na conversa. Deseja continuar?", + "proceed": "Continuar" }, "errors": { "invalid_data_uri": "Formato de URI de dados inválido", @@ -111,13 +110,11 @@ "answers": { "yes": "Sim", "no": "Não", - "cancel": "Cancelar", "remove": "Remover", "keep": "Manter" }, "buttons": { "save": "Salvar", - "cancel": "Cancelar", "edit": "Editar" }, "tasks": { @@ -171,7 +168,6 @@ "title": "Excluir Modo Personalizado", "description": "Tem certeza de que deseja excluir este modo {{scope}}? Isso também excluirá a pasta de regras associada em: {{rulesFolderPath}}", "descriptionNoRules": "Tem certeza de que deseja excluir este modo personalizado?", - "cancel": "Cancelar", "confirm": "Excluir" } } diff --git a/src/i18n/locales/pt-BR/embeddings.json b/src/i18n/locales/pt-BR/embeddings.json index ec1db07113..741a10423e 100644 --- a/src/i18n/locales/pt-BR/embeddings.json +++ b/src/i18n/locales/pt-BR/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "URL base inválida. Verifique sua configuração de URL.", "invalidModel": "Modelo inválido. Verifique a configuração do seu modelo.", "invalidResponse": "Resposta inválida do serviço de embedder. Verifique sua configuração." + }, + "serviceFactory": { + "openAiConfigMissing": "Configuração do OpenAI ausente para criação do embedder", + "ollamaConfigMissing": "Configuração do Ollama ausente para criação do embedder", + "openAiCompatibleConfigMissing": "Configuração compatível com OpenAI ausente para criação do embedder", + "geminiConfigMissing": "Configuração do Gemini ausente para criação do embedder", + "invalidEmbedderType": "Tipo de embedder configurado inválido: {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "Não foi possível determinar a dimensão do vetor para o modelo '{{modelId}}' com o provedor '{{provider}}'. Certifique-se de que a 'Dimensão de Embedding' esteja configurada corretamente nas configurações do provedor compatível com OpenAI.", + "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" } } diff --git a/src/i18n/locales/ru/common.json b/src/i18n/locales/ru/common.json index fca0623f65..8e100bff9a 100644 --- a/src/i18n/locales/ru/common.json +++ b/src/i18n/locales/ru/common.json @@ -21,9 +21,8 @@ "delete_message": "Что вы хотите удалить?", "delete_just_this_message": "Только это сообщение", "delete_this_and_subsequent": "Это и все последующие сообщения", - "edit_message": "Удалить все сообщения после этого?", - "edit_just_this_message": "Нет, только редактировать это", - "edit_this_and_delete_subsequent": "Да" + "edit_warning": "Редактирование этого сообщения удалит все последующие сообщения в разговоре. Хотите продолжить?", + "proceed": "Продолжить" }, "errors": { "invalid_data_uri": "Неверный формат URI данных", @@ -107,13 +106,11 @@ "answers": { "yes": "Да", "no": "Нет", - "cancel": "Отмена", "remove": "Удалить", "keep": "Оставить" }, "buttons": { "save": "Сохранить", - "cancel": "Отмена", "edit": "Редактировать" }, "tasks": { @@ -171,7 +168,6 @@ "title": "Удалить пользовательский режим", "description": "Вы уверены, что хотите удалить этот режим {{scope}}? Это также удалит связанную папку правил по адресу: {{rulesFolderPath}}", "descriptionNoRules": "Вы уверены, что хотите удалить этот пользовательский режим?", - "cancel": "Отмена", "confirm": "Удалить" } } diff --git a/src/i18n/locales/ru/embeddings.json b/src/i18n/locales/ru/embeddings.json index 931dca5bbd..78a21872c6 100644 --- a/src/i18n/locales/ru/embeddings.json +++ b/src/i18n/locales/ru/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "Неверный базовый URL. Проверьте конфигурацию URL.", "invalidModel": "Неверная модель. Проверьте конфигурацию модели.", "invalidResponse": "Неверный ответ от службы embedder. Проверьте вашу конфигурацию." + }, + "serviceFactory": { + "openAiConfigMissing": "Отсутствует конфигурация OpenAI для создания эмбеддера", + "ollamaConfigMissing": "Отсутствует конфигурация Ollama для создания эмбеддера", + "openAiCompatibleConfigMissing": "Отсутствует конфигурация, совместимая с OpenAI, для создания эмбеддера", + "geminiConfigMissing": "Отсутствует конфигурация Gemini для создания эмбеддера", + "invalidEmbedderType": "Настроен недопустимый тип эмбеддера: {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "Не удалось определить размерность вектора для модели '{{modelId}}' с провайдером '{{provider}}'. Убедитесь, что 'Размерность эмбеддинга' правильно установлена в настройках провайдера, совместимого с OpenAI.", + "vectorDimensionNotDetermined": "Не удалось определить размерность вектора для модели '{{modelId}}' с провайдером '{{provider}}'. Проверьте профили модели или конфигурацию.", + "qdrantUrlMissing": "Отсутствует URL Qdrant для создания векторного хранилища", + "codeIndexingNotConfigured": "Невозможно создать сервисы: Индексация кода не настроена должным образом" } } diff --git a/src/i18n/locales/tr/common.json b/src/i18n/locales/tr/common.json index 5aff8c2483..df8212cf3c 100644 --- a/src/i18n/locales/tr/common.json +++ b/src/i18n/locales/tr/common.json @@ -21,9 +21,8 @@ "delete_message": "Neyi silmek istersiniz?", "delete_just_this_message": "Sadece bu mesajı", "delete_this_and_subsequent": "Bu ve sonraki tüm mesajları", - "edit_message": "Bu mesajdan sonraki tüm mesajlar silinsin mi?", - "edit_just_this_message": "Hayır, sadece bunu düzenle", - "edit_this_and_delete_subsequent": "Evet" + "edit_warning": "Bu mesajı düzenlemek konuşmadaki tüm sonraki mesajları silecektir. Devam etmek istiyor musunuz?", + "proceed": "Devam et" }, "errors": { "invalid_data_uri": "Geçersiz veri URI formatı", @@ -107,13 +106,11 @@ "answers": { "yes": "Evet", "no": "Hayır", - "cancel": "İptal", "remove": "Kaldır", "keep": "Koru" }, "buttons": { "save": "Kaydet", - "cancel": "İptal", "edit": "Düzenle" }, "tasks": { @@ -171,7 +168,6 @@ "title": "Özel Modu Sil", "description": "Bu {{scope}} modunu silmek istediğinizden emin misiniz? Bu, {{rulesFolderPath}} adresindeki ilişkili kurallar klasörünü de silecektir", "descriptionNoRules": "Bu özel modu silmek istediğinizden emin misiniz?", - "cancel": "İptal", "confirm": "Sil" } } diff --git a/src/i18n/locales/tr/embeddings.json b/src/i18n/locales/tr/embeddings.json index 8ff94b0dae..411bad5eb3 100644 --- a/src/i18n/locales/tr/embeddings.json +++ b/src/i18n/locales/tr/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "Geçersiz temel URL. Lütfen URL yapılandırmanızı kontrol edin.", "invalidModel": "Geçersiz model. Lütfen model yapılandırmanızı kontrol edin.", "invalidResponse": "Embedder hizmetinden geçersiz yanıt. Lütfen yapılandırmanızı kontrol edin." + }, + "serviceFactory": { + "openAiConfigMissing": "Gömücü oluşturmak için OpenAI yapılandırması eksik", + "ollamaConfigMissing": "Gömücü oluşturmak için Ollama yapılandırması eksik", + "openAiCompatibleConfigMissing": "Gömücü oluşturmak için OpenAI uyumlu yapılandırması eksik", + "geminiConfigMissing": "Gömücü oluşturmak için Gemini yapılandırması eksik", + "invalidEmbedderType": "Geçersiz gömücü türü yapılandırıldı: {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "'{{provider}}' sağlayıcısı ile '{{modelId}}' modeli için vektör boyutu belirlenemedi. OpenAI uyumlu sağlayıcı ayarlarında 'Gömme Boyutu'nun doğru ayarlandığından emin ol.", + "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ış" } } diff --git a/src/i18n/locales/vi/common.json b/src/i18n/locales/vi/common.json index a106b21bf6..6710cd136d 100644 --- a/src/i18n/locales/vi/common.json +++ b/src/i18n/locales/vi/common.json @@ -21,9 +21,8 @@ "delete_message": "Bạn muốn xóa gì?", "delete_just_this_message": "Chỉ tin nhắn này", "delete_this_and_subsequent": "Tin nhắn này và tất cả tin nhắn tiếp theo", - "edit_message": "Xóa tất cả tin nhắn sau tin nhắn này?", - "edit_just_this_message": "Không, chỉ chỉnh sửa tin nhắn này", - "edit_this_and_delete_subsequent": "Có" + "edit_warning": "Chỉnh sửa tin nhắn này sẽ xóa tất cả tin nhắn tiếp theo trong cuộc trò chuyện. Bạn có muốn tiếp tục không?", + "proceed": "Tiếp tục" }, "errors": { "invalid_data_uri": "Định dạng URI dữ liệu không hợp lệ", @@ -107,13 +106,11 @@ "answers": { "yes": "Có", "no": "Không", - "cancel": "Hủy", "remove": "Xóa", "keep": "Giữ" }, "buttons": { "save": "Lưu", - "cancel": "Hủy", "edit": "Chỉnh sửa" }, "tasks": { @@ -178,7 +175,6 @@ "deleteConfirmation": "Chắc chắn xóa chế độ này?" }, "descriptionNoRules": "Bạn có chắc chắn muốn xóa chế độ tùy chỉnh này không?", - "cancel": "Hủy", "confirm": "Xóa" } } diff --git a/src/i18n/locales/vi/embeddings.json b/src/i18n/locales/vi/embeddings.json index 5988219aed..c645199046 100644 --- a/src/i18n/locales/vi/embeddings.json +++ b/src/i18n/locales/vi/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "URL cơ sở không hợp lệ. Vui lòng kiểm tra cấu hình URL của bạn.", "invalidModel": "Mô hình không hợp lệ. Vui lòng kiểm tra cấu hình mô hình của bạn.", "invalidResponse": "Phản hồi không hợp lệ từ dịch vụ embedder. Vui lòng kiểm tra cấu hình của bạn." + }, + "serviceFactory": { + "openAiConfigMissing": "Thiếu cấu hình OpenAI để tạo embedder", + "ollamaConfigMissing": "Thiếu cấu hình Ollama để tạo embedder", + "openAiCompatibleConfigMissing": "Thiếu cấu hình tương thích OpenAI để tạo embedder", + "geminiConfigMissing": "Thiếu cấu hình Gemini để tạo embedder", + "invalidEmbedderType": "Loại embedder được cấu hình không hợp lệ: {{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "Không thể xác định kích thước vector cho mô hình '{{modelId}}' với nhà cung cấp '{{provider}}'. Hãy đảm bảo 'Kích thước Embedding' được cài đặt đúng trong cài đặt nhà cung cấp tương thích OpenAI.", + "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" } } diff --git a/src/i18n/locales/zh-CN/common.json b/src/i18n/locales/zh-CN/common.json index 6e730a106d..5a8fc51ef1 100644 --- a/src/i18n/locales/zh-CN/common.json +++ b/src/i18n/locales/zh-CN/common.json @@ -19,11 +19,10 @@ "delete_config_profile": "您确定要删除此配置文件吗?", "delete_custom_mode_with_rules": "您确定要删除此 {scope} 模式吗?\n\n这也将删除位于以下位置的关联规则文件夹:\n{rulesFolderPath}", "delete_message": "您想删除什么?", - "edit_message": "删除此消息后的所有消息?", + "edit_warning": "编辑此消息将删除对话中的所有后续消息。您要继续吗?", "delete_just_this_message": "仅此消息", - "edit_just_this_message": "不,仅编辑此消息", "delete_this_and_subsequent": "此消息及所有后续消息", - "edit_this_and_delete_subsequent": "是" + "proceed": "继续" }, "errors": { "invalid_mcp_config": "项目MCP配置格式无效", @@ -112,13 +111,11 @@ "answers": { "yes": "是", "no": "否", - "cancel": "取消", "remove": "删除", "keep": "保留" }, "buttons": { "save": "保存", - "cancel": "取消", "edit": "编辑" }, "tasks": { @@ -176,7 +173,6 @@ "title": "删除自定义模式", "description": "您确定要删除此 {{scope}} 模式吗?这也将删除位于 {{rulesFolderPath}} 的关联规则文件夹", "descriptionNoRules": "您确定要删除此自定义模式吗?", - "cancel": "取消", "confirm": "删除" } } diff --git a/src/i18n/locales/zh-CN/embeddings.json b/src/i18n/locales/zh-CN/embeddings.json index 68d41a2f4c..8eb4ae4d2d 100644 --- a/src/i18n/locales/zh-CN/embeddings.json +++ b/src/i18n/locales/zh-CN/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "基础 URL 无效。请检查您的 URL 配置。", "invalidModel": "模型无效。请检查您的模型配置。", "invalidResponse": "嵌入服务响应无效。请检查您的配置。" + }, + "serviceFactory": { + "openAiConfigMissing": "创建嵌入器缺少 OpenAI 配置", + "ollamaConfigMissing": "创建嵌入器缺少 Ollama 配置", + "openAiCompatibleConfigMissing": "创建嵌入器缺少 OpenAI 兼容配置", + "geminiConfigMissing": "创建嵌入器缺少 Gemini 配置", + "invalidEmbedderType": "配置的嵌入器类型无效:{{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "无法确定提供商 '{{provider}}' 的模型 '{{modelId}}' 的向量维度。请确保在 OpenAI 兼容提供商设置中正确设置了「嵌入维度」。", + "vectorDimensionNotDetermined": "无法确定提供商 '{{provider}}' 的模型 '{{modelId}}' 的向量维度。请检查模型配置文件或配置。", + "qdrantUrlMissing": "创建向量存储缺少 Qdrant URL", + "codeIndexingNotConfigured": "无法创建服务:代码索引未正确配置" } } diff --git a/src/i18n/locales/zh-TW/common.json b/src/i18n/locales/zh-TW/common.json index 0a4ad22d17..2bfad5e00f 100644 --- a/src/i18n/locales/zh-TW/common.json +++ b/src/i18n/locales/zh-TW/common.json @@ -19,11 +19,10 @@ "delete_config_profile": "您確定要刪除此設定檔案嗎?", "delete_custom_mode_with_rules": "您確定要刪除此 {scope} 模式嗎?\n\n這也將刪除位於以下位置的關聯規則資料夾:\n{rulesFolderPath}", "delete_message": "您想刪除哪些內容?", - "edit_message": "刪除此訊息後的所有訊息?", + "edit_warning": "編輯此訊息將刪除對話中的所有後續訊息。您要繼續嗎?", "delete_just_this_message": "僅這則訊息", - "edit_just_this_message": "否,僅編輯此訊息", "delete_this_and_subsequent": "這則訊息及所有後續訊息", - "edit_this_and_delete_subsequent": "是" + "proceed": "繼續" }, "errors": { "invalid_data_uri": "資料 URI 格式無效", @@ -107,13 +106,11 @@ "answers": { "yes": "是", "no": "否", - "cancel": "取消", "remove": "刪除", "keep": "保留" }, "buttons": { "save": "儲存", - "cancel": "取消", "edit": "編輯" }, "tasks": { @@ -171,7 +168,6 @@ "title": "刪除自訂模式", "description": "您確定要刪除此 {{scope}} 模式嗎?這也將刪除位於 {{rulesFolderPath}} 的關聯規則資料夾", "descriptionNoRules": "您確定要刪除此自訂模式嗎?", - "cancel": "取消", "confirm": "刪除" } } diff --git a/src/i18n/locales/zh-TW/embeddings.json b/src/i18n/locales/zh-TW/embeddings.json index 2b9967a930..7bd4dfeba3 100644 --- a/src/i18n/locales/zh-TW/embeddings.json +++ b/src/i18n/locales/zh-TW/embeddings.json @@ -37,5 +37,16 @@ "invalidBaseUrl": "無效的基礎 URL。請檢查您的 URL 組態。", "invalidModel": "無效的模型。請檢查您的模型組態。", "invalidResponse": "內嵌服務回應無效。請檢查您的組態。" + }, + "serviceFactory": { + "openAiConfigMissing": "建立嵌入器缺少 OpenAI 設定", + "ollamaConfigMissing": "建立嵌入器缺少 Ollama 設定", + "openAiCompatibleConfigMissing": "建立嵌入器缺少 OpenAI 相容設定", + "geminiConfigMissing": "建立嵌入器缺少 Gemini 設定", + "invalidEmbedderType": "設定的嵌入器類型無效:{{embedderProvider}}", + "vectorDimensionNotDeterminedOpenAiCompatible": "無法確定提供商 '{{provider}}' 的模型 '{{modelId}}' 的向量維度。請確保在 OpenAI 相容提供商設定中正確設定了「嵌入維度」。", + "vectorDimensionNotDetermined": "無法確定提供商 '{{provider}}' 的模型 '{{modelId}}' 的向量維度。請檢查模型設定檔或設定。", + "qdrantUrlMissing": "建立向量儲存缺少 Qdrant URL", + "codeIndexingNotConfigured": "無法建立服務:程式碼索引未正確設定" } } diff --git a/src/package.json b/src/package.json index 82438dd167..58c62c207f 100644 --- a/src/package.json +++ b/src/package.json @@ -3,7 +3,7 @@ "displayName": "%extension.displayName%", "description": "%extension.description%", "publisher": "RooVeterinaryInc", - "version": "3.22.6", + "version": "3.23.3", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", diff --git a/src/services/code-index/__tests__/config-manager.spec.ts b/src/services/code-index/__tests__/config-manager.spec.ts index 994f228e52..641abfa306 100644 --- a/src/services/code-index/__tests__/config-manager.spec.ts +++ b/src/services/code-index/__tests__/config-manager.spec.ts @@ -32,7 +32,7 @@ describe("CodeIndexConfigManager", () => { describe("constructor", () => { it("should initialize with ContextProxy", () => { expect(configManager).toBeDefined() - expect(configManager.isFeatureEnabled).toBe(false) + expect(configManager.isFeatureEnabled).toBe(true) expect(configManager.currentEmbedderProvider).toBe("openai") }) }) @@ -45,7 +45,6 @@ describe("CodeIndexConfigManager", () => { const result = await configManager.loadConfiguration() expect(result.currentConfig).toEqual({ - isEnabled: false, isConfigured: false, embedderProvider: "openai", modelId: undefined, @@ -77,7 +76,6 @@ describe("CodeIndexConfigManager", () => { const result = await configManager.loadConfiguration() expect(result.currentConfig).toEqual({ - isEnabled: true, isConfigured: true, embedderProvider: "openai", modelId: "text-embedding-3-large", @@ -111,7 +109,6 @@ describe("CodeIndexConfigManager", () => { const result = await configManager.loadConfiguration() expect(result.currentConfig).toEqual({ - isEnabled: true, isConfigured: true, embedderProvider: "openai-compatible", modelId: "text-embedding-3-large", @@ -135,7 +132,7 @@ describe("CodeIndexConfigManager", () => { codebaseIndexEmbedderBaseUrl: "", codebaseIndexEmbedderModelId: "custom-model", codebaseIndexOpenAiCompatibleBaseUrl: "https://api.example.com/v1", - codebaseIndexOpenAiCompatibleModelDimension: 1024, + codebaseIndexEmbedderModelDimension: 1024, } mockContextProxy.getGlobalState.mockImplementation((key: string) => { if (key === "codebaseIndexConfig") return mockGlobalState @@ -149,16 +146,15 @@ describe("CodeIndexConfigManager", () => { const result = await configManager.loadConfiguration() expect(result.currentConfig).toEqual({ - isEnabled: true, isConfigured: true, embedderProvider: "openai-compatible", modelId: "custom-model", + modelDimension: 1024, openAiOptions: { openAiNativeApiKey: "" }, ollamaOptions: { ollamaBaseUrl: "" }, openAiCompatibleOptions: { baseUrl: "https://api.example.com/v1", apiKey: "test-openai-compatible-key", - modelDimension: 1024, }, qdrantUrl: "http://qdrant.local", qdrantApiKey: "test-qdrant-key", @@ -188,7 +184,6 @@ describe("CodeIndexConfigManager", () => { const result = await configManager.loadConfiguration() expect(result.currentConfig).toEqual({ - isEnabled: true, isConfigured: true, embedderProvider: "openai-compatible", modelId: "custom-model", @@ -213,7 +208,7 @@ describe("CodeIndexConfigManager", () => { codebaseIndexEmbedderBaseUrl: "", codebaseIndexEmbedderModelId: "custom-model", codebaseIndexOpenAiCompatibleBaseUrl: "https://api.example.com/v1", - codebaseIndexOpenAiCompatibleModelDimension: "invalid-dimension", // Invalid type + codebaseIndexEmbedderModelDimension: "invalid-dimension", // Invalid type } mockContextProxy.getGlobalState.mockImplementation((key: string) => { if (key === "codebaseIndexConfig") return mockGlobalState @@ -227,17 +222,17 @@ describe("CodeIndexConfigManager", () => { const result = await configManager.loadConfiguration() expect(result.currentConfig).toEqual({ - isEnabled: true, isConfigured: true, embedderProvider: "openai-compatible", modelId: "custom-model", + modelDimension: undefined, // Invalid dimension is converted to undefined openAiOptions: { openAiNativeApiKey: "" }, ollamaOptions: { ollamaBaseUrl: "" }, openAiCompatibleOptions: { baseUrl: "https://api.example.com/v1", apiKey: "test-openai-compatible-key", - modelDimension: "invalid-dimension", }, + geminiOptions: undefined, qdrantUrl: "http://qdrant.local", qdrantApiKey: "test-qdrant-key", searchMinScore: 0.4, @@ -325,14 +320,14 @@ describe("CodeIndexConfigManager", () => { }) it("should detect restart requirement when transitioning to enabled+configured", async () => { - // Initial state - disabled + // Initial state - enabled but not configured mockContextProxy.getGlobalState.mockReturnValue({ - codebaseIndexEnabled: false, + codebaseIndexEnabled: true, }) await configManager.loadConfiguration() - // Enable and configure + // Configure the feature mockContextProxy.getGlobalState.mockReturnValue({ codebaseIndexEnabled: true, codebaseIndexQdrantUrl: "http://qdrant.local", @@ -533,7 +528,7 @@ describe("CodeIndexConfigManager", () => { codebaseIndexEmbedderProvider: "openai-compatible", codebaseIndexEmbedderModelId: "custom-model", codebaseIndexOpenAiCompatibleBaseUrl: "https://api.example.com/v1", - codebaseIndexOpenAiCompatibleModelDimension: 1024, + codebaseIndexEmbedderModelDimension: 1024, } } return undefined @@ -554,7 +549,7 @@ describe("CodeIndexConfigManager", () => { codebaseIndexEmbedderProvider: "openai-compatible", codebaseIndexEmbedderModelId: "custom-model", codebaseIndexOpenAiCompatibleBaseUrl: "https://api.example.com/v1", - codebaseIndexOpenAiCompatibleModelDimension: 2048, + codebaseIndexEmbedderModelDimension: 2048, } } return undefined @@ -573,10 +568,10 @@ describe("CodeIndexConfigManager", () => { codebaseIndexQdrantUrl: "http://qdrant.local", codebaseIndexEmbedderProvider: "openai-compatible", codebaseIndexEmbedderModelId: "custom-model", + codebaseIndexOpenAiCompatibleBaseUrl: "https://api.example.com/v1", + codebaseIndexEmbedderModelDimension: 1024, } } - if (key === "codebaseIndexOpenAiCompatibleBaseUrl") return "https://api.example.com/v1" - if (key === "codebaseIndexOpenAiCompatibleModelDimension") return 1024 return undefined }) setupSecretMocks({ @@ -594,11 +589,11 @@ describe("CodeIndexConfigManager", () => { codebaseIndexQdrantUrl: "http://qdrant.local", codebaseIndexEmbedderProvider: "openai-compatible", codebaseIndexEmbedderModelId: "custom-model", + codebaseIndexOpenAiCompatibleBaseUrl: "https://api.example.com/v1", + codebaseIndexEmbedderModelDimension: 1024, codebaseIndexSearchMinScore: 0.5, // Changed unrelated setting } } - if (key === "codebaseIndexOpenAiCompatibleBaseUrl") return "https://api.example.com/v1" - if (key === "codebaseIndexOpenAiCompatibleModelDimension") return 1024 return undefined }) @@ -637,7 +632,7 @@ describe("CodeIndexConfigManager", () => { codebaseIndexEmbedderProvider: "openai-compatible", codebaseIndexEmbedderModelId: "custom-model", codebaseIndexOpenAiCompatibleBaseUrl: "https://api.example.com/v1", - codebaseIndexOpenAiCompatibleModelDimension: 1024, + codebaseIndexEmbedderModelDimension: 1024, } } return undefined @@ -657,7 +652,7 @@ describe("CodeIndexConfigManager", () => { codebaseIndexEmbedderProvider: "openai-compatible", codebaseIndexEmbedderModelId: "custom-model", codebaseIndexOpenAiCompatibleBaseUrl: "https://api.example.com/v1", - codebaseIndexOpenAiCompatibleModelDimension: 1024, + codebaseIndexEmbedderModelDimension: 1024, } } return undefined @@ -688,29 +683,28 @@ describe("CodeIndexConfigManager", () => { expect(result.requiresRestart).toBe(true) }) - it("should not require restart when disabled remains disabled", async () => { - // Initial state - disabled but configured + it("should require restart when enabled and provider changes even if unconfigured", async () => { + // Initial state - enabled but not configured (missing API key) mockContextProxy.getGlobalState.mockReturnValue({ - codebaseIndexEnabled: false, + codebaseIndexEnabled: true, codebaseIndexQdrantUrl: "http://qdrant.local", codebaseIndexEmbedderProvider: "openai", }) - setupSecretMocks({ - codeIndexOpenAiKey: "test-key", - }) + setupSecretMocks({}) await configManager.loadConfiguration() - // Still disabled but change other settings + // Still enabled but change provider while remaining unconfigured mockContextProxy.getGlobalState.mockReturnValue({ - codebaseIndexEnabled: false, - codebaseIndexQdrantUrl: "http://different-qdrant.local", + codebaseIndexEnabled: true, + codebaseIndexQdrantUrl: "http://qdrant.local", codebaseIndexEmbedderProvider: "ollama", codebaseIndexEmbedderBaseUrl: "http://ollama.local", }) const result = await configManager.loadConfiguration() - expect(result.requiresRestart).toBe(false) + // Should require restart because provider changed while enabled + expect(result.requiresRestart).toBe(true) }) it("should not require restart when unconfigured remains unconfigured", async () => { @@ -808,10 +802,10 @@ describe("CodeIndexConfigManager", () => { codebaseIndexQdrantUrl: "http://qdrant.local", codebaseIndexEmbedderProvider: "openai-compatible", codebaseIndexEmbedderModelId: "nomic-embed-code", + codebaseIndexOpenAiCompatibleBaseUrl: "https://api.example.com/v1", // No codebaseIndexSearchMinScore } } - if (key === "codebaseIndexOpenAiCompatibleBaseUrl") return "https://api.example.com/v1" return undefined }) mockContextProxy.getSecret.mockImplementation((key: string) => { @@ -969,7 +963,7 @@ describe("CodeIndexConfigManager", () => { it("should not require restart when API keys transition from undefined to empty string", async () => { // Initial state with undefined API keys mockContextProxy.getGlobalState.mockReturnValue({ - codebaseIndexEnabled: false, // Start disabled to avoid restart due to enable+configure + codebaseIndexEnabled: true, // Always enabled now codebaseIndexQdrantUrl: "http://qdrant.local", codebaseIndexEmbedderProvider: "openai", }) @@ -1207,7 +1201,6 @@ describe("CodeIndexConfigManager", () => { it("should return correct configuration via getConfig", () => { const config = configManager.getConfig() expect(config).toEqual({ - isEnabled: true, isConfigured: true, embedderProvider: "openai", modelId: "text-embedding-3-large", @@ -1266,7 +1259,7 @@ describe("CodeIndexConfigManager", () => { it("should properly initialize with current config to prevent false restarts", async () => { // Setup configuration mockContextProxy.getGlobalState.mockReturnValue({ - codebaseIndexEnabled: false, // Start disabled to avoid transition restart + codebaseIndexEnabled: true, // Always enabled now codebaseIndexQdrantUrl: "http://qdrant.local", codebaseIndexEmbedderProvider: "openai", codebaseIndexEmbedderModelId: "text-embedding-3-small", diff --git a/src/services/code-index/__tests__/manager.spec.ts b/src/services/code-index/__tests__/manager.spec.ts index ae473e3870..82fa9f3c14 100644 --- a/src/services/code-index/__tests__/manager.spec.ts +++ b/src/services/code-index/__tests__/manager.spec.ts @@ -81,7 +81,6 @@ describe("CodeIndexManager - handleSettingsChange regression", () => { isFeatureConfigured: true, isFeatureEnabled: true, getConfig: vi.fn().mockReturnValue({ - isEnabled: true, isConfigured: true, embedderProvider: "openai", modelId: "text-embedding-3-small", @@ -149,7 +148,6 @@ describe("CodeIndexManager - handleSettingsChange regression", () => { isFeatureConfigured: true, isFeatureEnabled: true, getConfig: vi.fn().mockReturnValue({ - isEnabled: true, isConfigured: true, embedderProvider: "openai", modelId: "text-embedding-3-small", @@ -276,7 +274,6 @@ describe("CodeIndexManager - handleSettingsChange regression", () => { isFeatureConfigured: true, isFeatureEnabled: true, getConfig: vitest.fn().mockReturnValue({ - isEnabled: true, isConfigured: true, embedderProvider: "openai", modelId: "text-embedding-3-small", diff --git a/src/services/code-index/__tests__/service-factory.spec.ts b/src/services/code-index/__tests__/service-factory.spec.ts index c2b56a0463..65932225eb 100644 --- a/src/services/code-index/__tests__/service-factory.spec.ts +++ b/src/services/code-index/__tests__/service-factory.spec.ts @@ -146,7 +146,7 @@ describe("CodeIndexServiceFactory", () => { mockConfigManager.getConfig.mockReturnValue(testConfig as any) // Act & Assert - expect(() => factory.createEmbedder()).toThrow("OpenAI configuration missing for embedder creation") + expect(() => factory.createEmbedder()).toThrow("serviceFactory.openAiConfigMissing") }) it("should throw error when Ollama base URL is missing", () => { @@ -161,7 +161,7 @@ describe("CodeIndexServiceFactory", () => { mockConfigManager.getConfig.mockReturnValue(testConfig as any) // Act & Assert - expect(() => factory.createEmbedder()).toThrow("Ollama configuration missing for embedder creation") + expect(() => factory.createEmbedder()).toThrow("serviceFactory.ollamaConfigMissing") }) it("should pass model ID to OpenAI Compatible embedder when using OpenAI Compatible provider", () => { @@ -224,9 +224,7 @@ describe("CodeIndexServiceFactory", () => { mockConfigManager.getConfig.mockReturnValue(testConfig as any) // Act & Assert - expect(() => factory.createEmbedder()).toThrow( - "OpenAI Compatible configuration missing for embedder creation", - ) + expect(() => factory.createEmbedder()).toThrow("serviceFactory.openAiCompatibleConfigMissing") }) it("should throw error when OpenAI Compatible API key is missing", () => { @@ -242,9 +240,7 @@ describe("CodeIndexServiceFactory", () => { mockConfigManager.getConfig.mockReturnValue(testConfig as any) // Act & Assert - expect(() => factory.createEmbedder()).toThrow( - "OpenAI Compatible configuration missing for embedder creation", - ) + expect(() => factory.createEmbedder()).toThrow("serviceFactory.openAiCompatibleConfigMissing") }) it("should throw error when OpenAI Compatible options are missing", () => { @@ -257,9 +253,7 @@ describe("CodeIndexServiceFactory", () => { mockConfigManager.getConfig.mockReturnValue(testConfig as any) // Act & Assert - expect(() => factory.createEmbedder()).toThrow( - "OpenAI Compatible configuration missing for embedder creation", - ) + expect(() => factory.createEmbedder()).toThrow("serviceFactory.openAiCompatibleConfigMissing") }) it("should create GeminiEmbedder when using Gemini provider", () => { @@ -290,7 +284,7 @@ describe("CodeIndexServiceFactory", () => { mockConfigManager.getConfig.mockReturnValue(testConfig as any) // Act & Assert - expect(() => factory.createEmbedder()).toThrow("Gemini configuration missing for embedder creation") + expect(() => factory.createEmbedder()).toThrow("serviceFactory.geminiConfigMissing") }) it("should throw error when Gemini options are missing", () => { @@ -302,7 +296,7 @@ describe("CodeIndexServiceFactory", () => { mockConfigManager.getConfig.mockReturnValue(testConfig as any) // Act & Assert - expect(() => factory.createEmbedder()).toThrow("Gemini configuration missing for embedder creation") + expect(() => factory.createEmbedder()).toThrow("serviceFactory.geminiConfigMissing") }) it("should throw error for invalid embedder provider", () => { @@ -314,7 +308,7 @@ describe("CodeIndexServiceFactory", () => { mockConfigManager.getConfig.mockReturnValue(testConfig as any) // Act & Assert - expect(() => factory.createEmbedder()).toThrow("Invalid embedder type configured: invalid-provider") + expect(() => factory.createEmbedder()).toThrow("serviceFactory.invalidEmbedderType") }) }) @@ -406,8 +400,10 @@ describe("CodeIndexServiceFactory", () => { const testConfig = { embedderProvider: "openai-compatible", modelId: testModelId, + modelDimension: manualDimension, openAiCompatibleOptions: { - modelDimension: manualDimension, + baseUrl: "https://api.example.com/v1", + apiKey: "test-api-key", }, qdrantUrl: "http://localhost:6333", qdrantApiKey: "test-key", @@ -463,8 +459,10 @@ describe("CodeIndexServiceFactory", () => { const testConfig = { embedderProvider: "openai-compatible", modelId: testModelId, + modelDimension: 0, // Invalid dimension openAiCompatibleOptions: { - modelDimension: 0, // Invalid dimension + baseUrl: "https://api.example.com/v1", + apiKey: "test-api-key", }, qdrantUrl: "http://localhost:6333", qdrantApiKey: "test-key", @@ -474,7 +472,7 @@ describe("CodeIndexServiceFactory", () => { // Act & Assert expect(() => factory.createVectorStore()).toThrow( - "Could not determine vector dimension for model 'custom-model' with provider 'openai-compatible'. Please ensure the 'Embedding Dimension' is correctly set in the OpenAI-Compatible provider settings.", + "serviceFactory.vectorDimensionNotDeterminedOpenAiCompatible", ) }) @@ -496,7 +494,7 @@ describe("CodeIndexServiceFactory", () => { // Act & Assert expect(() => factory.createVectorStore()).toThrow( - "Could not determine vector dimension for model 'unknown-model' with provider 'openai-compatible'. Please ensure the 'Embedding Dimension' is correctly set in the OpenAI-Compatible provider settings.", + "serviceFactory.vectorDimensionNotDeterminedOpenAiCompatible", ) }) @@ -560,9 +558,7 @@ describe("CodeIndexServiceFactory", () => { mockGetModelDimension.mockReturnValue(undefined) // Act & Assert - expect(() => factory.createVectorStore()).toThrow( - "Could not determine vector dimension for model 'unknown-model' with provider 'openai'. Check model profiles or configuration.", - ) + expect(() => factory.createVectorStore()).toThrow("serviceFactory.vectorDimensionNotDetermined") }) it("should throw error when Qdrant URL is missing", () => { @@ -577,7 +573,7 @@ describe("CodeIndexServiceFactory", () => { mockGetModelDimension.mockReturnValue(1536) // Act & Assert - expect(() => factory.createVectorStore()).toThrow("Qdrant URL missing for vector store creation") + expect(() => factory.createVectorStore()).toThrow("serviceFactory.qdrantUrlMissing") }) }) @@ -747,7 +743,7 @@ describe("CodeIndexServiceFactory", () => { await expect(async () => { const embedder = factory.createEmbedder() await factory.validateEmbedder(embedder) - }).rejects.toThrow("OpenAI configuration missing for embedder creation") + }).rejects.toThrow("serviceFactory.openAiConfigMissing") }) it("should return error for unknown embedder provider", async () => { @@ -760,7 +756,7 @@ describe("CodeIndexServiceFactory", () => { // Act & Assert // This should throw when trying to create the embedder - expect(() => factory.createEmbedder()).toThrow("Invalid embedder type configured: unknown-provider") + expect(() => factory.createEmbedder()).toThrow("serviceFactory.invalidEmbedderType") }) }) }) diff --git a/src/services/code-index/config-manager.ts b/src/services/code-index/config-manager.ts index 26ea0e2a48..245621a1bd 100644 --- a/src/services/code-index/config-manager.ts +++ b/src/services/code-index/config-manager.ts @@ -10,12 +10,12 @@ import { getDefaultModelId, getModelDimension, getModelScoreThreshold } from ".. * Handles loading, validating, and providing access to configuration values. */ export class CodeIndexConfigManager { - private isEnabled: boolean = false private embedderProvider: EmbedderProvider = "openai" private modelId?: string + private modelDimension?: number private openAiOptions?: ApiHandlerOptions private ollamaOptions?: ApiHandlerOptions - private openAiCompatibleOptions?: { baseUrl: string; apiKey: string; modelDimension?: number } + private openAiCompatibleOptions?: { baseUrl: string; apiKey: string } private geminiOptions?: { apiKey: string } private qdrantUrl?: string = "http://localhost:6333" private qdrantApiKey?: string @@ -41,7 +41,7 @@ export class CodeIndexConfigManager { private _loadAndSetConfiguration(): void { // Load configuration from storage const codebaseIndexConfig = this.contextProxy?.getGlobalState("codebaseIndexConfig") ?? { - codebaseIndexEnabled: false, + codebaseIndexEnabled: true, codebaseIndexQdrantUrl: "http://localhost:6333", codebaseIndexEmbedderProvider: "openai", codebaseIndexEmbedderBaseUrl: "", @@ -65,17 +65,31 @@ export class CodeIndexConfigManager { // Fix: Read OpenAI Compatible settings from the correct location within codebaseIndexConfig const openAiCompatibleBaseUrl = codebaseIndexConfig.codebaseIndexOpenAiCompatibleBaseUrl ?? "" const openAiCompatibleApiKey = this.contextProxy?.getSecret("codebaseIndexOpenAiCompatibleApiKey") ?? "" - const openAiCompatibleModelDimension = codebaseIndexConfig.codebaseIndexOpenAiCompatibleModelDimension as - | number - | undefined const geminiApiKey = this.contextProxy?.getSecret("codebaseIndexGeminiApiKey") ?? "" // Update instance variables with configuration - this.isEnabled = codebaseIndexEnabled || false + // Note: codebaseIndexEnabled is no longer used as the feature is always enabled this.qdrantUrl = codebaseIndexQdrantUrl this.qdrantApiKey = qdrantApiKey ?? "" this.searchMinScore = codebaseIndexSearchMinScore this.searchMaxResults = codebaseIndexSearchMaxResults + + // Validate and set model dimension + const rawDimension = codebaseIndexConfig.codebaseIndexEmbedderModelDimension + if (rawDimension !== undefined && rawDimension !== null) { + const dimension = Number(rawDimension) + if (!isNaN(dimension) && dimension > 0) { + this.modelDimension = dimension + } else { + console.warn( + `Invalid codebaseIndexEmbedderModelDimension value: ${rawDimension}. Must be a positive number.`, + ) + this.modelDimension = undefined + } + } else { + this.modelDimension = undefined + } + this.openAiOptions = { openAiNativeApiKey: openAiKey } // Set embedder provider with support for openai-compatible @@ -100,7 +114,6 @@ export class CodeIndexConfigManager { ? { baseUrl: openAiCompatibleBaseUrl, apiKey: openAiCompatibleApiKey, - modelDimension: openAiCompatibleModelDimension, } : undefined @@ -113,10 +126,10 @@ export class CodeIndexConfigManager { public async loadConfiguration(): Promise<{ configSnapshot: PreviousConfigSnapshot currentConfig: { - isEnabled: boolean isConfigured: boolean embedderProvider: EmbedderProvider modelId?: string + modelDimension?: number openAiOptions?: ApiHandlerOptions ollamaOptions?: ApiHandlerOptions openAiCompatibleOptions?: { baseUrl: string; apiKey: string } @@ -129,15 +142,15 @@ export class CodeIndexConfigManager { }> { // Capture the ACTUAL previous state before loading new configuration const previousConfigSnapshot: PreviousConfigSnapshot = { - enabled: this.isEnabled, + enabled: true, // Feature is always enabled configured: this.isConfigured(), embedderProvider: this.embedderProvider, modelId: this.modelId, + modelDimension: this.modelDimension, openAiKey: this.openAiOptions?.openAiNativeApiKey ?? "", ollamaBaseUrl: this.ollamaOptions?.ollamaBaseUrl ?? "", openAiCompatibleBaseUrl: this.openAiCompatibleOptions?.baseUrl ?? "", openAiCompatibleApiKey: this.openAiCompatibleOptions?.apiKey ?? "", - openAiCompatibleModelDimension: this.openAiCompatibleOptions?.modelDimension, geminiApiKey: this.geminiOptions?.apiKey ?? "", qdrantUrl: this.qdrantUrl ?? "", qdrantApiKey: this.qdrantApiKey ?? "", @@ -154,10 +167,10 @@ export class CodeIndexConfigManager { return { configSnapshot: previousConfigSnapshot, currentConfig: { - isEnabled: this.isEnabled, isConfigured: this.isConfigured(), embedderProvider: this.embedderProvider, modelId: this.modelId, + modelDimension: this.modelDimension, openAiOptions: this.openAiOptions, ollamaOptions: this.ollamaOptions, openAiCompatibleOptions: this.openAiCompatibleOptions, @@ -225,73 +238,67 @@ export class CodeIndexConfigManager { const prevOllamaBaseUrl = prev?.ollamaBaseUrl ?? "" const prevOpenAiCompatibleBaseUrl = prev?.openAiCompatibleBaseUrl ?? "" const prevOpenAiCompatibleApiKey = prev?.openAiCompatibleApiKey ?? "" - const prevOpenAiCompatibleModelDimension = prev?.openAiCompatibleModelDimension + const prevModelDimension = prev?.modelDimension const prevGeminiApiKey = prev?.geminiApiKey ?? "" const prevQdrantUrl = prev?.qdrantUrl ?? "" const prevQdrantApiKey = prev?.qdrantApiKey ?? "" - // 1. Transition from disabled/unconfigured to enabled+configured - if ((!prevEnabled || !prevConfigured) && this.isEnabled && nowConfigured) { + // 1. Transition from unconfigured to configured + // Since the feature is always enabled, we only check configuration status + if (!prevConfigured && nowConfigured) { return true } - // 2. If was disabled and still is, no restart needed - if (!prevEnabled && !this.isEnabled) { - return false - } - // 3. If wasn't ready before and isn't ready now, no restart needed if (!prevConfigured && !nowConfigured) { return false } // 4. CRITICAL CHANGES - Always restart for these - if (this.isEnabled || prevEnabled) { - // Provider change - if (prevProvider !== this.embedderProvider) { - return true - } + // Since feature is always enabled, we always check for critical changes - // Authentication changes (API keys) - const currentOpenAiKey = this.openAiOptions?.openAiNativeApiKey ?? "" - const currentOllamaBaseUrl = this.ollamaOptions?.ollamaBaseUrl ?? "" - const currentOpenAiCompatibleBaseUrl = this.openAiCompatibleOptions?.baseUrl ?? "" - const currentOpenAiCompatibleApiKey = this.openAiCompatibleOptions?.apiKey ?? "" - const currentOpenAiCompatibleModelDimension = this.openAiCompatibleOptions?.modelDimension - const currentGeminiApiKey = this.geminiOptions?.apiKey ?? "" - const currentQdrantUrl = this.qdrantUrl ?? "" - const currentQdrantApiKey = this.qdrantApiKey ?? "" + // Provider change + if (prevProvider !== this.embedderProvider) { + return true + } - if (prevOpenAiKey !== currentOpenAiKey) { - return true - } + // Authentication changes (API keys) + const currentOpenAiKey = this.openAiOptions?.openAiNativeApiKey ?? "" + const currentOllamaBaseUrl = this.ollamaOptions?.ollamaBaseUrl ?? "" + const currentOpenAiCompatibleBaseUrl = this.openAiCompatibleOptions?.baseUrl ?? "" + const currentOpenAiCompatibleApiKey = this.openAiCompatibleOptions?.apiKey ?? "" + const currentModelDimension = this.modelDimension + const currentGeminiApiKey = this.geminiOptions?.apiKey ?? "" + const currentQdrantUrl = this.qdrantUrl ?? "" + const currentQdrantApiKey = this.qdrantApiKey ?? "" - if (prevOllamaBaseUrl !== currentOllamaBaseUrl) { - return true - } + if (prevOpenAiKey !== currentOpenAiKey) { + return true + } - if ( - prevOpenAiCompatibleBaseUrl !== currentOpenAiCompatibleBaseUrl || - prevOpenAiCompatibleApiKey !== currentOpenAiCompatibleApiKey - ) { - return true - } + if (prevOllamaBaseUrl !== currentOllamaBaseUrl) { + return true + } - // Check for OpenAI Compatible modelDimension changes - if (this.embedderProvider === "openai-compatible" || prevProvider === "openai-compatible") { - if (prevOpenAiCompatibleModelDimension !== currentOpenAiCompatibleModelDimension) { - return true - } - } + if ( + prevOpenAiCompatibleBaseUrl !== currentOpenAiCompatibleBaseUrl || + prevOpenAiCompatibleApiKey !== currentOpenAiCompatibleApiKey + ) { + return true + } - if (prevQdrantUrl !== currentQdrantUrl || prevQdrantApiKey !== currentQdrantApiKey) { - return true - } + // Check for model dimension changes (generic for all providers) + if (prevModelDimension !== currentModelDimension) { + return true + } - // Vector dimension changes (still important for compatibility) - if (this._hasVectorDimensionChanged(prevProvider, prev?.modelId)) { - return true - } + if (prevQdrantUrl !== currentQdrantUrl || prevQdrantApiKey !== currentQdrantApiKey) { + return true + } + + // Vector dimension changes (still important for compatibility) + if (this._hasVectorDimensionChanged(prevProvider, prev?.modelId)) { + return true } return false @@ -328,10 +335,10 @@ export class CodeIndexConfigManager { */ public getConfig(): CodeIndexConfig { return { - isEnabled: this.isEnabled, isConfigured: this.isConfigured(), embedderProvider: this.embedderProvider, modelId: this.modelId, + modelDimension: this.modelDimension, openAiOptions: this.openAiOptions, ollamaOptions: this.ollamaOptions, openAiCompatibleOptions: this.openAiCompatibleOptions, @@ -347,7 +354,7 @@ export class CodeIndexConfigManager { * Gets whether the code indexing feature is enabled */ public get isFeatureEnabled(): boolean { - return this.isEnabled + return true } /** @@ -381,6 +388,14 @@ export class CodeIndexConfigManager { return this.modelId } + /** + * Gets the current model dimension being used for embeddings. + * Returns the explicitly configured dimension or undefined if not set. + */ + public get currentModelDimension(): number | undefined { + return this.modelDimension + } + /** * Gets the configured minimum search score based on user setting, model-specific threshold, or fallback. * Priority: 1) User setting, 2) Model-specific threshold, 3) Default DEFAULT_SEARCH_MIN_SCORE constant. diff --git a/src/services/code-index/embedders/__tests__/ollama.spec.ts b/src/services/code-index/embedders/__tests__/ollama.spec.ts index 30e6057388..7d625a83fe 100644 --- a/src/services/code-index/embedders/__tests__/ollama.spec.ts +++ b/src/services/code-index/embedders/__tests__/ollama.spec.ts @@ -127,7 +127,7 @@ describe("CodeIndexOllamaEmbedder", () => { const result = await embedder.validateConfiguration() expect(result.valid).toBe(false) - expect(result.error).toBe("Connection to Ollama timed out at http://localhost:11434") + expect(result.error).toBe("embeddings:ollama.serviceNotRunning") }) it("should fail validation when tags endpoint returns 404", async () => { @@ -141,9 +141,7 @@ describe("CodeIndexOllamaEmbedder", () => { const result = await embedder.validateConfiguration() expect(result.valid).toBe(false) - expect(result.error).toBe( - "Ollama service is not running at http://localhost:11434. Please start Ollama first.", - ) + expect(result.error).toBe("embeddings:ollama.serviceNotRunning") }) it("should fail validation when tags endpoint returns other error", async () => { @@ -157,7 +155,7 @@ describe("CodeIndexOllamaEmbedder", () => { const result = await embedder.validateConfiguration() expect(result.valid).toBe(false) - expect(result.error).toBe("Ollama service is unavailable at http://localhost:11434. HTTP status: 500") + expect(result.error).toBe("embeddings:ollama.serviceUnavailable") }) it("should fail validation when model does not exist", async () => { @@ -176,9 +174,7 @@ describe("CodeIndexOllamaEmbedder", () => { const result = await embedder.validateConfiguration() expect(result.valid).toBe(false) - expect(result.error).toBe( - "Model 'nomic-embed-text' not found. Available models: llama2:latest, mistral:latest", - ) + expect(result.error).toBe("embeddings:ollama.modelNotFound") }) it("should fail validation when model exists but doesn't support embeddings", async () => { @@ -205,7 +201,7 @@ describe("CodeIndexOllamaEmbedder", () => { const result = await embedder.validateConfiguration() expect(result.valid).toBe(false) - expect(result.error).toBe("Model 'nomic-embed-text' is not embedding capable") + expect(result.error).toBe("embeddings:ollama.modelNotEmbeddingCapable") }) it("should handle ECONNREFUSED errors", async () => { @@ -214,7 +210,7 @@ describe("CodeIndexOllamaEmbedder", () => { const result = await embedder.validateConfiguration() expect(result.valid).toBe(false) - expect(result.error).toBe("Connection to Ollama timed out at http://localhost:11434") + expect(result.error).toBe("embeddings:ollama.serviceNotRunning") }) it("should handle ENOTFOUND errors", async () => { @@ -223,7 +219,7 @@ describe("CodeIndexOllamaEmbedder", () => { const result = await embedder.validateConfiguration() expect(result.valid).toBe(false) - expect(result.error).toBe("Ollama host not found: http://localhost:11434") + expect(result.error).toBe("embeddings:ollama.hostNotFound") }) it("should handle generic network errors", async () => { diff --git a/src/services/code-index/embedders/ollama.ts b/src/services/code-index/embedders/ollama.ts index f9001a743e..8b7ad79d7b 100644 --- a/src/services/code-index/embedders/ollama.ts +++ b/src/services/code-index/embedders/ollama.ts @@ -56,6 +56,11 @@ export class CodeIndexOllamaEmbedder implements IEmbedder { try { // Note: Standard Ollama API uses 'prompt' for single text, not 'input' for array. // Implementing based on user's specific request structure. + + // Add timeout to prevent indefinite hanging + const controller = new AbortController() + const timeoutId = setTimeout(() => controller.abort(), 10000) // 10 second timeout + const response = await fetch(url, { method: "POST", headers: { @@ -65,7 +70,9 @@ export class CodeIndexOllamaEmbedder implements IEmbedder { model: modelToUse, input: processedTexts, // Using 'input' as requested }), + signal: controller.signal, }) + clearTimeout(timeoutId) if (!response.ok) { let errorBody = t("embeddings:ollama.couldNotReadErrorBody") @@ -97,6 +104,16 @@ export class CodeIndexOllamaEmbedder implements IEmbedder { } catch (error: any) { // Log the original error for debugging purposes console.error("Ollama embedding failed:", error) + + // Handle specific error types with better messages + if (error.name === "AbortError") { + throw new Error(t("embeddings:validation.connectionFailed")) + } else if (error.message?.includes("fetch failed") || error.code === "ECONNREFUSED") { + throw new Error(t("embeddings:ollama.serviceNotRunning", { baseUrl: this.baseUrl })) + } else if (error.code === "ENOTFOUND") { + throw new Error(t("embeddings:ollama.hostNotFound", { baseUrl: this.baseUrl })) + } + // Re-throw a more specific error for the caller throw new Error(t("embeddings:ollama.embeddingFailed", { message: error.message })) } @@ -129,12 +146,12 @@ export class CodeIndexOllamaEmbedder implements IEmbedder { if (modelsResponse.status === 404) { return { valid: false, - error: t("embeddings:errors.ollama.serviceNotRunning", { baseUrl: this.baseUrl }), + error: t("embeddings:ollama.serviceNotRunning", { baseUrl: this.baseUrl }), } } return { valid: false, - error: t("embeddings:errors.ollama.serviceUnavailable", { + error: t("embeddings:ollama.serviceUnavailable", { baseUrl: this.baseUrl, status: modelsResponse.status, }), @@ -159,8 +176,8 @@ export class CodeIndexOllamaEmbedder implements IEmbedder { const availableModels = models.map((m: any) => m.name).join(", ") return { valid: false, - error: t("embeddings:errors.ollama.modelNotFound", { - model: this.defaultModelId, + error: t("embeddings:ollama.modelNotFound", { + modelId: this.defaultModelId, availableModels, }), } @@ -189,7 +206,7 @@ export class CodeIndexOllamaEmbedder implements IEmbedder { if (!testResponse.ok) { return { valid: false, - error: t("embeddings:errors.ollama.modelNotEmbedding", { model: this.defaultModelId }), + error: t("embeddings:ollama.modelNotEmbeddingCapable", { modelId: this.defaultModelId }), } } @@ -199,21 +216,26 @@ export class CodeIndexOllamaEmbedder implements IEmbedder { { beforeStandardHandling: (error: any) => { // Handle Ollama-specific connection errors - if (error?.message === "ECONNREFUSED") { + // Check for fetch failed errors which indicate Ollama is not running + if ( + error?.message?.includes("fetch failed") || + error?.code === "ECONNREFUSED" || + error?.message?.includes("ECONNREFUSED") + ) { return { valid: false, - error: t("embeddings:errors.ollama.connectionTimeout", { baseUrl: this.baseUrl }), + error: t("embeddings:ollama.serviceNotRunning", { baseUrl: this.baseUrl }), } - } else if (error?.message === "ENOTFOUND") { + } else if (error?.code === "ENOTFOUND" || error?.message?.includes("ENOTFOUND")) { return { valid: false, - error: t("embeddings:errors.ollama.hostNotFound", { baseUrl: this.baseUrl }), + error: t("embeddings:ollama.hostNotFound", { baseUrl: this.baseUrl }), } } else if (error?.name === "AbortError") { // Handle timeout return { valid: false, - error: t("embeddings:errors.ollama.connectionTimeout", { baseUrl: this.baseUrl }), + error: t("embeddings:validation.connectionFailed"), } } // Let standard handling take over diff --git a/src/services/code-index/interfaces/config.ts b/src/services/code-index/interfaces/config.ts index 0600f29c2a..190a23e2a3 100644 --- a/src/services/code-index/interfaces/config.ts +++ b/src/services/code-index/interfaces/config.ts @@ -5,13 +5,13 @@ import { EmbedderProvider } from "./manager" * Configuration state for the code indexing feature */ export interface CodeIndexConfig { - isEnabled: boolean isConfigured: boolean embedderProvider: EmbedderProvider modelId?: string + modelDimension?: number // Generic dimension property for all providers openAiOptions?: ApiHandlerOptions ollamaOptions?: ApiHandlerOptions - openAiCompatibleOptions?: { baseUrl: string; apiKey: string; modelDimension?: number } + openAiCompatibleOptions?: { baseUrl: string; apiKey: string } geminiOptions?: { apiKey: string } qdrantUrl?: string qdrantApiKey?: string @@ -27,11 +27,11 @@ export type PreviousConfigSnapshot = { configured: boolean embedderProvider: EmbedderProvider modelId?: string + modelDimension?: number // Generic dimension property openAiKey?: string ollamaBaseUrl?: string openAiCompatibleBaseUrl?: string openAiCompatibleApiKey?: string - openAiCompatibleModelDimension?: number geminiApiKey?: string qdrantUrl?: string qdrantApiKey?: string diff --git a/src/services/code-index/service-factory.ts b/src/services/code-index/service-factory.ts index a9c84481a6..818dafb497 100644 --- a/src/services/code-index/service-factory.ts +++ b/src/services/code-index/service-factory.ts @@ -10,6 +10,7 @@ import { ICodeParser, IEmbedder, IFileWatcher, IVectorStore } from "./interfaces import { CodeIndexConfigManager } from "./config-manager" import { CacheManager } from "./cache-manager" import { Ignore } from "ignore" +import { t } from "../../i18n" /** * Factory class responsible for creating and configuring code indexing service dependencies. @@ -33,7 +34,7 @@ export class CodeIndexServiceFactory { const apiKey = config.openAiOptions?.openAiNativeApiKey if (!apiKey) { - throw new Error("OpenAI configuration missing for embedder creation") + throw new Error(t("embeddings:serviceFactory.openAiConfigMissing")) } return new OpenAiEmbedder({ ...config.openAiOptions, @@ -41,7 +42,7 @@ export class CodeIndexServiceFactory { }) } else if (provider === "ollama") { if (!config.ollamaOptions?.ollamaBaseUrl) { - throw new Error("Ollama configuration missing for embedder creation") + throw new Error(t("embeddings:serviceFactory.ollamaConfigMissing")) } return new CodeIndexOllamaEmbedder({ ...config.ollamaOptions, @@ -49,7 +50,7 @@ export class CodeIndexServiceFactory { }) } else if (provider === "openai-compatible") { if (!config.openAiCompatibleOptions?.baseUrl || !config.openAiCompatibleOptions?.apiKey) { - throw new Error("OpenAI Compatible configuration missing for embedder creation") + throw new Error(t("embeddings:serviceFactory.openAiCompatibleConfigMissing")) } return new OpenAICompatibleEmbedder( config.openAiCompatibleOptions.baseUrl, @@ -58,12 +59,14 @@ export class CodeIndexServiceFactory { ) } else if (provider === "gemini") { if (!config.geminiOptions?.apiKey) { - throw new Error("Gemini configuration missing for embedder creation") + throw new Error(t("embeddings:serviceFactory.geminiConfigMissing")) } return new GeminiEmbedder(config.geminiOptions.apiKey) } - throw new Error(`Invalid embedder type configured: ${config.embedderProvider}`) + throw new Error( + t("embeddings:serviceFactory.invalidEmbedderType", { embedderProvider: config.embedderProvider }), + ) } /** @@ -96,33 +99,29 @@ export class CodeIndexServiceFactory { let vectorSize: number | undefined - if (provider === "openai-compatible") { - if (config.openAiCompatibleOptions?.modelDimension && config.openAiCompatibleOptions.modelDimension > 0) { - vectorSize = config.openAiCompatibleOptions.modelDimension - } else { - // Fallback if not provided or invalid in openAiCompatibleOptions - vectorSize = getModelDimension(provider, modelId) - } + // First check if a manual dimension is provided (works for all providers) + if (config.modelDimension && config.modelDimension > 0) { + vectorSize = config.modelDimension } else if (provider === "gemini") { // Gemini's text-embedding-004 has a fixed dimension of 768 vectorSize = 768 } else { + // Fall back to model-specific dimension from profiles vectorSize = getModelDimension(provider, modelId) } - if (vectorSize === undefined) { - let errorMessage = `Could not determine vector dimension for model '${modelId}' with provider '${provider}'. ` + if (vectorSize === undefined || vectorSize <= 0) { if (provider === "openai-compatible") { - errorMessage += `Please ensure the 'Embedding Dimension' is correctly set in the OpenAI-Compatible provider settings.` + throw new Error( + t("embeddings:serviceFactory.vectorDimensionNotDeterminedOpenAiCompatible", { modelId, provider }), + ) } else { - errorMessage += `Check model profiles or configuration.` + throw new Error(t("embeddings:serviceFactory.vectorDimensionNotDetermined", { modelId, provider })) } - throw new Error(errorMessage) } if (!config.qdrantUrl) { - // This check remains important - throw new Error("Qdrant URL missing for vector store creation") + throw new Error(t("embeddings:serviceFactory.qdrantUrlMissing")) } // Assuming constructor is updated: new QdrantVectorStore(workspacePath, url, vectorSize, apiKey?) @@ -170,7 +169,7 @@ export class CodeIndexServiceFactory { fileWatcher: IFileWatcher } { if (!this.configManager.isFeatureConfigured) { - throw new Error("Cannot create services: Code indexing is not properly configured") + throw new Error(t("embeddings:serviceFactory.codeIndexingNotConfigured")) } const embedder = this.createEmbedder() diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 312b7ceb11..fa9fb67310 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -241,8 +241,8 @@ export interface WebviewMessage { codebaseIndexEmbedderProvider: "openai" | "ollama" | "openai-compatible" | "gemini" codebaseIndexEmbedderBaseUrl?: string codebaseIndexEmbedderModelId: string + codebaseIndexEmbedderModelDimension?: number // Generic dimension for all providers codebaseIndexOpenAiCompatibleBaseUrl?: string - codebaseIndexOpenAiCompatibleModelDimension?: number codebaseIndexSearchMaxResults?: number codebaseIndexSearchMinScore?: number diff --git a/src/shared/__tests__/modes-empty-prompt-component.spec.ts b/src/shared/__tests__/modes-empty-prompt-component.spec.ts new file mode 100644 index 0000000000..5af93cb5d9 --- /dev/null +++ b/src/shared/__tests__/modes-empty-prompt-component.spec.ts @@ -0,0 +1,97 @@ +import { describe, it, expect } from "vitest" +import { getModeSelection, modes } from "../modes" +import type { PromptComponent } from "@roo-code/types" + +describe("getModeSelection with empty promptComponent", () => { + it("should use built-in mode instructions when promptComponent is undefined", () => { + const architectMode = modes.find((m) => m.slug === "architect")! + + // Test with undefined promptComponent (which is what getPromptComponent returns for empty objects) + const result = getModeSelection("architect", undefined, []) + + // Should use built-in mode values + expect(result.roleDefinition).toBe(architectMode.roleDefinition) + expect(result.baseInstructions).toBe(architectMode.customInstructions) + expect(result.baseInstructions).toContain("Do some information gathering") + }) + + it("should use built-in mode instructions when promptComponent is null", () => { + const debugMode = modes.find((m) => m.slug === "debug")! + + // Test with null promptComponent + const result = getModeSelection("debug", null as any, []) + + // Should use built-in mode values + expect(result.roleDefinition).toBe(debugMode.roleDefinition) + expect(result.baseInstructions).toBe(debugMode.customInstructions) + expect(result.baseInstructions).toContain("Reflect on 5-7 different possible sources") + }) + + it("should use promptComponent when it has actual content", () => { + // Test with promptComponent that has actual content + const validPromptComponent: PromptComponent = { + roleDefinition: "Custom role", + customInstructions: "Custom instructions", + } + const result = getModeSelection("architect", validPromptComponent, []) + + // Should use promptComponent values + expect(result.roleDefinition).toBe("Custom role") + expect(result.baseInstructions).toBe("Custom instructions") + }) + + it("should merge promptComponent with built-in mode when it has partial content", () => { + const architectMode = modes.find((m) => m.slug === "architect")! + + // Test with promptComponent that only has customInstructions + const partialPromptComponent: PromptComponent = { + customInstructions: "Only custom instructions", + } + const result = getModeSelection("architect", partialPromptComponent, []) + + // Should merge: use promptComponent's customInstructions but fall back to built-in roleDefinition + expect(result.roleDefinition).toBe(architectMode.roleDefinition) // Falls back to built-in + expect(result.baseInstructions).toBe("Only custom instructions") // Uses promptComponent + }) + + it("should merge promptComponent with built-in mode when it only has roleDefinition", () => { + const debugMode = modes.find((m) => m.slug === "debug")! + + // Test with promptComponent that only has roleDefinition + const partialPromptComponent: PromptComponent = { + roleDefinition: "Custom debug role", + } + const result = getModeSelection("debug", partialPromptComponent, []) + + // Should merge: use promptComponent's roleDefinition but fall back to built-in customInstructions + expect(result.roleDefinition).toBe("Custom debug role") // Uses promptComponent + expect(result.baseInstructions).toBe(debugMode.customInstructions) // Falls back to built-in + }) + + it("should handle promptComponent with both roleDefinition and customInstructions", () => { + // Test with promptComponent that has both properties + const fullPromptComponent: PromptComponent = { + roleDefinition: "Full custom role", + customInstructions: "Full custom instructions", + } + const result = getModeSelection("architect", fullPromptComponent, []) + + // Should use promptComponent values for both + expect(result.roleDefinition).toBe("Full custom role") + expect(result.baseInstructions).toBe("Full custom instructions") + }) + + it("should fall back to default mode when built-in mode is not found", () => { + const defaultMode = modes[0] // First mode is the default + + // Test with non-existent mode + const partialPromptComponent: PromptComponent = { + customInstructions: "Custom instructions for unknown mode", + } + const result = getModeSelection("non-existent-mode", partialPromptComponent, []) + + // Should merge with default mode + expect(result.roleDefinition).toBe(defaultMode.roleDefinition) // Falls back to default mode + expect(result.baseInstructions).toBe("Custom instructions for unknown mode") // Uses promptComponent + }) +}) diff --git a/src/shared/__tests__/modes.spec.ts b/src/shared/__tests__/modes.spec.ts index acf7da84c8..52e4424d8d 100644 --- a/src/shared/__tests__/modes.spec.ts +++ b/src/shared/__tests__/modes.spec.ts @@ -245,6 +245,112 @@ describe("isToolAllowedForMode", () => { expect(isToolAllowedForMode("browser_action", "architect", [])).toBe(true) expect(isToolAllowedForMode("use_mcp_tool", "architect", [])).toBe(true) }) + + it("applies restrictions to all edit tools including search_and_replace and insert_content", () => { + // Test search_and_replace with matching file + expect( + isToolAllowedForMode("search_and_replace", "architect", [], undefined, { + path: "test.md", + search: "old text", + replace: "new text", + }), + ).toBe(true) + + // Test insert_content with matching file + expect( + isToolAllowedForMode("insert_content", "architect", [], undefined, { + path: "test.md", + line: "1", + content: "# New content", + }), + ).toBe(true) + + // Test search_and_replace with non-matching file - should throw error + expect(() => + isToolAllowedForMode("search_and_replace", "architect", [], undefined, { + path: "test.py", + search: "old text", + replace: "new text", + }), + ).toThrow(FileRestrictionError) + expect(() => + isToolAllowedForMode("search_and_replace", "architect", [], undefined, { + path: "test.py", + search: "old text", + replace: "new text", + }), + ).toThrow(/Markdown files only/) + + // Test insert_content with non-matching file - should throw error + expect(() => + isToolAllowedForMode("insert_content", "architect", [], undefined, { + path: "test.py", + line: "1", + content: "print('hello')", + }), + ).toThrow(FileRestrictionError) + expect(() => + isToolAllowedForMode("insert_content", "architect", [], undefined, { + path: "test.py", + line: "1", + content: "print('hello')", + }), + ).toThrow(/Markdown files only/) + }) + + it("applies restrictions to apply_diff with concurrent file edits (MULTI_FILE_APPLY_DIFF experiment)", () => { + // Test apply_diff with args parameter (used when MULTI_FILE_APPLY_DIFF experiment is enabled) + // This simulates concurrent/batch file editing + const xmlArgs = + "test.md- old content\\n+ new content" + + // Should allow markdown files in architect mode + expect( + isToolAllowedForMode("apply_diff", "architect", [], undefined, { + args: xmlArgs, + }), + ).toBe(true) + + // Test with non-markdown file - should throw error + const xmlArgsNonMd = + "test.py- old content\\n+ new content" + + expect(() => + isToolAllowedForMode("apply_diff", "architect", [], undefined, { + args: xmlArgsNonMd, + }), + ).toThrow(FileRestrictionError) + expect(() => + isToolAllowedForMode("apply_diff", "architect", [], undefined, { + args: xmlArgsNonMd, + }), + ).toThrow(/Markdown files only/) + + // Test with multiple files - should allow only markdown files + const xmlArgsMultiple = + "readme.md- old content\\n+ new contentdocs.md- old content\\n+ new content" + + expect( + isToolAllowedForMode("apply_diff", "architect", [], undefined, { + args: xmlArgsMultiple, + }), + ).toBe(true) + + // Test with mixed file types - should throw error for non-markdown + const xmlArgsMixed = + "readme.md- old content\\n+ new contentscript.py- old content\\n+ new content" + + expect(() => + isToolAllowedForMode("apply_diff", "architect", [], undefined, { + args: xmlArgsMixed, + }), + ).toThrow(FileRestrictionError) + expect(() => + isToolAllowedForMode("apply_diff", "architect", [], undefined, { + args: xmlArgsMixed, + }), + ).toThrow(/Markdown files only/) + }) }) it("handles non-existent modes", () => { @@ -269,6 +375,14 @@ describe("FileRestrictionError", () => { expect(error.name).toBe("FileRestrictionError") }) + it("formats error message with tool name when provided", () => { + const error = new FileRestrictionError("Markdown Editor", "\\.md$", undefined, "test.js", "write_to_file") + expect(error.message).toBe( + "Tool 'write_to_file' in mode 'Markdown Editor' can only edit files matching pattern: \\.md$. Got: test.js", + ) + expect(error.name).toBe("FileRestrictionError") + }) + describe("debug mode", () => { it("is configured correctly", () => { const debugMode = modes.find((mode) => mode.slug === "debug") @@ -368,6 +482,20 @@ describe("FileRestrictionError", () => { ) expect(error.name).toBe("FileRestrictionError") }) + + it("formats error message with both tool name and description when provided", () => { + const error = new FileRestrictionError( + "Markdown Editor", + "\\.md$", + "Markdown files only", + "test.js", + "apply_diff", + ) + expect(error.message).toBe( + "Tool 'apply_diff' in mode 'Markdown Editor' can only edit files matching pattern: \\.md$ (Markdown files only). Got: test.js", + ) + expect(error.name).toBe("FileRestrictionError") + }) }) describe("getModeSelection", () => { @@ -443,10 +571,11 @@ describe("getModeSelection", () => { expect(selection.baseInstructions).toBe(newCustomMode.customInstructions) }) - test("should return empty strings if slug does not exist in custom, prompt, or built-in modes", () => { + test("should fall back to default mode if slug does not exist in custom, prompt, or built-in modes", () => { const selection = getModeSelection("non-existent-mode", undefined, customModesList) - expect(selection.roleDefinition).toBe("") - expect(selection.baseInstructions).toBe("") + const defaultMode = modes[0] // First mode is the default + expect(selection.roleDefinition).toBe(defaultMode.roleDefinition) + expect(selection.baseInstructions).toBe(defaultMode.customInstructions || "") }) test("customMode's properties are used if customMode exists, ignoring promptComponent's properties", () => { diff --git a/src/shared/modes.ts b/src/shared/modes.ts index 23efdc45f7..4666a85d6d 100644 --- a/src/shared/modes.ts +++ b/src/shared/modes.ts @@ -72,7 +72,7 @@ export const modes: readonly ModeConfig[] = [ description: "Plan and design before implementation", groups: ["read", ["edit", { fileRegex: "\\.md$", description: "Markdown files only" }], "browser", "mcp"], customInstructions: - "1. Do some information gathering (for example using read_file or search_files) 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, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.\n\n4. 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 plan the best way to accomplish it.\n\n5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.\n\n**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**", + "1. Do some information gathering (for example using read_file or search_files) 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\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. Include Mermaid diagrams if they help clarify complex workflows or system architecture.\n\n6. 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", @@ -183,31 +183,41 @@ export function findModeBySlug(slug: string, modes: readonly ModeConfig[] | unde /** * Get the mode selection based on the provided mode slug, prompt component, and custom modes. * If a custom mode is found, it takes precedence over the built-in modes. - * If no custom mode is found, the built-in mode is used. + * If no custom mode is found, the built-in mode is used with partial merging from promptComponent. * If neither is found, the default mode is used. */ export function getModeSelection(mode: string, promptComponent?: PromptComponent, customModes?: ModeConfig[]) { const customMode = findModeBySlug(mode, customModes) const builtInMode = findModeBySlug(mode, modes) - const modeToUse = customMode || promptComponent || builtInMode + // If we have a custom mode, use it entirely + if (customMode) { + return { + roleDefinition: customMode.roleDefinition || "", + baseInstructions: customMode.customInstructions || "", + description: customMode.description || "", + } + } - const roleDefinition = modeToUse?.roleDefinition || "" - const baseInstructions = modeToUse?.customInstructions || "" - const description = (customMode || builtInMode)?.description || "" + // Otherwise, use built-in mode as base and merge with promptComponent + const baseMode = builtInMode || modes[0] // fallback to default mode return { - roleDefinition, - baseInstructions, - description, + roleDefinition: promptComponent?.roleDefinition || baseMode.roleDefinition || "", + baseInstructions: promptComponent?.customInstructions || baseMode.customInstructions || "", + description: baseMode.description || "", } } +// Edit operation parameters that indicate an actual edit operation +const EDIT_OPERATION_PARAMS = ["diff", "content", "operations", "search", "replace", "args", "line"] as const + // Custom error class for file restrictions export class FileRestrictionError extends Error { - constructor(mode: string, pattern: string, description: string | undefined, filePath: string) { + constructor(mode: string, pattern: string, description: string | undefined, filePath: string, tool?: string) { + const toolInfo = tool ? `Tool '${tool}' in mode '${mode}'` : `This mode (${mode})` super( - `This mode (${mode}) can only edit files matching pattern: ${pattern}${description ? ` (${description})` : ""}. Got: ${filePath}`, + `${toolInfo} can only edit files matching pattern: ${pattern}${description ? ` (${description})` : ""}. Got: ${filePath}`, ) this.name = "FileRestrictionError" } @@ -266,12 +276,48 @@ export function isToolAllowedForMode( // For the edit group, check file regex if specified if (groupName === "edit" && options.fileRegex) { const filePath = toolParams?.path - if ( - filePath && - (toolParams.diff || toolParams.content || toolParams.operations) && - !doesFileMatchRegex(filePath, options.fileRegex) - ) { - throw new FileRestrictionError(mode.name, options.fileRegex, options.description, filePath) + // Check if this is an actual edit operation (not just path-only for streaming) + const isEditOperation = EDIT_OPERATION_PARAMS.some((param) => toolParams?.[param]) + + // Handle single file path validation + if (filePath && isEditOperation && !doesFileMatchRegex(filePath, options.fileRegex)) { + throw new FileRestrictionError(mode.name, options.fileRegex, options.description, filePath, tool) + } + + // Handle XML args parameter (used by MULTI_FILE_APPLY_DIFF experiment) + if (toolParams?.args && typeof toolParams.args === "string") { + // Extract file paths from XML args with improved validation + try { + const filePathMatches = toolParams.args.match(/([^<]+)<\/path>/g) + if (filePathMatches) { + for (const match of filePathMatches) { + // More robust path extraction with validation + const pathMatch = match.match(/([^<]+)<\/path>/) + if (pathMatch && pathMatch[1]) { + const extractedPath = pathMatch[1].trim() + // Validate that the path is not empty and doesn't contain invalid characters + if (extractedPath && !extractedPath.includes("<") && !extractedPath.includes(">")) { + if (!doesFileMatchRegex(extractedPath, options.fileRegex)) { + throw new FileRestrictionError( + mode.name, + options.fileRegex, + options.description, + extractedPath, + tool, + ) + } + } + } + } + } + } catch (error) { + // Re-throw FileRestrictionError as it's an expected validation error + if (error instanceof FileRestrictionError) { + throw error + } + // If XML parsing fails, log the error but don't block the operation + console.warn(`Failed to parse XML args for file restriction validation: ${error}`) + } } } diff --git a/src/utils/__tests__/object.spec.ts b/src/utils/__tests__/object.spec.ts new file mode 100644 index 0000000000..ce9d9f5cc7 --- /dev/null +++ b/src/utils/__tests__/object.spec.ts @@ -0,0 +1,38 @@ +import { describe, it, expect } from "vitest" +import { isEmpty } from "../object" + +describe("isEmpty", () => { + describe("should return true for empty values", () => { + it.each([ + ["empty object", {}], + ["empty array", []], + ["null", null], + ["undefined", undefined], + ["string", "string"], + ["number", 123], + ["boolean true", true], + ["boolean false", false], + ])("%s", (_, value) => { + expect(isEmpty(value)).toBe(true) + }) + }) + + describe("should return false for non-empty values", () => { + it.each([ + ["object with properties", { a: 1 }], + ["object with multiple properties", { a: 1, b: 2 }], + ["array with one item", [1]], + ["array with multiple items", [1, 2, 3]], + ])("%s", (_, value) => { + expect(isEmpty(value)).toBe(false) + }) + }) + + it("should handle objects with null prototype", () => { + const obj = Object.create(null) + expect(isEmpty(obj)).toBe(true) + + obj.prop = "value" + expect(isEmpty(obj)).toBe(false) + }) +}) diff --git a/src/utils/object.ts b/src/utils/object.ts new file mode 100644 index 0000000000..1aec4a1309 --- /dev/null +++ b/src/utils/object.ts @@ -0,0 +1,18 @@ +/** + * Check if an object is empty (has no own enumerable properties) + * @param obj The object to check + * @returns true if the object is empty, false otherwise + */ +export function isEmpty(obj: unknown): boolean { + if (!obj || typeof obj !== "object") { + return true + } + + // Check if it's an array + if (Array.isArray(obj)) { + return obj.length === 0 + } + + // Check if it's an object with no own properties + return Object.keys(obj).length === 0 +} diff --git a/webview-ui/src/__tests__/SearchableSelect.spec.tsx b/webview-ui/src/__tests__/SearchableSelect.spec.tsx new file mode 100644 index 0000000000..bcc0a2c8b7 --- /dev/null +++ b/webview-ui/src/__tests__/SearchableSelect.spec.tsx @@ -0,0 +1,256 @@ +import React from "react" +import { render, screen, act, cleanup, waitFor, within, fireEvent } from "@/utils/test-utils" +import { SearchableSelect, SearchableSelectOption } from "@/components/ui/searchable-select" +import userEvent from "@testing-library/user-event" + +describe("SearchableSelect", () => { + const mockOptions: SearchableSelectOption[] = [ + { value: "option1", label: "Option 1" }, + { value: "option2", label: "Option 2" }, + { value: "option3", label: "Option 3", disabled: true }, + ] + + const defaultProps = { + options: mockOptions, + placeholder: "Select an option", + searchPlaceholder: "Search options...", + emptyMessage: "No options found", + onValueChange: vi.fn(), + } + + beforeEach(() => { + vi.clearAllMocks() + }) + + afterEach(() => { + cleanup() + vi.useRealTimers() + }) + + it("renders with placeholder when no value is selected", () => { + render() + expect(screen.getByText("Select an option")).toBeInTheDocument() + }) + + it("renders with selected option label when value is provided", () => { + render() + expect(screen.getByText("Option 1")).toBeInTheDocument() + }) + + it("opens dropdown when clicked", async () => { + const user = userEvent.setup() + render() + + const trigger = screen.getByRole("combobox") + await user.click(trigger) + + expect(screen.getByPlaceholderText("Search options...")).toBeInTheDocument() + expect(screen.getByText("Option 1")).toBeInTheDocument() + expect(screen.getByText("Option 2")).toBeInTheDocument() + }) + + it("filters options based on search input", async () => { + const user = userEvent.setup() + render() + + const trigger = screen.getByRole("combobox") + await user.click(trigger) + + // Verify all options are initially visible + await waitFor(() => { + expect(screen.getByText("Option 1")).toBeInTheDocument() + expect(screen.getByText("Option 2")).toBeInTheDocument() + expect(screen.getByText("Option 3")).toBeInTheDocument() + }) + + const searchInput = screen.getByPlaceholderText("Search options...") + + // Use fireEvent for cmdk input + fireEvent.change(searchInput, { target: { value: "1" } }) + + // Wait for the filtering to take effect + await waitFor(() => { + expect(screen.getByText("Option 1")).toBeInTheDocument() + expect(screen.queryByText("Option 2")).not.toBeInTheDocument() + expect(screen.queryByText("Option 3")).not.toBeInTheDocument() + }) + }) + + it("calls onValueChange when an option is selected", async () => { + const user = userEvent.setup() + render() + + const trigger = screen.getByRole("combobox") + await user.click(trigger) + + const option = screen.getByText("Option 2") + await user.click(option) + + expect(defaultProps.onValueChange).toHaveBeenCalledWith("option2") + }) + + it("does not call onValueChange when a disabled option is clicked", async () => { + const user = userEvent.setup() + render() + + const trigger = screen.getByRole("combobox") + await user.click(trigger) + + const disabledOption = screen.getByText("Option 3") + await user.click(disabledOption) + + expect(defaultProps.onValueChange).not.toHaveBeenCalled() + }) + + it("clears search value when dropdown is closed", async () => { + const user = userEvent.setup() + render() + + const trigger = screen.getByRole("combobox") + await user.click(trigger) + + const searchInput = screen.getByPlaceholderText("Search options...") + + // Use fireEvent for cmdk input + fireEvent.change(searchInput, { target: { value: "test" } }) + + // Verify the search filters the options + await waitFor(() => { + expect(screen.queryByText("Option 1")).not.toBeInTheDocument() + expect(screen.queryByText("Option 2")).not.toBeInTheDocument() + }) + + // Close the dropdown by clicking outside + await user.click(document.body) + + // Wait for dropdown to close + await waitFor(() => { + expect(screen.queryByRole("dialog")).not.toBeInTheDocument() + }) + + // Wait a bit for the timeout to clear search + await new Promise((resolve) => setTimeout(resolve, 200)) + + // Open again to check if search was cleared + await user.click(trigger) + + // All options should be visible again + await waitFor(() => { + expect(screen.getByText("Option 1")).toBeInTheDocument() + expect(screen.getByText("Option 2")).toBeInTheDocument() + expect(screen.getByText("Option 3")).toBeInTheDocument() + }) + }) + + it("handles component unmounting without memory leaks", async () => { + vi.useFakeTimers() + const { unmount, rerender } = render() + + // Change the value prop to trigger the effect with timeout + rerender() + + // Immediately unmount the component before the timeout completes + act(() => { + unmount() + }) + + // This test ensures that no setState calls happen after unmount + // If there was a memory leak, this would throw an error + expect(() => { + // Wait for any pending timeouts + act(() => { + vi.runAllTimers() + }) + }).not.toThrow() + }) + + it("cleans up timeouts on unmount", () => { + vi.useFakeTimers() + const clearTimeoutSpy = vi.spyOn(global, "clearTimeout") + const { unmount } = render() + + act(() => { + unmount() + }) + + // Verify that clearTimeout was called during cleanup + expect(clearTimeoutSpy).toHaveBeenCalled() + clearTimeoutSpy.mockRestore() + }) + + it("resets search value when value prop changes", async () => { + const user = userEvent.setup() + const { rerender } = render() + + // Open dropdown and type something + const trigger = screen.getByRole("combobox") + await user.click(trigger) + + const searchInput = screen.getByPlaceholderText("Search options...") + fireEvent.change(searchInput, { target: { value: "2" } }) + + // Verify search is working - use within to scope to dropdown + const dropdown = screen.getByRole("dialog") + await waitFor(() => { + expect(within(dropdown).queryByText("Option 1")).not.toBeInTheDocument() + expect(within(dropdown).getByText("Option 2")).toBeInTheDocument() + }) + + // Close dropdown + await user.click(document.body) + + // Change the value prop + rerender() + + // Wait for the component to update + await waitFor(() => { + expect(screen.getByRole("combobox")).toHaveTextContent("Option 2") + }) + + // Wait for the effect to run (100ms timeout in component) + await new Promise((resolve) => setTimeout(resolve, 150)) + + // Open dropdown again + await user.click(trigger) + + // All options should be visible (search cleared) - use within to scope + const newDropdown = screen.getByRole("dialog") + await waitFor(() => { + expect(within(newDropdown).getByText("Option 1")).toBeInTheDocument() + expect(within(newDropdown).getByText("Option 2")).toBeInTheDocument() + expect(within(newDropdown).getByText("Option 3")).toBeInTheDocument() + }) + }) + + it("handles rapid value changes without issues", async () => { + const { rerender } = render() + + // Rapidly change values + rerender() + rerender() + rerender() + + // Wait for the final value to be reflected + await waitFor(() => { + const trigger = screen.getByRole("combobox") + expect(trigger).toHaveTextContent("Option 1") + }) + + // Component should still be functional - open dropdown + const user = userEvent.setup() + const trigger = screen.getByRole("combobox") + await user.click(trigger) + + // Should be able to search + const searchInput = screen.getByPlaceholderText("Search options...") + fireEvent.change(searchInput, { target: { value: "2" } }) + + // Check filtering works - use within to scope to dropdown + const dropdown = screen.getByRole("dialog") + await waitFor(() => { + expect(within(dropdown).getByText("Option 2")).toBeInTheDocument() + expect(within(dropdown).queryByText("Option 1")).not.toBeInTheDocument() + expect(within(dropdown).queryByText("Option 3")).not.toBeInTheDocument() + }) + }) +}) diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 0c4b4a03b0..fa0781c865 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -51,7 +51,7 @@ const Announcement = ({ hideAnnouncement }: AnnouncementProps) => { components={{ bold: , code: , - experimentalSettingsLink: ( + settingsLink: ( { @@ -62,7 +62,7 @@ const Announcement = ({ hideAnnouncement }: AnnouncementProps) => { { type: "action", action: "settingsButtonClicked", - values: { section: "experimental" }, + values: { section: "codebaseIndexing" }, }, "*", ) @@ -79,31 +79,9 @@ const Announcement = ({ hideAnnouncement }: AnnouncementProps) => { components={{ bold: , code: , - contextSettingsLink: ( - { - e.preventDefault() - setOpen(false) - hideAnnouncement() - window.postMessage( - { - type: "action", - action: "settingsButtonClicked", - values: { section: "contextManagement" }, - }, - "*", - ) - }} - /> - ), }} /> -
  • - •{" "} - , code: }} /> -
  • void onBatchFileResponse?: (response: { [key: string]: boolean }) => void onFollowUpUnmount?: () => void + isFollowUpAnswered?: boolean editable?: boolean } @@ -104,6 +105,7 @@ export const ChatRowContent = ({ onSuggestionClick, onFollowUpUnmount, onBatchFileResponse, + isFollowUpAnswered, editable, }: ChatRowContentProps) => { const { t } = useTranslation() @@ -1055,7 +1057,7 @@ export const ChatRowContent = ({ )} +
    + +
    + +
    + +
    + {!inputValue && (
    + className="absolute left-2 z-30 pr-9 flex items-center h-8" + style={{ + bottom: "0.25rem", + color: "var(--vscode-tab-inactiveForeground)", + userSelect: "none", + pointerEvents: "none", + }}> {placeholderBottomText}
    )} @@ -1133,25 +1145,13 @@ const ChatTextArea = forwardRef(
    - {codebaseIndexConfig?.codebaseIndexEnabled && } - + -
    diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 84bb7b89a2..38b8997faf 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -169,6 +169,8 @@ const ChatViewComponent: React.ForwardRefRenderFunction(null) + const userRespondedRef = useRef(false) + const [currentFollowUpTs, setCurrentFollowUpTs] = useState(null) const clineAskRef = useRef(clineAsk) useEffect(() => { @@ -238,6 +240,8 @@ const ChatViewComponent: React.ForwardRefRenderFunction { setExpandedRows({}) everVisibleMessagesTsRef.current.clear() // Clear for new task + setCurrentFollowUpTs(null) // Clear follow-up answered state for new task + + // Clear any pending auto-approval timeout from previous task + if (autoApproveTimeoutRef.current) { + clearTimeout(autoApproveTimeoutRef.current) + autoApproveTimeoutRef.current = null + } + // Reset user response flag for new task + userRespondedRef.current = false }, [task?.ts]) useEffect(() => { @@ -486,7 +499,22 @@ const ChatViewComponent: React.ForwardRefRenderFunction { + const lastFollowUpMessage = messagesRef.current.findLast((msg) => msg.ask === "followup") + if (lastFollowUpMessage) { + setCurrentFollowUpTs(lastFollowUpMessage.ts) + } + }, []) + const handleChatReset = useCallback(() => { + // Clear any pending auto-approval timeout + if (autoApproveTimeoutRef.current) { + clearTimeout(autoApproveTimeoutRef.current) + autoApproveTimeoutRef.current = null + } + // Reset user response flag for new message + userRespondedRef.current = false + // Only reset message-specific state, preserving mode. setInputValue("") setSendingDisabled(true) @@ -504,9 +532,16 @@ const ChatViewComponent: React.ForwardRefRenderFunction 0) { + // 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() + } + // Use clineAskRef.current switch ( clineAskRef.current // Use clineAskRef.current @@ -530,7 +565,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction { + // Mark that user has responded + userRespondedRef.current = true + const trimmedInput = text?.trim() switch (clineAsk) { @@ -599,6 +637,9 @@ const ChatViewComponent: React.ForwardRefRenderFunction { + // Mark that user has responded + userRespondedRef.current = true + const trimmedInput = text?.trim() if (isStreaming) { @@ -1219,6 +1260,16 @@ const ChatViewComponent: React.ForwardRefRenderFunction { + // Mark that user has responded if this is a manual click (not auto-approval) + if (event) { + userRespondedRef.current = true + } + + // Mark the current follow-up question as answered when a suggestion is clicked + if (clineAsk === "followup" && !event?.shiftKey) { + markFollowUpAsAnswered() + } + // Check if we need to switch modes if (suggestion.mode) { // Only switch modes if it's a manual click (event exists) or auto-approval is allowed @@ -1238,7 +1289,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction { @@ -1248,11 +1299,8 @@ const ChatViewComponent: React.ForwardRefRenderFunction { - // Clear the auto-approve timeout to prevent race conditions - if (autoApproveTimeoutRef.current) { - clearTimeout(autoApproveTimeoutRef.current) - autoApproveTimeoutRef.current = null - } + // Mark that user has responded + userRespondedRef.current = true }, []) const itemContent = useCallback( @@ -1291,6 +1339,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction { if (lastMessage?.ask && isAutoApproved(lastMessage)) { // Special handling for follow-up questions @@ -1354,9 +1409,17 @@ const ChatViewComponent: React.ForwardRefRenderFunction 0) { // Wait for the configured timeout before auto-selecting the first suggestion await new Promise((resolve) => { - autoApproveTimeoutRef.current = setTimeout(resolve, followupAutoApproveTimeoutMs) + autoApproveTimeoutRef.current = setTimeout(() => { + autoApproveTimeoutRef.current = null + resolve() + }, followupAutoApproveTimeoutMs) }) + // Check if user responded manually + if (userRespondedRef.current) { + return + } + // Get the first suggestion const firstSuggestion = followUpData.suggest[0] @@ -1366,7 +1429,10 @@ const ChatViewComponent: React.ForwardRefRenderFunction((resolve) => { - autoApproveTimeoutRef.current = setTimeout(resolve, writeDelayMs) + autoApproveTimeoutRef.current = setTimeout(() => { + autoApproveTimeoutRef.current = null + resolve() + }, writeDelayMs) }) } diff --git a/webview-ui/src/components/chat/CodeIndexPopover.tsx b/webview-ui/src/components/chat/CodeIndexPopover.tsx index 6c9ea1c204..1243b7efa2 100644 --- a/webview-ui/src/components/chat/CodeIndexPopover.tsx +++ b/webview-ui/src/components/chat/CodeIndexPopover.tsx @@ -1,5 +1,6 @@ -import React, { useState, useEffect, useMemo } from "react" +import React, { useState, useEffect, useMemo, useCallback, useRef } from "react" import { Trans } from "react-i18next" +import { z } from "zod" import { VSCodeButton, VSCodeTextField, @@ -34,11 +35,16 @@ import { Slider, StandardTooltip, } from "@src/components/ui" +import { AlertTriangle } from "lucide-react" import { useRooPortal } from "@src/components/ui/hooks/useRooPortal" import type { EmbedderProvider } from "@roo/embeddingModels" import type { IndexingStatus } from "@roo/ExtensionMessage" import { CODEBASE_INDEX_DEFAULTS } from "@roo-code/types" +// Default URLs for providers +const DEFAULT_QDRANT_URL = "http://localhost:6333" +const DEFAULT_OLLAMA_URL = "http://localhost:11434" + interface CodeIndexPopoverProps { children: React.ReactNode indexingStatus: IndexingStatus @@ -51,6 +57,7 @@ interface LocalCodeIndexSettings { codebaseIndexEmbedderProvider: EmbedderProvider codebaseIndexEmbedderBaseUrl?: string codebaseIndexEmbedderModelId: string + codebaseIndexEmbedderModelDimension?: number // Generic dimension for all providers codebaseIndexSearchMaxResults?: number codebaseIndexSearchMinScore?: number @@ -59,10 +66,65 @@ interface LocalCodeIndexSettings { codeIndexQdrantApiKey?: string codebaseIndexOpenAiCompatibleBaseUrl?: string codebaseIndexOpenAiCompatibleApiKey?: string - codebaseIndexOpenAiCompatibleModelDimension?: number codebaseIndexGeminiApiKey?: string } +// Validation schema for codebase index settings +const createValidationSchema = (provider: EmbedderProvider, t: any) => { + const baseSchema = z.object({ + codebaseIndexQdrantUrl: z + .string() + .min(1, t("settings:codeIndex.validation.qdrantUrlRequired")) + .url(t("settings:codeIndex.validation.invalidQdrantUrl")), + codeIndexQdrantApiKey: z.string().optional(), + }) + + switch (provider) { + case "openai": + return baseSchema.extend({ + codeIndexOpenAiKey: z.string().min(1, t("settings:codeIndex.validation.openaiApiKeyRequired")), + codebaseIndexEmbedderModelId: z + .string() + .min(1, t("settings:codeIndex.validation.modelSelectionRequired")), + }) + + case "ollama": + return baseSchema.extend({ + codebaseIndexEmbedderBaseUrl: z + .string() + .min(1, t("settings:codeIndex.validation.ollamaBaseUrlRequired")) + .url(t("settings:codeIndex.validation.invalidOllamaUrl")), + codebaseIndexEmbedderModelId: z.string().min(1, t("settings:codeIndex.validation.modelIdRequired")), + }) + + case "openai-compatible": + return baseSchema.extend({ + codebaseIndexOpenAiCompatibleBaseUrl: z + .string() + .min(1, t("settings:codeIndex.validation.baseUrlRequired")) + .url(t("settings:codeIndex.validation.invalidBaseUrl")), + codebaseIndexOpenAiCompatibleApiKey: z + .string() + .min(1, t("settings:codeIndex.validation.apiKeyRequired")), + codebaseIndexEmbedderModelId: z.string().min(1, t("settings:codeIndex.validation.modelIdRequired")), + codebaseIndexEmbedderModelDimension: z + .number() + .min(1, t("settings:codeIndex.validation.modelDimensionRequired")), + }) + + case "gemini": + return baseSchema.extend({ + codebaseIndexGeminiApiKey: z.string().min(1, t("settings:codeIndex.validation.geminiApiKeyRequired")), + codebaseIndexEmbedderModelId: z + .string() + .min(1, t("settings:codeIndex.validation.modelSelectionRequired")), + }) + + default: + return baseSchema + } +} + export const CodeIndexPopover: React.FC = ({ children, indexingStatus: externalIndexingStatus, @@ -72,26 +134,34 @@ export const CodeIndexPopover: React.FC = ({ const { codebaseIndexConfig, codebaseIndexModels } = useExtensionState() const [open, setOpen] = useState(false) const [isAdvancedSettingsOpen, setIsAdvancedSettingsOpen] = useState(false) + const [isSetupSettingsOpen, setIsSetupSettingsOpen] = useState(false) const [indexingStatus, setIndexingStatus] = useState(externalIndexingStatus) const [saveStatus, setSaveStatus] = useState<"idle" | "saving" | "saved" | "error">("idle") const [saveError, setSaveError] = useState(null) + // Form validation state + const [formErrors, setFormErrors] = useState>({}) + + // Discard changes dialog state + const [isDiscardDialogShow, setDiscardDialogShow] = useState(false) + const confirmDialogHandler = useRef<(() => void) | null>(null) + // Default settings template const getDefaultSettings = (): LocalCodeIndexSettings => ({ - codebaseIndexEnabled: false, + codebaseIndexEnabled: true, codebaseIndexQdrantUrl: "", codebaseIndexEmbedderProvider: "openai", codebaseIndexEmbedderBaseUrl: "", codebaseIndexEmbedderModelId: "", + codebaseIndexEmbedderModelDimension: undefined, codebaseIndexSearchMaxResults: CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_RESULTS, codebaseIndexSearchMinScore: CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_MIN_SCORE, codeIndexOpenAiKey: "", codeIndexQdrantApiKey: "", codebaseIndexOpenAiCompatibleBaseUrl: "", codebaseIndexOpenAiCompatibleApiKey: "", - codebaseIndexOpenAiCompatibleModelDimension: undefined, codebaseIndexGeminiApiKey: "", }) @@ -110,11 +180,13 @@ export const CodeIndexPopover: React.FC = ({ useEffect(() => { if (codebaseIndexConfig) { const settings = { - codebaseIndexEnabled: codebaseIndexConfig.codebaseIndexEnabled || false, + codebaseIndexEnabled: codebaseIndexConfig.codebaseIndexEnabled ?? true, codebaseIndexQdrantUrl: codebaseIndexConfig.codebaseIndexQdrantUrl || "", codebaseIndexEmbedderProvider: codebaseIndexConfig.codebaseIndexEmbedderProvider || "openai", codebaseIndexEmbedderBaseUrl: codebaseIndexConfig.codebaseIndexEmbedderBaseUrl || "", codebaseIndexEmbedderModelId: codebaseIndexConfig.codebaseIndexEmbedderModelId || "", + codebaseIndexEmbedderModelDimension: + codebaseIndexConfig.codebaseIndexEmbedderModelDimension || undefined, codebaseIndexSearchMaxResults: codebaseIndexConfig.codebaseIndexSearchMaxResults ?? CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_RESULTS, codebaseIndexSearchMinScore: @@ -123,8 +195,6 @@ export const CodeIndexPopover: React.FC = ({ codeIndexQdrantApiKey: "", codebaseIndexOpenAiCompatibleBaseUrl: codebaseIndexConfig.codebaseIndexOpenAiCompatibleBaseUrl || "", codebaseIndexOpenAiCompatibleApiKey: "", - codebaseIndexOpenAiCompatibleModelDimension: - codebaseIndexConfig.codebaseIndexOpenAiCompatibleModelDimension || undefined, codebaseIndexGeminiApiKey: "", } setInitialSettings(settings) @@ -254,9 +324,96 @@ export const CodeIndexPopover: React.FC = ({ const updateSetting = (key: keyof LocalCodeIndexSettings, value: any) => { setCurrentSettings((prev) => ({ ...prev, [key]: value })) + // Clear validation error for this field when user starts typing + if (formErrors[key]) { + setFormErrors((prev) => { + const newErrors = { ...prev } + delete newErrors[key] + return newErrors + }) + } } + // Validation function + const validateSettings = (): boolean => { + const schema = createValidationSchema(currentSettings.codebaseIndexEmbedderProvider, t) + + // Prepare data for validation + const dataToValidate: any = {} + for (const [key, value] of Object.entries(currentSettings)) { + // For secret fields with placeholder values, treat them as valid (they exist in backend) + if (value === SECRET_PLACEHOLDER) { + // Add a dummy value that will pass validation for these fields + if ( + key === "codeIndexOpenAiKey" || + key === "codebaseIndexOpenAiCompatibleApiKey" || + key === "codebaseIndexGeminiApiKey" + ) { + dataToValidate[key] = "placeholder-valid" + } + } else { + dataToValidate[key] = value + } + } + + try { + // Validate using the schema + schema.parse(dataToValidate) + setFormErrors({}) + return true + } catch (error) { + if (error instanceof z.ZodError) { + const errors: Record = {} + error.errors.forEach((err) => { + if (err.path[0]) { + errors[err.path[0] as string] = err.message + } + }) + setFormErrors(errors) + } + return false + } + } + + // Discard changes functionality + const checkUnsavedChanges = useCallback( + (then: () => void) => { + if (hasUnsavedChanges) { + confirmDialogHandler.current = then + setDiscardDialogShow(true) + } else { + then() + } + }, + [hasUnsavedChanges], + ) + + const onConfirmDialogResult = useCallback( + (confirm: boolean) => { + if (confirm) { + // Discard changes: Reset to initial settings + setCurrentSettings(initialSettings) + setFormErrors({}) // Clear any validation errors + confirmDialogHandler.current?.() // Execute the pending action (e.g., close popover) + } + setDiscardDialogShow(false) + }, + [initialSettings], + ) + + // Handle popover close with unsaved changes check + const handlePopoverClose = useCallback(() => { + checkUnsavedChanges(() => { + setOpen(false) + }) + }, [checkUnsavedChanges]) + const handleSaveSettings = () => { + // Validate settings before saving + if (!validateSettings()) { + return + } + setSaveStatus("saving") setSaveError(null) @@ -301,457 +458,680 @@ export const CodeIndexPopover: React.FC = ({ const portalContainer = useRooPortal("roo-portal") return ( - - {children} - -
    -

    {t("settings:codeIndex.title")}

    -

    - - - -

    -
    + <> + { + if (!newOpen) { + // User is trying to close the popover + handlePopoverClose() + } else { + setOpen(newOpen) + } + }}> + {children} + +
    +
    +

    {t("settings:codeIndex.title")}

    +
    +

    + + + +

    +
    -
    - {/* Status Section */} -
    -

    {t("settings:codeIndex.statusTitle")}

    -
    - - {t(`settings:codeIndex.indexingStatuses.${indexingStatus.systemStatus.toLowerCase()}`)} - {indexingStatus.message ? ` - ${indexingStatus.message}` : ""} +
    + {/* Status Section */} +
    +

    {t("settings:codeIndex.statusTitle")}

    +
    + + {t(`settings:codeIndex.indexingStatuses.${indexingStatus.systemStatus.toLowerCase()}`)} + {indexingStatus.message ? ` - ${indexingStatus.message}` : ""} +
    + + {indexingStatus.systemStatus === "Indexing" && ( +
    + + + +
    + )}
    - {indexingStatus.systemStatus === "Indexing" && ( + {/* Setup Settings Disclosure */} +
    + + + {isSetupSettingsOpen && ( +
    + {/* Embedder Provider Section */} +
    + + +
    + + {/* Provider-specific settings */} + {currentSettings.codebaseIndexEmbedderProvider === "openai" && ( + <> +
    + + + updateSetting("codeIndexOpenAiKey", e.target.value) + } + placeholder={t("settings:codeIndex.openAiKeyPlaceholder")} + className={cn("w-full", { + "border-red-500": formErrors.codeIndexOpenAiKey, + })} + /> + {formErrors.codeIndexOpenAiKey && ( +

    + {formErrors.codeIndexOpenAiKey} +

    + )} +
    + +
    + + + updateSetting("codebaseIndexEmbedderModelId", e.target.value) + } + className={cn("w-full", { + "border-red-500": formErrors.codebaseIndexEmbedderModelId, + })}> + + {t("settings:codeIndex.selectModel")} + + {getAvailableModels().map((modelId) => { + const model = + codebaseIndexModels?.[ + currentSettings.codebaseIndexEmbedderProvider + ]?.[modelId] + return ( + + {modelId}{" "} + {model + ? t("settings:codeIndex.modelDimensions", { + dimension: model.dimension, + }) + : ""} + + ) + })} + + {formErrors.codebaseIndexEmbedderModelId && ( +

    + {formErrors.codebaseIndexEmbedderModelId} +

    + )} +
    + + )} + + {currentSettings.codebaseIndexEmbedderProvider === "ollama" && ( + <> +
    + + + updateSetting("codebaseIndexEmbedderBaseUrl", e.target.value) + } + onBlur={(e: any) => { + // Set default Ollama URL if field is empty + if (!e.target.value.trim()) { + e.target.value = DEFAULT_OLLAMA_URL + updateSetting( + "codebaseIndexEmbedderBaseUrl", + DEFAULT_OLLAMA_URL, + ) + } + }} + placeholder={t("settings:codeIndex.ollamaUrlPlaceholder")} + className={cn("w-full", { + "border-red-500": formErrors.codebaseIndexEmbedderBaseUrl, + })} + /> + {formErrors.codebaseIndexEmbedderBaseUrl && ( +

    + {formErrors.codebaseIndexEmbedderBaseUrl} +

    + )} +
    + +
    + + + updateSetting("codebaseIndexEmbedderModelId", e.target.value) + } + className={cn("w-full", { + "border-red-500": formErrors.codebaseIndexEmbedderModelId, + })}> + + {t("settings:codeIndex.selectModel")} + + {getAvailableModels().map((modelId) => { + const model = + codebaseIndexModels?.[ + currentSettings.codebaseIndexEmbedderProvider + ]?.[modelId] + return ( + + {modelId}{" "} + {model + ? t("settings:codeIndex.modelDimensions", { + dimension: model.dimension, + }) + : ""} + + ) + })} + + {formErrors.codebaseIndexEmbedderModelId && ( +

    + {formErrors.codebaseIndexEmbedderModelId} +

    + )} +
    + + )} + + {currentSettings.codebaseIndexEmbedderProvider === "openai-compatible" && ( + <> +
    + + + updateSetting( + "codebaseIndexOpenAiCompatibleBaseUrl", + e.target.value, + ) + } + placeholder={t( + "settings:codeIndex.openAiCompatibleBaseUrlPlaceholder", + )} + className={cn("w-full", { + "border-red-500": + formErrors.codebaseIndexOpenAiCompatibleBaseUrl, + })} + /> + {formErrors.codebaseIndexOpenAiCompatibleBaseUrl && ( +

    + {formErrors.codebaseIndexOpenAiCompatibleBaseUrl} +

    + )} +
    + +
    + + + updateSetting( + "codebaseIndexOpenAiCompatibleApiKey", + e.target.value, + ) + } + placeholder={t( + "settings:codeIndex.openAiCompatibleApiKeyPlaceholder", + )} + className={cn("w-full", { + "border-red-500": + formErrors.codebaseIndexOpenAiCompatibleApiKey, + })} + /> + {formErrors.codebaseIndexOpenAiCompatibleApiKey && ( +

    + {formErrors.codebaseIndexOpenAiCompatibleApiKey} +

    + )} +
    + +
    + + + updateSetting("codebaseIndexEmbedderModelId", e.target.value) + } + placeholder={t("settings:codeIndex.modelPlaceholder")} + className={cn("w-full", { + "border-red-500": formErrors.codebaseIndexEmbedderModelId, + })} + /> + {formErrors.codebaseIndexEmbedderModelId && ( +

    + {formErrors.codebaseIndexEmbedderModelId} +

    + )} +
    + +
    + + { + const value = e.target.value + ? parseInt(e.target.value) + : undefined + updateSetting("codebaseIndexEmbedderModelDimension", value) + }} + placeholder={t("settings:codeIndex.modelDimensionPlaceholder")} + className={cn("w-full", { + "border-red-500": + formErrors.codebaseIndexEmbedderModelDimension, + })} + /> + {formErrors.codebaseIndexEmbedderModelDimension && ( +

    + {formErrors.codebaseIndexEmbedderModelDimension} +

    + )} +
    + + )} + + {currentSettings.codebaseIndexEmbedderProvider === "gemini" && ( + <> +
    + + + updateSetting("codebaseIndexGeminiApiKey", e.target.value) + } + placeholder={t("settings:codeIndex.geminiApiKeyPlaceholder")} + className={cn("w-full", { + "border-red-500": formErrors.codebaseIndexGeminiApiKey, + })} + /> + {formErrors.codebaseIndexGeminiApiKey && ( +

    + {formErrors.codebaseIndexGeminiApiKey} +

    + )} +
    + +
    + + + updateSetting("codebaseIndexEmbedderModelId", e.target.value) + } + className={cn("w-full", { + "border-red-500": formErrors.codebaseIndexEmbedderModelId, + })}> + + {t("settings:codeIndex.selectModel")} + + {getAvailableModels().map((modelId) => { + const model = + codebaseIndexModels?.[ + currentSettings.codebaseIndexEmbedderProvider + ]?.[modelId] + return ( + + {modelId}{" "} + {model + ? t("settings:codeIndex.modelDimensions", { + dimension: model.dimension, + }) + : ""} + + ) + })} + + {formErrors.codebaseIndexEmbedderModelId && ( +

    + {formErrors.codebaseIndexEmbedderModelId} +

    + )} +
    + + )} + + {/* Qdrant Settings */} +
    + + + updateSetting("codebaseIndexQdrantUrl", e.target.value) + } + onBlur={(e: any) => { + // Set default Qdrant URL if field is empty + if (!e.target.value.trim()) { + currentSettings.codebaseIndexQdrantUrl = DEFAULT_QDRANT_URL + updateSetting("codebaseIndexQdrantUrl", DEFAULT_QDRANT_URL) + } + }} + placeholder={t("settings:codeIndex.qdrantUrlPlaceholder")} + className={cn("w-full", { + "border-red-500": formErrors.codebaseIndexQdrantUrl, + })} + /> + {formErrors.codebaseIndexQdrantUrl && ( +

    + {formErrors.codebaseIndexQdrantUrl} +

    + )} +
    + +
    + + updateSetting("codeIndexQdrantApiKey", e.target.value)} + placeholder={t("settings:codeIndex.qdrantApiKeyPlaceholder")} + className={cn("w-full", { + "border-red-500": formErrors.codeIndexQdrantApiKey, + })} + /> + {formErrors.codeIndexQdrantApiKey && ( +

    + {formErrors.codeIndexQdrantApiKey} +

    + )} +
    +
    + )} +
    + + {/* Advanced Settings Disclosure */} +
    + + + {isAdvancedSettingsOpen && ( +
    + {/* Search Score Threshold Slider */} +
    +
    + + + + +
    +
    + + updateSetting("codebaseIndexSearchMinScore", values[0]) + } + className="flex-1" + data-testid="search-min-score-slider" + /> + + {( + currentSettings.codebaseIndexSearchMinScore ?? + CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_MIN_SCORE + ).toFixed(2)} + + + updateSetting( + "codebaseIndexSearchMinScore", + CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_MIN_SCORE, + ) + }> + + +
    +
    + + {/* Maximum Search Results Slider */} +
    +
    + + + + +
    +
    + + updateSetting("codebaseIndexSearchMaxResults", values[0]) + } + className="flex-1" + data-testid="search-max-results-slider" + /> + + {currentSettings.codebaseIndexSearchMaxResults ?? + CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_RESULTS} + + + updateSetting( + "codebaseIndexSearchMaxResults", + CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_RESULTS, + ) + }> + + +
    +
    +
    + )} +
    + + {/* Action Buttons */} +
    +
    + {(indexingStatus.systemStatus === "Error" || + indexingStatus.systemStatus === "Standby") && ( + vscode.postMessage({ type: "startIndexing" })} + disabled={saveStatus === "saving" || hasUnsavedChanges}> + {t("settings:codeIndex.startIndexingButton")} + + )} + + {(indexingStatus.systemStatus === "Indexed" || + indexingStatus.systemStatus === "Error") && ( + + + + {t("settings:codeIndex.clearIndexDataButton")} + + + + + + {t("settings:codeIndex.clearDataDialog.title")} + + + {t("settings:codeIndex.clearDataDialog.description")} + + + + + {t("settings:codeIndex.clearDataDialog.cancelButton")} + + vscode.postMessage({ type: "clearIndexData" })}> + {t("settings:codeIndex.clearDataDialog.confirmButton")} + + + + + )} +
    + + + {saveStatus === "saving" + ? t("settings:codeIndex.saving") + : t("settings:codeIndex.saveSettings")} + +
    + + {/* Save Status Messages */} + {saveStatus === "error" && (
    - - - + + {saveError || t("settings:codeIndex.saveError")} +
    )}
    + + - {/* Embedder Provider Section */} -
    - - -
    - - {/* Provider-specific settings */} - {currentSettings.codebaseIndexEmbedderProvider === "openai" && ( - <> -
    - - updateSetting("codeIndexOpenAiKey", e.target.value)} - placeholder={t("settings:codeIndex.openAiKeyPlaceholder")} - className="w-full" - /> -
    - -
    - - updateSetting("codebaseIndexEmbedderModelId", e.target.value)} - className="w-full"> - {t("settings:codeIndex.selectModel")} - {getAvailableModels().map((modelId) => { - const model = - codebaseIndexModels?.[currentSettings.codebaseIndexEmbedderProvider]?.[ - modelId - ] - return ( - - {modelId}{" "} - {model - ? t("settings:codeIndex.modelDimensions", { - dimension: model.dimension, - }) - : ""} - - ) - })} - -
    - - )} - - {currentSettings.codebaseIndexEmbedderProvider === "ollama" && ( - <> -
    - - updateSetting("codebaseIndexEmbedderBaseUrl", e.target.value)} - placeholder={t("settings:codeIndex.ollamaUrlPlaceholder")} - className="w-full" - /> -
    - -
    - - updateSetting("codebaseIndexEmbedderModelId", e.target.value)} - className="w-full"> - {t("settings:codeIndex.selectModel")} - {getAvailableModels().map((modelId) => { - const model = - codebaseIndexModels?.[currentSettings.codebaseIndexEmbedderProvider]?.[ - modelId - ] - return ( - - {modelId}{" "} - {model - ? t("settings:codeIndex.modelDimensions", { - dimension: model.dimension, - }) - : ""} - - ) - })} - -
    - - )} - - {currentSettings.codebaseIndexEmbedderProvider === "openai-compatible" && ( - <> -
    - - - updateSetting("codebaseIndexOpenAiCompatibleBaseUrl", e.target.value) - } - placeholder={t("settings:codeIndex.openAiCompatibleBaseUrlPlaceholder")} - className="w-full" - /> -
    - -
    - - - updateSetting("codebaseIndexOpenAiCompatibleApiKey", e.target.value) - } - placeholder={t("settings:codeIndex.openAiCompatibleApiKeyPlaceholder")} - className="w-full" - /> -
    - -
    - - updateSetting("codebaseIndexEmbedderModelId", e.target.value)} - placeholder={t("settings:codeIndex.modelPlaceholder")} - className="w-full" - /> -
    - -
    - - { - const value = e.target.value ? parseInt(e.target.value) : undefined - updateSetting("codebaseIndexOpenAiCompatibleModelDimension", value) - }} - placeholder={t("settings:codeIndex.modelDimensionPlaceholder")} - className="w-full" - /> -
    - - )} - - {currentSettings.codebaseIndexEmbedderProvider === "gemini" && ( - <> -
    - - updateSetting("codebaseIndexGeminiApiKey", e.target.value)} - placeholder={t("settings:codeIndex.geminiApiKeyPlaceholder")} - className="w-full" - /> -
    - -
    - - updateSetting("codebaseIndexEmbedderModelId", e.target.value)} - className="w-full"> - {t("settings:codeIndex.selectModel")} - {getAvailableModels().map((modelId) => { - const model = - codebaseIndexModels?.[currentSettings.codebaseIndexEmbedderProvider]?.[ - modelId - ] - return ( - - {modelId}{" "} - {model - ? t("settings:codeIndex.modelDimensions", { - dimension: model.dimension, - }) - : ""} - - ) - })} - -
    - - )} - - {/* Qdrant Settings */} -
    - - updateSetting("codebaseIndexQdrantUrl", e.target.value)} - placeholder={t("settings:codeIndex.qdrantUrlPlaceholder")} - className="w-full" - /> -
    - -
    - - updateSetting("codeIndexQdrantApiKey", e.target.value)} - placeholder={t("settings:codeIndex.qdrantApiKeyPlaceholder")} - className="w-full" - /> -
    - - {/* Advanced Settings Disclosure */} -
    - - - {isAdvancedSettingsOpen && ( -
    - {/* Search Score Threshold Slider */} -
    -
    - - - - -
    -
    - - updateSetting("codebaseIndexSearchMinScore", values[0]) - } - className="flex-1" - data-testid="search-min-score-slider" - /> - - {( - currentSettings.codebaseIndexSearchMinScore ?? - CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_MIN_SCORE - ).toFixed(2)} - - - updateSetting( - "codebaseIndexSearchMinScore", - CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_MIN_SCORE, - ) - }> - - -
    -
    - - {/* Maximum Search Results Slider */} -
    -
    - - - - -
    -
    - - updateSetting("codebaseIndexSearchMaxResults", values[0]) - } - className="flex-1" - data-testid="search-max-results-slider" - /> - - {currentSettings.codebaseIndexSearchMaxResults ?? - CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_RESULTS} - - - updateSetting( - "codebaseIndexSearchMaxResults", - CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_RESULTS, - ) - }> - - -
    -
    -
    - )} -
    - - {/* Action Buttons */} -
    -
    - {(indexingStatus.systemStatus === "Error" || indexingStatus.systemStatus === "Standby") && ( - vscode.postMessage({ type: "startIndexing" })} - disabled={saveStatus === "saving" || hasUnsavedChanges}> - {t("settings:codeIndex.startIndexingButton")} - - )} - - {(indexingStatus.systemStatus === "Indexed" || indexingStatus.systemStatus === "Error") && ( - - - - {t("settings:codeIndex.clearIndexDataButton")} - - - - - - {t("settings:codeIndex.clearDataDialog.title")} - - - {t("settings:codeIndex.clearDataDialog.description")} - - - - - {t("settings:codeIndex.clearDataDialog.cancelButton")} - - vscode.postMessage({ type: "clearIndexData" })}> - {t("settings:codeIndex.clearDataDialog.confirmButton")} - - - - - )} -
    - - - {saveStatus === "saving" - ? t("settings:codeIndex.saving") - : t("settings:codeIndex.saveSettings")} - -
    - - {/* Save Status Messages */} - {saveStatus === "error" && ( -
    - - {saveError || t("settings:codeIndex.saveError")} - -
    - )} -
    - - + {/* Discard Changes Dialog */} + + + + + + {t("settings:unsavedChangesDialog.title")} + + + {t("settings:unsavedChangesDialog.description")} + + + + onConfirmDialogResult(false)}> + {t("settings:unsavedChangesDialog.cancelButton")} + + onConfirmDialogResult(true)}> + {t("settings:unsavedChangesDialog.discardButton")} + + + + + ) } diff --git a/webview-ui/src/components/chat/FollowUpSuggest.tsx b/webview-ui/src/components/chat/FollowUpSuggest.tsx index 5649da744a..1ffe31bbcb 100644 --- a/webview-ui/src/components/chat/FollowUpSuggest.tsx +++ b/webview-ui/src/components/chat/FollowUpSuggest.tsx @@ -14,10 +14,17 @@ interface FollowUpSuggestProps { suggestions?: SuggestionItem[] onSuggestionClick?: (suggestion: SuggestionItem, event?: React.MouseEvent) => void ts: number - onUnmount?: () => void + onCancelAutoApproval?: () => void + isAnswered?: boolean } -export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1, onUnmount }: FollowUpSuggestProps) => { +export const FollowUpSuggest = ({ + suggestions = [], + onSuggestionClick, + ts = 1, + onCancelAutoApproval, + isAnswered = false, +}: FollowUpSuggestProps) => { const { autoApprovalEnabled, alwaysAllowFollowupQuestions, followupAutoApproveTimeoutMs } = useExtensionState() const [countdown, setCountdown] = useState(null) const [suggestionSelected, setSuggestionSelected] = useState(false) @@ -26,7 +33,14 @@ export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1, o // Start countdown timer when auto-approval is enabled for follow-up questions useEffect(() => { // Only start countdown if auto-approval is enabled for follow-up questions and no suggestion has been selected - if (autoApprovalEnabled && alwaysAllowFollowupQuestions && suggestions.length > 0 && !suggestionSelected) { + // Also stop countdown if the question has been answered + if ( + autoApprovalEnabled && + alwaysAllowFollowupQuestions && + suggestions.length > 0 && + !suggestionSelected && + !isAnswered + ) { // Start with the configured timeout in seconds const timeoutMs = typeof followupAutoApproveTimeoutMs === "number" && !isNaN(followupAutoApproveTimeoutMs) @@ -52,7 +66,7 @@ export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1, o clearInterval(intervalId) // Notify parent component that this component is unmounting // so it can clear any related timeouts - onUnmount?.() + onCancelAutoApproval?.() } } else { setCountdown(null) @@ -63,7 +77,8 @@ export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1, o suggestions, followupAutoApproveTimeoutMs, suggestionSelected, - onUnmount, + onCancelAutoApproval, + isAnswered, ]) const handleSuggestionClick = useCallback( (suggestion: SuggestionItem, event: React.MouseEvent) => { @@ -72,14 +87,14 @@ export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1, o setSuggestionSelected(true) // Also notify parent component to cancel auto-approval timeout // This prevents race conditions between visual countdown and actual timeout - onUnmount?.() + onCancelAutoApproval?.() } // Pass the suggestion object to the parent component // The parent component will handle mode switching if needed onSuggestionClick?.(suggestion, event) }, - [onSuggestionClick, onUnmount], + [onSuggestionClick, onCancelAutoApproval], ) // Don't render if there are no suggestions or no click handler. @@ -100,7 +115,7 @@ export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1, o onClick={(event) => handleSuggestionClick(suggestion, event)} aria-label={suggestion.answer}> {suggestion.answer} - {isFirstSuggestion && countdown !== null && !suggestionSelected && ( + {isFirstSuggestion && countdown !== null && !suggestionSelected && !isAnswered && ( diff --git a/webview-ui/src/components/chat/IndexingStatusBadge.tsx b/webview-ui/src/components/chat/IndexingStatusBadge.tsx index 409ae64c24..f3c268c2ba 100644 --- a/webview-ui/src/components/chat/IndexingStatusBadge.tsx +++ b/webview-ui/src/components/chat/IndexingStatusBadge.tsx @@ -109,13 +109,17 @@ export const IndexingStatusDot: React.FC = ({ className onMouseEnter={handleMouseEnterButton} onMouseLeave={handleMouseLeaveButton} className={cn( - "flex items-center justify-center w-7 h-7 rounded-md", - "bg-transparent hover:bg-vscode-list-hoverBackground", - "cursor-pointer transition-all duration-200", - "opacity-85 hover:opacity-100 relative", + "relative inline-flex items-center justify-center", + "bg-transparent border-none p-1.5", + "rounded-md min-w-[28px] min-h-[28px]", + "opacity-85 text-vscode-foreground", + "transition-all duration-150", + "hover:opacity-100 hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]", + "focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder", + "active:bg-[rgba(255,255,255,0.1)]", + className, )} aria-label={getTooltipText()}> - {/* Status dot */} { const { t } = useTranslation() const { sharingEnabled, cloudIsAuthenticated, cloudUserInfo } = useExtensionState() const wasUnauthenticatedRef = useRef(false) + const initiatedAuthFromThisButtonRef = useRef(false) // Track authentication state changes to auto-open popover after login useEffect(() => { if (!cloudIsAuthenticated || !sharingEnabled) { wasUnauthenticatedRef.current = true } else if (wasUnauthenticatedRef.current && cloudIsAuthenticated && sharingEnabled) { - // User just authenticated, send telemetry, close modal, and open the popover - telemetryClient.capture(TelemetryEventName.ACCOUNT_CONNECT_SUCCESS) - setConnectModalOpen(false) - setShareDropdownOpen(true) + // Only open dropdown if auth was initiated from this button + if (initiatedAuthFromThisButtonRef.current) { + // User just authenticated from this share button, send telemetry, close modal, and open the popover + telemetryClient.capture(TelemetryEventName.ACCOUNT_CONNECT_SUCCESS) + setConnectModalOpen(false) + setShareDropdownOpen(true) + initiatedAuthFromThisButtonRef.current = false // Reset the flag + } wasUnauthenticatedRef.current = false } }, [cloudIsAuthenticated, sharingEnabled]) @@ -92,6 +97,8 @@ export const ShareButton = ({ item, disabled = false }: ShareButtonProps) => { // Send telemetry for connect to cloud action telemetryClient.capture(TelemetryEventName.SHARE_CONNECT_TO_CLOUD_CLICKED) + // Mark that authentication was initiated from this button + initiatedAuthFromThisButtonRef.current = true vscode.postMessage({ type: "rooCloudSignIn" }) setShareDropdownOpen(false) setConnectModalOpen(false) diff --git a/webview-ui/src/components/chat/__tests__/CodeIndexPopover.validation.spec.tsx b/webview-ui/src/components/chat/__tests__/CodeIndexPopover.validation.spec.tsx new file mode 100644 index 0000000000..4dd89288ea --- /dev/null +++ b/webview-ui/src/components/chat/__tests__/CodeIndexPopover.validation.spec.tsx @@ -0,0 +1,375 @@ +import React from "react" +import { render, screen, fireEvent, waitFor } from "@testing-library/react" +import { describe, it, expect, vi, beforeEach } from "vitest" +import { CodeIndexPopover } from "../CodeIndexPopover" + +// Mock the vscode API +vi.mock("@src/utils/vscode", () => ({ + vscode: { + postMessage: vi.fn(), + }, +})) + +// Mock the extension state context +vi.mock("@src/context/ExtensionStateContext", () => ({ + useExtensionState: vi.fn(), +})) + +// Mock the translation context +vi.mock("@src/i18n/TranslationContext", () => ({ + useAppTranslation: () => ({ t: vi.fn((key: string) => key) }), +})) + +// Mock react-i18next +vi.mock("react-i18next", () => ({ + Trans: ({ children }: { children: React.ReactNode }) =>
    {children}
    , +})) + +// Mock the doc links utility +vi.mock("@src/utils/docLinks", () => ({ + buildDocLink: vi.fn(() => "https://docs.roocode.com"), +})) + +// Mock the portal hook +vi.mock("@src/components/ui/hooks/useRooPortal", () => ({ + useRooPortal: () => ({ portalContainer: document.body }), +})) + +// Mock Radix UI components to avoid portal issues +vi.mock("@src/components/ui", () => ({ + Popover: ({ children }: { children: React.ReactNode }) =>
    {children}
    , + PopoverContent: ({ children }: { children: React.ReactNode }) =>
    {children}
    , + PopoverTrigger: ({ children }: { children: React.ReactNode }) =>
    {children}
    , + Select: ({ children }: { children: React.ReactNode }) =>
    {children}
    , + SelectContent: ({ children }: { children: React.ReactNode }) =>
    {children}
    , + SelectItem: ({ children, value }: { children: React.ReactNode; value: string }) => ( +
    + {children} +
    + ), + SelectTrigger: ({ children }: { children: React.ReactNode }) =>
    {children}
    , + SelectValue: ({ placeholder }: { placeholder?: string }) => {placeholder}, + AlertDialog: ({ children }: { children: React.ReactNode }) =>
    {children}
    , + AlertDialogAction: ({ children }: { children: React.ReactNode }) => , + AlertDialogCancel: ({ children }: { children: React.ReactNode }) => , + AlertDialogContent: ({ children }: { children: React.ReactNode }) =>
    {children}
    , + AlertDialogDescription: ({ children }: { children: React.ReactNode }) =>
    {children}
    , + AlertDialogFooter: ({ children }: { children: React.ReactNode }) =>
    {children}
    , + AlertDialogHeader: ({ children }: { children: React.ReactNode }) =>
    {children}
    , + AlertDialogTitle: ({ children }: { children: React.ReactNode }) =>
    {children}
    , + AlertDialogTrigger: ({ children }: { children: React.ReactNode }) =>
    {children}
    , + Slider: ({ value, onValueChange }: { value: number[]; onValueChange: (value: number[]) => void }) => ( + onValueChange([parseInt(e.target.value)])} /> + ), + StandardTooltip: ({ children }: { children: React.ReactNode }) =>
    {children}
    , + cn: (...classes: string[]) => classes.join(" "), +})) + +// Mock VSCode web components to behave like regular HTML inputs +vi.mock("@vscode/webview-ui-toolkit/react", () => ({ + VSCodeTextField: ({ value, onInput, placeholder, className, ...rest }: any) => ( + onInput && onInput(e)} + placeholder={placeholder} + className={className} + aria-label="Text field" + {...rest} + /> + ), + VSCodeButton: ({ children, onClick, ...rest }: any) => ( + + ), + VSCodeDropdown: ({ value, onChange, children, className, ...rest }: any) => ( + + ), + VSCodeOption: ({ value, children, ...rest }: any) => ( + + ), + VSCodeLink: ({ href, children, ...rest }: any) => ( + + {children} + + ), +})) + +// Helper function to simulate input on form elements +const simulateInput = (element: Element, value: string) => { + // Now that we're mocking VSCode components as regular HTML inputs, + // we can use standard fireEvent.change + fireEvent.change(element, { target: { value } }) +} + +describe("CodeIndexPopover Validation", () => { + let mockUseExtensionState: any + + beforeEach(async () => { + vi.clearAllMocks() + + // Get the mocked function + const { useExtensionState } = await import("@src/context/ExtensionStateContext") + mockUseExtensionState = vi.mocked(useExtensionState) + + // Setup default extension state + mockUseExtensionState.mockReturnValue({ + codebaseIndexConfig: { + codebaseIndexEnabled: false, + codebaseIndexQdrantUrl: "", + codebaseIndexEmbedderProvider: "openai", + codebaseIndexEmbedderBaseUrl: "", + codebaseIndexEmbedderModelId: "", + codebaseIndexSearchMaxResults: 10, + codebaseIndexSearchMinScore: 0.7, + codebaseIndexOpenAiCompatibleBaseUrl: "", + codebaseIndexEmbedderModelDimension: undefined, + }, + codebaseIndexModels: { + openai: [{ dimension: 1536 }], + }, + }) + }) + + const renderComponent = () => { + return render( + + + , + ) + } + + const openPopover = async () => { + const trigger = screen.getByText("Test Trigger") + fireEvent.click(trigger) + + // Wait for popover to open + await waitFor(() => { + expect(screen.getByRole("dialog")).toBeInTheDocument() + }) + } + + const expandSetupSection = async () => { + const setupButton = screen.getByText("settings:codeIndex.setupConfigLabel") + fireEvent.click(setupButton) + + // Wait for section to expand - look for vscode-text-field elements + await waitFor(() => { + const textFields = screen.getAllByLabelText("Text field") + expect(textFields.length).toBeGreaterThan(0) + }) + } + + describe("OpenAI Provider Validation", () => { + it("should show validation error when OpenAI API key is empty", async () => { + renderComponent() + await openPopover() + await expandSetupSection() + + // First, make a change to enable the save button by modifying the Qdrant URL + const qdrantUrlField = screen.getByPlaceholderText(/settings:codeIndex.qdrantUrlPlaceholder/i) + fireEvent.change(qdrantUrlField, { target: { value: "http://localhost:6333" } }) + + // Wait for the save button to become enabled + await waitFor(() => { + const saveButton = screen.getByText("settings:codeIndex.saveSettings") + expect(saveButton).not.toBeDisabled() + }) + + // Now clear the OpenAI API key to create a validation error + const apiKeyField = screen.getByPlaceholderText(/settings:codeIndex.openAiKeyPlaceholder/i) + fireEvent.change(apiKeyField, { target: { value: "" } }) + + // Click the save button to trigger validation + const saveButton = screen.getByText("settings:codeIndex.saveSettings") + fireEvent.click(saveButton) + + // Should show specific field error + await waitFor(() => { + expect(screen.getByText("settings:codeIndex.validation.openaiApiKeyRequired")).toBeInTheDocument() + }) + }) + + it("should show validation error when model is not selected", async () => { + renderComponent() + await openPopover() + await expandSetupSection() + + // First, make a change to enable the save button + const qdrantUrlField = screen.getByPlaceholderText(/settings:codeIndex.qdrantUrlPlaceholder/i) + fireEvent.change(qdrantUrlField, { target: { value: "http://localhost:6333" } }) + + // Set API key but leave model empty + const apiKeyField = screen.getByPlaceholderText(/settings:codeIndex.openAiKeyPlaceholder/i) + fireEvent.change(apiKeyField, { target: { value: "test-api-key" } }) + + // Wait for the save button to become enabled + await waitFor(() => { + const saveButton = screen.getByText("settings:codeIndex.saveSettings") + expect(saveButton).not.toBeDisabled() + }) + + const saveButton = screen.getByText("settings:codeIndex.saveSettings") + fireEvent.click(saveButton) + + await waitFor(() => { + expect(screen.getByText("settings:codeIndex.validation.modelSelectionRequired")).toBeInTheDocument() + }) + }) + }) + + describe("Qdrant URL Validation", () => { + it("should show validation error when Qdrant URL is empty", async () => { + renderComponent() + await openPopover() + await expandSetupSection() + + // First, make a change to enable the save button by setting API key + const apiKeyField = screen.getByPlaceholderText(/settings:codeIndex.openAiKeyPlaceholder/i) + fireEvent.change(apiKeyField, { target: { value: "test-api-key" } }) + + // Clear the Qdrant URL to create validation error + const qdrantUrlField = screen.getByPlaceholderText(/settings:codeIndex.qdrantUrlPlaceholder/i) + fireEvent.change(qdrantUrlField, { target: { value: "" } }) + + // Wait for the save button to become enabled + await waitFor(() => { + const saveButton = screen.getByText("settings:codeIndex.saveSettings") + expect(saveButton).not.toBeDisabled() + }) + + const saveButton = screen.getByText("settings:codeIndex.saveSettings") + fireEvent.click(saveButton) + + await waitFor(() => { + expect(screen.getByText("settings:codeIndex.validation.invalidQdrantUrl")).toBeInTheDocument() + }) + }) + + it("should show validation error when Qdrant URL is invalid", async () => { + renderComponent() + await openPopover() + await expandSetupSection() + + // First, make a change to enable the save button by setting API key + const apiKeyField = screen.getByPlaceholderText(/settings:codeIndex.openAiKeyPlaceholder/i) + fireEvent.change(apiKeyField, { target: { value: "test-api-key" } }) + + // Set invalid Qdrant URL + const qdrantUrlField = screen.getByPlaceholderText(/settings:codeIndex.qdrantUrlPlaceholder/i) + fireEvent.change(qdrantUrlField, { target: { value: "invalid-url" } }) + + // Wait for the save button to become enabled + await waitFor(() => { + const saveButton = screen.getByText("settings:codeIndex.saveSettings") + expect(saveButton).not.toBeDisabled() + }) + + const saveButton = screen.getByText("settings:codeIndex.saveSettings") + fireEvent.click(saveButton) + + await waitFor(() => { + expect(screen.getByText("settings:codeIndex.validation.invalidQdrantUrl")).toBeInTheDocument() + }) + }) + }) + + describe("Common Field Validation", () => { + it("should not show validation error for optional Qdrant API key", async () => { + renderComponent() + await openPopover() + await expandSetupSection() + + // Set required fields to make form valid + const qdrantUrlField = screen.getByPlaceholderText(/settings:codeIndex.qdrantUrlPlaceholder/i) + fireEvent.change(qdrantUrlField, { target: { value: "http://localhost:6333" } }) + + const apiKeyField = screen.getByPlaceholderText(/settings:codeIndex.openAiKeyPlaceholder/i) + fireEvent.change(apiKeyField, { target: { value: "test-api-key" } }) + + // Select a model - this is required (get the select element specifically) + const modelSelect = screen.getAllByRole("combobox").find((el) => el.tagName === "SELECT") + if (modelSelect) { + fireEvent.change(modelSelect, { target: { value: "0" } }) + } + + // Leave Qdrant API key empty (it's optional) + const qdrantApiKeyField = screen.getByPlaceholderText(/settings:codeIndex.qdrantApiKeyPlaceholder/i) + fireEvent.change(qdrantApiKeyField, { target: { value: "" } }) + + // Wait for the save button to become enabled + await waitFor(() => { + const saveButton = screen.getByText("settings:codeIndex.saveSettings") + expect(saveButton).not.toBeDisabled() + }) + + const saveButton = screen.getByText("settings:codeIndex.saveSettings") + fireEvent.click(saveButton) + + // Should not show validation errors since Qdrant API key is optional + }) + + it("should clear validation errors when fields are corrected", async () => { + renderComponent() + await openPopover() + await expandSetupSection() + + // First make an invalid change to enable the save button and trigger validation + const textFields = screen.getAllByLabelText("Text field") + const qdrantField = textFields.find((field) => + field.getAttribute("placeholder")?.toLowerCase().includes("qdrant"), + ) + + if (qdrantField) { + simulateInput(qdrantField, "invalid-url") // Invalid URL to trigger validation + } + + // Wait for save button to be enabled + const saveButton = screen.getByText("settings:codeIndex.saveSettings") + await waitFor(() => { + expect(saveButton).not.toBeDisabled() + }) + + // Click save to trigger validation errors + fireEvent.click(saveButton) + + // Now fix the errors with valid values + const apiKeyField = textFields.find( + (field) => + field.getAttribute("placeholder")?.toLowerCase().includes("openai") || + field.getAttribute("placeholder")?.toLowerCase().includes("key"), + ) + + // Set valid Qdrant URL + if (qdrantField) { + simulateInput(qdrantField, "http://localhost:6333") + } + + // Set API key + if (apiKeyField) { + simulateInput(apiKeyField, "test-api-key") + } + + // Select a model - this is required (get the select element specifically) + const modelSelect = screen.getAllByRole("combobox").find((el) => el.tagName === "SELECT") + if (modelSelect) { + fireEvent.change(modelSelect, { target: { value: "0" } }) + } + + // Try to save again + fireEvent.click(saveButton) + + // Validation errors should be cleared (specific field errors are checked elsewhere) + }) + }) +}) diff --git a/webview-ui/src/components/chat/__tests__/FollowUpSuggest.spec.tsx b/webview-ui/src/components/chat/__tests__/FollowUpSuggest.spec.tsx new file mode 100644 index 0000000000..aa3f84fd8c --- /dev/null +++ b/webview-ui/src/components/chat/__tests__/FollowUpSuggest.spec.tsx @@ -0,0 +1,414 @@ +import React, { createContext, useContext } from "react" +import { render, screen, act } from "@testing-library/react" + +import { describe, it, expect, vi, beforeEach, afterEach } from "vitest" +import { FollowUpSuggest } from "../FollowUpSuggest" +import { TooltipProvider } from "@radix-ui/react-tooltip" + +// Mock the translation hook +vi.mock("@src/i18n/TranslationContext", () => ({ + TranslationProvider: ({ children }: { children: React.ReactNode }) => children, + useAppTranslation: () => ({ + t: (key: string, options?: any) => { + if (key === "chat:followUpSuggest.countdownDisplay" && options?.count !== undefined) { + return `${options.count}s` + } + if (key === "chat:followUpSuggest.autoSelectCountdown" && options?.count !== undefined) { + return `Auto-selecting in ${options.count} seconds` + } + if (key === "chat:followUpSuggest.copyToInput") { + return "Copy to input" + } + return key + }, + }), +})) + +// Test-specific extension state context that only provides the values needed by FollowUpSuggest +interface TestExtensionState { + autoApprovalEnabled: boolean + alwaysAllowFollowupQuestions: boolean + followupAutoApproveTimeoutMs: number +} + +const TestExtensionStateContext = createContext(undefined) + +// Mock the useExtensionState hook to use our test context +vi.mock("@src/context/ExtensionStateContext", () => ({ + useExtensionState: () => { + const context = useContext(TestExtensionStateContext) + if (!context) { + throw new Error("useExtensionState must be used within TestExtensionStateProvider") + } + return context + }, +})) + +// Test provider that only provides the specific values needed by FollowUpSuggest +const TestExtensionStateProvider: React.FC<{ + children: React.ReactNode + value: TestExtensionState +}> = ({ children, value }) => { + return {children} +} + +// Helper function to render component with test providers +const renderWithTestProviders = (component: React.ReactElement, extensionState: TestExtensionState) => { + return render( + + {component} + , + ) +} + +describe("FollowUpSuggest", () => { + const mockSuggestions = [{ answer: "First suggestion" }, { answer: "Second suggestion" }] + + const mockOnSuggestionClick = vi.fn() + const mockOnCancelAutoApproval = vi.fn() + + // Default test state with auto-approval enabled + const defaultTestState: TestExtensionState = { + autoApprovalEnabled: true, + alwaysAllowFollowupQuestions: true, + followupAutoApproveTimeoutMs: 3000, // 3 seconds for testing + } + + beforeEach(() => { + vi.clearAllMocks() + vi.useFakeTimers() + }) + + afterEach(() => { + vi.useRealTimers() + }) + + it("should display countdown timer when auto-approval is enabled", () => { + renderWithTestProviders( + , + defaultTestState, + ) + + // Should show initial countdown (3 seconds) + expect(screen.getByText(/3s/)).toBeInTheDocument() + }) + + it("should not display countdown timer when isAnswered is true", () => { + renderWithTestProviders( + , + defaultTestState, + ) + + // Should not show countdown + expect(screen.queryByText(/\d+s/)).not.toBeInTheDocument() + }) + + it("should clear interval and call onCancelAutoApproval when component unmounts", () => { + const { unmount } = renderWithTestProviders( + , + defaultTestState, + ) + + // Unmount the component + unmount() + + // onCancelAutoApproval should have been called + expect(mockOnCancelAutoApproval).toHaveBeenCalled() + }) + + it("should not show countdown when auto-approval is disabled", () => { + const testState: TestExtensionState = { + ...defaultTestState, + autoApprovalEnabled: false, + } + + renderWithTestProviders( + , + testState, + ) + + // Should not show countdown + expect(screen.queryByText(/\d+s/)).not.toBeInTheDocument() + }) + + it("should not show countdown when alwaysAllowFollowupQuestions is false", () => { + const testState: TestExtensionState = { + ...defaultTestState, + alwaysAllowFollowupQuestions: false, + } + + renderWithTestProviders( + , + testState, + ) + + // Should not show countdown + expect(screen.queryByText(/\d+s/)).not.toBeInTheDocument() + }) + + it("should use custom timeout value from extension state", () => { + const testState: TestExtensionState = { + ...defaultTestState, + followupAutoApproveTimeoutMs: 5000, // 5 seconds + } + + renderWithTestProviders( + , + testState, + ) + + // Should show initial countdown (5 seconds) + expect(screen.getByText(/5s/)).toBeInTheDocument() + }) + + it("should render suggestions without countdown when both auto-approval settings are disabled", () => { + const testState: TestExtensionState = { + autoApprovalEnabled: false, + alwaysAllowFollowupQuestions: false, + followupAutoApproveTimeoutMs: 3000, + } + + renderWithTestProviders( + , + testState, + ) + + // Should render suggestions + expect(screen.getByText("First suggestion")).toBeInTheDocument() + expect(screen.getByText("Second suggestion")).toBeInTheDocument() + + // Should not show countdown + expect(screen.queryByText(/\d+s/)).not.toBeInTheDocument() + }) + + it("should not render when no suggestions are provided", () => { + const { container } = renderWithTestProviders( + , + defaultTestState, + ) + + // Component should not render anything + expect(container.firstChild).toBeNull() + }) + + it("should not render when onSuggestionClick is not provided", () => { + const { container } = renderWithTestProviders( + , + defaultTestState, + ) + + // Component should not render anything + expect(container.firstChild).toBeNull() + }) + + it("should stop countdown when user manually responds (isAnswered becomes true)", () => { + const { rerender } = renderWithTestProviders( + , + defaultTestState, + ) + + // Initially should show countdown + expect(screen.getByText(/3s/)).toBeInTheDocument() + + // Simulate user manually responding by setting isAnswered to true + rerender( + + + + + , + ) + + // Countdown should no longer be visible immediately after isAnswered becomes true + expect(screen.queryByText(/\d+s/)).not.toBeInTheDocument() + + // Advance timer to ensure countdown doesn't restart or continue + vi.advanceTimersByTime(5000) + + // onSuggestionClick should not have been called (auto-selection stopped) + expect(mockOnSuggestionClick).not.toHaveBeenCalled() + + // Countdown should still not be visible + expect(screen.queryByText(/\d+s/)).not.toBeInTheDocument() + + // Verify onCancelAutoApproval was called when the countdown was stopped + expect(mockOnCancelAutoApproval).toHaveBeenCalled() + }) + + it("should handle race condition when timeout fires but user has already responded", () => { + // This test simulates the scenario where: + // 1. Auto-approval countdown starts + // 2. User manually responds (isAnswered becomes true) + // 3. The timeout still fires (because it was already scheduled) + // 4. The auto-selection should NOT happen because user already responded + + const { rerender } = renderWithTestProviders( + , + defaultTestState, + ) + + // Initially should show countdown + expect(screen.getByText(/3s/)).toBeInTheDocument() + + // Advance timer to just before timeout completes (2.5 seconds) + vi.advanceTimersByTime(2500) + + // User manually responds before timeout completes + rerender( + + + + + , + ) + + // Countdown should be hidden immediately + expect(screen.queryByText(/\d+s/)).not.toBeInTheDocument() + + // Now advance timer past the original timeout duration + vi.advanceTimersByTime(1000) // Total: 3.5 seconds + + // onSuggestionClick should NOT have been called + // This verifies the fix for the race condition + expect(mockOnSuggestionClick).not.toHaveBeenCalled() + }) + + it("should update countdown display as time progresses", async () => { + renderWithTestProviders( + , + defaultTestState, + ) + + // Initially should show 3s + expect(screen.getByText(/3s/)).toBeInTheDocument() + + // Advance timer by 1 second and wait for React to update + await act(async () => { + vi.advanceTimersByTime(1000) + }) + + // Check countdown updated to 2s + expect(screen.getByText(/2s/)).toBeInTheDocument() + + // Advance timer by another second + await act(async () => { + vi.advanceTimersByTime(1000) + }) + + // Check countdown updated to 1s + expect(screen.getByText(/1s/)).toBeInTheDocument() + + // Advance timer to completion - countdown should disappear + await act(async () => { + vi.advanceTimersByTime(1000) + }) + + // Countdown should no longer be visible after reaching 0 + expect(screen.queryByText(/\d+s/)).not.toBeInTheDocument() + + // The component itself doesn't trigger auto-selection, that's handled by ChatView + expect(mockOnSuggestionClick).not.toHaveBeenCalled() + }) + + it("should handle component unmounting during countdown", () => { + const { unmount } = renderWithTestProviders( + , + defaultTestState, + ) + + // Initially should show countdown + expect(screen.getByText(/3s/)).toBeInTheDocument() + + // Advance timer partially + vi.advanceTimersByTime(1500) + + // Unmount component before countdown completes + unmount() + + // onCancelAutoApproval should have been called + expect(mockOnCancelAutoApproval).toHaveBeenCalled() + + // Advance timer past the original timeout + vi.advanceTimersByTime(2000) + + // onSuggestionClick should NOT have been called (component doesn't auto-select) + expect(mockOnSuggestionClick).not.toHaveBeenCalled() + }) +}) diff --git a/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx b/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx index 2d9ea0cac1..5db6287747 100644 --- a/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx @@ -265,7 +265,7 @@ describe("TaskActions", () => { expect(screen.queryByText("Connect to Cloud")).not.toBeInTheDocument() }) - it("automatically opens popover when user becomes authenticated", () => { + it("does not automatically open popover when user becomes authenticated from elsewhere", () => { // Start with unauthenticated state mockUseExtensionState.mockReturnValue({ sharingEnabled: false, @@ -277,7 +277,7 @@ describe("TaskActions", () => { // Verify popover is not open initially expect(screen.queryByText("Share with Organization")).not.toBeInTheDocument() - // Simulate user becoming authenticated + // Simulate user becoming authenticated (e.g., from AccountView) mockUseExtensionState.mockReturnValue({ sharingEnabled: true, cloudIsAuthenticated: true, @@ -288,7 +288,47 @@ describe("TaskActions", () => { rerender() - // Verify popover automatically opens and shows sharing options + // Verify popover does NOT automatically open when auth happens from elsewhere + expect(screen.queryByText("Share with Organization")).not.toBeInTheDocument() + expect(screen.queryByText("Share Publicly")).not.toBeInTheDocument() + }) + + it("automatically opens popover when user authenticates from share button", () => { + // Start with unauthenticated state + mockUseExtensionState.mockReturnValue({ + sharingEnabled: false, + cloudIsAuthenticated: false, + } as any) + + const { rerender } = render() + + // Click share button to open connect modal + const buttons = screen.getAllByRole("button") + const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) + expect(shareButton).toBeDefined() + fireEvent.click(shareButton!) + + // Click connect button to initiate authentication + const connectButton = screen.getByText("Connect") + fireEvent.click(connectButton) + + // Verify rooCloudSignIn message was sent + expect(mockPostMessage).toHaveBeenCalledWith({ + type: "rooCloudSignIn", + }) + + // Simulate user becoming authenticated after clicking connect from share button + mockUseExtensionState.mockReturnValue({ + sharingEnabled: true, + cloudIsAuthenticated: true, + cloudUserInfo: { + organizationName: "Test Organization", + }, + } as any) + + rerender() + + // Verify popover automatically opens when auth was initiated from share button expect(screen.getByText("Share with Organization")).toBeInTheDocument() expect(screen.getByText("Share Publicly")).toBeInTheDocument() }) diff --git a/webview-ui/src/components/settings/ApiConfigManager.tsx b/webview-ui/src/components/settings/ApiConfigManager.tsx index edd0a5fe07..e737678c01 100644 --- a/webview-ui/src/components/settings/ApiConfigManager.tsx +++ b/webview-ui/src/components/settings/ApiConfigManager.tsx @@ -1,28 +1,12 @@ import { memo, useEffect, useRef, useState } from "react" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ChevronsUpDown, Check, X, AlertTriangle } from "lucide-react" +import { AlertTriangle } from "lucide-react" import type { ProviderSettingsEntry, OrganizationAllowList } from "@roo-code/types" import { useAppTranslation } from "@/i18n/TranslationContext" -import { cn } from "@/lib/utils" -import { - Button, - Input, - Dialog, - DialogContent, - DialogTitle, - Command, - CommandEmpty, - CommandGroup, - CommandInput, - CommandItem, - CommandList, - Popover, - PopoverContent, - PopoverTrigger, - StandardTooltip, -} from "@/components/ui" +import { Button, Input, Dialog, DialogContent, DialogTitle, StandardTooltip, SearchableSelect } from "@/components/ui" +import type { SearchableSelectOption } from "@/components/ui" interface ApiConfigManagerProps { currentApiConfigName?: string @@ -50,12 +34,8 @@ const ApiConfigManager = ({ const [inputValue, setInputValue] = useState("") const [newProfileName, setNewProfileName] = useState("") const [error, setError] = useState(null) - const [open, setOpen] = useState(false) - const [searchValue, setSearchValue] = useState("") const inputRef = useRef(null) const newProfileInputRef = useRef(null) - const searchInputRef = useRef(null) - const searchResetTimeoutRef = useRef(null) // Check if a profile is valid based on the organization allow list const isProfileValid = (profile: ProviderSettingsEntry): boolean => { @@ -128,42 +108,10 @@ const ApiConfigManager = ({ useEffect(() => { resetCreateState() resetRenameState() - // Reset search value when current profile changes - const timeoutId = setTimeout(() => setSearchValue(""), 100) - return () => clearTimeout(timeoutId) }, [currentApiConfigName]) - // Cleanup timeout on unmount - useEffect(() => { - return () => { - if (searchResetTimeoutRef.current) { - clearTimeout(searchResetTimeoutRef.current) - } - } - }, []) - - const onOpenChange = (open: boolean) => { - setOpen(open) - - // Reset search when closing the popover - if (!open) { - // Clear any existing timeout - if (searchResetTimeoutRef.current) { - clearTimeout(searchResetTimeoutRef.current) - } - searchResetTimeoutRef.current = setTimeout(() => setSearchValue(""), 100) - } - } - - const onClearSearch = () => { - setSearchValue("") - searchInputRef.current?.focus() - } - const handleSelectConfig = (configName: string) => { if (!configName) return - - setOpen(false) onSelectConfig(configName) } @@ -278,95 +226,30 @@ const ApiConfigManager = ({ ) : ( <>
    - - - - - - -
    - - {searchValue.length > 0 && ( -
    - -
    - )} -
    - - - {searchValue && ( -
    - {t("settings:providers.noMatchFound")} -
    - )} -
    - - {listApiConfigMeta - .filter((config) => - searchValue - ? config.name.toLowerCase().includes(searchValue.toLowerCase()) - : true, - ) - .map((config) => { - const valid = isProfileValid(config) - return ( - -
    - {!valid && ( - - - - - - )} - {config.name} -
    - -
    - ) - })} -
    -
    -
    -
    -
    + { + const valid = isProfileValid(config) + return { + value: config.name, + label: config.name, + disabled: !valid, + icon: !valid ? ( + + + + + + ) : undefined, + } as SearchableSelectOption + })} + placeholder={t("settings:common.select")} + searchPlaceholder={t("settings:providers.searchPlaceholder")} + emptyMessage={t("settings:providers.noMatchFound")} + className="grow" + data-testid="select-component" + />
    {errorMessage && } diff --git a/webview-ui/src/components/settings/AutoApproveSettings.tsx b/webview-ui/src/components/settings/AutoApproveSettings.tsx index 71283a833b..3521653892 100644 --- a/webview-ui/src/components/settings/AutoApproveSettings.tsx +++ b/webview-ui/src/components/settings/AutoApproveSettings.tsx @@ -26,6 +26,7 @@ type AutoApproveSettingsProps = HTMLAttributes & { alwaysAllowSubtasks?: boolean alwaysAllowExecute?: boolean alwaysAllowFollowupQuestions?: boolean + alwaysAllowUpdateTodoList?: boolean followupAutoApproveTimeoutMs?: number allowedCommands?: string[] setCachedStateField: SetCachedStateField< @@ -65,6 +66,7 @@ export const AutoApproveSettings = ({ alwaysAllowExecute, alwaysAllowFollowupQuestions, followupAutoApproveTimeoutMs = 60000, + alwaysAllowUpdateTodoList, allowedCommands, setCachedStateField, ...props @@ -103,6 +105,7 @@ export const AutoApproveSettings = ({ alwaysAllowSubtasks={alwaysAllowSubtasks} alwaysAllowExecute={alwaysAllowExecute} alwaysAllowFollowupQuestions={alwaysAllowFollowupQuestions} + alwaysAllowUpdateTodoList={alwaysAllowUpdateTodoList} onToggle={(key, value) => setCachedStateField(key, value)} /> diff --git a/webview-ui/src/components/settings/ExperimentalSettings.tsx b/webview-ui/src/components/settings/ExperimentalSettings.tsx index 958c7742fd..53801232ec 100644 --- a/webview-ui/src/components/settings/ExperimentalSettings.tsx +++ b/webview-ui/src/components/settings/ExperimentalSettings.tsx @@ -1,40 +1,26 @@ import { HTMLAttributes } from "react" import { FlaskConical } from "lucide-react" -import { VSCodeCheckbox, VSCodeLink } from "@vscode/webview-ui-toolkit/react" -import { Trans } from "react-i18next" -import type { Experiments, CodebaseIndexConfig, CodebaseIndexModels } from "@roo-code/types" +import type { Experiments } from "@roo-code/types" import { EXPERIMENT_IDS, experimentConfigsMap } from "@roo/experiments" import { useAppTranslation } from "@src/i18n/TranslationContext" import { cn } from "@src/lib/utils" -import { buildDocLink } from "@src/utils/docLinks" import { SetExperimentEnabled } from "./types" import { SectionHeader } from "./SectionHeader" import { Section } from "./Section" import { ExperimentalFeature } from "./ExperimentalFeature" -import { SetCachedStateField } from "./types" type ExperimentalSettingsProps = HTMLAttributes & { experiments: Experiments setExperimentEnabled: SetExperimentEnabled - // CodeIndexSettings props - codebaseIndexModels: CodebaseIndexModels | undefined - codebaseIndexConfig: CodebaseIndexConfig | undefined - // For codebase index enabled toggle - codebaseIndexEnabled?: boolean - setCachedStateField?: SetCachedStateField } export const ExperimentalSettings = ({ experiments, setExperimentEnabled, - codebaseIndexModels, - codebaseIndexConfig, - codebaseIndexEnabled, - setCachedStateField, className, ...props }: ExperimentalSettingsProps) => { @@ -79,32 +65,6 @@ export const ExperimentalSettings = ({ /> ) })} - - {/* Codebase Indexing Enable/Disable Toggle */} -
    -
    - { - const newEnabledState = e.target.checked - if (setCachedStateField && codebaseIndexConfig) { - setCachedStateField("codebaseIndexConfig", { - ...codebaseIndexConfig, - codebaseIndexEnabled: newEnabledState, - }) - } - }}> - {t("settings:codeIndex.enableLabel")} - -
    -

    - - - -

    -
    ) diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 3ece8146af..8550be1e1b 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -170,11 +170,10 @@ const SettingsView = forwardRef(({ onDone, t maxConcurrentFileReads, condensingApiConfigId, customCondensingPrompt, - codebaseIndexConfig, - codebaseIndexModels, customSupportPrompts, profileThresholds, alwaysAllowFollowupQuestions, + alwaysAllowUpdateTodoList, followupAutoApproveTimeoutMs, } = cachedState @@ -314,15 +313,13 @@ const SettingsView = forwardRef(({ onDone, t vscode.postMessage({ type: "alwaysAllowModeSwitch", bool: alwaysAllowModeSwitch }) vscode.postMessage({ type: "alwaysAllowSubtasks", bool: alwaysAllowSubtasks }) vscode.postMessage({ type: "alwaysAllowFollowupQuestions", bool: alwaysAllowFollowupQuestions }) + vscode.postMessage({ type: "alwaysAllowUpdateTodoList", bool: alwaysAllowUpdateTodoList }) vscode.postMessage({ type: "followupAutoApproveTimeoutMs", value: followupAutoApproveTimeoutMs }) vscode.postMessage({ type: "condensingApiConfigId", text: condensingApiConfigId || "" }) vscode.postMessage({ type: "updateCondensingPrompt", text: customCondensingPrompt || "" }) vscode.postMessage({ type: "updateSupportPrompt", values: customSupportPrompts || {} }) vscode.postMessage({ type: "upsertApiConfiguration", text: currentApiConfigName, apiConfiguration }) vscode.postMessage({ type: "telemetrySetting", text: telemetrySetting }) - if (codebaseIndexConfig) { - vscode.postMessage({ type: "codebaseIndexEnabled", bool: codebaseIndexConfig.codebaseIndexEnabled }) - } vscode.postMessage({ type: "profileThresholds", values: profileThresholds }) setChangeDetected(false) } @@ -606,6 +603,7 @@ const SettingsView = forwardRef(({ onDone, t alwaysAllowSubtasks={alwaysAllowSubtasks} alwaysAllowExecute={alwaysAllowExecute} alwaysAllowFollowupQuestions={alwaysAllowFollowupQuestions} + alwaysAllowUpdateTodoList={alwaysAllowUpdateTodoList} followupAutoApproveTimeoutMs={followupAutoApproveTimeoutMs} allowedCommands={allowedCommands} setCachedStateField={setCachedStateField} @@ -688,14 +686,7 @@ const SettingsView = forwardRef(({ onDone, t {/* Experimental Section */} {activeTab === "experimental" && ( - + )} {/* Language Section */} diff --git a/webview-ui/src/components/settings/__tests__/ApiConfigManager.spec.tsx b/webview-ui/src/components/settings/__tests__/ApiConfigManager.spec.tsx index 194f0ff31e..152d853444 100644 --- a/webview-ui/src/components/settings/__tests__/ApiConfigManager.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/ApiConfigManager.spec.tsx @@ -89,6 +89,21 @@ vitest.mock("@/components/ui", () => ({ {children} ), + SearchableSelect: ({ value, onValueChange, options, placeholder, "data-testid": dataTestId }: any) => ( + + ), })) describe("ApiConfigManager", () => { @@ -243,20 +258,11 @@ describe("ApiConfigManager", () => { it("allows selecting a different config", () => { render() - // Click the select component to open the dropdown - const selectButton = screen.getByTestId("select-component") - fireEvent.click(selectButton) + // The SearchableSelect mock renders as a simple select element + const selectElement = screen.getByTestId("select-component") as HTMLSelectElement - // Find all command items and click the one with "Another Config" - const commandItems = document.querySelectorAll(".command-item") - // Find the item with "Another Config" text - const anotherConfigItem = Array.from(commandItems).find((item) => item.textContent?.includes("Another Config")) - - if (!anotherConfigItem) { - throw new Error("Could not find 'Another Config' option") - } - - fireEvent.click(anotherConfigItem) + // Change the select value to "Another Config" + fireEvent.change(selectElement, { target: { value: "Another Config" } }) expect(mockOnSelectConfig).toHaveBeenCalledWith("Another Config") }) diff --git a/webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx b/webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx index 1e13323f36..07331b8e42 100644 --- a/webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx @@ -88,6 +88,18 @@ vi.mock("@/components/ui", () => ({ onChange(parseFloat(e.target.value))} />
    ), + SearchableSelect: ({ value, onValueChange, options, placeholder, "data-testid": dataTestId }: any) => ( +
    + +
    + ), })) vi.mock("../TemperatureControl", () => ({ @@ -291,6 +303,32 @@ describe("ApiOptions", () => { // since we have separate tests for that component. We just need to verify that // it's included in the ApiOptions component when appropriate. }) + it("filters providers by search input and shows no match message when appropriate", () => { + renderApiOptions({ + apiConfiguration: {}, + setApiConfigurationField: () => {}, + }) + + // The SearchableSelect mock renders inside a div with the test id + const providerSelectContainer = screen.getByTestId("provider-select") + expect(providerSelectContainer).toBeInTheDocument() + + // Get the actual select element inside the container + const providerSelect = providerSelectContainer.querySelector("select") as HTMLSelectElement + expect(providerSelect).toBeInTheDocument() + + // Check that we have options + const options = providerSelect.querySelectorAll("option") + expect(options.length).toBeGreaterThan(1) // Should have placeholder + actual options + + // Check that OpenAI option exists + const optionTexts = Array.from(options).map((opt) => opt.textContent) + expect(optionTexts).toContain("OpenAI") + expect(optionTexts).toContain("Anthropic") + + // Note: The mock doesn't implement search functionality, so we're just verifying + // that the select element is rendered with the expected options + }) describe("OpenAI provider tests", () => { it("removes reasoningEffort from openAiCustomModelInfo when unchecked", () => { diff --git a/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx b/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx index 0a76e54ffe..404b3a6883 100644 --- a/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx @@ -102,6 +102,21 @@ vi.mock("../../../components/common/Tab", () => ({ vi.mock("@/components/ui", () => ({ ...vi.importActual("@/components/ui"), + Popover: ({ children }: any) =>
    {children}
    , + PopoverTrigger: ({ children }: any) =>
    {children}
    , + PopoverContent: ({ children }: any) =>
    {children}
    , + Command: ({ children }: any) =>
    {children}
    , + CommandInput: ({ value, onValueChange }: any) => ( + onValueChange(e.target.value)} /> + ), + CommandGroup: ({ children }: any) =>
    {children}
    , + CommandItem: ({ children, onSelect }: any) => ( +
    + {children} +
    + ), + CommandList: ({ children }: any) =>
    {children}
    , + CommandEmpty: ({ children }: any) =>
    {children}
    , Slider: ({ value, onValueChange, "data-testid": dataTestId }: any) => ( ({ ), SelectTrigger: ({ children }: any) =>
    {children}
    , SelectValue: ({ placeholder }: any) =>
    {placeholder}
    , + SearchableSelect: ({ value, onValueChange, options, placeholder }: any) => ( + + ), AlertDialog: ({ children, open }: any) => (
    {children} diff --git a/webview-ui/src/components/ui/index.ts b/webview-ui/src/components/ui/index.ts index 5bd6b62ee8..c36d3b4769 100644 --- a/webview-ui/src/components/ui/index.ts +++ b/webview-ui/src/components/ui/index.ts @@ -10,6 +10,7 @@ export * from "./dropdown-menu" export * from "./input" export * from "./popover" export * from "./progress" +export * from "./searchable-select" export * from "./separator" export * from "./slider" export * from "./select-dropdown" diff --git a/webview-ui/src/components/ui/searchable-select.tsx b/webview-ui/src/components/ui/searchable-select.tsx new file mode 100644 index 0000000000..7317dda781 --- /dev/null +++ b/webview-ui/src/components/ui/searchable-select.tsx @@ -0,0 +1,176 @@ +import * as React from "react" +import { Check, ChevronDown, X } from "lucide-react" +import { cn } from "@/lib/utils" +import { + Button, + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui" + +export interface SearchableSelectOption { + value: string + label: string + disabled?: boolean + icon?: React.ReactNode +} + +interface SearchableSelectProps { + value?: string + onValueChange: (value: string) => void + options: SearchableSelectOption[] + placeholder: string + searchPlaceholder: string + emptyMessage: string + className?: string + disabled?: boolean + "data-testid"?: string +} + +export function SearchableSelect({ + value, + onValueChange, + options, + placeholder, + searchPlaceholder, + emptyMessage, + className, + disabled, + "data-testid": dataTestId, +}: SearchableSelectProps) { + const [open, setOpen] = React.useState(false) + const [searchValue, setSearchValue] = React.useState("") + const searchInputRef = React.useRef(null) + const searchResetTimeoutRef = React.useRef(null) + const isMountedRef = React.useRef(true) + + // Find the selected option + const selectedOption = options.find((option) => option.value === value) + + // Filter options based on search + const filteredOptions = React.useMemo(() => { + if (!searchValue) return options + return options.filter((option) => option.label.toLowerCase().includes(searchValue.toLowerCase())) + }, [options, searchValue]) + + // Cleanup timeout on unmount + React.useEffect(() => { + return () => { + isMountedRef.current = false + if (searchResetTimeoutRef.current) { + clearTimeout(searchResetTimeoutRef.current) + } + } + }, []) + + // Reset search when value changes + React.useEffect(() => { + const timeoutId = setTimeout(() => { + if (isMountedRef.current) { + setSearchValue("") + } + }, 100) + return () => clearTimeout(timeoutId) + }, [value]) + + const handleOpenChange = (open: boolean) => { + setOpen(open) + // Reset search when closing + if (!open) { + if (searchResetTimeoutRef.current) { + clearTimeout(searchResetTimeoutRef.current) + } + searchResetTimeoutRef.current = setTimeout(() => setSearchValue(""), 100) + } + } + + const handleSelect = (selectedValue: string) => { + setOpen(false) + onValueChange(selectedValue) + } + + const handleClearSearch = () => { + setSearchValue("") + searchInputRef.current?.focus() + } + + return ( + + + + + + +
    + + {searchValue.length > 0 && ( +
    + +
    + )} +
    + + + {searchValue &&
    {emptyMessage}
    } +
    + + {filteredOptions.map((option) => ( + handleSelect(option.value)} + disabled={option.disabled} + className={option.disabled ? "text-vscode-errorForeground" : ""}> +
    + {option.icon} + {option.label} +
    + +
    + ))} +
    +
    +
    +
    +
    + ) +} diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index df7cee5627..bf927211c2 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -214,7 +214,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode autoCondenseContextPercent: 100, profileThresholds: {}, codebaseIndexConfig: { - codebaseIndexEnabled: false, + codebaseIndexEnabled: true, codebaseIndexQdrantUrl: "http://localhost:6333", codebaseIndexEmbedderProvider: "openai", codebaseIndexEmbedderBaseUrl: "", diff --git a/webview-ui/src/i18n/locales/ca/chat.json b/webview-ui/src/i18n/locales/ca/chat.json index 1dd892a39f..848306a1cf 100644 --- a/webview-ui/src/i18n/locales/ca/chat.json +++ b/webview-ui/src/i18n/locales/ca/chat.json @@ -242,8 +242,8 @@ "title": "🎉 Roo Code {{version}} Llançat", "description": "Roo Code {{version}} porta noves funcions potents i millores significatives per millorar el vostre flux de treball de desenvolupament.", "whatsNew": "Novetats", - "feature1": "Compartició de Tasques amb 1 Clic: Comparteix instantàniament les vostres tasques amb companys i la comunitat amb un sol clic.", - "feature2": "Suport per a Directori Global .roo: Carrega regles i configuracions des d'un directori global .roo per a configuracions consistents entre projectes.", + "feature1": "Indexació de Base de Codi Graduada d'Experimental: La indexació completa de la base de codi ara és estable i està llesta per a ús en producció amb cerca millorada i comprensió del context.", + "feature2": "Nova Funcionalitat de Llista de Tasques Pendents: Mantingueu les vostres tasques en el bon camí amb gestió integrada de tasques pendents que us ajuda a mantenir-vos organitzats i centrats en els vostres objectius de desenvolupament.", "feature3": "Transicions Millorades d'Arquitecte a Codi: Transferències fluides de la planificació en mode Arquitecte a la implementació en mode Codi.", "hideButton": "Amaga l'anunci", "detailsDiscussLinks": "Obtén més detalls i uneix-te a les discussions a Discord i Reddit 🚀" diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index ca1808ef89..72b8df4892 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -81,6 +81,7 @@ "ollamaBaseUrlLabel": "URL base d'Ollama", "qdrantApiKeyLabel": "Clau API de Qdrant", "qdrantApiKeyPlaceholder": "Introduïu la vostra clau API de Qdrant (opcional)", + "setupConfigLabel": "Configuració", "ollamaUrlPlaceholder": "http://localhost:11434", "openAiCompatibleBaseUrlPlaceholder": "https://api.example.com", "modelDimensionPlaceholder": "1536", @@ -97,6 +98,21 @@ "error": "Error" }, "close": "Tancar", + "validation": { + "invalidQdrantUrl": "URL de Qdrant no vàlida", + "invalidOllamaUrl": "URL d'Ollama no vàlida", + "invalidBaseUrl": "URL de base no vàlida", + "qdrantUrlRequired": "Cal una URL de Qdrant", + "openaiApiKeyRequired": "Cal una clau d'API d'OpenAI", + "modelSelectionRequired": "Cal seleccionar un model", + "apiKeyRequired": "Cal una clau d'API", + "modelIdRequired": "Cal un ID de model", + "modelDimensionRequired": "Cal una dimensió de model", + "geminiApiKeyRequired": "Cal una clau d'API de Gemini", + "ollamaBaseUrlRequired": "Cal una URL base d'Ollama", + "baseUrlRequired": "Cal una URL base", + "modelDimensionMinValue": "La dimensió del model ha de ser superior a 0" + }, "advancedConfigLabel": "Configuració avançada", "searchMinScoreLabel": "Llindar de puntuació de cerca", "searchMinScoreDescription": "Puntuació mínima de similitud (0.0-1.0) requerida per als resultats de la cerca. Valors més baixos retornen més resultats però poden ser menys rellevants. Valors més alts retornen menys resultats però més rellevants.", @@ -190,6 +206,8 @@ "createProfile": "Crea perfil", "cannotDeleteOnlyProfile": "No es pot eliminar l'únic perfil", "searchPlaceholder": "Cerca perfils", + "searchProviderPlaceholder": "Cerca proveïdors", + "noProviderMatchFound": "No s'han trobat proveïdors", "noMatchFound": "No s'han trobat perfils coincidents", "vscodeLmDescription": "L'API del model de llenguatge de VS Code us permet executar models proporcionats per altres extensions de VS Code (incloent-hi, però no limitat a, GitHub Copilot). La manera més senzilla de començar és instal·lar les extensions Copilot i Copilot Chat des del VS Code Marketplace.", "awsCustomArnUse": "Introduïu un ARN vàlid d'Amazon Bedrock per al model que voleu utilitzar. Exemples de format:", diff --git a/webview-ui/src/i18n/locales/de/chat.json b/webview-ui/src/i18n/locales/de/chat.json index c62fe9d3bb..f28448ce54 100644 --- a/webview-ui/src/i18n/locales/de/chat.json +++ b/webview-ui/src/i18n/locales/de/chat.json @@ -242,8 +242,8 @@ "title": "🎉 Roo Code {{version}} veröffentlicht", "description": "Roo Code {{version}} bringt mächtige neue Funktionen und bedeutende Verbesserungen, um deinen Entwicklungsworkflow zu verbessern.", "whatsNew": "Was ist neu", - "feature1": "1-Klick-Aufgaben-Teilen: Teile deine Aufgaben sofort mit Kollegen und der Community mit einem einzigen Klick.", - "feature2": "Globale .roo-Verzeichnis-Unterstützung: Lade Regeln und Konfigurationen aus einem globalen .roo-Verzeichnis für konsistente Einstellungen über Projekte hinweg.", + "feature1": "Codebase-Indizierung aus experimentellem Status graduiert: Die vollständige Codebase-Indizierung ist jetzt stabil und bereit für den Produktionseinsatz mit verbesserter Suche und Kontextverständnis.", + "feature2": "Neue Todo-Listen-Funktion: Behalte deine Aufgaben im Blick mit integriertem Todo-Management, das dir hilft, organisiert und fokussiert auf deine Entwicklungsziele zu bleiben.", "feature3": "Verbesserte Architect-zu-Code-Übergänge: Nahtlose Übergaben von der Planung im Architect-Modus zur Implementierung im Code-Modus.", "hideButton": "Ankündigung ausblenden", "detailsDiscussLinks": "Erhalte mehr Details und diskutiere auf Discord und Reddit 🚀" diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index 04b71864f6..30f47021d3 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -72,6 +72,7 @@ "qdrantKeyLabel": "Qdrant-Schlüssel:", "qdrantApiKeyLabel": "Qdrant API-Schlüssel", "qdrantApiKeyPlaceholder": "Gib deinen Qdrant API-Schlüssel ein (optional)", + "setupConfigLabel": "Einrichtung", "startIndexingButton": "Start", "clearIndexDataButton": "Index löschen", "unsavedSettingsMessage": "Bitte speichere deine Einstellungen, bevor du den Indexierungsprozess startest.", @@ -97,6 +98,21 @@ "error": "Fehler" }, "close": "Schließen", + "validation": { + "invalidQdrantUrl": "Ungültige Qdrant-URL", + "invalidOllamaUrl": "Ungültige Ollama-URL", + "invalidBaseUrl": "Ungültige Basis-URL", + "qdrantUrlRequired": "Qdrant-URL ist erforderlich", + "openaiApiKeyRequired": "OpenAI-API-Schlüssel ist erforderlich", + "modelSelectionRequired": "Modellauswahl ist erforderlich", + "apiKeyRequired": "API-Schlüssel ist erforderlich", + "modelIdRequired": "Modell-ID ist erforderlich", + "modelDimensionRequired": "Modellabmessung ist erforderlich", + "geminiApiKeyRequired": "Gemini-API-Schlüssel ist erforderlich", + "ollamaBaseUrlRequired": "Ollama-Basis-URL ist erforderlich", + "baseUrlRequired": "Basis-URL ist erforderlich", + "modelDimensionMinValue": "Modellabmessung muss größer als 0 sein" + }, "advancedConfigLabel": "Erweiterte Konfiguration", "searchMinScoreLabel": "Suchergebnis-Schwellenwert", "searchMinScoreDescription": "Mindestähnlichkeitswert (0.0-1.0), der für Suchergebnisse erforderlich ist. Niedrigere Werte liefern mehr Ergebnisse, die jedoch möglicherweise weniger relevant sind. Höhere Werte liefern weniger, aber relevantere Ergebnisse.", @@ -190,6 +206,8 @@ "createProfile": "Profil erstellen", "cannotDeleteOnlyProfile": "Das einzige Profil kann nicht gelöscht werden", "searchPlaceholder": "Profile durchsuchen", + "searchProviderPlaceholder": "Suchanbieter durchsuchen", + "noProviderMatchFound": "Keine Anbieter gefunden", "noMatchFound": "Keine passenden Profile gefunden", "vscodeLmDescription": "Die VS Code Language Model API ermöglicht das Ausführen von Modellen, die von anderen VS Code-Erweiterungen bereitgestellt werden (einschließlich, aber nicht beschränkt auf GitHub Copilot). Der einfachste Weg, um zu starten, besteht darin, die Erweiterungen Copilot und Copilot Chat aus dem VS Code Marketplace zu installieren.", "awsCustomArnUse": "Geben Sie eine gültige Amazon Bedrock ARN für das Modell ein, das Sie verwenden möchten. Formatbeispiele:", @@ -507,7 +525,7 @@ }, "commandDelay": { "label": "Terminal-Befehlsverzögerung", - "description": "Verzögerung in Millisekunden, die nach der Befehlsausführung hinzugefügt wird. Die Standardeinstellung von 0 deaktiviert die Verzögerung vollständig. Dies kann dazu beitragen, dass die Befehlsausgabe in Terminals mit Timing-Problemen vollständig erfasst wird. In den meisten Terminals wird dies durch Setzen von `PROMPT_COMMAND='sleep N'` implementiert, und Powershell fügt `start-sleep` am Ende jedes Befehls hinzu. Ursprünglich war dies eine Lösung für VSCode-Bug#237208 und ist möglicherweise nicht mehr erforderlich. <0>Mehr erfahren" + "description": "Verzögerung in Millisekunden, die nach der Befehlsausführung hinzugefügt wird. Die Standardeinstellung von 0 deaktiviert die Verzögerung vollständig. Dies kann dazu beitragen, dass die Befehlsausgabe in Terminals mit Timing-Problemen vollständig erfasst wird. In den meisten Terminals wird dies durch Setzen von `PROMPT_COMMAND='sleep N'` und Powershell fügt `start-sleep` am Ende jedes Befehls hinzu. Ursprünglich war dies eine Lösung für VSCode-Bug#237208 und ist möglicherweise nicht mehr erforderlich. <0>Mehr erfahren" }, "compressProgressBar": { "label": "Fortschrittsbalken-Ausgabe komprimieren", @@ -527,72 +545,72 @@ }, "zshP10k": { "label": "Powerlevel10k-Integration aktivieren", - "description": "Wenn aktiviert, wird POWERLEVEL9K_TERM_SHELL_INTEGRATION=true gesetzt, um die Shell-Integrationsfunktionen von Powerlevel10k zu aktivieren. <0>Mehr erfahren" + "description": "Wenn aktiviert, wird POWERLEVEL9K_INSTANT_PROMPT=quiet gesetzt, um die Powerlevel10k-Integration zu aktivieren. Dies kann die Leistung verbessern, indem der Prompt sofort angezeigt wird. <0>Mehr erfahren" }, "zdotdir": { - "label": "ZDOTDIR-Behandlung aktivieren", - "description": "Erstellt bei Aktivierung ein temporäres Verzeichnis für ZDOTDIR, um die zsh-Shell-Integration korrekt zu handhaben. Dies stellt sicher, dass die VSCode-Shell-Integration mit zsh funktioniert und dabei deine zsh-Konfiguration erhalten bleibt. <0>Mehr erfahren" + "label": "ZDOTDIR Handhabung aktivieren", + "description": "Wenn aktiviert, wird ein temporäres Verzeichnis für ZDOTDIR erstellt, um die Zsh-Shell-Integration ordnungsgemäß zu handhaben. Dies stellt sicher, dass die VSCode-Shell-Integration mit Zsh korrekt funktioniert, während deine Zsh-Konfiguration erhalten bleibt. <0>Mehr erfahren" }, "inheritEnv": { - "label": "Umgebungsvariablen übernehmen", - "description": "Wenn aktiviert, übernimmt das Terminal Umgebungsvariablen vom übergeordneten VSCode-Prozess, wie z.B. in Benutzerprofilen definierte Shell-Integrationseinstellungen. Dies schaltet direkt die globale VSCode-Einstellung `terminal.integrated.inheritEnv` um. <0>Mehr erfahren" + "label": "Umgebungsvariablen erben", + "description": "Wenn aktiviert, erbt das Terminal Umgebungsvariablen aus dem übergeordneten Prozess von VSCode, wie z.B. benutzerdefinierte Shell-Integrationseinstellungen. Dies schaltet direkt die globale VSCode-Einstellung `terminal.integrated.inheritEnv` um. <0>Mehr erfahren" } }, "advanced": { "diff": { "label": "Bearbeitung durch Diffs aktivieren", - "description": "Wenn aktiviert, kann Roo Dateien schneller bearbeiten und lehnt automatisch gekürzte vollständige Dateischreibvorgänge ab. Funktioniert am besten mit dem neuesten Claude 3.7 Sonnet-Modell.", + "description": "Wenn aktiviert, kann Roo Dateien schneller bearbeiten und lehnt automatisch abgeschnittene vollständige Dateischreibvorgänge ab. Funktioniert am besten mit dem neuesten Claude 3.7 Sonnet-Modell.", "strategy": { "label": "Diff-Strategie", "options": { - "standard": "Standard (Einzelner Block)", - "multiBlock": "Experimentell: Multi-Block-Diff", - "unified": "Experimentell: Vereinheitlichter Diff" + "standard": "Standard (Einzelblock)", + "multiBlock": "Experimentell: Mehrblock-Diff", + "unified": "Experimentell: Einheitliches Diff" }, "descriptions": { - "standard": "Die Standard-Diff-Strategie wendet Änderungen auf einen einzelnen Codeblock gleichzeitig an.", - "unified": "Die vereinheitlichte Diff-Strategie verwendet mehrere Ansätze zum Anwenden von Diffs und wählt den besten Ansatz aus.", - "multiBlock": "Die Multi-Block-Diff-Strategie ermöglicht die Aktualisierung mehrerer Codeblöcke in einer Datei in einer Anfrage." + "standard": "Die Standard-Diff-Strategie wendet Änderungen jeweils auf einen einzelnen Codeblock an.", + "unified": "Die einheitliche Diff-Strategie wendet mehrere Ansätze zur Anwendung von Diffs an und wählt den besten Ansatz.", + "multiBlock": "Die Mehrblock-Diff-Strategie ermöglicht das Aktualisieren mehrerer Codeblöcke in einer Datei in einer Anfrage." } }, "matchPrecision": { - "label": "Übereinstimmungsgenauigkeit", - "description": "Dieser Schieberegler steuert, wie genau Codeabschnitte beim Anwenden von Diffs übereinstimmen müssen. Niedrigere Werte ermöglichen flexiblere Übereinstimmungen, erhöhen aber das Risiko falscher Ersetzungen. Verwende Werte unter 100% mit äußerster Vorsicht." + "label": "Übereinstimmungspräzision", + "description": "Dieser Schieberegler steuert, wie genau Codeabschnitte bei der Anwendung von Diffs übereinstimmen müssen. Niedrigere Werte ermöglichen eine flexiblere Übereinstimmung, erhöhen aber das Risiko falscher Ersetzungen. Verwenden Sie Werte unter 100 % mit äußerster Vorsicht." } } }, "experimental": { "DIFF_STRATEGY_UNIFIED": { "name": "Experimentelle einheitliche Diff-Strategie verwenden", - "description": "Aktiviert die experimentelle einheitliche Diff-Strategie. Diese Strategie könnte die Anzahl der durch Modellfehler verursachten Wiederholungen reduzieren, kann aber unerwartetes Verhalten oder falsche Bearbeitungen verursachen. Nur aktivieren, wenn du die Risiken verstehst und bereit bist, alle Änderungen sorgfältig zu überprüfen." + "description": "Aktiviere die experimentelle einheitliche Diff-Strategie. Diese Strategie könnte die Anzahl der durch Modellfehler verursachten Wiederholungsversuche reduzieren, kann aber zu unerwartetem Verhalten oder falschen Bearbeitungen führen. Aktiviere sie nur, wenn du die Risiken verstehst und bereit bist, alle Änderungen sorgfältig zu überprüfen." }, "SEARCH_AND_REPLACE": { "name": "Experimentelles Such- und Ersetzungswerkzeug verwenden", - "description": "Aktiviert das experimentelle Such- und Ersetzungswerkzeug, das Roo ermöglicht, mehrere Instanzen eines Suchbegriffs in einer Anfrage zu ersetzen." + "description": "Aktiviere das experimentelle Such- und Ersetzungswerkzeug, mit dem Roo mehrere Instanzen eines Suchbegriffs in einer Anfrage ersetzen kann." }, "INSERT_BLOCK": { - "name": "Experimentelles Inhalts-Einfüge-Werkzeug verwenden", - "description": "Aktiviert das experimentelle Inhalts-Einfüge-Werkzeug, das Roo ermöglicht, Inhalte an bestimmten Zeilennummern einzufügen, ohne einen Diff erstellen zu müssen." + "name": "Experimentelles Inhalts-Einfügewerkzeug verwenden", + "description": "Aktiviere das experimentelle Inhalts-Einfügewerkzeug, mit dem Roo Inhalte an bestimmten Zeilennummern einfügen kann, ohne einen Diff erstellen zu müssen." }, "POWER_STEERING": { - "name": "Experimentellen \"Servolenkung\"-Modus verwenden", - "description": "Wenn aktiviert, wird Roo das Modell häufiger an die Details seiner aktuellen Modusdefinition erinnern. Dies führt zu einer stärkeren Einhaltung von Rollendefinitionen und benutzerdefinierten Anweisungen, verwendet aber mehr Tokens pro Nachricht." - }, - "MULTI_SEARCH_AND_REPLACE": { - "name": "Experimentelles Multi-Block-Diff-Werkzeug verwenden", - "description": "Wenn aktiviert, verwendet Roo das Multi-Block-Diff-Werkzeug. Dies versucht, mehrere Codeblöcke in der Datei in einer Anfrage zu aktualisieren." + "name": "Experimentellen \"Power Steering\"-Modus verwenden", + "description": "Wenn aktiviert, erinnert Roo das Modell häufiger an die Details seiner aktuellen Modusdefinition. Dies führt zu einer stärkeren Einhaltung von Rollendefinitionen und benutzerdefinierten Anweisungen, verbraucht aber mehr Token pro Nachricht." }, "CONCURRENT_FILE_READS": { "name": "Gleichzeitiges Lesen von Dateien aktivieren", - "description": "Wenn aktiviert, kann Roo mehrere Dateien in einer einzigen Anfrage lesen. Wenn deaktiviert, muss Roo Dateien nacheinander lesen. Das Deaktivieren kann helfen, wenn du mit weniger leistungsfähigen Modellen arbeitest oder mehr Kontrolle über den Dateizugriff möchtest." + "description": "Wenn aktiviert, kann Roo mehrere Dateien in einer einzigen Anfrage lesen. Wenn deaktiviert, muss Roo Dateien einzeln lesen. Das Deaktivieren kann hilfreich sein, wenn mit weniger fähigen Modellen gearbeitet wird oder wenn du mehr Kontrolle über den Dateizugriff haben möchtest." + }, + "MULTI_SEARCH_AND_REPLACE": { + "name": "Experimentelles Multi-Block-Diff-Tool verwenden", + "description": "Wenn aktiviert, wird Roo das Multi-Block-Diff-Tool verwenden. Dies wird versuchen, mehrere Codeblöcke in der Datei in einer Anfrage zu aktualisieren." }, "MARKETPLACE": { - "name": "Marketplace aktivieren", - "description": "Wenn aktiviert, kannst du MCP und benutzerdefinierte Modi aus dem Marketplace installieren und verwalten." + "name": "Marktplatz aktivieren", + "description": "Wenn aktiviert, können Sie MCPs und benutzerdefinierte Modi aus dem Marketplace installieren." }, "MULTI_FILE_APPLY_DIFF": { "name": "Gleichzeitige Dateibearbeitungen aktivieren", - "description": "Wenn aktiviert, kann Roo mehrere Dateien in einer einzigen Anfrage bearbeiten. Wenn deaktiviert, muss Roo Dateien einzeln bearbeiten. Das Deaktivieren kann helfen, wenn du mit weniger fähigen Modellen arbeitest oder mehr Kontrolle über Dateiänderungen haben möchtest." + "description": "Wenn aktiviert, kann Roo mehrere Dateien in einer einzigen Anfrage bearbeiten. Wenn deaktiviert, muss Roo Dateien einzeln bearbeiten. Das Deaktivieren kann hilfreich sein, wenn mit weniger fähigen Modellen gearbeitet wird oder wenn du mehr Kontrolle über Dateiänderungen haben möchtest." } }, "promptCaching": { @@ -601,16 +619,16 @@ }, "temperature": { "useCustom": "Benutzerdefinierte Temperatur verwenden", - "description": "Steuert die Zufälligkeit in den Antworten des Modells.", + "description": "Steuert die Zufälligkeit der Modellantworten.", "rangeDescription": "Höhere Werte machen die Ausgabe zufälliger, niedrigere Werte machen sie deterministischer." }, "modelInfo": { "supportsImages": "Unterstützt Bilder", "noImages": "Unterstützt keine Bilder", - "supportsComputerUse": "Unterstützt Computer-Nutzung", - "noComputerUse": "Unterstützt keine Computer-Nutzung", - "supportsPromptCache": "Unterstützt Prompt-Caching", - "noPromptCache": "Unterstützt kein Prompt-Caching", + "supportsComputerUse": "Unterstützt Computernutzung", + "noComputerUse": "Unterstützt keine Computernutzung", + "supportsPromptCache": "Unterstützt Prompt-Cache", + "noPromptCache": "Unterstützt keinen Prompt-Cache", "maxOutput": "Maximale Ausgabe", "inputPrice": "Eingabepreis", "outputPrice": "Ausgabepreis", @@ -618,27 +636,27 @@ "cacheWritesPrice": "Cache-Schreibpreis", "enableStreaming": "Streaming aktivieren", "enableR1Format": "R1-Modellparameter aktivieren", - "enableR1FormatTips": "Muss aktiviert werden, wenn R1-Modelle wie QWQ verwendet werden, um 400-Fehler zu vermeiden", + "enableR1FormatTips": "Muss bei Verwendung von R1-Modellen wie QWQ aktiviert werden, um 400er-Fehler zu vermeiden", "useAzure": "Azure verwenden", "azureApiVersion": "Azure API-Version festlegen", "gemini": { "freeRequests": "* Kostenlos bis zu {{count}} Anfragen pro Minute. Danach hängt die Abrechnung von der Prompt-Größe ab.", - "pricingDetails": "Weitere Informationen finden Sie in den Preisdetails.", + "pricingDetails": "Weitere Informationen finden Sie unter Preisdetails.", "billingEstimate": "* Die Abrechnung ist eine Schätzung - die genauen Kosten hängen von der Prompt-Größe ab." } }, "modelPicker": { - "automaticFetch": "Die Erweiterung ruft automatisch die neueste Liste der verfügbaren Modelle von {{serviceName}} ab. Wenn du dir nicht sicher bist, welches Modell du wählen sollst, funktioniert Roo Code am besten mit {{defaultModelId}}. Du kannst auch nach \"free\" suchen, um derzeit verfügbare kostenlose Optionen zu finden.", + "automaticFetch": "Die Erweiterung ruft automatisch die neueste Liste der auf {{serviceName}} verfügbaren Modelle ab. Wenn du dir nicht sicher bist, welches Modell du wählen sollst, funktioniert Roo Code am besten mit {{defaultModelId}}. Du kannst auch versuchen, nach \"kostenlos\" zu suchen, um die derzeit verfügbaren kostenlosen Optionen zu finden.", "label": "Modell", "searchPlaceholder": "Suchen", "noMatchFound": "Keine Übereinstimmung gefunden", "useCustomModel": "Benutzerdefiniert verwenden: {{modelId}}" }, "footer": { - "feedback": "Wenn du Fragen oder Feedback hast, kannst du gerne ein Issue auf github.com/RooCodeInc/Roo-Code öffnen oder reddit.com/r/RooCode oder discord.gg/roocode beitreten", + "feedback": "Wenn du Fragen oder Feedback hast, kannst du gerne ein Issue auf github.com/RooCodeInc/Roo-Code eröffnen oder reddit.com/r/RooCode oder discord.gg/roocode beitreten", "telemetry": { "label": "Anonyme Fehler- und Nutzungsberichte zulassen", - "description": "Helfen Sie, Roo Code zu verbessern, indem Sie anonyme Nutzungsdaten und Fehlerberichte senden. Es werden niemals Code, Prompts oder persönliche Informationen gesendet. Weitere Details finden Sie in unserer Datenschutzrichtlinie." + "description": "Hilf mit, Roo Code zu verbessern, indem du anonyme Nutzungsdaten und Fehlerberichte sendest. Es werden niemals Code, Prompts oder persönliche Informationen gesendet (es sei denn, du verbindest dich mit Roo Code Cloud). Weitere Einzelheiten findest du in unserer Datenschutzrichtlinie." }, "settings": { "import": "Importieren", @@ -647,19 +665,19 @@ } }, "thinkingBudget": { - "maxTokens": "Maximale Tokens", - "maxThinkingTokens": "Maximale Thinking-Tokens" + "maxTokens": "Max Tokens", + "maxThinkingTokens": "Max Thinking Tokens" }, "validation": { "apiKey": "Du musst einen gültigen API-Schlüssel angeben.", - "awsRegion": "Du musst eine Region für Amazon Bedrock auswählen.", + "awsRegion": "Du musst eine Region für die Verwendung mit Amazon Bedrock auswählen.", "googleCloud": "Du musst eine gültige Google Cloud Projekt-ID und Region angeben.", "modelId": "Du musst eine gültige Modell-ID angeben.", - "modelSelector": "Du musst einen gültigen Modell-Selektor angeben.", - "openAi": "Du musst eine gültige Basis-URL, API-Schlüssel und Modell-ID angeben.", + "modelSelector": "Du musst einen gültigen Modellselektor angeben.", + "openAi": "Du musst eine gültige Basis-URL, einen API-Schlüssel und eine Modell-ID angeben.", "arn": { - "invalidFormat": "Ungültiges ARN-Format. Bitte überprüfen Sie die Formatanforderungen.", - "regionMismatch": "Warnung: Die Region in deiner ARN ({{arnRegion}}) stimmt nicht mit deiner ausgewählten Region ({{region}}) überein. Dies kann zu Zugriffsproblemen führen. Der Provider wird die Region aus der ARN verwenden." + "invalidFormat": "Ungültiges ARN-Format. Bitte überprüfe die Formatanforderungen.", + "regionMismatch": "Warnung: Die Region in deiner ARN ({{arnRegion}}) stimmt nicht mit deiner ausgewählten Region ({{region}}) überein. Dies kann zu Zugriffsproblemen führen. Der Anbieter wird die Region aus der ARN verwenden." }, "modelAvailability": "Die von dir angegebene Modell-ID ({{modelId}}) ist nicht verfügbar. Bitte wähle ein anderes Modell.", "providerNotAllowed": "Anbieter '{{provider}}' ist von deiner Organisation nicht erlaubt", @@ -672,7 +690,7 @@ "accessKey": "Zugriffsschlüssel eingeben...", "secretKey": "Geheimschlüssel eingeben...", "sessionToken": "Sitzungstoken eingeben...", - "credentialsJson": "Anmeldedaten-JSON eingeben...", + "credentialsJson": "Anmeldeinformationen JSON eingeben...", "keyFilePath": "Schlüsseldateipfad eingeben...", "projectId": "Projekt-ID eingeben...", "customArn": "ARN eingeben (z.B. arn:aws:bedrock:us-east-1:123456789012:foundation-model/my-model)", @@ -700,5 +718,5 @@ "useCustomArn": "Benutzerdefinierte ARN verwenden..." }, "includeMaxOutputTokens": "Maximale Ausgabe-Tokens einbeziehen", - "includeMaxOutputTokensDescription": "Sende den Parameter für maximale Ausgabe-Tokens in API-Anfragen. Einige Anbieter unterstützen dies möglicherweise nicht." + "includeMaxOutputTokensDescription": "Senden Sie den Parameter für maximale Ausgabe-Tokens in API-Anfragen. Einige Anbieter unterstützen dies möglicherweise nicht." } diff --git a/webview-ui/src/i18n/locales/en/chat.json b/webview-ui/src/i18n/locales/en/chat.json index ea4f8920f5..0c49fbaac7 100644 --- a/webview-ui/src/i18n/locales/en/chat.json +++ b/webview-ui/src/i18n/locales/en/chat.json @@ -247,9 +247,8 @@ "title": "🎉 Roo Code {{version}} Released", "description": "Roo Code {{version}} brings powerful new features and significant improvements to enhance your development workflow.", "whatsNew": "What's New", - "feature1": "1-Click Task Sharing: Share your tasks instantly with colleagues and the community with a single click.", - "feature2": "Global .roo Directory Support: Load rules and configurations from a global .roo directory for consistent settings across projects.", - "feature3": "Improved Architect to Code Transitions: Seamless handoffs from planning in Architect mode to implementation in Code mode.", + "feature1": "Codebase Indexing Graduated from Experimental: Full codebase indexing is now stable and ready for production use with improved search and context understanding.", + "feature2": "New Todo List Feature: Keep your tasks on track with integrated todo management that helps you stay organized and focused on your development goals.", "hideButton": "Hide announcement", "detailsDiscussLinks": "Get more details and discuss in Discord and Reddit 🚀" }, diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index 607ef5fce5..aa2a39044d 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -72,6 +72,7 @@ "qdrantKeyLabel": "Qdrant Key:", "qdrantApiKeyLabel": "Qdrant API Key", "qdrantApiKeyPlaceholder": "Enter your Qdrant API key (optional)", + "setupConfigLabel": "Setup", "advancedConfigLabel": "Advanced Configuration", "searchMinScoreLabel": "Search Score Threshold", "searchMinScoreDescription": "Minimum similarity score (0.0-1.0) required for search results. Lower values return more results but may be less relevant. Higher values return fewer but more relevant results.", @@ -103,7 +104,22 @@ "indexed": "Indexed", "error": "Error" }, - "close": "Close" + "close": "Close", + "validation": { + "qdrantUrlRequired": "Qdrant URL is required", + "invalidQdrantUrl": "Invalid Qdrant URL", + "invalidOllamaUrl": "Invalid Ollama URL", + "invalidBaseUrl": "Invalid base URL", + "openaiApiKeyRequired": "OpenAI API key is required", + "modelSelectionRequired": "Model selection is required", + "apiKeyRequired": "API key is required", + "modelIdRequired": "Model ID is required", + "modelDimensionRequired": "Model dimension is required", + "geminiApiKeyRequired": "Gemini API key is required", + "ollamaBaseUrlRequired": "Ollama base URL is required", + "baseUrlRequired": "Base URL is required", + "modelDimensionMinValue": "Model dimension must be greater than 0" + } }, "autoApprove": { "description": "Allow Roo to automatically perform operations without requiring approval. Enable these settings only if you fully trust the AI and understand the associated security risks.", @@ -190,6 +206,8 @@ "createProfile": "Create Profile", "cannotDeleteOnlyProfile": "Cannot delete the only profile", "searchPlaceholder": "Search profiles", + "searchProviderPlaceholder": "Search providers", + "noProviderMatchFound": "No providers found", "noMatchFound": "No matching profiles found", "vscodeLmDescription": " The VS Code Language Model API allows you to run models provided by other VS Code extensions (including but not limited to GitHub Copilot). The easiest way to get started is to install the Copilot and Copilot Chat extensions from the VS Code Marketplace.", "awsCustomArnUse": "Enter a valid Amazon Bedrock ARN for the model you want to use. Format examples:", diff --git a/webview-ui/src/i18n/locales/es/chat.json b/webview-ui/src/i18n/locales/es/chat.json index a4349b13dc..71a26f6c10 100644 --- a/webview-ui/src/i18n/locales/es/chat.json +++ b/webview-ui/src/i18n/locales/es/chat.json @@ -242,8 +242,8 @@ "title": "🎉 Roo Code {{version}} publicado", "description": "Roo Code {{version}} trae poderosas nuevas funcionalidades y mejoras significativas para mejorar tu flujo de trabajo de desarrollo.", "whatsNew": "Novedades", - "feature1": "Compartir tareas con 1 clic: Comparte tus tareas instantáneamente con colegas y la comunidad con un solo clic.", - "feature2": "Soporte de directorio .roo global: Carga reglas y configuraciones desde un directorio .roo global para configuraciones consistentes entre proyectos.", + "feature1": "Indexación de código base graduada de experimental: La indexación completa del código base ahora es estable y está lista para uso en producción con búsqueda mejorada y comprensión de contexto.", + "feature2": "Nueva función 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.", "feature3": "Transiciones mejoradas de Arquitecto a Código: Transferencias fluidas desde la planificación en modo Arquitecto hasta la implementación en modo Código.", "hideButton": "Ocultar anuncio", "detailsDiscussLinks": "Obtén más detalles y participa en Discord y Reddit 🚀" diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index d71274b0e9..7205ff90ba 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -72,6 +72,7 @@ "qdrantKeyLabel": "Clave de Qdrant:", "qdrantApiKeyLabel": "Clave API de Qdrant", "qdrantApiKeyPlaceholder": "Introduce tu clave API de Qdrant (opcional)", + "setupConfigLabel": "Configuración", "startIndexingButton": "Iniciar", "clearIndexDataButton": "Borrar índice", "unsavedSettingsMessage": "Por favor guarda tus ajustes antes de iniciar el proceso de indexación.", @@ -97,6 +98,21 @@ "error": "Error" }, "close": "Cerrar", + "validation": { + "invalidQdrantUrl": "URL de Qdrant no válida", + "invalidOllamaUrl": "URL de Ollama no válida", + "invalidBaseUrl": "URL base no válida", + "qdrantUrlRequired": "Se requiere la URL de Qdrant", + "openaiApiKeyRequired": "Se requiere la clave API de OpenAI", + "modelSelectionRequired": "Se requiere la selección de un modelo", + "apiKeyRequired": "Se requiere la clave API", + "modelIdRequired": "Se requiere el ID del modelo", + "modelDimensionRequired": "Se requiere la dimensión del modelo", + "geminiApiKeyRequired": "Se requiere la clave API de Gemini", + "ollamaBaseUrlRequired": "Se requiere la URL base de Ollama", + "baseUrlRequired": "Se requiere la URL base", + "modelDimensionMinValue": "La dimensión del modelo debe ser mayor que 0" + }, "advancedConfigLabel": "Configuración avanzada", "searchMinScoreLabel": "Umbral de puntuación de búsqueda", "searchMinScoreDescription": "Puntuación mínima de similitud (0.0-1.0) requerida para los resultados de búsqueda. Valores más bajos devuelven más resultados pero pueden ser menos relevantes. Valores más altos devuelven menos resultados pero más relevantes.", @@ -190,6 +206,8 @@ "createProfile": "Crear perfil", "cannotDeleteOnlyProfile": "No se puede eliminar el único perfil", "searchPlaceholder": "Buscar perfiles", + "searchProviderPlaceholder": "Buscar proveedores", + "noProviderMatchFound": "No se encontraron proveedores", "noMatchFound": "No se encontraron perfiles coincidentes", "vscodeLmDescription": "La API del Modelo de Lenguaje de VS Code le permite ejecutar modelos proporcionados por otras extensiones de VS Code (incluido, entre otros, GitHub Copilot). La forma más sencilla de empezar es instalar las extensiones Copilot y Copilot Chat desde el VS Code Marketplace.", "awsCustomArnUse": "Ingrese un ARN de Amazon Bedrock válido para el modelo que desea utilizar. Ejemplos de formato:", diff --git a/webview-ui/src/i18n/locales/fr/chat.json b/webview-ui/src/i18n/locales/fr/chat.json index b5f06354bb..19531f2554 100644 --- a/webview-ui/src/i18n/locales/fr/chat.json +++ b/webview-ui/src/i18n/locales/fr/chat.json @@ -242,8 +242,8 @@ "title": "🎉 Roo Code {{version}} est sortie", "description": "Roo Code {{version}} apporte de puissantes nouvelles fonctionnalités et des améliorations significatives pour améliorer ton flux de travail de développement.", "whatsNew": "Quoi de neuf", - "feature1": "Partage de tâches en 1 clic : Partage tes tâches instantanément avec tes collègues et la communauté en un seul clic.", - "feature2": "Support du répertoire .roo global : Charge les règles et configurations depuis un répertoire .roo global pour des paramètres cohérents entre les projets.", + "feature1": "L'indexation de la base de code sort du statut expérimental : 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 meilleure compréhension du contexte.", + "feature2": "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.", "feature3": "Transitions Architecte vers Code améliorées : Transferts fluides de la planification en mode Architecte vers l'implémentation en mode Code.", "hideButton": "Masquer l'annonce", "detailsDiscussLinks": "Obtenez plus de détails et participez aux discussions sur Discord et Reddit 🚀" diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index 1ea058b6e4..5a18d7f55c 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -72,6 +72,7 @@ "qdrantKeyLabel": "Clé Qdrant :", "qdrantApiKeyLabel": "Clé API Qdrant", "qdrantApiKeyPlaceholder": "Entrez votre clé API Qdrant (optionnel)", + "setupConfigLabel": "Configuration", "startIndexingButton": "Démarrer", "clearIndexDataButton": "Effacer l'index", "unsavedSettingsMessage": "Merci d'enregistrer tes paramètres avant de démarrer le processus d'indexation.", @@ -97,6 +98,21 @@ "error": "Erreur" }, "close": "Fermer", + "validation": { + "invalidQdrantUrl": "URL Qdrant invalide", + "invalidOllamaUrl": "URL Ollama invalide", + "invalidBaseUrl": "URL de base invalide", + "qdrantUrlRequired": "L'URL Qdrant est requise", + "openaiApiKeyRequired": "La clé API OpenAI est requise", + "modelSelectionRequired": "La sélection du modèle est requise", + "apiKeyRequired": "La clé API est requise", + "modelIdRequired": "L'ID du modèle est requis", + "modelDimensionRequired": "La dimension du modèle est requise", + "geminiApiKeyRequired": "La clé API Gemini est requise", + "ollamaBaseUrlRequired": "L'URL de base Ollama est requise", + "baseUrlRequired": "L'URL de base est requise", + "modelDimensionMinValue": "La dimension du modèle doit être supérieure à 0" + }, "advancedConfigLabel": "Configuration avancée", "searchMinScoreLabel": "Seuil de score de recherche", "searchMinScoreDescription": "Score de similarité minimum (0.0-1.0) requis pour les résultats de recherche. Des valeurs plus faibles renvoient plus de résultats mais peuvent être moins pertinents. Des valeurs plus élevées renvoient moins de résultats mais plus pertinents.", @@ -190,6 +206,8 @@ "createProfile": "Créer un profil", "cannotDeleteOnlyProfile": "Impossible de supprimer le seul profil", "searchPlaceholder": "Rechercher des profils", + "searchProviderPlaceholder": "Rechercher des fournisseurs", + "noProviderMatchFound": "Aucun fournisseur trouvé", "noMatchFound": "Aucun profil correspondant trouvé", "vscodeLmDescription": "L'API du modèle de langage VS Code vous permet d'exécuter des modèles fournis par d'autres extensions VS Code (y compris, mais sans s'y limiter, GitHub Copilot). Le moyen le plus simple de commencer est d'installer les extensions Copilot et Copilot Chat depuis le VS Code Marketplace.", "awsCustomArnUse": "Entrez un ARN Amazon Bedrock valide pour le modèle que vous souhaitez utiliser. Exemples de format :", diff --git a/webview-ui/src/i18n/locales/hi/chat.json b/webview-ui/src/i18n/locales/hi/chat.json index 9afdcbdd38..a45317d2da 100644 --- a/webview-ui/src/i18n/locales/hi/chat.json +++ b/webview-ui/src/i18n/locales/hi/chat.json @@ -242,8 +242,8 @@ "title": "🎉 Roo Code {{version}} रिलीज़ हुआ", "description": "Roo Code {{version}} आपके विकास वर्कफ़्लो को बेहतर बनाने के लिए शक्तिशाली नई सुविधाएं और महत्वपूर्ण सुधार लेकर आया है।", "whatsNew": "नया क्या है", - "feature1": "1-क्लिक टास्क शेयरिंग: अपने टास्क को सहकर्मियों और समुदाय के साथ एक क्लिक में तुरंत साझा करें।", - "feature2": "ग्लोबल .roo डायरेक्टरी समर्थन: प्रोजेक्ट्स में निरंतर सेटिंग्स के लिए ग्लोबल .roo डायरेक्टरी से नियम और कॉन्फ़िगरेशन लोड करें।", + "feature1": "कोडबेस इंडेक्सिंग प्रयोगात्मक से स्नातक: पूर्ण कोडबेस इंडेक्सिंग अब स्थिर है और बेहतर खोज और संदर्भ समझ के साथ उत्पादन उपयोग के लिए तैयार है।", + "feature2": "नई टूडू सूची सुविधा: एकीकृत टूडू प्रबंधन के साथ अपने कार्यों को ट्रैक पर रखें जो आपको व्यवस्थित रहने और अपने विकास लक्ष्यों पर केंद्रित रहने में मदद करता है।", "feature3": "बेहतर आर्किटेक्ट से कोड ट्रांज़िशन: आर्किटेक्ट मोड में प्लानिंग से कोड मोड में इम्प्लीमेंटेशन तक सहज स्थानांतरण।", "hideButton": "घोषणा छुपाएं", "detailsDiscussLinks": "Discord और Reddit पर अधिक विवरण प्राप्त करें और चर्चाओं में शामिल हों 🚀" diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index 9967be6aec..e59c5e0059 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -81,6 +81,7 @@ "ollamaBaseUrlLabel": "Ollama आधार URL", "qdrantApiKeyLabel": "Qdrant API कुंजी", "qdrantApiKeyPlaceholder": "अपनी Qdrant API कुंजी दर्ज करें (वैकल्पिक)", + "setupConfigLabel": "सेटअप", "ollamaUrlPlaceholder": "http://localhost:11434", "openAiCompatibleBaseUrlPlaceholder": "https://api.example.com", "modelDimensionPlaceholder": "1536", @@ -97,6 +98,21 @@ "error": "त्रुटि" }, "close": "बंद करें", + "validation": { + "invalidQdrantUrl": "अमान्य Qdrant URL", + "invalidOllamaUrl": "अमान्य Ollama URL", + "invalidBaseUrl": "अमान्य बेस URL", + "qdrantUrlRequired": "Qdrant URL आवश्यक है", + "openaiApiKeyRequired": "OpenAI API कुंजी आवश्यक है", + "modelSelectionRequired": "मॉडल चयन आवश्यक है", + "apiKeyRequired": "API कुंजी आवश्यक है", + "modelIdRequired": "मॉडल आईडी आवश्यक है", + "modelDimensionRequired": "मॉडल आयाम आवश्यक है", + "geminiApiKeyRequired": "Gemini API कुंजी आवश्यक है", + "ollamaBaseUrlRequired": "Ollama आधार URL आवश्यक है", + "baseUrlRequired": "आधार URL आवश्यक है", + "modelDimensionMinValue": "मॉडल आयाम 0 से बड़ा होना चाहिए" + }, "advancedConfigLabel": "उन्नत कॉन्फ़िगरेशन", "searchMinScoreLabel": "खोज स्कोर थ्रेसहोल्ड", "searchMinScoreDescription": "खोज परिणामों के लिए आवश्यक न्यूनतम समानता स्कोर (0.0-1.0)। कम मान अधिक परिणाम लौटाते हैं लेकिन कम प्रासंगिक हो सकते हैं। उच्च मान कम लेकिन अधिक प्रासंगिक परिणाम लौटाते हैं।", @@ -190,6 +206,8 @@ "createProfile": "प्रोफ़ाइल बनाएं", "cannotDeleteOnlyProfile": "केवल एकमात्र प्रोफ़ाइल को हटाया नहीं जा सकता", "searchPlaceholder": "प्रोफ़ाइल खोजें", + "searchProviderPlaceholder": "प्रदाता खोजें", + "noProviderMatchFound": "कोई प्रदाता नहीं मिला", "noMatchFound": "कोई मिलान प्रोफ़ाइल नहीं मिला", "vscodeLmDescription": "VS कोड भाषा मॉडल API आपको अन्य VS कोड एक्सटेंशन (जैसे GitHub Copilot) द्वारा प्रदान किए गए मॉडल चलाने की अनुमति देता है। शुरू करने का सबसे आसान तरीका VS कोड मार्केटप्लेस से Copilot और Copilot चैट एक्सटेंशन इंस्टॉल करना है।", "awsCustomArnUse": "आप जिस मॉडल का उपयोग करना चाहते हैं, उसके लिए एक वैध AWS बेडरॉक ARN दर्ज करें। प्रारूप उदाहरण:", diff --git a/webview-ui/src/i18n/locales/id/chat.json b/webview-ui/src/i18n/locales/id/chat.json index fc0bd5056f..7df325b7f9 100644 --- a/webview-ui/src/i18n/locales/id/chat.json +++ b/webview-ui/src/i18n/locales/id/chat.json @@ -253,8 +253,8 @@ "title": "🎉 Roo Code {{version}} Dirilis", "description": "Roo Code {{version}} menghadirkan fitur-fitur baru yang kuat dan peningkatan signifikan untuk meningkatkan alur kerja pengembangan Anda.", "whatsNew": "Yang Baru", - "feature1": "Berbagi Tugas 1-Klik: Bagikan tugas Anda secara instan dengan rekan kerja dan komunitas hanya dengan satu klik.", - "feature2": "Dukungan Direktori Global .roo: Muat aturan dan konfigurasi dari direktori global .roo untuk pengaturan yang konsisten di seluruh proyek.", + "feature1": "Pengindeksan Codebase Lulus dari Eksperimental: Pengindeksan codebase lengkap kini stabil dan siap untuk penggunaan produksi dengan pencarian yang ditingkatkan dan pemahaman konteks.", + "feature2": "Fitur Daftar Todo Baru: Jaga tugas Anda tetap pada jalur dengan manajemen todo terintegrasi yang membantu Anda tetap terorganisir dan fokus pada tujuan pengembangan.", "feature3": "Transisi Arsitektur ke Kode yang Ditingkatkan: Transfer yang mulus dari perencanaan di mode Arsitektur ke implementasi di mode Kode.", "hideButton": "Sembunyikan pengumuman", "detailsDiscussLinks": "Dapatkan detail lebih lanjut dan bergabung dalam diskusi di Discord dan Reddit 🚀" diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index 9b3723072f..12755ef6fa 100644 --- a/webview-ui/src/i18n/locales/id/settings.json +++ b/webview-ui/src/i18n/locales/id/settings.json @@ -81,6 +81,7 @@ "ollamaBaseUrlLabel": "URL Dasar Ollama", "qdrantApiKeyLabel": "Kunci API Qdrant", "qdrantApiKeyPlaceholder": "Masukkan kunci API Qdrant kamu (opsional)", + "setupConfigLabel": "Pengaturan", "ollamaUrlPlaceholder": "http://localhost:11434", "openAiCompatibleBaseUrlPlaceholder": "https://api.example.com", "modelDimensionPlaceholder": "1536", @@ -97,6 +98,21 @@ "error": "Error" }, "close": "Tutup", + "validation": { + "invalidQdrantUrl": "URL Qdrant tidak valid", + "invalidOllamaUrl": "URL Ollama tidak valid", + "invalidBaseUrl": "URL dasar tidak valid", + "qdrantUrlRequired": "URL Qdrant diperlukan", + "openaiApiKeyRequired": "Kunci API OpenAI diperlukan", + "modelSelectionRequired": "Pemilihan model diperlukan", + "apiKeyRequired": "Kunci API diperlukan", + "modelIdRequired": "ID Model diperlukan", + "modelDimensionRequired": "Dimensi model diperlukan", + "geminiApiKeyRequired": "Kunci API Gemini diperlukan", + "ollamaBaseUrlRequired": "URL dasar Ollama diperlukan", + "baseUrlRequired": "URL dasar diperlukan", + "modelDimensionMinValue": "Dimensi model harus lebih besar dari 0" + }, "advancedConfigLabel": "Konfigurasi Lanjutan", "searchMinScoreLabel": "Ambang Batas Skor Pencarian", "searchMinScoreDescription": "Skor kesamaan minimum (0.0-1.0) yang diperlukan untuk hasil pencarian. Nilai yang lebih rendah mengembalikan lebih banyak hasil tetapi mungkin kurang relevan. Nilai yang lebih tinggi mengembalikan lebih sedikit hasil tetapi lebih relevan.", @@ -194,6 +210,8 @@ "createProfile": "Buat Profil", "cannotDeleteOnlyProfile": "Tidak dapat menghapus satu-satunya profil", "searchPlaceholder": "Cari profil", + "searchProviderPlaceholder": "Cari penyedia", + "noProviderMatchFound": "Tidak ada penyedia ditemukan", "noMatchFound": "Tidak ada profil yang cocok ditemukan", "vscodeLmDescription": " API Model Bahasa VS Code memungkinkan kamu menjalankan model yang disediakan oleh ekstensi VS Code lainnya (termasuk namun tidak terbatas pada GitHub Copilot). Cara termudah untuk memulai adalah menginstal ekstensi Copilot dan Copilot Chat dari VS Code Marketplace.", "awsCustomArnUse": "Masukkan ARN Amazon Bedrock yang valid untuk model yang ingin kamu gunakan. Contoh format:", diff --git a/webview-ui/src/i18n/locales/it/chat.json b/webview-ui/src/i18n/locales/it/chat.json index f49a25dfa6..4b368f214f 100644 --- a/webview-ui/src/i18n/locales/it/chat.json +++ b/webview-ui/src/i18n/locales/it/chat.json @@ -242,8 +242,8 @@ "title": "🎉 Rilasciato Roo Code {{version}}", "description": "Roo Code {{version}} porta nuove potenti funzionalità e miglioramenti significativi per potenziare il tuo flusso di lavoro di sviluppo.", "whatsNew": "Novità", - "feature1": "Condivisione Task con 1 Clic: Condividi istantaneamente i tuoi task con colleghi e la community con un solo clic.", - "feature2": "Supporto Directory Globale .roo: Carica regole e configurazioni da una directory globale .roo per impostazioni coerenti tra progetti.", + "feature1": "Indicizzazione Codebase Promossa da Sperimentale: L'indicizzazione completa del codebase è ora stabile e pronta per l'uso in produzione con ricerca migliorata e comprensione del contesto.", + "feature2": "Nuova Funzione Lista Todo: Mantieni i tuoi task in carreggiata con la gestione integrata dei todo che ti aiuta a rimanere organizzato e concentrato sui tuoi obiettivi di sviluppo.", "feature3": "Transizioni Migliorate da Architetto a Codice: Trasferimenti fluidi dalla pianificazione in modalità Architetto all'implementazione in modalità Codice.", "hideButton": "Nascondi annuncio", "detailsDiscussLinks": "Ottieni maggiori dettagli e partecipa alle discussioni su Discord e Reddit 🚀" diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index 2ce9bb3bdd..3f27152aa3 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -81,6 +81,7 @@ "ollamaBaseUrlLabel": "URL base Ollama", "qdrantApiKeyLabel": "Chiave API Qdrant", "qdrantApiKeyPlaceholder": "Inserisci la tua chiave API Qdrant (opzionale)", + "setupConfigLabel": "Impostazione", "ollamaUrlPlaceholder": "http://localhost:11434", "openAiCompatibleBaseUrlPlaceholder": "https://api.example.com", "modelDimensionPlaceholder": "1536", @@ -97,6 +98,21 @@ "error": "Errore" }, "close": "Chiudi", + "validation": { + "invalidQdrantUrl": "URL Qdrant non valido", + "invalidOllamaUrl": "URL Ollama non valido", + "invalidBaseUrl": "URL di base non valido", + "qdrantUrlRequired": "È richiesto l'URL di Qdrant", + "openaiApiKeyRequired": "È richiesta la chiave API di OpenAI", + "modelSelectionRequired": "È richiesta la selezione del modello", + "apiKeyRequired": "È richiesta la chiave API", + "modelIdRequired": "È richiesto l'ID del modello", + "modelDimensionRequired": "È richiesta la dimensione del modello", + "geminiApiKeyRequired": "È richiesta la chiave API Gemini", + "ollamaBaseUrlRequired": "È richiesto l'URL di base di Ollama", + "baseUrlRequired": "È richiesto l'URL di base", + "modelDimensionMinValue": "La dimensione del modello deve essere maggiore di 0" + }, "advancedConfigLabel": "Configurazione avanzata", "searchMinScoreLabel": "Soglia punteggio di ricerca", "searchMinScoreDescription": "Punteggio minimo di somiglianza (0.0-1.0) richiesto per i risultati della ricerca. Valori più bassi restituiscono più risultati ma potrebbero essere meno pertinenti. Valori più alti restituiscono meno risultati ma più pertinenti.", @@ -191,6 +207,8 @@ "cannotDeleteOnlyProfile": "Impossibile eliminare l'unico profilo", "searchPlaceholder": "Cerca profili", "noMatchFound": "Nessun profilo corrispondente trovato", + "searchProviderPlaceholder": "Cerca fornitori", + "noProviderMatchFound": "Nessun fornitore trovato", "vscodeLmDescription": "L'API del Modello di Linguaggio di VS Code consente di eseguire modelli forniti da altre estensioni di VS Code (incluso, ma non limitato a, GitHub Copilot). Il modo più semplice per iniziare è installare le estensioni Copilot e Copilot Chat dal VS Code Marketplace.", "awsCustomArnUse": "Inserisci un ARN Amazon Bedrock valido per il modello che desideri utilizzare. Esempi di formato:", "awsCustomArnDesc": "Assicurati che la regione nell'ARN corrisponda alla regione AWS selezionata sopra.", diff --git a/webview-ui/src/i18n/locales/ja/chat.json b/webview-ui/src/i18n/locales/ja/chat.json index cb5ebcdafd..5a19b64945 100644 --- a/webview-ui/src/i18n/locales/ja/chat.json +++ b/webview-ui/src/i18n/locales/ja/chat.json @@ -242,8 +242,8 @@ "title": "🎉 Roo Code {{version}} リリース", "description": "Roo Code {{version}}は、開発ワークフローを向上させる強力な新機能と重要な改善をもたらします。", "whatsNew": "新機能", - "feature1": "1クリックタスク共有: ワンクリックで同僚やコミュニティとタスクを瞬時に共有できます。", - "feature2": "グローバル.rooディレクトリサポート: グローバル.rooディレクトリからルールと設定を読み込み、プロジェクト間で一貫した設定を実現。", + "feature1": "コードベースインデックス機能が実験段階を卒業: 完全なコードベースインデックス機能が安定し、改善された検索とコンテキスト理解により本番環境での使用が可能になりました。", + "feature2": "新しいTodoリスト機能: 統合されたTodo管理でタスクを軌道に乗せ、開発目標に整理され集中した状態を維持できます。", "feature3": "改善されたアーキテクトからコードへの移行: アーキテクトモードでの計画からコードモードでの実装へのシームレスな引き継ぎ。", "hideButton": "通知を非表示", "detailsDiscussLinks": "詳細はDiscordRedditでご確認・ディスカッションください 🚀" diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index b3068dbbb3..5843fd03b9 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -81,6 +81,7 @@ "ollamaBaseUrlLabel": "Ollama ベースURL", "qdrantApiKeyLabel": "Qdrant APIキー", "qdrantApiKeyPlaceholder": "Qdrant APIキーを入力(オプション)", + "setupConfigLabel": "設定", "ollamaUrlPlaceholder": "http://localhost:11434", "openAiCompatibleBaseUrlPlaceholder": "https://api.example.com", "modelDimensionPlaceholder": "1536", @@ -97,6 +98,21 @@ "error": "エラー" }, "close": "閉じる", + "validation": { + "invalidQdrantUrl": "無効なQdrant URL", + "invalidOllamaUrl": "無効なOllama URL", + "invalidBaseUrl": "無効なベースURL", + "qdrantUrlRequired": "Qdrant URL が必要です", + "openaiApiKeyRequired": "OpenAI APIキーが必要です", + "modelSelectionRequired": "モデルの選択が必要です", + "apiKeyRequired": "APIキーが必要です", + "modelIdRequired": "モデルIDが必要です", + "modelDimensionRequired": "モデルの次元が必要です", + "geminiApiKeyRequired": "Gemini APIキーが必要です", + "ollamaBaseUrlRequired": "OllamaのベースURLが必要です", + "baseUrlRequired": "ベースURLが必要です", + "modelDimensionMinValue": "モデルの次元は0より大きくなければなりません" + }, "advancedConfigLabel": "詳細設定", "searchMinScoreLabel": "検索スコアのしきい値", "searchMinScoreDescription": "検索結果に必要な最小類似度スコア(0.0-1.0)。値を低くするとより多くの結果が返されますが、関連性が低くなる可能性があります。値を高くすると返される結果は少なくなりますが、より関連性が高くなります。", @@ -190,6 +206,8 @@ "createProfile": "プロファイルを作成", "cannotDeleteOnlyProfile": "唯一のプロファイルは削除できません", "searchPlaceholder": "プロファイルを検索", + "searchProviderPlaceholder": "プロバイダーを検索", + "noProviderMatchFound": "プロバイダーが見つかりません", "noMatchFound": "一致するプロファイルが見つかりません", "vscodeLmDescription": "VS Code言語モデルAPIを使用すると、他のVS Code拡張機能(GitHub Copilotなど)が提供するモデルを実行できます。最も簡単な方法は、VS Code MarketplaceからCopilotおよびCopilot Chat拡張機能をインストールすることです。", "awsCustomArnUse": "使用したいモデルの有効なAmazon Bedrock ARNを入力してください。形式の例:", diff --git a/webview-ui/src/i18n/locales/ko/chat.json b/webview-ui/src/i18n/locales/ko/chat.json index 1f86dc8cf4..f3ed7699ca 100644 --- a/webview-ui/src/i18n/locales/ko/chat.json +++ b/webview-ui/src/i18n/locales/ko/chat.json @@ -242,8 +242,8 @@ "title": "🎉 Roo Code {{version}} 출시", "description": "Roo Code {{version}}은 개발 워크플로우를 향상시키는 강력한 새 기능과 중요한 개선사항을 제공합니다.", "whatsNew": "새로운 기능", - "feature1": "원클릭 작업 공유: 한 번의 클릭으로 동료 및 커뮤니티와 작업을 즉시 공유하세요.", - "feature2": "글로벌 .roo 디렉토리 지원: 글로벌 .roo 디렉토리에서 규칙과 구성을 로드하여 프로젝트 간 일관된 설정을 유지하세요.", + "feature1": "코드베이스 인덱싱이 실험 단계에서 졸업: 전체 코드베이스 인덱싱이 이제 안정적이며 향상된 검색 및 컨텍스트 이해 기능으로 프로덕션 사용이 준비되었습니다.", + "feature2": "새로운 할 일 목록 기능: 통합된 할 일 관리로 작업을 궤도에 유지하여 개발 목표에 체계적이고 집중된 상태를 유지하세요.", "feature3": "개선된 아키텍트에서 코드로의 전환: 아키텍트 모드에서의 계획부터 코드 모드에서의 구현까지 원활한 인수인계.", "hideButton": "공지 숨기기", "detailsDiscussLinks": "DiscordReddit에서 자세한 내용을 확인하고 토론에 참여하세요 🚀" diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index c70e9b0a61..92dd864233 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -81,6 +81,7 @@ "ollamaBaseUrlLabel": "Ollama 기본 URL", "qdrantApiKeyLabel": "Qdrant API 키", "qdrantApiKeyPlaceholder": "Qdrant API 키를 입력하세요 (선택사항)", + "setupConfigLabel": "설정", "ollamaUrlPlaceholder": "http://localhost:11434", "openAiCompatibleBaseUrlPlaceholder": "https://api.example.com", "modelDimensionPlaceholder": "1536", @@ -97,6 +98,21 @@ "error": "오류" }, "close": "닫기", + "validation": { + "invalidQdrantUrl": "잘못된 Qdrant URL", + "invalidOllamaUrl": "잘못된 Ollama URL", + "invalidBaseUrl": "잘못된 기본 URL", + "qdrantUrlRequired": "Qdrant URL이 필요합니다", + "openaiApiKeyRequired": "OpenAI API 키가 필요합니다", + "modelSelectionRequired": "모델 선택이 필요합니다", + "apiKeyRequired": "API 키가 필요합니다", + "modelIdRequired": "모델 ID가 필요합니다", + "modelDimensionRequired": "모델 차원이 필요합니다", + "geminiApiKeyRequired": "Gemini API 키가 필요합니다", + "ollamaBaseUrlRequired": "Ollama 기본 URL이 필요합니다", + "baseUrlRequired": "기본 URL이 필요합니다", + "modelDimensionMinValue": "모델 차원은 0보다 커야 합니다" + }, "advancedConfigLabel": "고급 구성", "searchMinScoreLabel": "검색 점수 임계값", "searchMinScoreDescription": "검색 결과에 필요한 최소 유사도 점수(0.0-1.0). 값이 낮을수록 더 많은 결과가 반환되지만 관련성이 떨어질 수 있습니다. 값이 높을수록 결과는 적지만 관련성이 높은 결과가 반환됩니다.", @@ -190,6 +206,8 @@ "createProfile": "프로필 생성", "cannotDeleteOnlyProfile": "유일한 프로필은 삭제할 수 없습니다", "searchPlaceholder": "프로필 검색", + "searchProviderPlaceholder": "공급자 검색", + "noProviderMatchFound": "공급자를 찾을 수 없습니다", "noMatchFound": "일치하는 프로필이 없습니다", "vscodeLmDescription": "VS Code 언어 모델 API를 사용하면 GitHub Copilot을 포함한 기타 VS Code 확장 프로그램이 제공하는 모델을 실행할 수 있습니다. 시작하려면 VS Code 마켓플레이스에서 Copilot 및 Copilot Chat 확장 프로그램을 설치하는 것이 가장 쉽습니다.", "awsCustomArnUse": "사용하려는 모델의 유효한 Amazon Bedrock ARN을 입력하세요. 형식 예시:", diff --git a/webview-ui/src/i18n/locales/nl/chat.json b/webview-ui/src/i18n/locales/nl/chat.json index d228d7b0c2..874fb74bc7 100644 --- a/webview-ui/src/i18n/locales/nl/chat.json +++ b/webview-ui/src/i18n/locales/nl/chat.json @@ -227,8 +227,8 @@ "title": "🎉 Roo Code {{version}} uitgebracht", "description": "Roo Code {{version}} brengt krachtige nieuwe functies en significante verbeteringen om je ontwikkelingsworkflow te verbeteren.", "whatsNew": "Wat is er nieuw", - "feature1": "1-Klik Taak Delen: Deel je taken direct met collega's en de community met slechts één klik.", - "feature2": "Globale .roo Directory Ondersteuning: Laad regels en configuraties vanuit een globale .roo directory voor consistente instellingen tussen projecten.", + "feature1": "Codebase Indexering Afgestudeerd van Experimenteel: Volledige codebase indexering is nu stabiel en klaar voor productiegebruik met verbeterde zoekfunctionaliteit en contextbegrip.", + "feature2": "Nieuwe Todo Lijst Functie: Houd je taken op koers met geïntegreerd todo-beheer dat je helpt georganiseerd en gefocust te blijven op je ontwikkelingsdoelen.", "feature3": "Verbeterde Architect naar Code Overgangen: Soepele overdrachten van planning in Architect modus naar implementatie in Code modus.", "hideButton": "Aankondiging verbergen", "detailsDiscussLinks": "Krijg meer details en doe mee aan discussies op Discord en Reddit 🚀" diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index 096667d6b5..b56a40ed39 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -81,6 +81,7 @@ "ollamaBaseUrlLabel": "Ollama Basis-URL", "qdrantApiKeyLabel": "Qdrant API-sleutel", "qdrantApiKeyPlaceholder": "Voer je Qdrant API-sleutel in (optioneel)", + "setupConfigLabel": "Instellen", "ollamaUrlPlaceholder": "http://localhost:11434", "openAiCompatibleBaseUrlPlaceholder": "https://api.example.com", "modelDimensionPlaceholder": "1536", @@ -97,6 +98,21 @@ "error": "Fout" }, "close": "Sluiten", + "validation": { + "invalidQdrantUrl": "Ongeldige Qdrant URL", + "invalidOllamaUrl": "Ongeldige Ollama URL", + "invalidBaseUrl": "Ongeldige basis-URL", + "qdrantUrlRequired": "Qdrant URL is vereist", + "openaiApiKeyRequired": "OpenAI API-sleutel is vereist", + "modelSelectionRequired": "Modelselectie is vereist", + "apiKeyRequired": "API-sleutel is vereist", + "modelIdRequired": "Model-ID is vereist", + "modelDimensionRequired": "Modelafmeting is vereist", + "geminiApiKeyRequired": "Gemini API-sleutel is vereist", + "ollamaBaseUrlRequired": "Ollama basis-URL is vereist", + "baseUrlRequired": "Basis-URL is vereist", + "modelDimensionMinValue": "Modelafmeting moet groter zijn dan 0" + }, "advancedConfigLabel": "Geavanceerde configuratie", "searchMinScoreLabel": "Zoekscore drempel", "searchMinScoreDescription": "Minimale overeenkomstscore (0.0-1.0) vereist voor zoekresultaten. Lagere waarden leveren meer resultaten op, maar zijn mogelijk minder relevant. Hogere waarden leveren minder, maar relevantere resultaten op.", @@ -190,6 +206,8 @@ "createProfile": "Profiel aanmaken", "cannotDeleteOnlyProfile": "Kan het enige profiel niet verwijderen", "searchPlaceholder": "Zoek profielen", + "searchProviderPlaceholder": "Zoek providers", + "noProviderMatchFound": "Geen providers gevonden", "noMatchFound": "Geen overeenkomende profielen gevonden", "vscodeLmDescription": "De VS Code Language Model API stelt je in staat modellen te draaien die door andere VS Code-extensies worden geleverd (waaronder GitHub Copilot). De eenvoudigste manier om te beginnen is door de Copilot- en Copilot Chat-extensies te installeren vanuit de VS Code Marketplace.", "awsCustomArnUse": "Voer een geldige Amazon Bedrock ARN in voor het model dat je wilt gebruiken. Voorbeeldformaten:", diff --git a/webview-ui/src/i18n/locales/pl/chat.json b/webview-ui/src/i18n/locales/pl/chat.json index fdb39b0851..254f18c9ba 100644 --- a/webview-ui/src/i18n/locales/pl/chat.json +++ b/webview-ui/src/i18n/locales/pl/chat.json @@ -242,8 +242,8 @@ "title": "🎉 Roo Code {{version}} wydany", "description": "Roo Code {{version}} wprowadza potężne nowe funkcje i znaczące ulepszenia, aby ulepszyć Twój przepływ pracy programistycznej.", "whatsNew": "Co nowego", - "feature1": "Udostępnianie zadań jednym kliknięciem: Natychmiast udostępniaj swoje zadania współpracownikom i społeczności jednym kliknięciem.", - "feature2": "Wsparcie globalnego katalogu .roo: Ładuj reguły i konfiguracje z globalnego katalogu .roo dla spójnych ustawień między projektami.", + "feature1": "Indeksowanie bazy kodu ukończone z fazy eksperymentalnej: Pełne indeksowanie bazy kodu jest teraz stabilne i gotowe do użytku produkcyjnego z ulepszonymi funkcjami wyszukiwania i rozumienia kontekstu.", + "feature2": "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 rozwojowych.", "feature3": "Ulepszone przejścia z Architekta do Kodu: Płynne transfery z planowania w trybie Architekta do implementacji w trybie Kodu.", "hideButton": "Ukryj ogłoszenie", "detailsDiscussLinks": "Uzyskaj więcej szczegółów i dołącz do dyskusji na Discord i Reddit 🚀" diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index d71b98bf80..7277e19842 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -81,6 +81,7 @@ "ollamaBaseUrlLabel": "Bazowy URL Ollama", "qdrantApiKeyLabel": "Klucz API Qdrant", "qdrantApiKeyPlaceholder": "Wprowadź swój klucz API Qdrant (opcjonalnie)", + "setupConfigLabel": "Konfiguracja", "ollamaUrlPlaceholder": "http://localhost:11434", "openAiCompatibleBaseUrlPlaceholder": "https://api.example.com", "modelDimensionPlaceholder": "1536", @@ -97,6 +98,21 @@ "error": "Błąd" }, "close": "Zamknij", + "validation": { + "invalidQdrantUrl": "Nieprawidłowy URL Qdrant", + "invalidOllamaUrl": "Nieprawidłowy URL Ollama", + "invalidBaseUrl": "Nieprawidłowy podstawowy URL", + "qdrantUrlRequired": "Wymagany jest URL Qdrant", + "openaiApiKeyRequired": "Wymagany jest klucz API OpenAI", + "modelSelectionRequired": "Wymagany jest wybór modelu", + "apiKeyRequired": "Wymagany jest klucz API", + "modelIdRequired": "Wymagane jest ID modelu", + "modelDimensionRequired": "Wymagany jest wymiar modelu", + "geminiApiKeyRequired": "Wymagany jest klucz API Gemini", + "ollamaBaseUrlRequired": "Wymagany jest bazowy adres URL Ollama", + "baseUrlRequired": "Wymagany jest bazowy adres URL", + "modelDimensionMinValue": "Wymiar modelu musi być większy niż 0" + }, "advancedConfigLabel": "Konfiguracja zaawansowana", "searchMinScoreLabel": "Próg wyniku wyszukiwania", "searchMinScoreDescription": "Minimalny wynik podobieństwa (0.0-1.0) wymagany dla wyników wyszukiwania. Niższe wartości zwracają więcej wyników, ale mogą być mniej trafne. Wyższe wartości zwracają mniej wyników, ale bardziej trafnych.", @@ -190,6 +206,8 @@ "createProfile": "Utwórz profil", "cannotDeleteOnlyProfile": "Nie można usunąć jedynego profilu", "searchPlaceholder": "Szukaj profili", + "searchProviderPlaceholder": "Szukaj dostawców", + "noProviderMatchFound": "Nie znaleziono dostawców", "noMatchFound": "Nie znaleziono pasujących profili", "vscodeLmDescription": "Interfejs API modelu językowego VS Code umożliwia uruchamianie modeli dostarczanych przez inne rozszerzenia VS Code (w tym, ale nie tylko, GitHub Copilot). Najłatwiejszym sposobem na rozpoczęcie jest zainstalowanie rozszerzeń Copilot i Copilot Chat z VS Code Marketplace.", "awsCustomArnUse": "Wprowadź prawidłowy Amazon Bedrock ARN dla modelu, którego chcesz użyć. Przykłady formatu:", diff --git a/webview-ui/src/i18n/locales/pt-BR/chat.json b/webview-ui/src/i18n/locales/pt-BR/chat.json index b37879f2f0..bebfe0c722 100644 --- a/webview-ui/src/i18n/locales/pt-BR/chat.json +++ b/webview-ui/src/i18n/locales/pt-BR/chat.json @@ -242,8 +242,8 @@ "title": "🎉 Roo Code {{version}} Lançado", "description": "Roo Code {{version}} traz novos recursos poderosos e melhorias significativas para aprimorar seu fluxo de trabalho de desenvolvimento.", "whatsNew": "O que há de novo", - "feature1": "Compartilhamento de Tarefas com 1 Clique: Compartilhe instantaneamente suas tarefas com colegas e a comunidade com apenas um clique.", - "feature2": "Suporte a Diretório Global .roo: Carregue regras e configurações de um diretório global .roo para configurações consistentes entre projetos.", + "feature1": "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.", + "feature2": "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.", "feature3": "Transições Aprimoradas de Arquiteto para Código: Transferências suaves do planejamento no modo Arquiteto para implementação no modo Código.", "hideButton": "Ocultar anúncio", "detailsDiscussLinks": "Obtenha mais detalhes e participe da discussão no Discord e Reddit 🚀" diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index f1350f698e..ec7f54f06a 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -81,6 +81,7 @@ "ollamaBaseUrlLabel": "URL Base do Ollama", "qdrantApiKeyLabel": "Chave da API Qdrant", "qdrantApiKeyPlaceholder": "Insira sua chave da API Qdrant (opcional)", + "setupConfigLabel": "Configuração", "ollamaUrlPlaceholder": "http://localhost:11434", "openAiCompatibleBaseUrlPlaceholder": "https://api.example.com", "modelDimensionPlaceholder": "1536", @@ -97,6 +98,21 @@ "error": "Erro" }, "close": "Fechar", + "validation": { + "invalidQdrantUrl": "URL do Qdrant inválida", + "invalidOllamaUrl": "URL do Ollama inválida", + "invalidBaseUrl": "URL base inválida", + "qdrantUrlRequired": "A URL do Qdrant é obrigatória", + "openaiApiKeyRequired": "A chave de API da OpenAI é obrigatória", + "modelSelectionRequired": "A seleção do modelo é obrigatória", + "apiKeyRequired": "A chave de API é obrigatória", + "modelIdRequired": "O ID do modelo é obrigatório", + "modelDimensionRequired": "A dimensão do modelo é obrigatória", + "geminiApiKeyRequired": "A chave de API do Gemini é obrigatória", + "ollamaBaseUrlRequired": "A URL base do Ollama é obrigatória", + "baseUrlRequired": "A URL base é obrigatória", + "modelDimensionMinValue": "A dimensão do modelo deve ser maior que 0" + }, "advancedConfigLabel": "Configuração Avançada", "searchMinScoreLabel": "Limite de pontuação de busca", "searchMinScoreDescription": "Pontuação mínima de similaridade (0.0-1.0) necessária para os resultados da busca. Valores mais baixos retornam mais resultados, mas podem ser menos relevantes. Valores mais altos retornam menos resultados, mas mais relevantes.", @@ -190,6 +206,8 @@ "createProfile": "Criar perfil", "cannotDeleteOnlyProfile": "Não é possível excluir o único perfil", "searchPlaceholder": "Pesquisar perfis", + "searchProviderPlaceholder": "Pesquisar provedores", + "noProviderMatchFound": "Nenhum provedor encontrado", "noMatchFound": "Nenhum perfil correspondente encontrado", "vscodeLmDescription": "A API do Modelo de Linguagem do VS Code permite executar modelos fornecidos por outras extensões do VS Code (incluindo, mas não se limitando, ao GitHub Copilot). A maneira mais fácil de começar é instalar as extensões Copilot e Copilot Chat no VS Code Marketplace.", "awsCustomArnUse": "Insira um ARN Amazon Bedrock válido para o modelo que deseja usar. Exemplos de formato:", diff --git a/webview-ui/src/i18n/locales/ru/chat.json b/webview-ui/src/i18n/locales/ru/chat.json index 5865e41a53..4ac8f4854a 100644 --- a/webview-ui/src/i18n/locales/ru/chat.json +++ b/webview-ui/src/i18n/locales/ru/chat.json @@ -227,8 +227,8 @@ "title": "🎉 Выпущен Roo Code {{version}}", "description": "Roo Code {{version}} приносит мощные новые функции и значительные улучшения для совершенствования вашего рабочего процесса разработки.", "whatsNew": "Что нового", - "feature1": "Обмен задачами в 1 клик: Мгновенно делитесь своими задачами с коллегами и сообществом одним кликом.", - "feature2": "Поддержка глобального каталога .roo: Загружайте правила и конфигурации из глобального каталога .roo для согласованных настроек между проектами.", + "feature1": "Индексация кодовой базы выпущена из экспериментального статуса: Полная индексация кодовой базы теперь стабильна и готова к использованию в продакшене с улучшенным поиском и пониманием контекста.", + "feature2": "Новая функция списка задач: Держите свои задачи на правильном пути с интегрированным управлением задачами, которое помогает оставаться организованным и сосредоточенным на целях разработки.", "feature3": "Улучшенные переходы от Архитектора к Коду: Плавные переходы от планирования в режиме Архитектора к реализации в режиме Кода.", "hideButton": "Скрыть объявление", "detailsDiscussLinks": "Подробнее и обсуждение в Discord и Reddit 🚀" diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index 406ef670a7..806204ae0c 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -81,6 +81,7 @@ "ollamaBaseUrlLabel": "Базовый URL Ollama", "qdrantApiKeyLabel": "API-ключ Qdrant", "qdrantApiKeyPlaceholder": "Введите ваш API-ключ Qdrant (необязательно)", + "setupConfigLabel": "Настройка", "ollamaUrlPlaceholder": "http://localhost:11434", "openAiCompatibleBaseUrlPlaceholder": "https://api.example.com", "modelDimensionPlaceholder": "1536", @@ -97,6 +98,21 @@ "error": "Ошибка" }, "close": "Закрыть", + "validation": { + "invalidQdrantUrl": "Неверный URL Qdrant", + "invalidOllamaUrl": "Неверный URL Ollama", + "invalidBaseUrl": "Неверный базовый URL", + "qdrantUrlRequired": "Требуется URL Qdrant", + "openaiApiKeyRequired": "Требуется ключ API OpenAI", + "modelSelectionRequired": "Требуется выбор модели", + "apiKeyRequired": "Требуется ключ API", + "modelIdRequired": "Требуется идентификатор модели", + "modelDimensionRequired": "Требуется размерность модели", + "geminiApiKeyRequired": "Требуется ключ API Gemini", + "ollamaBaseUrlRequired": "Требуется базовый URL Ollama", + "baseUrlRequired": "Требуется базовый URL", + "modelDimensionMinValue": "Размерность модели должна быть больше 0" + }, "advancedConfigLabel": "Расширенная конфигурация", "searchMinScoreLabel": "Порог оценки поиска", "searchMinScoreDescription": "Минимальный балл сходства (0.0-1.0), необходимый для результатов поиска. Более низкие значения возвращают больше результатов, но они могут быть менее релевантными. Более высокие значения возвращают меньше результатов, но более релевантных.", @@ -190,6 +206,8 @@ "createProfile": "Создать профиль", "cannotDeleteOnlyProfile": "Нельзя удалить единственный профиль", "searchPlaceholder": "Поиск профилей", + "searchProviderPlaceholder": "Поиск провайдеров", + "noProviderMatchFound": "Провайдеры не найдены", "noMatchFound": "Совпадений не найдено", "vscodeLmDescription": "API языковой модели VS Code позволяет запускать модели, предоставляемые другими расширениями VS Code (включая, но не ограничиваясь GitHub Copilot). Для начала установите расширения Copilot и Copilot Chat из VS Code Marketplace.", "awsCustomArnUse": "Введите действительный Amazon Bedrock ARN для используемой модели. Примеры формата:", diff --git a/webview-ui/src/i18n/locales/tr/chat.json b/webview-ui/src/i18n/locales/tr/chat.json index 6c5bd20353..56a9f54cb7 100644 --- a/webview-ui/src/i18n/locales/tr/chat.json +++ b/webview-ui/src/i18n/locales/tr/chat.json @@ -242,8 +242,8 @@ "title": "🎉 Roo Code {{version}} Yayınlandı", "description": "Roo Code {{version}}, geliştirme iş akışınızı geliştirmek için güçlü yeni özellikler ve önemli iyileştirmeler getiriyor.", "whatsNew": "Yenilikler", - "feature1": "Tek Tıkla Görev Paylaşımı: Görevlerinizi meslektaşlarınız ve toplulukla tek tıkla anında paylaşın.", - "feature2": "Global .roo Dizin Desteği: Projeler arası tutarlı ayarlar için global .roo dizininden kurallar ve yapılandırmalar yükleyin.", + "feature1": "Kod Tabanı İndeksleme Deneysel Aşamadan Mezun Oldu: Tam kod tabanı indeksleme artık kararlı ve geliştirilmiş arama ve bağlam anlayışı ile üretim kullanımına hazır.", + "feature2": "Yeni Yapılacaklar Listesi Özelliği: Görevlerinizi yolunda tutmak için entegre yapılacaklar yönetimi ile organize kalın ve geliştirme hedeflerinize odaklanın.", "feature3": "Geliştirilmiş Mimar'dan Kod'a Geçişler: Mimar modunda planlamadan Kod modunda uygulamaya sorunsuz aktarımlar.", "hideButton": "Duyuruyu gizle", "detailsDiscussLinks": "Discord ve Reddit'te daha fazla ayrıntı alın ve tartışmalara katılın 🚀" diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index 47eb616529..3b053fba80 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -81,6 +81,7 @@ "ollamaBaseUrlLabel": "Ollama Temel URL", "qdrantApiKeyLabel": "Qdrant API Anahtarı", "qdrantApiKeyPlaceholder": "Qdrant API anahtarınızı girin (isteğe bağlı)", + "setupConfigLabel": "Kurulum", "ollamaUrlPlaceholder": "http://localhost:11434", "openAiCompatibleBaseUrlPlaceholder": "https://api.example.com", "modelDimensionPlaceholder": "1536", @@ -97,6 +98,21 @@ "error": "Hata" }, "close": "Kapat", + "validation": { + "invalidQdrantUrl": "Geçersiz Qdrant URL'si", + "invalidOllamaUrl": "Geçersiz Ollama URL'si", + "invalidBaseUrl": "Geçersiz temel URL'si", + "qdrantUrlRequired": "Qdrant URL'si gereklidir", + "openaiApiKeyRequired": "OpenAI API anahtarı gereklidir", + "modelSelectionRequired": "Model seçimi gereklidir", + "apiKeyRequired": "API anahtarı gereklidir", + "modelIdRequired": "Model kimliği gereklidir", + "modelDimensionRequired": "Model boyutu gereklidir", + "geminiApiKeyRequired": "Gemini API anahtarı gereklidir", + "ollamaBaseUrlRequired": "Ollama temel URL'si gereklidir", + "baseUrlRequired": "Temel URL'si gereklidir", + "modelDimensionMinValue": "Model boyutu 0'dan büyük olmalıdır" + }, "advancedConfigLabel": "Gelişmiş Yapılandırma", "searchMinScoreLabel": "Arama Skoru Eşiği", "searchMinScoreDescription": "Arama sonuçları için gereken minimum benzerlik puanı (0.0-1.0). Düşük değerler daha fazla sonuç döndürür ancak daha az alakalı olabilir. Yüksek değerler daha az ancak daha alakalı sonuçlar döndürür.", @@ -190,6 +206,8 @@ "createProfile": "Profil oluştur", "cannotDeleteOnlyProfile": "Yalnızca tek profili silemezsiniz", "searchPlaceholder": "Profilleri ara", + "searchProviderPlaceholder": "Sağlayıcıları ara", + "noProviderMatchFound": "Eşleşen sağlayıcı bulunamadı", "noMatchFound": "Eşleşen profil bulunamadı", "vscodeLmDescription": "VS Code Dil Modeli API'si, diğer VS Code uzantıları tarafından sağlanan modelleri çalıştırmanıza olanak tanır (GitHub Copilot dahil ancak bunlarla sınırlı değildir). Başlamanın en kolay yolu, VS Code Marketplace'ten Copilot ve Copilot Chat uzantılarını yüklemektir.", "awsCustomArnUse": "Kullanmak istediğiniz model için geçerli bir Amazon Bedrock ARN'si girin. Format örnekleri:", diff --git a/webview-ui/src/i18n/locales/vi/chat.json b/webview-ui/src/i18n/locales/vi/chat.json index eb7cdc2306..574df08da1 100644 --- a/webview-ui/src/i18n/locales/vi/chat.json +++ b/webview-ui/src/i18n/locales/vi/chat.json @@ -242,8 +242,8 @@ "title": "🎉 Roo Code {{version}} Đã phát hành", "description": "Roo Code {{version}} mang đến các tính năng mạnh mẽ mới và cải tiến đáng kể để nâng cao quy trình phát triển của bạn.", "whatsNew": "Có gì mới", - "feature1": "Chia sẻ Nhiệm vụ 1-Click: Chia sẻ nhiệm vụ của bạn với đồng nghiệp và cộng đồng ngay lập tức chỉ với một cú nhấp chuột.", - "feature2": "Hỗ trợ Thư mục .roo Toàn cục: Tải quy tắc và cấu hình từ thư mục .roo toàn cục để có cài đặt nhất quán giữa các dự án.", + "feature1": "Lập chỉ mục Codebase Tốt nghiệp từ 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 tìm kiếm cải tiến và hiểu biết ngữ cảnh.", + "feature2": "Tính năng Danh sách Todo Mới: Giữ nhiệm vụ của bạn đúng hướng với quản lý todo tích hợp giúp bạn duy trì tổ chức và tập trung vào mục tiêu phát triển.", "feature3": "Cải thiện Chuyển đổi từ Architect sang Code: Chuyển đổi mượt mà từ lập kế hoạch trong chế độ Architect sang triển khai trong chế độ Code.", "hideButton": "Ẩn thông báo", "detailsDiscussLinks": "Nhận thêm chi tiết và thảo luận tại DiscordReddit 🚀" diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index 66a4875922..6c9f2d0d8f 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -81,6 +81,7 @@ "ollamaBaseUrlLabel": "URL cơ sở Ollama", "qdrantApiKeyLabel": "Khóa API Qdrant", "qdrantApiKeyPlaceholder": "Nhập khóa API Qdrant của bạn (tùy chọn)", + "setupConfigLabel": "Cài đặt", "ollamaUrlPlaceholder": "http://localhost:11434", "openAiCompatibleBaseUrlPlaceholder": "https://api.example.com", "modelDimensionPlaceholder": "1536", @@ -97,6 +98,21 @@ "error": "Lỗi" }, "close": "Đóng", + "validation": { + "invalidQdrantUrl": "URL Qdrant không hợp lệ", + "invalidOllamaUrl": "URL Ollama không hợp lệ", + "invalidBaseUrl": "URL cơ sở không hợp lệ", + "qdrantUrlRequired": "Yêu cầu URL Qdrant", + "openaiApiKeyRequired": "Yêu cầu khóa API OpenAI", + "modelSelectionRequired": "Yêu cầu chọn mô hình", + "apiKeyRequired": "Yêu cầu khóa API", + "modelIdRequired": "Yêu cầu ID mô hình", + "modelDimensionRequired": "Yêu cầu kích thước mô hình", + "geminiApiKeyRequired": "Yêu cầu khóa API Gemini", + "ollamaBaseUrlRequired": "Yêu cầu URL cơ sở Ollama", + "baseUrlRequired": "Yêu cầu URL cơ sở", + "modelDimensionMinValue": "Kích thước mô hình phải lớn hơn 0" + }, "advancedConfigLabel": "Cấu hình nâng cao", "searchMinScoreLabel": "Ngưỡng điểm tìm kiếm", "searchMinScoreDescription": "Điểm tương đồng tối thiểu (0.0-1.0) cần thiết cho kết quả tìm kiếm. Giá trị thấp hơn trả về nhiều kết quả hơn nhưng có thể kém liên quan hơn. Giá trị cao hơn trả về ít kết quả hơn nhưng có liên quan hơn.", @@ -190,6 +206,8 @@ "createProfile": "Tạo hồ sơ", "cannotDeleteOnlyProfile": "Không thể xóa hồ sơ duy nhất", "searchPlaceholder": "Tìm kiếm hồ sơ", + "searchProviderPlaceholder": "Tìm kiếm nhà cung cấp", + "noProviderMatchFound": "Không tìm thấy nhà cung cấp", "noMatchFound": "Không tìm thấy hồ sơ phù hợp", "vscodeLmDescription": "API Mô hình Ngôn ngữ VS Code cho phép bạn chạy các mô hình được cung cấp bởi các tiện ích mở rộng khác của VS Code (bao gồm nhưng không giới hạn ở GitHub Copilot). Cách dễ nhất để bắt đầu là cài đặt các tiện ích mở rộng Copilot và Copilot Chat từ VS Code Marketplace.", "awsCustomArnUse": "Nhập một ARN Amazon Bedrock hợp lệ cho mô hình bạn muốn sử dụng. Ví dụ về định dạng:", diff --git a/webview-ui/src/i18n/locales/zh-CN/chat.json b/webview-ui/src/i18n/locales/zh-CN/chat.json index 93494e6f50..f6e51cfa49 100644 --- a/webview-ui/src/i18n/locales/zh-CN/chat.json +++ b/webview-ui/src/i18n/locales/zh-CN/chat.json @@ -242,8 +242,8 @@ "title": "🎉 Roo Code {{version}} 已发布", "description": "Roo Code {{version}} 带来强大的新功能和重大改进,提升您的开发工作流程。", "whatsNew": "新特性", - "feature1": "一键任务分享: 一键即可与同事和社区分享您的任务。", - "feature2": "全局 .roo 目录支持: 从全局 .roo 目录加载规则和配置,确保项目间设置一致。", + "feature1": "代码库索引从实验阶段正式发布: 完整的代码库索引现已稳定,可用于生产环境,具备改进的搜索和上下文理解功能。", + "feature2": "新增待办事项列表功能: 通过集成的待办事项管理保持任务进度,帮助你保持条理并专注于开发目标。", "feature3": "改进的架构师到代码转换: 从架构师模式的规划到代码模式的实现,实现无缝交接。", "hideButton": "隐藏公告", "detailsDiscussLinks": "在 DiscordReddit 获取更多详情并参与讨论 🚀" diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index 7d047ac958..97b78e7d0c 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -72,6 +72,7 @@ "qdrantKeyLabel": "Qdrant 密钥:", "qdrantApiKeyLabel": "Qdrant API 密钥", "qdrantApiKeyPlaceholder": "输入你的 Qdrant API 密钥(可选)", + "setupConfigLabel": "设置", "startIndexingButton": "开始", "clearIndexDataButton": "清除索引", "unsavedSettingsMessage": "请先保存设置再开始索引过程。", @@ -97,6 +98,21 @@ "error": "错误" }, "close": "关闭", + "validation": { + "invalidQdrantUrl": "无效的 Qdrant URL", + "invalidOllamaUrl": "无效的 Ollama URL", + "invalidBaseUrl": "无效的基础 URL", + "qdrantUrlRequired": "需要 Qdrant URL", + "openaiApiKeyRequired": "需要 OpenAI API 密钥", + "modelSelectionRequired": "需要选择模型", + "apiKeyRequired": "需要 API 密钥", + "modelIdRequired": "需要模型 ID", + "modelDimensionRequired": "需要模型维度", + "geminiApiKeyRequired": "需要 Gemini API 密钥", + "ollamaBaseUrlRequired": "需要 Ollama 基础 URL", + "baseUrlRequired": "需要基础 URL", + "modelDimensionMinValue": "模型维度必须大于 0" + }, "advancedConfigLabel": "高级配置", "searchMinScoreLabel": "搜索分数阈值", "searchMinScoreDescription": "搜索结果所需的最低相似度分数(0.0-1.0)。较低的值返回更多结果,但可能不太相关。较高的值返回较少但更相关的结果。", @@ -190,6 +206,8 @@ "createProfile": "创建配置", "cannotDeleteOnlyProfile": "无法删除唯一的配置文件", "searchPlaceholder": "搜索配置文件", + "searchProviderPlaceholder": "搜索提供商", + "noProviderMatchFound": "未找到提供商", "noMatchFound": "未找到匹配的配置文件", "vscodeLmDescription": "VS Code 语言模型 API 允许您运行由其他 VS Code 扩展(包括但不限于 GitHub Copilot)提供的模型。最简单的方法是从 VS Code 市场安装 Copilot 和 Copilot Chat 扩展。", "awsCustomArnUse": "请输入有效的 Amazon Bedrock ARN(Amazon资源名称),格式示例:", diff --git a/webview-ui/src/i18n/locales/zh-TW/chat.json b/webview-ui/src/i18n/locales/zh-TW/chat.json index e7a476cb37..54aeacf15c 100644 --- a/webview-ui/src/i18n/locales/zh-TW/chat.json +++ b/webview-ui/src/i18n/locales/zh-TW/chat.json @@ -242,8 +242,8 @@ "title": "🎉 Roo Code {{version}} 已發布", "description": "Roo Code {{version}} 帶來強大的新功能和重大改進,提升您的開發工作流程。", "whatsNew": "新功能", - "feature1": "一鍵分享工作:只需一鍵即可立即與同事和社群分享您的工作。", - "feature2": "全域 .roo 目錄支援:從全域 .roo 目錄載入規則和設定,確保專案間設定一致。", + "feature1": "程式碼庫索引從實驗階段正式發布:完整的程式碼庫索引現已穩定,可用於正式環境,具備改進的搜尋和內容理解功能。", + "feature2": "新增待辦事項清單功能:透過整合的待辦事項管理保持工作進度,幫助您保持條理並專注於開發目標。", "feature3": "改進的 Architect 到 Code 轉換:從 Architect 模式的規劃到 Code 模式的實作,轉換更加順暢。", "hideButton": "隱藏公告", "detailsDiscussLinks": "在 DiscordReddit 取得更多詳細資訊並參與討論 🚀" diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 3ade155434..ec4b41eb74 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -81,6 +81,7 @@ "ollamaBaseUrlLabel": "Ollama 基礎 URL", "qdrantApiKeyLabel": "Qdrant API 金鑰", "qdrantApiKeyPlaceholder": "輸入您的 Qdrant API 金鑰(選用)", + "setupConfigLabel": "設定", "ollamaUrlPlaceholder": "http://localhost:11434", "openAiCompatibleBaseUrlPlaceholder": "https://api.example.com", "modelDimensionPlaceholder": "1536", @@ -97,6 +98,21 @@ "error": "錯誤" }, "close": "關閉", + "validation": { + "invalidQdrantUrl": "無效的 Qdrant URL", + "invalidOllamaUrl": "無效的 Ollama URL", + "invalidBaseUrl": "無效的基礎 URL", + "qdrantUrlRequired": "需要 Qdrant URL", + "openaiApiKeyRequired": "需要 OpenAI API 金鑰", + "modelSelectionRequired": "需要選擇模型", + "apiKeyRequired": "需要 API 金鑰", + "modelIdRequired": "需要模型 ID", + "modelDimensionRequired": "需要模型維度", + "geminiApiKeyRequired": "需要 Gemini API 金鑰", + "ollamaBaseUrlRequired": "需要 Ollama 基礎 URL", + "baseUrlRequired": "需要基礎 URL", + "modelDimensionMinValue": "模型維度必須大於 0" + }, "advancedConfigLabel": "進階設定", "searchMinScoreLabel": "搜尋分數閾值", "searchMinScoreDescription": "搜尋結果所需的最低相似度分數(0.0-1.0)。較低的值會傳回更多結果,但可能較不相關。較高的值會傳回較少但更相關的結果。", @@ -190,6 +206,8 @@ "createProfile": "建立設定檔", "cannotDeleteOnlyProfile": "無法刪除唯一的設定檔", "searchPlaceholder": "搜尋設定檔", + "searchProviderPlaceholder": "搜尋供應商", + "noProviderMatchFound": "找不到供應商", "noMatchFound": "找不到符合的設定檔", "vscodeLmDescription": "VS Code 語言模型 API 可以讓您使用其他擴充功能(如 GitHub Copilot)提供的模型。最簡單的方式是從 VS Code Marketplace 安裝 Copilot 和 Copilot Chat 擴充套件。", "awsCustomArnUse": "輸入您要使用的模型的有效 Amazon Bedrock ARN。格式範例:",