Introduce the platform adapter layer; extract window context behind it
Template tests / tests (pull_request) Failing after 33s
Template tests / tests (pull_request) Failing after 33s
Phase 3 groundwork of the improvement plan (PR 7 of the sequence). The Linux
work is a platform rewrite, so this first establishes the interface boundary
and moves an OS-specific piece behind it with Windows behavior preserved — no
new process.platform branches in shared code.
- app/platform/index.js is the single factory that selects a platform
implementation; shared code asks it for adapters and never inspects
process.platform itself.
- app/platform/interfaces.js documents the adapter contracts
(WindowContextProvider, ClickSource, PowerPolicy) and the explicit click-
source vocabulary.
- Extracted the foreground-window/element detection into per-OS adapters,
verbatim from text-intel.js:
app/platform/windows/window-context.js (PowerShell UIAutomation)
app/platform/linux/window-context.js (xprop)
app/platform/darwin/window-context.js (AppleScript)
text-intel.js now delegates to the injected provider and its three
platform-branching methods (and the now-dead child_process import) are gone.
- app/platform/linux/diagnostics.js detects session type, portal/PipeWire,
xinput, readable input devices, and the resulting click/screen-capture
profile, returning actionable messages for the UI. Exposed via a new
platform:capabilities IPC + preload method.
This is behavior-preserving: the Windows/macOS/Linux window-context code is
the same, just relocated behind the factory, and the capture pipeline is
untouched.
Tests: platform selection for every OS, provider validity + null-object for
unsupported OS, the shared service delegating to an injected provider, Linux
capability detection (x11/xinput, Wayland-without-PipeWire messaging, no-click
fallback, evdev), the capability facade, and a guard that text-intel no longer
branches on process.platform. 268 unit tests pass; startup smoke passes and
the click self-test is unchanged (stream source, markers 3/3, burst 8/8).
Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Platform adapter interfaces (documentation + light runtime shape checks).
|
||||
*
|
||||
* The platform-neutral capture/text-intel code consumes these interfaces and
|
||||
* never inspects `process.platform` itself. `app/platform/index.js` is the
|
||||
* only module that selects a concrete implementation. New OS support is a new
|
||||
* set of files under `app/platform/<os>/`, not more conditionals inside the
|
||||
* shared code.
|
||||
*
|
||||
* ---------------------------------------------------------------------------
|
||||
* WindowContextProvider
|
||||
* collect(osPoint?: {x,y}) -> Promise<{
|
||||
* appName, windowTitle,
|
||||
* elementLabel?, elementRole?, elementClass?, elementValue?
|
||||
* }>
|
||||
* Best-effort foreground window / clicked-element context. Never throws;
|
||||
* returns {} (or partial) when unavailable.
|
||||
*
|
||||
* ClickSource (runtime capture — implemented incrementally per platform)
|
||||
* describe() -> { source, coordinates: boolean, keyboard: boolean }
|
||||
* source ∈ 'windows-hook' | 'x11' | 'evdev-x11' | 'evdev-wayland' |
|
||||
* 'wayland-portal' | 'hotkey' | 'interval' | 'unavailable'
|
||||
*
|
||||
* PowerPolicy
|
||||
* setRecording(recording: boolean) -> void
|
||||
* Holds/releases OS power + throttling state for the recording lifecycle.
|
||||
*
|
||||
* PlatformCapabilities (from index.detectCapabilities())
|
||||
* { os, sessionType, isWayland, hasXinput, canSandbox, ... }
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
// Interface names, exported so adapters and tests can reference a single
|
||||
// source of truth for the contract identifiers.
|
||||
const INTERFACES = Object.freeze([
|
||||
'WindowContextProvider',
|
||||
'ClickSource',
|
||||
'PowerPolicy',
|
||||
]);
|
||||
|
||||
const CLICK_SOURCES = Object.freeze([
|
||||
'windows-hook',
|
||||
'x11',
|
||||
'evdev-x11',
|
||||
'evdev-wayland',
|
||||
'wayland-portal',
|
||||
'hotkey',
|
||||
'interval',
|
||||
'unavailable',
|
||||
]);
|
||||
|
||||
/** Assert a value looks like a WindowContextProvider (has async collect()). */
|
||||
function assertWindowContextProvider(provider) {
|
||||
if (!provider || typeof provider.collect !== 'function') {
|
||||
throw new Error('platform: WindowContextProvider must implement collect()');
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
module.exports = { INTERFACES, CLICK_SOURCES, assertWindowContextProvider };
|
||||
Reference in New Issue
Block a user