Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/i18n-inventory.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# i18n inventory (egdev6/quorb#66)

Generated by `node scripts/i18n-inventory.mjs` from the source trees `src/` = `129601dcd1c39752bf3a0d5e2a484ed622db7138` and `src-tauri/src/` = `df433ca38183d57bc26b6840a43190bba6083dd1`.
Generated by `node scripts/i18n-inventory.mjs` from the source trees `src/` = `129601dcd1c39752bf3a0d5e2a484ed622db7138` and `src-tauri/src/` = `fa2fd75f1124453a881a835169cde8f4ffb08839`.
Any commit whose `git rev-parse <commit>:src` and `<commit>:src-tauri/src` match has these exact texts.
Do not edit by hand: regenerate, or verify with `node scripts/i18n-inventory.mjs --check`.

Expand Down
2 changes: 1 addition & 1 deletion src-tauri/src/cli_process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl CommandRunner for ProcessRunner {
cwd: &Path,
timeout: Duration,
) -> Result<CommandOutput, RunError> {
let mut child = spawn_child(program, args, env, cwd)?;
let child = spawn_child(program, args, env, cwd)?;
run_pipelined(child, timeout)
}
}
Expand Down
1 change: 1 addition & 0 deletions src-tauri/src/codex_setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1627,6 +1627,7 @@ mod tests {

/// Node real del proyecto (por `QUORB_TEST_NODE_EXECUTABLE` o PATH); nunca se
/// lee su versión ni se ejecutan probes de npm/Codex.
#[cfg(unix)]
fn test_node_executable() -> Option<PathBuf> {
if let Some(explicit) = std::env::var_os("QUORB_TEST_NODE_EXECUTABLE") {
let explicit = PathBuf::from(explicit);
Expand Down
8 changes: 6 additions & 2 deletions src-tauri/src/detail_placement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,13 @@ use std::sync::atomic::{AtomicU64, Ordering};

use crate::detail_geometry::Bounds;
use crate::widget_placement::{
position_matches, rooted_origin, size_matches, to_logical, to_physical, Geometry, Reason,
Transport, READS, SETTLE,
position_matches, size_matches, to_logical, Geometry, Reason, Transport, READS,
};
// Piezas del ciclo nativo X11: solo las usa `UiSurface`, que existe únicamente
// en Linux. En Windows/macOS el transporte aplica la petición e informa sin
// read-back, así que estos símbolos no se importan ahí.
#[cfg(target_os = "linux")]
use crate::widget_placement::{rooted_origin, to_physical, SETTLE};
// El informe es el espejo de `set_widget_bounds`: viajan los mismos tipos,
// así el frontend trata con un solo contrato.
pub use crate::widget_placement::{Report, Status};
Expand Down
14 changes: 10 additions & 4 deletions src-tauri/src/login.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,11 @@ type SessionEnv = Option<(&'static str, std::path::PathBuf)>;

/// Antepone al PATH la carpeta donde se encontró el CLI (si no estaba en el PATH),
/// incluyendo el PATH fresco del registro para que la terminal nueva lo vea.
/// Solo la consumen las ramas Windows/Linux: en macOS el PATH viaja dentro del
/// texto del script de Terminal, no por herencia del entorno.
#[cfg(any(test, not(target_os = "macos")))]
/// Solo la consume la rama Windows (`spawn_terminal`: inyecta el PATH en la
/// consola nueva): en macOS el PATH viaja dentro del texto del script de
/// Terminal y en Linux la rama usa `path_with_dirs` con los directorios
/// explícitos.
#[cfg(windows)]
fn path_with(extra: Option<PathBuf>) -> Option<std::ffi::OsString> {
let mut dirs: Vec<PathBuf> = std::env::var_os("PATH")
.map(|p| std::env::split_paths(&p).collect())
Expand All @@ -266,7 +268,7 @@ fn path_with(extra: Option<PathBuf>) -> Option<std::ffi::OsString> {
}

/// Antepone `extra` a `current` (el PATH actual) sin tocar el entorno real.
#[cfg(any(test, not(target_os = "macos")))]
#[cfg(any(test, windows))]
fn path_with_current(
extra: Option<PathBuf>,
current: Option<std::ffi::OsString>,
Expand Down Expand Up @@ -396,6 +398,10 @@ const SHELL_WRAP: &str = "\"$@\"; exec \"${SHELL:-/bin/sh}\"";
/// literal): si el CLI necesita variables, deben definirse fuera del comando.
/// Comillas sin cerrar devuelven `Err` y el login se aborta
/// (fail-closed): el texto del usuario nunca se interpola como código.
/// Solo lo consumen `spawn_terminal` de Linux (la terminal recibe el login
/// como argv) y los tests: en Windows el comando va dentro de `cmd /K` y en
/// macOS dentro del script de Terminal.
#[cfg(any(test, all(not(windows), not(target_os = "macos"))))]
fn split_login_command(command: &str) -> Result<(String, Vec<String>), String> {
let mut tokens: Vec<String> = Vec::new();
let mut current = String::new();
Expand Down
15 changes: 10 additions & 5 deletions src-tauri/src/providers/claude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use crate::config::SubscriptionConfig;
use crate::model::{Kind, Meter, Status, UsageReport};
use crate::wsl::{SessionError, SessionResolver};
use serde_json::Value;
use std::path::Path;

const USAGE_URL: &str = "https://api.anthropic.com/api/oauth/usage";

Expand All @@ -25,11 +24,15 @@ const KEYCHAIN_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5);
/// Resultado de consultar el Keychain de macOS por la sesión de Claude Code.
#[derive(Debug, PartialEq)]
enum KeychainOutcome {
/// Sesión válida encontrada y parseada.
/// Sesión válida encontrada y parseada. Solo el Keychain de macOS la
/// produce (`keychain_sync`); fuera de macOS no se construye.
#[cfg(target_os = "macos")]
Session(Credentials),
/// No hay entrada, el usuario negó el acceso o el secreto no parsea.
NoSession,
/// La autorización no se completó dentro del presupuesto: estado accionable.
/// Igual que `Session`, solo la rama macOS la produce.
#[cfg(target_os = "macos")]
TimedOut,
}

Expand Down Expand Up @@ -105,7 +108,7 @@ fn keychain_sync(timeout: std::time::Duration) -> KeychainOutcome {
/// Resultado diferenciado de la espera acotada: terminar bien, terminar mal
/// o agotar el presupuesto. Distintos a propósito — `keychain_sync` reporta
/// `NoSession` y `TimedOut` de forma distinta (revisión #112).
#[cfg(any(test, target_os = "macos"))]
#[cfg(any(target_os = "macos", all(test, unix)))]
enum WaitOutcome {
/// Terminó con éxito dentro del presupuesto.
Success(BoundedOutput),
Expand All @@ -119,7 +122,7 @@ enum WaitOutcome {
/// terminó bien dentro del presupuesto; en timeout mata el árbol y devuelve
/// `TimedOut`; en salida fallida, `Failed`. Puro respecto del Keychain para
/// poder probarlo con procesos reales (`sleep`, `true`, `false`).
#[cfg(any(test, target_os = "macos"))]
#[cfg(any(target_os = "macos", all(test, unix)))]
fn wait_bounded(mut child: std::process::Child, timeout: std::time::Duration) -> WaitOutcome {
use std::io::Read;
let mut pipe = match child.stdout.take() {
Expand Down Expand Up @@ -153,7 +156,7 @@ fn wait_bounded(mut child: std::process::Child, timeout: std::time::Duration) ->
}

/// Salida capturada de un proceso que terminó con éxito dentro del presupuesto.
#[cfg(any(test, target_os = "macos"))]
#[cfg(any(target_os = "macos", all(test, unix)))]
struct BoundedOutput {
stdout: String,
}
Expand Down Expand Up @@ -244,7 +247,9 @@ pub async fn fetch(
);
}
match keychain_fallback().await {
#[cfg(target_os = "macos")]
KeychainOutcome::Session(c) => c,
#[cfg(target_os = "macos")]
KeychainOutcome::TimedOut => {
return report.fail(
Status::Warning,
Expand Down
1 change: 0 additions & 1 deletion src-tauri/src/providers/gemini.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use crate::model::{Kind, Meter, Status, UsageReport};
use crate::wsl::{SessionError, SessionResolver};
use serde_json::{json, Value};
use std::collections::BTreeMap;
use std::path::Path;
use std::sync::Mutex;

const API: &str = "https://cloudcode-pa.googleapis.com/v1internal";
Expand Down
14 changes: 14 additions & 0 deletions src-tauri/src/uninstall.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Explicit NSIS delete-data helper, dispatched before Tauri/plugins start.
//! No config/session contents are loaded and no credential values are read.
#[cfg(any(windows, test))]
use crate::channel::Profile;
#[cfg(any(windows, test))]
use std::{
fs,
path::{Path, PathBuf},
Expand All @@ -9,24 +11,33 @@ use std::{
#[derive(Debug, PartialEq)]
enum Failure {
Arguments,
#[cfg(any(windows, test))]
Paths,
#[cfg(any(windows, test))]
Credentials,
#[cfg(any(windows, test))]
Files,
}
impl Failure {
fn exit_code(&self) -> i32 {
match self {
Self::Arguments => 2,
#[cfg(any(windows, test))]
Self::Paths => 3,
#[cfg(any(windows, test))]
Self::Credentials => 4,
#[cfg(any(windows, test))]
Self::Files => 5,
}
}
}

// Only the Windows NSIS helper deletes data; tests exercise it everywhere.
#[cfg(any(windows, test))]
struct Plan {
roots: [PathBuf; 3],
}
#[cfg(any(windows, test))]
impl Plan {
fn new(profile: &Profile, home: &Path, roaming: &Path, local: &Path) -> Result<Self, Failure> {
if !matches!(
Expand Down Expand Up @@ -81,6 +92,7 @@ impl Plan {
}
}

#[cfg(any(windows, test))]
fn is_link(meta: &fs::Metadata) -> bool {
#[cfg(windows)]
{
Expand All @@ -93,6 +105,7 @@ fn is_link(meta: &fs::Metadata) -> bool {
}
}

#[cfg(any(windows, test))]
fn purge(plan: &Plan, credentials: impl FnOnce() -> Result<(), Failure>) -> Result<(), Failure> {
plan.preflight()?;
// If vault access/deletion fails, preserve files and stop the uninstaller.
Expand All @@ -107,6 +120,7 @@ fn purge(plan: &Plan, credentials: impl FnOnce() -> Result<(), Failure>) -> Resu
Ok(())
}

#[cfg(any(windows, test))]
fn owned_target(target: &str, identifier: &str) -> bool {
let Some(key) = target.strip_suffix(&format!(".{identifier}")) else {
return false;
Expand Down
4 changes: 3 additions & 1 deletion src-tauri/src/wm_compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,9 @@ pub fn display_backend_from_env(env: &Env) -> DisplayBackend {
/// live GDK probe, when it resolves, MUST win over the env fallback. Pure
/// helper, applied at the command level: rewrites `display_backend` and
/// recomputes ONLY `surfaces.window_positioning`; every other surface stays
/// untouched.
/// untouched. Only `get_wm_info` on Linux (the sole platform with the runtime
/// GDK backend probe) and the tests call it.
#[cfg(any(test, target_os = "linux"))]
pub fn with_display_backend(
mut info: WindowManagerInfo,
backend: DisplayBackend,
Expand Down
5 changes: 5 additions & 0 deletions src-tauri/src/wsl/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ pub fn pidfile_base() -> PathBuf {
/// El nombre del subdirectorio lo decide `mktemp -d` en la distro, así que
/// el host lo descubre con un glob dentro del base. `$1` entra como
/// parámetro posicional: nada se interpola en el script.
///
/// El código de producción lee PID y token en una sola llamada
/// (`SCRIPT_READ_IDENTITY`); este script queda como fixture de los tests de
/// argv.
#[cfg(test)]
pub const SCRIPT_READ_PID: &str = "cat \"$1\"/*/pid";

/// Script constante para leer PID **y token de instancia** en la misma
Expand Down
Loading