Skip to content

feat: add OpenCode native chat support - #13287

Closed
akhan157 wants to merge 19 commits into
stablyai:mainfrom
akhan157:akhan157/opencode-native-chat
Closed

akhan157 wants to merge 19 commits into
stablyai:mainfrom
akhan157:akhan157/opencode-native-chat

Conversation

@akhan157

@akhan157 akhan157 commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add OpenCode SQLite transcript mapping for text, reasoning, tool, and patch parts
  • add live reconciliation for in-place streaming mutations
  • wire OpenCode into desktop and mobile native-chat eligibility and renderer deduplication
  • add focused transcript, live-update, pagination, and eligibility tests

Validation

  • Feature-focused desktop/native tests: 128 passed
  • Mobile eligibility test: 12 passed
  • Full Vitest: 4,564 passed, 15 unrelated baseline/environment failures, 19 skipped
  • Formatting, lint, and diff checks pass

@coderabbitai

coderabbitai Bot commented Aug 9, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Added 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)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description includes a summary and validation results but omits the required Screenshots, AI Review Report, Security Audit, and Notes sections. Add all missing template sections, state “No visual change” if applicable, complete the testing checklist, and document AI review, security checks, and platform-specific risks.
Docstring Coverage ⚠️ Warning Docstring coverage is 28.05% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the main change: adding OpenCode native chat support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (1)
src/main/native-chat/opencode-sqlite-live.test.ts (1)

356-382: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Restore 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

📥 Commits

Reviewing files that changed from the base of the PR and between e172a51 and 31f14b8.

📒 Files selected for processing (16)
  • mobile/src/session/mobile-native-chat-eligibility.test.ts
  • src/main/native-chat/opencode-sqlite-live.test.ts
  • src/main/native-chat/opencode-sqlite-live.ts
  • src/main/native-chat/opencode-sqlite-paging.ts
  • src/main/native-chat/opencode-sqlite-transcript.test.ts
  • src/main/native-chat/opencode-sqlite-transcript.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/native-chat-availability.test.ts
  • src/renderer/src/components/native-chat/use-native-chat-live-session.test.ts
  • src/renderer/src/components/native-chat/use-native-chat-live-session.ts
  • src/shared/native-chat-agent-profiles.test.ts
  • src/shared/native-chat-agent-profiles.ts
  • src/shared/native-chat-agent-support.test.ts
  • src/shared/native-chat-agent-support.ts

Comment on lines +41 to +45
function openReadonlyDatabase(dbPath: string): SyncDatabase {
const db = new SyncDatabase(dbPath, { readonly: true, fileMustExist: true })
db.pragma('query_only = ON')
return db
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 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:


🏁 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))'
fi

Repository: 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.

Suggested change
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
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 win

Remove 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 returns true.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f589ed77-f733-4996-bd17-90e1ad2526d7

📥 Commits

Reviewing files that changed from the base of the PR and between a0a654c and 547d675.

📒 Files selected for processing (63)
  • docs/reference/remote-wire-compatibility.md
  • mobile/src/session/mobile-native-chat-eligibility.test.ts
  • mobile/src/session/mobile-native-chat-eligibility.ts
  • mobile/src/session/use-mobile-native-chat-readability.test.ts
  • mobile/src/session/use-mobile-native-chat-readability.ts
  • mobile/src/session/use-mobile-native-chat-session.test.ts
  • mobile/src/session/use-mobile-native-chat-session.ts
  • src/main/ai-vault/session-first-user-prompt-read.test.ts
  • src/main/ai-vault/session-first-user-prompt-read.ts
  • src/main/daemon/shell-ready.test.ts
  • src/main/daemon/shell-ready.ts
  • src/main/native-chat/opencode-sqlite-db-path.test.ts
  • src/main/native-chat/opencode-sqlite-live.test.ts
  • src/main/native-chat/opencode-sqlite-live.ts
  • src/main/native-chat/opencode-sqlite-paging.ts
  • src/main/native-chat/opencode-sqlite-read.ts
  • src/main/native-chat/opencode-sqlite-transcript.test.ts
  • src/main/native-chat/opencode-sqlite-transcript.ts
  • src/main/native-chat/session-file-resolver-wsl.test.ts
  • src/main/native-chat/session-file-resolver.test.ts
  • src/main/native-chat/session-file-resolver.ts
  • src/main/native-chat/transcript-read-cache.test.ts
  • src/main/native-chat/transcript-read-cache.ts
  • src/main/native-chat/transcript-reader.ts
  • src/main/native-chat/transcript-tail-reader.ts
  • src/main/native-chat/transcript-watch-resolve-poll.test.ts
  • src/main/native-chat/transcript-watch-wsl-exact-path.test.ts
  • src/main/native-chat/transcript-watch.ts
  • src/main/opencode/hook-plugin-lifecycle-delivery.test.ts
  • src/main/opencode/hook-service.ts
  • src/main/providers/local-pty-shell-ready.test.ts
  • src/main/providers/local-pty-shell-ready.ts
  • src/main/runtime/orca-runtime.test.ts
  • src/main/runtime/orchestration/worker-transcript-read.ts
  • src/main/ssh/ssh-remote-commands.ts
  • src/preload/api-types.ts
  • src/relay/git-handler.test.ts
  • src/relay/pty-shell-launch.test.ts
  • src/relay/pty-shell-launch.ts
  • src/renderer/src/components/native-chat/NativeChatSessionGate.tsx
  • src/renderer/src/components/native-chat/NativeChatView.test.tsx
  • src/renderer/src/components/native-chat/NativeChatView.tsx
  • src/renderer/src/components/native-chat/native-chat-availability.test.ts
  • src/renderer/src/components/native-chat/native-chat-availability.ts
  • src/renderer/src/components/native-chat/native-chat-runtime-contract.ts
  • src/renderer/src/components/native-chat/native-chat-session-assembler.ts
  • src/renderer/src/components/native-chat/native-chat-transcript-readiness.test.ts
  • src/renderer/src/components/native-chat/native-chat-transcript-readiness.ts
  • src/renderer/src/components/native-chat/use-native-chat-live-session.test.ts
  • src/renderer/src/components/native-chat/use-native-chat-live-session.ts
  • src/renderer/src/lib/native-chat-initial-view-mode.ts
  • src/renderer/src/lib/native-chat-supported-agent.ts
  • src/renderer/src/lib/worktree-activation.test.ts
  • src/renderer/src/lib/worktree-creation-agent-seeds.ts
  • src/renderer/src/lib/worktree-creation-flow.test.ts
  • src/renderer/src/lib/worktree-draft-startup-view-mode.ts
  • src/shared/agent-hook-listener.test.ts
  • src/shared/agent-hook-listener.ts
  • src/shared/agent-scratch-worktrees.test.ts
  • src/shared/native-chat-agent-profiles.test.ts
  • src/shared/native-chat-agent-profiles.ts
  • src/shared/native-chat-agent-support.test.ts
  • src/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

Comment thread src/main/daemon/shell-ready.ts Resolved
Comment on lines 236 to +246
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
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 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.

Suggested change
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') {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 547d675 and c759d59.

📒 Files selected for processing (11)
  • src/main/ipc/native-chat.test.ts
  • src/main/ipc/native-chat.ts
  • src/main/native-chat/opencode-sqlite-live.test.ts
  • src/main/native-chat/opencode-sqlite-live.ts
  • src/main/native-chat/opencode-sqlite-paging.ts
  • src/main/native-chat/opencode-sqlite-read.ts
  • src/main/native-chat/opencode-sqlite-transcript.ts
  • src/main/native-chat/transcript-tail-reader.ts
  • src/main/opencode/hook-service.test.ts
  • src/main/opencode/hook-service.ts
  • src/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

Comment thread src/main/opencode/hook-service.ts Resolved
@akhan157

Copy link
Copy Markdown
Contributor Author

Implemented and pushed as bb661d10d716764fb472d824cd434678875b1947 (fix OpenCode review regressions).

Addressed:

  • AI Vault handler dispatch and custom OPENCODE_DB basenames, including trusted synthetic candidates.
  • Mixed OpenCode reasoning preservation, blank-session live-watch guard, and valid empty-session polling.
  • Top-level overlay manifest tracking and stale-link removal.
  • Quote-aware PROMPT_COMMAND normalization in daemon, local PTY, and relay Bash wrappers.
  • Claude Skills scratch-root classification consistency.
  • SQLite fixture parameter binding.

Routing scope: active desktop/runtime reads use readNativeChatTranscriptTail, which dispatches OpenCode before file resolution and retains the host-internal openCodeDbPath override. The legacy JSONL full-reader/cache APIs have no production callers and remain unchanged; no client IPC/RPC database-path field was added.

Validation: focused suite 12 files / 234 tests passed; pnpm typecheck passed; targeted Oxlint with --deny-warnings and git diff --check passed. gh pr checks currently reports no checks; PR remains open and mergeable.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_command is 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 example bash-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 from src/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/relay is bundled separately and may only depend on src/main modules that are confirmed bundle-safe. As per coding guidelines, do not use vague names such as helpers, utils, common, misc, or shared-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

📥 Commits

Reviewing files that changed from the base of the PR and between c759d59 and bb661d1.

📒 Files selected for processing (20)
  • src/main/ai-vault/session-first-user-prompt-read.test.ts
  • src/main/ai-vault/session-first-user-prompt-read.ts
  • src/main/ai-vault/session-scanner-opencode-sqlite-paths.test.ts
  • src/main/ai-vault/session-scanner-opencode-sqlite-paths.ts
  • src/main/daemon/shell-ready.test.ts
  • src/main/daemon/shell-ready.ts
  • src/main/native-chat/opencode-sqlite-live.test.ts
  • src/main/native-chat/opencode-sqlite-paging.ts
  • src/main/native-chat/opencode-sqlite-transcript.test.ts
  • src/main/native-chat/opencode-sqlite-transcript.ts
  • src/main/native-chat/transcript-watch-resolve-poll.test.ts
  • src/main/native-chat/transcript-watch.ts
  • src/main/opencode/hook-service.test.ts
  • src/main/opencode/hook-service.ts
  • src/main/providers/local-pty-shell-ready.test.ts
  • src/main/providers/local-pty-shell-ready.ts
  • src/relay/pty-shell-launch.test.ts
  • src/relay/pty-shell-launch.ts
  • src/shared/agent-scratch-worktrees.test.ts
  • src/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

Comment on lines +184 to +194
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 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-L210
  • src/relay/pty-shell-launch.ts#L194-L204

@justeozan

Copy link
Copy Markdown

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)

nwparker added a commit that referenced this pull request Oct 3, 2026
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
nwparker added a commit that referenced this pull request Oct 4, 2026
…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>
@brennanb2025

Copy link
Copy Markdown
Contributor

Thanks for this contribution! OpenCode native Chat support landed in #24647, and #24790 adapted and credited this PR’s reasoning and patch rendering work. Closing this PR because that functionality is now on main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants