Commit Graph
27 Commits
Author SHA1 Message Date
Neil bec57632a4 refactor(settings): place shared host features and terminal catalogs with owners (#40051)
* refactor(settings): place shared host features and terminal catalogs with owners

* refactor(settings): retain browser host adapter policy
2026-11-08 17:25:35 -08:00
Neil 3228095e97 refactor(renderer): organize launch, workspace, browser and search owners (#38845)
* refactor(renderer): group launch, workspace, and browser owners

* fix(renderer): restore workspace name Enter focus to agent picker
2026-11-06 10:37:45 -08:00
Neil a82f279f77 refactor: organize workspace card and action owners (#38081) 2026-11-04 00:49:38 -08:00
Neil 11baf7a82e refactor(settings): group agent, account and repository owners (#37817) 2026-11-03 05:11:02 -08:00
Neil fced292c55 refactor(settings): group presentation and form-control owners (#37796) 2026-11-03 03:42:05 -08:00
Neil fd99549aec Draw workspace cards from a template (card plugins, phase 1) (#37647)
* feat(sidebar): draw workspace cards from a template (card plugins phase 1)

Today's card becomes the built-in card template: a JSON template of
layout primitives and Orca's own card parts, compiled once and evaluated
per card over a documented workspace fact model. Markup parity with the
original composition is tested for 34 states in all three card styles.

* fix(sidebar): card template typecheck

* fix(sidebar): bound card template def expansion and tighten expressions

- Cap expanded elements (maxExpandedNodes 2000), expanded depth (maxDepth)
  and def nesting (maxDefDepth 8) at compile time, so reused defs cannot
  multiply into millions of elements.
- A def reference now keeps the frame's root attributes, rejects props and
  children, and is looked up with hasOwn.
- Chained ternaries count toward the expression depth cap; len(x,) is rejected.
- Parts are documented as hook-free.
- Drop the unread CompiledCardTemplate.roots; schema now reads
  WORKSPACE_CARD_FACTS_VERSION. maxBytes stays for phase 2.

* chore(sidebar): baseline the card template's moved focus read and allowlist non-UI strings
2026-11-02 20:56:01 -08:00
Neil 2541edc98e feat(settings): import Kitty configs through a shared terminal config import pipeline (#37375)
* feat(settings): import Kitty configs through a shared terminal config import pipeline

* fix(settings): harden Kitty include and value parsing

* fix(settings): match Kitty globs linearly, skip read-only system configs, report non-family font selectors

* refactor(settings): read current settings through a typed map when diffing imports

* style: format Ghostty importer

* fix(settings): type the import hook stub and let dialog primitives own their typography
2026-11-02 01:11:26 -08:00
Kelvin Amoaba 7984ed1799 fix(emulator): show a dead Android preview as Not connected with a working Connect (#37146)
* fix(emulator): show a dead Android preview as disconnected so Connect restarts it

When the scrcpy session ended, the video registry dropped its subscribers silently and a later subscribe was a no-op, so the pane kept saying Connected over a blank 'Stream disconnected' screen with no way to retry. The registry now tells subscribers the session ended, the IPC relays it on the stream error channel, and the pane marks the session disconnected so the toolbar's Connect button restarts scrcpy.

* fix(emulator): retry a lost Android preview by AVD name and keep stale errors off new streams

* fix(emulator): keep a live emulator serial and fall back to its AVD name only once it is gone

* fix(emulator): keep the AVD target across failed reconnects and reused serials

* fix(emulator): reboot a vanished emulator by AVD name only when the host no longer finds its serial

Replaces the pre-attach device refresh: the live serial always goes first, and the AVD name is tried only after the host answers emulator_device_not_found.

* refactor(emulator): read the host error code plainly in the AVD fallback

* refactor(emulator): type the attach result without a cast and derive WebCodecs support in render

* fix(emulator): type the fallback test's attach result and allowlist the WebCodecs diagnostic
2026-11-01 21:24:35 +00:00
Brennan Benson 5cf236730f Add Chat UI upgrade tip and Chat/Terminal default tiles (#36171)
* Chat UI leaves Experimental: each agent's Chat | CLI choice decides launches

Remove the experimentalNativeChat switch and every gate on it. The Chat
settings page, Default Agent Chat | CLI choice, + menu Chat/CLI rows,
source-control surface choice, Antigravity chat section and orchestration
chat-error switch are always present. What a new launch opens comes only
from the per-agent choice (no saved choice opens a chat) plus the existing
support checks.

- One lookup, nativeChatPreferenceFor, keyed by agent id so host-registered
  agents read the same way; unreadable settings still open a terminal.
- A relayed desktop stamp (nativeChatDefault) maps onto the launched agent;
  an explicit surface still wins. Old phones' createSupport keeps admitting
  by the host's per-agent choice.
- settings.get stops publishing the retired switch keys; nothing in the
  repo reads them from a host.
- Startup chat sync and hydration run when some agent can open as a chat
  or the machine already holds chats.
- The retired key is stripped on load. The one-time upgrade tip from the
  chat upgrade is retired with its audience record; a new record, captured
  once from the raw profile, marks which existing profiles had Chat UI off.
- The window-side AI-button tab path, which only ran with the switch off,
  is deleted.

* Keep profiles that had Chat UI off on the terminal

Existing users who never turned Chat UI on would otherwise see new agent
launches open as chats, since an agent without a saved choice now opens as
a chat. The one-time load step that records the new audience also sets
every known agent to CLI for those profiles, in the same save and only
when the record was absent, overwriting saved chat choices the old switch
masked. Profiles that had Chat UI on and new profiles are untouched.

Browser profiles keep their own settings, so the web client does the same
once: a stored switch that is not on seeds CLI choices, and dropping the
key marks the step done.

Agents first seen after this step open as chats.

* Agents without a saved Chat | CLI choice open as their CLI

An agent with no saved choice now opens in the terminal for everyone,
including fresh installs and agents first seen later. The one-time load
step carries what launches opened while Chat UI was experimental: with
the switch on, every known agent without a saved choice is saved as
chat; with it off, chat choices the switch masked are saved as CLI.
Existing profiles join the launch tip audience whether the switch was on
or off. Browser profiles get the same carry from their saved key.

The startup chat restore and host agent list now run only when some
agent is saved as chat or the runtime holds chats.

* Chat UI is here: a one-time tip for profiles that upgraded

Profiles saved before Chat UI left Experimental see a "Chat UI is here"
tip once, on the first launch after updating. Fresh installs, unreadable
audience records and the web client never see it.

- Had Chat UI off: says agents can now open as a chat and that the
  terminal stays fully supported. "Use Chat UI" saves Chat for every
  agent Orca knows (the roster the load step carries), then closes;
  "Stay in terminal", close and Escape change nothing.
- Had Chat UI on: says Chat UI is now part of Orca and the terminal
  stays supported; one "Got it" closes without changes.
- Both link to Settings -> Agents. The visual is an animated miniature
  chat that sends a question, reads a file and draws a flow diagram,
  then fades as one and repeats; reduced motion shows the finished
  frame.
- The variant comes from main's once-decided audience record over a
  new onboarding IPC read; the startup gate waits for it.
- FeatureTipActions takes a secondary label; the frame takes a copy
  column class, used here so the buttons line up with the card's
  composer. Other tips are unchanged.
- Telemetry: chat_ui_feature_tip_shown and chat_ui_feature_tip_action.

* Preserve owned terminal launches and local chat choices

* Chat UI tip: translate the miniature, honor reduced motion mid-loop

- The miniature's conversation (tab title, prompt, reply, diagram and
  arrow labels) is translated in every locale; the composer, permission
  chip, working row and Read verb reuse the chat's own strings. File
  names, the /login route and the model name stay as written.
- The reply is one paragraph that wraps naturally; words (segmented per
  locale, so scripts without spaces still stream) reveal in turn.
  Diagram boxes size to their labels and arrow labels never widen the
  row.
- Turning reduced motion on mid-loop jumps to the finished still with
  no transitions.
- Telemetry records use_chat_ui only after the save succeeds and has a
  distinct stay_in_terminal action.
- The dialog renders its own title, so the duplicate catalog copy is
  gone; Use Chat UI writes the full roster without re-spreading saved
  choices.
- Buttons: the primary's focus ring meets the card's bottom edge.

* Clarify chat and terminal support

* Explain worker CLI integration timeout budget

* Use checked annotations for chat graduation test fixtures

* Store agent surface default separately from per-agent overrides

* Preserve explicit Chat intent across default changes

* Preserve current browser settings during host replies

* Correct browser settings factory and regression types

* Name exported launch fixture mock types and clarify agent defaults

* Preserve settings fallbacks and complete launch test lifecycles

* Check allocated tab identity before launch fixture interpolation

* Drop file links from the Chat UI tip copy

* Register combined integration project for compiler parity probes

* Use checked settings in the launch test fixture

* Settings → Agents: "Open agents as" Chat or Terminal tiles

A new top section in Settings → Agents sets this computer's default for
how agents open: two tiles, Chat ("Rich messages, visuals and images.")
and Terminal ("Each agent's own CLI."), each with a still preview. The
chat preview reuses the tip's copy and flow diagram; the terminal preview
draws Claude Code's interface in the user's terminal theme and font.

- Picking a tile writes only agentDefaultSurface, through the same queue
  as the per-agent Chat | CLI rows. The tiles show the saved default; an
  agent set on its own row keeps its choice and is not reflected up top.
- If any agent's own choice differs from the new default, one toast names
  them ("Claude and Codex stay in the terminal, as you set.") with "Set
  all to Chat" / "Set all to Terminal", which drops those choices so they
  follow the default. Only agents whose row offers Chat | CLI count. No
  toast when nothing differs, and never from the tip.
- "Choose per agent" scrolls to and focuses the Installed list.
- Shown for this computer only (not on a paired host's page); the web
  client gets it too. Searchable as "Open agents as".
- Copy in all locales; the tip's intro copy in other locales also drops
  "file links", matching English.

* Fix Chat UI settings navigation and acknowledged preference actions

* Keep the agent default surface controls in full Settings

* Keep the per-agent navigation button free of link underlining

* Use checked types and existing presentation primitives for Chat UI tips

* Preserve retired Chat preference data privately

* Align chat E2E fixtures and capture pane lifecycle evidence

* Use typed raw settings in retention contracts

* Fix Chat UI settings search types and localization catalogs

* Consolidate transcript diagnostic imports

* Keep setup-only dependency changes out of the branch

* Update dev education history expectation for Chat UI tip

* test: align chat fixtures with live pane and native menu contracts

* test: capture relay tab selection loss diagnostics

* test: wait for owned shells before synthetic chat fixtures

* test: preserve all-host visibility in SSH observer

* test: bind synthetic transcript fixtures before provider seeding

* test: assert selected chat owner after narrow image preview

* ci: allow fifth compiler project to complete comparison

* Drop 'keeps getting better' from the Chat UI tip's terminal line

* Trim the empty space above the Chat UI tip's visual

* Tighten the space above the Chat UI tip's flow diagram; undo the card resize

* Tighten the Chat UI tip's reply and diagram spacing

* Give the tip's flow diagram a little more room and shorten its tab bar

* Type the web-terminal fixture's chat map without an assertion

* Right-click the selection itself in the chat copy spec
2026-10-30 17:46:12 -07:00
OrcaWinandOrcaWin 12a7d4c13a feat(mobile): localization infrastructure and language setting (#35399)
* feat(mobile): add UI localization infrastructure

Mobile follows the phone's language (or an in-app choice under Settings > Appearance)
across the same 11 languages as desktop, switching live like the theme does.

- i18next with desktop's translate(key, fallback, options) call shape; catalogs in
  mobile/src/i18n/locales load lazily, English fallbacks stay inline
- Hermes lacks Intl.PluralRules: load the FormatJS polyfill with the 11 languages' rules
- OTA pages get the shell's language through an optional bridge init field
- iOS permission prompts localized; iOS and Android 13+ per-app language pickers
- verify:mobile-localization and a coverage ratchet run in lint, check:changed and CI

* fix(mobile): mount pages after the newest language request; tighten localization gates

- Wait for the latest page language activation, not a superseded one
- Keep literal fallbacks when a key also has a dynamic one
- Count headerTitle as visible copy; select the mobile check when the runtime catalog generator changes

* feat(mobile): repaint themed components on language changes

Components that read the theme already subscribe for repaint; a language switch
repaints them too, so labels built by helpers during render follow it. RPC
recordings load the real i18next and JSON catalogs.

* fix(mobile): scope the translate() gate to render bodies and memos; prune stale keys on sync

Handlers and effects may call translate() when they run. sync:mobile-localization now
removes keys no code references from every catalog.

* fix(mobile): use node: imports in the locale config plugin; pass uiLocale in bridge hook test

* chore(mobile): refresh the localization coverage baseline

* fix(mobile): follow render callbacks in the translate() gate; keep used plural siblings on prune

Also let anonymous default-exported screens count as components, flag any plural
family a locale started, and mark JSON modules as ES modules in the recording loader.

* fix(mobile): treat async and named local callbacks as handlers in the translate() gate

* chore(mobile): refresh the localization coverage baseline

* chore(mobile): refresh the localization coverage baseline

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:14:05 -07:00
OrcaWinandOrcaWin fe3eb45b85 feat(i18n): add German UI language (#34917)
* feat(i18n): add German UI language

Register German (de) as a built-in UI language alongside en, zh, zh-Hant,
ko, ja, es, fr, pt, ru and tr: language setting, system-locale detection
(de, de-DE, de-AT, de-CH, de_DE.UTF-8), renderer and main-process lazy
catalogs, Settings picker label in every catalog, the "Sprache" settings
search keyword, onboarding picker, docs and a German glossary and style
guide (config/i18n-german.md).

de.json covers every en.json key except the sparse-policy entries that must
fall back to English (status-bar credit balance copy and the incomplete goal
change notice). Tests that used de-DE as the unsupported system language now
use it-IT.

The catalog is machine-translated, reviewed by two independent passes with
arbitrated fixes, and swept for terminology consistency.

* feat(i18n): translate German strings added on main

Translate the 158 keys main added since the branch point (WSL project move,
diff size limits and others), reviewed by two passes like the rest of the
catalog, and drop the 5 keys main retired.

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 03:21:12 -07:00
4b1967bdd8 feat(i18n): add Turkish UI language (#34718)
* feat(i18n): add Turkish UI language

Register Turkish (tr) as a built-in UI language alongside en, zh, ko, ja,
es, fr and pt: language setting, system-locale detection, renderer and
main-process lazy catalogs, Settings picker label in every catalog,
Settings search keyword, onboarding picker, docs, README link and a
Turkish style glossary (config/i18n-turkish.md).

tr.json comes from the community Turkish catalog (#22200, refreshed in
#31316), reconciled with the current en.json: keys retired from en.json,
entries whose English source changed since the refresh, and entries with
placeholder mismatches are dropped and fall back to English until the
next translation pass.

Supersedes #31316.

Co-authored-by: Uğur Pala <mail@ugurpala.com>
Co-authored-by: mert <mmerttpz@gmail.com>
Co-authored-by: Mehmet Efe Aytaş <mehmetefeaytas@icloud.com>

* feat(i18n): complete Turkish catalog

Translate the 1,432 keys tr.json was missing, restore the count placeholder
in six Turkish singular forms, and order the catalog like en.json.

* fix(i18n): apply Turkish translation review

Correct 32 mistranslations (wrong meaning, translated command names and
example paths, swapped placeholders) and 525 glossary and grammar issues
that two independent review passes both flagged.

* fix(i18n): Turkish review fixes and dotted-I settings search

Fold U+0307 from lowercased Turkish İ so settings search matches plain-i
queries, fix sampled Turkish meaning/terminology issues, and align the
glossary casing rule with the catalog.

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Co-authored-by: Uğur Pala <mail@ugurpala.com>
Co-authored-by: mert <mmerttpz@gmail.com>
Co-authored-by: Mehmet Efe Aytaş <mehmetefeaytas@icloud.com>
2026-10-27 23:46:17 -07:00
Neil 5dfaee07b1 fix(ci): localize the chat font family search keywords (#33715)
#33687 added English-only search keywords and a code sample to the chat font
setting, which fails main's localization coverage check.
2026-10-25 17:54:29 -07:00
Neil a30d4f4f28 feat(devex): component fixtures with headless screenshots for fast UI checks (#33406)
* feat(devex): component fixtures with headless screenshots for fast UI checks

Colocated *.fixture.tsx files export named fixtures (render + optional store
seed, setup, interact, width). A dev-only Vite entry (vite.fixtures.config.ts,
extending vite.web.config.ts) renders one fixture in isolation with the real
I18nProvider, TooltipProvider, theme class, default-seeded store, and the web
client's preload bridge (installWebPreloadApi) as window.api.

`pnpm fixtures:shot <id|glob> [--theme dark|light|both]` starts or reuses a
detached server (Vite + one headless Chromium) and writes PNGs to
.cache/fixtures/. A warm page re-renders in place (~100ms/shot) and reloads
only after source changes. A stdio MCP server (registered in .mcp.json)
exposes list_fixtures and screenshot_fixture.

Fixtures load only through import.meta.glob in the fixture entry, which is
not a production build input; oxlint rejects static imports of *.fixture.

* Keep fixture config and agent config inside reviewed root entries

* Baseline the fixture page's default-settings seed in the focus-read ratchet

* docs(agents): shorten fixtures pointer

* Allowlist the dev-only fixture explorer's labels in localization coverage
2026-10-25 00:23:32 -07:00
Jinjing a53c2a2a72 Add onboarding language selection (#31784)
* Add onboarding language selection and system locale detection

- Detect and synchronize native/browser language preferences safely
- Load catalogs before rendering onboarding and support recovery
- Let users choose a supported language or request another language

* Add onboarding language experiment cohorts and detection recovery

* Stabilize onboarding language detection tests

* Test persisted onboarding language cohort behavior
2026-10-21 19:43:22 -07:00
Jinjing e02adc5320 Add translations for terminal shell settings (#25418)
* Add translations for terminal shell settings and search

Wrap Terminal Pane shell configuration strings and terminal search keywords with translation calls to enable localization across supported languages. Add translated strings to all locale files and update the localization coverage allowlist to reflect properly translated content.

* fix translation
2026-10-04 23:01:02 -07:00
Neil 4feaaf5c5c feat(terminal): configure interactive Unix shell arguments (#21904)
* feat(terminal): configure interactive Unix shell args

* fix(settings): clarify Unix shell argument defaults

* fix(settings): improve Unix shell argument guidance

* fix(settings): simplify shell argument guidance

* fix(settings): clarify empty shell args

* fix(settings): explain empty shell args

* feat(settings): make shell argument modes explicit

* fix(settings): keep no args inside custom mode

* fix(terminal): apply configured shell args on the renderer spawn path

The renderer's pty:spawn handler builds options in ipc/spawn-options, not
the runtime controller, so the configured profile never reached a terminal
pane. The local launch plan also dropped the args whenever shellOverride
was set -- which the spawn path always fills from terminalDefaultShell.

Both spawn paths now share one resolver.

* chore(i18n): allowlist the new terminal shell argument strings

Matches how the sibling Terminal shell settings strings are already handled.
2026-09-21 01:35:58 -07:00
Neil 52b53c5bda feat(settings): choose the default terminal shell (#21085)
* feat(settings): configure default terminal shell

* test(terminal): cover default shell selection

* fix(terminal): apply shell setting to daemon PTYs

* test(terminal): provide PTY dimensions in shell cases

* fix(settings): clarify default shell behavior

* feat(settings): make shell choice explicit

* fix(settings): keep shell control testable without preload

* fix(settings): slim terminal shell control

* chore(i18n): allow terminal shell setting labels

* chore(i18n): mark dynamic shell label
2026-09-16 15:50:53 -07:00
Neil 8c1a28d39c fix(i18n): repair French locale drift breaking static analysis (#18550)
The French UI locale landed with two catalog drifts that fail `static
analysis` on every PR in the repo:

- `fr.json` carried 15 keys absent from `en.json` (and from every other
  locale), so `verify:localization-catalog` rejected it. They are stale
  entries generated against an older `en.json` snapshot; none is
  referenced anywhere in the source.
- `settings.appearance.language.french` had no call site supplying a
  literal default, which promotes it to a boot-bundle-required entry
  that `en-runtime-required.json` does not ship, so
  `verify:localization-runtime-catalog` rejected it.

Registering the key in settings search alongside its siblings fixes the
runtime-catalog failure at its source and closes the real gap the drift
exposed: French was the only supported language not findable in settings
search.

`en-runtime-required.json` is deliberately untouched — the sync script
regenerates it wholesale and would drop 925 entries the check itself
documents as harmless.
2026-09-03 18:24:43 -07:00
Jinjing cda2280d63 Show all automations (#16532)
* Add all-host automations with scoped ownership and multi-authority suppo

Enable automations to run on multiple hosts (SSH targets and local) with
owner-fenced mutations, scoped list queries per host, and conflict
resolution. Introduces desktop and runtime authorities as distinct
automation storage owners, with per-host caching, invalidation, and
retry scheduling on the renderer. Captures registration generations for
SSH hosts to survive re-adoption. Adds CLI support for destination
selection and conflict recovery.

* Filter automation create projects by destination host

Only offer projects available on the selected destination, preventing
the mismatches that would fail at submit time. Auto-adjust the project
selection if it becomes unavailable when the destination changes.

* Add runtime storage authority support for automations

- Support both runtime and desktop as automation storage authorities
- Make owner preconditions optional for legacy-client compatibility
- Cache automation list projections to improve performance
- Add per-row repo/worktree resolution for cross-authority collisions
- Extend automation.list RPC to always include owner metadata

* Replace child_process.execFile with runProcess for external automations

- Migrate external-manager to use cross-platform runProcess wrapper per child-process safety policy
- Abstract electron app/ipcMain APIs in orca-runtime via environment accessors
- Install fake app environment in automation tests for consistent setup
- Reorganize imports to use specific module paths (ssh-target-registry, agent-detection, browser-error)
- Remove external-manager from child-process import allowlists (no longer violates direct import)

* Unify desktop automation CRUD onto the local runtime RPC surface

The desktop authority now speaks the same automation.* RPC contract as
remote runtimes, via callRuntimeRpc({kind:'local'}) -> runtime:call ->
the shared RpcDispatcher. The automations:list/listRuns/create/update/
delete/runNow IPC arms, their preload members, and every renderer
desktop-vs-runtime transport fork are retired; the runtime methods are
the single implementation of scoped lists, owner fencing, and change
publication for both transports (mobile clients already exercised them).

The desktop probe scheduler's priority lease survives the move as an
AutomationService hook the IPC registration installs and the runtime
methods take, so Orca's own automation traffic still parks queued
external-manager probes.

External-manager scope arms and dispatch-loop plumbing stay on IPC by
design; automation change events keep their existing channels (renderer
ingestion already converges them by authority).

* Remove automation ghost SSH tombstone scanning

This functionality for synthesizing tombstones for automation-referenced SSH
targets is no longer needed as part of the automation system refactoring.

* Refuse orphan automations at dispatch time, not migration time

Remove migration-time disabling of orphan automations and the `enabledDecidedBy` field. Dispatch now refuses orphans at runtime instead, simplifying state management and UI. Orphans are left unstamped and enabled; dispatch refuses to run them via `resolveAutomationRunTarget`.

* Show all automations in flat table with unified filter menu

- Replace host picker component with comprehensive Filters menu supporting status, last run, agent, and host filters
- Flatten automation list layout to single table instead of host-grouped sections
- Add Host column to display execution host for each automation
- Display active filters as removable pills below toolbar
- Delete unused AutomationHostPicker* components

* Add automation owner fencing and destination validation

- New AUTOMATION_OWNER_FENCING_RUNTIME_CAPABILITY for owner preconditions; legacy clients get owner metadata snapshotted at RPC boundary for compatibility
- Editor captures and revalidates automation destination before save, preventing silent retargeting if SSH infrastructure changes mid-edit
- SSH target types now isolate renderer-authored fields; generation is server-owned and stripped by IPC handlers

* Route automation recovery actions to the origin host

When an automation action fails due to owner fencing, recovery verbs
("Update server", "Reconnect") must run on the host where the refusal
originated: the row's captured owner for row operations, or the
destination the create dialog captured, not the list's filtered host.

* Remove external manager scope limitation notices

Consolidate create destination eligibility checks with a unified predicate
and fix the bug where desktop repo IDs could be sent to runtime hosts where
they cannot resolve.

* Persist only store-derived automation contexts, not client-perspective o

Store contexts must never be based on client-provided runContext or sourceContext
values—clients speak a different perspective (e.g., 'runtime:<id>' for host IDs
they assign), and persisting those makes the store projection orphan automations
it actually owns. Derived contexts now take precedence in create and update paths,
with explicit null still honored to clear a value. Tests verify this by simulating
drift after storage and confirming that moves re-derive while toggles preserve.
2026-08-26 09:50:12 -07:00
NeilandOrca 33e8d89d48 [perf-remote] perf(renderer): park hidden remote browser screencasts (#13608)
* perf(renderer): park hidden remote browser screencasts

* test(renderer): pin stale-visibility term and parked-unmount teardown

Restores the WHY behind the '|| isDocumentVisibilityProvenStale()' term the
emulator-module dedupe dropped, and pins it plus the close-tab-while-parked
path with tests. Extracts the lifecycle harness so the spec stays under
max-lines without a suppression.

Co-authored-by: Orca <help@stably.ai>

* fix(ci): exclude test-support modules from the localization audit

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-08-11 01:27:02 -07:00
Neil 600b0b1c15 refactor(renderer): split WorktreeCard (#13715) 2026-08-10 18:45:11 -07:00
f2d62a7887 fix(i18n): localize the status bar Resource Manager tooltip and remote-host count (#12478)
* fix(i18n): localize the status bar Resource Manager tooltip and remote-host count

The Resource Manager tooltip/aria label and the SSH segment's host count were
assembled from bare English literals inside helper functions, so they stayed
English under every non-English UI language while the labels around them
translated. Route them through the catalog with _one/_other plural keys and
whole-line messages (locales reorder and repunctuate the summary), and add
en/es/ja/ko/zh entries.

Root cause of the miss: audit-localization-coverage bailed on any ancestor
binary expression whose operator was not `+`, which hid every string under a
`cond && <JSX/>` guard or a `?? 'fallback'` — including this segment's
'Connecting…'. Only comparison operands are code, so keep `??`, `||` and
`&&` walking, and localize the four real strings that surfaced.

Co-authored-by: Orca <help@stably.ai>

* fix(status-bar): flag the space-scan tooltip row instead of matching its English text

The tooltip tinted a row with `line === 'Space scan ready'`, so routing that
copy through the catalog silently dropped the tint in every translated build.
Return `{ text, emphasized }` and let the segment read the flag.

Adopted from #12439 by @smwbev.

Co-authored-by: Evgenii <smwbev@users.noreply.github.com>

Co-authored-by: Orca <help@stably.ai>

* fix(status-bar): key Resource Manager tooltip rows by role instead of array index

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-08-06 19:14:15 -07:00
Henry Su abcdc04f6b fix(ci): mirror missing lint steps in PR workflow (#10601) (#10623)
Reviewed with an independent reproduction. Added the allowlist entry that unblocked verify:localization-coverage on main, the 4th drifted step, and a parity gate that fails when pnpm lint's chain contains a script absent from pr.yml.
2026-07-27 16:26:43 -07:00
JinjingandOrca 4c2bb508c3 feat(settings): make Language setting findable by native-language search terms (#9967)
The Language setting's native word (语言 / 언어 / 言語 / Idioma) only reached
settings search via the localized title in that word's own UI locale — so a
Chinese speaker on the default English UI could not find it by typing 语言.

Always-index the native word for 'language' in every supported language (plus
the previously-omitted Spanish native name Español), so speakers can locate and
switch to their language from any starting locale. Native words are
locale-invariant constants, so they are plain keyword literals with reviewed
localization-coverage allowlist entries.

Co-authored-by: Orca <help@stably.ai>
2026-07-22 11:52:49 -07:00
OrcaWin b232df732b fix(terminal): make remote agent sessions host-authoritative (#9687) 2026-07-21 20:51:28 -07:00
Jinwoo HongandOrca 9369708f6b Add English localization infrastructure (#4995)
Co-authored-by: Orca <help@stably.ai>
2026-06-09 10:43:04 -07:00