Skip to content

Use vue-i18n useI18n/t and add Erlang i18n#21

Open
TanNhatCMS wants to merge 3 commits intomasterfrom
update-lang
Open

Use vue-i18n useI18n/t and add Erlang i18n#21
TanNhatCMS wants to merge 3 commits intomasterfrom
update-lang

Conversation

@TanNhatCMS
Copy link
Owner

@TanNhatCMS TanNhatCMS commented Feb 27, 2026

Replace legacy I18nT usage with vue-i18n composition API (useI18n and t()) across numerous Vue components (App, Conf drawer, Deno, Erlang, MySQL modules, Podman, etc.). Add 'projectErlang' translation key to many locale host.json files and minor Vietnamese i18n additions. Remove legacy: true from createI18n call. Also add helper-go/go.sum and Windows resource binaries (rsrc_windows_386/amd64.syso).

Summary by CodeRabbit

  • New Features

    • Added support for Erlang projects with translated labels across all languages.
    • Added Vietnamese translations for online and local domain names.
  • Refactor

    • Migrated internationalization system from legacy helper API to Vue I18n composition API.
    • Removed legacy mode from i18n configuration.
  • Localization

    • Updated translation strings for existing project categories in multiple languages.

Replace legacy I18nT usage with vue-i18n composition API (useI18n and t()) across numerous Vue components (App, Conf drawer, Deno, Erlang, MySQL modules, Podman, etc.). Add 'projectErlang' translation key to many locale host.json files and minor Vietnamese i18n additions. Remove legacy: true from createI18n call. Also add helper-go/go.sum and Windows resource binaries (rsrc_windows_386/amd64.syso).
@coderabbitai
Copy link

coderabbitai bot commented Feb 27, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch update-lang

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment on lines 169 to 174
export const AppI18n = (l?: string): I18n => {
if (!i18n) {
i18n = createI18n({
legacy: true,
locale: l || 'en',
fallbackLocale: 'en',
messages: lang as any
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The removal of legacy: true from createI18n makes i18n.global.locale a Ref. The direct assignment i18n.global.locale = l will fail, breaking language switching.
Severity: CRITICAL

Suggested Fix

When legacy: false (the new default), the locale must be updated by assigning to the .value property of the Ref. Change i18n.global.locale = l to i18n.global.locale.value = l to correctly update the language.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: src/lang/index.ts#L169-L174

Potential issue: By removing `legacy: true` from the `createI18n` call, the
`i18n.global.locale` property is changed from a plain string to a reactive `Ref` object.
The code subsequently attempts to assign a new language code directly via
`i18n.global.locale = l`. This assignment will fail because a `Ref`'s value must be
updated through its `.value` property. This will prevent the application's language from
being updated when a user tries to change it in the settings, breaking the language
switching functionality.

Did we get this right? 👍 / 👎 to inform future reviews.

@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the application's internationalization system by adopting the vue-i18n Composition API. This change streamlines translation management within Vue components, making the codebase more maintainable and aligned with modern Vue 3 practices. Concurrently, it expands the application's linguistic capabilities by integrating support for Erlang-related terms and refining existing Vietnamese translations.

Highlights

  • Internationalization (i18n) Migration: Migrated numerous Vue components from the legacy I18nT function to the modern vue-i18n Composition API (useI18n and t()).
  • Erlang i18n Support: Added new translation keys for 'projectErlang' across various locale files, enhancing support for Erlang projects.
  • Vue I18n Configuration Update: Removed the legacy: true option from the createI18n call in src/lang/index.ts, aligning with the Composition API usage.
  • Vietnamese i18n Additions: Included minor additions to Vietnamese translations, specifically for 'OnlineDomain' and 'LocalDoman'.
Changelog
  • src/lang/en/host.json
    • Added 'projectErlang' translation key.
  • src/lang/es/host.json
    • Added 'projectErlang' translation key.
  • src/lang/fi/host.json
    • Added 'projectErlang' translation key.
  • src/lang/fr/host.json
    • Added 'projectErlang' translation key.
  • src/lang/id/host.json
    • Added 'projectErlang' translation key.
    • Updated existing Deno, Bun, and Perl project translations to Indonesian.
  • src/lang/index.ts
    • Removed 'legacy: true' option from 'createI18n' call.
  • src/lang/it/host.json
    • Added 'projectErlang' translation key.
    • Updated existing Deno, Bun, and Perl project translations to Italian.
  • src/lang/ja/host.json
    • Added 'projectErlang' translation key.
    • Updated existing Deno, Bun, and Perl project translations to Japanese.
  • src/lang/nl/host.json
    • Added 'projectErlang' translation key.
  • src/lang/no/host.json
    • Added 'projectErlang' translation key.
  • src/lang/pl/host.json
    • Added 'projectErlang' translation key.
  • src/lang/pt-br/host.json
    • Added 'projectErlang' translation key.
  • src/lang/pt/host.json
    • Added 'projectErlang' translation key.
  • src/lang/ro/host.json
    • Added 'projectErlang' translation key.
  • src/lang/ru/host.json
    • Added 'projectErlang' translation key.
  • src/lang/sv/host.json
    • Added 'projectErlang' translation key.
    • Updated existing Deno, Bun, and Perl project translations to Swedish.
  • src/lang/tr/host.json
    • Added 'projectErlang' translation key.
  • src/lang/uk/host.json
    • Added 'projectErlang' translation key.
  • src/lang/vi/host.json
    • Added 'projectErlang', 'OnlineDomain', and 'LocalDoman' translation keys.
  • src/lang/zh/host.json
    • Added 'projectErlang' translation key.
  • src/render/App.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Conf/drawer.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Deno/Index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Erlang/Index.vue
    • Migrated I18nT calls to t().
  • src/render/components/Mysql/Config.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Mysql/Group/Add.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
    • Updated readonly attribute from 'true' to 'readonly'.
  • src/render/components/Mysql/Group/Config.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Mysql/Group/Index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Mysql/Group/Logs.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Mysql/Group/SetupPopper.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Mysql/Index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Mysql/Manage/addDatabase.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Mysql/Manage/database.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Mysql/Manage/index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Mysql/Manage/setBackupDir.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Mysql/Manage/setPassword.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Nginx/Config.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Nginx/Index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Nodejs/Config.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
    • Changed config variable declaration from let to const.
  • src/render/components/Nodejs/Index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Nodejs/List.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
    • Removed an empty script setup tag.
  • src/render/components/Nodejs/default/index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
    • Updated hasOwnProperty usage to Object.prototype.hasOwnProperty.call.
  • src/render/components/Nodejs/fnm/index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
    • Removed an empty script setup tag.
  • src/render/components/Nodejs/nvm/index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
    • Removed an empty script setup tag.
  • src/render/components/Nodejs/projects/dependencies/index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Ollama/Index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Ollama/models/all/index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Ollama/models/index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Ollama/models/local/index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/PHP/Config.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/PHP/DisableFunction.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/PHP/ErrorLog.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/PHP/Extends.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/PHP/Extension/Homebrew/index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/PHP/Extension/Lib/index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/PHP/Extension/Loaded/index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/PHP/Extension/Macports/index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/PHP/List.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/PHP/Logs.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/PHP/aside.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Perl/Index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/Index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
    • Updated taskConfirm call to use t() for translation.
  • src/render/components/Podman/compose-build/Base.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/Bun.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/Consul.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/Deno.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/Elasticsearch.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/Erlang.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/Etcd.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/Go.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/Java.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/MariaDB.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/Meilisearch.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/MinIO.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/MongoDB.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/MySQL.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/NodeJS.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/Perl.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/PostgreSQL.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/Python.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/RabbitMQ.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/Redis.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/Ruby.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/Rust.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/components/base.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/components/docRoot.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/components/preview.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose-build/components/wwwRoot.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose/compose.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose/composeAdd.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/compose/composeBuild.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/container/container.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/container/containerCreate.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/container/info.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/container/preview.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/dashboard.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
    • Added a blank line in CSS for better formatting.
  • src/render/components/Podman/image/image.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/image/imageAdd.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/left.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/machine/machineAdd.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/Podman/right.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/components/PostgreSql/Index.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
  • src/render/tray/App.vue
    • Migrated I18nT calls to t().
    • Imported useI18n from 'vue-i18n'.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request successfully refactors most of the codebase to use the vue-i18n composition API, replacing the legacy I18nT helper. It also adds new translations for Erlang projects. The changes are mostly correct and improve consistency. However, I found a few issues: a typo in a translation key, one component that was missed in the refactoring, and a critical bug in a function call that would lead to a runtime error.

<template v-if="PodmanManager.installEnd">
<el-button type="primary" @click.stop="taskConfirm">{{
I18nT('base.confirm')
taskConfirm('base.confirm')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The function call taskConfirm('base.confirm') is incorrect. The taskConfirm function does not accept any arguments, and this will cause a runtime error. The intention was probably to use the translation function t('base.confirm') for the button's text.

                t('base.confirm')

"dbclickRowToEdit": "Nhấp đúp vào dòng này để chỉnh sửa",

"OnlineDomain": "Tên miền trực tuyến",
"LocalDoman": "Tên miền Local"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There's a typo in the translation key. It should be LocalDomain to match the English key and avoid potential issues.

Suggested change
"LocalDoman": "Tên miền Local"
"LocalDomain": "Tên miền Local"

<ProjectIndex
v-else-if="tab === 2"
:title="`Erlang ${I18nT('base.projects')}`"
:title="I18nT('host.projectErlang')"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This component still uses the legacy I18nT helper. To be consistent with the rest of the changes in this pull request, it should be updated to use the useI18n composition API. You'll need to import useI18n and initialize t in the <script setup> block, then use t() here and for defining tabs.

        :title="t('host.projectErlang')"

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
src/render/components/Podman/compose-build/Meilisearch.vue (1)

5-11: ⚠️ Potential issue | 🟡 Minor

Inconsistent i18n: hardcoded "Password" label.

Line 5 correctly uses t('podman.Persistence'), but line 9 has a hardcoded label="Password". For consistency and proper localization, this should also use the translation function.

Suggested fix
-    <el-form-item label="Password">
+    <el-form-item :label="t('base.password')">

Note: Verify that the appropriate translation key exists in your locale files, or add one if needed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/Meilisearch.vue` around lines 5 -
11, The "Password" label in Meilisearch.vue is hardcoded; update the
<el-form-item> that wraps the <el-input
v-model="form.environment.MEILI_MASTER_KEY"> to use the i18n function (e.g.
label="t('podman.Password')" or an appropriate key like
t('meilisearch.Password')), ensure the chosen translation key exists in your
locale files (or add it), and keep the v-model binding to
form.environment.MEILI_MASTER_KEY unchanged.
src/render/components/Podman/compose-build/RabbitMQ.vue (1)

5-21: ⚠️ Potential issue | 🟡 Minor

Inconsistent i18n: hardcoded labels.

Line 5 correctly uses t('podman.Persistence'), but lines 9 and 16 have hardcoded labels "Default User" and "Default Password". For consistent localization, these should also use the translation function.

Suggested fix
-    <el-form-item label="Default User">
+    <el-form-item :label="t('rabbitmq.defaultUser')">
       <el-input
         v-model="form.environment.RABBITMQ_DEFAULT_USER"
         placeholder="RABBITMQ_DEFAULT_USER"
       ></el-input>
     </el-form-item>

-    <el-form-item label="Default Password">
+    <el-form-item :label="t('rabbitmq.defaultPassword')">

Note: Ensure corresponding translation keys exist in your locale files.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/RabbitMQ.vue` around lines 5 - 21,
The two el-form-item labels in RabbitMQ.vue are hardcoded ("Default
User"/"Default Password"); update those labels to use the i18n function (e.g.
t('podman.DefaultUser') and t('podman.DefaultPassword')) so they match the
existing i18n style used for persistence, keeping the bindings to
form.environment.RABBITMQ_DEFAULT_USER and
form.environment.RABBITMQ_DEFAULT_PASS unchanged, and add the corresponding keys
to the locale files.
src/render/App.vue (1)

183-189: ⚠️ Potential issue | 🟡 Minor

Variable t shadows the i18n translation function.

The variable t declared on line 184 shadows the t function from useI18n() (line 25). While this works within the computed scope, it creates confusion and could lead to bugs if the computed body is modified to use translations.

Rename the local variable to avoid shadowing.

🐛 Proposed fix
  const theme = computed(() => {
-   const t = appStore?.config?.setup?.theme
-   if (!t) {
+   const configTheme = appStore?.config?.setup?.theme
+   if (!configTheme) {
      return isDark.value ? 'dark' : 'light'
    }
-   return t
+   return configTheme
  })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/App.vue` around lines 183 - 189, The computed property theme uses
a local variable named t which shadows the i18n translation function returned by
useI18n(); rename that local variable (e.g., to themeSetting or cfgTheme) inside
the theme computed (the block referencing appStore?.config?.setup?.theme) and
update its uses so the i18n t() function remains unshadowed and available for
translations elsewhere.
src/render/components/Nodejs/projects/dependencies/index.vue (1)

192-194: ⚠️ Potential issue | 🟡 Minor

Missing parentheses on toString method call.

e.toString references the function itself rather than calling it. This will display something like [Function: toString] instead of the actual error message.

🐛 Proposed fix
    } catch (e: any) {
-     ElMessage.error(e.toString)
+     ElMessage.error(e.toString())
    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Nodejs/projects/dependencies/index.vue` around lines
192 - 194, The catch block is passing the toString function reference instead of
invoking it; update the error handling in the catch for the ElMessage.error call
(the block containing "catch (e: any)" and the ElMessage.error invocation) to
call the function and surface a real message — e.g. invoke e.toString() or use
e.message || String(e) so ElMessage.error receives an actual string.
🧹 Nitpick comments (37)
src/render/components/Mysql/Manage/setBackupDir.vue (1)

24-30: Move useI18n() call after all imports.

The executable statement const { t } = useI18n() is placed between import declarations. For better readability and consistency, group all imports together at the top, then place executable code afterward.

♻️ Suggested reordering
 import { computed } from 'vue'
 import { AsyncComponentSetup } from '@/util/AsyncComponent'
 import { useI18n } from 'vue-i18n'
-
-const { t } = useI18n()
 import type { ModuleInstalledItem } from '@/core/Module/ModuleInstalledItem'
 import { MySQLManage } from './manage'
 import { FolderOpened } from '@element-plus/icons-vue'
 import { dialog } from '@/util/NodeFn'
+
+const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Mysql/Manage/setBackupDir.vue` around lines 24 - 30,
Move the executable call const { t } = useI18n() so that it appears after all
import statements; specifically, keep all imports (useI18n, ModuleInstalledItem,
MySQLManage, FolderOpened, dialog) grouped at the top of setBackupDir.vue and
then place the const { t } = useI18n() initialization immediately after the
imports (before any other executable logic) to avoid having an executable
statement between import declarations.
src/render/components/Podman/compose-build/components/wwwRoot.vue (1)

15-17: Move useI18n() call after all imports.

The const { t } = useI18n() statement is placed between import statements. While this works (imports are hoisted), it breaks conventional code organization where all imports should be grouped at the top before any executable statements.

♻️ Proposed fix
  import { computed } from 'vue'
  import { ComposeBuildForm } from '@/components/Podman/compose-build/Form'
  import { Folder } from '@element-plus/icons-vue'
  import { useI18n } from 'vue-i18n'
-  const { t } = useI18n()
  import { ComposeBuildSetup } from '@/components/Podman/compose-build/setup'
+
+  const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/components/wwwRoot.vue` around
lines 15 - 17, Move the call to useI18n so all import statements are grouped
together: remove the top-level const { t } = useI18n() that currently sits
between imports and place it immediately after the last import (e.g., after the
ComposeBuildSetup import) or inside the component's setup() block; ensure the
symbol t is still exported/available where used in this file (wwwRoot.vue) and
that useI18n() is called once in the appropriate scope.
src/render/components/Podman/machine/machineAdd.vue (2)

4-4: Avoid concatenating translated fragments in dialog title.

Line 4 builds the title with t(...) + t(...), which can break grammar/word order in several locales. Prefer a single translation key (with interpolation if needed) so each locale controls full phrasing.

Proposed refactor
-:title="isEdit ? t('base.edit') + t('podman.Machine') : t('podman.Machine') + t('base.add')"
+:title="isEdit ? t('podman.machineDialogTitle.edit') : t('podman.machineDialogTitle.add')"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/machine/machineAdd.vue` at line 4, The title
concatenates two translations which breaks localization; replace the inline
concatenation in machineAdd.vue's :title binding by using a single translation
key that accepts an action interpolation (e.g. t('podman.machineTitle', {
action: isEdit ? t('base.edit') : t('base.add') })), and add corresponding i18n
entries (e.g. "podman.machineTitle": "{{action}} {{Machine}}" or per-locale
phrasing) so each locale controls full word order; update any uses of isEdit and
t(...) in that :title binding to use the new single-key interpolation.

89-89: Use one localized key for the required-name error message.

Line 89 concatenates t('base.name') + t('podman.require'); this is brittle across locales. Use one message key (optionally interpolated) for a natural localized sentence.

Proposed refactor
-ElMessage.error(t('base.name') + t('podman.require'))
+ElMessage.error(t('podman.nameRequired'))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/machine/machineAdd.vue` at line 89, Replace the
concatenated localized strings with a single localization key that produces a
natural sentence; update the ElMessage.error call in the machineAdd component to
use one translation key (for example t('podman.requireName', { name:
t('base.name') })) instead of t('base.name') + t('podman.require'), and
add/update the corresponding entries in all locale files (podman.requireName) to
accept the interpolated name so translations remain natural.
src/render/components/Podman/compose/composeBuild.vue (1)

4-4: Localize the full dialog title key instead of concatenating an English suffix.

On Line 4, t('podman.Build') + ' Compose' hardcodes English and can produce awkward ordering in some locales. Prefer a single translation key (or interpolation) for the full title.

♻️ Proposed refactor
-    :title="t('podman.Build') + ' Compose'"
+    :title="t('podman.buildComposeTitle')"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose/composeBuild.vue` at line 4, The
template currently builds the dialog title by concatenating t('podman.Build') +
' Compose' which hardcodes English; change the :title binding in
composeBuild.vue to use a single i18n key or interpolation instead (e.g. add a
new translation key like "podman.BuildCompose" or a generic
"podman.BuildWithTool" that accepts a tool interpolation) and update the
template to call t(...) with that key and any interpolation variables; also add
the corresponding entries to your locale files so all languages get a properly
ordered, localized full title.
src/render/components/Podman/compose-build/components/base.vue (1)

40-42: Move useI18n() call after all imports.

The const { t } = useI18n() statement is placed between import statements. Imports should be grouped together at the top, followed by other declarations.

♻️ Suggested fix
 import { computed, onMounted, onUnmounted } from 'vue'
 import { ComposeBuildForm } from '@/components/Podman/compose-build/Form'
 import { useI18n } from 'vue-i18n'
-const { t } = useI18n()
 import { PodmanManager } from '../../class/Podman'
+
+const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/components/base.vue` around lines
40 - 42, Move the useI18n() call so all imports are grouped at the top: remove
"const { t } = useI18n()" from between the import statements and place it
immediately after the import block (e.g. after the import of PodmanManager).
Ensure the symbol useI18n and the destructured t remain unchanged and are
initialized once at the top of the module scope, keeping import lines
contiguous.
src/render/components/Podman/image/image.vue (1)

87-90: Move const { t } = useI18n() after all imports.

The const declaration is placed between import statements, which is non-idiomatic. While JavaScript hoists imports so this works at runtime, it reduces readability and violates conventional code organization.

♻️ Suggested fix
 import { computed } from 'vue'
 import { PodmanManager } from '@/components/Podman/class/Podman'
 import { useI18n } from 'vue-i18n'
-
-const { t } = useI18n()
 import type { Image } from '@/components/Podman/class/Image'
 import { AsyncComponentShow } from '@/util/AsyncComponent'
 import { clipboard } from '@/util/NodeFn'
 import { MessageSuccess } from '@/util/Element'
 import { formatBytes } from '@/util/Index'
 import { XTermExecCache } from '@/util/XTermExec'
+
+const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/image/image.vue` around lines 87 - 90, Move the
const { t } = useI18n() declaration so it appears after all import statements
(e.g., after import type { Image } from '@/components/Podman/class/Image') —
keep all import lines together at the top of
src/render/components/Podman/image/image.vue and then call useI18n()/const { t }
= useI18n() before any component code that uses t.
src/render/components/Podman/image/imageAdd.vue (2)

37-39: Consider moving the useI18n() call after all imports.

Placing the const { t } = useI18n() statement between import declarations is unconventional, even though <script setup> allows it. Grouping all imports at the top improves readability.

🔧 Suggested reorganization
 import { computed, ref, watch } from 'vue'
 import { useI18n } from 'vue-i18n'
-const { t } = useI18n()
 import { ElMessage } from 'element-plus'
 import { PodmanManager } from '@/components/Podman/class/Podman'
 import { OfficialImages } from '@/components/Podman/officialImages'
 import { AllAppModule } from '@/core/type'
 import Base from '../compose-build/Form/Base'
 import { XTermExec, XTermExecCache } from '@/util/XTermExec'
 import { reactiveBind, uuid } from '@/util/Index'
 import { AsyncComponentSetup, AsyncComponentShow } from '@/util/AsyncComponent'
 import { Image } from '@/components/Podman/class/Image'

+const { t } = useI18n()
+
 const { show, onClosed, onSubmit, closedFn } = AsyncComponentSetup()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/image/imageAdd.vue` around lines 37 - 39, Move
the call to useI18n() so all import statements are grouped at the top: keep the
import lines (including "import { useI18n } from 'vue-i18n'" and "import {
ElMessage } from 'element-plus'") together, then invoke const { t } = useI18n()
immediately after the imports (not between import lines). Update the file so
useI18n() is called once after imports to improve readability and maintain
conventional import grouping while leaving the rest of the component (references
to t and ElMessage) unchanged.

4-4: String concatenation may produce awkward translations in some languages.

Concatenating t('podman.Image') + t('base.add') doesn't account for languages with different word orders or grammatical rules. Consider using a dedicated key like t('podman.addImageTitle') with the full phrase in each locale file.

Same applies to line 165: t('podman.Image') + t('podman.require').

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/image/imageAdd.vue` at line 4, Replace the
string concatenations used for translated strings with single dedicated i18n
keys: instead of t('podman.Image') + t('base.add') update the template binding
(the :title expression) to use a new key like t('podman.addImageTitle'), and
instead of t('podman.Image') + t('podman.require') replace that usage with a new
key like t('podman.imageRequired'); add these full-phrase entries to the locale
files for each language and remove the concatenations in the component so
translations can handle word order and grammar correctly.
src/render/components/Nodejs/nvm/index.vue (3)

46-49: Organize imports: place useI18n import with other imports.

The useI18n import and its destructuring are placed before other imports, creating an unconventional import organization. Consider grouping all imports together at the top.

♻️ Suggested organization
 <script lang="tsx" setup>
-  import { useI18n } from 'vue-i18n'
-
-  const { t } = useI18n()
   import { NVMSetup, Setup } from './setup'
   import { type Column, ElButton, ElInput, ElTooltip } from 'element-plus'
   import { MessageSuccess } from '@/util/Element'
   import { clipboard } from '@/util/NodeFn'
+  import { useI18n } from 'vue-i18n'
+
+  const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Nodejs/nvm/index.vue` around lines 46 - 49, Move the
import statement "import { useI18n } from 'vue-i18n'" to be grouped with the
other imports at the top of the file and ensure the call "const { t } =
useI18n()" occurs after imports (or inside the component/setup block) rather
than before other imports; this keeps import ordering consistent with "import {
NVMSetup, Setup } from './setup'" and avoids using useI18n() before module
imports are declared.

13-15: Fix formatting per Prettier rules.

The static analysis tool flagged a formatting issue. The radio button content should be on a single line.

♻️ Suggested fix
-            <el-radio-button key="shell" label="shell"
-              >{{ t('base.Official') }}
-            </el-radio-button>
+            <el-radio-button key="shell" label="shell">{{ t('base.Official') }}</el-radio-button>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Nodejs/nvm/index.vue` around lines 13 - 15, The
el-radio-button element rendering the official label in the Nodejs nvm component
is split across multiple lines and violates Prettier; locate the
<el-radio-button key="shell" label="shell"> element in
src/render/components/Nodejs/nvm/index.vue and collapse its inner content so the
entire tag and its interpolation {{ t('base.Official') }} are on a single line
(e.g., <el-radio-button key="shell" label="shell">{{ t('base.Official')
}}</el-radio-button>) to satisfy formatting rules.

21-23: Consider consistent formatting with other radio buttons.

For consistency with line 16-17 (Homebrew and Macports buttons), consider keeping the install button content inline as well.

♻️ Suggested fix
-          <el-button class="mt-3" type="primary" `@click.stop`="installNVM"
-            >{{ t('base.install') }}
-          </el-button>
+          <el-button class="mt-3" type="primary" `@click.stop`="installNVM">{{
+            t('base.install')
+          }}</el-button>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Nodejs/nvm/index.vue` around lines 21 - 23, The install
button's template is broken across multiple lines unlike the other radio
buttons; update the <el-button> for installNVM so its content is inline like the
Homebrew/Macports buttons (keep the same attributes including `@click.stop` and
type="primary" and the installNVM handler, but place {{ t('base.install') }} on
the same line inside the <el-button> tag).
src/render/components/Nodejs/Index.vue (1)

24-28: Consider grouping all imports together at the top of the script.

The import statements on lines 27-28 are placed after the const { t } = useI18n() declaration. While JavaScript hoists imports, placing them after runtime code is unconventional and reduces readability.

♻️ Suggested reordering
 import { AppModuleSetup } from '@/core/Module'
 import { useI18n } from 'vue-i18n'
-
-  const { t } = useI18n()
 import Create from './CreateProject.vue'
 import ProjectIndex from './projects/index.vue'
+
+  const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Nodejs/Index.vue` around lines 24 - 28, The import
statements for Create and ProjectIndex are placed after the runtime call to
useI18n (the line with const { t } = useI18n()), which is unconventional; move
the imports for Create and ProjectIndex so that all import declarations
(including useI18n) appear at the top of the module before any runtime code,
e.g., import useI18n first then invoke const { t } = useI18n() afterward,
ensuring symbols Create and ProjectIndex are imported before use.
src/render/components/Podman/compose-build/Base.vue (1)

26-28: Minor style: import ordering.

Same pattern as other files - import appears after the const { t } declaration. Consider grouping all imports at the top for consistency across the codebase.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/Base.vue` around lines 26 - 28,
Move the import for ComposeBuildForm above any runtime statements so all imports
are grouped at the top: place "import { ComposeBuildForm } from
'@/components/Podman/compose-build/Form'" before the "const { t } = useI18n()"
line (and ensure the call to useI18n() remains after the imports), keeping the
useI18n import and the destructuring of t unchanged.
src/render/components/Mysql/Config.vue (1)

22-25: Minor style: import statement after variable declaration.

The import on line 25 appears after const { t } = useI18n(). While ES module imports are hoisted and this works, it's unconventional and can reduce readability. Consider grouping all imports together at the top.

Suggested reordering
-  import { useI18n } from 'vue-i18n'
-
-  const { t } = useI18n()
   import { debounce } from 'lodash-es'
+  import { useI18n } from 'vue-i18n'
   import { AppStore } from '@/store/app'
   import { uuid } from '@/util/Index'
   import { join } from '@/util/path-browserify'
   import { IniParse } from '@/util/IniParse'
+
+  const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Mysql/Config.vue` around lines 22 - 25, Move the import
for debounce so all imports are grouped at the top of the module: place "import
{ debounce } from 'lodash-es'" above the call to useI18n(), then keep the
existing "const { t } = useI18n()" afterwards; this preserves behavior (imports
are hoisted) but improves readability and follows conventional module
structure—locate the symbols useI18n, const { t } = useI18n(), and debounce when
making the change.
src/render/components/Podman/compose-build/Perl.vue (1)

18-20: Minor style: import ordering.

Same pattern as other files. Consider grouping all imports at the top.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/Perl.vue` around lines 18 - 20,
Reorder the imports in Perl.vue so all import statements (e.g., import { useI18n
} from 'vue-i18n' and import { OfficialImages } from
'@/components/Podman/officialImages') appear at the top of the module, and move
the destructuring const { t } = useI18n() immediately after the useI18n import
(not between imports); this matches the project style of grouping imports first
and then running module initialization like useI18n()/const { t } = useI18n().
src/render/components/Podman/compose-build/RabbitMQ.vue (1)

30-32: Minor style: import ordering.

Same pattern - import after const { t } declaration. Consider grouping imports for consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/RabbitMQ.vue` around lines 30 -
32, Move all import statements before any top-level code: place "import {
OfficialImages } from '@/components/Podman/officialImages'" above the call to
useI18n and the "const { t } = useI18n()" line so imports are grouped together;
ensure no other imports remain after the "const { t }" declaration and keep the
"useI18n" call immediately after the imports.
src/render/components/Podman/compose-build/Meilisearch.vue (1)

20-22: Minor style: import ordering.

Same pattern - import after const { t } declaration. Consider grouping imports for consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/Meilisearch.vue` around lines 20 -
22, Move the import of OfficialImages to be grouped with other imports before
any runtime code; specifically, ensure the import statement for
'@/components/Podman/officialImages' appears above the useI18n call so that
useI18n() and the const { t } = useI18n() remain after all imports. Update the
file to import OfficialImages alongside useI18n (and any other imports) to keep
consistent import ordering and avoid declaring const { t } before module
imports.
src/render/components/Podman/compose-build/Bun.vue (1)

18-19: Minor style: import after variable declaration.

Same as other files in this PR - the import on line 20 comes after const { t } = useI18n(). Consider grouping imports together for consistency.

Suggested reordering
   import { computed } from 'vue'
   import { ComposeBuildForm } from '@/components/Podman/compose-build/Form'
   import { useI18n } from 'vue-i18n'
-  const { t } = useI18n()
   import { OfficialImages } from '@/components/Podman/officialImages'
   import BaseVM from '@/components/Podman/compose-build/components/base.vue'
   import PreviewVM from './components/preview.vue'
   import WwwRoot from './components/wwwRoot.vue'
+
+  const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/Bun.vue` around lines 18 - 19,
Move the import so all imports are grouped at the top: place the "import {
useI18n } from 'vue-i18n'" statement before the "const { t } = useI18n()"
declaration in Bun.vue so the useI18n symbol is imported prior to being used and
matches the import ordering used across the PR.
src/render/components/Podman/compose-build/Python.vue (1)

18-20: Minor style: import ordering.

Same pattern as other files. Consider grouping all imports at the top for consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/Python.vue` around lines 18 - 20,
The import ordering is inconsistent: group all imports at the top of the module
and move the useI18n call after imports—specifically ensure the import of
OfficialImages and any other modules appear before calling const { t } =
useI18n(), keeping the useI18n() invocation (const { t } = useI18n()) below the
import block for consistent style with other files.
src/render/components/Podman/compose-build/NodeJS.vue (1)

16-23: Consider grouping imports before executable statements.

The const { t } = useI18n() call on line 19 is interleaved between import statements. While this works, it's cleaner to place all imports together at the top, followed by the useI18n() call.

♻️ Suggested reordering
 import { computed } from 'vue'
 import { ComposeBuildForm } from '@/components/Podman/compose-build/Form'
 import { useI18n } from 'vue-i18n'
-const { t } = useI18n()
 import { OfficialImages } from '@/components/Podman/officialImages'
 import BaseVM from '@/components/Podman/compose-build/components/base.vue'
 import PreviewVM from '@/components/Podman/compose-build/components/preview.vue'
 import WwwRoot from '@/components/Podman/compose-build/components/wwwRoot.vue'
+
+const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/NodeJS.vue` around lines 16 - 23,
Move the executable call const { t } = useI18n() so all import statements are
grouped together at the top of the module; specifically, keep the import lines
for computed, ComposeBuildForm, useI18n, OfficialImages, BaseVM, PreviewVM, and
WwwRoot together, then place the const { t } = useI18n() statement immediately
after the imports (e.g., before any component logic or setup) to avoid
interleaving imports with executable code.
src/render/components/Ollama/models/index.vue (1)

53-61: Import after executable statement.

Line 57 (import { OllamaModelsSetup, SetupAll }...) comes after the useI18n() call on line 56. Group all imports together.

♻️ Suggested reordering
 import { useI18n } from 'vue-i18n'
-
-const { t } = useI18n()
 import { OllamaModelsSetup, SetupAll } from './setup'
 import LocalVM from './local/index.vue'
 import AllVM from './all/index.vue'
+
+const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Ollama/models/index.vue` around lines 53 - 61, The
import of OllamaModelsSetup and SetupAll occurs after an executable call to
useI18n(), which violates module import ordering; move the import statements
(import { OllamaModelsSetup, SetupAll } from './setup' and imports for LocalVM
and AllVM) above the call to useI18n() so all imports are grouped at the top,
then call const { t } = useI18n() and finally invoke SetupAll() to destructure
showFooter, taskEnd, taskConfirm, taskCancel, loading, reFetch, openURL.
src/render/components/Deno/Index.vue (1)

41-41: Non-reactive translation in tabs array.

The tabs array is initialized once at component setup. If your app supports runtime locale switching, these translations won't update when the locale changes. Consider using a computed property instead.

♻️ Reactive alternative (if needed)
-const tabs = [t('base.service'), t('base.versionManager'), t('host.projectDeno')]
+const tabs = computed(() => [t('base.service'), t('base.versionManager'), t('host.projectDeno')])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Deno/Index.vue` at line 41, The tabs array is created
once with const tabs = [t('base.service'), t('base.versionManager'),
t('host.projectDeno')] so translations won't update when the locale changes;
replace it with a reactive computed that returns [t('base.service'),
t('base.versionManager'), t('host.projectDeno')] (i.e. use computed(() => [...])
inside the component setup and import computed from 'vue') so t() is
re-evaluated on locale changes; ensure any usage in the template or script reads
the computed directly (template auto-unwraps, script may need .value).
src/render/components/Podman/compose-build/MySQL.vue (1)

35-37: Consider grouping imports before variable declarations.

Same pattern as other files: move const { t } = useI18n() after all import statements.

♻️ Suggested reordering
  import { useI18n } from 'vue-i18n'
- const { t } = useI18n()
  import { OfficialImages } from '@/components/Podman/officialImages'
  import BaseVM from '@/components/Podman/compose-build/components/base.vue'
  import PreviewVM from '@/components/Podman/compose-build/components/preview.vue'
+
+ const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/MySQL.vue` around lines 35 - 37,
The file declares const { t } = useI18n() before completing imports; move the
const { t } = useI18n() line to after all import statements (i.e., after import
{ OfficialImages } from '@/components/Podman/officialImages') so useI18n() is
invoked only after imports are grouped, keeping the import block together and
consistent with other files.
src/render/components/Podman/compose-build/components/preview.vue (1)

27-29: Consider grouping imports before variable declarations.

The const { t } = useI18n() is placed between import statements. For consistency across the codebase, group all imports before variable declarations.

♻️ Suggested reordering
  import { useI18n } from 'vue-i18n'
- const { t } = useI18n()
  import { ComposeBuildSetup } from '@/components/Podman/compose-build/setup'
+
+ const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/components/preview.vue` around
lines 27 - 29, Move the variable declaration const { t } = useI18n() so that all
import statements are grouped above it; specifically, place the useI18n() call
after the import of ComposeBuildSetup and any other imports in preview.vue,
keeping the import block contiguous and then declare const { t } = useI18n()
(referencing useI18n and t) below the imports to conform with project import
ordering.
src/render/components/Podman/compose-build/Redis.vue (1)

20-22: Consider grouping imports before variable declarations.

The const { t } = useI18n() declaration (line 21) is placed between import statements. For better readability and consistency, group all imports together before any variable declarations.

♻️ Suggested reordering
  import { ComposeBuildForm } from '@/components/Podman/compose-build/Form'
  import { useI18n } from 'vue-i18n'
- const { t } = useI18n()
  import { OfficialImages } from '@/components/Podman/officialImages'
  import BaseVM from '@/components/Podman/compose-build/components/base.vue'
  import PreviewVM from '@/components/Podman/compose-build/components/preview.vue'
+
+ const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/Redis.vue` around lines 20 - 22,
In Redis.vue the variable destructuring const { t } = useI18n() is placed
between import statements (useI18n and OfficialImages); move that declaration so
all imports (including useI18n and OfficialImages) are grouped at the top of the
file, then immediately after the import block add const { t } = useI18n() to
keep imports and variable declarations separated for readability.
src/render/components/Nodejs/projects/dependencies/index.vue (1)

82-84: Consider grouping imports before variable declarations.

The const { t } = useI18n() is placed between import statements.

♻️ Suggested reordering
  import { useI18n } from 'vue-i18n'
- const { t } = useI18n()
  import { join } from '@/util/path-browserify'
  import { shell, fs } from '@/util/NodeFn'
  import { asyncComputed } from '@vueuse/core'
+
+ const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Nodejs/projects/dependencies/index.vue` around lines 82
- 84, Move the variable declaration splitting imports so all imports are grouped
at the top: relocate the const { t } = useI18n() line below the import
statements (after import { useI18n } from 'vue-i18n' and import { join } from
'@/util/path-browserify') so imports (useI18n, join) are contiguous and then
initialize t from useI18n() to keep module imports before runtime variable
declarations.
src/render/components/Ollama/models/local/index.vue (1)

25-28: Consider grouping imports before variable declarations.

Same pattern as other files in this PR: the const { t } = useI18n() declaration is placed between import statements. Group all imports together before variable declarations for consistency.

♻️ Suggested reordering
  import { useI18n } from 'vue-i18n'
-
- const { t } = useI18n()
  import { Setup } from './setup'
+
+ const { t } = useI18n()

  const { fetching, tableData } = Setup()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Ollama/models/local/index.vue` around lines 25 - 28,
The file places the call to useI18n (const { t } = useI18n()) between import
statements; move all imports (including "import { useI18n } from 'vue-i18n'" and
"import { Setup } from './setup'") together at the top, then declare const { t }
= useI18n() afterwards so imports are grouped consistently (look for useI18n and
the const { t } = useI18n() occurrence to relocate).
src/render/components/Podman/compose/composeAdd.vue (1)

129-130: Keep validation messages reactive to language changes.

Line 130 initializes translated text once inside rules. After a locale switch, form validation may keep the old language until component reload.

♻️ Proposed fix
- import { ref } from 'vue'
+ import { computed, ref } from 'vue'
@@
- const rules = ref<FormRules>({
+ const rules = computed<FormRules>(() => ({
     name: [{ required: true, message: t('base.name') + t('podman.require'), trigger: 'blur' }],
@@
-  })
+  }))

Also applies to: 144-150

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose/composeAdd.vue` around lines 129 - 130,
The rules object initializes translated messages once, so locale changes don't
update validation text; change rules from a static ref to a reactive/computed
structure that calls the i18n translator (t) on access or use function-based
validators that call t at runtime (e.g., convert const rules =
ref<FormRules>({...}) into a computed/ref that recomputes messages using
t('...') or replace message strings with validator callbacks that create
Error(t('...'))), and update the same pattern where rules are defined (the rules
symbol in this file and the similar definitions around lines 144-150) so
validation messages are evaluated after locale switches.
src/render/components/Nodejs/fnm/index.vue (1)

69-70: Make table column titles reactive to locale switching.

Lines 118, 159, and 183 call t(...) while creating a static array; those header labels stay fixed if language changes at runtime.

♻️ Proposed fix
+import { computed } from 'vue'
 import { useI18n } from 'vue-i18n'
@@
-const columns: Column<any>[] = [
+const columns = computed<Column<any>[]>(() => [
   // ...same column definitions...
-]
+])

Also applies to: 118-118, 159-159, 183-183

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Nodejs/fnm/index.vue` around lines 69 - 70, The table
column titles are being set once using t(...) when the static const columns:
Column<any>[] is created, so they won't update on locale changes; change the
static columns into a reactive/computed value or factory function that calls the
i18n t() at runtime (e.g. replace the const columns with a computed(() => [ ...
]) or a getColumns() function) and use that reactive/computed reference wherever
columns is used so the header titles (the places where t(...) is currently
called inside the columns array) re-evaluate on locale switch.
src/render/components/Perl/Index.vue (1)

37-38: Make tab labels reactive to locale changes.

Line 42 currently evaluates translations once during setup. If the user switches language at runtime, these tab labels will not update.

♻️ Proposed fix
+import { computed } from 'vue'
 import { AppModuleSetup } from '@/core/Module'
 import { useI18n } from 'vue-i18n'
 const { t } = useI18n()
@@
 const { tab } = AppModuleSetup('perl')
-const tabs = [t('base.service'), t('base.versionManager'), t('host.projectPerl')]
+const tabs = computed(() => [t('base.service'), t('base.versionManager'), t('host.projectPerl')])

Also applies to: 42-42

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Perl/Index.vue` around lines 37 - 38, The tab labels
are currently created once using useI18n's t() during setup and so won't update
on locale change; make the labels reactive by wrapping each t(...) call in a
computed (or build the entire tabs array inside a computed) so that components
like t and the tabs array recompute when the locale changes—update the code that
defines the tabs (the variable/const where tab labels are created) to use
computed(() => t('...')) or computed(() => [{ label: t('...'), ... }, ...]) so
label text updates automatically when useI18n's locale changes.
src/render/components/Mysql/Group/Add.vue (1)

68-71: Move const declaration after all imports.

The const { t } = useI18n() is placed between import statements with an extra blank line. Group all imports together first for consistency.

🔧 Suggested fix
 import { computed, ref, watch } from 'vue'
 import { AsyncComponentSetup } from '@/util/AsyncComponent'
 import { useI18n } from 'vue-i18n'
-
-const { t } = useI18n()
 import { uuid } from '@/util/Index'
 import { BrewStore } from '@/store/brew'
 import { MessageSuccess } from '@/util/Element'
 import type { MysqlGroupItem } from '@shared/app'
 import { MysqlStore } from '../mysql'
 import { join } from '@/util/path-browserify'
 import { dialog } from '@/util/NodeFn'
+
+const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Mysql/Group/Add.vue` around lines 68 - 71, Move the
runtime destructuring const { t } = useI18n() so that all import statements are
grouped together first; specifically, place the const { t } = useI18n() after
the import lines (including import { useI18n } from 'vue-i18n' and import { uuid
} from '@/util/Index') and remove the extra blank line so imports remain
contiguous and the useI18n call occurs after imports.
src/render/components/Podman/compose-build/Ruby.vue (1)

18-20: Move const declaration after all imports.

The const { t } = useI18n() statement is placed between import statements, breaking the conventional separation between imports and code. Consider grouping all imports together first.

🔧 Suggested fix
 import { computed } from 'vue'
 import { ComposeBuildForm } from '@/components/Podman/compose-build/Form'
 import { useI18n } from 'vue-i18n'
-const { t } = useI18n()
 import { OfficialImages } from '@/components/Podman/officialImages'
 import BaseVM from '@/components/Podman/compose-build/components/base.vue'
 import PreviewVM from '@/components/Podman/compose-build/components/preview.vue'
 import WwwRoot from '@/components/Podman/compose-build/components/wwwRoot.vue'
+
+const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/Ruby.vue` around lines 18 - 20,
Move the const declaration out of the import block: keep all import statements
together (including import { useI18n } from 'vue-i18n' and import {
OfficialImages } from '@/components/Podman/officialImages') and then place const
{ t } = useI18n() immediately after the imports; update the Ruby.vue file so
useI18n is imported first and the const { t } = useI18n() call occurs below the
import list.
src/render/components/Podman/compose-build/Elasticsearch.vue (1)

16-17: Move const declaration after all imports.

Same as other components in this PR – the const { t } = useI18n() statement is placed between import statements. Group all imports together, then add declarations.

🔧 Suggested fix
 import { computed } from 'vue'
 import { ComposeBuildForm } from '@/components/Podman/compose-build/Form'
 import { useI18n } from 'vue-i18n'
-const { t } = useI18n()
 import { OfficialImages } from '@/components/Podman/officialImages'
 import BaseVM from '@/components/Podman/compose-build/components/base.vue'
 import PreviewVM from '@/components/Podman/compose-build/components/preview.vue'
+
+const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/Elasticsearch.vue` around lines 16
- 17, Move the const declaration out of the import block: keep all import
statements (including import { useI18n } from 'vue-i18n') grouped at the top,
then add the declaration const { t } = useI18n() below the imports (e.g., after
the last import or at the start of the script setup). Update the
Elasticsearch.vue file so useI18n is only imported in the import section and
const { t } = useI18n() appears afterward to match the other components'
ordering.
src/render/components/Podman/compose-build/PostgreSQL.vue (1)

31-32: Move const declaration after all imports.

Same pattern as other components – group all imports together first.

🔧 Suggested fix
 import { computed } from 'vue'
 import { ComposeBuildForm } from '@/components/Podman/compose-build/Form'
 import { useI18n } from 'vue-i18n'
-const { t } = useI18n()
 import { OfficialImages } from '@/components/Podman/officialImages'
 import BaseVM from '@/components/Podman/compose-build/components/base.vue'
 import PreviewVM from '@/components/Podman/compose-build/components/preview.vue'
+
+const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/compose-build/PostgreSQL.vue` around lines 31 -
32, The const declaration for t is placed immediately after a single import;
move "const { t } = useI18n()" so that all import statements remain grouped at
the top and then add the const declaration below the import block (e.g., keep
the import { useI18n } from 'vue-i18n' with other imports, then place const { t
} = useI18n() after the imports), ensuring useI18n and t usage in the component
remains unchanged.
src/render/components/PHP/Extension/Macports/index.vue (1)

94-96: Move const declaration after all imports.

Consistent with the pattern across this PR, move const { t } = useI18n() after all import statements.

🔧 Suggested fix
 import { type SoftInstalled } from '@/store/brew'
 import { MacPortsSetup, Setup } from './setup'
 import { useI18n } from 'vue-i18n'
-const { t } = useI18n()
 import { Link, Document, Download, Delete } from '@element-plus/icons-vue'
+
+const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/PHP/Extension/Macports/index.vue` around lines 94 - 96,
The const declaration const { t } = useI18n() is placed before other imports;
move the call to useI18n so that const { t } = useI18n() appears after all
import statements (e.g., after import { Link, Document, Download, Delete } from
'@element-plus/icons-vue') to follow the project's import-first ordering and
keep the useI18n invocation below all imports.
src/render/components/Mysql/Manage/setPassword.vue (1)

49-52: Move const declaration after all imports.

The const { t } = useI18n() is placed between import statements with an extra blank line. Group all imports together for consistency.

🔧 Suggested fix
 import { computed, reactive, ref } from 'vue'
 import { AsyncComponentSetup } from '@/util/AsyncComponent'
 import { useI18n } from 'vue-i18n'
-
-const { t } = useI18n()
 import type { ModuleInstalledItem } from '@/core/Module/ModuleInstalledItem'
 import { MySQLManage } from './manage'
 import { uuid } from '@/util/Index'
 import { Refresh } from '@element-plus/icons-vue'
 import { ElMessageBox } from 'element-plus'
 import { BrewStore } from '@/store/brew'
 import { MessageSuccess } from '@/util/Element'
+
+const { t } = useI18n()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Mysql/Manage/setPassword.vue` around lines 49 - 52,
Move the top-level const extraction "const { t } = useI18n()" so it appears
after all import statements (keep all imports grouped together), e.g., place it
after the last import that references ModuleInstalledItem; ensure useI18n is
still imported and the symbol t is declared only once and not interleaving
import lines.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2691f65 and e40e116.

📒 Files selected for processing (104)
  • src/lang/en/host.json
  • src/lang/es/host.json
  • src/lang/fi/host.json
  • src/lang/fr/host.json
  • src/lang/id/host.json
  • src/lang/index.ts
  • src/lang/it/host.json
  • src/lang/ja/host.json
  • src/lang/nl/host.json
  • src/lang/no/host.json
  • src/lang/pl/host.json
  • src/lang/pt-br/host.json
  • src/lang/pt/host.json
  • src/lang/ro/host.json
  • src/lang/ru/host.json
  • src/lang/sv/host.json
  • src/lang/tr/host.json
  • src/lang/uk/host.json
  • src/lang/vi/host.json
  • src/lang/zh/host.json
  • src/render/App.vue
  • src/render/components/Conf/drawer.vue
  • src/render/components/Deno/Index.vue
  • src/render/components/Erlang/Index.vue
  • src/render/components/Mysql/Config.vue
  • src/render/components/Mysql/Group/Add.vue
  • src/render/components/Mysql/Group/Config.vue
  • src/render/components/Mysql/Group/Index.vue
  • src/render/components/Mysql/Group/Logs.vue
  • src/render/components/Mysql/Group/SetupPopper.vue
  • src/render/components/Mysql/Index.vue
  • src/render/components/Mysql/Manage/addDatabase.vue
  • src/render/components/Mysql/Manage/database.vue
  • src/render/components/Mysql/Manage/index.vue
  • src/render/components/Mysql/Manage/setBackupDir.vue
  • src/render/components/Mysql/Manage/setPassword.vue
  • src/render/components/Nginx/Config.vue
  • src/render/components/Nginx/Index.vue
  • src/render/components/Nodejs/Config.vue
  • src/render/components/Nodejs/Index.vue
  • src/render/components/Nodejs/List.vue
  • src/render/components/Nodejs/default/index.vue
  • src/render/components/Nodejs/fnm/index.vue
  • src/render/components/Nodejs/nvm/index.vue
  • src/render/components/Nodejs/projects/dependencies/index.vue
  • src/render/components/Ollama/Index.vue
  • src/render/components/Ollama/models/all/index.vue
  • src/render/components/Ollama/models/index.vue
  • src/render/components/Ollama/models/local/index.vue
  • src/render/components/PHP/Config.vue
  • src/render/components/PHP/DisableFunction.vue
  • src/render/components/PHP/ErrorLog.vue
  • src/render/components/PHP/Extends.vue
  • src/render/components/PHP/Extension/Homebrew/index.vue
  • src/render/components/PHP/Extension/Lib/index.vue
  • src/render/components/PHP/Extension/Loaded/index.vue
  • src/render/components/PHP/Extension/Local/index.vue
  • src/render/components/PHP/Extension/Macports/index.vue
  • src/render/components/PHP/List.vue
  • src/render/components/PHP/Logs.vue
  • src/render/components/PHP/aside.vue
  • src/render/components/Perl/Index.vue
  • src/render/components/Podman/Index.vue
  • src/render/components/Podman/compose-build/Base.vue
  • src/render/components/Podman/compose-build/Bun.vue
  • src/render/components/Podman/compose-build/Consul.vue
  • src/render/components/Podman/compose-build/Deno.vue
  • src/render/components/Podman/compose-build/Elasticsearch.vue
  • src/render/components/Podman/compose-build/Erlang.vue
  • src/render/components/Podman/compose-build/Etcd.vue
  • src/render/components/Podman/compose-build/Go.vue
  • src/render/components/Podman/compose-build/Java.vue
  • src/render/components/Podman/compose-build/MariaDB.vue
  • src/render/components/Podman/compose-build/Meilisearch.vue
  • src/render/components/Podman/compose-build/MinIO.vue
  • src/render/components/Podman/compose-build/MongoDB.vue
  • src/render/components/Podman/compose-build/MySQL.vue
  • src/render/components/Podman/compose-build/NodeJS.vue
  • src/render/components/Podman/compose-build/Perl.vue
  • src/render/components/Podman/compose-build/PostgreSQL.vue
  • src/render/components/Podman/compose-build/Python.vue
  • src/render/components/Podman/compose-build/RabbitMQ.vue
  • src/render/components/Podman/compose-build/Redis.vue
  • src/render/components/Podman/compose-build/Ruby.vue
  • src/render/components/Podman/compose-build/Rust.vue
  • src/render/components/Podman/compose-build/components/base.vue
  • src/render/components/Podman/compose-build/components/docRoot.vue
  • src/render/components/Podman/compose-build/components/preview.vue
  • src/render/components/Podman/compose-build/components/wwwRoot.vue
  • src/render/components/Podman/compose/compose.vue
  • src/render/components/Podman/compose/composeAdd.vue
  • src/render/components/Podman/compose/composeBuild.vue
  • src/render/components/Podman/container/container.vue
  • src/render/components/Podman/container/containerCreate.vue
  • src/render/components/Podman/container/info.vue
  • src/render/components/Podman/container/preview.vue
  • src/render/components/Podman/dashboard.vue
  • src/render/components/Podman/image/image.vue
  • src/render/components/Podman/image/imageAdd.vue
  • src/render/components/Podman/left.vue
  • src/render/components/Podman/machine/machineAdd.vue
  • src/render/components/Podman/right.vue
  • src/render/components/PostgreSql/Index.vue
  • src/render/tray/App.vue
💤 Files with no reviewable changes (1)
  • src/lang/index.ts

Comment on lines +42 to 45
import { useI18n } from 'vue-i18n'

const { t } = useI18n()
import type { MysqlGroupItem } from '@shared/app'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Incomplete migration: t is declared but never used.

The t function from useI18n() is imported but not utilized. Meanwhile, I18nT(...) is still called throughout the file (lines 80, 117, 128, 140, 156, 209). Complete the migration by replacing all I18nT(...) calls with t(...).

Additionally, the import on line 45 should be moved above the const { t } = useI18n() statement to keep all imports grouped at the top.

🔧 Proposed fix
 import { computed } from 'vue'
 import { MysqlStore } from '../mysql'
 import type { Column } from 'element-plus'
 import { useI18n } from 'vue-i18n'
-
-const { t } = useI18n()
 import type { MysqlGroupItem } from '@shared/app'
 import { AsyncComponentShow } from '@/util/AsyncComponent'
 import { MessageError, MessageSuccess } from '@/util/Element'
 import Popper from './SetupPopper.vue'
 import { shell } from '@/util/NodeFn'

+const { t } = useI18n()
+
 const mysqlStore = MysqlStore()

Then replace I18nT(...) calls with t(...):

 const handleRes = (res: true | string) => {
   if (res === true) {
-    MessageSuccess(I18nT('base.success'))
+    MessageSuccess(t('base.success'))
   } else {

Apply similar changes to lines 117, 128, 140, 156, and 209.

🧰 Tools
🪛 ESLint

[error] 44-44: 't' is assigned a value but never used. Allowed unused vars must match /^[hH]$/u.

(@typescript-eslint/no-unused-vars)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Mysql/Group/Index.vue` around lines 42 - 45, Move the
import "import type { MysqlGroupItem } from '@shared/app'" above the const { t }
= useI18n() so all imports are grouped, then remove all uses of the legacy
I18nT(...) and replace them with t(...) calls (search for I18nT at places around
the current I18nT usages near lines where messages are built). Ensure you keep
the existing argument(s) passed to I18nT and pass them unchanged to t, and keep
useI18n() as the source of t; verify no unused t warnings remain.

Comment on lines 88 to 95
const tabs = [
I18nT('base.service'),
I18nT('base.versionManager'),
I18nT('base.configFile'),
I18nT('base.log'),
I18nT('base.slowLog'),
I18nT('base.group')
t('base.service'),
t('base.versionManager'),
t('base.configFile'),
t('base.log'),
t('base.slowLog'),
t('base.group')
]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

find . -name "package.json" -type f | head -5

Repository: TanNhatCMS/FlyEnv

Length of output: 380


🏁 Script executed:

git ls-files | grep -E "(i18n|vuerc|tsconfig)" | head -20

Repository: TanNhatCMS/FlyEnv

Length of output: 74


🌐 Web query:

vue-i18n v9 composition api locale change reactivity computed

💡 Result:

In vue-i18n v9 (Composition API mode) the locale is a Vue ref, so locale switching (and anything computed that depends on translations) is only reactive if you update/read it as a ref.

Correct reactive pattern (Composition API)

import { useI18n } from 'vue-i18n'
import { computed } from 'vue'

const { t, locale } = useI18n({ useScope: 'global' })

function setLocale(l: string) {
  locale.value = l
}

const title = computed(() => t('page.title')) // re-computes when locale changes

Changing locale.value will update all t() usages reactively. [1]

Common mistakes

  • Using $t.locale: $t is the translate function, not the i18n/composer instance, so changing $t.locale won’t work. Use $i18n.locale (template) or useI18n() (script). [3]
  • Forgetting .value when changing locale via the global composer:
    i18n.global.locale.value = 'en'
    not i18n.global.locale = 'en'. [4]

Template-side locale switching

<select v-model="$i18n.locale">
  <option value="en">en</option>
  <option value="ja">ja</option>
</select>

This is the documented reactive way (global scope). [1]

Sources: [1] Vue I18n docs (Composition API / Locale Changing), [3] Vue subreddit discussion, [4] Stack Overflow (locale is a ref)


🏁 Script executed:

cat package.json | grep -A 5 -B 5 "vue-i18n"

Repository: TanNhatCMS/FlyEnv

Length of output: 324


🏁 Script executed:

find . -name "*.ts" -o -name "*.js" | xargs grep -l "createI18n\|useI18n" | head -5

Repository: TanNhatCMS/FlyEnv

Length of output: 5515


🏁 Script executed:

cat src/render/components/Mysql/Index.vue | head -150

Repository: TanNhatCMS/FlyEnv

Length of output: 13065


🏁 Script executed:

rg -i "locale.*=|setLocale|i18n.global.locale" --type vue --type ts --type js -A 3 -B 1 | head -100

Repository: TanNhatCMS/FlyEnv

Length of output: 88


🏁 Script executed:

rg "computed\s*\(\s*\(\)\s*=>" src/render/components/ --type vue -A 2 | grep -E "(tabs|label|title)" | head -20

Repository: TanNhatCMS/FlyEnv

Length of output: 88


🏁 Script executed:

rg "locale\s*=|setLocale" --type-add 'vue:*.vue' -t vue -t ts -t js -A 2 -B 1 | head -80

Repository: TanNhatCMS/FlyEnv

Length of output: 2263


🏁 Script executed:

rg "computed\s*\(\s*\(\)\s*=>\s*\[" -A 3 | head -50

Repository: TanNhatCMS/FlyEnv

Length of output: 43


Wrap tabs array in computed() for locale-reactive labels.

The tabs array snapshots translated strings at initialization. Since locale switching is implemented elsewhere in the app (src/lang/index.ts), runtime locale changes won't update these labels until the component remounts. Wrap the array in computed() so the translations re-evaluate reactively when locale changes.

Proposed fix
-  const tabs = [
-    t('base.service'),
-    t('base.versionManager'),
-    t('base.configFile'),
-    t('base.log'),
-    t('base.slowLog'),
-    t('base.group')
-  ]
+  const tabs = computed(() => [
+    t('base.service'),
+    t('base.versionManager'),
+    t('base.configFile'),
+    t('base.log'),
+    t('base.slowLog'),
+    t('base.group')
+  ])
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const tabs = [
I18nT('base.service'),
I18nT('base.versionManager'),
I18nT('base.configFile'),
I18nT('base.log'),
I18nT('base.slowLog'),
I18nT('base.group')
t('base.service'),
t('base.versionManager'),
t('base.configFile'),
t('base.log'),
t('base.slowLog'),
t('base.group')
]
const tabs = computed(() => [
t('base.service'),
t('base.versionManager'),
t('base.configFile'),
t('base.log'),
t('base.slowLog'),
t('base.group')
])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Mysql/Index.vue` around lines 88 - 95, The tabs array
currently captures translated strings once; make it reactive by replacing the
plain tabs array with a computed property: wrap the array in computed(() =>
[t('base.service'), t('base.versionManager'), ...]) so translations re-evaluate
on locale change, and ensure computed is imported from 'vue'; keep using the ref
in templates (auto-unwrapped) but if referenced in script logic use tabs.value.

Comment on lines 34 to 40
const tabs = [
I18nT('base.service'),
I18nT('base.versionManager'),
I18nT('base.configFile'),
I18nT('base.errorLog'),
I18nT('base.log')
t('base.service'),
t('base.versionManager'),
t('base.configFile'),
t('base.errorLog'),
t('base.log')
]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

vue-i18n v9 Composition API t() function automatic locale change reactivity computed

💡 Result:

In vue-i18n v9 (Composition API), the translation result updates automatically on locale change only if t() is executed inside a reactive context (template render, computed, watchEffect, etc.). If you call t() once and store the returned string (e.g., in a plain variable/ref initialized once), it won’t update when locale changes—because the string has no reactive dependency tracking. Vue I18n explicitly notes that changing the global locale makes dependent translations work reactively (when used in reactive contexts). [1]

Correct pattern (reactive)

<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'

const { t, locale } = useI18n({ useScope: 'global' })

const title = computed(() => t('page.title')) // updates when locale.value changes

function setLang(lang: string) {
  locale.value = lang
}
</script>

What won’t be reactive

const title = t('page.title') // evaluated once; won't change with locale

If you’re generating lists/objects of labels

Make the whole structure computed:

const columns = computed(() => ([
  { key: 'name', label: t('table.name') },
  { key: 'email', label: t('table.email') },
]))

Related API note

Vue I18n’s Composition API also documents that translations (e.g., via resolver-style translation helpers) re-evaluate when locale changes if used in a reactive context—same principle as using t() inside computed/render. [2]

Sources: Vue I18n Composition API guide on reactive locale switching [1], Vue I18n Composition API reference note about re-evaluation on locale change in reactive contexts [2], common Vue-i18n advice to use computed rather than data for reactive translations [3].

References
[1] Vue I18n docs – Composition API / Locale Changing (reactivity on locale change): turn0search0
[2] Vue I18n docs – Composition API reference (reactive context re-evaluates on locale change): turn0search2
[3] Stack Overflow – translations in data not reactive; use computed: turn0search1


🏁 Script executed:

find . -name "Index.vue" -path "*/Nginx/*" | head -5

Repository: TanNhatCMS/FlyEnv

Length of output: 100


🏁 Script executed:

cat -n ./src/render/components/Nginx/Index.vue | head -80

Repository: TanNhatCMS/FlyEnv

Length of output: 1640


Make tab labels reactive to locale changes.

The tabs array is created once with t() calls at initialization. When users switch language at runtime, the tab labels won't update because the array is not in a reactive context. The template at line 4 iterates over tabs in a v-for, so stale translations will persist even after locale changes.

Wrap tabs in computed() to ensure translation calls re-evaluate when the locale changes:

Suggested fix
+ import { computed } from 'vue'
  import { useI18n } from 'vue-i18n'

  const { t } = useI18n()
  const { tab, checkVersion } = AppModuleSetup('nginx')
- const tabs = [
-   t('base.service'),
-   t('base.versionManager'),
-   t('base.configFile'),
-   t('base.errorLog'),
-   t('base.log')
- ]
+ const tabs = computed(() => [
+   t('base.service'),
+   t('base.versionManager'),
+   t('base.configFile'),
+   t('base.errorLog'),
+   t('base.log')
+ ])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Nginx/Index.vue` around lines 34 - 40, The tab labels
are created once with t() and stale after locale changes; replace the top-level
const tabs = [...] with a reactive computed wrapper: const tabs = computed(() =>
[t('base.service'), t('base.versionManager'), t('base.configFile'),
t('base.errorLog'), t('base.log')]) and import computed from 'vue' if missing;
the template v-for can continue using tabs (templates auto-unwrap refs) so
translations re-evaluate when the locale changes.

Comment on lines 36 to 42
const tabs = [
I18nT('base.service'),
I18nT('base.versionManager'),
I18nT('ollama.model'),
I18nT('base.configFile'),
I18nT('base.log')
t('base.service'),
t('base.versionManager'),
t('ollama.model'),
t('base.configFile'),
t('base.log')
]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

fd "Index.vue" | grep -i ollama

Repository: TanNhatCMS/FlyEnv

Length of output: 99


🏁 Script executed:

cat -n src/render/components/Ollama/Index.vue | head -60

Repository: TanNhatCMS/FlyEnv

Length of output: 1699


🌐 Web query:

vue-i18n composition api t() function reactive locale change setup

💡 Result:

In Vue I18n (v9+) Composition API, t is reactive only when it’s evaluated in a reactive context (template, computed, etc.). If you do const label = t('key') in setup(), that string won’t update when the locale changes—wrap it instead. (vue-i18n.intlify.dev)

<script setup>
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'

const { t, locale } = useI18n({ useScope: 'global' }) // or omit options for global by default
const label = computed(() => t('message.hello'))      // reactive on locale changes

function setEn() {
  locale.value = 'en' // locale is a ref in composition mode
}
</script>

<template>
  <p>{{ label }}</p>
  <button `@click`="setEn">EN</button>
</template>

Notes:

  • To switch the whole app, change the global composer locale: const { locale } = useI18n({ useScope: 'global' }); locale.value = 'en'. (vue-i18n.intlify.dev)
  • Call useI18n() once per component and destructure everything from that single call (multiple local-scope calls can break reactivity). (vue-i18n.intlify.dev)

Citations:


Wrap translated tab labels in computed for locale-switch updates.

Current tabs values are captured once during setup and won't react to language changes at runtime. Per vue-i18n's Composition API, t() is reactive only when evaluated in a reactive context like computed. Direct calls in setup-scope arrays are evaluated once and cached.

♻️ Proposed fix
-  const tabs = [
-    t('base.service'),
-    t('base.versionManager'),
-    t('ollama.model'),
-    t('base.configFile'),
-    t('base.log')
-  ]
+  const tabs = computed(() => [
+    t('base.service'),
+    t('base.versionManager'),
+    t('ollama.model'),
+    t('base.configFile'),
+    t('base.log')
+  ])
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const tabs = [
I18nT('base.service'),
I18nT('base.versionManager'),
I18nT('ollama.model'),
I18nT('base.configFile'),
I18nT('base.log')
t('base.service'),
t('base.versionManager'),
t('ollama.model'),
t('base.configFile'),
t('base.log')
]
const tabs = computed(() => [
t('base.service'),
t('base.versionManager'),
t('ollama.model'),
t('base.configFile'),
t('base.log')
])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Ollama/Index.vue` around lines 36 - 42, The tab labels
are captured once because tabs is a plain array using t() in setup; change tabs
into a Vue computed so t() is evaluated reactively on locale change: replace the
const tabs = [...] assignment with a computed that returns the array of
t('base.service'), t('base.versionManager'), t('ollama.model'),
t('base.configFile'), t('base.log') and update any template/consumers to use the
computed (tabs.value or destructured) so the labels update when locale changes.

Comment on lines +120 to +121
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find i18n initialization files
echo "=== Looking for i18n initialization files ==="
fd -e ts -e js -e mjs | xargs rg -l 'createI18n' 2>/dev/null | head -20

echo -e "\n=== Checking src/lang/index.ts if it exists ==="
if [ -f src/lang/index.ts ]; then
  echo "File found. Content:"
  cat -n src/lang/index.ts
else
  echo "File not found"
fi

echo -e "\n=== Searching for createI18n in entire repo ==="
rg -n 'createI18n\(' --type ts --type js -A 10 2>/dev/null | head -100

Repository: TanNhatCMS/FlyEnv

Length of output: 7455


Composition API mode is not enabled in i18n configuration.

The component uses useI18n() (Composition API) on lines 120-121, but src/lang/index.ts initializes createI18n without legacy: false. This will cause a runtime error because useI18n() requires Composition API mode.

Fix required in src/lang/index.ts
i18n = createI18n({
+ legacy: false,
  locale: l || 'en',
  fallbackLocale: 'en',
  messages: lang as any
})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/PHP/Extends.vue` around lines 120 - 121, The component
uses useI18n() (Composition API) but createI18n was initialized in legacy mode;
update the i18n initialization in src/lang/index.ts by enabling Composition API
mode (pass legacy: false into createI18n configuration) so useI18n() works at
runtime; locate the createI18n(...) call (and any exported i18n instance) and
add legacy: false alongside the existing locale/messages/options.

Comment on lines 50 to 52
{{
containerDetail.IsInfra ? I18nT('podman.common.yes') : I18nT('podman.common.no')
containerDetail.IsInfra ? t('podman.common.yes') : t('podman.common.no')
}}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Resolve Prettier violations in multiline ternaries.

Static analysis flags these ranges as formatting errors; this will likely fail lint gates. Please run formatter or inline the ternaries as suggested by the linter output.

Also applies to: 66-70, 75-79, 85-87, 94-96, 102-106

🧰 Tools
🪛 ESLint

[error] 50-52: Replace ⏎··················containerDetail.IsInfra·?·t('podman.common.yes')·:·t('podman.common.no')⏎··············· with ·containerDetail.IsInfra·?·t('podman.common.yes')·:·t('podman.common.no')

(prettier/prettier)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/container/info.vue` around lines 50 - 52, The
multiline ternary expressions in src/render/components/Podman/container/info.vue
(e.g., the expression using containerDetail.IsInfra) are causing Prettier lint
failures; change each multiline ternary to either a single-line ternary (e.g.,
containerDetail.IsInfra ? t('podman.common.yes') : t('podman.common.no')) or
refactor into a computed property or small helper method (e.g.,
computed/isInfraLabel) that returns t('podman.common.yes') or
t('podman.common.no'), and replace the multiline blocks at the indicated ranges
(50-52, 66-70, 75-79, 85-87, 94-96, 102-106) with the single-line expression or
the computed property to satisfy Prettier.

Comment on lines 54 to 56
<el-button type="primary" @click.stop="taskConfirm">{{
I18nT('base.confirm')
taskConfirm('base.confirm')
}}</el-button>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: render-time side effect on confirm button label.

Line 55 calls taskConfirm(...) while rendering, which triggers install/reset logic immediately and renders an empty/undefined label. This should be a translation lookup instead.

Suggested fix
             <template v-if="PodmanManager.installEnd">
               <el-button type="primary" `@click.stop`="taskConfirm">{{
-                taskConfirm('base.confirm')
+                t('base.confirm')
               }}</el-button>
             </template>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<el-button type="primary" @click.stop="taskConfirm">{{
I18nT('base.confirm')
taskConfirm('base.confirm')
}}</el-button>
<el-button type="primary" `@click.stop`="taskConfirm">{{
t('base.confirm')
}}</el-button>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/Index.vue` around lines 54 - 56, The template is
calling taskConfirm('base.confirm') during render which causes side effects and
an empty label; stop invoking the action in interpolation—use a pure label
lookup instead and keep taskConfirm as the click handler. Replace the
interpolation {{ taskConfirm('base.confirm') }} with a translation lookup (e.g.
$t('base.confirm')) or a pure computed/property like taskConfirmLabel, and
ensure the button remains <el-button `@click.stop`="taskConfirm"> so the
taskConfirm method (the action with install/reset logic) is only executed on
click.

Comment on lines +37 to 41
<el-form-item v-if="!isEdit" :label="t('podman.identityPath')" prop="identityPath">
<el-input v-model="form.identityPath" placeholder="~/.ssh/id_rsa" />
</el-form-item>
<el-form-item v-if="!isEdit" :label="I18nT('podman.remoteUsername')" prop="remoteUsername">
<el-form-item v-if="!isEdit" :label="t('podman.remoteUsername')" prop="remoteUsername">
<el-input v-model="form.remoteUsername" placeholder="user" />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Localize field placeholders for consistency.

Lines 38 and 41 placeholders are still hardcoded English (~/.ssh/id_rsa, user) while labels are translated. Consider moving placeholders to i18n keys for consistent multilingual UX.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/Podman/machine/machineAdd.vue` around lines 37 - 41,
The input placeholders for the identity path and remote username are hardcoded;
replace the literal placeholders "~/.ssh/id_rsa" and "user" in the template (the
<el-input> bound to form.identityPath and the <el-input> bound to
form.remoteUsername in machineAdd.vue) with translated i18n keys (e.g.
t('podman.identityPlaceholder') and t('podman.remoteUsernamePlaceholder')), and
add the corresponding keys to the locale files so placeholders are localized
consistently with the labels.

<template #tool-left>
<div class="flex items-center gap-1 pl-4 pr-2">
<span class="flex-shrink-0">{{ I18nT('util.mysqlDataDir') }}: </span>
<span class="flex-shrink-0">{{ t('util.mysqlDataDir') }}: </span>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Translation key util.mysqlDataDir used in PostgreSQL component.

Using a MySQL-named translation key in a PostgreSQL component is confusing. Consider adding a generic or PostgreSQL-specific translation key (e.g., util.dataDir or util.postgresqlDataDir) for clarity and maintainability.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/PostgreSql/Index.vue` at line 12, The translation key
used in the PostgreSQL component is misnamed: replace the call to
t('util.mysqlDataDir') inside the Index.vue template with a clearer key such as
t('util.dataDir') or t('util.postgresqlDataDir'); then add the corresponding
entries to the i18n translation files (for all locales) so the new key is
defined. Update any references to the old 'util.mysqlDataDir' key (search for
t('util.mysqlDataDir') or similar) and remove it if no longer used to keep
translations consistent.

import { shell } from '@/util/NodeFn'

const { t } = useI18n()
const { tab, checkVersion } = AppModuleSetup('nginx')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Wrong module type passed to AppModuleSetup.

This is a PostgreSQL component, but AppModuleSetup('nginx') passes 'nginx' as the type flag. The Service and Manager components correctly use type-flag="postgresql", so this should be consistent.

🐛 Proposed fix
-  const { tab, checkVersion } = AppModuleSetup('nginx')
+  const { tab, checkVersion } = AppModuleSetup('postgresql')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { tab, checkVersion } = AppModuleSetup('nginx')
const { tab, checkVersion } = AppModuleSetup('postgresql')
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/render/components/PostgreSql/Index.vue` at line 56, The component
incorrectly calls AppModuleSetup with the 'nginx' type flag; update the call
site where const { tab, checkVersion } = AppModuleSetup('nginx') to use the
'postgresql' type flag so it matches the Service/Manager type-flag="postgresql"
usage and ensures the correct module behavior for this PostgreSql component.

dependabot bot and others added 2 commits February 28, 2026 23:08
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 5.3.6 to 5.3.8.
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](NaturalIntelligence/fast-xml-parser@v5.3.6...v5.3.8)

---
updated-dependencies:
- dependency-name: fast-xml-parser
  dependency-version: 5.3.8
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
…d_yarn/fast-xml-parser-5.3.8' into update-lang
Comment on lines +98 to +101
const edit: any = props.item
for (const key in form.value) {
form.value[key] = edit?.[key] ?? ''
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The Vue form passes flat properties to the CloudflareTunnel class, but the class expects them within a dns array, causing all save operations to fail validation.
Severity: CRITICAL

Suggested Fix

In the form submission logic of add.vue and edit.vue, transform the flat form data into the expected structure before creating the CloudflareTunnel instance. Specifically, create an object with the form values and place it inside the dns array, like new CloudflareTunnel({ dns: [{ subdomain: form.value.subdomain, ... }] }). This ensures the data structure aligns with the backend's requirements.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: src/render/components/CloudflareTunnel/edit.vue#L98-L101

Potential issue: A data structure mismatch exists between the Vue forms and the
`CloudflareTunnel` class. The forms in `add.vue` and `edit.vue` collect individual
properties like `subdomain` and `zoneName` and pass them directly to the
`CloudflareTunnel` constructor. The constructor assigns these as flat properties, but
the backend logic, specifically in `CloudflareTunnel.start()`, expects these properties
to be nested within a `dns` array. Because the `dns` array is never populated and
remains empty, a validation check `if (!this.dns || this.dns.length === 0)` will always
throw an error, preventing any new Cloudflare Tunnels from being created or existing
ones from being saved.

let versions: SoftInstalled[] = []
let all: Promise<SoftInstalled[]>[] = []
if (isWindows()) {
all = [versionLocalFetch(setup?.caddy?.dirs ?? [], 'cloudflared.exe')]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The Cloudflared module incorrectly uses setup?.caddy?.dirs instead of setup?.cloudflared?.dirs to locate installed binaries, breaking custom path detection.
Severity: MEDIUM

Suggested Fix

In src/fork/module/Cloudflared/index.ts, replace the incorrect reference setup?.caddy?.dirs with the correct one, setup?.cloudflared?.dirs. This will ensure the module correctly reads its own configuration when scanning for binaries in custom installation directories.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: src/fork/module/Cloudflared/index.ts#L65

Potential issue: In the Cloudflared module, the logic for discovering installed versions
incorrectly references the configuration for the Caddy module. The code at
`src/fork/module/Cloudflared/index.ts` uses `setup?.caddy?.dirs` to find local binaries,
which is a copy-paste error. The correct path should be `setup?.cloudflared?.dirs` to
match the pattern used by all other modules. This bug prevents the application from
finding Cloudflared binaries installed in custom directories specified by the user in
their `cloudflared` configuration, as it will look in Caddy's custom directories
instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant