mirror of
https://github.com/stablyai/orca.git
synced 2026-10-28 08:02:54 +00:00
Merge remote-tracking branch 'origin/main' into brennanb2025/contextual-feature-tours
# Conflicts: # docs/reference/feature-discovery-interaction-tracking.md # src/main/persistence.test.ts # src/main/persistence.ts # src/main/runtime/rpc/dispatcher-feature-interactions.test.ts # src/main/runtime/rpc/dispatcher.ts # src/main/runtime/rpc/methods/client-ui.test.ts # src/main/runtime/rpc/methods/client-ui.ts # src/renderer/src/App.tsx # src/renderer/src/components/automations/AutomationsPage.tsx # src/renderer/src/components/browser-pane/BrowserPane.tsx # src/renderer/src/components/onboarding/use-onboarding-flow-persistence.ts # src/renderer/src/components/right-sidebar/useCreatePullRequestDialogFields.ts # src/renderer/src/components/settings/NotificationsPane.tsx # src/renderer/src/components/sidebar/AddRepoSetupStep.tsx # src/renderer/src/store/slices/browser.ts # src/renderer/src/store/slices/diffComments.ts # src/renderer/src/store/slices/tabs.ts # src/renderer/src/store/slices/terminals.ts # src/renderer/src/store/slices/ui.test.ts # src/renderer/src/store/slices/ui.ts # src/renderer/src/store/slices/workspace-space.ts # src/renderer/src/web/web-preload-api.test.ts # src/shared/constants.ts # src/shared/feature-interactions.test.ts # src/shared/feature-interactions.ts # src/shared/types.ts
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Feature Discovery Interaction Tracking
|
||||
|
||||
This document defines local feature-interaction state used to decide whether Orca should still teach a feature with a contextual tour or feature tip.
|
||||
This document defines local feature-interaction state used to decide whether Orca should still teach a feature with an education surface such as a tour or feature tip.
|
||||
|
||||
## Decision
|
||||
|
||||
@@ -53,9 +53,9 @@ Do not upload this state as broad analytics. Product analytics should continue t
|
||||
| Agent Orchestration | `agent-orchestration` | A successful `orchestration.*` runtime method is handled. | Suppress future usage tips once an agent/runtime has actually used orchestration. |
|
||||
| Notifications | `notifications` | Notifications are enabled in onboarding/settings or a test notification is sent. | Suppress future notification setup tips. |
|
||||
|
||||
## Existing Contextual Tour Features
|
||||
## Surface-Level Features
|
||||
|
||||
The branch already records surface-level interactions for the current contextual tours:
|
||||
Orca also records surface-level interactions for feature areas where opening the surface is itself a meaningful discovery signal:
|
||||
|
||||
- `workspace-board`: workspace board opened
|
||||
- `browser`: non-blank browser page viewed
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# Keyboard Layout Shortcut Dispatch
|
||||
|
||||
## Problem
|
||||
|
||||
Keyboard shortcuts must follow the user's active keyboard layout. A shortcut like `Cmd+W`
|
||||
means "Command plus the key that produces `w`", not "Command plus the physical key labeled
|
||||
W on a US keyboard." Physical-position matching breaks Dvorak, Colemak, AZERTY, JIS, and
|
||||
other non-US layouts, and it also makes user keybinding overrides impossible to reason about.
|
||||
|
||||
## Decision
|
||||
|
||||
Orca app shortcuts dispatch by logical key by default.
|
||||
|
||||
The shared keybinding registry in `src/shared/keybindings.ts` is the source of truth for
|
||||
app commands, configurable commands, shortcut recording, labels, conflict detection, browser
|
||||
guest forwarding, and terminal pane commands. Code handling a user-facing app command must
|
||||
call `keybindingMatchesAction`, `keybindingMatchesInput`, or a policy function built on those
|
||||
helpers.
|
||||
|
||||
Physical `KeyboardEvent.code` may only decide a shortcut when the key is layout-invariant or
|
||||
the platform cannot provide a real logical key.
|
||||
|
||||
Allowed physical-code uses:
|
||||
|
||||
- Modifier key release tracking, such as left/right Control release for held `Ctrl+Tab`.
|
||||
- Layout-invariant keys, such as arrows, Tab, Enter, Escape, Backspace, Delete, Insert,
|
||||
PageUp, PageDown, and explicit numpad bindings.
|
||||
- Dead, unidentified, or missing logical keys where `KeyboardEvent.key` cannot describe the
|
||||
produced key.
|
||||
- Terminal byte encoding where the intent is a physical terminal escape sequence rather than
|
||||
an Orca command.
|
||||
|
||||
Disallowed physical-code uses:
|
||||
|
||||
- Letter shortcuts for app actions.
|
||||
- Punctuation shortcuts for app actions when `KeyboardEvent.key` reports the produced
|
||||
punctuation.
|
||||
- Clipboard shortcuts that are exposed as app or terminal UI commands.
|
||||
- Hardcoded undo/redo/new/close/copy/paste handling outside the shared registry.
|
||||
|
||||
## Terminal Boundary
|
||||
|
||||
Terminal handling has two different jobs:
|
||||
|
||||
1. Orca commands that act on terminal UI, such as copy selection, paste, search, clear,
|
||||
pane focus, split, and close. These are app shortcuts and must be layout-aware.
|
||||
2. Bytes sent to the shell, such as readline escapes and Option-as-Alt sequences. These may
|
||||
use physical key positions when terminal compatibility requires it.
|
||||
|
||||
This boundary is intentional. It lets non-US layouts use Orca commands naturally while
|
||||
preserving shell behavior where users expect physical terminal-control sequences.
|
||||
|
||||
## Regression Requirements
|
||||
|
||||
Shortcut tests must cover both directions of a non-QWERTY swap:
|
||||
|
||||
- The key that produces the configured logical character must match, even if its physical code
|
||||
differs.
|
||||
- The physical US key must not match when it produces a different logical character.
|
||||
|
||||
Tests must also cover intentional exceptions:
|
||||
|
||||
- Dead or missing key fallback.
|
||||
- Shifted punctuation aliases.
|
||||
- Numpad-specific bindings.
|
||||
- Terminal byte-encoding paths that intentionally use physical codes.
|
||||
@@ -0,0 +1,74 @@
|
||||
# Memory Leak Audit
|
||||
|
||||
Started: 2026-05-26 18:36 PDT
|
||||
|
||||
Objective: scan the entire Orca codebase for memory leaks, fix confirmed leaks, and keep durable coverage notes until the repository-wide scan is complete.
|
||||
|
||||
## Codebase Inventory
|
||||
|
||||
Tracked code files, from `git ls-files`:
|
||||
|
||||
| Bucket | Files | Status |
|
||||
| ----------------- | ----: | ------------------------------------------- |
|
||||
| `src/renderer` | 1534 | Checked |
|
||||
| `src/main` | 838 | Checked |
|
||||
| `src/shared` | 220 | Checked |
|
||||
| `mobile/src` | 94 | Checked |
|
||||
| `tests/e2e` | 71 | Checked |
|
||||
| `src/relay` | 65 | Checked |
|
||||
| `src/cli` | 64 | Checked |
|
||||
| `config/scripts` | 27 | Checked |
|
||||
| `mobile/app` | 16 | Checked |
|
||||
| `other-code` | 13 | Checked |
|
||||
| `mobile/packages` | 12 | Checked |
|
||||
| `native` | 6 | Checked |
|
||||
| `src/preload` | 6 | Checked by IPC subscription heuristic |
|
||||
| Total | 2966 | Repository-wide risk-pattern scan completed |
|
||||
|
||||
## Scan Log
|
||||
|
||||
- 2026-05-26: Loaded `$memory-leak-audit` checklist and built an initial inventory from `git ls-files`.
|
||||
- 2026-05-26: Ran a broad listener/timer/observer search across `src`, `mobile`, `tests`, and `config`.
|
||||
- 2026-05-26: Ran a React `useEffect` cleanup heuristic over 1845 TS/TSX files. Manual follow-up identified one confirmed issue in `src/renderer/src/components/editor/PdfViewer.tsx`: `EventBus.on('scalechanging', ...)` had no matching `off`.
|
||||
- 2026-05-26: Ran a preload IPC heuristic. `src/preload/index.ts` and `src/preload/runtime-environment-subscriptions.ts` had apparent cleanup for their `ipcRenderer.on` subscriptions.
|
||||
- 2026-05-26: Ran an `ipcMain.on` cleanup heuristic over `src/main`. The only unpaired hit was `src/main/ipc/session.ts`, which is a process-lifetime registration via `registerSessionHandlers`.
|
||||
- 2026-05-26: Manually reviewed main-process interval/service candidates. Confirmed `src/main/speech/stt-service.ts` retained a timed-out, terminated speech worker in service state until idle teardown.
|
||||
- 2026-05-26: Ran a Promise/EventEmitter heuristic over main, relay, and CLI code. Confirmed `src/main/ssh/ssh-connection.ts` left ssh2 startup listeners attached after a successful long-lived connection.
|
||||
- 2026-05-26: Confirmed `src/main/browser/cdp-ws-proxy.ts` retained its startup HTTP server `error` listener after successful bind.
|
||||
- 2026-05-26: Continued Promise/EventEmitter follow-up in daemon startup paths. Confirmed startup listeners were retained after successful bind/readiness in `src/main/daemon/daemon-server.ts`, `src/main/daemon/daemon-init.ts`, and `src/main/daemon/production-launcher.ts`.
|
||||
- 2026-05-26: Reviewed BrowserWindow/session listeners. Confirmed `src/main/window/attach-main-window-services.ts` stacked a persistent browser-session `will-download` listener on every main-window services attach.
|
||||
- 2026-05-26: Reviewed browser-session profile lifecycle. Confirmed deleted isolated/imported profiles left partition policy callbacks/listeners and configured-partition bookkeeping behind in `src/main/browser/browser-session-registry.ts`.
|
||||
- 2026-05-26: Reviewed mobile RPC subscriptions. Confirmed `mobile/src/notifications/mobile-notifications.ts` retained a local streaming callback when notification subscription cleanup ran before the desktop returned `ready`.
|
||||
- 2026-05-26: Reviewed speech model extraction timers. Confirmed `src/main/speech/model-manager.ts` left the abort polling interval alive when extraction abort/timeout rejected before the child emitted `close` or `error`.
|
||||
- 2026-05-26: Manually followed up renderer high-risk surfaces from the broad scan: pane manager, browser webviews, terminal pane lifecycle, editor integrations, sidebar/global document listeners, observers, and shared clocks. Remaining hits had cleanup, were process-lifetime globals, or were element-owned listeners that are collected with their DOM nodes.
|
||||
- 2026-05-26: Manually followed up main-process long-lived services from the broad scan: runtime RPC, SSH services, speech worker/model manager, rate-limit polling, filesystem watchers, BrowserWindow-scoped IPC/listeners, browser-session handlers, daemon startup, and relay-backed flows.
|
||||
- 2026-05-26: Checked mobile React Native subscriptions, WebView injected listeners, RPC subscription teardown, repeated polling intervals, and app/session screens. Confirmed one notifications subscription cleanup issue and no additional unpaired repeated-mount listener leaks.
|
||||
- 2026-05-26: Checked `src/shared`, `src/relay`, `src/cli`, `config/scripts`, `tests/e2e`, `mobile/packages`, and native computer-use runtimes for listener/timer/socket/watch patterns. Follow-up found existing cleanup or process/test-lifetime ownership.
|
||||
|
||||
## Confirmed Fixes
|
||||
|
||||
- `src/renderer/src/components/editor/PdfViewer.tsx`: unregister the pdf.js `scalechanging` listener on cleanup to avoid retaining stale component state after repeated PDF opens.
|
||||
- `src/main/speech/stt-service.ts`: when dictation stop times out, remove worker listeners, terminate the worker, and clear the warm-worker slot so later dictation cannot retain or reuse a dead worker.
|
||||
- `src/main/ssh/ssh-connection.ts`: remove ssh2 startup `ready`/`error` listeners once the connection resolves or rejects; steady-state disconnect listeners remain scoped to the live connection.
|
||||
- `src/main/browser/cdp-ws-proxy.ts`: remove the startup server `error` listener after the proxy binds so the resolved start promise closure is not retained for the proxy lifetime.
|
||||
- `src/main/daemon/daemon-server.ts`: remove the startup server `error` listener after the daemon socket binds.
|
||||
- `src/main/daemon/daemon-init.ts`: remove detached daemon child-process startup listeners after IPC readiness or startup failure.
|
||||
- `src/main/daemon/production-launcher.ts`: remove detached daemon child-process startup listeners after IPC readiness or startup failure.
|
||||
- `src/main/window/attach-main-window-services.ts`: replace the named persistent browser-session `will-download` handler before registering it so window re-attach cannot stack handlers.
|
||||
- `src/main/browser/browser-session-registry.ts`: clear deleted profile partition permission/display-media callbacks, remove the download listener, and drop configured-partition bookkeeping.
|
||||
- `mobile/src/notifications/mobile-notifications.ts`: always drop the local notification stream on cleanup, even if the desktop has not returned a subscription id yet.
|
||||
- `src/main/speech/model-manager.ts`: clear extraction timeout/abort pollers and remove child listeners directly on abort/timeout rejection, instead of depending on a later child `close`.
|
||||
|
||||
## Validation
|
||||
|
||||
- Passed: `pnpm vitest run --config config/vitest.config.ts src/main/speech/stt-service.test.ts src/main/speech/model-manager.test.ts src/main/ssh/ssh-connection.test.ts src/main/browser/cdp-ws-proxy.test.ts src/main/daemon/daemon-server.test.ts src/main/daemon/production-launcher.test.ts src/main/daemon/daemon-init.test.ts src/main/window/attach-main-window-services.test.ts src/main/browser/browser-session-registry.test.ts src/main/browser/browser-session-registry.persistence.test.ts` (10 files, 128 tests).
|
||||
- Passed: `pnpm run typecheck:node`.
|
||||
- Passed: `pnpm run typecheck:web`.
|
||||
- Passed: focused `pnpm exec oxlint` over changed TypeScript files.
|
||||
- Passed after final import cleanup: `pnpm vitest run --config config/vitest.config.ts src/main/daemon/daemon-server.test.ts src/main/daemon/production-launcher.test.ts`.
|
||||
- Passed: `git diff --check`.
|
||||
- Attempted: `./node_modules/.bin/vitest run mobile/src/notifications/mobile-notifications.test.ts`; blocked in this workspace because mobile dependencies are not installed (`expo/tsconfig.base` cannot be resolved). The mobile test file is included for the mobile package test environment.
|
||||
|
||||
## Residual Risk
|
||||
|
||||
- This was a repository-wide static/manual memory-leak audit of listener, timer, observer, worker, socket, watcher, subscription, and resource-pool patterns. It does not replace heap-snapshot profiling under a long interactive session, but no further confirmed leaks were found in the scanned patterns.
|
||||
Reference in New Issue
Block a user