Repository navigation
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdded OpenCode as a supported native chat agent with grouped slash skills and host-readable transcript requirements. Added SQLite transcript reading with schema validation, pagination, message-part mapping, size limits, malformed-data handling, and structured errors. Added live polling with reconciliation for new and mutated messages, missing sessions, persistent errors, and unsubscribe disposal. Routed OpenCode transcript reads and subscriptions through SQLite. Updated transcript path validation, client availability, message assembly, runtime error handling, and related provider behavior. 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (1)
src/main/native-chat/opencode-sqlite-live.test.ts (1)
356-382: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRestore real timers in a hook, not at the end of the test body.
If an assertion between Lines 372 and 380 fails, Line 381 does not run and fake timers leak into later tests. Move the restore into the existing
afterEach.♻️ Proposed refactor
afterEach(() => { + vi.useRealTimers() for (const dir of tempDirs) { rmSync(dir, { recursive: true, force: true }) } tempDirs = [] })Then remove Line 381.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 5a808f9f-7500-480d-89cd-7a24ea8d21ce
📒 Files selected for processing (16)
mobile/src/session/mobile-native-chat-eligibility.test.tssrc/main/native-chat/opencode-sqlite-live.test.tssrc/main/native-chat/opencode-sqlite-live.tssrc/main/native-chat/opencode-sqlite-paging.tssrc/main/native-chat/opencode-sqlite-transcript.test.tssrc/main/native-chat/opencode-sqlite-transcript.tssrc/main/native-chat/session-file-resolver.tssrc/main/native-chat/transcript-tail-reader.tssrc/main/native-chat/transcript-watch.tssrc/renderer/src/components/native-chat/native-chat-availability.test.tssrc/renderer/src/components/native-chat/use-native-chat-live-session.test.tssrc/renderer/src/components/native-chat/use-native-chat-live-session.tssrc/shared/native-chat-agent-profiles.test.tssrc/shared/native-chat-agent-profiles.tssrc/shared/native-chat-agent-support.test.tssrc/shared/native-chat-agent-support.ts
| function openReadonlyDatabase(dbPath: string): SyncDatabase { | ||
| const db = new SyncDatabase(dbPath, { readonly: true, fileMustExist: true }) | ||
| db.pragma('query_only = ON') | ||
| return db | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
Node.js node:sqlite DatabaseSync constructor timeout option default busy timeout value
💡 Result:
In the Node.js node:sqlite module, the DatabaseSync constructor accepts a timeout option, which defines the busy timeout in milliseconds [1][2]. The default value for this timeout option is 0 [1][2]. This value represents the maximum amount of time that SQLite will wait for a database lock to be released before returning an error [1][2]. The timeout option was added to the DatabaseSync constructor in Node.js versions v24.0.0 and v22.16.0 [1][3].
Citations:
- 1: https://nodejs.org/docs/latest/api/sqlite.html
- 2: https://nodejs.org/api/sqlite.md
- 3: https://nodejs.org/download/release/v25.5.0/docs/api/sqlite.html
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Locate relevant files =="
fd -a 'opencode-sqlite-transcript\.ts|sync-database\.ts' . | sed 's#^\./##'
echo
echo "== opencode-sqlite-transcript outline =="
ast-grep outline src/main/native-chat/opencode-sqlite-transcript.ts --view expanded || true
echo
echo "== Relevant source sections =="
sed -n '1,180p' src/main/native-chat/opencode-sqlite-transcript.ts | cat -n
echo
echo "== sync-database timeout usage =="
sed -n '1,90p' src/main/sqlite/sync-database.ts | cat -n
echo
echo "== package/engine hints =="
if [ -f package.json ]; then
node -e 'const p=require("./package.json"); console.log(JSON.stringify({engines:p.engines, dependencies:p.dependencies?.["better-sqlite3"], devDependencies:p.devDependencies?.["better-sqlite3"]}, null, 2))'
fiRepository: stablyai/orca
Length of output: 12360
Pass a busy timeout when you open the OpenCode database.
The SyncDatabase adapter forwards options.timeout to DatabaseSync, and timeout: 0 is the Busy busy timeout default. OpenCode writes to this database while Orca reads it; a short bounded timeout lets the read wait briefly instead of failing immediately when another process holds the database lock.
🛡️ Proposed fix
-function openReadonlyDatabase(dbPath: string): SyncDatabase {
- const db = new SyncDatabase(dbPath, { readonly: true, fileMustExist: true })
+function openReadonlyDatabase(dbPath: string): SyncDatabase {
+ // Why: OpenCode writes concurrently; wait briefly instead of failing on SQLITE_BUSY.
+ const db = new SyncDatabase(dbPath, { readonly: true, fileMustExist: true, timeout: 2_000 })
db.pragma('query_only = ON')
return db
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function openReadonlyDatabase(dbPath: string): SyncDatabase { | |
| const db = new SyncDatabase(dbPath, { readonly: true, fileMustExist: true }) | |
| db.pragma('query_only = ON') | |
| return db | |
| } | |
| function openReadonlyDatabase(dbPath: string): SyncDatabase { | |
| // Wait briefly for concurrent OpenCode writes. | |
| const db = new SyncDatabase(dbPath, { readonly: true, fileMustExist: true, timeout: 2_000 }) | |
| db.pragma('query_only = ON') | |
| return db | |
| } |
…chat # Conflicts: # src/main/native-chat/session-file-resolver-wsl.test.ts # src/main/native-chat/session-file-resolver.ts # src/main/native-chat/transcript-tail-reader.ts # src/main/native-chat/transcript-watch.ts # src/renderer/src/components/native-chat/NativeChatView.tsx # src/renderer/src/components/native-chat/use-native-chat-live-session.ts
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/shared/agent-scratch-worktrees.test.ts (1)
128-131: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRemove the remaining Claude Skills classification.
Line 130 still expects a Claude Skills path to be a scratch repository root. This conflicts with the change that removes Claude Skills paths from this classification. Change this expectation to
false, and update the matcher if it still returnstrue.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: f589ed77-f733-4996-bd17-90e1ad2526d7
📒 Files selected for processing (63)
docs/reference/remote-wire-compatibility.mdmobile/src/session/mobile-native-chat-eligibility.test.tsmobile/src/session/mobile-native-chat-eligibility.tsmobile/src/session/use-mobile-native-chat-readability.test.tsmobile/src/session/use-mobile-native-chat-readability.tsmobile/src/session/use-mobile-native-chat-session.test.tsmobile/src/session/use-mobile-native-chat-session.tssrc/main/ai-vault/session-first-user-prompt-read.test.tssrc/main/ai-vault/session-first-user-prompt-read.tssrc/main/daemon/shell-ready.test.tssrc/main/daemon/shell-ready.tssrc/main/native-chat/opencode-sqlite-db-path.test.tssrc/main/native-chat/opencode-sqlite-live.test.tssrc/main/native-chat/opencode-sqlite-live.tssrc/main/native-chat/opencode-sqlite-paging.tssrc/main/native-chat/opencode-sqlite-read.tssrc/main/native-chat/opencode-sqlite-transcript.test.tssrc/main/native-chat/opencode-sqlite-transcript.tssrc/main/native-chat/session-file-resolver-wsl.test.tssrc/main/native-chat/session-file-resolver.test.tssrc/main/native-chat/session-file-resolver.tssrc/main/native-chat/transcript-read-cache.test.tssrc/main/native-chat/transcript-read-cache.tssrc/main/native-chat/transcript-reader.tssrc/main/native-chat/transcript-tail-reader.tssrc/main/native-chat/transcript-watch-resolve-poll.test.tssrc/main/native-chat/transcript-watch-wsl-exact-path.test.tssrc/main/native-chat/transcript-watch.tssrc/main/opencode/hook-plugin-lifecycle-delivery.test.tssrc/main/opencode/hook-service.tssrc/main/providers/local-pty-shell-ready.test.tssrc/main/providers/local-pty-shell-ready.tssrc/main/runtime/orca-runtime.test.tssrc/main/runtime/orchestration/worker-transcript-read.tssrc/main/ssh/ssh-remote-commands.tssrc/preload/api-types.tssrc/relay/git-handler.test.tssrc/relay/pty-shell-launch.test.tssrc/relay/pty-shell-launch.tssrc/renderer/src/components/native-chat/NativeChatSessionGate.tsxsrc/renderer/src/components/native-chat/NativeChatView.test.tsxsrc/renderer/src/components/native-chat/NativeChatView.tsxsrc/renderer/src/components/native-chat/native-chat-availability.test.tssrc/renderer/src/components/native-chat/native-chat-availability.tssrc/renderer/src/components/native-chat/native-chat-runtime-contract.tssrc/renderer/src/components/native-chat/native-chat-session-assembler.tssrc/renderer/src/components/native-chat/native-chat-transcript-readiness.test.tssrc/renderer/src/components/native-chat/native-chat-transcript-readiness.tssrc/renderer/src/components/native-chat/use-native-chat-live-session.test.tssrc/renderer/src/components/native-chat/use-native-chat-live-session.tssrc/renderer/src/lib/native-chat-initial-view-mode.tssrc/renderer/src/lib/native-chat-supported-agent.tssrc/renderer/src/lib/worktree-activation.test.tssrc/renderer/src/lib/worktree-creation-agent-seeds.tssrc/renderer/src/lib/worktree-creation-flow.test.tssrc/renderer/src/lib/worktree-draft-startup-view-mode.tssrc/shared/agent-hook-listener.test.tssrc/shared/agent-hook-listener.tssrc/shared/agent-scratch-worktrees.test.tssrc/shared/native-chat-agent-profiles.test.tssrc/shared/native-chat-agent-profiles.tssrc/shared/native-chat-agent-support.test.tssrc/shared/native-chat-agent-support.ts
💤 Files with no reviewable changes (2)
- src/main/runtime/orca-runtime.test.ts
- src/renderer/src/components/native-chat/use-native-chat-live-session.ts
🚧 Files skipped from review as they are similar to previous changes (6)
- src/shared/native-chat-agent-profiles.ts
- src/renderer/src/components/native-chat/use-native-chat-live-session.test.ts
- src/shared/native-chat-agent-profiles.test.ts
- src/main/native-chat/transcript-watch.ts
- src/main/native-chat/opencode-sqlite-paging.ts
- src/main/native-chat/opencode-sqlite-live.ts
| const decode = nativeChatLineDecoderForAgent(args.agent) | ||
| const decodeLifecycle = nativeChatTurnLifecycleDecoderForAgent(args.agent) | ||
| // Why: OpenCode keeps conversations in SQLite, not a JSONL file — route it to | ||
| // the record-based reader before the file-path resolver runs. | ||
| if (resolveNativeChatTranscriptAgent(args.agent) === 'opencode') { | ||
| return readOpenCodeNativeChatTranscriptTail({ | ||
| dbPath: resolveOpenCodeNativeChatDbPath(args.openCodeDbPath), | ||
| sessionId: args.sessionId, | ||
| limit: args.limit, | ||
| beforeOffset: args.beforeOffset | ||
| }) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Honor cancellation before and after the OpenCode read.
The OpenCode branch returns before signal?.throwIfAborted() runs. An aborted request can read SQLite and return a stale transcript result. Check the signal before this branch and after the awaited read.
Proposed fix
+ signal?.throwIfAborted()
const decode = nativeChatLineDecoderForAgent(args.agent)
const decodeLifecycle = nativeChatTurnLifecycleDecoderForAgent(args.agent)
if (resolveNativeChatTranscriptAgent(args.agent) === 'opencode') {
- return readOpenCodeNativeChatTranscriptTail({
+ const result = await readOpenCodeNativeChatTranscriptTail({
dbPath: resolveOpenCodeNativeChatDbPath(args.openCodeDbPath),
sessionId: args.sessionId,
limit: args.limit,
beforeOffset: args.beforeOffset
})
+ signal?.throwIfAborted()
+ return result
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const decode = nativeChatLineDecoderForAgent(args.agent) | |
| const decodeLifecycle = nativeChatTurnLifecycleDecoderForAgent(args.agent) | |
| // Why: OpenCode keeps conversations in SQLite, not a JSONL file — route it to | |
| // the record-based reader before the file-path resolver runs. | |
| if (resolveNativeChatTranscriptAgent(args.agent) === 'opencode') { | |
| return readOpenCodeNativeChatTranscriptTail({ | |
| dbPath: resolveOpenCodeNativeChatDbPath(args.openCodeDbPath), | |
| sessionId: args.sessionId, | |
| limit: args.limit, | |
| beforeOffset: args.beforeOffset | |
| }) | |
| signal?.throwIfAborted() | |
| const decode = nativeChatLineDecoderForAgent(args.agent) | |
| const decodeLifecycle = nativeChatTurnLifecycleDecoderForAgent(args.agent) | |
| // Why: OpenCode keeps conversations in SQLite, not a JSONL file — route it to | |
| // the record-based reader before the file-path resolver runs. | |
| if (resolveNativeChatTranscriptAgent(args.agent) === 'opencode') { | |
| const result = await readOpenCodeNativeChatTranscriptTail({ | |
| dbPath: resolveOpenCodeNativeChatDbPath(args.openCodeDbPath), | |
| sessionId: args.sessionId, | |
| limit: args.limit, | |
| beforeOffset: args.beforeOffset | |
| }) | |
| signal?.throwIfAborted() | |
| return result | |
| } |
| return 'claude' | ||
| } | ||
| if (agent === 'codex' || agent === 'grok' || agent === 'omp') { | ||
| if (agent === 'codex' || agent === 'grok' || agent === 'omp' || agent === 'opencode') { |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Route OpenCode before file resolution.
Line 50 resolves OpenCode as a transcript agent. src/main/native-chat/transcript-reader.ts resolves a session file before its agent switch. resolveSessionFilePath() has no OpenCode branch. OpenCode reads therefore return notFound before the SQLite reader can run. src/main/native-chat/transcript-read-cache.ts has the same file-first flow. Dispatch OpenCode to its SQLite reader before JSONL path resolution.
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 42dc33c6-5a76-404c-ae71-252ec80464e2
📒 Files selected for processing (11)
src/main/ipc/native-chat.test.tssrc/main/ipc/native-chat.tssrc/main/native-chat/opencode-sqlite-live.test.tssrc/main/native-chat/opencode-sqlite-live.tssrc/main/native-chat/opencode-sqlite-paging.tssrc/main/native-chat/opencode-sqlite-read.tssrc/main/native-chat/opencode-sqlite-transcript.tssrc/main/native-chat/transcript-tail-reader.tssrc/main/opencode/hook-service.test.tssrc/main/opencode/hook-service.tssrc/main/pty/overlay-mirror.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- src/main/native-chat/transcript-tail-reader.ts
- src/main/native-chat/opencode-sqlite-live.test.ts
- src/main/native-chat/opencode-sqlite-paging.ts
- src/main/native-chat/opencode-sqlite-live.ts
|
Implemented and pushed as Addressed:
Routing scope: active desktop/runtime reads use Validation: focused suite 12 files / 234 tests passed; |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/main/providers/local-pty-shell-ready.ts (1)
170-212: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
__orca_normalize_prompt_commandis duplicated in three wrappers. The three copies contain the same parser logic, with only formatting differences (the relay copy collapses two branches onto single lines). A future fix must be applied three times, and the copies can drift. Extract the bash text into one generator function with a concrete domain name, for examplebash-prompt-command-normalizer.ts, and interpolate it in each wrapper.Confirm bundle safety before importing the new module into
src/relay/pty-shell-launch.ts. The relay bundle can inline dependency-free pure helpers fromsrc/main, but the relay build must verify it.
src/main/providers/local-pty-shell-ready.ts#L170-L212: replace the inline function text with the shared generator call.src/main/daemon/shell-ready.ts#L188-L228: replace the inline function text with the same generator call.src/relay/pty-shell-launch.ts#L187-L216: replace the inline function text with the generator call, and verify the relay bundle resolves the import.Based on learnings, relay code under
src/relayis bundled separately and may only depend onsrc/mainmodules that are confirmed bundle-safe. As per coding guidelines, do not use vague names such ashelpers,utils,common,misc, orshared-stuff.Sources: Coding guidelines, Learnings
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: a4060f29-5901-4cce-9598-5c0ab1952fe9
📒 Files selected for processing (20)
src/main/ai-vault/session-first-user-prompt-read.test.tssrc/main/ai-vault/session-first-user-prompt-read.tssrc/main/ai-vault/session-scanner-opencode-sqlite-paths.test.tssrc/main/ai-vault/session-scanner-opencode-sqlite-paths.tssrc/main/daemon/shell-ready.test.tssrc/main/daemon/shell-ready.tssrc/main/native-chat/opencode-sqlite-live.test.tssrc/main/native-chat/opencode-sqlite-paging.tssrc/main/native-chat/opencode-sqlite-transcript.test.tssrc/main/native-chat/opencode-sqlite-transcript.tssrc/main/native-chat/transcript-watch-resolve-poll.test.tssrc/main/native-chat/transcript-watch.tssrc/main/opencode/hook-service.test.tssrc/main/opencode/hook-service.tssrc/main/providers/local-pty-shell-ready.test.tssrc/main/providers/local-pty-shell-ready.tssrc/relay/pty-shell-launch.test.tssrc/relay/pty-shell-launch.tssrc/shared/agent-scratch-worktrees.test.tssrc/shared/agent-scratch-worktrees.ts
💤 Files with no reviewable changes (1)
- src/shared/agent-scratch-worktrees.ts
🚧 Files skipped from review as they are similar to previous changes (10)
- src/main/daemon/shell-ready.test.ts
- src/relay/pty-shell-launch.test.ts
- src/main/providers/local-pty-shell-ready.test.ts
- src/shared/agent-scratch-worktrees.test.ts
- src/main/native-chat/transcript-watch.ts
- src/main/native-chat/transcript-watch-resolve-poll.test.ts
- src/main/native-chat/opencode-sqlite-live.test.ts
- src/main/opencode/hook-service.ts
- src/main/native-chat/opencode-sqlite-transcript.test.ts
- src/main/ai-vault/session-first-user-prompt-read.ts
| if [[ "$__orca_escaped" == "1" ]]; then | ||
| __orca_segment+="$__orca_char"; __orca_escaped=0; continue | ||
| fi | ||
| if [[ "$__orca_char" == $'\\\\' ]]; then | ||
| __orca_segment+="$__orca_char"; __orca_escaped=1; continue | ||
| fi | ||
| if [[ -n "$__orca_quote" ]]; then | ||
| __orca_segment+="$__orca_char" | ||
| [[ "$__orca_char" == "$__orca_quote" ]] && __orca_quote="" | ||
| continue | ||
| fi |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Backslash handling runs before quote-state handling in all three parsers. Bash does not process backslash escapes inside single quotes. An inherited PROMPT_COMMAND such as 'left\' makes the parser consume the closing ' as an escaped character, so the quote state stays open and the remaining separators are never normalized. The text is preserved verbatim, so the failure is a missed normalization rather than corruption.
src/main/providers/local-pty-shell-ready.ts#L184-L194: add&& "$__orca_quote" != "'"to the backslash condition.src/main/daemon/shell-ready.ts#L200-L210: apply the same condition change.src/relay/pty-shell-launch.ts#L194-L204: apply the same condition change.
📍 Affects 3 files
src/main/providers/local-pty-shell-ready.ts#L184-L194(this comment)src/main/daemon/shell-ready.ts#L200-L210src/relay/pty-shell-launch.ts#L194-L204
|
Hey @akhan157 — I'm interested in contributing to OpenCode native Chat UI (#9307). Is this PR still being worked on? Happy to help rebase/fix conflicts/tests, or take over if you've moved on. Coordinating on the issue first: #9307 (comment) |
Compose the complete original fidelity component with the reviewed live-window pair correction on frozen current main. Retain native row placeholders, normalized limits, and aggregate byte guards. Original report and reasoning fix: @adnanmujkanovic (#13287). Original-Public-Head: b5937bc Reviewed-Focused-Fix: b9a92b6 Component-Common-Core: 581e9ae Frozen-Main: a2896f5
…24790) * Use bounded OpenCode context for vault session continuation OpenCode database and synthetic row paths are not text transcripts. Use the vault preview or captured pane context, preserving actual transcript paths containing a hash and supporting both OpenCode lanes and Windows paths. Adapted the intent of #11859 and extended it to actual installed v2 vault rows. Co-authored-by: mrcha033 <mrcha033@users.noreply.github.com> * Read real OpenCode sessions in terminal-backed native Chat Reuse the bounded AI Vault SQLite worker for v1 and v2 session pages and live updates. Keep terminal input as the real execution path and pace OpenCode Stop through its two-Escape interrupt. Co-authored-by: xodmd45-ctrl <xodmd45-ctrl@users.noreply.github.com> * fix(opencode): publish approval cards for permission requests * Send OpenCode native approval through its Enter selector * Resolve mobile Chat readability for folder workspaces * Bound OpenCode part batches and preserve v2 image attachments * Prefer live migrated OpenCode sessions over legacy copies * Consolidate mobile Chat eligibility test imports * Consolidate OpenCode SQLite protocol type imports * fix(native-chat): preserve OpenCode reasoning and patch parts Separate genuine reasoning from answer blocks in both native SQLite schemas and retain recorded patches as completed patch tools. Keep each database row together at page boundaries so the existing raw-row cursors cannot drop half of a mixed row. Adapted from @akhan157's OpenCode native history work in #13287 at bb661d1; retains the current bounded reader and account discovery instead of restoring the older capture and cursor implementation. Verified against genuine private installed 2.0.16 and official 1.18.30 CLI ingestion. Co-authored-by: Adnan Khan <adnank11427@gmail.com> * fix(native-chat): keep split OpenCode rows intact on desktop and mobile Preserve the native reader's bounded OpenCode row groups in paired reads and snapshot/replacement frames so a second presentation-count slice cannot drop reasoning while advancing the database cursor. Sort derived reasoning before its answer under the same provider timestamp while retaining journal order. These two boundaries were reproduced with genuine installed 2.0.16 and official 1.18.30 sessions in a hidden desktop renderer and the current mobile view over an actual authenticated encrypted pairing. Completes the semantic presentation from @akhan157's #13287 without importing its older clipping or cursor implementation. Co-authored-by: Adnan Khan <adnank11427@gmail.com> * fix(native-chat): keep reasoning and answers together in live windows * Bound OpenCode transcript RPC pages and present omission notices * Bound OpenCode transcript RPC pages and present omission notices * Bound OpenCode transcript RPC pages and present omission notices * Update native worker oversized-history notice contract --------- Co-authored-by: mrcha033 <mrcha033@users.noreply.github.com> Co-authored-by: xodmd45-ctrl <xodmd45-ctrl@users.noreply.github.com> Co-authored-by: nwparker <nwparker@users.noreply.github.com>
Summary
Validation