mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 08:02:28 +00:00
* fix(mobile): decide terminal preedit from the marked-text range, not a script table The live terminal capture field decided what to withhold from the PTY with a Unicode-block allowlist (Hangul jamo and syllables) and held exactly one trailing code point. Kana and kanji are not in the table, so a Japanese reading streamed to the PTY one fragment at a time and was repaired afterwards with DEL bytes (#7427). A code-point table cannot work, and the counterexample is not exotic: Chinese pinyin preedit is plain ASCII, and a Japanese romaji reading is one code point on the first keystroke and three on the fourth. Preedit is a property of the FIELD, not of the characters in it, so the only signal that identifies it is the text system's marked-text range. That is what a reference terminal implementation uses on every platform it supports - `hasMarkedText` there, the input-method context's composing state elsewhere - and neither one classifies code points anywhere in the input path. So the mirror now takes the marked-text report per change and holds the whole preedit region, whatever its length or script: - Subscribe the capture field to `onChange`, not `onChangeText`; only the raw native event carries the report at all. - A reported preedit is held entire and is never committed by the settle timer, because preedit is not text yet. Explicit boundaries still flush it. - `isTerminalLiveHangulCodePoint` and its four ranges are deleted. iOS reports the range but React Native drops it before JS, so the pinned patch forwards `markedTextRange` into the change payload. It is three hunks and it compiles because the app already sets `buildReactNativeFromSource` for iOS. The same idea was proposed in #11450, which is where the patch comes from. Android has no marked-text report in React Native at all, and a Kotlin patch would not help: Android consumes the prebuilt react-android artifact, so node_modules sources are never compiled. Until the report exists there, the fallback holds the trailing non-ASCII run. It enumerates nothing, it covers kana, kanji and Hangul, and ASCII keeps its zero-latency echo - but it cannot see an ASCII preedit, so Chinese pinyin on Android still leaks its reading. Only a report fixes that. Not-tested: no physical device or emulator was available, so no real IME drove this path. Japanese, Chinese and Korean composition are covered at the model and hook level only, and the iOS patch has not been compiled. Co-authored-by: Brennan Benson <brennanb2025@users.noreply.github.com> * fix(mobile): bound the fallback hold to text the pty has not received The no-report branch walked the trailing non-ASCII run over the whole field and ignored stableLength, unlike the reported branch directly above it. So after a settle-timer commit the next keystroke re-held everything already delivered and the caller erased it with DEL and retyped it — a nine-character Cyrillic word cost a DEL per already-sent character, and for the 300ms before the re-send the held text was the only copy, so a blur or reconnect destroyed characters the pty already had. Bound it the way the reported branch is bounded. Pinned by a test that drives a settle commit between every keystroke and asserts no DEL reaches the wire. --------- Co-authored-by: Brennan Benson <brennanb2025@users.noreply.github.com>
94 lines
2.9 KiB
JSON
94 lines
2.9 KiB
JSON
{
|
|
"name": "orca-mobile",
|
|
"version": "0.0.1",
|
|
"private": true,
|
|
"main": "expo-router/entry",
|
|
"scripts": {
|
|
"start": "node scripts/start-expo.mjs",
|
|
"android": "expo run:android",
|
|
"ios": "expo run:ios",
|
|
"postinstall": "node scripts/build-terminal-webview-engine.mjs && node scripts/build-mermaid-webview-engine.mjs",
|
|
"test": "vitest run",
|
|
"typecheck": "tsc --noEmit",
|
|
"lint": "oxlint",
|
|
"format": "oxfmt --write .",
|
|
"format:check": "oxfmt --check .",
|
|
"mock-server": "npx tsx scripts/mock-server.ts",
|
|
"repro:workspace-picker-lag": "npx tsx scripts/repro-workspace-picker-lag.ts",
|
|
"start:emulator": "node scripts/start-emulator.mjs"
|
|
},
|
|
"dependencies": {
|
|
"@noble/hashes": "1.8.0",
|
|
"@orca/expo-two-way-audio": "file:./packages/expo-two-way-audio",
|
|
"@react-native-async-storage/async-storage": "^2.2.0",
|
|
"@xterm/addon-unicode11": "0.10.0-beta.285",
|
|
"@xterm/addon-webgl": "0.20.0-beta.284",
|
|
"@xterm/xterm": "6.1.0-beta.285",
|
|
"buffer": "^6.0.3",
|
|
"expo": "^55.0.27",
|
|
"expo-build-properties": "^55.0.13",
|
|
"expo-camera": "^55.0.18",
|
|
"expo-clipboard": "^55.0.13",
|
|
"expo-constants": "^55.0.16",
|
|
"expo-crypto": "^55.0.14",
|
|
"expo-dev-client": "~55.0.35",
|
|
"expo-document-picker": "^55.0.13",
|
|
"expo-file-system": "55.0.19",
|
|
"expo-haptics": "^55.0.14",
|
|
"expo-image-manipulator": "^55.0.17",
|
|
"expo-image-picker": "^55.0.20",
|
|
"expo-keep-awake": "~55.0.8",
|
|
"expo-linking": "^55.0.15",
|
|
"expo-modules-core": "~55.0.25",
|
|
"expo-network": "~55.0.14",
|
|
"expo-notifications": "^55.0.22",
|
|
"expo-router": "^55.0.14",
|
|
"expo-secure-store": "^55.0.13",
|
|
"expo-splash-screen": "^55.0.20",
|
|
"expo-status-bar": "^55.0.6",
|
|
"lowlight": "^3.3.0",
|
|
"lucide-react-native": "^1.14.0",
|
|
"mermaid": "11.16.1",
|
|
"react": "^19.2.6",
|
|
"react-dom": "19.2.6",
|
|
"react-native": "^0.83.9",
|
|
"react-native-gesture-handler": "^2.31.2",
|
|
"react-native-reanimated": "^4.3.0",
|
|
"react-native-safe-area-context": "^5.7.0",
|
|
"react-native-screens": "^4.24.0",
|
|
"react-native-svg": "^15.15.4",
|
|
"react-native-web": "^0.21.2",
|
|
"react-native-webview": "^13.16.1",
|
|
"react-native-worklets": "^0.8.3",
|
|
"tweetnacl": "^1.0.3",
|
|
"ws": "^8.21.0",
|
|
"zod": "~4.4.3",
|
|
"zustand": "^5.0.13"
|
|
},
|
|
"devDependencies": {
|
|
"@types/react": "^19.2.14",
|
|
"@types/react-native": "^0.73.0",
|
|
"@types/react-test-renderer": "19.1.0",
|
|
"@types/ws": "^8.18.1",
|
|
"acorn": "8.15.0",
|
|
"esbuild": "0.25.4",
|
|
"expo-module-scripts": "^55.0.2",
|
|
"happy-dom": "^20.9.0",
|
|
"oxfmt": "^0.52.0",
|
|
"oxlint": "^1.71.0",
|
|
"react-test-renderer": "19.2.6",
|
|
"tsx": "^4.22.4",
|
|
"typescript": "6.0.3",
|
|
"vite": "^8.0.16",
|
|
"vitest": "^4.1.9"
|
|
},
|
|
"pnpm": {
|
|
"overrides": {
|
|
"xcode>uuid": "11.1.1"
|
|
},
|
|
"patchedDependencies": {
|
|
"react-native@0.83.9": "patches/react-native@0.83.9.patch"
|
|
}
|
|
}
|
|
}
|