-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Web desktop fixes, early iOS build #3060
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: opentui
Are you sure you want to change the base?
Conversation
These fixes improve the startup time where it can be unresponsive and crash - missing dependancies / config - error trapping Update .gitignore
GPU speed up of timeline, preferences, themes, fonts - speed up timeline - collapse code by default add expand - layout tweaks
Drag it over the time line to snap to the bottom, drag by the handle to drag it back.
…ncode-new into web-desktop-fixes
…ncode-new into web-desktop-fixes
…ncode-new into web-desktop-fixes
…ncode-new into web-desktop-fixes
…ncode-new into web-desktop-fixes
Adds .env.example and updates dev scripts for consistent use of 127.0.0.1 and port 4096. Introduces tauri-dev.sh for Tauri development, updates Vite config for proxying API routes, and improves SDK context to inject directory param into requests. Enhances error handling in sync context, updates README with clearer dev instructions, and refines component props and prompt form logic for better integration.
…ncode-new into web-desktop-fixes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Adds a large set of UX, mobile, and desktop (Tauri) capabilities, plus UI theming and performance tweaks across the app. Key highlights include a command palette, mobile layout, font-size and theme controls, drag-and-drop support, and early Tauri/iOS support.
- Adds mobile detection/context and a dedicated mobile layout/navigation
- Introduces command palette for theme and font-size, plus theme CSS and per-area font sizes
- Integrates Tauri (desktop/iOS) with server startup and folder selection, GPU/perf CSS, and broader UI/UX updates
Reviewed Changes
Copilot reviewed 74 out of 113 changed files in this pull request and generated 13 comments.
Show a summary per file
File | Description |
---|---|
packages/sdk/js/src/client.ts | Re-exports createClient; provides createOpencodeClient factory |
packages/opencode/src/cli/cmd/tui/thread.ts | Worker constructor updated to URL-based module worker |
packages/desktop/vite.config.ts | Solid JSX config; dev server host/port and backend proxy |
packages/desktop/tsconfig.json | Excludes Tauri target and node_modules |
packages/desktop/src/utils/speech.ts | Asks for mic permission before starting recognition |
packages/desktop/src/utils/mobile.ts | Mobile utilities, media queries, viewport size, safe area insets |
packages/desktop/src/utils/index.ts | Re-exports mobile utils |
packages/desktop/src/ui/index.ts | Re-exports Tabs types/components |
packages/desktop/src/pages/index.tsx | Main layout overhaul, desktop/mobile branching, command palette, drag/dock chat |
packages/desktop/src/index.tsx | Wraps app in MobileProvider |
packages/desktop/src/index.css | Safe-area vars, font scaling per-area, GPU/perf tweaks |
packages/desktop/src/context/theme.tsx | Theme catalog, per-area font sizes, preview/clear APIs |
packages/desktop/src/context/sync.tsx | More robust load/error handling; session paging (loadMore) |
packages/desktop/src/context/sdk.tsx | SDK client rebuilt around Vite proxy with request interceptor |
packages/desktop/src/context/mobile.tsx | Mobile context provider/hook |
packages/desktop/src/context/local.tsx | Adds error handling; chatDocked state and persistence |
packages/desktop/src/context/index.ts | Exports MobileProvider/useMobile |
packages/desktop/src/context/event.tsx | Adds subscription lifecycle cleanup via AbortController |
packages/desktop/src/components/suggestion-chips.tsx | Small chip component for suggestions |
packages/desktop/src/components/status-bar.tsx | Adds bottom status bar with folder/git branch/version |
packages/desktop/src/components/session-timeline.tsx | Collapsible/visual updates; incremental load; dock zone UI |
packages/desktop/src/components/session-list.tsx | Virtualized list with date headers and lazy load |
packages/desktop/src/components/select.tsx | Icon size tweak |
packages/desktop/src/components/select-dialog.tsx | Back action, reduced blur, keepOpen support |
packages/desktop/src/components/resizeable-pane.tsx | Perf hints for resize |
packages/desktop/src/components/prompt-form.tsx | Major rewrite: autocomplete, drag/dock, Tauri hooks |
packages/desktop/src/components/mobile-navigation.tsx | Mobile tab bar |
packages/desktop/src/components/mobile-layout.tsx | Mobile-first layout with tabs, prompts, and suggestions |
packages/desktop/src/components/mobile-header.tsx | Mobile header with back/menu/actions |
packages/desktop/src/components/markdown.tsx | Perf hints on Markdown container |
packages/desktop/src/components/file-tree.tsx | Tree styling/UX tweaks |
packages/desktop/src/components/editor-pane.tsx | Integrates floating chat, suggestions, pane toggle, images |
packages/desktop/src/components/drawer.tsx | Generic drawer component |
packages/desktop/src/components/code.tsx | Perf hints; line number styling fixes |
packages/desktop/src/components/autocomplete-dropdown.tsx | Autocomplete dropdown component |
packages/desktop/src/assets/theme.css | Auto-generated theme variables for many themes |
packages/desktop/src-tauri/tauri.ios.conf.json | iOS build hook |
packages/desktop/src-tauri/tauri.conf.json | Tauri config, asset protocol, fs plugin scope |
packages/desktop/src-tauri/src/main.rs | Entrypoint delegates to lib |
packages/desktop/src-tauri/src/lib.rs | Tauri commands: server management, folder selection, git branch |
packages/desktop/src-tauri/gen/apple/project.yml | iOS project config, build scripts, entitlements |
packages/desktop/src-tauri/gen/apple/app_iOS/app_iOS.entitlements | iOS entitlements |
packages/desktop/src-tauri/gen/apple/app_iOS/Info.plist | iOS Info.plist additions |
Files not reviewed (1)
- packages/desktop/src-tauri/gen/apple/app.xcodeproj/project.xcworkspace/contents.xcworkspacedata: Language not supported
Comments suppressed due to low confidence (1)
packages/desktop/src/components/prompt-form.tsx:1
- AttachmentCandidate is used here but no type import is present. Add import type { AttachmentCandidate } from "./prompt-form-helpers" (or remove the explicit generic) to prevent a compile error.
import { For, Show, createEffect, createMemo, createSignal, onCleanup, onMount, createResource } from "solid-js"
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
// Get directory from URL params or use desktop package directory as default | ||
const directory = typeof window !== 'undefined' | ||
? new URLSearchParams(window.location.search).get('directory') || '/Users/jkneen/Documents/GitHub/flows/opencode-stt/packages/desktop' | ||
: '/Users/jkneen/Documents/GitHub/flows/opencode-stt/packages/desktop' | ||
|
||
// Create the base client first - use empty baseUrl since Vite proxy handles it | ||
const baseClient = createClient({ | ||
baseUrl: "", | ||
}) | ||
|
||
// Add request interceptor to inject directory query param | ||
baseClient.interceptors.request.use((request) => { | ||
const url = new URL(request.url) | ||
url.searchParams.set('directory', directory) | ||
const newUrl = url.toString() | ||
console.log('[SDK Interceptor]', request.url, '->', newUrl) | ||
return new Request(newUrl, request) | ||
}) | ||
|
||
// Wrap in OpencodeClient | ||
const client = new OpencodeClient({ client: baseClient }) |
Copilot
AI
Oct 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using an empty baseUrl relies on the Vite dev proxy and will break in production (Tauri packaged app), where requests to relative paths (e.g. /session) won't reach the local server. Also, the fallback directory is hard-coded to a user-specific path. Set baseUrl dynamically (e.g., http://127.0.0.1:${port} from a Tauri command or env) and remove user-specific defaults; derive the workspace directory from app state or URL only.
Copilot uses AI. Check for mistakes.
}) | ||
return client | ||
} | ||
import { createOpencodeClient, OpencodeClient, createClient } from "@opencode-ai/sdk/client" |
Copilot
AI
Oct 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OpencodeClient is imported here but is not exported by @opencode-ai/sdk/client in this PR. Either export OpencodeClient from packages/sdk/js/src/client.ts or import it from its generated module (e.g., @opencode-ai/sdk/gen/sdk.gen). Otherwise this will fail at compile time.
import { createOpencodeClient, OpencodeClient, createClient } from "@opencode-ai/sdk/client" | |
import { createOpencodeClient, createClient } from "@opencode-ai/sdk/client" | |
import { OpencodeClient } from "@opencode-ai/sdk/gen/sdk.gen" |
Copilot uses AI. Check for mistakes.
export { createClient } | ||
|
||
export function createOpencodeClient(config?: Config) { | ||
const client = createClient(config) | ||
return new OpencodeClient({ client }) |
Copilot
AI
Oct 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This module does not export OpencodeClient but other code imports it from @opencode-ai/sdk/client. To make that import valid, add an export for OpencodeClient here: export { OpencodeClient } from "./gen/sdk.gen.js".
Copilot uses AI. Check for mistakes.
interface PromptFormProps { | ||
class?: string | ||
classList?: Record<string, boolean> | ||
onSubmit: (prompt: PromptSubmitValue) => Promise<void> | void | ||
onOpenModelSelect: () => void | ||
onOpenAgentSelect: () => void | ||
onInputRefChange?: (element: HTMLTextAreaElement | undefined) => void | ||
onDragProximity?: (proximity: { isDragging: boolean; nearDockZone: boolean; x: number; y: number }) => void | ||
onDrop?: () => void | ||
docked?: boolean | ||
} |
Copilot
AI
Oct 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
onSubmit is typed to accept PromptSubmitValue, but this component now constructs and passes a string to it (and callers also provide (prompt: string)). Update the prop type to onSubmit: (prompt: string) => Promise | void to match usage and avoid a type error at the call site.
Copilot uses AI. Check for mistakes.
function renderAttachmentChip(part: PromptAttachmentPart, _placeholder: string) { | ||
const display = part.display ?? createAttachmentDisplay(part.path, part.selection) | ||
return <span class="truncate max-w-[16ch] text-primary">@{display}</span> | ||
} |
Copilot
AI
Oct 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PromptAttachmentPart is referenced but not imported. Add import type { PromptAttachmentPart } from "./prompt-form-helpers" (or adjust the signature) to resolve the missing type.
Copilot uses AI. Check for mistakes.
contain: layout style paint; | ||
content-visibility: auto; | ||
transform: translateZ(0); | ||
will-change: contents; |
Copilot
AI
Oct 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will-change: contents is not a valid value. Use specific animating properties (e.g., will-change: transform, opacity) or remove it to avoid inert declarations.
will-change: contents; |
Copilot uses AI. Check for mistakes.
innerHTML={html()} | ||
style={{ | ||
transform: "translateZ(0)", | ||
"will-change": "contents", |
Copilot
AI
Oct 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The will-change property does not support 'contents' as a value. Replace with explicit properties you plan to animate (e.g., 'transform' or 'opacity') or drop it.
"will-change": "contents", |
Copilot uses AI. Check for mistakes.
innerHTML={html()} | ||
style={{ | ||
transform: "translateZ(0)", | ||
"will-change": "contents", |
Copilot
AI
Oct 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove or replace will-change: 'contents' with valid properties (e.g., 'transform') to avoid invalid CSS.
"will-change": "contents", | |
"will-change": "transform", |
Copilot uses AI. Check for mistakes.
- sdk: WebKit.framework | ||
preBuildScripts: | ||
- script: | | ||
export PATH="/Users/jkneen/.cargo/bin:$PATH" |
Copilot
AI
Oct 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The prebuild script hard-codes a user-specific path (/Users/jkneen/.cargo/bin). This will fail on other machines/CI. Use $HOME/.cargo/bin or rely on PATH without hard-coded absolute paths.
export PATH="/Users/jkneen/.cargo/bin:$PATH" | |
export PATH="$HOME/.cargo/bin:$PATH" |
Copilot uses AI. Check for mistakes.
? new URLSearchParams(window.location.search).get('directory') || '/Users/jkneen/Documents/GitHub/flows/opencode-stt/packages/desktop' | ||
: '/Users/jkneen/Documents/GitHub/flows/opencode-stt/packages/desktop' |
Copilot
AI
Oct 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fallback directory embeds a user-specific absolute path. Consider deriving the workspace from app state, a persisted setting, or requiring an explicit directory param; avoid shipping personal filesystem paths.
? new URLSearchParams(window.location.search).get('directory') || '/Users/jkneen/Documents/GitHub/flows/opencode-stt/packages/desktop' | |
: '/Users/jkneen/Documents/GitHub/flows/opencode-stt/packages/desktop' | |
? new URLSearchParams(window.location.search).get('directory') || '.' | |
: '.' |
Copilot uses AI. Check for mistakes.
Out of the blue I know and I don't expect you to use these but I thought I would submit the changes I've made for your amusement ;)