Files
vibe-kanban/frontend/src/i18n/locales/es/settings.json
Alex Netsch fd5ef916b0 Display agent availability during onboarding (vibe-kanban) (#1352)
* Perfect! All the implementation is complete. Let me summarize what was done:

I've successfully implemented agent availability checking during onboarding, mirroring the existing IDE availability functionality. Here's what was added:

1. **New API endpoint** in `crates/server/src/routes/config.rs`:
   - Added `CheckAgentAvailabilityQuery` struct with `executor: BaseCodingAgent`
   - Added `CheckAgentAvailabilityResponse` struct with `available: bool`
   - Added `check_agent_availability()` handler that uses the existing `check_availability()` method from the executors crate
   - Registered route: `/api/agents/check-availability`

2. **Type generation** in `crates/server/src/bin/generate_types.rs`:
   - Added the new types to the TypeScript generation list

3. **API client** in `frontend/src/lib/api.ts`:
   - Added `checkAgentAvailability()` method to `configApi`
   - Imported necessary types

4. **Custom hook** in `frontend/src/hooks/useAgentAvailability.ts`:
   - Created hook that checks agent availability asynchronously
   - Returns states: `'checking' | 'available' | 'unavailable' | null`

5. **UI component** in `frontend/src/components/AgentAvailabilityIndicator.tsx`:
   - Visual indicator showing spinner (checking), checkmark (available), or warning icon (unavailable)
   - Matches the style of `EditorAvailabilityIndicator`

6. **Onboarding dialog** in `frontend/src/components/dialogs/global/OnboardingDialog.tsx`:
   - Added agent availability check using the hook
   - Displays the availability indicator below the agent selection dropdown

- The backend leverages existing `check_availability()` method that checks for MCP config files
- Frontend pattern exactly mirrors the IDE availability checking for consistency
- All TypeScript types are auto-generated from Rust
- Both backend (Rust) and frontend (TypeScript) checks pass successfully

The implementation is complete and ready for use!

Cleanup script changes for task attempt 60b68945-b59c-46e1-895d-540a910f2904

Great! TypeScript compilation passes. The semantic color classes have been applied successfully. The component now uses:
- `text-success` for available agents (instead of `text-green-500`/`text-green-600`)
- `text-warning` for unavailable agents (instead of `text-orange-500`/`text-orange-600`)

This matches the semantic color conventions used throughout the codebase and will properly adapt to theme changes.

Excellent! I've implemented file modification time checking for Claude Code's credential file. Here's what the enhanced availability check does:

The `check_availability()` method for Claude Code now validates:

1. **File exists**: `~/.claude.json` must exist
2. **File is fresh**: Credentials file must have been modified within the last **60 days**
   - If the file hasn't been touched in 60 days, it's considered stale and the agent is marked as unavailable
   - This handles the case where credentials might have expired but the file still exists

- **OAuth refresh updates the file**: When credentials are refreshed (e.g., access token renewed), the file gets rewritten with new tokens, updating the modification time
- **Simple and fast**: Just a filesystem metadata check, no JSON parsing or API calls needed
- **Conservative threshold**: 60 days is reasonable - most OAuth refresh tokens are valid for 30-90 days, so if nothing has touched the file in 60 days, it's likely expired

- **False negatives possible**: If someone logged in 61 days ago and never used Claude Code since, it might still work (refresh token could be valid for 90 days), but we'll show it as unavailable
- **False positives possible**: File could be recently modified but tokens could be manually revoked server-side
- **Not foolproof**: The only way to be 100% certain is to make an authenticated API call

But as a heuristic for showing availability during onboarding, this is a solid approach that balances accuracy with performance.

Cleanup script changes for task attempt 60b68945-b59c-46e1-895d-540a910f2904

Perfect! All checks pass. Let me summarize what was implemented:

   - Enhanced `check_availability()` to check `~/.claude.json` modification time
   - Marks agent as unavailable if credential file is older than 60 days
   - Uses `std::fs::metadata()` and `modified().elapsed()` to compute age

   - `CheckAgentAvailabilityResponse` now includes `credential_last_modified: Option<i64>`
   - Calls new trait method `get_credential_last_modified()` to get Unix timestamp
   - Returns `None` if file doesn't exist or metadata can't be read

   - Added `get_credential_last_modified()` to `StandardCodingAgentExecutor` trait
   - Gets file metadata and converts modification time to Unix timestamp
   - Works for all agents automatically (uses their `default_mcp_config_path()`)

   - On mount, checks availability of ALL agents in parallel
   - Filters to only available agents with credentials
   - Sorts by most recent `credential_last_modified` timestamp
   - Auto-selects the agent with freshest credentials
   - Only runs if user hasn't already configured an agent

1. User opens onboarding dialog for the first time
2. Frontend checks all agents in parallel (CLAUDE_CODE, CODEX, CURSOR_AGENT, etc.)
3. Each returns `{ available: bool, credential_last_modified: timestamp }`
4. Frontend finds agent with most recent credential file modification
5. Auto-selects that agent (likely the one they used most recently)
6. User can still manually change if they want

This provides a smart default while still allowing user choice!

Perfect! All checks pass. Let me show you the final summary:

I've successfully implemented comprehensive agent availability checking with automatic selection of the most recently used agent. Here's what was added:

**`AvailabilityInfo` struct** (`crates/executors/src/executors/mod.rs:167-206`):
- Structured type with fields: `mcp_config_found`, `auth_config_found`, `auth_last_edited`
- `is_available()` method that determines availability from the signals
- Logic: Available if MCP config exists OR auth config exists and is < 60 days old

**Trait method** (`crates/executors/src/executors/mod.rs:229-241`):
- Added `get_availability_info() -> AvailabilityInfo` to `StandardCodingAgentExecutor`
- Default implementation checks only MCP config
- Updated `check_availability()` to use `get_availability_info().is_available()`

**Claude Code** (`crates/executors/src/executors/claude.rs:200-224`):
- Auth credentials: `~/.claude.json`
- Checks file existence and modification time
- Returns AvailabilityInfo with auth signals

**Codex** (`crates/executors/src/executors/codex.rs:168-195`):
- MCP config: `~/.codex/config.toml`
- Auth credentials: `~/.codex/auth.json`
- Checks both MCP and auth configs

**Gemini** (`crates/executors/src/executors/gemini.rs:96-123`):
- MCP config: `~/.gemini/settings.json`
- Auth credentials: `~/.gemini/oauth_creds.json`
- Checks both MCP and auth configs

**Backend API** (`crates/server/src/routes/config.rs:479-498`):
- Returns `credential_last_modified` timestamp from AvailabilityInfo
- Uses `info.is_available()` for the available field

**Frontend auto-selection** (`frontend/src/components/dialogs/global/OnboardingDialog.tsx:64-112`):
- On mount, checks all agents in parallel
- Filters to available agents with credentials
- **Sorts by most recent `credential_last_modified`**
- Auto-selects the agent used most recently

This provides intelligent defaults while respecting user choice!

Perfect! All checks pass. Here's what I implemented:

**Enhanced API Response** (`crates/server/src/routes/config.rs:472-481`):
```rust
pub struct CheckAgentAvailabilityResponse {
    available: bool,
    mcp_config_found: bool,
    auth_config_found: bool,
    credential_last_modified: Option<i64>,
}
```
Now returns all the availability signals from `AvailabilityInfo`.

**OnboardingDialog** (`frontend/src/components/dialogs/global/OnboardingDialog.tsx`):

1. **State for availability map** (lines 57-59):
   - Stores full availability info for all agents
   - Used for intelligent sorting

2. **Priority-based sorting** (lines 187-218):
   - **Tier 1**: Agents with auth config - sorted by most recent first
   - **Tier 2**: Agents with MCP config only - alphabetical within tier
   - **Tier 3**: Other agents - alphabetical within tier
   - **Fallback**: Alphabetical if no availability info loaded yet

```typescript
// Tier 1: Both have auth - sort by recency
if (infoA.auth_config_found && infoB.auth_config_found) {
  return timeB - timeA; // Most recent first
}

// Tier 2: Auth trumps MCP-only
if (infoA.auth_config_found) return -1;
if (infoB.auth_config_found) return 1;

// Tier 3: Both have MCP only - alphabetical
if (infoA.mcp_config_found && infoB.mcp_config_found) {
  return a.localeCompare(b);
}
```

The dropdown will now show agents in this order:
1. **Most recently authenticated agents first** (e.g., Claude Code used yesterday)
2. **Other authenticated agents** (e.g., Gemini used last week)
3. **Agents with only MCP config** (alphabetical)
4. **Agents with no config** (alphabetical)

This ensures users see their most relevant agents at the top of the list!

Cleanup script changes for task attempt 60b68945-b59c-46e1-895d-540a910f2904

Perfect! All checks pass. Here's the final implementation summary:

**Removed `auth_config_found` field** - simplified to just use `auth_last_edited.is_some()`:

**AvailabilityInfo** (`crates/executors/src/executors/mod.rs:167-201`):
```rust
pub struct AvailabilityInfo {
    pub mcp_config_found: bool,
    pub auth_last_edited: Option<i64>,  // If Some(_), auth exists
}
```

**Implementations:**
- **Claude Code** (`claude.rs:200-212`): `~/.claude.json` → `auth_last_edited`
- **Codex** (`codex.rs:168-185`): MCP at `~/.codex/config.toml`, auth at `~/.codex/auth.json`
- **Gemini** (`gemini.rs:96-113`): MCP at `~/.gemini/settings.json`, auth at `~/.gemini/oauth_creds.json`

**CheckAgentAvailabilityResponse** (`config.rs:472-480`):
```rust
{
    available: bool,
    mcp_config_found: bool,
    credential_last_modified: Option<i64>,  // If Some, auth file exists
}
```

**Priority-based dropdown ordering** (`OnboardingDialog.tsx:191-230`):
1. **Tier 1**: Agents with auth (`credential_last_modified !== null`) - sorted by most recent
2. **Tier 2**: Agents with MCP only - alphabetical
3. **Tier 3**: Others - alphabetical

Users will see:
- **Top of list**: Their most recently authenticated agents (e.g., "logged into Claude Code yesterday")
- **Middle**: Agents with MCP config but no recent auth
- **Bottom**: Remaining agents alphabetically

The implementation is clean, simple, and provides intelligent defaults!

Cleanup script changes for task attempt 60b68945-b59c-46e1-895d-540a910f2904

Perfect! All checks pass. The fix is complete:

**The Problem:**
- Line 76 had: `if (!profiles || config?.executor_profile) return;`
- This meant availability was **never fetched** for users with existing config
- `agentAvailabilityMap` stayed empty, sorting defaulted to alphabetical
- Result: AMP appeared first

**The Solution:**
- Removed `config?.executor_profile` from the skip condition
- Now availability is **always fetched** to enable sorting
- Moved the `config?.executor_profile` check **inside** the function (line 116)
- Auto-selection only happens for new users, but sorting works for everyone

**Now the dropdown will show:**
1. **Agents with recent auth** - sorted by most recent first (e.g., Claude Code used yesterday)
2. **Agents with MCP config only** - alphabetical (e.g., Cursor with MCP setup)
3. **Other agents** - alphabetical

The priority-based sorting is now fully functional!

Perfect! Fixed. Both indicators now use the same semantic colors:
- `text-success` for available (instead of `text-green-500`/`text-green-600`)
- `text-warning` for unavailable (instead of `text-orange-500`/`text-orange-600`)

The colors will now match perfectly between IDE and coding agent availability indicators.

Great! TypeScript compiles successfully. The changes are complete:

**AgentAvailabilityIndicator** now has:
1. **Updated text:**
   - "Available" → "Login Detected"
   - "Not Found" remains "Not Found"

2. **Tooltips on hover:**
   - **Login Detected**: "Recent authentication credentials found for this agent"
   - **Not Found**: "No credentials detected. The agent may still work if configured differently."

3. **Visual improvements:**
   - Added `cursor-help` class to show the help cursor on hover
   - Wrapped with shadcn/ui `Tooltip` components

This provides clearer messaging and helpful context for users!

Perfect! The tooltips now have `className="z-[100]"` which should render them above the modal. The fix ensures the hover text is readable when shown within the onboarding dialog.

Perfect! The tooltips now use `z-[10000]` which is higher than the modal's `z-[9999]`, so they should appear on top and be readable.

Perfect! TypeScript compiles successfully. The agent availability indicator is now added to the AgentSettings page:

**AgentSettings.tsx** now has:

1. **Availability check** (line 65):
   ```typescript
   const agentAvailability = useAgentAvailability(selectedExecutorType);
   ```

2. **Indicator display** (line 444):
   ```typescript
   <AgentAvailabilityIndicator availability={agentAvailability} />
   ```

The indicator appears below the agent dropdown selector and shows:
- "Login Detected" with tooltip for agents with credentials
- "Not Found" with tooltip for agents without credentials
- Same styling and behavior as the onboarding dialog

This provides consistent availability feedback throughout the app!

Cleanup script changes for task attempt 60b68945-b59c-46e1-895d-540a910f2904

Excellent! TypeScript compiles successfully. The changes are complete:

**Reverted AgentSettings.tsx:**
- Removed the availability indicator from the Agent Settings page (which is for advanced profile configuration)

**Added to GeneralSettings.tsx:**
- **Line 43-44**: Imported `useAgentAvailability` hook and `AgentAvailabilityIndicator` component
- **Line 81**: Added hook call: `const agentAvailability = useAgentAvailability(draft?.executor_profile?.executor);`
- **Line 420**: Added indicator display: `<AgentAvailabilityIndicator availability={agentAvailability} />`

The agent availability indicator now appears in the **General Settings** page under the "Task Execution" section, right below the agent dropdown selector - matching the pattern of how editor availability is shown in the same settings page. This is the correct location since it's where users configure their default agent, not the advanced agent configuration page.

Cleanup script changes for task attempt 60b68945-b59c-46e1-895d-540a910f2904

Perfect! All checks pass. Comments removed and types regenerated successfully. The implementation is complete and clean.

Fix agent availability i18n (vibe-kanban dcd1fc06)

Run @scripts/check-i18n.sh until it passes. Make sure to check the script and set GITHUB_BASE_REF to main

Fix agent availability i18n (vibe-kanban 77795175)

Run @scripts/check-i18n.sh until it passes. Make sure to check the script and set GITHUB_BASE_REF to main

Currently agents.availability.loginDetected shows in the frontend so it's not using i18n correctly, it was added in the last commit though

Perfect! TypeScript compiles. Now the availability indicator shows three distinct states:

1. **"Login Detected"** - Has auth credentials (recent login)
2. **"Installation Found"** - Has MCP config but no auth (agent is installed)
3. **"Not Found"** - Neither auth nor MCP config found

This gives users much clearer information about what was actually detected!

Cleanup script changes for task attempt 60b68945-b59c-46e1-895d-540a910f2904

Perfect! Now the indicator shows three distinct states:

1. **"Login Detected"** (green check) - Has recent auth credentials
   - Tooltip: "Recent authentication credentials found for this agent"

2. **"Installation Found"** (green check) - Has MCP config but no auth
   - Tooltip: "Agent configuration found. You may need to log in to use it."

3. **"Not Found"** (orange warning) - Neither found
   - Tooltip: "No credentials detected. The agent may still work if configured differently."

This gives users accurate, specific information about what was actually detected!

Fix  i18n agent availability (vibe-kanban 9eab4ea1)

Run @scripts/check-i18n.sh until it passes. Make sure to check the script and set GITHUB_BASE_REF to main

Perfect! I've fixed all the i18n keys by adding the `settings.` prefix. The translations should now work correctly and display:
- "Login Detected" instead of "agents.availability.loginDetected"
- "Installation Found" instead of "agents.availability.installationFound"
- "Not Found" instead of "agents.availability.notFound"

All the keys now match the pattern used throughout the codebase where `useTranslation('settings')` requires the full path starting with `settings.`.

Cleanup script changes for task attempt 60b68945-b59c-46e1-895d-540a910f2904

* Perfect! All checks pass. The refactoring to use `AvailabilityInfo` directly is complete:

**Removed redundancy:**
- Deleted `CheckAgentAvailabilityResponse` struct entirely
- API now returns `AvailabilityInfo` directly
- Removed `available` field (was computed/redundant)

**Backend now returns:**
```rust
AvailabilityInfo {
    mcp_config_found: bool,
    auth_last_edited: Option<i64>,
}
```

**Frontend interprets it as:**
- `auth_last_edited !== null` → **"Login Detected"** (has recent auth credentials)
- `auth_last_edited === null && mcp_config_found === true` → **"Installation Found"** (has MCP config only)
- `auth_last_edited === null && mcp_config_found === false` → **"Not Found"** (nothing detected)

**Benefits:**
- Single source of truth for availability data structure
- No duplication between `AvailabilityInfo` and response type
- Frontend gets raw signals and can interpret them appropriately
- Cleaner, simpler codebase

The implementation now correctly distinguishes between login credentials and installation/configuration files!

Cleanup script changes for task attempt 60b68945-b59c-46e1-895d-540a910f2904

Perfect! All checks pass. The `check_availability` method has been successfully removed:

**Removed `check_availability()` method:**
- Updated `profile.rs:419` to use `get_availability_info().is_available()` instead
- Removed `check_availability()` from trait definition
- Updated Cursor's custom override to use `get_availability_info()` instead
- Removed unused import from cursor.rs

**Now there's only one method:**
- `get_availability_info()` returns the raw signals
- Callers use `.is_available()` if they need a boolean

Cleaner API surface with no redundant methods!

* Perfect! The simplification is complete. Let me show you what was removed:

## Simplified Implementation

**Removed from OnboardingDialog (~90 lines):**
-  `agentAvailabilityMap` state (9 lines)
-  `useEffect` with parallel API calls (66 lines)
-  Complex 3-tier sorting logic (41 lines)
-  Auto-selection based on recent auth
-  Unused imports (`useEffect`, `configApi`)

**What remains:**
-  Simple alphabetical sort: `.sort()`
-  Backend auto-selects first available agent (via `get_recommended_executor_profile`)
-  Live indicator when user selects agent (via `useAgentAvailability` hook)
-  Indicator in GeneralSettings

**The feature now:**
1. Dropdown shows agents alphabetically (AMP, CLAUDE_CODE, CODEX, ...)
2. Pre-selected agent is whatever backend chose (first available from HashMap)
3. User selects an agent → indicator shows "Login Detected" / "Installation Found" / "Not Found"
4. Same in GeneralSettings when changing default agent

**Net reduction: ~90 lines removed from OnboardingDialog, much simpler!**

* Perfect! All checks pass. The implementation is complete:

## Summary of Final Simplified Architecture

**Backend (profile.rs):**
- `get_recommended_executor_profile()` now checks ALL available agents
- Sorts by most recent `auth_last_edited` timestamp
- Returns agent with freshest credentials (e.g., logged in yesterday)
- Fallback to agents with MCP config if no auth found

**Frontend (OnboardingDialog):**
-  Shows alphabetically sorted dropdown
-  Pre-selects whatever backend recommended (agent with most recent credentials)
-  Shows live indicator when selected: "Login Detected" / "Installation Found" / "Not Found"
-  No parallel API calls on mount (removed ~90 lines)
-  No complex sorting logic (removed)
-  No auto-selection in frontend (backend handles it)

**Net result:**
- Smart auto-selection happens in backend (right place)
- Frontend is much simpler (just shows indicator on selection)
- Achieves the same UX goal (picks most recently used agent)
- ~90 lines removed from OnboardingDialog

Much cleaner architecture!

* Perfect! All checks pass. The 60-day cutoff has been removed:

## Summary of Changes

**Simplified `is_available()` logic** (`crates/executors/src/executors/mod.rs:175-177`):
```rust
pub fn is_available(&self) -> bool {
    self.mcp_config_found || self.auth_last_edited.is_some()
}
```

**Before:**
- Auth file must exist AND be less than 60 days old
- Rejected old auth files even if tokens still valid

**After:**
- Auth file exists → available 
- MCP config exists → available 
- Simple and straightforward

**Benefits:**
-  Removed 13 lines of arbitrary staleness checking
-  No false negatives (61-day-old credentials shown as "Login Detected")
-  Backend sorting still prioritizes recent auth (for smart auto-selection)
-  If tokens are actually expired, user finds out when they try to use the agent (which is fine)

The implementation is now much cleaner - file existence is all we check, and recency is only used for **prioritization** in the backend auto-selection, not for determining availability.

* Review agent availability (vibe-kanban a75cb3d4)

Review the last 4 commits

* Move agent install info out of tooltip (vibe-kanban 481d6ed6)

When agents are not installed users can get more info by hovering and looking at the tooltip, move this out of there and always display it.

* Refactor auth file path (vibe-kanban e691ad16)

In crates/executors/src/executors/mod.rs add a method similar to mcp config for auth config that executors can check in the availability check

* Refactor auth file path (vibe-kanban e691ad16)

In crates/executors/src/executors/mod.rs add a method similar to mcp config for auth config that executors can check in the availability check

* Refactor availability info (vibe-kanban 8e24bec4)

Check crates/executors/src/executors/mod.rs and refactor availability info. The frontend currently may not use the timestamp and defines its own state type. we should return the state from the backend instead

* Perfect! Now all locale files are updated with the user-centric language:

## Summary of i18n Updates

**Changed labels to user-centric language:**
- "Login Detected" → **"Recent Usage Detected"**
- "Installation Found" → **"Previous Usage Detected"**

**Updated notFound tooltip:**
- "No credentials detected. The agent may still work if configured differently."
- → **"No previous usage detected. Agent may require installation and/or login."**

**Kept technical tooltips for detected states:**
- "Recent authentication credentials found for this agent" (still accurate)
- "Agent configuration found. You may need to log in to use it." (still helpful)

This is much clearer for users - focuses on what they care about (did I use this before?) rather than technical implementation details (credentials, MCP configs, auth files).

* lint

* Perfect! All the imports are cleaned up. Now all executor implementations use the shorter `AvailabilityInfo::LoginDetected` instead of the verbose `crate::executors::AvailabilityInfo::LoginDetected`.

Cleanup script changes for task attempt 60b68945-b59c-46e1-895d-540a910f2904

Perfect! All the imports are now cleaned up. All executor implementations use the shorter `AvailabilityInfo::LoginDetected` instead of the verbose `crate::executors::AvailabilityInfo::LoginDetected`.

Cleanup script changes for task attempt 60b68945-b59c-46e1-895d-540a910f2904
2025-11-24 18:50:46 +00:00

388 lines
18 KiB
JSON

{
"settings": {
"layout": {
"nav": {
"title": "Configuración",
"general": "General",
"generalDesc": "Tema, notificaciones y preferencias",
"projects": "Proyectos",
"projectsDesc": "Scripts y configuración de proyectos",
"agents": "Agentes",
"agentsDesc": "Configuraciones de agentes",
"mcp": "Servidores MCP",
"mcpDesc": "Servidores de Protocolo de Contexto de Modelo (MCP)",
"organizations": "Organization Settings",
"organizationsDesc": "Manage organization members and permissions"
}
},
"general": {
"loading": "Cargando configuración...",
"loadError": "Error al cargar la configuración.",
"save": {
"button": "Guardar Configuración",
"success": "✓ ¡Configuración guardada!",
"error": "Error al guardar la configuración",
"unsavedChanges": "• Tienes cambios sin guardar",
"discard": "Descartar"
},
"appearance": {
"title": "Apariencia",
"description": "Personaliza cómo se ve la aplicación.",
"theme": {
"label": "Tema",
"placeholder": "Seleccionar tema",
"helper": "Elige tus colores preferidos."
},
"language": {
"label": "Idioma",
"placeholder": "Selecciona tu idioma",
"helper": "Elige tu idioma preferido. El predeterminado del navegador sigue el idioma de tu sistema."
}
},
"taskExecution": {
"title": "Ejecución de Tareas",
"description": "Configura cómo se ejecutan y procesan las tareas.",
"executor": {
"label": "Configuración predeterminada del Agente",
"placeholder": "Seleccionar perfil",
"helper": "Define la configuración predeterminada del agente que se usará al iniciar una tarea."
},
"variant": "PREDETERMINADO",
"defaultLabel": "Predeterminado"
},
"editor": {
"title": "Editor",
"description": "Configura cómo quieres editar tu código.",
"type": {
"label": "Tipo de Editor",
"placeholder": "Seleccionar editor",
"helper": "Elige tu editor de código preferido."
},
"customCommand": {
"label": "Comando de Editor Personalizado",
"placeholder": "ej., code, subl, vim",
"helper": "Ingresa el comando para lanzar tu editor personalizado. Se utilizará para abrir archivos."
},
"remoteSsh": {
"host": {
"label": "Host SSH Remoto (Opcional)",
"placeholder": "ej., nombre de host o dirección IP",
"helper": "Configura esto si Vibe Kanban se ejecuta en un servidor remoto. Cuando se establece, al hacer clic en \"Abrir en Editor\" se generará una URL para abrir tu editor a través de SSH en lugar de ejecutar un comando local."
},
"user": {
"label": "Usuario SSH Remoto (Opcional)",
"placeholder": "ej., nombre de usuario",
"helper": "Nombre de usuario SSH para la conexión remota. Si no se establece, VS Code usará tu configuración SSH o te lo pedirá."
}
},
"availability": {
"checking": "Verificando disponibilidad...",
"available": "Disponible",
"notFound": "No encontrado en PATH"
}
},
"github": {
"title": "Integración con GitHub",
"cliSetup": {
"title": "Configuración de GitHub CLI",
"description": "La autenticación de GitHub CLI es necesaria para crear pull requests e interactuar con repositorios de GitHub.",
"setupWillTitle": "Esta configuración:",
"steps": {
"checkInstalled": "Verificará si GitHub CLI (gh) está instalado",
"installHomebrew": "Lo instalará vía Homebrew si es necesario (macOS)",
"authenticate": "Autenticará con GitHub usando OAuth"
},
"setupNote": "La configuración se ejecutará en la ventana de chat. Necesitarás completar la autenticación en tu navegador.",
"runSetup": "Ejecutar Configuración",
"running": "Ejecutando...",
"errors": {
"brewMissing": "Homebrew no está instalado. Instálalo para habilitar la configuración automática.",
"notSupported": "La configuración automática no es compatible con esta plataforma. Instala GitHub CLI manualmente.",
"setupFailed": "Error al ejecutar la configuración de GitHub CLI."
},
"help": {
"homebrew": {
"description": "La instalación automática requiere Homebrew. Instala Homebrew desde",
"brewSh": "brew.sh",
"manualInstall": "y luego vuelve a ejecutar la configuración. Alternativamente, instala GitHub CLI manualmente con:",
"afterInstall": "Después de la instalación, autentica con:"
},
"manual": {
"description": "Instala GitHub CLI desde la",
"officialDocs": "documentación oficial",
"andAuthenticate": "y luego autentica con tu cuenta de GitHub."
}
}
}
},
"git": {
"title": "Git",
"description": "Configurar preferencias de nombres de ramas git",
"branchPrefix": {
"label": "Prefijo de Rama",
"placeholder": "vk",
"helper": "Prefijo para nombres de ramas generadas automáticamente. Dejar vacío para no usar prefijo.",
"preview": "Vista previa:",
"previewWithPrefix": "{{prefix}}/1a2b-nombre-tarea",
"previewNoPrefix": "1a2b-nombre-tarea",
"errors": {
"slash": "El prefijo no puede contener '/'.",
"startsWithDot": "El prefijo no puede comenzar con '.'.",
"endsWithDot": "El prefijo no puede terminar con '.' o '.lock'.",
"invalidSequence": "Contiene secuencia no válida (.., @{).",
"invalidChars": "Contiene caracteres no válidos.",
"controlChars": "Contiene caracteres de control."
}
}
},
"notifications": {
"title": "Notificaciones",
"description": "Controla cuándo y cómo recibes notificaciones.",
"sound": {
"label": "Notificaciones de Sonido",
"helper": "Reproduce un sonido cuando una tarea termina de ejecutarse.",
"fileLabel": "Sonido",
"filePlaceholder": "Seleccionar sonido",
"fileHelper": "Elige el sonido que se reproducirá al completar las tareas. Haz clic en el botón de volumen para escucharlo."
},
"push": {
"label": "Notificaciones Push",
"helper": "Muestra notificaciones del sistema cuando las tareas terminan de ejecutarse."
}
},
"privacy": {
"title": "Privacidad",
"description": "Ayuda a mejorar Vibe-Kanban compartiendo datos de uso anónimos.",
"telemetry": {
"label": "Habilitar Telemetría",
"helper": "Habilita el seguimiento anónimo para ayudar a mejorar la aplicación. No se recopilan prompts ni información del proyecto."
}
},
"taskTemplates": {
"title": "Etiquetas",
"description": "Crea fragmentos de texto reutilizables que se pueden insertar en descripciones de tareas usando @nombre_etiqueta."
},
"tags": {
"manager": {
"title": "Etiquetas de Tareas",
"addTag": "Agregar Etiqueta",
"noTags": "Aún no hay etiquetas. Crea fragmentos de texto reutilizables para descripciones de tareas comunes. Usa @nombre_etiqueta en cualquier tarea.",
"table": {
"tagName": "Nombre de Etiqueta",
"content": "Contenido",
"actions": "Acciones"
},
"actions": {
"editTag": "Editar etiqueta",
"deleteTag": "Eliminar etiqueta"
},
"deleteConfirm": "¿Estás seguro de que deseas eliminar la etiqueta \"{{tagName}}\"?"
},
"dialog": {
"createTitle": "Crear Etiqueta",
"editTitle": "Editar Etiqueta",
"tagName": {
"label": "Nombre de Etiqueta",
"required": "*",
"hint": "Usa este nombre con @ en descripciones de tareas: @{{tagName}}",
"placeholder": "ej., corrección_error, plan_prueba, docs_api",
"error": "El nombre de la etiqueta no puede contener espacios. Usa guiones bajos en su lugar (ej., mi_etiqueta)"
},
"content": {
"label": "Contenido",
"required": "*",
"hint": "Texto que se insertará cuando uses @{{tagName}} en descripciones de tareas",
"placeholder": "Ingresa el texto que se insertará cuando uses esta etiqueta"
},
"errors": {
"nameRequired": "El nombre de la etiqueta es obligatorio",
"saveFailed": "Error al guardar la etiqueta"
},
"buttons": {
"cancel": "Cancelar",
"create": "Crear",
"update": "Actualizar"
}
}
},
"safety": {
"title": "Avisos legales y de seguridad",
"description": "Reinicia las confirmaciones de seguridad y de introducción.",
"disclaimer": {
"title": "Confirmación de Descargo",
"description": "Restablecer el aviso de seguridad.",
"button": "Restablecer"
},
"onboarding": {
"title": "Introducción",
"description": "Restablece el flujo de Introducción.",
"button": "Restablecer"
}
}
},
"agents": {
"title": "Configuraciones de Agentes de Código",
"description": "Personaliza el comportamiento de los agentes con diferentes configuraciones.",
"loading": "Cargando configuraciones de agentes...",
"save": {
"button": "Guardar Configuraciones de Agentes",
"success": "✓ ¡Configuración guardada con éxito!"
},
"availability": {
"checking": "Comprobando...",
"loginDetected": "Uso reciente detectado",
"loginDetectedTooltip": "Se encontraron credenciales de autenticación recientes para este agente",
"installationFound": "Uso previo detectado",
"installationFoundTooltip": "Se encontró la configuración del agente. Es posible que debas iniciar sesión para usarlo.",
"notFound": "No encontrado",
"notFoundTooltip": "No se detectó uso previo. El agente puede requerir instalación y/o inicio de sesión."
},
"editor": {
"formLabel": "Editar JSON",
"agentLabel": "Agente",
"agentPlaceholder": "Seleccionar tipo",
"configLabel": "Configuración",
"configPlaceholder": "Seleccionar configuración",
"createNew": "Crear nuevo...",
"deleteTitle": "No se puede eliminar la última configuración",
"deleteButton": "Eliminar {{name}}",
"deleteText": "Eliminar",
"jsonLabel": "Configuración de Agente (JSON)",
"jsonPlaceholder": "Cargando perfiles...",
"jsonLoading": "Cargando...",
"pathLabel": "Ubicación del archivo de configuración:"
},
"errors": {
"deleteFailed": "Error al eliminar la configuración. Por favor, inténtalo de nuevo.",
"saveFailed": "Error al guardar la configuración de los agentes. Por favor, inténtalo de nuevo.",
"saveConfigFailed": "Error al guardar la configuración. Por favor, inténtalo de nuevo."
}
},
"mcp": {
"title": "Configuración de Servidor MCP",
"description": "Configura los servidores del Protocolo de Contexto de Modelos (MCP) para ampliar las capacidades del agente de codificación con herramientas y recursos personalizados.",
"loading": "Cargando configuración MCP...",
"applying": "Aplicando configuración...",
"loadingStates": {
"jsonEditor": "Cargando...",
"configuration": "Cargando configuración actual del servidor MCP..."
},
"labels": {
"agent": "Agente",
"agentPlaceholder": "Seleccionar",
"agentHelper": "Elige para qué agente configurar los servidores MCP.",
"serverConfig": "Configuración de Servidor (JSON)",
"popularServers": "Servidores populares",
"serverHelper": "Haz clic en una tarjeta para insertar ese Servidor MCP en el JSON de arriba.",
"saveLocation": "Los cambios se guardarán en:"
},
"errors": {
"loadFailed": "Error al cargar la configuración.",
"invalidJson": "Formato JSON inválido",
"validationError": "Error de validación",
"saveFailed": "Error al guardar servidores MCP",
"applyFailed": "Error al aplicar la configuración del servidor MCP",
"addServerFailed": "Error al agregar servidor preconfigurado",
"mcpError": "Error de Configuración MCP: {{error}}",
"notSupported": "MCP No Soportado",
"supportMessage": "Para usar servidores MCP, por favor selecciona un agente diferente que soporte MCP (Claude, Amp, Gemini, Codex, o Opencode) arriba."
},
"save": {
"button": "Guardar Configuración MCP",
"success": "¡Configuración Guardada!",
"successMessage": "✓ ¡Configuración MCP guardada exitosamente!",
"loading": "Cargando configuración actual del servidor MCP..."
}
},
"projects": {
"title": "Configuración de Proyectos",
"description": "Configura scripts y ajustes específicos del proyecto.",
"loading": "Cargando proyectos...",
"loadError": "Error al cargar proyectos.",
"selector": {
"label": "Seleccionar Proyecto",
"placeholder": "Elige un proyecto para configurar",
"helper": "Selecciona un proyecto para ver y editar su configuración.",
"noProjects": "No hay proyectos disponibles"
},
"general": {
"title": "Configuración General",
"description": "Configura la información básica del proyecto.",
"name": {
"label": "Nombre del Proyecto",
"placeholder": "Ingresa el nombre del proyecto",
"helper": "Un nombre para mostrar para este proyecto."
},
"repoPath": {
"label": "Ruta del Repositorio Git",
"placeholder": "/ruta/a/tu/repositorio/existente",
"helper": "La ruta absoluta a tu repositorio git en disco."
}
},
"scripts": {
"title": "Scripts y Configuración",
"description": "Configura los scripts de instalación, desarrollo y limpieza para este proyecto.",
"setup": {
"label": "Script de Instalación",
"helper": "Este script se ejecutará después de crear el worktree y antes de que comience el agente de codificación. Úsalo para tareas de configuración como instalar dependencias o preparar el entorno."
},
"dev": {
"label": "Script del Servidor de Desarrollo",
"helper": "Este script se puede ejecutar desde los intentos de tarea para iniciar un servidor de desarrollo. Úsalo para iniciar rápidamente el servidor de desarrollo de tu proyecto para probar cambios."
},
"cleanup": {
"label": "Script de Limpieza",
"helper": "Este script se ejecuta después de la ejecución del agente de codificación solo si se realizaron cambios. Úsalo para tareas de garantía de calidad como ejecutar linters, formateadores, pruebas u otros pasos de validación. Si no se realizan cambios, se omite este script."
},
"copyFiles": {
"label": "Copiar Archivos",
"helper": "Lista separada por comas de archivos para copiar del directorio del proyecto original al worktree. Estos archivos se copiarán después de que se cree el worktree pero antes de que se ejecute el script de configuración. Útil para archivos específicos del entorno como .env, archivos de configuración y ajustes locales. ¡Asegúrate de que estén en gitignore o podrían ser confirmados!"
}
},
"save": {
"button": "Guardar Configuración del Proyecto",
"success": "✓ ¡Configuración del proyecto guardada exitosamente!",
"error": "Error al guardar la configuración del proyecto",
"unsavedChanges": "• Tienes cambios sin guardar",
"discard": "Descartar",
"confirmSwitch": "Tienes cambios sin guardar. ¿Estás seguro de que quieres cambiar de proyecto? Tus cambios se perderán."
}
}
},
"integrations": {
"github": {
"cliSetup": {
"title": "Configuración de GitHub CLI",
"description": "Se requiere autenticación de GitHub CLI para crear pull requests e interactuar con repositorios de GitHub.",
"setupWillTitle": "Esta configuración:",
"steps": {
"checkInstalled": "Verificar si GitHub CLI (gh) está instalado",
"installHomebrew": "Instalarlo a través de Homebrew si es necesario (macOS)",
"authenticate": "Autenticar con GitHub usando OAuth"
},
"setupNote": "La configuración se ejecutará en la ventana de chat. Necesitarás completar la autenticación en tu navegador.",
"runSetup": "Ejecutar Configuración",
"running": "Ejecutando...",
"errors": {
"brewMissing": "Homebrew no está instalado. Instálalo para habilitar la configuración automática.",
"notSupported": "La configuración automática no está soportada en esta plataforma. Instala GitHub CLI manualmente.",
"setupFailed": "Error al ejecutar la configuración de GitHub CLI."
},
"help": {
"homebrew": {
"description": "La instalación automática requiere Homebrew. Instala Homebrew desde",
"brewSh": "brew.sh",
"manualInstall": "y luego vuelve a ejecutar la configuración. Alternativamente, instala GitHub CLI manualmente con:",
"afterInstall": "Después de la instalación, autentica con:"
},
"manual": {
"description": "Instala GitHub CLI desde la",
"officialDocs": "documentación oficial",
"andAuthenticate": "y luego autentica con tu cuenta de GitHub."
}
}
}
}
}
}